본문 바로가기

K8S

쿠버네티스(Kubernetes) Pod 설계 디자인

728x90

■ Pod 설계 디자인

  • single-container design pattern
    • 하나의 파드 안에 하나의 컨테이너가 동작하는 형태. 
    • 가장 일반적인 형태 

  • multi-container design pattern
    • 하나의 파드 안에 여러개의 컨테이너가 동작하는 형태 
    • 파드에 포함되어 있는 컨테이너는 IP / Port를 공유하기 때문에 같은 Port를 사용하는 서비스와 같이 배포해서는 안된다
    • 전체 서비스를 기능 단위로 분산하고 파드를 최소 배포 단위로 구성하는 쿠버네티스 설계 사상에 맞춰 밀접한 연관성을 가지는 서비스와 묶어서 배포 해야 한다. 
    • 멀티-컨테이너 구성은 메인 프로세스를 네트워크 또는 스토리지의 밀접한 공유가 필요한 다른 컨테이너와 함께 운영하고자 할 때 적합하다.

 

■ 멀티-컨테이너 설계 디자인 종류 

  • 사이드카(Sidecar) 디자인 패턴 
    • 사이드가 디자인은 메인 애플리케이션과 보조 애플리케이션으로 이루어 지고, 사이드카 컨테이너는 파드 시작 이후에도 계속 작동 합니다. 
    • 파드의 파일시스템을 공유하는 형태의 보조 컨테이너 사이드카 컨테이너라고 부른다. 
    • 로깅 서비스, 동기화 서비스, 모니터링 서비스와 같은 메인 애플리케이션을 보조하는 역할을 수행 한다. 사이드카 컨테이너를 활용하면 코드 분리를 수행하며 결과적으로 메인 애플리케이션의 성능을 유지하고 확장성과 보안을 단순화하여 배포를 향상 시킬 수 있음. 
    • 예제 보기

  • 어댑터(Adapter) 디자인 패턴
    • 파드에 탑재된 특정 애플리케이션의 출력물 규격을 필요에 맞게 다듬는 용도로 사용 된다. 
    • 사용하는 솔루션에 따라 날자/시간의 출력값이 다를 경우, 중앙 모니터링 시스템 또는 중앙 로그 수집 장치에서 문제가 발생함.
    • 어댑터 컨테이너에서 이러한 값을 정제하여 외부로 전달 하기 때문에 메인 애플리케이션에서는 별도로 수정이 필요하지 않다

 

  • 앰버서더(Ambassador) 디자인 패턴
    • 파드 외부의 서비스에 대한 엑세스를 간소화하는 특수한 유형의 컨테이너, 메인 컨테이너가 수행해야 할 네트워크 통신을 대신해주는 역할을 수행 한다.
    • In / Out 통신 모두 앰버서더 컨테이너를 통해야 하며, 이러한 구성으로 앰버서더 컨테이너는 메인 컨테이너의 네트워크를 전담하는 프록시 역할을 수행 한다.

  • 초기화(Init) 디자인 패턴
    • 초기화 컨테이너는 파드의 앱 컨테이너들이 실행되기 전에 실행되는 특수한 컨테이너이며,  초기화 컨테이너는 앱 이미지에는 없는 유틸리티 또는 설정 스크립트 등을 포함할 수 있다
    • restartPolicy 정책이 Always 일 경우: 파드의 초기화 컨테이너가 실패하면, kubelet은 초기화 컨테이너가 성공할 때까지 반복적으로 재시작 수행.
    • restartPolicy 정책이 Never 일 경우: 해당 파드를 시작하는 동안 초기화 컨테이너가 실패하면, 쿠버네티스는 전체 파드를 실패한 것으로 처리
    • 초기화 컨테이너는 파드가 준비 상태가 되기 전에 완료를 목표로 하며, 만약 Pod안에 다수의 초기화 컨테이너가 포함되어 있다면 kubelet은 초기화 컨테이너를 순차적으로 수행 한다. 
    • 예제 보기

 


 

■ 초기화(Init) 디자인 패턴 예제

  • 초기화 컨테이너 생성 예제 코드
# vi init_container.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app.kubernetes.io/name: MyApp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
  1. init-myservice
    • 메인 애플리케이션 (myapp-pod)가 실행 되기 전에 먼저 실행되는 초기화 컨테이너
    • DNS 질의를 통해 myservice 서비스가 조회 될 때 까지 대기 합니다.
    • 명령어 실행 구문 분석
      • until: 조건이 충족 될 때까지 반복문을 계속 수행 합니다
      • nslookup myservice. ~~~~ local;: "myservice"에 대한 DNS 질의를 쿠버네티스의 동일한 namespace안에서 수행 합니다. 
      • do echo ~~ done: DNS 질의에 실패할 경우 waiting for myservice 문구를 보냅니다. 
      • 해당 반복문은 DNS 질의를 성골 할 때 까지 반복적으로 수행 합니다. 
  2. init-mydb
    • init-myservice와 전체적인 내용은 동일 합니다. 

 

  • 코드 적용 및 세부 내용 확인 
    • 코드 적용: kubectl apply -f init_container.yaml
    • 간략 내용: kubectl get -f init_container.yaml 
    • 세부 내용: kubectl describe pod myapp-pod
