[k8s] Controller - DaemonSet

2022. 9. 16. 16:41[ DevOps ]/[ k8s ]

 

이전 포스팅에서 다룬 컨트롤러

- ReplicationController: 컨트롤러의 가장 근본적인 역할을 하는 컨트롤러로 Pod의 개수를 보장

- ReplicaSet: 풍부한 label을 지원하여 다양한 조건에 해당하는 Pod 개수 보장

- Deployment: ReplicaSet을 컨트롤하며 Rolling Update를 지원

 

-> 결국 세 개의 컨트롤러는 모두 'Pod의 개수를 보장'하는 것이 주요 역할이었던 컨트롤러였다. DaemonSet도 Pod의 개수를 보장하지만 다른 컨트롤러와 비교해보면 약간 성격이 다르다.

 

 

 

DaemonSet

- 이전에 다룬 다른 컨트롤러와 달리 DaemonSet은 노드 당 1개씩의 Pod를 보장하는 컨트롤러이다.

- 운영 중에 노드가 추가되면 추가된 노드 개수만큼 Pod를 각각 추가한다.

- DaemonSet으로 실행 중인 Pod를 삭제하면 Pod가 삭제되지 않는 것이 아니라 해당 Pod가 완전히 삭제된 후 동일한 노드 위치에 다시 실행시키는 구조로 동작한다.

- 각 노드에 한 개씩의 Pod가 필요한 상황에서 사용되며 '로그 수집기', 'HW리소스 모니터링 툴'이 대표적이다.

- 쿠버네티스 환경에서 내부적으로 실행되는 kube-proxy, CNI 네트워크 플러그인들은 DaemonSet 타입으로 실행 중인 Pod이다.

- Definition 파일의 type으로 'DaemonSet'을 사용한다.

- 노드 당 1개의 Pod를 보장하는 정의가 내재되어 있기 때문에 Definition 파일에서 replicas 필드가 필요 없다.

- DaemonSet은 Rolling Update도 지원한다. 하지만 Deployment와 실행방법은 약간 다르다. DaemonSet은 edit 커맨드를 통해 실행 중인 파일을 직접 변경하기만 하면 바로 Rolling Update가 트리거된다.

 

 

실습

DaemonSet에 대한 실습을 진행하기 위해 기존의 워커 노드 1개를 삭제고 DaemonSet을 실행시킨 후, 다시 워커 노드를 join 하여 DaemonSet Pod가 새로운 노드에 추가되는지 확인한다.

 

우선 실행 중인 Pod가 있는지 먼저 확인하고 남겨둘 Pod가 없다면 노드를 제거한다.

 

Daemonset Definition 파일

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-nginx
spec:
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14

- 노드 당 1개의 Pod를 보장하는 정의가 내재되어 있기 때문에 Definition 파일에서 replicas 필드가 불필요하다.

- kind 필드로 DaemonSet을 사용한다.

 

 

실행 후 결과 확인

- 현재 워커 노드가 1개이므로 master 노드를 제외한 1개의 Pod가 정상적으로 실행되었다.

 

 

워커 노드 추가

1) token 발급 (master에서 진행)

워커 노드가 master에 join 하기 위한 token이 필요하다. 토큰과 해시값을 확인한다. (반드시 master에서 진행)

 

 

cf. 만약 토큰이 없다면 아래와 같이 2시간 유효한 토큰을 발급한다.

$ kubeadm token create --ttl 2h

 

 

2) 노드 join

이미 join 한 기록이 있다면 reset 한다.

root@node2:~# kubeadm reset
[reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted.
[reset] Are you sure you want to proceed? [y/N]: y
[preflight] Running pre-flight checks
W1001 21:48:44.156000   14945 removeetcdmember.go:80] [reset] No kubeadm config, using etcd pod spec to get data directory
[reset] No etcd config found. Assuming external etcd
[reset] Please, manually reset etcd to prevent further issues
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki]
[reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]
[reset] Deleting contents of stateful directories: [/var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni]

The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d

The reset process does not reset or clean up iptables rules or IPVS tables.
If you wish to reset iptables, you must do so manually by using the "iptables" command.

If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar)
to reset your system's IPVS tables.

The reset process does not clean your kubeconfig files and you must remove them manually.
Please, check the contents of the $HOME/.kube/config file.

* 반드시 새로 join 할 worker에서 진행할 것.

 

 

- 위 master에서 발급한 토큰과 해시값으로 master에 join 한다.

root@node2:~# kubeadm join 10.100.0.104:6443 --token pigsgh.kdnvlzk9sm4f9iqm --discovery-token-ca-cert-hash sha256:9c2614cf987f3b4775980b68760254bc6bad540307169149994d6e6e91f1591a
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

 

--token: master에서 발급한 토큰

--discovery-token-ca-cert-hash: master에서 확인한 해시

 

 

결과 확인

 

- 위와 같이 node2가 추가되었고 DaemonSet에 의해 새로 Join 한 노드에 새로운 Pod가 추가되었음을 확인할 수 있다.

 

 


 

DaemonSet의 Rolling Update

데몬셋의 Rolling Update는 실행 중인 DaemonSet을 편집하여 진행할 수 있다.

$ kubectl edit daemonsets.apps daemonset-nginx

 

- 위와 같이 1.14를 1.15 버전으로 변경하면 자동으로 Rolling Update가 발생한다.

 

 

 

DaemonSet의 Rollback

edit로 Rolling Update를 하면 위와 같이 history가 남겨지기 때문에 Rollback 또한 가능하다. Deployment와 마찬가지로 rollout undo 커맨드를 사용하여 Rollback 할 수 있다.

 

 

 

cf. 실행 중인 DaemonSet 삭제

- DaemonSet을 삭제해야 Pod도 함께 삭제된다.

 

 

 

Reference

- 따배쿠, https://youtu.be/wJeb561CMOg

- k8s 데몬셋 문서, https://kubernetes.io/ko/docs/concepts/workloads/controllers/daemonset/