카테고리 없음

[k8s] Docker&K8s -4

ride-dev 2025. 5. 18. 16:46

1. Pod LifeCycle

파드는 정의된 생명주기 단계를 따릅니다.

Pending 단계에서 시작,

기본 컨테이너 중 적어도 하나 이상이 OK로 시작하면 Running 단계를 통과하고,

파드 컨테이너  종료 시 성공/실패 여부에 따라 Succeeded/Failed 단계로 이동합니다.

 

1.1 파드의 단계

각 단계에 대한 세부 설명은 아래와 같습니다.

의미
Pending 파드가 쿠버네티스 클러스터에서 승인되었지만,
하나 이상의 컨테이너가 설정되지 않았고 실행할 준비가 되지 않았다.
여기에는 파드가 스케줄되기 이전까지의 시간 뿐만 아니라
네트워크를 통한 컨테이너 이미지 다운로드 시간도 포함된다.
Node를 사용할 수 없는 상태
Container를 생성하기 위한 자원이 보족한 상태
Container Image를 아직 가져오지 못한 상태
Running 파드가 노드에 바인딩되었고, 모든 컨테이너가 생성되었다.
적어도 하나의 컨테이너가 아직 실행 중이거나,
시작 또는 재시작 중에 있다.
Succeded 파드에 있는 모든 컨테이너들이 성공적으로 종료되었고,
재시작되지 않을 것이다.
Failed 파드에 있는 모든 컨테이너가 종료되었고,
적어도 하나 이상의 컨테이너가 실패로 종료되었다.
즉, 해당 컨테이너는 non-zero 상태로 빠져나왔거나(exited)
시스템에 의해서 종료(terminated)되었다.
Unkown 어떤 이유에 의해서 파드의 상태를 얻을 수 없다.
일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생한다.

파드가 실행되는 동안 kubelet은 일종의 오류를 처리하기 위해 컨테이너를 다시 시작할 수 있으며,

쿠버네티스는 파드내에서 다양한 컨테이너 상태를 추적하고

파드를 다시 정상 상태로 만들기 위해 취할 조치를 결정합니다.

1.2. 컨테이너 프로브(Probe)

프로브는 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단(diagnostic)입니다.

이런 기능을 통해 서비스의 가용성, 신뢰성을 확보할 수 있습니다.

kubelet은 진단을 수행하기 위해,

컨테이너 안에서 코드를 실행하거나 네트워크 요청을 전송합니다.

체크 메커니즘

프로브를 사용하여 컨테이너를 체크하는 방법은 4가지가 있으며,

각 프로브는 각 메커니즘 중 하나만 정의해야 합니다.

exec

컨테이너 내에서 지정된 명령어를 실행합니다.

명령어가 상태 코드 0으로 종료되면 진단이 성공한 것으로 간주합니다.

grpc

gRPC를 사용하여 원격 프로시저 호출을 수행합니다.

체크 대상이 gRPC 헬스 체크를 구현해야 합니다.

응답의 status 가 SERVING 이면 진단이 성공했다고 간주합니다.

gRPC 프로브는 알파 기능이며

GRPCContainerProbe 기능 게이트(Feature Gate)를 활성화해야 사용할 수 있습니다.

httpGet

지정한 포트 및 경로에서 컨테이너의 IP주소에 대한 HTTP GET 요청을 수행합니다.

응답의 상태 코드가 200 이상 400 미만이면 진단이 성공한 것으로 간주합니다.

주로 사용되며, SpringBoot Actuator와 연동됩니다.

tcpSocket

지정된 포트에서 컨테이너의 IP주소에 대해 TCP 검사를 수행합니다.

포트가 활성화되어 있다면 진단이 성공한 것으로 간주합니다.

원격 시스템(컨테이너)가 연결을 연 이후 즉시 닫는다면, 이 또한 진단이 성공한 것으로 간주합니다.

프로브 결과

각 probe는 다음 세가지 결과 중 하나를 가집니다.

Success

컨테이너가 진단을 통과

Failure

컨테이너가 진단에 실패

Unkown

진단 자체가 실패

아무런 조치를 수행해서는 안 됨

kubelet이 추가 체크를 수행

프로브 종류

kubelet은 실행중인 컨테이너들에 대해 선택적으로 세 가지 종류의 프로브를 수행합니다.

livenessProbe

