본문 바로가기

Docker & Kubernetes

도커 & 쿠버네티스 스터디 4주차 - Kubernetes Probe & GitOps 개요

실습환경 배포

  • 지난 3주차와 동일

 

Pod LifeCycle

Probe 개요

Pod LifeCycle

파드는 정의된 라이프사이클을 따른다.

Pending → Running → Succeded or Failed

  • Node 를 사용할 수 없는 상태
  • Container 를 생성하기 위한 자원이 부족한 상태
  • Container Image 를 아직 가져오지 못한 상태 | | Running | Pod Container 가 생성되었고 1개 이상의 Container 가 실행중이거나 시작, 재시작 상태 | | Succeeded | Pod 내부의 모든 Container 가 성공적으로 종료된 상태 | | Failed | Pod 내부 모든 Container 가 종료되었고, 적어도 1개 이상의 Container 가 실패로 종료된 상태 | | Unknown | 어떤 이유에 의해서 Pod 의 상태를 얻을 수 없는 상태 일반적으로 파드와 노드간의 통신 오류 |
  • 파드가 실행되는 동안, kubelet 은 일종의 오류를 처리하기 위해 컨테이너를 다시 시작할 수 있다.
  • 파드 내에서, 쿠버네티스는 다양한 컨테이너 상태를 추적하고 파드를 다시 정상 상태로 만들기 위해 취할 조치를 결정한다.

Probe

  • 프로브는 컨테이너에서 kubelet 에 의해 주기적으로 수행되는 진단
    • Pod HealthCheck
  • 진단을 수행하기 위해서 kubelet은 컨테이너 안에서 코드를 실행하거나 네트워크 요청을 전송한다.

Probe 체크 메커니즘

  1. exec
    • 컨테이너 내에서 지정된 명령어 실행
    • 명령어가 상태 코드 0으로 종료되면 진단이 성공한 것으로 간주
  2. grpc
    • gRPC 를 사용하여 원격 프로시저 호출을 수행
    • 체크 대상이 gRPC 헬스 체크 구현 필요
    • 응답의 status 가 SERVING 이면 진단이 성공했다고 간주
    • gRPC 프로브는 알파 기능이며 GRPCContainerProbe 기능 게이트(Feature Gate) 활성화 필요
  3. httpGet =⇒ 보통 많이 사용한다!
    • 지정한 포트 및 경로에서 컨테이너의 IP주소에 대한 HTTP GET 요청 수행
    • 응답의 상태 코드가 200 이상 400 미만이면 진단이 성공한 것으로 간주
    • 주로 사용되는 Probe 체크 메커니즘이며 Java Springboot 의 Actuator 와 연동
  4. tcpSocket
    • 지정된 포트에서 컨테이너의 IP주소에 대해 TCP 검사를 수행
    • 포트가 활성화되어 있다면 진단이 성공한 것으로 간주
    • 원격 시스템(컨테이너)가 연결을 연 이후 즉시 닫는다면, 이 또한 진단이 성공한 것으로 간주

Probe 종류 정리

  1. livenessProbe ⇒ 실습 O
    • 컨테이너가 동작 중인지 여부
    • 만약 활성 프로브 (liveness probe) 에 실패한다면, kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 된다.
    • 만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는 Success 이다.
  2. readinessProbe ⇒ 실습 O
    • 컨테이너가 요청을 처리할 준비가 되었는지 여부
    • 만약 준비성 프로브 (readiness probe)가 실패한다면, 엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거한다.
    • 준비성 프로브의 초기 지연 이전의 기본 상태는 Failure 이다.
    • 만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는 Success 이다.
  3. startupProbe
    • 컨테이너 내의 애플리케이션이 시작되었는지 여부
    • 스타트업 프로브 (startup probe) 가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다.
    • 만약 스타트업 프로브가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다.
    • 컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는 Success 이다.

Liveness Probe

Liveness Probe (활성 프로브)

  • 컨테이너가 동작 중인지 여부를 판단
  • 만약 활성 프로브 (liveness probe) 에 실패한다면, kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 됨
  • 만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는 Success
  • Liveness Probe 실패 시
    • 해당 컨테이너를 재시작

Liveness Probe 실습

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
  • Probe 설정
    • 컨테이너의 8080 포트의 /healthz 경로가 성공(Status 200)하면 Probe 성공
    • 첫 번째 프로브를 수행하기 전 3초를 기다림
      • initialDelaySeconds: 3
    • kubelet 이 3초마다 LivenessProbe 를 수행
      • periodSeconds: 3

 

# Pod 확인
watch kubectl get pod -o wide

...
NAME             READY   STATUS    RESTARTS      AGE   IP            NODE          NOMINATED NODE   READINESS GATES
liveness-http    1/1     Running   2 (14s ago)   51s   10.244.1.17   kind-worker   <none>           <none>
...

# Pod 상세 정보
kubectl describe pod liveness-http

...
Events:
  Type     Reason     Age                 From               Message
  ----     ------     ----                ----               -------
  Warning  Unhealthy  19s (x12 over 79s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500
  Normal   Killing    19s (x4 over 73s)   kubelet            Container liveness failed liveness probe, will be restarted
  Warning  BackOff    7s (x3 over 19s)    kubelet            Back-off restarting failed container liveness in pod liveness-http_default(0f16d9a4-b767-410e-8d06-bd802da16b04)
...

 

Readiness Probe

readinessProbe (준비성 프로브)

  • 컨테이너가 요청을 처리할 준비가 되었는지 여부
  • 만약 준비성 프로브 (readiness probe)가 실패한다면, 엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거한다.
  • → 해당 Pod 를 Service 에서 제외하고 다른 Pod 로 요청 전달
  • 준비성 프로브의 초기 지연 이전의 기본 상태는 Failure 이다.
  • 만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는 Success 이다.
  • Readiness Probe 실패시
    • 트래픽이 해당 Pod 로 흐르지 않음
    • Liveness 와는 달리 재기동하지 않음
    • ⇒ 실제 운영 환경에서는 Liveness + Readiness를 같이 써야 한다.

Readiness Probe 실습

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
  • Probe 설정
    • 컨테이너의 8080 포트의 /healthz 경로가 성공(Status 200)하면 Probe 성공
    • 첫 번째 프로브를 수행하기 전 3초를 기다림
      • initialDelaySeconds: 3
    • kubelet 이 3초마다 ReadinessProbe 를 수행
      • periodSeconds: 3

 

# Pod 확인
watch kubectl get pod -o wide

...
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE          NOMINATED NODE   READINESS GATES
readiness-http   0/1     Running   0          19s   10.244.1.18   kind-worker   <none>           <none>
...

# Pod 상세 정보
kubectl describe pod readiness-http

...
Events:
  Type     Reason     Age                 From               Message
  ----     ------     ----                ----               -------
  Warning  Unhealthy  1s (x16 over 43s)  kubelet             Readiness probe failed: HTTP probe failed with statuscode: 500
...

 

 

liveness와는 달리 restart 카운트가 올라가지 않고, Running이긴 하지만 Ready가 아님을 확인

 

Liveness vs Readiness

 

Startup Probe (실습 x)

Startup Probe 설정 시

  • 좀더 유연하게 사용 가능

Liveness Probe 의 initialDelaySeconds만 설정 시

startupProbe

  • 컨테이너 내의 애플리케이션이 시작되었는지 여부
  • 스타트업 프로브 (startup probe) 가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다.
  • 만약 스타트업 프로브가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다.
  • 컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는 Success

Manifest Management

 

  • Manifest
    • Kubernetes 리소스를 정의하는 설정 파일 (YAML)
    • 선언형 파일

Manifest 관리 도구의 필요성

  1. 환경별 구성 분리
    • dev, stg, prd 환경 마다 구성 및 설정이 조금씩 다르게 배포되어야 함
    • 이러한 관리 도구 없이는 모든 YAML 파일을 각각 복사해서 만들어야 하기 때문에 누락, 오타 등의 Human Error 가 발생할 가능성이 커짐
    → 도구 사용을 통해 환경별 차이점만 덮어쓰기 가능
  2. 템플릿화, 변수화
    • 일관된 구조 유지
    • 변경 편리성, 재사용성 향상
  3. 버전 관리 및 롤백
    • Helm, Kustomize 의 자체 버전 관리 기능을 사용하여 변경 이력과 롤백 가능
  4. 자동화 & GitOps 통합

대표적인 Manifest 관리도구

  • Kustomize
    • kubectl 에 기본 내장
    kubectl version
    ...
    Client Version: v1.32.3
    Kustomize Version: v5.5.0
    Server Version: v1.32.2
    ...
    
    • Kubernetes 구성을 사용자 정의화하는 도구
    • 주요 기능
      • 오버레이
      • 공통 설정 재사용
  • Helm
    • 가장 많이 사용 되는 매니페스트 도구
      • kubernetes 사용 시 Helm 사용법은 필수
    • Kubernetes 애플리케이션을 쉽고 체계적으로 배포하고 관리할 수 있게 해주는 일종의 패키지 매니저
    • 주요 기능
      • 템플릿 기반 매니페스트 생성
      • 버전 관리, 업그레이드, 롤백
      • 차트를 통해 재사용 가능
  • 그 외 매니페스트 관리 도구들
    • Kpt
    • Jsonnet

Kustomize

Kustomize 소개

Kustomize

  • Kubernetes Customize (Kustomize) - customize raw, template-free YAML files for multiple purposes
  • 쿠버네티스 리소스(YAML) 를 레이어별로 구성
  • 쿠버네티스 리소스를 변경하지 않고 필드를 재정의하여 새로운 쿠버네티스 리소스를 생성하는 도구
    • Linux sed 명령어와 유사한 동작 방식
  • kustomize Goal & Feature
    • kubectl tooling force users to write their own scripting and tooling to augment the declarative tools with preprocessing transformations.
    • Purely declarative approach to configuration customization
    • Natively built into kubectl
    • Manage an arbitrary number of distinctly customized Kubernetes configurations
    • Available as a standalone binary for extension and integration into other services
    • Every artifact that kustomize uses is plain YAML and can be validated and processed as such
    • Kustomize encourages a fork/modify/rebase workflow

Kustomize 핵심 개념

  • Base
    • Kustomize 를 통해 변경할 yaml 파일이 저장된 디렉토리
    • 재사용이 가능한 yaml 로 구성
      • deployment.yaml, service.yaml 같은 공통 파일
    • Terraform - Module / Helm - Helm Chart 와 유사
  • Overlay
    • Base 에 저장된 yaml 파일에 적용할 kustomization.yaml 이 저장된 디렉토리
    • 환경별 차이점 정의 (dev, stg, prd)
      • overlays/dev, overlays/stg, overlays/prd
  • kustomization.yaml
    • kustomize 가 실행될 때 어떤 필드를 재정의 할 것인가를 설정하는 파일
    • resource, patches, namePrefix, ConfigMapGenerator 등 다양한 설정

Kustomization.yaml 필드

  1. resources : kustomize 를 적용할 yaml 파일
  2. generators : 새로운 필드 생성
  3. transformers : 필드 변경
  4. validators : 검증 - 실패 시 배포 금지
  5. 그 외에도 configMapGenerator , namePrefix , patches 등의 Plug-in 이 존재
  • kustomize 실행 순서
  • resources → generators → transformers → validators

Kustomize 실습

Kustomize 설치

  • kubectl 과 통합되어 있기 때문에 별도의 설치 과정이 필요 없음
    • kustomize build 외 다른 기능을 사용하기 위해서 설치가 필요
  • Kustomize 버전 확인
# Kubectl Version 확인
kubectl version --client

...
Client Version: v1.32.3
Kustomize Version: v5.5.0
...

 

  • kubectl 버전에 통합된 kustomize 버전

  • Kustomize 설치
# 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
choco install kustomize
# 설치 확인
kustomize version

...
v5.6.0
...

Kustomize 기본 사용

  • kustomize 사용을 위한 파일 생성
# 실습 디렉토리 생성
mkdir kustomize && cd kustomize
cat << EOF >> kustomization.yaml
resources:
  - pod.yaml

images:
  - name: nginx
    newName: new-nginx
    newTag: 1.23.1
EOF
cat << EOF >> pod.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: nginx
  name: nginx
spec:
  containers:
  - image: nginx:latest
    name: nginx
    resources:
      limits:
        cpu: 100m
        memory: 64Mi
EOF

 

 

  • kustomize 실행
# Tree 구조 확인
tree .

...
.
├── kustomization.yaml
└── pod.yaml
...

# kustomization.yaml 파일이 있는 PATH 실행
kubectl kustomize <PATH>

# 현재 Directory 에서 실행
kubectl kustomize .

...
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: nginx
  name: nginx
spec:
  containers:
  - image: new-nginx:1.23.1
    name: nginx
    resources:
      limits:
        cpu: 100m
        memory: 64Mi
...

[참고] Window (WSL2) 사용 시 tree 명령어

apt install tree # version 2.1.1-2

로 설치 후 사용 가능하였습니다.

 

기존 pod.yaml 가 변경된 걸까?

# kustomize 결과를 파일로 추출
kubectl kustomize . > pod-kustomize.yaml

# 기존 Pod 파일과 차이 확인
diff pod.yaml pod-kustomize.yaml

 

 

  • BASE가 되는 파일이 하나 있으면, 이름을 환경에 따라 바꿔가며 배포를 할 수 있다.
  • kustomize 리소스 생성
# 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
  • Kustomize 리소스 삭제
kubectl kustomize . | kubectl delete -f -

 

Kustomize 심화 - kustomization 필드 활용

Resource 필드

  • 특정 yaml 파일을 kustomization 설정에 따라 변경하고자 할 때 사용
  • 같은 경로라도 kustomization 에 지정되어 있지 않으면 적용 대상이 아님
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

 

  • kustomize 실행
tree .

...
.
├── kustomize.yaml
├── pod-1.yaml
├── pod-2.yaml
└── service.yaml
...

kubectl kustomize .

 

  • resource에 선언이 되어 있어야 kustomize의 대상이 된다.
  • 즉 다음과 같이 kustomization.yaml의 내용을 수정하면 pod-2도 나온다.

Transformers 필드

  • 필드값을 변경하는 기능
  • 다양한 빌트인 존재
  • Namespace 변경
kubectl create ns test

cat << EOT > kustomization.yaml
namespace: test
resources:
  - pod-1.yaml
  - service.yaml
EOT

kubectl kustomize .

 

  • Image Tag 변경
cat << EOT > kustomization.yaml
namespace: test
images:
  - name: nginx
    newTag: 1.23.1
resources:
  - pod-1.yaml
  - service.yaml
EOT

# kustomize 실행
kubectl kustomize .

 

  • 원래 latest였는데, 1.23.1로 변경되었다.

Kustomize 심화 - Base / Overlays 개념 활용

Base / Overlays 개념

  • Base
    • kustomize 를 통해 변경할 yaml 파일이 저장된 디렉토리
    • 재사용이 가능한 yaml 로 구성
    • Terraform 에서는 Module , Helm 에서는 Helm Chart 와 유사한 기능
  • Overlays
    • Base 에 저장된 yaml 파일에 적용할 kustomization.yaml 이 저장된 디렉토리
    • 단계별 분리 - overlays/prd , overlays/dev , overlays/stg
    • 유사한 k8s 리소스가 많을 수록 용이

실습

  • 새로운 실습 디렉토리 이동
cd .. && mkdir kustomize-2 && cd kustomize-2

# 실습 디렉토리 구성
mkdir -p base overlays/dev overlays/prd

tree .
...
.
├── base
└── overlays
    ├── dev
    └── prd
...

  • Base 생성
# 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
  • Overlays 생성 - dev
cat << EOT > ./overlays/dev/kustomization.yaml
resources:
- ../../base
namePrefix: dev-
EOT

cat << EOT > ./overlays/prd/kustomization.yaml
resources:
- ../../base
namePrefix: prd-
EOT
tree .

# 현재 디렉토리 구조
.
├── base
│   ├── kustomization.yaml
│   └── pod.yaml
└── overlays
    ├── dev
    │   └── kustomization.yaml
    └── prd
        └── kustomization.yaml

 

# dev kustomize 실행
kubectl kustomize overlays/dev

# prd kustomize 실행
kubectl kustomize overlays/prd

 

Helm

Helm 소개

Helm 구조

 

  • Chart
    • Helm 에서 사용 되는 패키지
    • 애플리케이션, 도구, 서비스를 구동하는 데 필요한 모든 리소스 정의가 포함
      • Kubernetes 리소스들(Deployment, Service 등)
    • yum, apt, brew 기능과 유사
  • Repository
    • 헬름 차트를 모아두고 공유하는 장소
    • 공유 저장소
      • Artifact Hub - Link
    • 설치형
  • Release
    • Helm Chart를 실제 Kubernetes 클러스터에 배포한 인스턴스
    • 하나의 Chart로 여러 개의 Release를 만들 수 있음 (예: myapp-dev, myapp-prod)
  • Values
    • values.yaml 또는 커맨드라인에서 전달하는 사용자 정의 값
    • 템플릿 파일 내의 변수들을 바인딩하여 동적인 리소스 생성 가능

Helm 실습

Helm 설치

# Mac Homebrew 설치
brew install helm

# Windows Chocolatey
choco install kubernetes-helm

# Helm Version 확인
helm version
helm version --short

[참고]

curl <https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3> | bash 

명령어로 설치하였습니다.

Helm 기본 사용

# Helm 디렉토리 이동
mkdir helm-practice

# Helm Repo 확인
helm repo ls

# Helm 생성
helm create mychart
# Helm 구조 확인
cd mychart
tree .

...
.
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml
...

  • Helm 배포
# Helm 배포
# helm install <RELEASE_NAME> <패키지 경로> [flags]
helm install myapp .

# Helm Release 확인
helm list

# Helm 으로 배포된 리소스 확인
kubectl get po,deploy,svc,sa

# Helm 삭제
helm delete myapp

 

Helm 심화 - Values.yaml 활용

Values.yaml

  • 템플릿 파일 내의 변수들을 바인딩하여 동적인 리소스 생성 가능
  • values.yaml 을 통해 환경 분리 가능
    • dev, stg, prd
  • 실습
# Community Repository 추가
helm repo add bitnami <https://charts.bitnami.com/bitnami>

# Helm Repo 조회
helm repo ls
...
NAME   	URL
bitnami	<https://charts.bitnami.com/bitnami>
...

# Bitnami 의 Helm Chart 조회
helm search repo bitnami

# Helm Nginx 설치
# 최신 차트 정보를 가져오도록 하는 명령어
helm repo update

# Helm
# helm install   [flags]
helm install mynginx bitnami/nginx

kubectl describe deploy mynginx
kubectl describe deployments.apps mynginx | grep 'Containers:' -A5

 

  • 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
...
Version 이 올라감
...

 

 

  • 현업에서 쿠버네티스를 사용할 때는 인증된 차트 공급자의 파일을 가져와서 values.yaml 을 내 환경에 맞게 수정하여 사용 하거나 Helm Chart 를 새로 작성하여 배포하는 형식으로 사용
    • 공급자 파일을 가져오는 경우 : OpenSource (ArgoCD, Metrics Server, Nginx Ingress Controller 등)
    • Helm Chart 를 생성하는 경우 : Application 배포용 (NextJS, SpringBoot)

Custom Helm Chart 를 생성하기 위한 Helm Template 문법 - Link

GitOps

GitOps 개념

GitOps 개념

GitOps

  • GitOps 는 Flux 를 개발한 웨이브웍스 (Weaveworks) 직원들2017년 처음 사용
  • 본인이 원하는 환경을 선언적으로 정의하기 위해 깃 리포지터리를 사용하는 것
  • 버전 관리병합 요청을 통해 변경하는 방식으로 전체 시스템 감시
  • Git 을 중심으로 한 운영 및 배포 자동화 방식
  • 인프라 및 애플리케이션 설정을 Git 저장소에 선언적으로 정의하고 이를 기반으로 클러스터 상태를 자동으로 동기화 및 관리하는 방식
  • GitOps 특성상 애플리케이션 자체의 소스코드와 (CI) 배포에 해당되는 소스코드를 (CD) 별개로 관리하는 것이 일반적
    • 배포 시 리소스나 런타임 설정만 변경할 경우 애플리케이션의 빌드 없이 빠르게 배포 및 롤백이 가능

GitOps 핵심 개념

  • Git : 단일 진실 원천 (SSOT, Single Source of Truth) 로 사용. 모든 설정은 Git 에 저장
  • 선언형 인프라 : YAML 로 원하는 상태를 정의
  • 자동 동기화 : Git 의 선언형 파일과 클러스터 상태를 자동으로 일치
  • 자동 롤백 및 감사 : Git 을 통한 History 추적 및 승인 절차 적용

GitOps 도입 시 고려사항

  • 관찰 가능성 (Observability)고가용성 (High Availability) 염두
  • CI/CD 파이프라인 고민
  • 조직 부서 별, 팀 별 관리 및 설정 통합 고민
  • Namespace 별 RBAC (역할 기반 접근 제어) 구성

ArgoCD

ArgoCD 개념

 

  • ArgoCD 는 Git 을 배포의 원천으로 사용하는 GitOps CD 도구
  • Git에 작성된 매니페스트 기반으로 쿠버네티스의 리소스 상태를 일치 시키므로 선언적인 리소스 관리 가능
  • Argo Rollouts 이나 Argo CD Notifications 등을 추가로 적용해 다양한 배포 전략을 사용하거나 배포 관련 알림을 설정 하는 등의 확장성 보유

ArgoCD 아키텍처

  • ArgoCD 핵심 구성 요소는 쿠버네티스 컨트롤러로 구성
  • 쿠버네티스 컨트롤러 작동 방식 - 현재 상태를 의도한 상태와 비슷하게 유지
    1. 클러스터 상태 관찰
    2. 필요한 경우 변경 사항을 적용하거나 요청
  • ArgoCD 는 GitOps 핵심 도구이기 때문에 동작 방식이나 확장 플러그인 등의 관련 내용이 상당히 많다. → 지긍늠 ArgoCD 가 어떤 역할을 하는 지 간단하게 작동하는 방법만 살펴봄
  • 추천) 예제로 배우는 ArgoCD
  • 참고) Certified Argo Project Associate (CAPA)

