[9. Kustomize]
출제 비중: 중간. Helm 과 같은 커리큘럼 항목이라 둘 중 하나 또는 둘 다 나온다.
보통 overlay 작성이나 patch 한 개 수준.
관련 문제: 0021 (Kustomize overlay 작성과 적용) - 통과
1. 왜 Kustomize 인가
Helm 과 목표는 같다. 환경마다 조금씩 다른 YAML 을 깔끔하게 관리하는 것.
방식이 다르다.
항목 Helm Kustomize
방식 YAML 에 {{ .Values.x }} 빈칸을 뚫음 원본 YAML 은 그대로, 바꿀 부분만 따로 적음
설치 helm 바이너리 필요 kubectl 에 내장 (kubectl apply -k)
release/이력 있음. rollback 가능 없음. 그냥 apply
주 용도 남이 만든 앱 배포 내 YAML 을 환경별로 관리
2. base 와 overlay
kustomize/
base/ 원본. 모든 환경 공통
kustomization.yaml resources: [deployment.yaml, service.yaml]
deployment.yaml
service.yaml
overlays/
prod/ prod 환경에서 바꿀 부분만
kustomization.yaml resources: [../../base] + 변경 사항
overlay 는 base 를 참조하고 그 위에 변경을 얹는다. base 는 절대 수정하지 않는다.
dev, staging, prod overlay 를 따로 만들면 같은 base 로 환경 셋을 관리할 수 있다.
3. 자주 쓰는 필드
resources 가져올 YAML 이나 다른 kustomization 경로
namespace 모든 리소스의 네임스페이스를 바꿈
namePrefix/Suffix 모든 리소스 이름 앞뒤에 붙임
images 이미지 이름이나 태그 교체
replicas Deployment replicas 변경
patches 위 필드로 안 되는 나머지 변경. 부분 YAML 로 덮어씀
configMapGenerator ConfigMap 생성. 이름 뒤에 해시가 붙음
4. 명령
kubectl kustomize overlays/prod 적용 전에 결과 YAML 미리 보기
kubectl apply -k overlays/prod 적용
kubectl delete -k overlays/prod 삭제
적용 전에 항상 미리 보기부터. 결과 YAML 을 눈으로 확인하면 함정 대부분을 잡는다.
5. 필드는 어떻게 자동으로 매핑되나
kustomization.yaml 은 정해진 필드 목록이 있는 파일이다.
필드는 두 종류로 나뉜다.
지시서 replicas, images, namespace, namePrefix
Kustomize 에 내장된 규칙으로 정해진 위치를 찾아가 바꾼다.
depth 를 맞출 필요 없음. 대상 이름과 값만 적는다.
덮어쓰기 patches
내가 적은 YAML 을 원본과 같은 depth 로 겹친다.
지시서마다 찾아가는 위치
replicas name 이 일치하는 Deployment/StatefulSet/ReplicaSet -> spec.replicas
images 모든 컨테이너 중 이미지 이름이 일치하는 것 -> containers[].image, initContainers[].image
namespace 모든 리소스 -> metadata.namespace
namePrefix 모든 리소스 -> metadata.name (참조하는 이름도 같이 바꿈)
예) replicas 지시서
replicas:
- name: api 어느 Deployment 인가
count: 5 몇 개로
지시서가 없는 변경은 patches 로. 이때는 원본과 똑같은 depth 로 적는다.
# patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
template:
spec:
containers:
- name: app 컨테이너 이름으로 어느 항목인지 찾음
resources:
limits:
memory: 512Mi
바꾸고 싶은 값까지 가는 경로만 남기고 나머지는 생략한다.
replicas 도 patch 로 바꿀 수 있다. 지시서는 자주 쓰는 변경의 지름길일 뿐.
Helm 과의 차이
Helm 원본 YAML 에 빈칸을 뚫어 두고 값을 채움 = 템플릿
Kustomize 원본은 손대지 않음. 정해진 지시서 필드로 결과만 바꿈
필드는 마음대로 만들 수 없다. 목록에 없는 필드는 에러가 나거나 무시된다.
6. 함정
- namespace 필드는 네임스페이스를 만들지 않는다.
리소스에 이름만 적어준다. 없으면 apply 가 실패한다.
-> 먼저 kubectl create ns <이름>, 또는 Namespace YAML 을 resources 에 추가.
- images 의 name 은 컨테이너 이름이 아니라 이미지 이름.
nginx:1.24 면 name 에 nginx.
- replicas 의 name 은 prefix 붙기 전 base 의 원래 이름.
prod-web 이 아니라 web.
- 대상을 못 찾아도 에러 없이 조용히 무시되는 경우가 많다. 미리 보기로 확인.
- newTag 는 따옴표로 감싼다. "1.25"
따옴표 없이 1.20 을 쓰면 YAML 이 숫자로 읽어 1.2 가 된다.
- 폴더에 apply -f 를 쓰면 kustomization.yaml 을 해석하지 않는다. 반드시 -k.
- resources 의 base 경로는 overlay 폴더 기준 상대경로. base 파일을 복사하지 말고 참조.
7. YAML 한 줄 표기 (flow style)
{ } 맵 (key: value 묶음)
[ ] 리스트 (- 로 시작하는 항목)
JSON 과 같은 기호. 평소 표기와 의미는 완전히 같다.
metadata: {name: web, labels: {app: web}}
=
metadata:
name: web
labels:
app: web
ports: [{containerPort: 80}]
=
ports:
- containerPort: 80
kubectl kustomize <폴더> 로 미리 보기를 하면 펼친 표기로 다시 출력해 준다.
시험에서는 펼친 표기로 쓴다. 괄호 하나 빠지면 에러 찾기가 어렵다.
8. 시험에서 YAML 을 덜 치는 방법
1) apiVersion 과 kind 는 빼도 된다. Kustomize 가 기본값으로 채운다.
resources:
- ../../base
namespace: kprod
이것만 있어도 동작한다.
2) 옆에 있는 파일을 복사해서 고친다.
cp ../../base/kustomization.yaml .
base 가 주어지는 문제가 많다. 단, 항상 보장되지는 않는다.
3) 공식 문서에서 복사한다.
문서 검색 "kustomization"
-> Declarative Management of Kubernetes Objects Using Kustomize
namePrefix, images, patches, configMapGenerator 예시가 전부 있다.
시험 터미널 복사/붙여넣기: Ctrl+Shift+C / Ctrl+Shift+V
4) 다른 YAML 은 kubectl 로 생성한다.
kubectl create deploy web --image=nginx --dry-run=client -o yaml > deploy.yaml
5) vi 들여쓰기 설정 (시험 시작 직후 한 번)
echo 'set expandtab tabstop=2 shiftwidth=2' >> ~/.vimrc
붙여넣기 전에 vi 에서 :set paste 를 치면 들여쓰기가 밀리지 않는다.
helm create 같은 생성 명령이 있나?
kubectl 에는 없다. kubectl kustomize 는 결과를 만드는 기능뿐.
별도 kustomize 바이너리에는 있다.
kustomize create --autodetect
kustomize edit set namespace kprod
kustomize edit set nameprefix prod-
kustomize edit set image nginx=nginx:1.25
kustomize edit set replicas web=3
시험 환경에 있다는 보장이 없다. 있으면 쓰고, 없어도 풀 수 있게 준비한다.
base 가 없을 때 순서
1) 리소스 YAML 은 --dry-run=client -o yaml 로 생성
2) kustomization.yaml 은 resources 몇 줄만 직접 작성
3) 나머지 필드는 공식 문서에서 복사해 이름과 값만 변경
4) 미리 보기로 결과 확인
외울 것은 필드 이름뿐: resources, namespace, namePrefix, images, replicas, patches
9. 문제 0021 풀이
요구사항
- overlay 위치 /tmp/cncf-out/kustomize/overlays/prod/
- namespace kprod (없으면 생성)
- namePrefix prod-
- Deployment replicas 3
- 이미지 nginx 태그를 1.25 로
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kprod
namePrefix: prod-
resources:
- ../../base
replicas:
- name: web
count: 3
images:
- name: nginx
newTag: "1.25"
명령
kubectl create ns kprod
kubectl kustomize /tmp/cncf-out/kustomize/overlays/prod 미리 보기
kubectl apply -k /tmp/cncf-out/kustomize/overlays/prod
kubectl -n kprod get deploy,svc prod-web 3/3, svc prod-web
./bin/q check 21
채점기는 Pod 3개 Ready 까지 본다. 이미지 받는 데 시간이 걸리니
apply 직후 실패하면 30초쯤 기다렸다가 다시 채점.