zaki work log

作業ログやら生活ログやらなんやら

[Kubernetes] DaemonSetで動いてるPodを停止(スケールを0に)したい

業務で元リソースはそのままでPodを一時的に停止していろいろ確認するなんやかやがあり、DeploymentやStatefulSetはkubectl scaleでレプリカ数を0にすれば良かったんだけど、DaemonSetってそういえばレプリカ0にできないというかそもそもレプリカの概念がなく、なんとかできそうにないかと思いつつ検索してみるとnodeSelectorを使ってデプロイできるノードを無くすという技がいくつかヒットしたので試してみた。

stackoverflow.com

まとめておくと以下でOK

# 停止
kubectl -n <namespace> patch daemonset <daemonset-resource> -p '{"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}}'

# 起動
kubectl -n <namespace> patch daemonset <daemonset-resource> --type json -p='[{"op": "remove", "path": "/spec/template/spec/nodeSelector/non-existing"}]'

サンプルDaemonSet

GitHubに置いてあるDaemonSet版webサーバーマニフェストを使用。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: http-daemon
  name: http-daemon
spec:
  selector:
    matchLabels:
      app: http-daemon
  template:
    metadata:
      labels:
        app: http-daemon
    spec:
      containers:
      - image: httpd
        name: httpd
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: http-daemon
  name: http-daemon
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    name: http
  selector:
    app: http-daemon
  type: ClusterIP
$ kubectl apply -f https://raw.githubusercontent.com/zaki-lknr/k8s-samples/master/sample-web/httpd-daemonset/sample-http.yaml
daemonset.apps/http-daemon created
service/http-daemon created

zaki@cloud-dev2:~$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP          NODE           NOMINATED NODE   READINESS GATES
http-daemon-g6glw   1/1     Running   0          23s   10.42.0.6   730dd035b3ef   <none>           <none>
http-daemon-rxxbk   1/1     Running   0          23s   10.42.1.6   e35370123528   <none>           <none>

このDaemonSetリソースに対してレプリカ数を操作しようとしてもエラーになる。

zaki@cloud-dev2:~$ kubectl scale ds http-daemon --replicas=0
Error from server (NotFound): the server could not find the requested resource

ノードセレクタを設定

kubectl patchでノードセレクタを追加

zaki@cloud-dev2:~$ kubectl -n default patch daemonset http-daemon -p '{"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}}'
daemonset.apps/http-daemon patched

するとPodが停止する。

zaki@cloud-dev2:~$ kubectl get pod -o wide
NAME                READY   STATUS        RESTARTS   AGE     IP       NODE           NOMINATED NODE   READINESS GATES
http-daemon-rxxbk   0/1     Terminating   0          2m18s   <none>   e35370123528   <none>           <none>
zaki@cloud-dev2:~$ kubectl get pod -o wide
No resources found in default namespace.

DaemonSetリソースはこの通り、ノードセレクタが設定され、DESIREDが0になる。

zaki@cloud-dev2:~$ kubectl get daemonset
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR       AGE
http-daemon   0         0         0       0            0           non-existing=true   4m5s

元に戻す

zaki@cloud-dev2:~$ kubectl -n default patch daemonset http-daemon --type json -p='[{"op": "remove", "path": "/spec/template/spec/nodeSelector/non-existing"}]'
daemonset.apps/http-daemon patched

ノードセレクタの設定を削除するとPodが再度デプロイされる。

zaki@cloud-dev2:~$ kubectl get daemonset
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
http-daemon   2         2         1       2            1           <none>          5m7s
zaki@cloud-dev2:~$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP          NODE           NOMINATED NODE   READINESS GATES
http-daemon-j84kz   1/1     Running   0          7s    10.42.1.7   e35370123528   <none>           <none>
http-daemon-whp2q   1/1     Running   0          7s    10.42.0.7   730dd035b3ef   <none>           <none>

(余談) 停止中に対象ラベルをノードに設定すると…

もちろんラベルをセットしたノードではデプロイされる。

# podが停止している状態
zaki@cloud-dev2:~$ kubectl get pod 
No resources found in default namespace.

# ノードのラベル状態
zaki@cloud-dev2:~$ kubectl get nodes --show-labels 
NAME           STATUS   ROLES                  AGE   VERSION        LABELS
e35370123528   Ready    control-plane,master   11m   v1.29.1+k3s2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=k3s,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=e35370123528,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=true,node-role.kubernetes.io/master=true,node.kubernetes.io/instance-type=k3s
730dd035b3ef   Ready    <none>                 11m   v1.29.1+k3s2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=k3s,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=730dd035b3ef,kubernetes.io/os=linux,node.kubernetes.io/instance-type=k3s

# ラベル設定
zaki@cloud-dev2:~$ kubectl label node 730dd035b3ef non-existing=true
node/730dd035b3ef labeled
zaki@cloud-dev2:~$ kubectl get nodes --show-labels 
NAME           STATUS   ROLES                  AGE   VERSION        LABELS
e35370123528   Ready    control-plane,master   11m   v1.29.1+k3s2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=k3s,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=e35370123528,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=true,node-role.kubernetes.io/master=true,node.kubernetes.io/instance-type=k3s
730dd035b3ef   Ready    <none>                 11m   v1.29.1+k3s2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=k3s,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=730dd035b3ef,kubernetes.io/os=linux,node.kubernetes.io/instance-type=k3s,non-existing=true

# ラベルを設定したノードにはpodがデプロイされる
zaki@cloud-dev2:~$ kubectl get pod -o wide
NAME                READY   STATUS              RESTARTS   AGE   IP       NODE           NOMINATED NODE   READINESS GATES
http-daemon-jwg8d   0/1     ContainerCreating   0          9s    <none>   730dd035b3ef   <none>           <none>
zaki@cloud-dev2:~$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP          NODE           NOMINATED NODE   READINESS GATES
http-daemon-jwg8d   1/1     Running   0          29s   10.42.0.8   730dd035b3ef   <none>           <none>

環境

K3s v1.29(コンテナ版)で確認

zaki@cloud-dev2:~$ kubectl get node
NAME           STATUS   ROLES                  AGE    VERSION
730dd035b3ef   Ready    <none>                 115s   v1.29.1+k3s2
e35370123528   Ready    control-plane,master   2m6s   v1.29.1+k3s2

nodeSelectorを使ってPodをデプロイするノードを制御、みたいなまとめを書いてたような気がしてたけど気のせいだったか。。