목차

Kubernetes Deployments

  • 클러스터에서 컨테이너화된 애플리케이션을 관리하기 위한 빌딩 블록 제공
    • 애플리케이션 → 컨테이너 → Pod → ReplicaSet → Deployment
  • 복제 Pod집합을 관리 및 확장하는 선언적 방법을 제공하는 API Resource로 상위 수준의 Object
  • 원하는 상태를 지정하면 Deployments Controller가 현재 상태를 원하는 상태로 조정 및 유지 → 지정된 수의 Pod replicas가 항상 실행되도록 보장 → Pod의 지속적 상태관리(Desired state management)
  • ReplicaSet rollout을 통한 Pod 복제 및 Image 버전관리
  • Workload(CPU, Memory usage) 기준 수동 및 자동 확장, 축소 기능 구현(HPA)
  • Rolling update를 통한 중단 없는 업데이트 지원
  • 다양한 배포 전략 제공
  • 이전 버전(Rollback) 지원(revision)
  • 사용하지 않는 ReplicaSet 정리

deployments-sample.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
  namespace: sample-nodespace
spec:
  replicas: 3  # Pod의 복제본 개수 지정
  selector:  # Deployment가 label을 통하여 관리하는 Pod선택
    matchLabels:
      app: sample
  strategy: {}  # default: RollingUpdate --- kubectl explain deployment.spec.strategy
    type: RollingUpdate  # Recreate설정시는 아래의 내용을 적지 않음
      rollingUpdate:  # 두 값 모두 기본값은 25% 또는 개수로 지정가능
        maxSurge: 3  # 최대로 생성 할 수 있는 Pod수 또는 %
        maxUnavailable: 1  # 최대로 삭제 할 수 있는 Pod수 또는 %
  template:  # 새 Pod를 생성하는데 사용되는 Pod
    metadata:
      labels:
        app: sample
    spec:
      containers:
      - name: sample-container
        image: sample-image
        ports:
        - containerPort: 80
        resources: {}  # {} 제한두지않음
          limits:  # 제한을 주고 싶을때 {} 삭제 후 아래의 내용 추가
            memory: "512Mi"  # 최대 memory 허용량
            cpu: "200m"  # 최대 CPU 허용량 (200 milliCPU) 1024m = 1core
          requests:
            memory: "256Mi"  # 초기 memory request
            cpu: "100m"  # 초기 CPU request
#기본 헬프
$ kubectl create deployment -h

#yaml 생성
$ kubectl create deployment smoke-deploy \
--image=python:2.7-slim --port=8000 \
--replicas=2 \
--dry-run=client -o yaml > smoke-deploy.yaml
#yaml생성 후 입맛에 맞게 수정

$ kubectl apply -f smoke-deploy.yaml

#service
$ kubectl expose deployment smoke-deploy --name smoke-svc \
--port 8000 --target-port 8000

#확인
$ kubectl get deploy,rs,po,svc -o wide | grep smoke
deployment.apps/smoke-deploy      2/2     2            2           2m38s   smoke-python      python:2.7-slim                     app=smoke-deploy
replicaset.apps/smoke-deploy-fd5ccfd9f       2         2         2       2m38s   smoke-python      python:2.7-slim                     app=smoke-deploy,pod-template-hash=fd5ccfd9f
pod/smoke-deploy-fd5ccfd9f-g5gp7        1/1     Running   0          2m38s   10.111.156.93   k8s-node1    <none>           <none>
pod/smoke-deploy-fd5ccfd9f-jjxdx        1/1     Running   0          2m38s   10.109.131.18   k8s-node2    <none>           <none>
service/smoke-svc                  ClusterIP   10.109.17.20    <none>        8000/TCP    8s      app=smoke-deploy

#접속 여러번하고 Pod들 접속 되는지 확인
$ curl 10.111.156.93:8000

수정 smoke-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: smoke-deploy
  name: smoke-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: smoke-deploy
  strategy: {}
  template:
    metadata:
      labels:
        app: smoke-deploy
    spec:
      containers:
      - image: python:2.7-slim  # 2.7버전은 http기본 탑재 상위버전 X
        name: smoke-python
        command: ["/bin/bash","-c","echo \"<h1>Smoke Test Deployment : $(hostname).</h1>\" > index.html; python -m SimpleHTTPServer 8000"]
        ports:
        - containerPort: 8000
        resources: {}

#모니터링 - 추가 터미널에 실행시키고 Pod 변동사항 확인 할 수 있음
$ kubectl get po --watch

#deployment 생성
$ kubectl create deployment deploy-web --image=nginx:1.17 --port=80 --replicas=2
deployment.apps/deploy-web created

#container image 버전확인
$ kubectl get deploy deploy-web -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
nginx:1.17

#Pod명은 모니터링에서 확인 할 수 있음
$ kubectl describe po deploy-web-58f97d77cf-fb9bs | grep -i image:
    Image:          nginx:1.17

$ kubectl get deploy,rs,po -o wide | grep deploy-web
deployment.apps/deploy-web        2/2     2            2           107s   nginx             nginx:1.17                          app=deploy-web
replicaset.apps/deploy-web-58f97d77cf        2         2         2       107s   nginx             nginx:1.17                          app=deploy-web,pod-template-hash=58f97d77cf
pod/deploy-web-58f97d77cf-fb9bs         1/1     Running   0          107s    10.111.156.94   k8s-node1    <none>           <none>
pod/deploy-web-58f97d77cf-rtx2k         1/1     Running   0          107s    10.109.131.19   k8s-node2    <none>           <none>

