Last Updated on 10월 28, 2021 by Jade(정현호)
안녕하세요
이번 포스팅에서는 쿠버네티스의 파드의 외부 접속 방법 중 LoadBalancer 관련 내용과 Replica 와 Deployment 에 대해서 확인 해보도록 하겠습니다.
해당 포스팅은 아래 포스팅에서 이어지는 글 입니다.
Contents
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 기능을 사용할 수 있으며 외부 접속을 할 수 있습니다.
metal Kubernetes clusters, using standard
routing protocols.
MetalLB 설치를 진행 해보도록 하겠습니다. 설치 관련된 정보는 아래 링크에서 더 자세하게 확인 해보실 수 있습니다.
requirements. In
particular, you should pay attention to network addon
compatibility.
먼저 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
관련된 다른 글
Principal DBA(MySQL, AWS Aurora, Oracle)
핀테크 서비스인 핀다에서 데이터베이스를 운영하고 있어요(at finda.co.kr)
Previous - 당근마켓, 위메프, Oracle Korea ACS / Fedora Kor UserGroup 운영중
Database 외에도 NoSQL , Linux , Python, Cloud, Http/PHP CGI 등에도 관심이 있습니다
purityboy83@gmail.com / admin@hoing.io