1. Probe
1) Probe의 개요
- 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단 ( Pod Healthcheck )
(1) Pod LifeCycle
- Pending - Running-Succeed/Fail ( unknown : 통신 불가 )
① pending : pod 생성이 시작되었지만 아직 컨테이너 설정이 진행중
② running: 1개 이상의 pod container가 생성, 실행중 or 시작/재시작 상태
( 시작 실패 시, Running이지만 접속되지 않는 상황을 Health Check )
③ succeeded : 모든 container가 성공적으로 종료
(2) 체크 메커니즘
① exec : 지정된 명령 실행 (상태 코드 0으로 종료시 진단 성공)
② rhttpGet : get요청으로 상태가 200~400미만이면 성공 (Java SpringBoot의 Actuator호출 등)
③ grpc : gRPC를 사용하여 원격 프로시져 호출, 응답 status가 SERVING이면 진단 성공
④ tcpSocket : 컨테이너 IP주소에 대해 TCP검사 수행, 포트 활성화시 진단 성공으로 간주
2) Probe 종류
(1) livenessProbe ( 활성 Probe )
① 컨테이너가 동작중인지 체크
- 동작 체크 실패시 kubelet이 해당 컨테이너를 terminate하고 새 container가동
- 서비스의 엔드포인트에 연결된 개별 pod의 IP를 제거 ( 준비된 Pod에 traffic )
- 미지정 시 기본 상태 Success
② 구동 실습
- InitialDelaySeconds : 컨테이너가 시작되는 시간 ( 3초간 활성화하지 않고 대기 )
- 실패시 Pod를 다시 시작
cat <<EOF>> liveness-test.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: registry.k8s.io/e2e-test-images/agnhost:2.40
args:
- liveness
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
EOF
kubectl apply -f liveness-test.yaml
# Pod 확인
watch kubectl get pod -o wide
# Pod 상세 정보
kubectl describe pod liveness-http

(2) readiness Probe ( 준비성 Probe )
① 컨테이너가 요청을 처리할 준비가 되었는지 여부 체크
- 실패시, 엔드포인트 컨트롤러가 pod에 연관된 모든 서비스 엔드포인트에서 pod의 IP주소제거
( 서비스를 다른 Pod로 요청, 트래픽 차단 )
- 초기 지연 이전의 기본상태 Failure ( 미지정 시 기본 상태 Success )
- 운영환경에서는 liveness probe와 readiness probe를 함께 사용
② 구동 실습
- 8080포트로 3초마다 시도, 준비되지 않으면 ready로 변경되지 않고 대기
cat <<EOF>> readiness-test.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: readiness
name: readiness-http
spec:
containers:
- name: readiness
image: registry.k8s.io/e2e-test-images/agnhost:2.40
args:
- liveness
readinessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
EOF
kubectl apply -f readiness-test.yaml
# Pod 확인
watch kubectl get pod -o wide
# Pod 상세 정보
kubectl describe pod readiness-http

(3) startupProbe
- 컨테이너 내의 어플리케이션의 시작여부 ( 시작이 느린 SpringBoot, Actuator로 체크 )
- startup probe가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않음 (성공후 다른 프루브로 전환)
- 실패시 kubelet이 container를 terminate한 후 재시작 정책 적용
2. Manifest

1) Manifest의 개요
- Kubernetes리소스를 정의하는 설정 파일 ( 선언형 파일, yaml )
(1) 환경별 구성 분리 및 Overlay
① 개발, 검증, 운영 환경별로 구성과 설정이 다른 경우에도 일관성 확보 ( 누락, 오타, 오류의 가능성 높아 기본 구성에 overlay하는 방식 적용 )
② Template화, 변수화하여 일관된 구조를 유지하고 유지/보수 및 재사용성 향상
③ 관리도구를 사용하여 버전관리와 롤백, 자동화 & GitOps통합
(2) 관리 도구
① Kustomize (kubectl 내장)
- Kubernetes구성을 사용자 정의화하는 도구
- Overlay, 공통설정 재사용
② Helm
- 보편적으로 사용되는 Manifest도구 ( Kubernetes의 package manager)
- Template기반 manifest생성, 버전관리/업그레이드/롤백, 재사용 가능(차트)
③ 기타 : Kpt, Jsonnet
2) Kustomize (Kubernetes Customize)

