- ReplicationController
- ReplicaSet
- Deployment ← 오늘 볼 내용
- DaemonSet
- StatefulSet
- Job
- CronJob
3. Deployment
Deployment은 쿠버네티스에서 애플리케이션을 배포하고 관리하기 위한 리소스 오브젝트 중 하나다.
주로 파드를 관리하는데 사용되며, 쿠버네티스 클러스터에서 어플리케이션의 업데이트, 롤백, 스케일링 등을 쉽게 처리할 수 있게 해준다.
Deployment는 Rolling update를 목적으로 만들어졌으며 이전에 본 ReplicaSet의 상위 오브젝트다.
- Rolling update : 파드 인스턴스를 점진적으로 새로운 것으로 업데이트하여 디플로이먼트 업데이트가 서비스 중단 없이 이루어질 수 있도록 해주는 것
Deployment definition
ReplicaSet definition | Deployment definition |
apiVersion: apps/v1 kind: ReplicaSet metadata: name: rs-nginx spec: replicas: 3 selector: matchLabels: app: webui template: metadata: labels: app: webui spec: containers: - name: nginx-container image: nginx:1.25 |
apiVersion: apps/v1 kind: Deployment metadata: name: deploy-nginx spec: replicas: 3 selector: matchLabels: app: webui template: metadata: labels: app: webui spec: containers: - name: nginx-container image: nginx:1.25 |
왼쪽과 오른쪽의 차이는 kind만 변경되었을 뿐 아무런 변화가 없다.
즉, Deployment만으로도 ReplicaSet의 운영이 가능하다.
Deployment 생성
위 yaml코드를 그대로 사용한다.
# deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
spec:
replicas: 3
selector:
matchLabels:
app: webui
template:
metadata:
labels:
app: webui
spec:
containers:
- name: nginx-container
image: nginx:1.25
Deployment의 동작 순서
그렇다면 파드는 어떤 순서로 만들어졌을까?
# Deployment, ReplicaSet, Pod 정보 확인
kubectl get Deploy,rs,po
순서는 다음과 같다.
- deploy-nginx라는 이름의 Deployment를 생성한다.
- Deployment는 자신의 이름을 따서 deploy-nginx-d894fc95c라는 이름의 ReplicaSet을 생성한다.
- ReplicaSet은 자신의 이름을 따서 deploy-nginx-d894fc95c-djmms라는 이름의 Pod를 생성한다.
즉, Deployment는 ReplicaSet을 제어하고 ReplicaSet은 Pod를 제어한다.
ReplicaSet을 통해 Pod의 개수를 보장하고 Deployment를 통해 ReplicaSet 컨트롤러의 동작을 보장한다.
Pod를 삭제하면 ReplicaSet이 다시 생성해주고 ReplicaSet을 삭제하면 Deployment가 다시 생성하도록 운영된다.
Deployment Rolling Update & Roll Back(1)
Rolling Update 사용법
kubectl set image deployment <deploy_name> <container_name>=<new_version_image>
RollBack 사용
kubectl rollout history deployment <deploy_name>
kubectl rollout undo deploy <deploy_name>
kubectl set 커맨드
kubectl set은 쿠버네티스 리소스의 특정 필드를 업데이트하는 데 사용되는 명령입니다.
이 명령을 사용하면 리소스의 특정 필드 값을 변경하거나 수정할 수 있습니다.
Rolling Update 동작과정
1. 기존 버전의 ReplicaSet으로 인해 ngnix:1.14컨테이너가 들어있는 파드 3개가 실행중이다.
2. 관리자가 버전 업데이트를 위해 명령어를 입력한다.
3. Deployment는 새로운 버전의 ReplicaSet을 생성하고 nginx:1.15컨테이너가 들어있는 파드 1개를 실행한다.
4. 기존 버전의 ReplicaSet의 replicas를 2로 변경한다.
5. 새로운 버전의 ReplicaSet의 replicas를 2로 변경한다.
6. 기존 버전의 ReplicaSet의 replicas를 1로 변경한다.
7. 새로운 버전의 ReplicaSet의 replicas를 3로 변경한다.
8. 기존 버전의 ReplicaSet을 제거한다.
Deployment 예제 - 1
Deployment 실행
# deploy-exam1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deploy
spec:
replicas: 3
selector:
matchLabels:
app: webui
template:
metadata:
labels:
app: webui
spec:
containers:
- name: web
image: nginx:1.22
ports:
- containerPort: 80
protocol: TCP
위 코드대로 yaml파일을 생성하고 아래 명령을 실행한다.
# yaml파일 실행
kubectl create -f deploy-exam1.yaml --record
이번에는 '--record' 라는 옵션을 기재하여 실행했다.
'--record' 는 현재 버전 정보를 기록하는 것으로 만약 기재하지 않고 실행하면 이후 rollback할 수 없다.
위와 같이 기재하지 않고 실행하면 <none>이라고 표시되며 정보가 기록되지 않는다.
실행해보면 다음과 같이 사용되지 않는 플래그라 미래에 없어질 것이라 주의를 주지만 일단 무시한다.
kubectl set image - Rolling Update
# Rolling Update
kubectl set image deployment app-deploy web=nginx:1.23 --record
위 캡처와 같이 Rolling Update가 되는 과정에서 파드들이 생성되고 종료되는 과정을 거쳐서 업데이트가 완료된다.
kubectl rollout status - 업데이트 과정 화면에 출력
중간중간 상태의 변화를 자세하게 보고 싶다면 다음 명령을 입력한다.
대신 이런 단순한 업데이트는 순식간에 끝나기 때문에 업데이트가 실행 중일 때 명령을 빠르게 입력해야 한다.
# Rolling Update 상태변화 상세하게 확인
kubectl rollout status deployment app-deploy
kubectl rollout [ pause / resume ] - 업데이트 일시정지 / 재개
'kubectl rollout [ pause / resume ]' 을 통해 업데이트를 일시정지하거나 재개할 수 있다.
# 업데이트 일시정지 및 재개
kubectl rollout pause deployment app-deploy
kubectl rollout resume deployment app-deploy
여러 버전으로 Rolling Update
다양한 버전으로 업데이트 해보고 여러 명령을 입력해보면서 각각의 결과를 확인해본다.
# 버전을 하나씩 증가시키며 결과 확인
kubectl set image deployment app-deploy web=nginx:1.24 --record
kubectl set image deployment app-deploy web=nginx:1.25 --record
kubectl rollout restart - 업데이트 재실행
Rolling Update 과정에 준하여 해당 리소스의 모든 파드를 재시작한다.
# Rolling Update 재실행
kubectl rollout restart deployment app-deploy
kubectl rollout history - 업데이트 기록 확인
업데이트의 했던 기록을 확인한다.
# 버전 업데이트 기록 확인
kubectl rollout history deployment app-deploy
kubectl rollout undo - Rollback
이전 업데이트로 되돌린다.
'--to-revision' 옵션을 사용하면 원하는 revision으로 되돌릴 수 있다.
# 바로 이전 단계로 Rollback
kubectl rollout undo deployment app-deploy
# 원하는 revision으로 Rollback -> 아래 명령은 1.23버전으로 이동
kubectl rollout undo deployment app-deploy --to-revision=2
아래는 revision=2로 롤백한 캡처화면이다.
REVISION을 보면 뒤로 롤백을 하기 전에는 버전 순서별로 1, 2, 3, 4 였지만
롤백한 이후에는 롤백 시점의 REVISION이 2에서 5로 변경되었고 2는 없어졌다.
방금 롤백을 했기에 현재는 1.23인데 여기서 --to-revision을 입력하지 않고 롤백을 하면 다시 1.25로 돌아간다.
아주 이전의 버전으로 롤백하기 위해 뒤에 --to-revision 을 입력하지 않고 계속 롤백 명령만 입력하면 두 버전에서만 왔다갔다 하는 상황이 벌어지니 과거로 돌아가고 싶으면 반드시 --to-revision 을 입력해서 원하는 revision으로 이동하자.
Deployment Rolling Update & Roll Back(2)
yaml파일에 추가적인 필드를 입력하여 Rolling Update하는 과정을 원하는 대로 커스터마이징 가능하다.
apiVersion: apps/v1 kind: Deployment metadata: name: app-deploy annotations: kubernetes.io/change-cause: version 1.22 spec: progressDeadlineSeconds: 600 revisionHistoryLimit: 10 strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate replicas: 3 selector: matchLabels: app: web |
- annotations : 특별한 주석. 위에서는 변경 원인을 나타내는 주석으로 "version 1.22"로 지정
- progressDeadlineSeconds : 업데이트 완료가 입력한 시간(초)동안 완료되지 않으면 업데이트 취소
- revisionHistoryLimit : 해당 Deployment에서 '--record' 옵션을 통해 기록될 업데이트의 최대 개수
- strategy : 업데이트 전략을 정의
- rollingUpdate : 롤링 업데이트 전략을 사용함을 나타냄
- maxSurge(%) : 업데이트 중에 새로운 버전의 파드 수가 현재 파드 수 대비 최대 몇%까지 늘어날 수 있도록 허용
- maxUnavailable(%) : 업데이트 중에 현재 버전의 파드 중 최대 몇%가 동시에 사용 불가능하게 되도록 진행
- type: RollingUpdate : 롤링 업데이트 전략을 사용함을 명시
Deployment 예제 - 2
Deployment 실행
# deploy-exam2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deploy
annotations:
kubernetes.io/change-cause: version 1.22
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.22
ports:
- containerPort: 80
protocol: TCP
위 코드대로 yaml파일을 생성하고 아래 명령을 실행한다.
# kubectl apply 명령으로 yaml파일 실행
kubectl apply -f deploy-exam2.yaml
이번에는 처음과 다르게 create가 아닌 apply를 사용하여 yaml파일을 실행했다.
kubectl apply로 롤링 업데이트를 하는 것이 더 간단하며 많이 쓰인다.
더 알아보고 싶으면 아래를 참조.
kubectl create와 kubectl apply의 차이
kubectl create:
1. kubectl create 명령어는 주어진 YAML 또는 JSON 파일에서 새로운 쿠버네티스 오브젝트를 생성합니다.
2. 새로운 오브젝트를 생성할 때만 사용되며, 이미 존재하는 오브젝트에 대해서는 오류를 발생시킵니다.
3. 오브젝트를 생성할 때마다 kubectl create를 사용하면 오브젝트의 버전을 증가시키지 않고 오브젝트를 새로 만듭니다.
kubectl apply:
1. kubectl apply 명령어는 주어진 YAML 또는 JSON 파일에서 쿠버네티스 오브젝트를 생성하거나 업데이트합니다.
2. 오브젝트가 이미 존재하는 경우 해당 오브젝트를 업데이트하고, 없는 경우에는 새로운 오브젝트를 생성합니다.
3. kubectl apply는 오브젝트를 "원하는 상태"로 유지하도록 설계되었으며, 동일한 리소스를 여러 번 적용해도 동일한 상태가 유지됩니다.
일반적으로는
kubectl apply 를 사용하는 것이 더 유용하며, 특히 동일한 오브젝트를 여러 번 적용해야 할 때 유용합니다.
kubectl apply 는 변경 사항만 적용하므로 현재 상태와 원하는 상태가 일치하면 아무 작업도 수행하지 않습니다.
URL 참조
https://stackoverflow.com/questions/47369351/kubectl-apply-vs-kubectl-create
Rolling Update
vi 에디터를 열어서 annotation의 1.22를 1.23으로 컨테이너 이미지의 버전을 1.22에서 1.23으로 변경하고 저장한다.
# 방금 전과 같은 명령
kubectl apply -f deploy-exam2.yaml
yaml파일의 버전 정보만 수정하고 apply명령을 실행했더니 그대로 적용되면서 Rolling Update가 시작되었다.
실행 결과
버전도 1.23으로 변경된 것을 확인
업데이트 기록 결과
history까지 적용된 것 확인
실행 과정도 결과도 훨씬 간결하다.
무슨 방법을 사용하든 자유지만 개인적으로는 kubectl apply 명령을 사용하여 롤링 업데이트를 수행하는 것이 더 간단하고 쉬워보인다.
아까 '--record' 옵션이 곧 사라질 옵션이라고 하는 이유를 알 것같다.
이왕이면 쉽고 간단한 방법을 쓰는게 좋을 것 같다.
실습
1. 다음의 조건으로 Deployment를 사용하는 dep-lab.yaml 파일을 생성하고 apply 명령으로 동작시킵니다.
- labels(name: apache, app: main, rel: stable)을 가지는 httpd:2.2 버전의 Pod 2개를 히스토리를 기록하며 운영합니다.
- annotations(kubernetes.io/change-cause: version 2.2)를 추가로 설정합니다.
- deployment name : dep-mainui
- container : httpd:2.2
(선택사항)
- progressDeadlineSeconds은 60로 지정합니다.
- revisionHistoryLimit는 10으로 지정합니다.
- strategy를 설정합니다(maxSurge: 50%, maxUnavailable: 50%)
- port는 80번 TCP를 쓰도록 지정합니다.
- selector를 설정합니다.
- 라벨 app: main은 반드시 포함해야하도록 matchLabels을 작성
- rel키이름이 존재하면 선택하도록 matchExpressions를 작성
- name이라는 키에 apache라는 값이 포함되도록 matchExpressions를 작성
2. 동작되는 dep-lab.yaml의 이미지를 httpd:2.4 버전으로 rolling update 합니다.
단, apply 명령을 통해 rolling update를 진행합니다.
3. 현재의 dep-mainui 히스토리(history)를 확인하고 rollback시킵니다.
4. 현재 동작중인 Pod의 httpd 이미지 버전은 어떻게 되는지 확인합니다.
1번 답안
# dep-lab.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep-mainui
annotations:
kubernetes.io/change-cause: version 2.2
spec:
replicas: 2
progressDeadlineSeconds: 60
revisionHistoryLimit: 10
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
type: RollingUpdate
selector:
matchLabels:
app: main
matchExpressions:
- {key: rel, operator: Exists}
- {key: name, operator: In, values: [apache]}
template:
metadata:
labels:
app: main
rel: stable
name: apache
spec:
containers:
- name: apache-container
image: httpd:2.2
ports:
- containerPort: 80
protocol: TCP
2번 답안
# vi 에디터를 통해 아래처럼 버전 정보를 수정 후 kubectl apply 명령 입력
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep-mainui
annotations:
kubernetes.io/change-cause: version 2.4
spec:
replicas: 2
progressDeadlineSeconds: 60
revisionHistoryLimit: 10
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
type: RollingUpdate
selector:
matchLabels:
app: main
matchExpressions:
- {key: rel, operator: Exists}
- {key: name, operator: In, values: [apache]}
template:
metadata:
labels:
app: main
rel: stable
name: apache
spec:
containers:
- name: apache-container
image: httpd:2.4
ports:
- containerPort: 80
protocol: TCP
3번 답안
# 1번 history 버전으로 rollback
kubectl rollout undo deploy dep-mainui --to-revision=1
# 이전 history 버전으로 rollback
kubectl rollout undo deploy dep-mainui
4번 답안
# 컨테이너의 이미지 버전확인
kubectl describe deploy dep-mainui
아래 영상을 참고했습니다.
https://youtube.com/playlist?list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&si=hbPclcPuc-6lTNdE
'Kubernetes' 카테고리의 다른 글
Kubernetes 기초 - Controller(5) (0) | 2023.12.14 |
---|---|
Kubernetes 기초 - Controller(4) (0) | 2023.12.14 |
Kubernetes 기초 - Controller(2) (0) | 2023.12.12 |
Kubernetes 기초 - Controller(1) (0) | 2023.12.11 |
Kubernetes 기초 - Namespace (0) | 2023.12.11 |