ArgoCD 설치

Helm 설치

# 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 접속

# 초기 비밀번호 확인
kubectl -n argocd get secrets argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

...
0DtTrgRUaKfy7FPu
...

# ArgoCD UI 접근
open <http://localhost:31001>
  • Windows 사용자 (Port-forwarding)
    • WSL2 + Docker Desktop 환경이며 로컬 PC 가 컨테이너 내부 포트로 접근하지 못할 때
    • kubectl port-forward 명령어 사용
    kubectl port-forward -n argocd service/argocd-server 31001:80

[참고]

kubectl port-forward -n argocd svc/argocd-server 31001:80

위 명령어 사용하였습니다.

 

  • 초기 접근 정보
    • ID: admin
    • PW: 위에서 나온 Hash 값

ArgoCD를 통한 Application 배포

  • 본인 Github public repository 생성
    • 실제로는 Private Repository 를 사용하고, ArgoCD 와 연동하는 과정이 필요하나 편의를 위해 Public Repository 사용
  • Local 에 Git Clone 후 Helm Push
# 본인 Repository 클론
git clone <https://github.com/>{깃허브 username}/argocd-knou.git

# Helm Chart 생성
helm create argo-test-chart

# Git Push
git add . && git commit -m "Initial Commit" && git push origin main

 

  • ArgoCD 연동

 

  • Application 정보 입력
    • Application Name : custom-nginx
    • Project: default
    • Sync Policy: Automatic

  • Application Source 입력
    • Repository URL : https://github.com/{깃허브 username}/argocd-knou.git
    • Revision: main
    • Path: argo-test-chart

  • ArgoCD 를 통해 배포할 Cluster 정보 입력

  • 배포할 Helm Values.yaml 파일 선택

  • 배포 성공

 

values.yaml 변경

# values 파일 변경
vim values.yaml

...
replicaCount: 2

image:
  repository: nginx
  tag: "1.24"
...

# Git push
git add . && git commit -m "Values Modified" && git push

  • ArgoCD 에서 Refresh & Sync
    • cf) ArgoCD Default 동기화(조정, Reconciliation) 주기는 3분(180s)

실습 환경 제거

kind get clusters

kind get clusters

마무리…

  • 4주간 배운 내용
    • Docker
      • 도커 개념 및 아키텍처
      • 도커 명령어 및 네트워크
      • 도커 빌드 방법 및 최적화
    • Kubernetes
      • 쿠버네티스 개념 및 아키텍처
      • 쿠버네티스 명령어
      • 쿠버네티스 리소스 (namespace, pod, deployment)
      • 쿠버네티스 가용성 향상 방법 (hpa, vpa)
      • 쿠버네티스 어플리케이션 설정 관리 (ConfigMap, Secret)
      • 쿠버네티스 네트워크 Service, Ingress (ClusterIP, NodePort)
      • 쿠버네티스 헬스체크 (Probe)
      • 매니페스트 관리 도구 (Kustomize, Helm)
      • GitOps 개념 및 ArgoCD 기본