프로덕션에서 생성하고 사용할 것은 deployment이다.
deployment는 replicaSet을 매니징한다.
1 deployment 당 1서비스이다.
Demo
아래 파일을 생성 후 적용해보면 결과를 확인할 수 있다.
#01-simple-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deploy
spec:
selector:
matchLabels:
app: my-app
replicas: 3
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: nginx
image: nginx
kubectl create -f 01-simple-deploy.yaml
적용하면 deployment를 생성하고 해당 deployment가 replicaset을 생성하며 replicaset이 pod들을 생성하는걸 확인할 수 있다.
kubectl craete와 kubectl apply의 차이점
Command | Description |
kubectl create -f [파일이름] | 주어진 파일로 리소스를 생성한다. |
kubectl create -f . | 현재 디렉토리에서 모든 yaml파일을 기반으로 리소스를 생성한다. |
kubectl create -f http://vinsguru.com/k8s.yaml | 주어진 url로 리소스를 생성한다. |
Command | Description |
kubectl apply -f [파일이름] | 주어진 파일로 리소스를 생성/업데이트한다. |
kubectl apply -f . | 현재 디렉토리에서 모든 yaml파일을 기반으로 리소스를 생성/업데이트한다. |
kubectl apply -f http://vinsguru.com/k8s.yaml | 주어진 url로 리소스를 생성/업데이트한다. |
create는 없으면 생성 있으면 에러를 내지만
apply는 없으면 생성 있으면 변경사항을 적용하며, 변경사항이 없으면 무시된다.
위 01 파일이 실행된 삭제된 상태로 아래 명령어들을 차례로 실행해보면 결과를 알 수 있다.
# 정상적으로 생성
kubectl create -f 01-simple-deploy.yaml
# 다시 실행시 에러
kubectl create -f 01-simple-deploy.yaml
=> Error from server (AlreadyExists): error when creating "01-simple-deploy.yaml": deployments.apps "my-deploy" already exists
# 만들어진 deploy 삭제
kubectl delete -f 01-simple-deploy.yaml
# 새로 생성
kubectl apply -f 01-simple-deploy.yaml
=> deployment.apps/my-deploy created
# 변경 사항 적용 (없으면 무시) 몇번을 반복해도 같은 결과만 나온다
kubectl apply -f 01-simple-deploy.yaml
=> deployment.apps/my-deploy configured
Log & Port forward
kubectl get 관련 커맨드는 아래와 같다.
Command | Description |
kubectl get [kind명] | 특정 종류의 리소스를 나열한다. |
kubectl get [kind명] [resource-name] | 특정 리소스를 조회한다. |
kubectl get [kind명] --show-labels | 라벨을 표시한다. |
kubectl get [kind명] -l app=my-app | 리소스를 쿼리한다. |
kubectl get [kind명] -o yaml | 출력형식을 yaml형식으로 지정한다. |
Command | Description |
kubectl describe [kind] [resource-name] | 리소스 설명하기 |
kubectl delete [kind] [resource-name] | 리소스 삭제하기 |
kubectl logs [kind]/[resource-name] | 로그 확인 |
kubectl exec -it [kind]/[resource-name] – bash | 파드 컨테이너에 접근 |
kubectl port-forward [kind]/[resource-name] 8080:80 | 포트포워딩 설정 |
Deployment revisions
deploy는 서비스의 버전을 관리할 수 있다. 아래 예시를 통해 확인해보자
# 02-deploy-rs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
selector:
matchLabels:
app: order-service
replicas: 3
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v1
ports:
- name: "app-port"
containerPort: 80
kubectl apply -f 02-deploy-rs.yaml
생성된걸 확인후 아래 파일처럼 변경해보자
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
selector:
matchLabels:
app: order-service
replicas: 2
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v1
ports:
- name: "app-port"
containerPort: 80
kubectl apply -f 02-deploy-rs.yaml
이렇게 진행하면 레플리카셋을 2개로 변경한다 컨테이너 스펙을 변경 해야 새로운 변경으로 감지 한다.
이제 v2로 변경해보자
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
selector:
matchLabels:
app: order-service
replicas: 2
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v2
ports:
- name: "app-port"
containerPort: 80
# 적용
kubectl apply -f 02-deploy-rs.yaml
명령어를 치고 확인해보면 새로운 레플리카셋이 생기고 기존 레플리카셋의 ready 갯수는 0인걸 확인할 수 있다.
이번에는 환경변수를 변경해보자
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
selector:
matchLabels:
app: order-service
replicas: 2
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v2
env:
- name: DUMMY
value: "8"
ports:
- name: "app-port"
containerPort: 80
# 적용
kubectl apply -f 02-deploy-rs.yaml
변경 사항을 적용해보면 또 새로운 레플리카 셋이 생길 수 있다.
이로 인해 알 수 있는 사실은 컨테이너 동작에 새로운 변경 사항이 생기면 레플리카셋을 새로 생성하지만 레플리카셋의 갯수만 변경하면 단순히 pod의 갯수만 변경되는걸 확인할 수있다.
Rollout history
새로운 파일을 생성한 후 적용하고 포트 포워딩을 설정해주자.
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
selector:
matchLabels:
app: order-service
replicas: 2
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v1
ports:
- name: "app-port"
containerPort: 80
# 적용
kubectl apply -f 03-deploy-rollout.yaml
# 포트포워딩
kubectl port-forward deploy/order-service-deployment 8080:80
이제 localhost:8080으로 접속해보면 V1 화면이 나오는 걸 확인할 수 있다.
이제 v2 로 버젼을 바꿔서 진행해보자
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
selector:
matchLabels:
app: order-service
replicas: 2
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v2
ports:
- name: "app-port"
containerPort: 80
kubectl apply -f 03-deploy-rollout.yaml
kubectl port-forward deploy/order-service-deployment 8080:80
이 후 다시 브라우저로 들어간 후 새로고칭하면 V2 화면이 나오는 것을 확인할 수 있다.
이제 터미널에서 아래 명령어를 입력한다.
kubectl rollout history deploy
그럼 2가지 수정본이 나오는것을 확인할 수 있다.
그럼 이제 containers의 버전을 3로 바꾸고 다시 적용해보자
# 생략
image: vinsdocker/k8s-app:v3
# 생략
kubectl apply -f 03-deploy-rollout.yaml
다시 kubectl rollout history deploy로 확인해보면 3개의 버전이 있는것을 확인할 수 있다.
이제 port-forward를 한 후 localhost:8080으로 접속하면 V3 화면이 뜨는것을 확인할 수 있다.
이제 롤백을 진행해보자
# 이전 버전으로 돌아간다.
kubectl rollout undo deploy/order-service-deployment
다시 port-forward를 한 후 localhost:8080으로 접속하면 V2 화면이 뜨는것을 확인할 수 있다.
다시 history를 확인해보자
kubectl rollout history deploy
# 결과
deployment.apps/order-service-deployment
REVISION CHANGE-CAUSE
1 <none>
3 <none>
4 <none>
다시 같은 명령을 실행한다
kubectl rollout undo deploy/order-service-deployment
포트포워딩 적용 후 확인해보면 version3로 돌아간것을 확인할 수 있다.
Rollback
이전 정의는 그대로 두고 새로 v1 부터 시작한다
또한 annotations을 추가하자
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
annotations:
kubernetes.io/change-cause: "deploying v1"
spec:
selector:
matchLabels:
app: order-service
replicas: 2
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v1
ports:
- name: "app-port"
containerPort: 80
이제 이전 deploy를 삭제하고 적용해보자
kubectl apply -f 03-deploy-rollout.yaml
다시 히스토리를 확인해보면 CHANGE-CAUSE가 바뀐것을 확인할 수 있다.
kubectl rollout history deploy
# 결과
REVISION CHANGE-CAUSE
1 deploying v1
이제 위 작업에서 컨테이너를 v2 로 변경하고 annotaions도 v2로 변경 후 다시 확인하면 아래와 같다
kubectl rollout history deploy
# 결과
REVISION CHANGE-CAUSE
1 deploying v1
2 deploying v2
이제 위 작업에서 컨테이너를 v3 로 변경하고 annotaions도 v3로 변경 후 적용하자
#결과
REVISION CHANGE-CAUSE
1 deploying v1
2 deploying v2
3 deploying v3
이전 섹션에서 3인 상태에서 undo를 실행하면 v2로 가고 v2에서 undo를 실행하면 v3로 돌아갔다.
1로 돌아가보자
kubectl rollout undo deploy/order-service-deployment --to-revision=1
kubectl rollout history deploy
# 결과
REVISION CHANGE-CAUSE
2 deploying v2
3 deploying v3
4 deploying v1
Checking Rollout Changes
간단한 정보만 보면 헷갈릴수 있다.
아래 명령어를 통해 자세히 알 수 있다.
kubectl rollout history deploy --revision=[번호]
ex) kubectl rollout history deploy --revision=4
#결과
deployment.apps/order-service-deployment with revision #4
Pod Template:
Labels: app=order-service
pod-template-hash=56864789dc
Annotations: kubernetes.io/change-cause: deploying v1
Containers:
order-service-container:
Image: vinsdocker/k8s-app:v1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Min ready Seconds (최소 준비 시간)
실제로 애플리케이션이 실행되는데는 시간이 걸린다.
이 때 실제로 걸리는 시간을 deploy yaml 파일에 정의해 둘 수 있다.
원래는 heath check, Probe등으로 확인하며 이 방법은 하드 코딩해서 알려주는 방법이다.
# 04-min-ready-seconds.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deploy
spec:
minReadySeconds: 10
selector:
matchLabels:
app: my-app
replicas: 3
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: nginx
image: nginx
kubectl apply -f 04-min-ready-seconds.yaml
적용후 watch로 확인해보면 deploy의 AVAILABLE이 10초 뒤에 활성화 되는것을 확인 할 수 있다.
배포 전략
만약 version1에서 version2를 배포하고 싶다고 할 때 변경사항을 어떻게 적용할건지를 정의한다.
전략 | 설명 | |
recreate | 기존 파드를 종료하고 새로운 파드를 생성합니다. | |
rolling update | 변경 사항을 점진적으로 배포합니다. 기존 파드와 새로운 파드가 일시적으로 혼합될 수 있습니다. 아래 속성 들은 0 또는 %가 될 수 있다. | |
속성 | 설명 | |
maxSurge | 생성할 수 있는 추가 파드의 최대 수 | |
maxUnavailable | 종료할 수 있는 파드의 최대 수 |
recreate 전략
# 05-deploy-recreate.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
annotations:
kubernetes.io/change-cause: "deploying v1"
spec:
minReadySeconds: 10
strategy:
type: Recreate
selector:
matchLabels:
app: order-service
replicas: 2
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v1
ports:
- name: "app-port"
containerPort: 80
# 적용
kubectl apply -f 05-deploy-recreate.yaml
위 파일을 정의 한 후 실행한다.
이 후 아래 파일처럼 변경하고 다시 apply 해보자
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
minReadySeconds: 10
strategy:
type: Recreate
selector:
matchLabels:
app: order-service
replicas: 3
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v2
ports:
- name: "app-port"
containerPort: 80
# 적용
kubectl apply -f 05-deploy-recreate.yaml
확인해보면 먼저 존재하던 모든 파드들이 삭제되고 새로운 파드들이 새로 한번에 생기는걸 확인할 수 있다.
Rolling update - maxSurge
아래 파일을 생성 후 실행해보자
# 06-deploy-max-surge.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
minReadySeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: "100%"
selector:
matchLabels:
app: order-service
replicas: 3
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v1
ports:
- name: "app-port"
containerPort: 80
kubectl apply -f 06-deploy-max-surge.yaml
pod 3개가 켜진것을 확인할 수 있다.
이제 이미지를 v2로 바꿔보자
...
image: vinsdocker/k8s-app:v2
...
이후 실행을 해보면 순간적으로 파드가 6개가 되는것을 확인할 수 있다.
이제 v3를 maxSurge 1 로 변경한 후 적용해보자
...
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
...
image: vinsdocker/k8s-app:v3
...
이제 결과를 살펴보면 하나씩 파드가 교체되는 과정을 확인할 수 있다.
Rolling update - maxUnavailable
파일을 생성하고 실행해보자
# 07-deploy-max-unavailable.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-deployment
spec:
minReadySeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
selector:
matchLabels:
app: order-service
replicas: 3
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service-container
image: vinsdocker/k8s-app:v1
ports:
- name: "app-port"
containerPort: 80
kubectl apply -f 07-deploy-max-unavailable.yaml
v2로 변경한 후 실행해보면 하나씩 변경되는것을 확인할 수 있다
'Kubernetes' 카테고리의 다른 글
[Kubernetes] Namespace (0) | 2024.12.19 |
---|---|
[Kubernetes] Service (0) | 2024.12.17 |
[Kubernetes] ReplicaSet (0) | 2024.12.12 |
[Kubernetes] Pod 기초 - 2 (1) | 2024.12.06 |
[Kubernetes] Pod 기초 - 1 (0) | 2024.11.27 |