(1) 기본 기능
① Kubernetes 리소스를 레이어별로 구성
② 리소스를 변경하지 않고 필드를 재정의하여 새로운 쿠버네티스 리소스를 생성 (override하여 생성)
(2) 구성
- 디렉터리 형태로 구성 ( base & overlay )
① Base
- Kustomize를 통해 변경할 yaml이 저장된 디렉터리
- Kustomization을 통해 재사용 가능 ( deployment, service등의 재사용 가능한 기본 yaml )
② Overlay
- Base에 적용할 kustomization.yaml이 저장된 디렉터리
- 환경별 차이점을 정의 ( overlays/prd, overlays/dev, overlays/stg 등으로 구성 )
(3) kustomization.yaml
① kustomize가 수행될때 재정의 될 필드를 설정하는 파일 (resource, patches, ... )
② resource, patches, namePrefix, ConfigMapGenerator 등 다양한 설정구성
- resources : kustomize 를 적용할 yaml 파일
- generators : 새로운 필드 생성
- transformers : 필드 변경
- validators : 검증 - 실패 시 배포 금지
- 그 외에도 configMapGenerator , namePrefix , patches 등의 플러그인
③ kustomize 실행 순서
- resources → generators → transformers → validators
(4) 기본 활용
① 설치 및 버전확인
- 기본적으로 kubectl에 통합되어 있으나 여러 기능을 사용하기 위해서는 설치 필요
# Kubectl Version 확인
kubectl version --client
# Kubectl Version 확인 (kcustomize build외 다른 기능을 사용하기 위해 설치필요한 경우가 있음)
kubectl version --client
# Binary 설치
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash && mv kustomize /usr/local/bin
# MacOS
brew install kustomize
# Chocolatey (Window)
choco install kustomize
kustomize version

② Kustomize 실행
- resourcce에 pod.yaml ( image에도 변경이 있으며, 변경된 이미지로 시행 )에 이미지 변경 적용
# 실습 디렉토리 생성
mkdir kustomize && cd kustomize
cat << EOF >> kustomization.yaml
resources:
- pod.yaml
images:
- name: nginx
newName: new-nginx
newTag: 1.23.1
EOF
kubectl kustomize .
# kustomize 결과를 파일로 추출
kubectl kustomize . > pod-kustomize.yaml
# 기존 Pod 파일과 차이 확인
diff pod.yaml pod-kustomize.yaml

③ Kustomize로 배포 (기존 yaml파일 변경없이 새로운 설정을 적용)
# kustomize 배포
kubectl kustomize . | kubectl apply -f -
# kustomize 파일로 추출 후 배포
kubectl kustomize . > pod-kustomize.yaml | kubectl apply -f pod-kustomize.yaml
# 배포 확인
kubectl describe pod nginx | grep -i containers: -A4
#리소스 삭제
kubectl kustomize . | kubectl delete -f -

(5) 심화 실습
① reource 필드 확인
- 명시된 파일이 지정된 조건으로 overlay (경로가 같아도 kustomization에 선언되지 않으면 적용안됨)
- 서비스, pod2개 배포, kustomization
- 리소스에는 kustomization에 선언되어 있는 pod만 적용
mkdir kustomize-1 && cd kustomize-1
cat << EOT > service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
EOT
cat << EOF > pod-1.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
name: nginx-1
name: nginx-1
spec:
containers:
- image: nginx:latest
name: nginx-1
resources:
limits:
cpu: 100m
memory: 64Mi
EOF
cat << EOF > pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
name: nginx-2
name: nginx-2
spec:
containers:
- image: nginx:latest
name: nginx-2
resources:
limits:
cpu: 100m
memory: 64Mi
EOF
cat << EOF > kustomization.yaml
resources:
- pod-1.yaml
- service.yaml
EOF
➡ 1개의 서비스와 2개의 pod생성했으나 kustomize는 resource에 선언된 내용만 포함

