클라우드,가상화/K8S

k8s - Deployment

aiemag 2023. 7. 2. 16:14
반응형

 

Deployment?

deployment는 여러 replicaSet을 관리하여 롤링 업데이트나 롤백 등을 구현하는 리소스.

deployment가 replicaSet을 관리하고 replicaSet이 pod를 관리하는 관계.

다음 순서로 동작

1. 신규 replicaset을 생성

2. 신규 replicaset의 replica 수(pod 수)를 단계적으로 늘림.

3. 이전 replicaset의 replica 수(pod 수)를 단계적으로 줄임.

4. (2, 을 반복)

5. 이전 replicaset은 replica 수를 0으로 유지.

 

Deployment 생성

sample-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.16

 

--record 옵션을 사용하면 어떤 명령어를 실행하고 업데이트했는지 이력이 저장됨.

※ 이력을 작성해 놓으면 rollout에서 롤백 등을 실시할 때 참고 정보로 사용할 수 있으나 rollout을 사용하는 경우는 거의 없기 때문에 --record 옵션은 많이 사용하지 않음.

 

이력은 각 replicaset의 meta.annotations[kubernetes.io/change-cause]에 저장되어 있음.

[root@k8s-master deployment]# k apply -f sample-deployment.yaml --record
deployment.apps/sample-deployment created

[root@k8s-master deployment]# k get replicasets -o yaml | head
apiVersion: v1
items:
- apiVersion: apps/v1
  kind: ReplicaSet
  metadata:
    annotations:
      deployment.kubernetes.io/desired-replicas: "3"
      deployment.kubernetes.io/max-replicas: "4"
      deployment.kubernetes.io/revision: "1"
      kubernetes.io/change-cause: kubectl apply --filename=sample-deployment.yaml

 

deployment를 확인해보면 replicaset과 거의 같은 정보가 표시됨.

이름을 보면 deploment -> replicaset -> pod 순으로 생성한다는 것을 알 수 있음.

[root@k8s-master deployment]# k get deployments
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
sample-deployment   3/3     3            3           8m37s

[root@k8s-master deployment]# k get replicasets
NAME                           DESIRED   CURRENT   READY   AGE
sample-deployment-7bf986f9cf   3         3         3       8m48s

[root@k8s-master deployment]# k get pods
NAME                                 READY   STATUS    RESTARTS   AGE
sample-deployment-7bf986f9cf-mlqvn   1/1     Running   0          9m
sample-deployment-7bf986f9cf-tzcvb   1/1     Running   0          9m
sample-deployment-7bf986f9cf-vc9hz   1/1     Running   0          9m

 

Deployment 업데이트

롤링 업데이트를 위한 테스트(nginx:1.16 -> nginx:1.17 update)

[root@k8s-master deployment]# k set image deployment sample-deployment nginx-container=nginx:1.17 --record
deployment.apps/sample-deployment image updated

[root@k8s-master deployment]# kubectl rollout status deployment sample-deployment
Waiting for deployment "sample-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "sample-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "sample-deployment" successfully rolled out

[root@k8s-master deployment]# k get deployments
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
sample-deployment   3/3     3            3           93m

[root@k8s-master deployment]# k get replicasets
NAME                           DESIRED   CURRENT   READY   AGE
sample-deployment-5988b689cb   3         3         3       3m21s
sample-deployment-7bf986f9cf   0         0         0       93m
sample-deployment-cd848cf97    0         0         0       2m39s

[root@k8s-master deployment]# k get pods
NAME                                 READY   STATUS    RESTARTS   AGE
sample-deployment-5988b689cb-787nw   1/1     Running   0          78s
sample-deployment-5988b689cb-h75j5   1/1     Running   0          82s
sample-deployment-5988b689cb-k9ckq   1/1     Running   0          80s

 

Deployment 업데이트(replicaset이 생성되는) 조건

- deployment에서는 변경이 발생하면 replicaset이 생성.

- replica 수의 변경 등은 포함되어 있지 않음.

- 생성된 pod의 내용 변경이 필요(spec.template의 변경)

 

실제로 manifest를 kubernetes에 등록한 후 replicaset의 정의를 보면, spec.template 아래의 해시값(pod template hash)을 계산하고 이 값을 사용한 레이블로 관리.

※ 수작업으로 이미지 등을 이전 버전으로 재변경하여 해시값이 동일해진 경우는 replicaset을 신규로 생성하지 않고 기존 replicaset을 사용.

 

