無知

갈 길이 먼 공부 일기

기술 공부/쿠버네티스

쿠버네티스 (4) | 레플리카셋, 데몬셋, 잡, 크론잡

moozii 2022. 2. 10. 00:57
앞으로의 스터디 내용은 <Kubernetes in Action>을 기반으로 진행합니다.
자세한 내용은, 해당 책을 확인해주세요! 
http://www.yes24.com/Product/Goods/89607047 
이번 챕터의 경우 전체 포스트를 완성하였으나 티스토리 오류로 임시저장본이 초기 작성 시기로 롤백되고, 기존 작성 분이 모두 사라진 관계로... 일단 스터디를 통해 기억나는 개념을 간단히 재정리하면서 간략한 정리본만 남기겠습니다 ㅠㅠ

 

파드의 안정적인 유지를 위해서, 컨테이너 외부 측면에서도 컨테이너의 상황을 확인하는 장치가 필요한데, 

이를 위한 것이 쿠버네티스 라이브니스 프로브이다.

애플리케이션이 정상이라고 간주되는 조건을 http get 등의 방법을 통해 조회하여, 조건 충족 시 성공, 그렇지 않을 경우 실패로 판단한다. 

 

$ minikube start
😄  Darwin 12.0.1 의 minikube v1.25.1
(중략)
🏄  끝났습니다! kubectl이 "minikube" 클러스터와 "default" 네임스페이스를 기본적으로 사용하도록 구성되었습니다.

$ kubectl create -f kubia-liveness-probe.yaml
pod/kubia-liveness created

$ kubectl get po kubia-liveness
NAME             READY   STATUS    RESTARTS      AGE
kubia-liveness   1/1     Running   1 (27s ago)   2m57s

$ kubectl describe po kubia-liveness 
Name:         kubia-liveness
Namespace:    default
Priority:     0
Node:         minikube/192.168.59.100
Start Time:   Wed, 09 Feb 2022 17:28:35 +0900
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           172.17.0.5
IPs:
  IP:  172.17.0.5
