쿠버네티스(kubernetes) (4) - LoadBalancer - Relica - Deployment - 레플리카 - 디플로이먼트

Share

Last Updated on 10월 28, 2021 by Jade(정현호)

안녕하세요 

이번 포스팅에서는 쿠버네티스의 파드의 외부 접속 방법 중 LoadBalancer 관련 내용과 Replica 와 Deployment 에 대해서 확인 해보도록 하겠습니다.

해당 포스팅은 아래 포스팅에서 이어지는 글 입니다.

                     

External-IP 와 LoadBalancer

이전 포스팅 에서 테스트 시스템에 NodePort 를 구성하여 외부 접속을 하는 부분까지 알아보았습니다.
(이전 포스팅 부터 순서대로 참조 필요)

이번 포스팅 단계에서는 LoadBalance 를 통해서 구성된 파드의 외부 접속에 대해서 확인 해보려고 합니다.

/home/devops/work:$ kubectl get svc -o wide
NAME              TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE   SELECTOR
mynginx-service   NodePort   10.109.144.129   <none>        8002:31188/TCP   10h   app=myweb


위의 조회 결과에서 확인되는 EXTERNAL-IP(아직 까지는 설정이 안되어 있는 상태) 도 접속을 할 수 있습니다.
물론 아직 별다른 설정이 안되어있기 때문에 접속은 할 수 없으며, LoadBalance 로 설정을 통해서 External-IP 로 접속 할 수 있습니다.

LoadBalance 는 퍼블릭 클라우드의 장점이라고도 할 수 있으며 LoadBalance 가 AWS 나 GCP 등과 같은 퍼블릭 클라우드에서는 지원하지만 포스팅에서와 같이 직접 설치한 온프레미스의 쿠버네티스에서는 EXTERNAL IP 및 LoadBalance 를 사용 할 수 없습니다.

그래도 사용할 수 있는 방법이 있으며 LoadBalance 가 지금 과 같은 온프레미스 환경에서도 사용 할 수 있도록 만들어진 별도의 프로젝트가 존재 합니다.

온프레미스에 설치된 kubernetes 는 오픈소스 프로젝트인 metal lb 를 설치를 하면 쿠버네티스에서 loadbalancer type 을 사용할 수 있습니다.
               

MetalLB

온프레미스의 쿠버네티스 환경에서 외부 L4 스위치 없이 Load Balance 기능을 사용하기 위해서는 MetalLB 를 사용 해야 합니다(VM 이거나 물리 머신이거나 동일)
하지만 MetalLB 를 이용하면 서비스 오브젝트를 통해서 Load Balance 기능을 사용할 수 있으며 외부 접속을 할 수 있습니다.



MetalLB 설치를 진행 해보도록 하겠습니다. 설치 관련된 정보는 아래 링크에서 더 자세하게 확인 해보실 수 있습니다.


먼저 kube-proxy 의 수정하도록 하겠습니다.
37 라인의 strictARP 값을 true 로 변경 합니다.

~:$ kubectl edit configmap -n kube-system kube-proxy


strictARP: false

to

strictARP: true


그 다음 아래와 같이 원격에 있는 2개의 yaml 파일을 kubectl apply 로 설치를 합니다.

~:$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml

~:$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

링크 중간에 있는 v0.10.2 버전은 프로젝트의 버전업에 따라 달라 질 수 있으며, 설치를 진행 하는 시점에 버전을 별도로 확인을 하셔야 합니다.
 • MetalLB 사이트 설치 문서


설치가 완료 되면 metallb-system 라는 네임스페이스가 생성 됩니다.

/home/devops/work:$ kubectl get ns 
NAME              STATUS   AGE
default           Active   84d
kube-node-lease   Active   84d
kube-public       Active   84d
kube-system       Active   84d
metallb-system    Active   9s  <--- 새로운 ns 가 추가 됨
testns            Active   27d
workns            Active   28d


그리고 계정과 롤 등이 생성되게 됩니다.

