Kubernetes 배포 전략 + RollingUpdate 실습

신동수·2024년 5월 13일
0

K8S

목록 보기
11/14

무중단 배포

서버를 실제로 서비스할 때 서비스적인 장애와 배포에 있어서 부담감을 최소화하고, 서비스가 중단되지 않도록 배포하는 기술이다.

Rolling


구 버전을 하나 제거하고 새 버전을 하나 추가하는 과정을 반복하는 방식이다.(V1에서 V2로 점진적으로 전환)
이전버전(v1)과 새버전(v2)의 인스턴스가 동시에 존재할 수 있다는 단점이 있다.

Blue/Gree


이전버전과 새버전을 동시에 나란히 구성 후 트래픽을 일제히 전환한다.
롤링에서 존재하는 버전차이에 대한 문제를 해결할 수 있다.
문제 발생시 빠른 롤백(Roll-Back)이 가능하다.
단점으로는 시스템 자원이 두배로 필요하다.

Canary


서버의 트래픽 일부를 새로운 버전으로 분산해서 조금씩 테스트해본 후, 오류가 없으면 정상적으로 전체를 배포하는 방식이다.
트래픽 일부를 분산하는 방식으로 신버전에서의 오류여부를 확인 할 수 있다.
문제 발생시 트래픽만 조정하면 되므로, 빠른 롤백이 가능하다.

RollingUpdate 실습

# deployment-exam1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deploy
spec:
  selector:
    matchLabels:
      app: webui
  replicas: 3
  template:
    metadata:
      labels:
        app: webui
    spec:
      containers:
      - image: nginx:1.14
        name: web
        ports:
        - containerPort: 80

위는 RollingUpdate를 위한 yaml 파일이다.

# pod 배포 (--record옵션은 업데이트 과정을 history로 기록하는 옵션)
$ kubectl apply -f deployment-exam1.yaml --record
# pod 확인
$ kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
app-deploy-86c8cbb88-hsmmb   1/1     Running   0          16m   172.16.103.138   w2-k8s   <none>           <none>
app-deploy-86c8cbb88-hwvll   1/1     Running   0          16m   172.16.221.137   w1-k8s   <none>           <none>
app-deploy-86c8cbb88-k5vn6   1/1     Running   0          16m   172.16.132.14    w3-k8s   <none>           <none>

# describe를 통한 pod Image정보 확인
$ kubectl describe pod app-deploy-86c8cbb88-hsmmb | grep Image
    Image:          nginx:1.14
    Image ID:       docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d

# nginx:1.15 버전으로 업데이트
$ kubectl set image deployment app-deploy web=nginx:1.15 --record

# pod 확인
$ kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
app-deploy-cf8c7477c-6vnfb   1/1     Running   0          119s    172.16.103.140   w2-k8s   <none>           <none>
app-deploy-cf8c7477c-f8c6c   1/1     Running   0          2m10s   172.16.221.139   w1-k8s   <none>           <none>
app-deploy-cf8c7477c-lzgwg   1/1     Running   0          109s    172.16.132.16    w3-k8s   <none>           <none>

# describe를 통한 pod Image정보 확인
$ kubectl describe pod app-deploy-cf8c7477c-6vnfb | grep Image
    Image:          nginx:1.15
    Image ID:       docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68

# history 확인
$ kubectl rollout history deployment app-deploy
deployment.apps/app-deploy
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=deployment-exam1.yaml --record=true
2         kubectl set image deployment app-deploy web=nginx:1.15 --record=true


위 예시와 같이 v1은 nginx:1.14버전에서 RollingUpdate를 통해 v2의 nginx:1.15버전으로 점진적으로 바뀌는 것을 확인할 수 있다.

Rollout 실습

# history 확인
$ kubectl rollout history deployment app-deploy
deployment.apps/app-deploy
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=deployment-exam1.yaml --record=true
2         kubectl set image deployment app-deploy web=nginx:1.15 --record=true

# 1버전으로 rollout
$ kubectl rollout undo deployment app-deploy --to-revision=1
deployment.apps/app-deploy rolled back

# history 확인
$ kubectl rollout history deployment app-deploy
deployment.apps/app-deploy
REVISION  CHANGE-CAUSE
2         kubectl set image deployment app-deploy web=nginx:1.15 --record=true
3         kubectl apply --filename=deployment-exam1.yaml --record=true

# pod 확인
$ kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
app-deploy-86c8cbb88-kts7r   1/1     Running   0          3m45s   172.16.103.141   w2-k8s   <none>           <none>
app-deploy-86c8cbb88-v6q9d   1/1     Running   0          3m43s   172.16.221.140   w1-k8s   <none>           <none>
app-deploy-86c8cbb88-w2msh   1/1     Running   0          3m43s   172.16.132.17    w3-k8s   <none>           <none>