② 트랜스포머 필드확인
트랜스포머 필드 : namespace, image등의 다양한 필드값을 변경하는 기능
- namespace를 변경, 이미지의 태그를 변경하는 내용 수행
#test의 namespace생성
kubectl create ns test
#ns를 변경하도록 kustomization설정
cat << EOT > kustomization.yaml
namespace: test
resources:
- pod-1.yaml
- service.yaml
EOT
# kustomize 실행, 변경 내용 확인
kubectl kustomize .
#이미지의 태그를 변경하도록 kustomization설정
cat << EOT > kustomization.yaml
namespace: test
images:
- name: nginx
newTag: 1.23.1
resources:
- pod-1.yaml
- service.yaml
EOT
# kustomize 실행, 변경 내용 확인
kubectl kustomize .


③ Base / Overlays
- base와 overlay, dev와 prd
- base의 kustomize : resource에 pod 설정
- overlay의 kustomize : resource에 base 디렉토리 설정, prefix(pod 이름앞에 추가)
cd .. && mkdir kustomize-2 && cd kustomize-2
# 실습 디렉토리 구성
mkdir -p base overlays/dev overlays/prd
#트리 구성확인
tree .
# Base kustomization.yaml 생성
cat << EOT > ./base/kustomization.yaml
resources:
- pod.yaml
EOT
# Base pod.yaml 생성 (공통으로 사용할 YAML 파일)
cat << EOT > ./base/pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:latest
EOT
#dev, namePrefix를 네임앞에 적용
cat << EOT > ./overlays/dev/kustomization.yaml
resources:
- ../../base
namePrefix: dev-
EOT
#prd, namePrefix를 네임앞에 적용
cat << EOT > ./overlays/prd/kustomization.yaml
resources:
- ../../base
namePrefix: prd-
EOT
#변경된구조 확인
tree .
# dev kustomize 실행
kubectl kustomize overlays/dev
# prd kustomize 실행
kubectl kustomize overlays/prd


3) Helm ( 현업에서 일반적으로 쓰이는 방식 )
- Template형식, 하나의 yaml파일 (values.yaml) 모두 배포가능
- 인증된 차트 공급자의 파일활용 : 자사 환경에 맞게 values.yaml설정을 overlay (주로 OpenSource인 ArgoCD, Metric Server, Nginx Ingress Controller등)
- Helm Chart생성 : 자사의 서비스 배포환경에 맞게 구성 ( 주로 Application배포용으로 NextJS, SpringBoot )

(1) 주요 구성
① Chart
- Helm의 패키지 ( yum, apt, brew와 유사 )
- 애플리케이션, 도구, 서비스를 구동하는 데 필요한 모든 리소스 정의 포함, Kubernetes 리소스들(Deployment, Service 등)
② Repository
- Helm Chart의 저장/공유하는 장소 ( Kustomize의 경우는 공유하는 장이 없음 )
- 공유 저장소(Artifact Hub), 공유하기 어려운 내부 조건이 반영 시 설치형(Harbor)
** Harbor는 container설정 저장소였으나 최근 Helm chart저장소로도 확장
③ Release
- Helm Chart로 Kubernetes의 cluster에 배포한 인스턴스
- Chart별로 복수의 Release가능 ( overlay개념, version )
④ Values
- 사용자 정의값 (values.yaml이나 커맨드라인에서 전달하는 값 )커스터마이즈
- 템플릿 파일 내의 변수들을 바인딩, 동적인 리소스 생성 가능
(2)기본 실습
① Helm 설치 및 내용 확인
- Helm repo ls : 로컬의 내부 repository확인 (local에 등록된 repo, 원격 url등)
- Helm create : Helm의 template의 기본 구조를 생성
- values.yaml의 내용을 각 template의 내용으로 대입하여 실행
# Mac Homebrew 설치
brew install helm
# Windows Chocolatey
choco install kubernetes-helm
# Helm Version 확인
helm version
helm version --short
# Helm 디렉토리 이동
mkdir helm-practice
# Helm Repo 확인
helm repo ls
# Helm 생성
helm create mychart
# Helm 구조 확인
cd mychart
tree .