# 초기화 컨테이너 간략 내용
kubectl get -f init_container.yaml
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          24m

 

# myapp-pod 세부 내용 확인
kubectl describe pod myapp-pod
    [생략]
Init Containers:
  init-myservice:
    [생략]
    State:          Running
      Started:      Sat, 03 Aug 2024 11:13:10 +0900
    Ready:          False
    [생략]
  init-mydb:
    [생략]
    State:          Waiting
      Reason:       PodInitializing
    [생략]
Containers:
  myapp-container:
    [생략]
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
Conditions:
  Type              Status
  Initialized       False
  Ready             False
  ContainersReady   False
  PodScheduled      True
[생략]

 

  • 서비스 생성 (초기화 컨테이너에서 NSLOOKUP으로 조회하는 대상) 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

 

  • 서비스 검증
    • 초기화 컨테이너에서 nslookup으로 조회하던 항목들이 모두 정상적으로 조회 성공
    • 초기화 컨테이너가 모두 실행 된 이후 myapp-pod 컨테이너 실행 
# 컨테이너 생성 상태 확인 
kubectl get -f init_container.yaml
NAME        READY   STATUS    RESTARTS   AGE
myapp-pod   1/1     Running   0          39m


# myservice 조회 
kubectl exec -n default myapp-pod -- nslookup myservice
Name:      myservice
Address 1: 10.104.114.71 myservice.default.svc.cluster.local

kubectl exec -n default myapp-pod -- nslookup mydb
Name:      mydb
Address 1: 10.97.78.124 mydb.default.svc.cluster.local

 

사이드카 디자인 패턴 예제

  • 사이드카 컨테이너 생성 예제
apiVersion: v1
kind: Pod
metadata:
  name: log-pod
spec:
  containers:
  - name: app-container
    image: nginx
    volumeMounts:
    - name: html-log
      mountPath: /usr/share/nginx/html
  - name: sidecar-container
    image: nginx
    volumeMounts:
    - name: html-log
      mountPath: /data-log
    command: ["sh", "-c"]
    args:
      - while true; do
          date >> /data-log/index.html;
          sleep 1;
        done
  volumes:
  - name: html-log
    emptyDir: {}

 

  • 메인 애플리케이션 (app-container)와 보조 애플리케이션(sidecar-container) 동일한 마운트 위치 설정
  • 보조 애플리케이션에서 발생한 이벤트를 메인 애플리케이션에서 표기 할 수 있도록 설정 

 

  • 코드 적용 및 세부 내용 확인 
    • 코드 적용: kubectl apply -f sidecar_container.yaml
    • 간략 내용: kubectl get -f sidecar_container.yaml
    • 세부 내용: kubectl describe pod log-pod
# 사이드카 컨테이너 간략 확인

kubectl get -f sidecar_container.yaml
NAME      READY   STATUS    RESTARTS   AGE
log-pod   2/2     Running   0          26m

 

# log-pod 세부 내용 확인 

kubectl describe pod log-pod
Name:             log-pod
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8snode3/192.168.56.13
[생략]
IPs:
  IP:  10.101.174.143
Containers:
  app-container:
    [생략]
    State:          Running
      Started:      Sun, 04 Aug 2024 21:49:09 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /usr/share/nginx/html from html-log (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pp6mx (ro)
  sidecar-container:
    [생략]
    State:          Running
      Started:      Sun, 04 Aug 2024 21:49:10 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /data-log from html-log (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pp6mx (ro)

 

  • 서비스 검증
    • 사이드카 컨테이너에서 생성한 date 정보 확인 (메인 / 보조 컨테이너에서 수행)
# 메인 애플리케이션 정보 확인
kubectl exec -n default log-pod -c app-container  -- tail -f /usr/share/nginx/html/index.html

# 보조 애플리케이션 정보 확인
kubectl exec -n default log-pod -c sidecar-container  -- tail -f /data-log/index.html

참조

https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/

https://www.linkedin.com/pulse/8-k8s-pod-container-design-patterns-mbong-ekwoge

https://seongjin.me/kubernetes-multi-container-pod-design-patterns/

728x90