こんにちは
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
今日も今日とてKubernetesの学習をしていたのですが、Taints/Tolerationsという概念とDeamonSetという概念を学びました。
その時に1つの疑問が生じました。「あれ?どっちが優先されるんだろう?DeamonSetは全てのnodeに同じ環境をデプロイするんだよな?けどnodeにTaintsが設定されていたら、邪魔されるよね?どうなるんだ?どっちが優先されるんだ?」
今回はそんな(くだらない)疑問を解消する為のlogを取りましたので、備忘録として記載しておきます。
用語
Taints/Tolerations
toleration はPodに適用され、一致するtaintが付与されたNodeへPodがスケジューリングされることを認めるものです。ただしそのNodeへ必ずスケジューリングされるとは限りません。
taintとtolerationは組になって機能し、Podが不適切なNodeへスケジューリングされないことを保証します。taintはNodeに一つまたは複数個付与することができます。これはそのNodeがtaintを許容しないPodを受け入れるべきではないことを示します。
DeamonSet
DaemonSetは、すべての(または一部の)ノードがPodのコピーを実行することを保証します。ノードがクラスタに追加されると、Podが追加されます。ノードがクラスタから削除されると、これらのPodはガベージコレクションされます。DaemonSetを削除すると、それが作成したPodがクリーンアップされます。
検証イメージ
環境は以下を用意しました。4台のnodeでk8sクラスタを組んでおります。
k8s-master nodeに対してtaints env=master:NoScheduleを設定していきます。
この状態でtolerationsが設定されていないDeamonSet(pod)がk8s-masterにデプロイされるのか、或いはtolerationsが設定されていない為はじかれるのか、ということになります。
もしpodがデプロイされたらDeamonSetのプライオリティが高く、そうでなければTaints/Tolerationsのプライオリティが高いということになります。
以下が検証前の環境logになります。
nodeが4台あり、特に何もデプロイされていないことが分かると思います。
root@k8s-master:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-worker01 Ready <none> 34h v1.26.4
k8s-master Ready <none> 2d2h v1.26.4
k8s-worker02 Ready <none> 34h v1.26.4
k8s-worker03 Ready <none> 54s v1.26.4
root@k8s-master:~# kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 2d2h
また以下のコマンド結果より、k8s-master nodeにtaintsが何も設定されていないことが分かります。
root@k8s-master:~# kubectl describe node k8s-master | grep Taints
Taints: <none>
nodeにtaintsを設定する
taintsを設定する為にはkubectl taint nodeコマンドを実行します。
今回は以下のコマンドを実行しました。describeの出力結果で設定が正常に出来ていることが分かります。
root@k8s-master:~# kubectl taint node k8s-master env=master:NoSchedule
node/k8s-master tainted
root@k8s-master:~# kubectl describe node k8s-master | grep Taints
Taints: env=master:NoSchedule
DeamonSetをデプロイ
今回ds用に準備したyamlファイルは以下となります。
ds名は"test-ds"、pod名は"nginx"とし、pod内のコンテナは1つで名前を"nginx-container"としています。
root@k8s-master:~/yaml# cat test-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: test-ds
spec:
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
このyamlファイルをベースにデプロイしていきます。
root@k8s-master:~/yaml# kubectl create -f test-ds.yaml
daemonset.apps/test-ds created
どのノードにデプロイされているか確認します。
出力結果よりk8s-master nodeにはデプロイされていませんね。
taints/tolerationsが優先されているっぽいです。
root@k8s-master:~/yaml# kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/test-ds-f858g 1/1 Running 0 63s 10.1.79.69 k8s-worker01 <none> <none>
pod/test-ds-shk5r 1/1 Running 0 63s 10.1.39.193 k8s-worker03 <none> <none>
pod/test-ds-2nt4m 1/1 Running 0 63s 10.1.69.199 k8s-worker02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 2d2h <none>
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/test-ds 3 3 3 3 3 <none> 63s nginx-container nginx:latest name=nginx
DeamonSetにtolerationsを設定してみる
追加検証です。以下の様にyamlを修正しデプロイされるpodにtolerationを付与していきます。
root@k8s-master:~/yaml# cat test-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: test-ds
spec:
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
tolerations:
- key: "env"
operator: "Equal"
value: "master"
effect: NoSchedule
containers:
- name: nginx-container
image: nginx:latest
先程作成したdsを削除してから、修正したyamlで再度dsをデプロイします
root@k8s-master:~/yaml# kubectl delete ds test-ds
daemonset.apps "test-ds" deleted
root@k8s-master:~/yaml# kubectl create -f test-ds.yaml
daemonset.apps/test-ds created
デプロイ結果は以下です。
tolerationを設定したことでk8s-master nodeにもpodがデプロイされましたね。
root@k8s-master:~/yaml# kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/test-ds-4z2k9 1/1 Running 0 42s 10.1.79.70 k8s-worker01 <none> <none>
pod/test-ds-l9wps 1/1 Running 0 42s 10.1.39.194 k8s-worker03 <none> <none>
pod/test-ds-5677r 1/1 Running 0 42s 10.1.69.200 k8s-worker02 <none> <none>
pod/test-ds-wvwkj 1/1 Running 0 42s 10.1.235.210 k8s-master <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 2d3h <none>
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/test-ds 4 4 4 4 4 <none> 42s nginx-container nginx:latest name=nginx