/home/devops/work:$ kubectl get all -n metallb-system
NAME                              READY   STATUS    RESTARTS   AGE
pod/controller-6b78bff7d9-wb99q   1/1     Running   0          81s
pod/speaker-4fwcv                 1/1     Running   0          81s
pod/speaker-dzbd6                 1/1     Running   0          81s
pod/speaker-tw7zm                 1/1     Running   0          81s

NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/speaker   3         3         3       3            3           kubernetes.io/os=linux   81s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           81s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-6b78bff7d9   1         1         1       81s


그 다음 아래와 같이 configmap.yaml 파일을 작성 합니다

/home/devops/work:$ vi configmap.yaml


apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.56.90-192.168.56.150

addresses 에서의 IP 대역대는 워커노드의 ip 대역대로 기재 하면 되며, EXTERNAL-IP 에 할당할 IP 범위를 지정하면 됩니다. worker2 호스트가 192.168.56.57 을 사용하기 때문에 IP 충돌을 방지하기 위해서 90번 부터 ~ 150번으로 설정 하였습니다.

이런 IP 대역대와 범위는 사용하는 환경에 따라 달라 지게 됩니다.


작성한 configmap 을 생성 하도록 하겠습니다.(kubectl apply 실행)

/home/devops/work:$ kubectl apply -f configmap.yaml


/home/devops/work:$ kubectl get configmap -n metallb-system
NAME               DATA   AGE
config             1      32s

         

Service 생성

설치한 MetalLB 를 통해서 LoadBalancer 를 사용할 수 있으며 사용하기 위해서 service 를 생성 해야 합니다.

[tip] Service 의 Default Type

Service 생성시 type: 을 생략하면 기본은 clusterIP 가 됩니다.


이전 포스팅에서 이어서 진행 중인 환경이라면 기존의 생성된 서비스를 edit 하여 수정하면 됩니다.

/home/devops/work:$ kubectl edit svc mynginx-service


type: NodePort

to

type: LoadBalancer


서비스 신규 생성시 아래와 같이 yaml 파일을 작성하여 생성 합니다.

/home/devops/work:$ vi nginx_service.yaml


---
apiVersion: v1
kind: Service
metadata:
  name: mynginx-service
spec:
  ports:
  - name : mynginx-service-port
    port: 8001
    targetPort: 80
  selector:
    app: myweb
  type: LoadBalancer


yaml 파일 작성 완료 후에는 apply 로 생성 하면 됩니다.

/home/devops/work:$ kubectl apply -f nginx_service.yaml

                  

service 확인

service 를 수정 하였거나 또는 생성 이 완료 되었다면 서비스를 조회하여 내용을 확인 합니다.

/home/devops/work:$ kubectl get svc
NAME              TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)          AGE
mynginx-service   LoadBalancer   10.105.248.145   192.168.56.90   8001:31940/TCP   8m2s

이제 TYPE 이 이전의 NodePort 에서 LoadBalancer 로 변경 되었으며, 공란 이었던 EXTERNAL-IP 에 IP 가 Assign이 되었습니다. 

이제 외부에서 접속 할때 마스터 와 워커노드와 같은 IP 대역대로 접속 할 수 있습니다.
접속 주소 - 192.168.56.90:8001


describe svc 로 상세내역을 확인 해보도록 하겠습니다.

/home/devops/work:$ kubectl describe svc mynginx-service 
Name:                     mynginx-service
Namespace:                workns
Labels:                   <none>
Annotations:              <none>
Selector:                 app=myweb
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.109.144.129
IPs:                      10.109.144.129
LoadBalancer Ingress:     192.168.56.90
Port:                     mynginx-service-port  8002/TCP
TargetPort:               80/TCP
NodePort:                 mynginx-service-port  31188/TCP
Endpoints:                10.32.0.4:80,10.40.0.2:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

이전의 NodePort 사용시에는 없던 항목인 "LoadBalancer Ingress" 이 추가 되었습니다.

