티스토리 뷰
Deployment
- Controller인 ReplicaSet을 제어해주는 부모 역할을 한다.
- Deployment는 Rolling Update를 목적으로 만들어졌다.
- Deployment를 만들면 Deployment가 ReplicaSet을 만든다. 이때 Deployment는 실행시킬 Pod의 버전과 replicas를 ReplicaSet에게 전달한다. 그 후엔 ReplicaSet이 전달받은 정보를 기반으로 Pod를 생성하고 Pod 수를 보장하게 된다.
- 즉, Deployment가 ReplicaSet을 컨트롤하고 ReplicaSet이 Pod를 컨트롤하는 구조이다.
- 정리하자면, Deployment는 ReplicaSet Controller를 관리해서 Pod 수를 보장하고, 추가적으로 Rolling update를 지원하여 무중단으로 버전 업데이트를 지원한다.
- ReplicaSet과 Deployment의 차이는 Rolling Update의 사용 여부에 따라 결정하면 된다. 두 API의 definition file(yaml)도 kind 필드를 제외하고는 대부분이 동일하다. 즉, Deployment만으로도 ReplicaSet을 운영할 수 있다.
cf. Rolling Update란?
- 롤링 업데이트는 Pod를 하나씩 점진적으로 업데이트하여 새로운 버전으로 만들어서 Deployment 업데이트가 서비스 중단 없이 이루어질 수 있도록 해준다.
- 예시: Deployment를 이용해서 ReplicaSet에 nginx1.14를 실행시키면 서비스 중단 없이 pod(nginx)의 버전을 업데이트시킬 수 있게 한다.
- Deployment는 이러한 Rolling Update를 목적으로 만들어진 API 리소스이다. Pod의 버전을 서비스 중단 없이 업데이트(Rolling Update)하고 싶다면 Deployment로 요청하면 된다.
- 추가적으로, Rolling Back은 이전 버전으로 되돌아가는 것을 의미한다.
Rolling Update 과정
롤링 업데이트가 시작되면 Deployment는 새로운 ReplicaSet 컨트롤러를 생성하고 새로운 버전의 컨테이너의 replicas를 1부터 시작한다. 그리고 해당 Pod(컨테이너)가 Running 상태가 되면 기존 ReplicaSet의 replicas를 1 줄인다. 이때 가장 오래된 Pod 하나가 삭제된다. 그리고 새로운 ReplicaSet의 replicas를 2로 늘리고 위 과정을 반복한다.
1) Deploy를 처음 실행했을 때 상태
2) 컨테이너를 1:15 버전으로 실행 (kubectl set image deployment)
- 새로운 Pod가 실행되면 기존 버전의 Pod를 삭제
3) 최종
위와 같이 Rolling Update는 Pod를 '점진적으로' 업데이트하여 '서비스 중단 없이' Pod가 업데이트될 수 있도록 한다.
실습
- deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
spec:
replicas: 3
selector:
matchLabels:
app: webui
template:
metadata:
name: nginx-pod
labels:
app: webui
spec:
containers:
- name: nginx-container
image: nginx:1.14
출처: https://github.com/237summit/Getting-Start-Kubernetes/blob/main/6/deploy-nginx.yaml
deployment 실행 후 확인
- Deploy, RS, Pod의 이름을 보면 알 수 있듯이, 부모의 이름이 앞에 붙는 형식이다. 따라서 Pod의 부모는 RS이고, RS의 부모는 Deploy임을 확인할 수 있다.
RS 삭제 후 확인
- RS를 삭제해도 Deployment에 의해 다시 생성되었음을 확인할 수 있다.
- Deploy가 RS를 컨트롤하는 API이기 때문에 deploy를 삭제해야 RS, Pod가 삭제된다.
Deployment로 Rolling Update/RollBack 하기
- deployment에서 Rolling Update를 지원하기 위해, kubectl set image 커맨드를 지원한다.
1) rolling update 사용법
$ kubectl set image deployment <deploy_name> <container_name>=<new_version_image> --record
* Pod는 2개 이상의 컨테이너를 포함할 수 있기 때문에 container_name에서 업데이트할 컨테이너 이름을 명시해 줘야 한다.
* --record 옵션을 설정하지 않으면 history를 남기지 않기 때문에 롤백할 수 없다.
cf. kubectl set 커맨드
- kubectl set 커맨드는 애플리케이션 리소스를 설정하는 커맨드로 env, image, resources, selector, serviceaccount, subject를 업데이트하거나 변경할 수 있다.
- 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
출처: https://github.com/237summit/Getting-Start-Kubernetes/blob/main/6/deployment-exam1.yaml
nginx1.14 실행 후 1.15로 롤링 업데이트
* --record 옵션을 붙여야 현재 버전에 대한 히스토리를 남긴다. 즉, --record를 사용하지 않으면 rollback을 할 수 없다.
버전 확인
- deploymenet에 의해 실행 중인 pod 중 하나를 kubectl describe 커맨드로 확인해본 결과 1.15로 롤링 업데이트되었음을 확인할 수 있다.
- 같은 방식으로 1.17 버전까지 올린 후 아래와 같이 리비전을 확인해본다.
[revision history 확인]
가장 마지막 revision이 현재의 deployment이다. revision 개수는 제한되어 있는데 default 값은 10이며 deployment yaml 파일에서 revisionHistoryLimit 필드를 사용하여 수정할 수 있다. revision 1번은 처음 deployment를 생성했을 때의 revision인데, 이때 --record를 설정하지 않았다면 해당 revision 1번은 <node>으로 보이게 된다. 이 경우 롤백을 할 수 없다.
2) rollback 사용법
# 1. revision history 확인
$ kubectl rollout history deployment <deploy_name>
# 2-1. 실제 rollback 진행 (가장 최신 revision)
$ kubectl rollout undo deploy <deploy_name>
# 2-2. 실제 rollback 진행 (revision 번호 지정)
$ kubectl rollout undo deploy <deploy_name> --to-revision=<NUMBER>
- kubectl rollout 커맨드
ubuntu@master:~/k8s-practice$ kubectl rollout --help
Available Commands:
history View rollout history
pause Mark the provided resource as paused
restart Restart a resource // 방금 시작한 업데이트 재시작
resume Resume a paused resource // 일시 중지된 업데이트 재시작
status Show the status of the rollout
undo Undo a previous rollout // 업데이트 롤백
rollout 커맨드는 위와 같이 다양한 형태로 제공된다. 가장 아래 undo를 사용하면 Rolling Update에 대한 롤백을 진행할 수 있다.
- rollout undo 커맨드를 사용해서 이전 버전으로 롤백했더니 revision 순서에 가장 최신으로 변경되었음을 확인할 수 있다.
- undo 커맨드에서 --to-revision을 명시하지 않으면 가장 이전의 버전으로 롤백된다.
- 3번 revision으로 롤백했기 때문에 history 상에서는 3번 revision이 보이지 않고 해당 revision이 5번(현재 revision)으로 변경되었다. 만약 위 상태에서 최신 버전으로 롤백하면 revision은 1, 2, 5, 6이 될 것이고 기존 4번 revision이 6번 revision이 된다.
- kubectl delete로 deploy를 삭제하면 rollout history를 확인할 수 없으니 주의해야 한다.
cf. deployment yaml 파일 추가 필드
- 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
출처: https://github.com/237summit/Getting-Start-Kubernetes/blob/main/6/deployment-exam2.yaml
1) revisionHistoryLimit
- 최대로 남길 revision 개수에 대한 설정이다.
2) progressDeadlineSeconds (default 600)
- 업데이트를 위한 timeout이다. 설정한 시간 내에 업데이트하지 못하면 업데이트를 취소한다. default 값은 600이다.(10분)
3) maxSurge (default 25%)
- 현재 설정된 replicas 개수의 maxSurge(%) 개수만큼 업데이트를 동시에 진행한다. 한 번에 많이 업데이트하면 업데이트가 빨라질 것이다. 즉, 얼마나 빠르게 업데이트할 것인지를 설정하는 것이다.
- 예시: replicas가 3이고 maxSurge가 25%라고 가정하면 3의 25%는 0.75(반올림하면 1)이다. 즉, Rolling Update시 1개씩 점진적으로 업데이트하도록 설정한 것이다. 반대로 maxSurge가 50%이면 3의 50%는 1.5(반올림하면 2)이다. 따라서 이 경우에는 2개씩 동시에 Rolling Update를 진행한다.
4) maxUnavailable (default 25%)
- 동시에 Terminating 하는 개수를 지정한다.
5) type
- RollingUpdate는 롤링 업데이트를 적용하겠다는 의미이며, 이 외 Recreate type이 있는데 이는 기존 Pod를 먼저 삭제하고 새로운 Pod를 실행시키는 전략이다.
6) annotations
annotations를 활용해서 쿠버네티스의 동작 방식을 컨트롤할 수 있다. 그중 하나가 annotations필드에 change-cause를 활용하는 것인데, 위와 같이 change-cause에 버전을 명시하고 추후 Rolling Update가 필요한 시점에 위 파일의 change-cause의 버전 부분을 변경하면 커맨드 없이도 자동으로 Rolling Update가 진행된다. 즉, yaml 파일을 기반으로 Rolling Update를 진행할 수 있다.
cf. 롤링 업데이터 일시정지 또는 재시작 활용
'kubectl rollout < pause / resume > deployment <deploy_name>' 커맨드로 deployment의 롤링 업데이트를 일시 정지하거나 재시작할 수 있다. 이는 새로운 버전의 pod를 일부 업데이트한 후 모니터링하여 정상적으로 수행 중인지를 확인하는 데 사용된다. 모니터링 결과 새로운 버전에 문제가 없다면 롤링 업데이트를 resume 하여 재시작한다.
annotations의 change-cause 기반으로 Rolling Update 실습
위 deployment-exam2.yaml 파일의 annotation을 기반으로 Rolling Update를 실습한다.
1) deployment 실행 후 deployment 파일 수정
2) deployment 파일 수정: 버전 변경
- 위와 같이 annotations의 change-cause 부분과 template, containers의 image 버전을 모두 변경해야 한다.
3) 변경사항 적용
4) 변경 정보 확인
- kubectl describe pod 커맨드로 실행 중인 pod 중 하나를 확인한 결과 버전업이 정상적으로 반영되었음을 확인할 수 있다.
- history에도 정상적으로 반영되어 있다.
위와 같이 annotation을 기반으로 Rolling Update 하는 방식을 활용하면 최신 버전의 정보를 yaml 파일로 남겨둘 수 있기 때문에 관리에 더욱 용이하다.
Reference
- 따배쿠, https://youtu.be/L5LDBWrP6QU
- k8s docs 롤링 업데이트, https://kubernetes.io/ko/docs/tutorials/kubernetes-basics/update/update-intro/
- update type, https://www.kubermatic.com/blog/introduction-to-deployment-strategies/
'[ DevOps ] > [ k8s ]' 카테고리의 다른 글
[k8s] Controller - StatefulSet(sf) (0) | 2022.09.22 |
---|---|
[k8s] Controller - DaemonSet (0) | 2022.09.16 |
[k8s] Controller - ReplicaSet(RS) (0) | 2022.09.11 |
[k8s] Controller - ReplicationController(RC) (0) | 2022.09.10 |
[k8s] Controller, Control Loop, Custom Controller, Operator (0) | 2022.09.10 |
- Total
- Today
- Yesterday
- 컨트롤러
- Kubernetes
- CICD
- helm
- Non-Blocking
- 쿠버네티스
- LFCS
- jvm
- Linux
- 카프카
- spring
- RDB
- kafka
- docker
- golang
- 우분투
- go
- Java
- db
- Stream
- github actions
- Controller
- 코틀린
- argocd
- rolling update
- ci/cd
- ubuntu
- GitOps
- container
- K8s
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |