[Kubernetes] 7. 배포

2023. 6. 19. 23:30쿠버네티스 (Kubernetes)


Rollout

 

하루종일 열심히 웹 서핑을 하다가 컴퓨터를 끄고 자더라도,

지구 반대편의 누군가는 다시 그 사이트에서 웹 서핑을 시작합니다.

따라서 서비스는 지속 가능해야 합니다.

 

그리고 시스템과 기술은 언제나 발전하고 있습니다.

만일 새로운 기능을 개발했다면, 기존 것에 적용해야 합니다.

따라서 서비스는 발전 가능해야 합니다.

 

기존 서비스를 중지하고 새로운 서비스로 교체하는 것을 rollout이라고 합니다.

사실 지속 가능하고, 발전 가능한 서비스는 rollout을 잘하는 것 만큼 중요한 건 없습니다.

하지만 지금까지 배운 내용을 토대로 서비스를 배포하고 운용한다면 이 두 개의 나사가 약간 풀려있을 것입니다.

왜냐하면 기존 팟을 제거하고 다시 팟을 만들어야 할 수 밖에 없기 때문에 그 과정에서 누군가는 우리가 제공하는 서비스를 이용할 수 없을 뿐만 아니라, 엔드포인트(endpoint)도 못 찾아 헤멜 수 있기 때문입니다.

 

쿠버네티스에서의 배포(deployment)는 간단하면서도 안정적으로 rollout하는 것을 말합니다.
쉽게 말하면 사용자 입장에서 rollout을 느낄 수 없으면서 계속 이용하도록 만들면 됩니다.

 

 

 

 

 


Deployment

 

먼저 배포 관련 구성을 해보고 실행해봅니다.

 

kuard-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kuard
spec:
  selector:
    matchLabels:
      run: kuard
  replicas: 1
  template:
    metadata:
      labels:
        run: kuard
    spec:
      containers:
        - name: kuard
          image: gcr.io/kuar-demo/kuard-amd64:blue

 

kubectl create -f kuard-deployment.yaml

 

get 명령어로 deployments를 검색하면 이전에 알고 있던 것과 조금 다르게 표현합니다.

kubectl get deployments kuard
더보기

NAME    READY   UP-TO-DATE   AVAILABLE   AGE
kuard   1/1     1            1           4m

 

구성 파일에 replicas가 있는 것을 보고 눈치챘겠지만, 배포는 [Kubernetes] 6. 레플리카에서처럼 레플리카셋을 관리합니다.

한 번 레이블(label)로 레플리카를 검색해봅니다.

kubectl get replicasets --selector=run=kuard
더보기

NAME               DESIRED   CURRENT   READY   AGE
kuard-645b4bff86   1         1         1       5m54s

 

이제 scale 명령어로 replica를 늘려봅니다.

 kubectl scale deployments kuard --replicas=2

 

이제 다시 레플리카셋을 확인해보면

kubectl get replicasets --selector=run=kuard
더보기

NAME               DESIRED   CURRENT   READY   AGE
kuard-645b4bff86   2         2         2       2m7s

 

이번엔 다르게, kuard-645b4bff86 레플리카셋에 대한 크기를 줄여봅니다.

kubectl scale replicasets kuard-645b4bff86 --replicas=1

 

이제 다시 레플리카셋을 확인해보면

kubectl get replicasets --selector=run=kuard
더보기

NAME               DESIRED   CURRENT   READY   AGE
kuard-645b4bff86   2         2         2       2m7s

 

출력 결과를 보면 여전히 그대로임을 알 수 있습니다.

이는 레플리카셋 수준의 관리보다 배포 수준에서의 관리가 더 우선이기 때문인데,

레플리카셋 수준에서 개수를 제어한다고 해도, 어차피 배포 수준에서 원하는(desired) 레플리카수로 맞춰집니다.

 

describe 명령어로 배포 정보를 확인할 수 있습니다.

kubectl describe deployments kuard
더보기

Name:                   kuard
Namespace:              default
CreationTimestamp:      Mon, 19 Jun 2023 21:04:54 +0900
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               run=kuard
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=kuard
  Containers:
   kuard:
    Image:        gcr.io/kuar-demo/kuard-amd64:blue
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Progressing    True    NewReplicaSetAvailable
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  <none>
NewReplicaSet:   kuard-645b4bff86 (2/2 replicas created)
Events:
  Type    Reason             Age                   From                   Message
  ----    ------             ----                  ----                   -------
  Normal  ScalingReplicaSet  10m                   deployment-controller  Scaled up replica set kuard-645b4bff86 to 1
  Normal  ScalingReplicaSet  5m58s                 deployment-controller  Scaled down replica set kuard-645b4bff86 to 1 from 2
  Normal  ScalingReplicaSet  5m2s (x3 over 8m37s)  deployment-controller  Scaled up replica set kuard-645b4bff86 to 2 from 1

 