Loadbalancer 로 설정해도 물론 NodePort 도 여전히 동작을 해서 사용할 수 있습니다.
이처럼 퍼블릭 클라우드에서 지원하는 LB 기능을 이처럼 사용할 수 있습니다.
            

ReplicaSet

ReplicaSet(레플리카셋) 의 목적은 레플리카 파드 집합의 실행을 항상 안정적으로 유지하는 것입니다. 이처럼 레플리카셋은 보통 명시된 동일 파드 개수에 대한 가용성을 보증하는데 사용한다.

파드 개수에 대한 가용성을 보증하며, 지정한 개수 만큼의 파드가 항상 실행 되도록 관리 합니다.


레플리카셋을 정의하는 필드는 획득 가능한 파드를 식별하는 방법이 명시된 셀렉터, 유지해야 하는 파드 개수를 명시하는 레플리카의 개수, 그리고 레플리카 수 유지를 위해 생성하는 신규 파드에 대한 데이터를 명시하는 파드 템플릿을 포함하고 있습니다.

그러면 레플리카셋은 필드에 지정된 설정을 충족하기 위해 필요한 만큼 파드를 만들고 삭제하게 됩니다. 레플리카셋이 새로운 파드를 생성해야 할 경우, 명시된 파드 템플릿을 사용하게 됩니다.

yaml 파일을 작성하여 레플리카셋을 생성 하도록 하겠습니다.
                   

yaml 파일 작성

~$ vi replica.yaml


---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replica
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-replica-test
  template:
    metadata:
      labels:
        app: nginx-replica-test
    spec:
      containers:
      - name: myweb-container2
        image: nginx:latest
        ports:
        - containerPort: 80

ReplicaSet은 Label 을 확인하여 설정 된(spec.replicas) 만큼의 Pod 가 없다면 새로운 Pod 을 생성합니다.
위의 설정에서 주요 내용은 아래와 같습니다.

• selector.replicas
    해당 ReplicaSet 는 3개의 파드를 유지를 의미

• spec.selector
    ReplicaSet이 관리할 pod 의 명세

• spec.template
    파드를 유지 하기 하기 위해 생성할 Pod의 명세
             

생성 및 동작 확인

kubectl create 또는 apply 로 생성 할 수 있습니다.

~$ kubectl create -f replica.yaml


ReplicaSet 이 생성되었다면 몇가지 확인 해보도록 하겠습니다.
파드는 설정된 것과 같이 3개가 동작 중임을 확인 할 수 있습니다.

~$ kubectl get pods -o wide
NAME                  READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-replica-4qt4p   1/1     Running   0          15s   10.32.0.4   worker2   <none>           <none>
nginx-replica-sqtqf   1/1     Running   0          15s   10.32.0.2   worker2   <none>           <none>
nginx-replica-xkvcq   1/1     Running   0          15s   10.32.0.3   worker2   <none>           <none>


ReplicaSet 이 정상동작 하는지 확인 해보기 위해서 특정 파드를 하나를 삭제 해보도록 하겠습니다.
ReplicaSet 으로 파드를 동작하면 metadata.name 에 설정된 파드 이름 뒤에 랜덤한 숫자 와 영문이 붙은 라벨링이 되게 됩니다.

1개의 파드를 삭제 하고 다시 조회를 해보도록 하겠습니다.

~$ kubectl delete pods nginx-replica-xkvcq
pod "nginx-replica-xkvcq" deleted


~$ kubectl get pods -o wide
NAME                  READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-replica-4qt4p   1/1     Running   1          10m   10.32.0.4   worker2   <none>           <none>
nginx-replica-sqtqf   1/1     Running   1          10m   10.32.0.3   worker2   <none>           <none>
nginx-replica-t9lrl   1/1     Running   0          31s   10.40.0.3   worker1   <none>           <none>
   <-- 새로 파드가 시작되었음

nginx-replica-xkvcq 파드가 삭제가 된 이후 nginx-replica-t9lrl 이름의 파드가 바로 시작 되었으며 이번에는 노드는 worker1 에서 기동 된 것을 확인 할 수 있습니다(이전에는 worker2 에서 기동 되었었음)

