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