② Helm의 배포
- install 명령어로 배포 ( release_name과 경로표시가 필요, 배포와 함께 version/namespace(Helm은 namespace에 종속)/notes(Helm>templates>notes에도 있음) 포함
- helm의 배포로 pod, deployment, service, service account까지 모두 완료
# Helm 배포
# helm install <RELEASE_NAME> <패키지 경로> [flags]
helm install myapp .
# Helm Release 확인
helm list
# Helm 으로 배포된 리소스 확인
kubectl get po,deploy,svc,sa
# Helm 삭제
helm delete myapp


(3) Values.yaml
- 템플릿 파일 내의 변수들을 바인딩하여 동적인 리소스 생성 가능
- 환경별로 yaml파일로 적용가능 ( dev, stg, prd )

① artifactHub의 repo를 활용한 배포 ( 커뮤니티의 공신력있는 Repository추가)
- repository추가 : helm repo add 차트명 <URL>
- install 명령어로 배포 ( release_name과 chart경로표시 )
# Community Repository 추가
helm repo add bitnami https://charts.bitnami.com/bitnami
# Helm Repo 조회
helm repo ls
# Bitnami 의 Helm Chart 조회
helm search repo bitnami
# Helm Nginx 설치
# 최신 차트 정보를 가져오도록 하는 명령어
helm repo update
# Helm
# helm install <RELEASE_NAME> <CHART 경로> [flags]
helm install mynginx bitnami/nginx
kubectl describe deploy mynginx
kubectl describe deployments.apps mynginx | grep 'Containers:' -A5



② values.yaml을 이용한 설정 변경(배포)
- 이미지 태그를 변경하기 위한 values.yaml파일을 구성해서 helm에 적용 ( release에서 태그가 적용되며 version변경도 수행)
# values.yaml 작성 (태그변경)
cat <<EOF > values.yaml
image:
tag: 1.24
EOF
# 기존 Helm 설정을 values.yaml 파일에 기반하여 변경
helm upgrade mynginx bitnami/nginx -f values.yaml
kubectl describe deploy mynginx
kubectl describe deployments.apps mynginx | grep 'Containers:' -A5
# Helm Realese 조회
helm ls


3. GitOps

1)Git Ops의 개요
(1) Git Ops의 내용
① Flux를 개발한 Weaveworks에서 사용 (2017~)
② 환경을 선언적으로 정의하기 위해 Git Repository사용
③ 버전 관리와 병합요청을 통해 변경하여 전체 시스템 감시
(2) Git중심의 운영/배포 자동화 방식
① Infra와 Application설정을 Git저장소에 선언적 정의 ( 클러스터 상태 동기화 수행의 기반 )
② CI(소스코드)와 CD(배포용 코드) 저장소 구분관리 ( yaml 파일 변경으로 리소스나 런타임 설정 변경시 빌드없이 배포/롤백 가능)
③ 핵심 개념
- 모든 설정을 Git에 저장, SSOT(Single Source of Truth, 단일 진실의 원천)로 사용
- 선언형 인프라 ( yaml 형태의 선언형 파일로 원하는 상태를 정의 )
- 자동 동기화 (Git의 선언형 파일과 클러스터 상태 동기화)
- 자동 롤백 및 감시 (Git으로 History추적, 승인절차 적용)
2) ArgoCD
- 현업에서는 실제로 GitOps와 ArgoCD활용