get replicasets.apps 를 통해서 생성시 설정한 정보를 확인 할 수 있습니다

~$ kubectl get replicasets.apps -o wide
NAME            DESIRED   CURRENT   READY   AGE     CONTAINERS         IMAGES         SELECTOR
nginx-replica   3         3         3       9m39s   myweb-container2   nginx:latest   app=nginx-replica-test


이제 노드자체가 다운 되었을 경우에 동작하는 과정에 대해서 확인 해보도록 하겠습니다.
worker2 노드를 shudown 하도록 하겠습니다.

~$ sudo shutdown -h now


파드 상태를 조회해보도록 하겠습니다.

~$ kubectl get pods -o wide
NAME                  READY   STATUS    RESTARTS   AGE     IP          NODE      NOMINATED NODE   READINESS GATES
nginx-replica-4qt4p   1/1     Running   1          12m     10.32.0.4   worker2   <none>           <none>
nginx-replica-sqtqf   1/1     Running   1          12m     10.32.0.3   worker2   <none>           <none>
nginx-replica-t9lrl   1/1     Running   0          2m59s   10.40.0.3   worker1   <none>           <none>

노드가 다운되고 나서 수초 ~ 1분도 지났지만 변경되는 내역이 없는 것을 확인 할 수 있습니다.

5분(300초) 정도 지나게 되면 아래와 같이 다운된 노드의 파드는 종료(Terminating) 되고, 다른 노드에서 구동 되는 것을 확인 할 수 있습니다.

~$ kubectl get pods -o wide
NAME                  READY   STATUS        RESTARTS   AGE     IP          NODE      NOMINATED NODE   READINESS GATES
nginx-replica-4qt4p   1/1     Terminating   1          18m     10.32.0.4   worker2   <none>           <none>
nginx-replica-89q7z   1/1     Running       0          59s     10.40.0.4   worker1   <none>           <none>
nginx-replica-8swlf   1/1     Running       0          59s     10.40.0.5   worker1   <none>           <none>
nginx-replica-sqtqf   1/1     Terminating   1          18m     10.32.0.3   worker2   <none>           <none>
nginx-replica-t9lrl   1/1     Running       0          8m58s   10.40.0.3   worker1   <none>           <none>


노드가 다운된 이후 바로 다른 노드에서 파드가 실행되지 않고 또는 종료 되지 않고 300초(5분) 뒤에 동작한 이유는 노드의 문제나 장애 등에 의해서 축출을 결정하는 값인 tolerationSeconds 의 기본값이 300 이기 때문입니다.

참고:

쿠버네티스는 사용자나 컨트롤러에서 명시적으로 설정하지 않았다면, 자동으로 node.kubernetes.io/not-ready 와 node.kubernetes.io/unreachable 에 대해 tolerationSeconds=300 으로 톨러레이션을 추가한다.

자동으로 추가된 이 톨러레이션은 이러한 문제 중 하나가 감지된 후 5분 동안 파드가 노드에 바인딩된 상태를 유지함을 의미한다.


설정 된 tolerationSeconds 에 따라서 노드가 다운되었으나 300초 뒤에 파드가 종료 및 새로운 노드에서 시작 된 것 입니다.
            

삭제

사용 중인 ReplicaSet 삭제하는 방법 2가지가 있습니다.

1) yaml 파일을 수정하여 삭제 할 수 있습니다 replicas: 0 으로 변경 후 apply 합니다.

~$ vi replica.yaml

replicas: 0
  <-- 0 으로 수정


~$ kubectl apply -f replica.yaml

kubectl apply 까지 하면 삭제가 됩니다.

2) delete replicasets 를 통해서 삭제 합니다.

~$ kubectl delete replicasets.apps nginx-replica

       

Deployment

쿠버네티스에서 많이 사용 되는 Deployment 객체에 대해서 확인 해보도록 하겠습니다. 
      

디플로이먼트 개요

Deployment 는 컨테이너 어플리케이션을 배포 및 관리하는 역할을 하는 오브젝트 입니다.

