일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- vue
- hive
- 자동
- spring
- aws
- Docker
- config
- 클러스터
- Kafka
- java
- fastcampus
- Zeppelin
- 설정
- 간단
- 로그인
- 예제
- SpringBoot
- gradle
- Redis
- Cluster
- login
- 자바
- 레디스
- redash
- ec2
- 머신러닝
- 젠킨스
- Mac
- Jenkins
- EMR
- Today
- Total
코알못
[kubernetes] Deployment 란? 본문
이전 시간에는 ReplicaSet 을 통해 새 버전으로 배포하는 방법을 배웠다.
다시 복습하자면 세개의 작업을 통해 롤백이 가능하다.
- 새 버전으로 template 수정
- 기존 버전 파드 삭제 (scale 또는 lable 변경)
- 새 버전 파드 생성
만약 장애 상황이라면 급하게 해당 작업을 처리해야하는 상황이 오기도 한다.
사람이 아닌 쿠버네티스가 자동으로 해줄수 없을까? > Deployment 오브젝트를 사용하면 된다!
Deployment는 Pod 배포 자동화를 위한 오브젝트로 새로운 Pod를 롤아웃/롤백 할때 ReplicaSet 생성, Pod 복제를 대신 해준다.
Deployment는 ReplicaSet을 이용하여 배포하며 아래와 같이 두가지 배포 전략을 가지고 있다.
배포전략 | 설명 |
Recreate | 모든 이전 파드를 종료하고 새로운 파드를 생성 (서비스 다운 타임 발생) 모두 종료하고 새 파드를 생성하니 Replicas 수 만큼만 리소스 필요 개발 단계에서 사용하기 좋음 |
RollingUpdate | 이전 파드를 종료 하면서 새로운 파드를 생성 (서비스 다운 타임이 발생 하지 않음) 이전 파드와 새로운 파드가 공존하므로 Replicas 수 이상의 컴퓨팅 리소스 필요 |
배포 속도도 아래 옵션을 통해 조정이 가능하다.
제어 옵션 | 내용 |
maxUnavaliable | Running 상태로 되어 있어야 하는 Pod 비율 만약 70 이라고 하면 70%는 running 이 되어 있어야 하므로(이전,새 파드의 합) 30% 파드는 즉시 종료가 가능하다. |
maxSurge | 최대 추가 Pod 비율 만약 30이라고 하면 파드 수의 합이 130%를 넘을수 없다. |
롤백의 경우에는 버전 정보를 가지고 쉽게 롤백 할 수 있다.
Deployment는 Revision 으로 버전을 관리하며 숫자가 클수록 최신이며 배포 기록(Lable,containers 정보)을 가지고 있어 히스토리를 알 수 있다.
그리고 배포 기록 조회시 확인 가능한 pod-template-hash 라는 값은 template 값을 해쉬값으로 만든 것이므로 같은 값이라고 하면 같은 파드라고 볼 수 있다.
아래와 같은 방법으로 특정 버전(vision 1)으로 롤백 한다.
kubectl rollout undo deployment <deployment name> --to-revision=1
이제 부터 Deployment 오브젝트로 배포한 파드를 수정하는 실습 세가지 1) replica 수 늘리기 2) pod의 image 수정 3) pod의 label 수정을 진행한다.
1) replica 수 늘리기
Deployment yaml 파일을 작성해보자!
ReplicaSet과 동일하며 kind만 RepliaSet이 아닌 Deployment로 변경하면 된다.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
클러스터에 적용하고 확인해보면 정상적으로 2개의 파드가 배포 된것을 볼 수 있다.
$ kubectl apply -f deployment.yaml
deployment.apps/my-app created
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-app-5d6554bfbf-6n9zp 1/1 Running 0 15s 10.100.2.15 gke-corin-cluster-default-pool-d2d86113-zy02 <none> <none>
my-app-5d6554bfbf-ww25v 1/1 Running 0 15s 10.100.3.20 gke-corin-cluster-default-pool-d2d86113-xq03 <none> <none>
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
my-app-5d6554bfbf-6n9zp 1/1 Running 0 42s app=my-app,pod-template-hash=5d6554bfbf
my-app-5d6554bfbf-ww25v 1/1 Running 0 42s app=my-app,pod-template-hash=5d6554bfbf
deployment 상세정보를 보기 위해 아래와 같이 describe를 사용한다.
Deployment Events를 보면 ReplicaSet 'my-app-5d6554bfbf' 를 통해 2개의 파드로 Scaled up 한 것을 볼 수 있으며
$ kubectl describe deployment my-app
Name: my-app
Namespace: default
CreationTimestamp: Sat, 20 May 2023 20:40:21 +0900
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-app
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: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:1.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-5d6554bfbf (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 109s deployment-controller Scaled up replica set my-app-5d6554bfbf to 2
Deployment에 의해 생성된 ReplicaSet 정보를 보면 2개의 파드를 원하며(desired) 현재 생성된 파드(current)는 2개 이며 사용할 준비된 파드(ready)는 2개라고 나온다.
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
my-app-5d6554bfbf 2 2 2 3m2s
deployment 의 경우 rollout 작업이 완료 되었는지 아래 명령어로 확인도 가능하다.
$ kubectl rollout status deployment/my-app
deployment "my-app" successfully rolled out
이제 scale 명령어를 통해 repliaca를 5개로 늘려본다.
$ kubectl scale deployment/my-app --replicas=5
deployment.apps/my-app scaled
describe로 확인하면 pod 자체는 변경 사항이 없기에 replicaSet은 'my-app-5d6554bfbf'로 동일하며 2개 > 5개로 늘어난 이벤트를 확인 할 수 있다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Sat, 20 May 2023 20:40:21 +0900
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-app
Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:1.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-5d6554bfbf (5/5 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 4m13s deployment-controller Scaled up replica set my-app-5d6554bfbf to 2
Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set my-app-5d6554bfbf to 5 from 2
정상적으로 rollout 이 됐는지 확인하면 완료 되었다고 나온다.
$ kubectl rollout status deployment/my-app
deployment "my-app" successfully rolled out
컨테이너가 정상인지 확인을 하기위해 포트포워딩을 진행하며
$ kubectl port-forward deployment/my-app 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
포워딩한 포트로 호출하면 정상적으로 버전 1로 나오는것을 볼 수 있다.
$ curl localhost:8080
Welcome to Version 1!
===== Host Info =====
HostIP: 10.100.2.15
HostName: my-app-5d6554bfbf-6n9zp
이제 첫번째 실습을 종료하기 위해 deployment 를 삭제 하면 replicaset, pod 모두 제거 된다.
$ kubectl delete deployment my-app
deployment.apps "my-app" deleted
$ kubectl get pod
No resources found in default namespace.
$ kubectl get deployment
No resources found in default namespace.
$ kubectl get rs
No resources found in default namespace.
2) pod의 image 수정
이제 파드의 이미지 버전을 수정해보자! (1.0 > 2.0 으로 변경 예정)
우선 deployment 를 생성하기 위한 파일을 작성하며 첫번째 실습과 다른점은 replica 수가 2>3 으로 변경 하였으며 deployment 의 label 값을 추가하였다.
# deployment-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
이제 아래와 같이 클러스터에 적용한다.
$ kubectl apply -f deployment-v2.yaml
deployment.apps/my-app created
정상적으로 적용 되었는지 이벤트를 확인하면 ReplicaSet 'my-app-5d6554bfbf'로 3개의 파드를 스케일 업 했다고 나오는 것을 보니 정상이다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Sat, 20 May 2023 20:55:26 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:1.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-5d6554bfbf (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 25s deployment-controller Scaled up replica set my-app-5d6554bfbf to 3
이제 명령어를 통해 이미지 버전을 1.0 > 2.0 으로 변경한다.
$ kubectl set image deployment/my-app my-app=yoonjeong/my-app:2.0
deployment.apps/my-app image updated
다시 Deployment의 이벤트를 보면 새로운 ReplicaSet 'my-app-856cb86fb4' 가 추가 되었으며 해당 ReplicaSet 을 통해 새 파드를 1개 생성한다. 그 뒤에 이전 ReplicaSet 'my-app-5d6554bfbf'으로 기존 파드 수를 3 > 2 로 스케일 다운 하는것을 볼 수 있다.
이렇게 deployment가 점진적으로 배포(새 파드 1개 생성, 구 파드 1개 제거)를 자동으로 하는것을 볼 수 있다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Sat, 20 May 2023 20:55:26 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=my-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:2.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-856cb86fb4 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 3m29s deployment-controller Scaled up replica set my-app-5d6554bfbf to 3
Normal ScalingReplicaSet 40s deployment-controller Scaled up replica set my-app-856cb86fb4 to 1
Normal ScalingReplicaSet 29s deployment-controller Scaled down replica set my-app-5d6554bfbf to 2 from 3
Normal ScalingReplicaSet 29s deployment-controller Scaled up replica set my-app-856cb86fb4 to 2 from 1
Normal ScalingReplicaSet 18s deployment-controller Scaled down replica set my-app-5d6554bfbf to 1 from 2
Normal ScalingReplicaSet 18s deployment-controller Scaled up replica set my-app-856cb86fb4 to 3 from 2
Normal ScalingReplicaSet 7s deployment-controller Scaled down replica set my-app-5d6554bfbf to 0 from 1
배포 작업이 끝나고 ReplicaSet을 확인해보면 아래와 같이 이전 파드 관련 'my-app-5d6554bfbf' 은 현재 0개, 새 파드 관련 ReplicaSet인 'my-app-856cb86fb4'는 3개로 정상 배포 된것을 볼 수 있다.
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
my-app-5d6554bfbf 0 0 0 5m3s
my-app-856cb86fb4 3 3 3 2m14s
컨테이너가 정상 동작하는지 포트 포워딩을 통해 확인해보면
$ kubectl port-forward deployment/my-app 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
아래와 같이 version 2 로 정상 호출 되는것을 볼 수 있다.
$ curl localhost:8080
Welcome to Version 2!
===== Host Info =====
HostIP: 10.100.3.23
HostName: my-app-856cb86fb4-44492
이제 두번째 실습을 종료하며 모든 오브젝트를 삭제한다. 이번에는 deployment에 'app=my-app' lable 값을 붙였으니 해당 레이블로 모두 삭제 한다.
$ kubectl delete all -l app=my-app
pod "my-app-856cb86fb4-44492" deleted
pod "my-app-856cb86fb4-5l4g8" deleted
pod "my-app-856cb86fb4-skwpg" deleted
deployment.apps "my-app" deleted
$ kubectl get rs
No resources found in default namespace.
$ kubectl get deployment
No resources found in default namespace.
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-app-856cb86fb4-fcvrp 1/1 Terminating 0 19s
my-app-856cb86fb4-fdpmk 1/1 Terminating 0 20s
my-app-856cb86fb4-j4mcs 1/1 Terminating 0 18s
$ kubectl get pod
No resources found in default namespace.
3) pod의 label 수정
아래와 같이 deployment 를 생성한다.
# deployment-v3.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: yoonjeong/my-app:2.0
ports:
- containerPort: 8080
resources:
limits:
memory: "64Mi"
cpu: "50m"
클러스터에 적용한다.
$ kubectl apply -f deployment-v3.yaml
deployment.apps/my-app created
정상적으로 생성 되었는지 이벤트를 확인하며 3개의 파드를 정상적으로 생성함을 확인 할 수 있었다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Sat, 20 May 2023 21:14:57 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=my-app
Containers:
my-app:
Image: yoonjeong/my-app:2.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-856cb86fb4 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set my-app-856cb86fb4 to 3
이제 deployment yaml 파일의 label env 를 추가해본다!
# deployment-v3.yaml
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
env: prod
클러스터에 변경 사항을 적용한다.
$ kubectl apply -f deployment-v3.yaml
deployment.apps/my-app configured
정상적으로 적용 되었는지 상세 이벤트를 보면 Pod 정보가 변경(label 추가) 되어 ReplicaSet 이 새로 생성 되었으며(replicaset 의 뒤에 template 해쉬 번호가 다르다.) 스케일업/다운이 이뤄진것을 볼 수 있다.
$ kubectl describe deployment/my-app
Name: my-app
Namespace: default
CreationTimestamp: Sat, 20 May 2023 21:14:57 +0900
Labels: app=my-app
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=my-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=my-app
env=prod
Containers:
my-app:
Image: yoonjeong/my-app:2.0
Port: 8080/TCP
Host Port: 0/TCP
Limits:
cpu: 50m
memory: 64Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: my-app-94cc98846 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set my-app-856cb86fb4 to 3
Normal ScalingReplicaSet 59s deployment-controller Scaled up replica set my-app-94cc98846 to 1
Normal ScalingReplicaSet 49s deployment-controller Scaled down replica set my-app-856cb86fb4 to 2 from 3
Normal ScalingReplicaSet 49s deployment-controller Scaled up replica set my-app-94cc98846 to 2 from 1
Normal ScalingReplicaSet 40s deployment-controller Scaled down replica set my-app-856cb86fb4 to 1 from 2
Normal ScalingReplicaSet 40s deployment-controller Scaled up replica set my-app-94cc98846 to 3 from 2
Normal ScalingReplicaSet 29s deployment-controller Scaled down replica set my-app-856cb86fb4 to 0 from 1
ReplicaSet을 보면 아래와 같이 이전 버전의 ReplicaSet은 Pod 0개, 새 ReplicaSet은 Pod 3개로 정상 배포 된것을 볼 수 있다.
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
my-app-856cb86fb4 0 0 0 12m
my-app-94cc98846 3 3 3 108s
이제 Pod Label 정보까지 확인해보면 정상적으로 env Lable 이 모두 붙어 있는것을 볼 수 있다.
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
my-app-94cc98846-5bfc9 1/1 Running 0 2m26s app=my-app,env=prod,pod-template-hash=94cc98846
my-app-94cc98846-brzlw 1/1 Running 0 2m7s app=my-app,env=prod,pod-template-hash=94cc98846
my-app-94cc98846-hzg7q 1/1 Running 0 2m16s app=my-app,env=prod,pod-template-hash=94cc98846
이제 실습이 완료 되어 모든 pod, replicaset, deployment 를 제거한다!
$ kubectl delete all -l app=my-app
pod "my-app-94cc98846-5bfc9" deleted
pod "my-app-94cc98846-brzlw" deleted
pod "my-app-94cc98846-hzg7q" deleted
deployment.apps "my-app" deleted
$ kubectl get pod
No resources found in default namespace.
$ kubectl get rs
No resources found in default namespace.
$ kubectl get deployment
No resources found in default namespace.
이번 실습을 통해 deployment 오브젝트를 통해 변경 사항이 있다면 자동으로 배포 되는 부분을 확인 하였다.
다음 시간에는 배포 전략을 변경하며 배포하는 실습을 진행해보자!
끝!
'ETC' 카테고리의 다른 글
[kubernetes] Service 소개 및 ClusterIP로 Pod 노출 실습 (1) | 2023.05.27 |
---|---|
[kubernetes] Deployment - 배포 전략 Recreate, RollingUpdate 및 롤백 (1) | 2023.05.26 |
[kubernetes] ReplicaSet 실습 - pod 수 조정, 롤백 (0) | 2023.05.20 |
[kubernetes] ReplicaSet 실습 - pod 종료, template 수정 (1) | 2023.05.20 |
[kubernetes] ReplicaSet 란? (0) | 2023.05.20 |