클라우드 컴퓨팅/쿠버네티스

Kubernetes Application Lifecycle Management

espossible 2021. 9. 11. 16:35

Deployment Rollout and Versioning

Use kubectl rollout to inspect a rollout as it occurse, to pause and resume a rollout, to rollback an update, and to view an object's rollout history

 

디플로이먼트 업데이트 상태 확인

kubectl rollout status deployment nginx
--
Waiting for rollout to finish: 2 out of 3 newreplicas have been updated...
deployment "nginx" successfully rolled out

디플로이먼트 업데이트 히스토리 확인

kubectl rollout history deployment nginx (--revision 3)

디폴로이먼트 변경 롤백

- 명령어의 인수로 버전 번호를 지정할 수 있으며, 0으로 지정하거나 지정하지 않을 경우에는 바로 이전 버전으로 롤백하게 된다.

kubectl rollout undo deployment nginx (--to-revision 3)

- 실제 환경에서는 롤백 기능을 사용하는 경우가 많지 않다. CI/CD 파이프라인에서 롤백을 하는 경우 kubectl rollout 명령어보다 이전 매니페스트를 다시 kubectl apply 명령어로 실행하여 적용하는 것이 호환성 면에서 더 좋기 때문이다.

 

Note: A Deployment's revision is created when a Deployment's rollout is triggered. This means that the new revision is created if and only if the Deployment's Pod template (.spec.template) is changed, for example if you update the labels or container images of the template. Other updates, such as scaling the Deployment, do not create a Deployment revision, so that you can facilitate simultaneous manual- or auto-scaling. This means that when you roll back to an earlier revision, only the Deployment's Pod template part is rolled back.

출처
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-back-a-deployment

 

디플로이먼트 업데이트 일시 중지

kubectl rollout pause deployment nginx

디플로이먼트 업데이트 일시 정지 해제

kubectl rollout resume deployment nginx

 

Deployment Update Strategy

- Recreate : 모든 파드를 한 번 삭제하고 다시 파드를 생성하기 때문에 다운타임이 발생하지만, 추가 리소스를 사용하지 않고 전환이 빠른 것이 장점이다. 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment-recreate
spec:
  strategy:
    type: Recreate
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: nginx
          image: nginx

- Rolling update(default) : 업데이트 중에 동시에 정지 가능한 최대 파드 수(maxUnavailable)와 업데이트 중에 동시에 생성할 수 있는 최대 파드 수(maxSurge)를 설정할 수 있다. 이 설정을 사용하여 추가 리소스를 사용하지 않도록 하거나 많은 리소스를 소비하지 않고 빠르게 전환하는 등 업데이트를 하면서 동작을 제어할 수 있다. maxUnavailable과 maxSurge를 모두 0으로 설정할 수는 없다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment-rollingupdate
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: nginx
          image: nginx

 


Kubernetes command & args

Definition에 기술된 command와 args는 Dockerfile에 있는 각각 Entrypoint와 CMD를 override 한다.

- command : override entrypoint instruction

- args : override cmd instruction

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-sleeper-pod
spec:
  containers:
    - name: ubuntu-sleeper
      image: ubuntu-sleeper
      command: ["sleep", "500"] #override entrypoint instruction
      args: ["10"] #override CMD instruction

(참고) 아래와 같은 형태도 가능

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-sleeper-pod
spec:
  containers:
    - name: ubuntu-sleeper
      image: ubuntu-sleeper
      command:
      - "sleep"
      - "1200"
      args: ["--color=green"]

 

예시) Dockerfile에서 실행될 명령 : --color green

FROM python:3.7-alpine

...

ENTRYPOINT ["python", "app.py"]

CMD ["--color", "red"]
apiVersion: v1
kind: Pod
metadata:
  name: webapp-green
  labels:
    name: webapp-green
spec:
  containers:
  - name: simple-webapp
    image: xxx
    command: ["--color", "green"]

 


Configuring Application

쿠버네티스에서 개별 컨테이너의 설정 내용은 환경 변수나 파일이 저장되어 있는 영역을 마운트 하여 전달하는 것이 일반적이다. 

쿠버네티스에서 환경 변수를 전달할 때는 파드 템플릿에 env 또는 envFrom을 지정한다. 다음과 같은 다섯 가지 정보를 환경 변수에 포함시킬 수 있다.

 

참고) envFrom

kubectl explain pods --recursive | grep envFrom -A3

         envFrom	<[]Object>
            configMapRef	<Object>
               name	<string>
               optional	<boolean>

 

정적 설정/파드 정보/컨테이너 정보

apiVersion: v1
kind: Pod
metadata:
  name: env-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: ["echo"]
      args: ["$(TESTENV)"]
      env:
      - name: color   # 정적 설정
        value: red
      - name: K8S_NODE # 파드 정보
        valueFrom:
          fieldRef:
            fieldPath: spec.nodeName
      - name: CPU_REQUESTS # 컨테이너 정보
        valueFrom:
          resourceFieldRef:
            containerName: nginx-container
            resource: requests.cpu
      - name: TESTENV
        value: "100"

 

시크릿 리소스 기밀 정보

apiVersion: v1
kind: Secret
metadata:
  name: db-auth
data:
  host: mysql
  username: root
  password: password

환경 변수로 전달

apiVersion: v1
kind: Pod
metadata:
  name: single-env
spec:
  containers:
    - name: secret-container
      image: nginx
      # Example 1
      env:
      - name: DB_USERNAME
        valueFrom:
          secretKeyRef:
            name: db-auth
            key: username
      # Example 2
      envFrom:
      - secretRef:
          name: db-auth

볼륨으로 마운트

apiVersion: v1
kind: Pod
metadata:
  name: single-volume
spec:
  containers:
    - name: secret-container
      image: nginx
      volumeMounts:
      - name: config-volume
        mountPath: /config
  volumes:
    # Example 1
    - name: config-volume
      secret:
        secretName: db-auth
        items:
        - key: username
          path: username.txt
    # Example 2
    - name: config-volume
      secret:
        secretName: sample-db-auth

 

컨피그맵 리소스 설정값

컨피그맵은 설정 정보 등을 키-밸류 값으로 저장할 수 있는 데이터 저장 리소스다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: sample-configmap
data:
  thread: "16"
  connection.max: "100"
  connection.min: "10"
  sample.properties: |
    property.1=value-1
    property.2=value-2
    property.3=value-3
  nginx.conf: |
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;

 

환경변수로 전달

apiVersion: v1
kind: Pod
metadata:
  name: sample-configmap-single-env
spec:
  containers:
    - name: configmap-container
      image: nginx:1.12
      # Example 1
      env:
        - name: CONNECTION_MAX
          valueFrom:
            configMapKeyRef:
              name: sample-configmap
              key: connection.max
      # Example 2
      envFrom:
      - configMapRef:
          name: sample-configmap

볼륨으로 마운트

apiVersion: v1
kind: Pod
metadata:
  name: sample-configmap-single-volume
spec:
  containers:
    - name: configmap-container
      image: nginx:1.12
      volumeMounts:
      - name: config-volume
        mountPath: /config
  volumes:
    # Example 1
    - name: config-volume
      configMap:
        name: sample-configmap
        items:
        - key: nginx.conf
          path: nginx-sample.conf
    
    # Example 2
    - name: config-volume
      configMap:
        name: sample-configmap

 

시크릿과 컨피그맵의 사용 구분

시크릿과 컨피그맵은 비슷한 리소스들이지만, 둘의 가장 큰 차이는 시크릿이 기밀 정보를 취급하기 위한 리소스라는 점에 있다. 시크릿 데이터는 쿠버네티스 마스터가 사용하는 분산 KVC(Key-Value Store)의 etcd에 저장된다. 실제 시크릿을 사용하는 파드가 있는 경우에만 etcd에서 쿠버네티스 노드에 데이터를 보낸다. 이때 쿠버네티스 노드상에 영구적으로 데이터가 남지 않도록 시크릿 데이터는 tmps 영역(메모리상에 구축된 임시 파일 시스템)에 저장되게 되어 있다.

 

 


멀티 컨테이너 파드 디자인 패턴

사이드카 패턴(Sidecar)

사이드카 패턴은 원래 사용하려고 했던 기본컨테이너의 기능을 확장하거나 강화하는 용도의 컨테이너를 추가하는 패턴입니다. 기본 컨테이너에는 원래 목적의 기능에만 충실하고 나머지 부가적인 공통 기능들은 사이드카 컨테이너를 추가해서 사용할 수 있습니다. 일반적인 웹서버의 예를 생각해 보면 다음 그림처럼 웹서버 컨테이너는 웹서버로서의 역할에 충실하고 자신의 로그는 포드의 파일로 남깁니다. 그러면 사이드카 역할인 로그수집 컨테이너가 파일시스템에 쌓이는 로그를 수집해서 외부의 로그수집 시스템으로 보내는 역할을 합니다.

 