Containers:
  kubia:
    Container ID:   docker://6f1003cb1559780c23b704e892e92ae9a7e90d85b07df057ef5ece4e956fe710
    Image:          luksa/kubia-unhealthy
    Image ID:       docker-pullable://luksa/kubia-unhealthy@sha256:5c746a42612be61209417d913030d97555cff0b8225092908c57634ad7c235f7
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 09 Feb 2022 17:32:57 +0900
    Last State:     Terminated
      Reason:       Error
      Exit Code:    137
      Started:      Wed, 09 Feb 2022 17:31:07 +0900
      Finished:     Wed, 09 Feb 2022 17:32:55 +0900
    Ready:          True
    Restart Count:  2
    Liveness:       http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-m7jcq (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-m7jcq:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  5m11s                default-scheduler  Successfully assigned default/kubia-liveness to minikube
  Normal   Pulled     4m29s                kubelet            Successfully pulled image "luksa/kubia-unhealthy" in 41.401255065s
  Normal   Pulled     2m39s                kubelet            Successfully pulled image "luksa/kubia-unhealthy" in 2.397849365s
  Warning  Unhealthy  81s (x6 over 3m31s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500
  Normal   Killing    81s (x2 over 3m11s)  kubelet            Container kubia failed liveness probe, will be restarted
  Normal   Pulling    51s (x3 over 5m11s)  kubelet            Pulling image "luksa/kubia-unhealthy"
  Normal   Created    49s (x3 over 4m29s)  kubelet            Created container kubia
  Normal   Started    49s (x3 over 4m29s)  kubelet            Started container kubia
  Normal   Pulled     49s                  kubelet            Successfully pulled image "luksa/kubia-unhealthy" in 2.409374627s

 


 

파드는 직접 생성하기 보다, 미리 지정한 명세에 따라 자동 복원시키는 방식을 통해 안정성을 꾀해야 하는데, 

이때 활용하는 것이 레플리케이션 컨트롤러이다. 

레플리케이션 컨트롤러를 통해 원하는 파드 생성수를 명시해 해당 리소스를 생성하면, 그에 맞게 즉시 파드를 생성한다. 

의도하는 수의 파드 복제본을 파드 탬플릿에 맞추어 항상 생성해 실행 상태로 유지시킨다. 

즉, 파드의 수 조절은 레플리케이션 컨트롤러의 레플리카 수 변경으로 간단히 진행 가능하다. 

 

$ kubectl create -f kubia-rc.yaml 
replicationcontroller/kubia created

$ kubectl get pods
NAME             READY   STATUS             RESTARTS       AGE
kubia-8hxrp      1/1     Running            0              84s
kubia-liveness   0/1     CrashLoopBackOff   13 (34s ago)   44m
kubia-mz9pf      1/1     Running            0              84s
kubia-wjxpq      1/1     Running            0              84s

$ kubectl delete pod kubia-liveness 
pod "kubia-liveness" deleted

$ kubectl get pods                 
NAME          READY   STATUS    RESTARTS   AGE
kubia-8hxrp   1/1     Running   0          103s
kubia-mz9pf   1/1     Running   0          103s
kubia-wjxpq   1/1     Running   0          103s

$ kubectl delete pod kubia-8hxrp   
pod "kubia-8hxrp" deleted

$ kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
kubia-44lj4   1/1     Running   0          31s
kubia-mz9pf   1/1     Running   0          3m10s
kubia-wjxpq   1/1     Running   0          3m10s

$ kubectl get rc
NAME    DESIRED   CURRENT   READY   AGE
kubia   3         3         3       4m

$ kubectl describe rc kubia 
Name:         kubia
Namespace:    default
Selector:     app=kubia
Labels:       app=kubia
Annotations:  <none>
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=kubia
  Containers:
   kubia:
    Image:        luksa/kubia
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                    Message
  ----    ------            ----   ----                    -------
  Normal  SuccessfulCreate  4m30s  replication-controller  Created pod: kubia-8hxrp
  Normal  SuccessfulCreate  4m30s  replication-controller  Created pod: kubia-wjxpq
  Normal  SuccessfulCreate  4m30s  replication-controller  Created pod: kubia-mz9pf
Normal  SuccessfulCreate  111s   replication-controller  Created pod: kubia-44lj4

$ kubectl get pods --show-labels 
NAME          READY   STATUS    RESTARTS   AGE     LABELS
kubia-44lj4   1/1     Running   0          6m32s   app=kubia
kubia-mz9pf   1/1     Running   0          9m11s   app=kubia
kubia-wjxpq   1/1     Running   0          9m11s   app=kubia

$ kubectl label pod kubia-44lj4 app=foo --overwrite 
pod/kubia-44lj4 labeled

$ kubectl get pods -L app       
NAME          READY   STATUS    RESTARTS   AGE     APP
kubia-44lj4   1/1     Running   0          7m12s   foo
kubia-mz9pf   1/1     Running   0          9m51s   kubia
kubia-sgv6k   1/1     Running   0          10s     kubia
kubia-wjxpq   1/1     Running   0          9m51s   kubia

 


 

https://itnext.io/k8s-deployments-replicasets-part1-babdb0215156

 

레플리케이션 컨트롤러는, 레플리카셋과 디플로이먼트로 최신화되어 해당 방식으로 생성하기를 권장한다. 

레플리카셋은, 레플리케이션 컨트롤러와 달리 파드 셀렉터를 활용해서 보다 효과적으로 매칭 파드를 지정할 수 있다.

(기존 레플리케이션 컨트롤러도 파드를 레이블 셀렉터를 통해 지정하여 파드 조건을 미리 명세할 수 있었지만, 

표현식을 활용할 수 있는 레플리카셋 파드 셀렉터는 개선된 버전이다.)

여러 표현식을 추가하여 특정 레이블 값을 지니거나 지니지 않거나, 특징 키를 가진 레이블이 포함되거나 포함되지 않는 파드를 지정할 수 있다. 해당 조건을 만족하는 파드의 수가 원하는 수와 다르면 그만큼 생성하거나 삭제해서 그 수를 유지시킨다. 

 

$ kubectl create -f kubia-replicaset.yaml 
error: unable to recognize "kubia-replicaset.yaml": no matches for kind "ReplicaSet" in version "apps/v1beta2"

$ vim kubia-replicaset.yaml

$ kubectl create -f kubia-replicaset.yaml
replicaset.apps/kubia created

$ kubectl get rs
NAME    DESIRED   CURRENT   READY   AGE
kubia   3         3         3       83s

$ kubectl get pods -L app
NAME          READY   STATUS    RESTARTS   AGE     APP
kubia-27g22   1/1     Running   0          103s    kubia
kubia-2d88h   1/1     Running   0          103s    kubia
kubia-44lj4   1/1     Running   0          3h59m   foo
kubia-dhsxr   1/1     Running   0          103s    kubia
kubia-mz9pf   1/1     Running   0          4h2m    kubia
kubia-sgv6k   1/1     Running   0          3h52m   kubia
kubia-wjxpq   1/1     Running   0          4h2m    kubia

 

* 실습 중 레플리케이션 컨트롤러를 삭제하지 않은 채 레플리카셋을 생성하면, 동일 파드 조건을 요구하더라도, 추가로 파드를 레플리카셋이 생성했는데, 레플리케이션 컨트롤러를 삭제하고 조건에 부합하는 파드는 남겨놓는 경우 (캐스케이드 옵션을 지운 삭제 방식. 그냥 레플리카셋이나 레플리케이션 컨트롤러를 삭제하면, 그로 인해 생성된 파드도 함께 삭제되므로 해당 옵션을 사용해야만 한다.), 레플리카셋이 추가로 신규 파드를 생성하지 않는 모습을 보이는 것을 확인했다.

 

$ kubectl describe rs    
Name:         kubia
Namespace:    default
Selector:     app=kubia
Labels:       <none>
Annotations:  <none>
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=kubia
  Containers:
   kubia:
    Image:        luksa/kubia
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  2m45s  replicaset-controller  Created pod: kubia-dhsxr
  Normal  SuccessfulCreate  2m45s  replicaset-controller  Created pod: kubia-27g22
Normal  SuccessfulCreate  2m45s  replicaset-controller  Created pod: kubia-2d88h

$ kubectl get pods --show-labels
NAME          READY   STATUS    RESTARTS   AGE     LABELS
kubia-27g22   1/1     Running   0          3m37s   app=kubia
kubia-2d88h   1/1     Running   0          3m37s   app=kubia
kubia-44lj4   1/1     Running   0          4h1m    app=foo
kubia-dhsxr   1/1     Running   0          3m37s   app=kubia
kubia-mz9pf   1/1     Running   0          4h4m    app=kubia
kubia-sgv6k   1/1     Running   0          3h54m   app=kubia
kubia-wjxpq   1/1     Running   0          4h4m    app=kubia

$ kubectl delete rs kubia 
replicaset.apps "kubia" deleted

$ kubectl get pods --show-labels
NAME          READY   STATUS        RESTARTS   AGE     LABELS
kubia-27g22   1/1     Terminating   0          5m37s   app=kubia
kubia-2d88h   1/1     Terminating   0          5m37s   app=kubia
kubia-44lj4   1/1     Running       0          4h3m    app=foo
kubia-dhsxr   1/1     Terminating   0          5m37s   app=kubia
kubia-mz9pf   1/1     Running       0          4h6m    app=kubia
kubia-sgv6k   1/1     Running       0          3h56m   app=kubia
kubia-wjxpq   1/1     Running       0          4h6m    app=kubia

$ kubectl delete rc kubia --cascade=false
warning: --cascade=false is deprecated (boolean value) and can be replaced with --cascade=orphan.
replicationcontroller "kubia" deleted

$ kubectl get rc
No resources found in default namespace.

$ kubectl get pods --show-labels         
NAME          READY   STATUS    RESTARTS   AGE     LABELS
kubia-44lj4   1/1     Running   0          4h4m    app=foo
kubia-mz9pf   1/1     Running   0          4h7m    app=kubia
kubia-sgv6k   1/1     Running   0          3h57m   app=kubia
kubia-wjxpq   1/1     Running   0          4h7m    app=kubia

$ kubectl create -f kubia-replicaset.yaml
replicaset.apps/kubia created

$ kubectl get pods --show-labels         
NAME          READY   STATUS    RESTARTS   AGE     LABELS
kubia-44lj4   1/1     Running   0          4h4m    app=foo
kubia-mz9pf   1/1     Running   0          4h7m    app=kubia
kubia-sgv6k   1/1     Running   0          3h57m   app=kubia
kubia-wjxpq   1/1     Running   0          4h7m    app=kubia

 


 

레플리카셋 외에 각 노드에서 정확히 하나의 파드가 각각 실행되게 하려면 데몬셋을 사용한다. 

이러한 용례는 인프라 관련 파드 등 시스템 수준 작업을 수행하는 경우가 해당한다. 

데몬셋을 통해 모든 노드에 파드를 실행시킬 수 있는데, 클러스터의 모든 노드에 배포하는 것이 기본이라는 의미이다.

만약 일부 노드에만 1개의 파드를 실행하도록 노드 조건을 지정하려면 노드 셀렉터를 이용해야 한다. 

 

$ kubectl create -f ssd-monitor-daemonset.yaml
error: unable to recognize "ssd-monitor-daemonset.yaml": no matches for kind "DaemonSet" in version "apps/v1beta2"

$ vim ssd-monitor-daemonset.yaml 

$ kubectl create -f ssd-monitor-daemonset.yaml
daemonset.apps/ssd-monitor created

$ kubectl get ds
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
ssd-monitor   0         0         0       0            0           disk=ssd        70s

$ kubectl get node
NAME       STATUS   ROLES                  AGE   VERSION
minikube   Ready    control-plane,master   15d   v1.23.1

$ kubectl label node minikube disk=ssd
node/minikube labeled

$ kubectl get node                    
NAME       STATUS   ROLES                  AGE   VERSION
minikube   Ready    control-plane,master   15d   v1.23.1

$ kubectl get ds                      
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
ssd-monitor   1         1         1       1            1           disk=ssd        2m2s

$ kubectl get po
NAME                READY   STATUS    RESTARTS   AGE
kubia-44lj4         1/1     Running   0          5h15m
kubia-mz9pf         1/1     Running   0          5h18m
kubia-sgv6k         1/1     Running   0          5h8m
kubia-wjxpq         1/1     Running   0          5h18m
ssd-monitor-8mdsz   1/1     Running   0          61s

$ kubectl label node minikube disk=hdd --overwrite 
node/minikube labeled

$ kubectl get po
NAME                READY   STATUS        RESTARTS   AGE
kubia-44lj4         1/1     Running       0          5h16m
kubia-mz9pf         1/1     Running       0          5h18m
kubia-sgv6k         1/1     Running       0          5h9m
kubia-wjxpq         1/1     Running       0          5h18m
ssd-monitor-8mdsz   1/1     Terminating   0          81s

 


 

다음은, 위에서 생성했듯이 지속적으로 실행이 유지되는 태스크 외에, 

일회성으로 완료되면 반복되지 않는 태스크에 사용하는 잡 리소스가 소개된다.

잡 리소스는 잡 매니페스트를 기반으로 생성하면, 그에 맞게 파드를 생성해 해당 잡을 실행하고, 완료하면 종료된다.

이때 잡이 완료된 이후의 재시작 정책인 파드 스펙 속성 restartPolicy를 OnFailure, Never 등으로 명시해주는 것이 중요하다. 

 

$ kubectl create -f batch-job.yaml 
job.batch/batch-job created

$ kubectl get jobs                
NAME        COMPLETIONS   DURATION   AGE
batch-job   0/1           13s        13s

$ kubectl get po
NAME              READY   STATUS    RESTARTS   AGE
batch-job-ktpgq   1/1     Running   0          22s
kubia-44lj4       1/1     Running   0          5h23m
kubia-mz9pf       1/1     Running   0          5h26m
kubia-sgv6k       1/1     Running   0          5h16m
kubia-wjxpq       1/1     Running   0          5h26m

$ kubectl logs batch-job-ktpgq 
Wed Feb  9 14:37:52 UTC 2022 Batch job starting
Wed Feb  9 14:39:52 UTC 2022 Finished successfully


$ kubectl get rs
NAME    DESIRED   CURRENT   READY   AGE
kubia   3         3         3       90m

$ kubectl delete rs kubia 
replicaset.apps "kubia" deleted

$ kubectl delete job batch-job 
job.batch "batch-job" deleted

$ kubectl delete po kubia-44lj4 
pod "kubia-44lj4" deleted

$ kubectl get po               
No resources found in default namespace.

 

* 실습 중 kubectl get po -a, kubectl get po --show-all 명령을 통해 완료된 잡의 파드도 함께 보여지도록 하라는 가이드가 있었는데, 해당 명령어가 작동하지 않음을 확인했고, kubectl get po라는 명령어를 기본 옵션으로 수행시켜도 완료된 잡이 함께 보여지도록 파드 목록 조회 기능이 변경되었음을 확인했으니 유의하자.

 

$ kubectl get po -a
Error: unknown shorthand flag: 'a' in -a

$ kubectl get po --show-all
Error: unknown flag: --show-all

$ kubectl get po
NAME              READY   STATUS      RESTARTS   AGE
batch-job-ktpgq   0/1     Completed   0          2m47s
kubia-44lj4       1/1     Running     0          5h25m
kubia-mz9pf       1/1     Running     0          5h28m
kubia-sgv6k       1/1     Running     0          5h18m
kubia-wjxpq       1/1     Running     0          5h28m

 

잡에서 여러 파드 인스턴스를 수행시키기 위해서 parallelism 속성을 추가해, 여러 파드를 병렬로 수행시킬 수 있다. 

그리고 해당 잡의 완료 반복 수를 completions 속성을 추가해 지정할 수 있다. 

즉, completions=5, parallelism=3이라면, 해당 잡이 5번 성공할 때까지 3개의 파드를 동시에 굴려 수행시킨다.

 

$ kubectl create -f multi-completion-parallel-batch-job.yaml
job.batch/multi-completion-batch-job created

$ kubectl get po
NAME                               READY   STATUS    RESTARTS   AGE
multi-completion-batch-job-h6hcf   1/1     Running   0          68s
multi-completion-batch-job-svjpt   1/1     Running   0          68s

$ kubectl logs multi-completion-batch-job-svjpt
Wed Feb  9 14:54:19 UTC 2022 Batch job starting
Wed Feb  9 14:56:19 UTC 2022 Finished succesfully
$ kubectl logs multi-completion-batch-job-h6hcf
Wed Feb  9 14:54:21 UTC 2022 Batch job starting
Wed Feb  9 14:56:21 UTC 2022 Finished successfully

$ kubectl get po
NAME                               READY   STATUS      RESTARTS   AGE
multi-completion-batch-job-7l6tr   1/1     Running     0          24s
multi-completion-batch-job-h6hcf   0/1     Completed   0          2m28s
multi-completion-batch-job-svjpt   0/1     Completed   0          2m28s
multi-completion-batch-job-xmbcf   1/1     Running     0          22s

 

* 실습 중 kubectl scale job multi-completion-batch-job --replicas 3이라는 명령어를 통해 실행 중에도 잡의 레플리카, 즉 병렬 파드 수를 조정할 수 있다는 가이드가 있었으나 확인 결과 deprecated되었다. 

https://github.com/kubernetes/kubernetes/pull/60139

 

Deprecate kubectl scale job by soltysh · Pull Request #60139 · kubernetes/kubernetes

What this PR does / why we need it: With the generic scaler (#58298) the only problem is job and as discussed in #58468 (comment) and during SIG CLI we've agreed that scaling jobs was a mistake...

github.com

$ kubectl scale job multi-completion-batch-job --replicas=3
Error from server (NotFound): the server could not find the requested resource

$ kubectl delete job multi-completion-batch-job
job.batch "multi-completion-batch-job" deleted

$ minikube stop  
✋  Stopping node "minikube"  ...
🛑  1 node stopped.

 

잡이 완료되는 데 걸리는 시간의 경우 파드 스펙에 activeDeadlineSeconds를 추가해, 파드의 실행 시간 제한이 가능하다. 그 기한을 초과하면 시스템이 종료를 시도하고 잡은 실패한 것으로 간주된다.

 

잡을 주기적으로 실행시키거나, 특정 시간에 작동시키려면 크론잡 개념을 이용한다. 

해당 크론잡은 크론 형식의 시간마다, 작성한 잡 리소스 템플릿에 맞춰 잡을 생성한다. 

크론 형식 시간은 다음을 참고한다 : https://en.wikipedia.org/wiki/Cron#CRON_expression

 

 

 

 

 

 

https://kubernetes.io/ko/docs/reference/kubectl/cheatsheet/

 

kubectl 치트 시트

이 페이지는 일반적으로 사용하는 kubectl 커맨드와 플래그에 대한 목록을 포함한다. Kubectl 자동 완성 BASH source <(kubectl completion bash) # bash-completion 패키지를 먼저 설치한 후, bash의 자동 완성을 현재

kubernetes.io