이야기박스
Kubernetes 9. Deployments 본문
# 개요
서비스 운영을 위해서는 일회성 배포가 아닌 지속적인 업데이트가 필요합니다. 사용자는 Pod 배포를 어떻게 진행하면 될까요?
쿠버네티스는 ReplicationController, ReplicaSet 위에 배치되는 디플로이먼트라는 리소스를 제공합니다. 우리는 이를 통하여 어플리케이션의 업데이트(배포)를 지속적으로 할 수 있습니다.
# 쿠버네티스 서비스
우리가 제공하는 Service 리소스를 생각해보겠습니다. 쿠버네티스는 위 그림과 같은 모습으로 서비스를 클라이언트에 제공합니다. 서비스는 ReplicaSet을 통하여 배포된 Pod에 사용자들이 접근할 수 있게 해 주는데, 특정 버전이 나간 Pod는 이미지 변경이 어렵기 때문에, 새로운 이미지를 가진 Pod로 교체해주어야 합니다.
## How to update pod
1. ReplicaSet(Replication Controller) 수정
첫 번째 방법은 심플하게 ReplicaSet의 이미지 설정을 수정해주는 것입니다. v1 포드 세트를 관리하는 ReplicaSet이 있다면 v2 이미지를 참조하도록 포드 템플릿을 수정합니다.
...
spec:
...
image: {image url}
이 작업을 진행해주면 ReplicaSet은 기존 포드를 종료하고 새로운 포드를 생성합니다.
2. Blue/Green deploy
두 번째로는 유명한 Blue-Green 배포가 있습니다. 한 번에 두 배의 포드를 실행해야 하기 때문에 많은 리소스가 필요합니다.
3. Rolling deploy
마지막으로 롤링 배포입니다. 가장 많이 사용되는 배포 방법인 것 같네요. 자세한 내용은 아래에 정리하도록 하겠습니다.
# 롤링 업데이트
롤링 업데이트는 ReplicaSet의 이미지 설정을 변경하거나 Pod의 이미지를 직접 수정하는 방법으로 진행할 수 있습니다.
## ReplicaSet
위에서 보여준 방법으로 합니다. Pod가 한번에 내려가지 않도록 설정해 준 후 진행하면 됩니다.
## kubectl
쿠버네티스 초기의 자동화 명령어 버전입니다.
==> 1.11버전에서 deprecated 되었다고 합니다. 이유는 아래에 설명드리겠습니다.
$ kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v2
Created kubia-v2
Scaling up kubia-v2 from 0 to 3, scaling down kubia-v1 from 3 to 0 (keep 3
pods available, don't exceed 4 pods)
...
Process. 시작 전
Process. 시작 전
Process. 중간 과정
Tip
imagePullPolicy : 동일한 태그에 이미지를 푸시하는 경우, 기존에 해당 태그로 이미지를 가져왔다면 새로운 이미지를 가져오지 못함. 이를 해결하기 위하여 선언해두는 것
가장 좋은 건, 이미지 태그를 다르게 하는 것
## kubectl 사용하지 않는 이유
1. 포드의 라벨과 레플리케이션컨트롤러의 라벨 셀렉터를 수정함
자세한 과정은 아래 명령어를 통해 로깅 레벨을 올린 후 확인이 가능합니다.
$ kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v2 --v 6
2. 클라이언트에서 어플리케이션 업데이트하는 모양은 좋지 않음
kubectl을 사용한다는 것은 결국 외부에서 api server를 통하여 접근한다는 의미입니다. 이때, 네트워크 이슈라도 발생한다면 작업에 큰 이슈가 발생할 수 있습니다.
그렇기 때문에 쿠버네티스는 Deployment라는 리소스를 도입하였습니다.
# Deployment
실제 배포는 디플로이먼트가 아닌 레플리카 셋에 의하여 이루어집니다. 디플로이먼트는 그저 레플리카셋(레플리케이션 컨트롤러)를 관리할 뿐입니다.
## 생성
Deployment 생성은 다음 yaml을 통하여 할 수 있습니다.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
## 기타 명령어
rc 삭제
$ kubectl delete rc --all
create
$ kubectl create -f kubia-deployment-v1.yaml --record
deployment "kubia" created
상태확인 (deployment만 가능한 명령어)
$ kubectl rollout status deployment kubia
deployment kubia successfully rolled out
$ kubectl get po
NAME READY STATUS RESTARTS AGE
kubia-1506449474-otnnh 1/1 Running 0 14s
kubia-1506449474-vmn7s 1/1 Running 0 14s
kubia-1506449474-xis6m 1/1 Running 0 14s
Pod의 숫자 값은 Pod를 관리하는 레플리카셋의 해시값입니다.
$ kubectl get replicasets
NAME DESIRED CURRENT AGE
kubia-1506449474 3 3 10s
레플리카셋도 동일한 해시값이 이름에 들어가는 것을 확인할 수 있습니다.
포드를 새로 생성하였다고 서비스를 교체해야 하는 것은 아닙니다. 라벨이 일치한다면, 이전에 생성했던 서비스에서 그대로 위 포드 이용 가능합니다.
## 배포 전략
이제 순차적으로 배포할 것인지 아닌지, 배포 전략을 세울 수 있습니다.
1. RollingUpdate : default
minReadySeconds : RollingUpdate 속도 조절 필요한 경우 사용할 수 있습니다.
$ kubectl patch deployment kubia -p '{"spec": {"minReadySeconds": 10}}'
"kubia" patched
Note.
kubectl patch는 파일 에디트 없이 간단하게 리소스의 설정을 변경할 수 있지만 히스토리 추적이 어렵기 때문에 지양하는 것이 좋습니다.
deployment의 설정을 바꾸는 방법으로도 배포 진행이 가능합니다.
$ kubectl set image deployment kubia nodejs=luksa/kubia:v2
deployment "kubia" image updated
2. Recreate : blue/green
tip : kubectl 리소스 수정 명령어
kubectl edit : 객체의 매니페스트 파일 열기
kubectl patch : 개별 속성 수정
kubectl apply : json/yaml 속성 값을 적용
kubectl replace : json/yaml의 새 객체로 변경
kubectl image : 포드, rc 템플릿, 디플로이먼트, 데몬 셋, 잡, 레플리카셋에 정의된 이미지 변경
참고 ; ConfigMap을 변경하였다고 deployments가 트리거 되지 않음
# 롤백
아래 kubectl 명령어를 통하여 deployment를 이전 버전으로 롤백이 가능합니다.
$ kubectl rollout undo deployment kubia
deployment "kubia" rolled back
## 히스토리
Deployment의 히스토리가 남아 있는 경우, 이를 추적하여 롤백이 가능합니다.
히스토리 추적
$ kubectl rollout history deployment kubia
deployments "kubia":
REVISION CHANGE-CAUSE
2 kubectl set image deployment kubia nodejs=luksa/kubia:v2
3 kubectl set image deployment kubia nodejs=luksa/kubia:v3
특정 리비전으로 롤백
$ kubectl rollout undo deployment kubia --to-revision=1
deployment는 이전 버전의 레플리카셋을 기억하고 있기 때문에 위 같은 동작이 가능합니다. 그렇기 때문에 이 리비전을 수동으로 삭제하면 롤백이 불가능해집니다.
보관하는 리비전 개수는 다음 설정을 통하여 가능합니다.
- revisionHistoryLimit : 설정을 통하여 보관하는 개수 지정 (default 2 ; 현재와 이전 버전만 보관)
## 롤아웃 속도 통제
한 번에 롤아웃이 발생하면 서비스가 중단될 수 있기 때문에, 다음 두 설정 값을 통하여 롤아웃 속도를 조절할 수 있습니다.
maxSurge
배포 중 사용되는 추가 포드 인스턴스 수를 조절합니다.
default : 25% / 절대값 지정 가능
maxUnavailable
사용 안할 최대 포드 개수를 지정할 수 있습니다.
default : 25% / 절댓값 지정 가능
예시 1. 한대씩 롤아웃 진행
spec:
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
예시 2. Deployment extensions/v1beta1 버전
default 값이 25%가 아닌 절대값 1로 동작합니다.
## 롤아웃 프로세스 일시 중지
일부 포드만 배포를 진행하여 카나리아 배포 효과를 얻을 수 있습니다.
$ kubectl set image deployment kubia nodejs=luksa/kubia:v4
deployment "kubia" image updated
$ kubectl rollout pause deployment kubia
deployment "kubia" paused
롤아웃 재개할 때는 다음 명령어를 사용합니다.
$ kubectl rollout resume deployment kubia
deployment "kubia" resumed
## 잘못된 버전 롤아웃 방지
minReadySeconds 속성과 readiness probe를 이용합니다.
minReadySeconds를 통하여 포드간 배포 시간을 조절하고 그 사이에 Readiness Check를 합니다.
만약 Readiness Check가 성공 할때까지 Deployment는 새로운 포드를 배포하지 않습니다. 또한 포드는 maxSurge에 정의된 예비 공간에 배포가 되었기 때문에 기존 서비스에도 영향이 없습니다.
단지, maxSurge에 정의된 공간만큼의 리소스가 낭비되겠죠.
Step 1. Readiness probe 정의한 deployment manifest : kubia-deployment-v3-with-readinesscheck.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v3
name: nodejs
readinessProbe:
periodSeconds: 1
httpGet:
path: /
port: 8080
Step 2. Readiness probe 업데이트
$ kubectl apply -f kubia-deployment-v3-with-readinesscheck.yaml
deployment "kubia" configured
Step 3. 동작 구조
## 롤아웃 데드라인
기본값은 10분입니다. Deployment의 progressDeadlineSeconds 속성에서 구성 가능합니다.
$ kubectl describe deploy kubia
Name: kubia
...
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded
## 롤아웃 중지
롤아웃 중지도 롤백과 동일한 명령어로 진행합니다.
$ kubectl rollout undo deployment kubia
deployment "kubia" rolled back
'Computer & Data > Orchestration' 카테고리의 다른 글
Kubernetes. 포드의 계산 리소스 관리 (3) | 2019.10.30 |
---|---|
Intellij - Docker desktop; Spring Web app 이미지 만들기 (0) | 2019.10.16 |
Kubernetes 8. Accesing pod metadata and other resources from applications (0) | 2019.09.03 |
Kubernetes 7. ConfigMap & Secret (0) | 2019.08.28 |
Kubernetes 6. Volume (0) | 2019.08.21 |