#container image 변경
#kubectl set image deploy <deployment 이름> <컨테이너이름>=<이미지파일>
$ kubectl set image deploy deploy-web nginx=nginx:1.19
deployment.apps/deploy-web image updated

$ kubectl set image deploy deploy-web nginx=nginx:1.20
deployment.apps/deploy-web image updated

#rollout 히스토리 확인
$ kubectl rollout history deployment deploy-web
deployment.apps/deploy-web
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

#rollout 정보 확인
$ kubectl rollout history deployment deploy-web --revision 1

#edit를 통해 롤아웃 정보는 10개정도 저장된다는 것을 확인 가능 -수정도 가능
$ kubectl edit deployments.apps deploy-web
...
spec:
  minReadySeconds: 10
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10  # etcd에 기록되어 있음
...

#revision 2로 롤백(undo)
$ kubectl rollout undo deployment deploy-web --to-revision 2
deployment.apps/deploy-web rolled back

#2번이 사라지고 새롭게 4번이 된걸 확인 할 수 있음
$ kubectl rollout history deployment deploy-web
deployment.apps/deploy-web
REVISION  CHANGE-CAUSE
1         <none>
3         <none>
4         <none>

#4번내용이 2번과 동일한 것을 확인가능
$ kubectl rollout history deployment deploy-web --revision 4

#히스토리에 주석달기
$ kubectl annotate deployments.apps deploy-web \
kubernetes.io/change-cause="change nginx"
deployment.apps/deploy-web annotated

#주석 확인
$ kubectl rollout history deployment deploy-web
deployment.apps/deploy-web
REVISION  CHANGE-CAUSE
1         <none>
3         <none>
4         change nginx
#모니터링 - 추가 터미널에 실행시키고 Pod 변동사항 확인 할 수 있음
$ kubectl get po --watch

#일시정지
$ kubectl rollout pause deployment deploy-web
deployment.apps/deploy-web paused

$ kubectl rollout undo deployment deploy-web --to-revision 3
error: you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume' and try again
#pause 상태에서는 rollback 불가

#중요 여기서 부터는 모니터링 확인 하면서 명령어 입력
#pause를 풀때까진 변경이 이루어지지 않음
#업데이트만 이루어진 상태
$ kubectl set image deploy deploy-web nginx=nginx:1.24
deployment.apps/deploy-web image updated

$ kubectl get deploy deploy-web -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
nginx:1.24
#변경되었어도 변경된게 아님

#pause 해제
#모니터링 확인하면 변경되는 걸 확인 가능
$ kubectl rollout resume deployment deploy-web
deployment.apps/deploy-web resumed
  • replicas의 갯수 변경으로 줄이거나 늘리거나 가능
$ kubectl scale deployment deploy-web --replicas=6
deployment.apps/deploy-web scaled

  • 기존 Pod가 모두 다운되고 새 Pod가 시작되기에 일정시간의 “다운타임"이 있음
  • 개발환경이나 사용자가 장기간 성능 저하 또는 오류보다 짧은 가동 중지시간을 선호하는 경우, 구·신버전을 동시에 사용 할 수 없는 경우 사용
  • 설정이 간단하고, 애플리케이션의 상태가 완전히 교체되어 업데이트됨
spec:
  replicas: 3
  strategy:  # 전략 확인 kubectl explain deployment.spec.strategy
    type: Recreate
  • 실행중인 Pod를 새 버전으로 모든 노드가 점진적 업데이트 전략으로 가동 중지 시간을 줄이기 위해 설계됨
  • 상대적으로 롤백하기 쉽고 배포를 재생성하는 것보다 덜 위험하며 구현하기 쉬움
  • 속도가 느릴 수 있고 문제가 발생 할 경우 이전버전으로 롤백 및 애플리케이션에 여러버전이 동시에 병렬적으로 실행 됨
  • 정해진 비율 만큼의 Pod가 점진적으로 배포 되는 방식
    • maxSurge
      • 롤링 업데이트를 위해 최대로 생성할 수 있는 Pod 수 또는 %
      • 높게 설정하면 롤링배포를 빠르게 적용가능
      • 기본값은 25%
    • maxUnavailable
      • 롤링 업데이트 중 최대로 삭제할 Pod 수 또는 %
      • 높게 설정하면 롤링배포를 빠르게 적용가능
      • 단, 높게 설정시 트래픽이 남은 소수의 Pod로 집중되어 성능 문제 유발 가능
      • 기본값은 25%
spec:
  replicas: 3
  strategy: {}  # default: RollingUpdate --- kubectl explain deployment.spec.strategy
    type: RollingUpdate  # Recreate설정시는 아래의 내용을 적지 않음
      rollingUpdate:  # 두 값 모두 기본값은 25% 또는 개수로 지정가능
        maxSurge: 3  # 최대로 생성 할 수 있는 Pod수 또는 %
        maxUnavailable: 1  # 최대로 삭제할 Pod수 또는 %