# Image 확인
$ kubectl describe pod app-deploy-86c8cbb88-kts7r | grep Image
    Image:          nginx:1.14
    Image ID:       docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d

1버전으로 rollout하였고, history를 확인한다면 1버전이 3버전으로 바뀌는 것을 확인할 수 있다. 만약, kubectl rollout undo deployment <디플로이먼트> 으로 명령을 실행한다면 2버전의 nginx:1.15의 Pod가 rollout이 될 것이다.

명령어를 활용한 롤링 업데이트 정리

  • 이미지 업데이트
$ kubectl set image deployment <디플로이먼트> <컨테이너>=<이미지>:<버전>
  • 롤링 업데이트 상태 확인
$ kubectl rollout status deployment <디플로이먼트>
$ kubectl describe deployments.apps <디플로이먼트>
  • 롤백 적용
$ kubectl rollout undo deployment <디플로이먼트>
$ kubectl rollout undo deployment <디플로이먼트> --to-revision=<버전>
  • 롤링 업데이트/롤백 히스토리 확인
$ kubectl rollout history deployment <디플로이먼트>
$ kubectl rollout history deployment <디플로이먼트> --revision=<버전>

YAML을 사용한 RollingUpdate 실습

# deployment-exam2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  annotations:
    kubernetes.io/change-cause: version 1.15
spec:
  progressDeadlineSeconds: 600
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      labels:
        app: webui
    spec:
      containers:
      - name: web
        image: nginx:1.15
        ports:
        - containerPort: 80

위는 yaml을 통한 RollingUpdate를 위한 yaml 파일이다.

롤링 업데이트 옵션

  • maxSurge
    • 롤링 업데이트를 위해 최대로 생성할 수 있는 파드 갯수
    • maxSurge를 높게 설정하면 롤링 배포를 빠르게 적용 가능
    • % 단위 또는 갯수 단위로 지정 가능
    • 설정하지 않을 경우 기본 값은 25%
  • maxUnavailable
    • 롤링 업데이트 중 최대로 삭제할 파드 갯수
    • maxUnavailable를 높게 설정하면 롤링 배포를 빠르게 적용 가능
    • 다만 한번에 많은 파드를 삭제할 경우 트래픽이 남아있는 소수의 파드로 집중될 수 있어 값을 적절히 설정 필요
    • % 단위 또는 갯수 단위로 지정 가능
    • 설정하지 않을 경우 기본 값은 25%
# pod 배포
$ kubectl apply -f deployment-exam2.yaml --record
# pod 확인
$ kubectl get pod -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
deploy-nginx-cf8c7477c-ln6xr   1/1     Running   0          15s   172.16.221.141   w1-k8s   <none>           <none>
deploy-nginx-cf8c7477c-tfvmc   1/1     Running   0          15s   172.16.132.18    w3-k8s   <none>           <none>
deploy-nginx-cf8c7477c-zd646   1/1     Running   0          15s   172.16.103.142   w2-k8s   <none>           <none>

# describe를 통한 pod Image정보 확인
$ kubectl describe pod deploy-nginx-cf8c7477c-tfvmc | grep Image
    Image:          nginx:1.15
    Image ID:       docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68

# yaml 파일 수정
$ vi deployment-exam2.yaml
kubernetes.io/change-cause: version 1.15 -> kubernetes.io/change-cause: version 1.18
image:1.15 -> image:1.18

# pod 배포
$ kubectl apply -f deployment-exam2.yaml
deployment.apps/deploy-nginx configured

# pod 확인
$ kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
deploy-nginx-55cdc7c796-7pvd7   1/1     Running   0          63s   172.16.132.19    w3-k8s   <none>           <none>
deploy-nginx-55cdc7c796-cg7h2   1/1     Running   0          75s   172.16.221.142   w1-k8s   <none>           <none>
deploy-nginx-55cdc7c796-d4cvb   1/1     Running   0          86s   172.16.103.143   w2-k8s   <none>           <none>

# describe를 통한 pod Image정보 확인
kubectl describe pod deploy-nginx-55cdc7c796-7pvd7 | grep Image
    Image:          nginx:1.18
    Image ID:       docker.io/library/nginx@sha256:e90ac5331fe095cea01b121a3627174b2e33e06e83720e9a934c7b8ccc9c55a0

# history 확인
$ kubectl rollout history deployment deploy-nginx
deployment.apps/deploy-nginx
REVISION  CHANGE-CAUSE
1         version 1.15
2         version 1.18

yaml 수정을 통해 업데이트 시 훨씬 더 간결하게 history 정보를 확인할 수 있다. 마지막으로 업데이트한 내역을 yaml 로 업데이트하기에 어느 버전인지 더 빠르게 확인할 수 있다는 장점이 있다.

profile
조금씩 성장하는 DevOps 엔지니어가 되겠습니다. 😄

0개의 댓글

관련 채용 정보