컨테이너가 동작 중인지 여부

만약 활성 프로브 (liveness probe) 에 실패한다면,

kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 됩니다.

만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는 Success 입니다.

readinessProbe

컨테이너가 요청을 처리할 준비가 되었는지 여부

만약 준비성 프로브 (readiness probe)가 실패한다면,

엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거합니다.

(재기동하지 않으며, 트래픽을 차단합니다)

준비성 프로브의 초기 지연 이전의 기본 상태는 Failure 입니다.

만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는 Success 입니다.

startupProbe

컨테이너 내의 애플리케이션이 시작되었는지 여부

스타트업 프로브 (startup probe) 가 주어진 경우,

성공할 때까지 다른 나머지 프로브는 활성화되지 않습니다.

만약 스타트업 프로브가 실패하면,

kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리됩니다.

컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는 Success 입니다.

프로브 설정

livenessProbe

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

컨테이너 시작 후 3초 후에 상태를 확인합니다.

이후, 3초마다 LivenessProbe를 수행합니다.

컨테이너 8080 포트의 /healthz 경로가 Status 200 이면 Probe가 성공으로 간주합니다.

# 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)
...

readinessProbe

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

컨테이너 시작 후 3초 후에 상태를 확인합니다.

이후, 3초마다 LivenessProbe를 수행합니다.

컨테이너 8080 포트의 /healthz 경로가 Status 200 이면 Probe가 성공으로 간주합니다.

# 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
...

StartupProbe

좌: LivenessProbe, 우:Startup Probe, 출처:https://www.openmaru.io/kubernetes-%EC%97%90%EC%84%9C-pod-%EC%97%90-%EB%8C%80%ED%95%9C-%ED%97%AC%EC%8A%A4%EC%B2%B4%ED%81%AC-probe/

Startup Probe는 설정된 최대 시간보다 빠르게 서비스 할 수 있습니다.

Startup Probe가 한 번 성공하면, Liveness Probe 를 동작시킬 수 있습니다.

ports:
- name: liveness-port
  containerPort: 8080

livenessProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 1
  periodSeconds: 10

startupProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 30
  periodSeconds: 10

2. Helm

헬름은 패키지 관리를 통해 쿠버네티스 애플리케이션 관리를 편하게 해주는 오픈소스 프로젝트입니다.

Helm Chart라는 패키징 형식을 사용하여 애플리케이션 배포를 자동화합니다.

How does Helm work? 출처: https://everythingdevops.dev/intro-to-helm-charts-for-complete-beginners/

2.1. Helm Chart

Helm Chart는 쿠버네티스 클러스터의 리소스를 정의하고,

이를 애플리케이션으로 패키징하는 파일들의 모음입니다.

Helm Chart를 설치할 때마다 Release라는 인스턴스가 생성됩니다.

Helm Chart는 새 Release에 따라 관리되며,

이전 버전의 Chart를 사용하며 원하는 구성을 할 수 있습니다.

주요 개념은 다음과 같습니다.

Chart

애플리케이션 메타데이터(이름, 버전, 의존성 등)를 Chart.yaml에 정의합니다.

Repository

Helm Chart를 모아두고 공유하는 장소입니다.

공유저장소: Artifact Hub

설치형: Harbor

Release

Helm Chart를 실제 쿠버네티스 클러스터에 배포한 인스턴스입니다.

하나의 Chart로 여러 개의 Release를 만들 수 있습니다.

Values

Chart에 사용할 값들을 values.yaml에 정의하거나 cmd로 전달하여 사용합니다.

템플릿 파일 내의 변수를 바인딩하여 동적인 리소스를 생성할 수 있습니다.

Template Directory

템플릿을 보관하고, 이를 values.yaml 파일에 설정된 값과 결합하여 manifests를 생성합니다.

Chart Directory

Chart.yaml에 정의한 의존성을 

helm dependency build 또는 helm dependency update를 통해 재구성&저장합니다.

실습

설치

# Mac Homebrew 설치
brew install helm

# Windows Chocolatey
choco install kubernetes-helm

# script
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

#apt
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

#dnf
sudo dnf install 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 .

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

(tree 라이브러리 필요) 

brew install tree

sudo apt install tree

sudo yum install tree

배포

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

# Helm Release 확인
helm list

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

# Helm 삭제
helm delete myapp

Values.yaml 활용