여기서 중요한 정보 중 하나는 OldReplicaSets와 NewReplicaSet 입니다.

rollout이 시작되면 NewReplicaSet가 OldReplicaSets로 바뀌고 새로운 레플리카들이 NewReplicaSet에 표현됩니다.

rollout이 완료되면 OldReplicaSets가 <none>이 됩니다.

 

 

 

 

 


Updating Deployment

 

일전에 만들었던 kuard-deployment.yaml에서 아래처럼 바꾸고 apply를 실행해봅니다.

 

kuard-deployment-update.yaml

spec:
...
  template:
    metadata:
      annotations:
        kubernetes.io/change-cause: "Update to green kuard"
      labels:
        run: kuard
    spec:
      containers:
        - name: kuard
          image: gcr.io/kuar-demo/kuard-amd64:green
          imagePullPolicy: Always
kubectl apply -f kuard-deployment.yaml
더보기

deployment.apps/kuard configured

 

이 다음 바로 아래 rollout status 명령어를 실행하면

kubectl rollout status deployments
더보기

Waiting for deployment "kuard" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "kuard" rollout to finish: 1 old replicas are pending termination...
deployment "kuard" successfully rolled out

 

처럼 확인할 수 있고, 이어서 레플리카셋을 마저 보면

kubectl get replicasets -o wide
더보기

NAME               DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                               SELECTOR
kuard-645b4bff86   0         0         0       20m   kuard        gcr.io/kuar-demo/kuard-amd64:blue    pod-template-hash=645b4bff86,run=kuard
kuard-6c6b48b5d7   1         1         1       50s   kuard        gcr.io/kuar-demo/kuard-amd64:green   pod-template-hash=6c6b48b5d7,run=kuard

 

처럼 이미지가 교체되어 실행되고 있음을 할 수 잇습니다.

이력(history) 또한 rollout history 명령어로 확인할 수 있습니다.

kubectl rollout history deployment kuard
더보기

deployment.apps/kuard 
REVISION  CHANGE-CAUSE
1         <none>
2         Update to green kuard

 

 

 

 

 


Deployment Strategies

 

새로운 버전으로 서비스를 배포할 때, 쿠버네티스에서는 두 가지 전략을 선택할 수 있습니다.

 

Recreate Strategy

해당 서비스와 관련된 pod을 종료하고, 다시 새로운 버전의 이미지와 함께 pod을 생성합니다.

이 방법은 단순하지만 pod 종료되고 다시 시작하는 그 시간 안에는 서비스를 이용하지 못하는 단점이 있습니다.

따라서 downtime에 크게 구애 받지 않는 테스트 용으로 사용하는 것이 좋습니다.

 

 

RollingUpdate Strategy

실제 서비스를 운영할 때 주로 사용하는 전략으로, 기존 pod은 유지하면서 새로운 pod이 온전하게 생성되서 서비스를 수행할 수 있을 때 해당 pod으로 대체합니다. 그리고 기존 pod을 종료합니다.

해당 방법은 위 전략보다는 느릴 수 있지만, downtime이 없다는 장점이 있습니다.

 

해당 전략은 몇 가지 좋은 옵션을 가지고 있습니다.

첫 번째로, 실제 새로운 버전의 서비스가 생성되었지만 배포는 잠시 지연하도록 하고 싶을 때는 minReadSeconds 파라미터를 사용합니다.

...
spec:
  minReadSeconds: 60
...

 

위 예시는 새롭게 생성된 pod이 정상임을 확인한 후 60초가 흐른 뒤 배포해서 기존 서비스를 대체하라는 의미입니다.

만일 60초 내에 시스템이 비정상이라면, 배포하지 않습니다.

 

progressDeadlineSeconds 파라미터도 있는데 해당 시간안에 rollout이 끝나지 않으면 해당 배포를 실패 처리합니다.

...
spec:
  progressDeadlineSeconds: 600
...

 

 

 

 

 


Delete

 

배포를 제거하고 싶다면 delete deployments 명령어를 사용합니다.

 kubectl delete deployments kuard

'쿠버네티스 (Kubernetes)' 카테고리의 다른 글

[Kubernetes] 8. 설정  (0) 2023.06.20
[Kubernetes] 6. 레플리카  (0) 2023.06.13
[Kubernetes] 5. 서비스 검색  (0) 2023.06.12
[Kubernetes] 4. POD  (0) 2023.06.03
[Kubernetes] 3. 팁  (0) 2023.06.01