replicaset 상태를 YAML 형식으로 출력

[root@k8s-master deployment]# k get replicasets sample-deployment-5988b689cb -o yaml

...

spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
      pod-template-hash: 5988b689cb

...

 

 

변경 롤백

롤백 기능의 실체는 현재 사용 중인 replicaset의 전환과 같음.

deployment가 생성한 기존 replicaset은 replica 수가 0인 상태로 남아 있기 때문에 replica 수를 변경시켜 다시 사용할 수 있는 상태가 됨.

 

변경 이력을 확인할 때는 kubectl rollout history 명령어를 사용.

※ CHANGE-CAUSE 부분은 deployment를 생성할 때 --record 옵션을 사용하여 이력 내용이 있지만, --record 옵션을 사용하지 않았다면 <none> 등이 됨.

[root@k8s-master deployment]# k rollout history deployment sample-deployment
deployment.apps/sample-deployment
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment sample-deployment nginx-container=nginx:1.17 --record=true

 

수정 버전에 대한 상세 정보를 가져오려면 --revision 옵션을 지정

[root@k8s-master deployment]# k rollout history deployment sample-deployment --revision 1
deployment.apps/sample-deployment with revision #1
Pod Template:
  Labels:       app=sample-app
        pod-template-hash=7bf986f9cf
  Containers:
   nginx-container:
    Image:      nginx:1.16
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>

[root@k8s-master deployment]# k rollout history deployment sample-deployment --revision 2
deployment.apps/sample-deployment with revision #2
Pod Template:
  Labels:       app=sample-app
        pod-template-hash=5988b689cb
  Annotations:  kubernetes.io/change-cause: kubectl set image deployment sample-deployment nginx-container=nginx:1.17 --record=true
  Containers:
   nginx-container:
    Image:      nginx:1.17
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>

 

롤백은 kubectl rollout undo 를 사용. 

ㄴ 명령어의 인수로 버전 번호를 지정할 수 있으며 0으로 지정하거나 지정하지 ㅇ낳을 경우 바로 이전 버전으로 롤백.

 

# 버전 번호를 지정하여 롤백
[root@k8s-master deployment]# k rollout undo deployment sample-deployment --to-revision 1
deployment.apps/sample-deployment rolled back

# 바로 이전 버전으로 롤백
[root@k8s-master deployment]# k rollout undo deployment sample-deployment
deployment.apps/sample-deployment rolled back

 

롤백한 후에는 이전 replicaset의 pod가 기동

[root@k8s-master deployment]# k get replicasets
NAME                           DESIRED   CURRENT   READY   AGE
sample-deployment-5988b689cb   3         3         3       13m
sample-deployment-7bf986f9cf   0         0         0       16m

 

실제 환경에서는 롤백 기능을 사용하는 경우가 많지 않음.

 

CI/CD 파이프라인에서 롤백을 하는 경우 kubectl rollout 명령어보다 이전 manifest를 다시 kubectl apply 명령어로 실행하여 적용하는 것이 호환성 면에서 더 좋음. 

※ 이때 spec.template 을 같은 내용으로 되돌렸을 경우 pod-template-hash 값이 같기 때문에 kubectl rollout처럼 기존에 있었던 replicaset의 pod가 기동.

 

 

Deployment 변경 일시 중지

안전을 위해 deployment에 대한 업데이트를 바로 적용하는 것을 원치 않을 경우도 있음.

 

즉시 적용을 일시 정지하고 싶을 때는 kubectl rollout pause를 실행하고 다시 시작할 때 kubectl rollout resume을 실행

[root@k8s-master deployment]# kubectl rollout pause deployment sample-deployment
deployment.apps/sample-deployment paused

[root@k8s-master deployment]# kubectl rollout resume deployment sample-deployment
deployment.apps/sample-deployment resumed

pause 상태에서는 deployment 업데이트가 즉시 반영되지 않음.

pause 상태에서는 롤백도 되지 않음.

반응형

'클라우드,가상화 > K8S' 카테고리의 다른 글

k8s - ClusterIP  (0) 2023.07.17
k8s - kubernetes 클러스터 네트워크와 서비스  (0) 2023.07.16
k8s - ReplicaSet  (0) 2023.07.02
k8s - Pod  (0) 2023.07.02
k8s - Overview  (0) 2023.07.02