Replica 오브젝트 보다는 deployment 오브텍트를 많이 사용합니다.
이유는 Deployment 는 Replica 역할을 할 수 있으며 추가로 Replica 오브젝트가 불가한 기능을 Deployment 는 할 수 있기 때문입니다.

[쿠버네티스에 첫 번째 애플리케이션 배포하기]


Deployment 오브젝트는 Replica 기능은 기본으로 하며 롤링 업데이트 및 롤링 업데이트 및 rollback 이 가능 합니다.

어플리케이션을 배포하다가 문제가 있을 경우 deployment는 롤백을 할 수 있으며 이러한 기능적 장점 등에 의해서 Replica 오브젝트 자체 만은 잘 사용하지 않는 부분이 있습니다.

Deployment 를 사용하여 어플리케이션을 업데이트 할때 Revision 을 기록하여 rollback 이 가능하게 됩니다.
          

Api-Versions

Deployment 를 yaml 파일을 통해서 생성을 진행 하기 전에 yaml 파일에서 사용되는 api-versions 에 대해서 간략하게 살펴보도록 하겠습니다.

kubectl api-versions 명령어를 통해서 확인 할 수 있으며 v1beta1 은 베타버전이며, v1은 stable 버전 으로 보시면 됩니다.

~$ kubectl api-versions
[API Group]                [Version]
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1  <-- deployment
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
batch/v1
batch/v1beta1
certificates.k8s.io/v1
certificates.k8s.io/v1beta1
coordination.k8s.io/v1
coordination.k8s.io/v1beta1
discovery.k8s.io/v1
discovery.k8s.io/v1beta1
events.k8s.io/v1
events.k8s.io/v1beta1
extensions/v1beta1
flowcontrol.apiserver.k8s.io/v1beta1
metrics.k8s.io/v1beta1
networking.k8s.io/v1
networking.k8s.io/v1beta1
node.k8s.io/v1
node.k8s.io/v1beta1
policy/v1
policy/v1beta1
rbac.authorization.k8s.io/v1
rbac.authorization.k8s.io/v1beta1
scheduling.k8s.io/v1
scheduling.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1  <-- core group


조회 내용에서 왼쪽이 API Group 을 의미하며, 오른쪽이 Version 을 의미 합니다.

위에서 설명한 것처럼 Version 에는 v1beta1 도 있고 v1 인 내역도 있으며, 맨 아래 API Group 이 없이 v1 이라고만 표시되는 내역도 있습니다 

맨 아래 API Group 이 없이 v1 은 Core Group 입니다.

yaml 파일의 apiVersion 에는 위의 API Group 명과 그에 해당 하는 Version 이 들어가게 되며 디플로이먼트의 apiVersion은 apps/v1 입니다.
이와 같이 yaml 파일을 통해 오브젝트나 리소스 생성시 apiVerion 은 위에서 확인 되는 Group 과 Version 으로 입력되게 됩니다.

          

Deployment 생성

이제 yaml 파일을 작성하여 Deployment 를 생성하도록 하겠습니다. 계속 해서 Nginx 컨테이너 이미지를 사용하도록 하겠습니다.

yaml 파일 작성(deployment.yaml)

~$ vi deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec: 
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80


apiVersion: 디플로이먼트의 Api Group 과 버전 입니다 - apps/v1

kind: Deployment
이전의 Replica 에서는 ReplicaSet 이었고, 지금은 deployment 이기 때문에 Deployment 라고 기재합니다.

name: nginx-test
deployment 이름이면서 파드 이름으로 이번에는 nginx-test 로 사용하였습니다.

spec.replicas : 3
파드를 유지하는 숫자로 쿠버네티스는 3개의 파드가 항상 유지 되도록 합니다.

template : 파드를 만들기 위한 부분 입니다.

selector 의 키(Key) 와 값(Value) 이 template 의 키와 값 과 일치 하도록 해야 합니다.
위의 yaml 파일에서는 app: nginx 로 되어있습니다.