이렇게 구성하게 되면 웹서버 컨테이너만 다른 역할을 하는 컨테이너로 변경하게 되면 로그수집 컨테이너는 그대로 사용할 수 있습니다. 그래서 이런 공통역할을 하는 컨테이너의 재사용성을 끌어 올릴 수 있습니다. 

 

앰배서더 패턴(Ambassador)

앰배서더 패턴은 포드내에 프록시 역할을 하는 컨테이너를 추가하는 패턴입니다. 포드내에서 외부 서버에 접근할때 내부의 프록시에 접근하도록 설정하고 실제로 외부로의 연결은 프록시에서 알아서 처리하는 방식입니다. 다음 그림과 같은 구조입니다.

웹서버 컨테이너는 캐시에 접근하기 위해서 localhost로만 접근하고 실제 외부 캐시중 어디로 접근할지는 프록시 컨테이너에서 처리합니다. 

이런 방식으로 포드의 트래픽을 보다 세밀하게 제어하는 것도 가능합니다. 트래픽을 세밀하게 제어하기 위한 서비스 메시(service mesh)용 오픈소스인 이스티오(istio)를 보면 다음처럼 포드마다 프록시를 추가해서 트래픽을 처리하도록 구성되어 있는걸 확인할 수 있습니다.

어댑터 패턴(Adapter)

어댑터 컨테이너는 포드 외부로 노출되는 정보를 표준화하는 역할을 합니다. 주로 포드의 모니터링 지표를 어댑터 컨테이너를 통해서 표준화된 형식으로 노출시키고, 외부의 모니터링 시스템에서 그 데이터를 주기적으로 가져가서 모니터링하는데 이용할 수 있습니다. 다음과 같은 구조입니다.



출처: https://arisu1000.tistory.com/27863 [아리수]

 


initContainers

초기화 컨테이너(Init Container)란 파드 내부에서 메인이 되는 컨테이너를 기동하기 전에 별도의 컨테이너를 기동하기 위한 기능을 말한다. 설정에 필요한 스크립트 등을 메인 컨테이너에 보관하지 않은 상태를 유지할 수 있다(보안을 유지하고 이미지 용량을 줄임).

 

사용 사례로는 저장소에서 파일 등을 가져오는 처리, 컨테이너 기동을 지연시키는 처리, 설정 파일을 동적으로 생성하는 처리, 서비스가 생성되어 있는지 확인하는 작업과 그 외 메인 컨테이너를 기동하기 전의 체크 작업 등이 있다.

 

apiVersion: v1
kind: Pod
metadata:
  name: sample-initcontainer
spec:
  initContainers:
    - name: output-1
      image: centos:6
      command: ['sh', '-c', 'sleep 20; echo 1st > /usr/share/nginx/html/index.html']
      volumeMounts:
      - name: html-volume
        mountPath: /usr/share/nginx/html/
    - name: output-2
      image: centos:6
      command: ['sh', '-c', 'sleep 10; echo 2nd >> /usr/share/nginx/html/index.html']
      volumeMounts:
      - name: html-volume
        mountPath: /usr/share/nginx/html/
  containers:
    - name: nginx-container
      image: nginx:1.12
      volumeMounts:
      - name: html-volume
        mountPath: /usr/share/nginx/html/
  volumes:
  - name: html-volume
    emptyDir: {}

출처

Kubernetes IO

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

 

- 쿠버네티스 완벽 가이드(마사야 아오야마 지음, 박상욱 옮김)

- https://github.com/MasayaAoyama/kubernetes-perfect-guide

- https://cloud.google.com/kubernetes-engine/docs/how-to/updating-apps

- https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

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

[멀티컨테이너 디자인패턴]

- https://gruuuuu.github.io/cloud/design-pattern/

- https://arisu1000.tistory.com/27863

- https://velog.io/@youngerjesus/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%ED%8C%A8%ED%84%B4-%EC%82%AC%EC%9D%B4%EB%93%9C%EC%B9%B4