728x90
애플리케이션 롤링 업데이트와 롤백
기존 모든 포드를 삭제 후 새로운 포드 생성
- 잠깐의 다운 타임 발생
새로운 포드를 실행시키고 작업이 완료되면 오래된 포드를 삭제
- 새버전을 실행하는동안구버전포드와연결
- 서비스의 레이블셀렉터를 수정하여 간단하게 수정가능
레플리케이션컨트롤러가 제공하는 롤링 업데이트
- 이전에는 kubectl을 사용해 스케일링을 사용하여 수동으로 롤링 업데이트 진행 가능
- kubectl 중단되면 업데이트는 어떻게 될까?
- 레플리케이션컨트롤러 또는 레플리카셋을 통제할 수 있는 시스템이 필요
디플로이먼트 생성
- 레이블 셀렉터, 원하는 복제본 수, 포드 템플릿
- 디플로이먼트의 전략을 yaml에 지정하여 사용 가능
- 먼저 업데이트 시나리오리를 위해 3개의 도커 이미지를 준비
- gasbugs/http-go:v1
- gasbugs/http-go:v2
- gasbugs/http-go:v3
FROM golang:1.11
WORKDIR /usr/src/app
COPY main /usr/src/app
CMD ["/usr/src/app/main"]
디플로이먼트 생성 YAML 만들기
- 버전을 이름에 넣을 필요가 없음 (업데이트 되어도 동일한 디플로이먼트를 사용)
$ kubectl create -f http-go-deployment.yaml --record=true
deployment.apps/http-go created
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
http-go 3 3 3 3 18m
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
http-go-5bf4b7b6c9 3 3 3 15m
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
http-go-764d477998-c2hvv 1/1 Running 7 13m
http-go-764d477998-g5m8t 1/1 Running 7 13m
http-go-764d477998-w22b4 1/1 Running 7 13m
rollout을 통해서도 상태 확인 가능
$ kubectl rollout status deployment http-go
deployment "http-go" successfully rolled out
디플로이먼트 업데이트 전략(StrategyType)
spec:
strategy:
type: RollingUpdate
- Rolling Update(기본값)
- 오래된 포드를 하나씩 제거하는 동시에 새로운 포드 추가
- 요청을 처리할 수 있는 양은 그대로 유지
- 반드시 이전 버전과 새 버전을 동시에 처리 가능하도록 설계한 경우에만 사용해야 함
- Recreate
- 새 포드를 만들기 전에 이전 포드를 모두 삭제
- 여러 버전을 동시에 실행 불가능
- 잠깐의 다운 타임 존재
- 업데이트 과정을 보기 위해 업데이트 속도 조절
업데이트가 10초정도 준비가 되었다가 실행되게 함
$ kubectl patch deployment http-go -p '{"spec": {"minReadySeconds": 10}}'
deployment.extensions/http-go patched
디플로이먼트 업데이트 실행 준비
- 디플로이먼트를 모니터하는 프로그램 실행
$ while true; curl <ip>; sleep 1; done
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
...
디플로이먼트 업데이트 실행
- 새로운 터미널을 열어 이미지 업데이트 실행
$ kubectl set image deployment http-go http-go=gasbugs/http-go:v2
deployment.extensions/http-go image updated
- 모니터링하는 시스템에서 관찰
$ while true; curl <ip>; sleep 1; done
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
Welcome! http-go:v1
...
Welcome! http-go:v1
Welcome! http-go:v2
Welcome! http-go:v2
Welcome! http-go:v1
디플로이먼트 업데이트 실행 결과
- 업데이트한 이력을 확인
- 리비전의 개수는 디폴트로 10개까지 저장
$ kubectl rollout history deployment http-go
deployment.extensions/http-go REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployment http-go http-go=gasbugs/http-go:v2
롤백 실행하기
- 롤백을 실행하면 이전 업데이트 상태로 돌아감
- 롤백을 하여도 히스토리의 리비전 상태는 이전 상태로 돌아가지 않음
$ kubectl set image deployment http-go http-go=gasbugs/http-go:v3
deployment.extensions/http-go image updated
$ kubectl rollout undo deployment http-go
deployment.extensions/http-go
$ kubectl exec http-go-7dbcf5877-d6n6p curl 127.0.0.1:8080
Welcome! http-go:v2
$ kubectl rollout undo deployment http-go --to-revision=1
deployment.extensions/http-go
롤링 업데이터 전략 세부 설정
- maxSurge
- 기본값 25%, 개수로도 설정이 가능
- 최대로 추가 배포를 허용할 개수 설정
- 4개인 경우 25%이면 1개가 설정 (총 개수 5개까지 동시 포드 운영)
- maxUnavailable
- 기본값 25%, 개수로도 설정이 가능
- 동작하지 않는 포드의 개수 설정
- 4개인 경우 25%이면 1개가 설정(총 개수 4-1개는 운영해야 함)
spec:
strategy:
rollingUpdate:
maxSurge: 1
maxUnvailable: 1
type: RollingUpdate
롤아웃 일시중지와 재시작
- 업데이트 중에 일시정지하길 원하는 경우
$ kubectl rollout pause deployment http-go
- 업데이트 일시중지 중 취소
$ kubectl rollout undo deployment http-go
- 업데이트 재시작
$ kubectl rollout resume deployment http-go
업데이트를 실패한 경우
- 업데이트를 실패하는 케이스
- 부족한 할당량(Insufficient quota)
- 레디네스 프로브 실패(Readiness probe failures)
- 이미지 가져오기 오류(Image pull errors)
- 권한 부족(Insufficient permissions)
- 제한 범위(Limit ranges)
- 응용 프로그램 런타임 구성 오류(Application runtime misconfiguration)
- 업데이트를 실패하는 경우에는 기본적으로 600초 후에 업데이트를 중지한다
spec:
processDeadlineSeconds: 600
실습
http-go-deployment.yaml
파일 작성apiVersion: apps/v1 kind: Deployment metadata: name: http-go labels: app: http-go spec: replicas: 3 selector: matchLabels: app: http-go template: metadata: labels: app: http-go spec: containers: - name: http-go image: gasbugs/http-go:v1 ports: - containerPort: 8080
디플로이먼트 생성
$ kubectl create -f http-go-deployment.yaml --record=true deployment.apps/http-go created # rollout을 통해 상태 확인 $ kubectl rollout status deployment http-go deployment "http-go" successfully rolled out # history 확인 $ kubectl rollout history deploy http-go deployment.apps/http-go REVISION CHANGE-CAUSE 1 kubectl create --filename=http-go-deployment.yaml --record=true
디플로이먼트 정보 확인
- 디플로이먼트 상세 정보 확인
$ kuberctl describe deploy http-go
- 디플로이먼트 배포 yaml 파일 정보 확인
$ kubectl get deploy http-go -o yaml
업데이트가 10초정도 준비가 되었다가 실행되게 함
$ kubectl patch deployment http-go -p '{"spec": {"minReadySeconds": 10}}' deployment.extensions/http-go patched
로드밸런싱 생성
$ kubectl expose deploy http-go service/http-go exposed # IP 확인 $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE http-go ClusterIP 10.100.238.9 <none> 8080/TCP 7s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m53s
busybox 이미지를 kubectl 명령으로 생성해 요청 테스트
$ kubectl run -it --rm --image busybox -- bash If you don't see a command prompt, try pressing enter. / # wget -O- -q 10.100.238.9:8080 Welcome! v1
디플로이먼트 모니터링 프로그램 실행
$ while true; do wget -O- -q 10.100.238.9:8080; sleep 1; done Welcome! v1
새탭에서 업데이트 실행
$ kubectl set image deployment http-go http-go=gasbugs/http-go:v2 --record=true deployment.extensions/http-go image updated # v1 에서 v2로 순차적으로 업데이트 됨 $ kubectl get pod -w NAME READY STATUS RESTARTS AGE bash 1/1 Running 0 12m http-go-6c4d9d5989-whbs4 1/1 Running 0 16s http-go-ccb794f48-57q7q 1/1 Running 0 14m http-go-ccb794f48-qht4p 1/1 Running 0 14m http-go-ccb794f48-qxffh 1/1 Running 0 14m http-go-ccb794f48-qxffh 1/1 Terminating 0 14m http-go-6c4d9d5989-825fj 0/1 Pending 0 0s http-go-6c4d9d5989-825fj 0/1 Pending 0 0s http-go-6c4d9d5989-825fj 0/1 ContainerCreating 0 0s http-go-ccb794f48-qxffh 0/1 Terminating 0 14m http-go-6c4d9d5989-825fj 1/1 Running 0 5s http-go-ccb794f48-qxffh 0/1 Terminating 0 14m http-go-ccb794f48-qxffh 0/1 Terminating 0 14m http-go-ccb794f48-qht4p 1/1 Terminating 0 14m http-go-6c4d9d5989-w9cf4 0/1 Pending 0 0s http-go-6c4d9d5989-w9cf4 0/1 Pending 0 0s http-go-6c4d9d5989-w9cf4 0/1 ContainerCreating 0 0s http-go-ccb794f48-qht4p 0/1 Terminating 0 14m http-go-6c4d9d5989-w9cf4 1/1 Running 0 1s http-go-ccb794f48-57q7q 1/1 Terminating 0 14m http-go-ccb794f48-57q7q 0/1 Terminating 0 14m http-go-ccb794f48-qht4p 0/1 Terminating 0 14m http-go-ccb794f48-qht4p 0/1 Terminating 0 14m http-go-ccb794f48-57q7q 0/1 Terminating 0 14m http-go-ccb794f48-57q7q 0/1 Terminating 0 14m # history 확인 $ kubectl rollout history deploy http-go deployment.apps/http-go REVISION CHANGE-CAUSE 1 kubectl create --filename=http-go-deploy-v1.yaml --record=true 2 kubectl set image deployment http-go http-go=gasbugs/http-go:v2 --record=true
edit로 수정
$ kubectl edit deploy http-go --record=true
v3로 수정
spec: containers: - image: gasbugs/http-go:v3
신규 ReplicaSet 생성확인
$ kubectl get all ... NAME DESIRED CURRENT READY AGE replicaset.apps/http-go-6c4d9d5989 3 3 3 8m35s replicaset.apps/http-go-855b9bcff4 1 1 1 8s replicaset.apps/http-go-ccb794f48 0 0 0 22m
history 확인
kubectl rollout history deploy http-go deployment.apps/http-go REVISION CHANGE-CAUSE 1 kubectl create --filename=http-go-deployment.yaml --record=true 2 kubectl set image deployment http-go http-go=gasbugs/http-go:v2 --record=true 3 kubectl edit deploy http-go --record=true
롤백 실행
$ kubectl rollout undo deploy http-go deployment.apps/http-go rolled back
history 2가 사라지고 4가 추가되면서 v3가 v2로 롤백됨을 확인
kubectl rollout history deploy http-go deployment.apps/http-go REVISION CHANGE-CAUSE 1 kubectl create --filename=http-go-deployment.yaml --record=true 3 kubectl edit deploy http-go --record=true 4 kubectl set image deployment http-go http-go=gasbugs/http-go:v2 --record=true
버전을 지정하여 롤백하기
$ kubectl rollout undo deploy http-go --to-revision=1 deployment.apps/http-go rolled back $ kubectl rollout history deploy http-go deployment.apps/http-go REVISION CHANGE-CAUSE 3 kubectl edit deploy http-go --record=true 4 kubectl set image deployment http-go http-go=gasbugs/http-go:v2 --record=true 5 kubectl create --filename=http-go-deploy-v1.yaml --record=true
연습문제
- 다음 alpine 이미지를 사용하여 업데이트와 롤백을 실행하라
모든 revision 내용은 기록돼야 한다- alpine:3.4 이미지를 사용하여 deployment를 생성하라
- Replicas: 10
- maxSurge: 50%
- maxUnavailable: 50%
- alpine:3.4 이미지를 사용하여 deployment를 생성하라
alpine-deploy.yaml
생성apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: alpine-deploy name: alpine-deploy spec: replicas: 10 selector: matchLabels: app: alpine-deploy strategy: type: RollingUpdate rollingUpdate: maxSurge: 50% maxUnavailable: 50% template: metadata: creationTimestamp: null labels: app: alpine-deploy spec: containers: - image: alpine:3.4 name: alpine resources: {} status: {}
디플로이 먼트 생성
$ kubectl create -f alpine-deploy.yaml --record=true deployment.apps/alpine-deploy created $ kubectl rollout history deploy alpine-deploy deployment.apps/alpine-deploy REVISION CHANGE-CAUSE 1 kubectl create --filename=alpine-deploy.yaml --record=true
alpine:3.5 롤링 업데이트를 수행하라
edit 명령으로 업데이트
$ kubectl edit deploy alpine-deploy --record=true
alpine:3.5 로 변경 후 저장
spec: containers: - image: alpine:3.5
확인
$ kubectl get rs NAME DESIRED CURRENT READY AGE alpine-deploy-5bf4b7b6c9 10 10 0 27m alpine-deploy-8659f8ff96 4 4 0 32m
alpine:3.6 롤링 업데이트
$ kubectl edit deploy alpine-deploy --record=true
alpine:3.6 으로 변경 후 저장
spec: containers: - image: alpine:3.6
확인
$ kubectl get rs NAME DESIRED CURRENT READY AGE alpine-deploy-5bf4b7b6c9 4 4 0 3m51s alpine-deploy-764d477998 10 10 0 77s alpine-deploy-8659f8ff96 0 0 0 6m39s $ kubectl rollout history deploy alpine-deploy deployment.apps/alpine-deploy REVISION CHANGE-CAUSE 1 kubectl create --filename=alpine-deploy.yaml --record=true 2 kubectl edit deploy alpine-deploy --record=true 3 kubectl edit deploy alpine-deploy --record=true
alpine:3.4로 롤백을 수행하라
$ kubectl rollout undo deploy alpine-deploy --to-revision=1 deployment.apps/http-go rolled back $ kubectl rollout history deploy alpine-deploy deployment.apps/alpine-deploy REVISION CHANGE-CAUSE 2 kubectl edit deploy alpine-deploy --record=true 3 kubectl edit deploy alpine-deploy --record=true 4 kubectl create --filename=alpine-deploy.yaml --record=true
명령어가 잘되는지만 확인 --dry-run=client
$ kubectl create deploy --image alpine:3.4 alpine-deploy --dry-run=client
명령어가 잘되는지만 확인하는 yaml 파일로 출력
$ kubectl create deploy --image alpine:3.4 alpine-deploy --dry-run=client -o yaml
728x90
'개발강의정리 > DevOps' 카테고리의 다른 글
[데브옵스를 위한 쿠버네티스 마스터] 쿠버네티스 핵심 개념-Services (0) | 2020.12.27 |
---|---|
[데브옵스를 위한 쿠버네티스 마스터] 쿠버네티스 핵심 개념-Namespaces (0) | 2020.12.27 |
[데브옵스를 위한 쿠버네티스 마스터] 쿠버네티스 핵심 개념-디플로이먼트 (0) | 2020.12.01 |
[데브옵스를 위한 쿠버네티스 마스터] 쿠버네티스 핵심 개념-레플리케이션 컨트롤러와 레플리카셋 (0) | 2020.12.01 |
[데브옵스를 위한 쿠버네티스 마스터] 쿠버네티스 핵심 개념-레이블을 이용한 포드 구성 (0) | 2020.11.27 |
댓글