(1) Argo CD의 내용
① Git을 배포의 원천으로 사용하는 GitOps CD도구
- Git의 manifest를 기반으로 쿠버네티스 배포 및 상태 동기화
② ArgoCD의 Application Controller
- Kubernetes Controller(원하는 상태를 동기화)로 구성
- Git의 선언된 상태와 동기화 수행
③ 동작 방식이나 확장 플러그인의 활용이 다양함
- 배포전략, 알림설정등 확장성 보유 (Argo Rollout, Argo CD Notification)
(2) 실습
① ArgoCD설치
- helm으로 설치
- 서비스는 NodePort ( 31000, 31001번 포트연결, local 접속가능 )
# ArgoCD Namespace 생성
kubectl create ns argocd
# Terminal 2번
watch kubectl get pod,pvc,svc -n argocd
# Helm Repo 등록
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd --set server.service.type=NodePort --namespace argocd
# ArgoCD 서비스 접근을 위한 노드포트 변경
kubectl patch svc argocd-server -n argocd \
-p '{"spec": {"ports": [{"port": 443, "targetPort": 8080, "nodePort": 31001}]}}'
# 리소스 확인
kubectl get all -n argocd



② ArgoCD 로그인
- 비밀번호를 확인 후 Nodeport로 연결한 localhost의 포트주소로 연결하여 admin으로 로그인
# 초기 비밀번호 확인
kubectl -n argocd get secrets argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# ArgoCD UI 접근
open http://localhost:31001

③ Git저장소를 생성하여 Chart생성
- Git의 저장소 open하여 (ArgoCD가 접근할수 있는 Repository) clone
- Helm Chart생성 ( repository에 helm이 들어가 있으니깐 커밋 후 push하여 배포 )
# 본인 Repository 클론
git clone https://github.com/ellanelee/argocd-practice.git
# Helm Chart 생성
helm create argo-test-chart
# Git Push
git add . && git commit -m "Initial Commit" && git push origin main



④ ArgoCD에 Git저장소를 연결하여 배포
- 어플리케이션 기본정보, Git저장소 연결 및 values.yaml 정보 설정 후 배포(CREATE)






⑤ values.yaml의 설정을 변경
- replicaCount를 2로, tag를 1.24로 변경하여 ArgoCD
# values 파일 변경
vim values.yaml
...
replicaCount: 2
image:
repository: nginx
tag: "1.24"
...
# Git push
git add . && git commit -m "Values Modified" && git push




➡ 현업에서는 GitOps와 ArgoCD활용이 대세 ( ArgoCD 적용시 Default동기화 주기 3분으로 즉시 반영되지 않으며, 동기화 주기는 조정가능 )
➡ Custom Helm Chart생성을 위한 Helm Template문법 ( https://helm.sh/ko/docs/chart_template_guide/getting_started/ )
________________________________________________________
도커, 쿠버네티스 동아리의 마지막 강좌가 끝났다. 말로만 듣던 GitOps로 대단원의 막을 내렸다. 감개무량 ~
도커는 그래도 기본 개념은 알아서 수월했는데, 쿠버네티스는 생초보인데다가 CLI화면에 익숙하지 않은 리눅스 초짜여서 다채로운 국면이 있었다. 폴더를 잘못 들어가서 엉뚱한 짓(??)을 해놓고는 왜 안되지 어리둥절한 적도 있었다.
아무리 자료가 상세해도 강의를 들을때만 이해가 되고 다시 보면 이거 뭐였더라~ 하고 파악이 안되는 경우도 많은데, 강의를 녹화본으로 제공해주셔서 차례차례 눈으로 확인할수 있고 잘 모르겠으면 여러번 돌려보면서 틀린 부분을 찾을수 있어서 좋았다.