image: nginx:1.14.2
이미지는 nginx 를 사용하였으며 처음 파드를 생성 시에는 1.14.2 버전으로 생성 하도록 하겠습니다.

위에서 설명한 것 처럼 Deployment 오브젝트는 Replica 비교하여 롤링 업데이트 및 롤링 업데이트 및 rollback 이 되기 때문에 어플리케이션을 배포하다가 문제가 있을 경우 롤백을 할 수 있습니다
또한 롤링 업데이트가 가능하기 때문에 중단 없이 몇 개씩 업데이트 할 수 있습니다.


디플로이먼트 생성 및 조회

~$ kubectl create -f deployment.yaml

~$ kubectl get deployments.apps 
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx-test   0/0     0            0           12s

~$ kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-test-585449566-mvzqz   1/1     Running   0          40s   10.32.0.4   worker2   <none>           <none>
nginx-test-585449566-p5m8x   1/1     Running   0          40s   10.32.0.2   worker2   <none>           <none>
nginx-test-585449566-zw28c   1/1     Running   0          40s   10.32.0.3   worker2   <none>           <none>


Deployment 는 Replica 오브젝트 처럼 동작한다고 위에서 설명 하였으며 파드가 종료(삭제) 되더라도 설정된 spec.replicas 수 만큼을 유지하게 됩니다.


파드 삭제 및 확인

파드가 유지가 되는지 파드를 삭제 해보도록 하겠습니다.

~$ kubectl delete pod nginx-test-585449566-mvzqz
pod "nginx-test-585449566-mvzqz" deleted

~$ kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-test-585449566-ndt25   1/1     Running   0          6s    10.32.0.4   worker2   <none>           <none>
nginx-test-585449566-p5m8x   1/1     Running   0          40m   10.32.0.2   worker2   <none>           <none>
nginx-test-585449566-zw28c   1/1     Running   0          40m   10.32.0.3   worker2   <none>           <none>

위와 같이 삭제를 하더라도 yaml 파일에서 설정한 것과 같이 3개를 유지 될수 있도록 새로운 파드를 생성 하게 됩니다.
       

파드 업데이트

파드를 업데이트 하려면 디플로이먼트의 파드 템플릿만 다시 업데이트 하면 됩니다.

디플로이먼트는 업데이트되는 동안 일정한 수의 파드만 중단되도록 보장하며, 기본적으로 적어도 의도한 파드 수의 75% 이상이 동작하도록 보장합니다.(최대 25% 불가).

또한 디플로이먼트는 의도한 파드 수 보다 더 많이 생성되는 파드의 수를 제한합니다. 기본적으로, 의도한 파드의 수 기준 최대 125%까지만 추가 파드가 동작할 수 있도록 제한합니다.(최대 25% 까지)

먼저 현재 디플로이먼트 정보를 확인해보겠습니다.

~$ kubectl describe deployments.apps nginx-test 
Name:                   nginx-test
Namespace:              workns
CreationTimestamp:      Wed, 20 Oct 2021 02:01:26 +0900
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 3
Selector:               app=nginx
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=nginx
  Containers:
   nginx:
    Image:        nginx:1.14.2 <--- 현재 버전
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:

<... 중략...>

위에서 생성한 것처럼 Deployment 의 Nginx 버전은 1.14.2 입니다.

이전에 생성하였을때 롤링 업데이트를 위해서 낮은 버전인 1.14.2 로 생성하였고 이번에는 1.18.0 버전으로 업데이트를 해보도록 하겠습니다.

-- 현재 상태, 3개의 파드가 실행 중
~$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-test-66b6c48dd5-hbgwq   1/1     Running   0          3s    10.32.0.2   worker2   <none>           <none>
nginx-test-66b6c48dd5-hhtht   1/1     Running   0          3s    10.32.0.4   worker2   <none>           <none>
nginx-test-66b6c48dd5-p6s29   1/1     Running   0          3s    10.32.0.3   worker2   <none>           <none>