# 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 <RELEASE_NAME> <CHART 경로> [flags]
helm install mynginx bitnami/nginx

kubectl describe deploy mynginx
kubectl describe deployments.apps mynginx | grep 'Containers:' -A5
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 이 올라감
...

인증된 Chart 공급자의 파일을 가져와서 values.yaml을 사용자의 환경에 맞게 수정하여 사용하거나,

Helm Chart를 새로 작성하여 배포하는 형식으로 사용할 수 있습니다.

공급자 파일을 가져오는 경우 : OpenSource (ArgoCD, Metrics Server, Nginx Ingress Controller 등)

Helm Chart 를 생성하는 경우 : Application 배포용 (NextJS, SpringBoot)

Custom Helem Chart 생성

3. GitOps

3.1. GitOps 개념

출처: https://docs.kakaocloud.com/blog/240524-gitops

GitOps 는 본인이 원하는 환경을 선언적으로 정의하기 위해 깃 리포지터리를 사용하는 것으로,

버전 관리와 병합 요청을 통해 변경하는 방식으로 전체 시스템을 감시할 수 있습니다.

Flux 를 개발한 웨이브웍스 (Weaveworks) 직원들이 2017년 처음 사용했습니다.

Git 을 중심으로 한 운영 및 배포 자동화 방식입니다.

인프라 및 애플리케이션 설정을 Git 저장소에 선언적으로 정의하고,

이를 기반으로 클러스터 상태를 자동으로 동기화 및 관리하는 방식입니다.

GitOps 특성상 애플리케이션 자체의 소스코드와 (CI)

배포에 해당되는 소스코드를 (CD) 별개로 관리하는 것이 일반적입니다.

배포 시 리소스나 런타임 설정만 변경할 경우,

애플리케이션의 빌드 없이 빠르게 배포 및 롤백이 가능합니다.

핵심개념

Git : 단일 진실 원천 (SSOT, Single Source of Truth) 로 사용. 모든 설정은 Git 에 저장

선언형 인프라 : YAML 로 원하는 상태를 정의

자동 동기화 : Git 의 선언형 파일과 클러스터 상태를 자동으로 일치

자동 롤백 및 감사 : Git 을 통한 History 추적 및 승인 절차 적용

GitOps 도입 시 고려사항

관찰 가능성 (Observability)고가용성 (High Availability) 염두

CI/CD 파이프라인 고민

조직 부서 별, 팀 별 관리 및 설정 통합 고민

Namespace 별 RBAC (역할 기반 접근 제어) 구성

3.2. ArgoCD

ArgoCD는 Git을 배포의 원천으로 사용하는 GitOps CD 도구입니다.

Git에 작성된 매니페스트 기반으로 쿠버네티스의 리소스 상태를 일치 시키므로,

선언적인 리소스 관리가 가능합니다.

Argo Rollouts 이나 Argo CD Notifications 등을 추가로 적용하여,

다양한 배포 전략을 사용하거나 배포 관련 알림을 설정 하는 등의 확장성을 지녔습니다.

출처: https://argo-cd.readthedocs.io/en/stable/

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 \
  --set server.service.nodePort=31001 \
  --namespace argocd \
  --create-namespace

# ArgoCD 서비스 접근을 위한 포트포워딩(로컬용)
kubectl port-forward svc/argocd-server -n argocd 8080:443

# 리소스 확인
kubectl get all -n argocd

(nodePort가 열려있는지 확인하도록 합니다)

접속

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

...
초기비밀번호
...

# ArgoCD UI 접근
open http://localhost:8080

ID: admin

PW: 위에서 나온 Hash 값

생성 - Helm

Application Name : mynginx

Project: default

Sync Policy: Automatic

Application Source 입력

Repository URL : https://charts.bitnami.com/bitnami

Chart: nginx / Version: 20.0.1

생성 - GitHub Project

# 본인 Repository 클론
git clone https://github.com/Min-SungJo/argocd.git

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

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

Application 정보 입력

Application Name : custom-nginx

Project: default

Sync Policy: Automatic

Application Source 입력

Repository URL : https://github.com/Min-SungJo/argocd.git

Revision: main

Path: argo-test-chart

배포할 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(기본적인 주기는 180s 입니다)

 

실습환경을 제거합니다.

kind get clusters

kind delete cluster
728x90
반응형