-- 파드 업데이트 실행(1.18 버전으로)
~$ kubectl set image deployment nginx-test nginx=nginx:1.18.0 --record
deployment.apps/nginx-test image updated

-- Terminating 되면서 ContainerCreating 되는 파드가 확인 됨
/home/devops/work:$ kubectl get pods -o wide
NAME                          READY   STATUS              RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-test-66b6c48dd5-hbgwq   1/1     Running             0          61s   10.32.0.2   worker2   <none>           <none>
nginx-test-66b6c48dd5-hhtht   1/1     Terminating         0          61s   10.32.0.4   worker2   <none>           <none>
nginx-test-66b6c48dd5-p6s29   1/1     Running             0          61s   10.32.0.3   worker2   <none>           <none>
nginx-test-75c7f965d8-gzxnn   0/1     ContainerCreating   0          0s    <none>      worker2   <none>           <none>
nginx-test-75c7f965d8-z79mn   1/1     Running             0          1s    10.32.0.5   worker2   <none>           <none>

-- Terminating 중
/home/devops/work:$ kubectl get pods -o wide
NAME                          READY   STATUS        RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-test-66b6c48dd5-hbgwq   0/1     Terminating   0          48s   10.32.0.4   worker2   <none>           <none>
nginx-test-75c7f965d8-976nz   1/1     Running       0          13s   10.32.0.3   worker2   <none>           <none>
nginx-test-75c7f965d8-cvsrk   1/1     Running       0          30s   10.32.0.5   worker2   <none>           <none>
nginx-test-75c7f965d8-xwkr5   1/1     Running       0          15s   10.32.0.2   worker2   <none>           <none>


-- 모두 완료
home/devops/work:$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-test-75c7f965d8-ggfkl   1/1     Running   0          57s   10.32.0.3   worker2   <none>           <none>
nginx-test-75c7f965d8-gzxnn   1/1     Running   0          58s   10.32.0.4   worker2   <none>           <none>
nginx-test-75c7f965d8-z79mn   1/1     Running   0          59s   10.32.0.5   worker2   <none>           <none>

위 디플로이먼트를 자세히 살펴보면 먼저 새로운 파드를 생성한 다음 이전 파드를 삭제하고, 새로운 파드를 만든 것을 볼 수 있습니다.
충분한 수의 새로운 파드가 나올 때까지 이전 파드를 삭제(Terminating) 하지 않으며, 충분한 수의 이전 파드들이 삭제(Terminating) 전까지 새로운 파드를 만들지 않게 됩니다.
이것은 최소 2개의 파드를 사용할 수 있게 하고, 최대 4개의 파드를 사용할 수 있게 됩니다.

그리고 위에서 --record 를 사용한 이유는 사용하게 되면 향후에 원래 버전으로 Rollback 이 가능해집니다.

nginx-test 디폴로이먼트를 다시 한번 확인 해보겠습니다.

~$ kubectl describe deployments.apps nginx-test 
Name:                   nginx-test
Namespace:              workns
CreationTimestamp:      Wed, 20 Oct 2021 02:01:26 +0900
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 5
                        kubernetes.io/change-cause: kubectl set image deployment nginx-test nginx=nginx:1.18.0 --record=true
Selector:               app=nginx
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=nginx
  Containers:
   nginx:
    Image:        nginx:1.18.0 <---
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>

Nginx 버전이 1.18.0 으로 변경 된 것을 확인 할 수 있습니다.

동일한 방법으로 1.19.0 으로도 한번 더 변경을 해보겠습니다.

~$ kubectl set image deployment nginx-test nginx=nginx:1.19.0 --record
deployment.apps/nginx-test image updated


위와 마찬가지로 컨테이너 상태 값이 ContainerCreating 와 Terminating 이 번갈아 가면서 재생성 되게 됩니다.
다시 deployment 를 조회하면 nginx 가 1.19.0 버전으로 변경 된 것을 확인 할 수 있습니다.

~$ kubectl describe deployments.apps nginx-test 
Name:                   nginx-test
Namespace:              workns
CreationTimestamp:      Wed, 20 Oct 2021 02:01:26 +0900
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 6
                        kubernetes.io/change-cause: kubectl set image deployment nginx-test nginx=nginx:1.19.0 --record=true
Selector:               app=nginx
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=nginx
  Containers:
   nginx:
    Image:        nginx:1.19.0 <--- 1.19.0 으로 업데이트 됨
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
< ... 중략 ... >

              

파드 롤백

Deployment 은 롤링 업데이트 및 롤백을 지원합니다 위에서 업데이트한 내역을 다시 롤백 해보도록 하겠습니다.

먼저 rollout history 명령어를 통해서 변경된 REVISION 정보를 확인 할 수 있습니다.

~$ kubectl rollout history deployment nginx-test

REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment nginx-test nginx=nginx:1.18.0 --record=true
3         kubectl set image deployment nginx-test nginx=nginx:1.19.0 --record=true

REVISION 1 이 처음 생성한 Nginx 1.14.2 버전입니다 2번 3번은 각각 표기되어 있는 버전으로 deployment 를 변경한 이력이 확인 됩니다.
현재는 가장 최신번호인 REVISION 3번인 nginx:1.19.0 로 실행 중입니다.


위에서 설명한 것 처럼 Deployment 는 롤백이 가능하기 때문에 롤백을 수행해보도록 하겠습니다.

아래 명령어에서 --to-revision 에는 롤백해서 복귀하기를 원하는 REVISION 번호를 입력 하면 됩니다.
포스팅에서는 nginx:1.18.0 버전으로 롤백하기 위해서 REVISION 2 를 입력하여 롤백 하겠습니다.

~$ kubectl rollout undo deployment --to-revision=2
deployment.apps/nginx-test rolled back


컨테이너가 재생성 된 후 deployment 를 확인 해보면 Nginx 버전이 변경 된 것을 확인 할 수 있습니다.

~$ kubectl describe deployments.apps nginx-test 
Name:                   nginx-test
Namespace:              workns
CreationTimestamp:      Wed, 20 Oct 2021 02:01:26 +0900
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 7
                        kubernetes.io/change-cause: kubectl set image deployment nginx-test nginx=nginx:1.18.0 --record=true
Selector:               app=nginx
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=nginx
  Containers:
   nginx:
    Image:        nginx:1.18.0  <-------
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
< .. 중략 .. >


rollout history 에서도 다시 변경 된 것을 확인 할 수 있습니다.

~$ kubectl rollout history deployment nginx-test

REVISION  CHANGE-CAUSE
1         <none>
3         kubectl set image deployment nginx-test nginx=nginx:1.19.0 --record=true
4         kubectl set image deployment nginx-test nginx=nginx:1.18.0 --record=true

           

Deployment 삭제

Deployment 삭제는 kubectl 커멘트를 통해서 삭제할 수 있습니다.

생성된 파드를 삭제하면 설정한 ReplicaSet 에 의해서 3개를 유지 하기 위해서 계속 파드를 실행하게 됩니다.
그러므로 delete deployments 를 통해서 Deployment 객체 자체를 삭제 해야 합니다.

~$ kubectl delete deployments.apps nginx-test


상위 객체를 삭제하면 하위 객체까지 같이 삭제가 됩니다.
즉 deployment 를 삭제하면 deployment 내에 있는 ReplicaSet 과 생성된 파드도 같이 삭제가 됩니다.


여기까지 해서 외부 접속 방법 중 하나인 LoadBalancer 설정과 Replica 그리고 Deployment 에 대해서 확인 해보았습니다.

이번 포스팅은 여기에서 마무리 하도록 하겠으며, 다음 포스팅은 쿠버네티스에서 영구 볼륨 사용에 관한 내용을 확인 해보도록 하겠습니다.

                           

Reference

Reference Link
 • kubernetes.io/pods
 • kubernetes.io/replicaset
 • kubernetes.io/scheduling-eviction
 • kubernetes.io/deployment



관련된 다른 글

 

                 

0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x