はじめに
コンテナオーケストレーションプラットフォームとして広く利用されている Kubernetes は、ノードへの Pod のスケジューリングを制御するための強力な機能である「taints(汚染)」を提供しています。このチュートリアルでは、Kubernetes ノードに適用されている taints を表示する方法を探求します。これは、Kubernetes クラスタを効果的に管理するために不可欠なスキルです。
Taints を使用すると、特定の Pod を拒否できる特定の属性でノードをマークできます。これにより、ワークロードがノードの機能とリソースに基づいて適切にスケジュールされるようになります。Taints の表示と操作方法を理解することは、Kubernetes 環境で最適なリソース割り当てを維持するのに役立ちます。
テスト用の Kubernetes 環境のセットアップ
Kubernetes ノードの taints を表示する前に、機能する Kubernetes 環境が必要です。このチュートリアルでは、開発およびテスト目的で軽量なローカル Kubernetes クラスタを提供する Minikube を使用します。
まず、Minikube をインストールしましょう。
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
rm minikube-linux-amd64
Minikube がインストールされたので、Kubernetes クラスタを起動しましょう。
minikube start --driver=docker
次のような出力が表示されるはずです。
😄 minikube v1.29.0 on Ubuntu 22.04
✨ Using the docker driver based on user configuration
📌 Using Docker driver with root privileges
👍 Starting control plane node minikube in cluster minikube
🚜 Pulling base image ...
🔥 Creating docker container (CPUs=2, Memory=2200MB) ...
🐳 Preparing Kubernetes v1.26.1 on Docker 23.0.1 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔎 Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟 Enabled addons: default-storageclass, storage-provisioner
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
クラスタが実行されていることを確認するために、ノードの状態を確認しましょう。
kubectl get nodes
次のような出力が表示されるはずです。
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 1m v1.26.1
素晴らしい!これで、taints を探索するための機能する Kubernetes 環境ができました。kubectl コマンドは、すでに Minikube クラスタで動作するように設定されています。
Kubernetes Taints の理解
taints を表示する前に、それらが何であり、Kubernetes でどのように機能するかを理解しましょう。
Taints とは?
Taints は、特定の Pod を拒否できるように Kubernetes ノードに適用されるプロパティです。taints を、特定の種類のワークロードに適さないノードをマークするラベルと考えてください。
Taints は、「tolerations(容認)」と呼ばれる概念と連携して機能します。taints はノードに適用されますが、tolerations は Pod に適用されます。ノードの taint に一致する toleration を持つ Pod は、その tainted ノードでスケジュールできます。
Taint の構造
Taints は、次の 3 つのコンポーネントで構成されています。
- Key(キー): taint を識別する文字列(例:
gpu,disk,network) - Value(値): キーに割り当てられたオプションの文字列(例:
true,high-performance) - Effect(エフェクト): 一致する tolerations を持たない Pod の処理方法を定義します
最も一般的な taint エフェクトは次のとおりです。
NoSchedule: 一致する tolerations を持たない新しい Pod は、ノードにスケジュールされませんPreferNoSchedule: システムは、一致する tolerations を持たない Pod をノードに配置しないように試みますが、保証されていませんNoExecute: 一致する tolerations を持たない新しい Pod はノードにスケジュールされず、一致する tolerations を持たない既存の Pod は追い出されます
Taint の構文は次のとおりです。
- 値あり:
key=value:effect - 値なし:
key:effect
Kubernetes クラスタの一部のノードには、デフォルトの taints があります。たとえば、コントロールプレーンノードには、通常のワークロードがそれらにスケジュールされるのを防ぎ、システムコンポーネントのリソースを確保するために、node-role.kubernetes.io/control-plane:NoSchedule が付与されることがよくあります。
Minikube ノードにデフォルトの taints があるかどうかを確認してみましょう。
kubectl describe node minikube | grep -A3 Taints
次のような出力が表示されるはずです。
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable: false
Lease:
HolderIdentity: minikube
この出力は、Minikube ノードが、コントロールプレーンノードであるため、通常の Pod がスケジュールされないようにする taint を持っていることを示しています。
Kubernetes ノードの Taints の表示
taints が何であるかを理解したので、Kubernetes ノードに適用されている taints を表示するためのさまざまな方法を調べてみましょう。
方法 1: kubectl describe の使用
ノードの taints を表示する最も詳細な方法は、kubectl describe node コマンドを使用することです。
kubectl describe node minikube
このコマンドは、ノードに関する包括的な情報を出力します。taints のみに焦点を当てるには、grep を使用できます。
kubectl describe node minikube | grep -A1 Taints
出力例:
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable: false
方法 2: custom-columns を使用した kubectl get の使用
kubectl get nodes コマンドとカスタム出力列を使用して、taints のみを表示できます。
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
出力例:
NAME TAINTS
minikube [map[effect:NoSchedule key:node-role.kubernetes.io/control-plane]]
方法 3: JSONPath を使用した kubectl get の使用
別の方法は、JSONPath を使用して taint 情報を抽出することです。
kubectl get nodes minikube -o jsonpath='{.spec.taints}'
出力例:
[{"effect":"NoSchedule","key":"node-role.kubernetes.io/control-plane"}]
読みやすくするために、出力を JSON としてフォーマットできます。
kubectl get nodes minikube -o jsonpath='{.spec.taints}' | jq .
jq がインストールされていない場合は、次のようにインストールできます。
sudo apt-get update && sudo apt-get install -y jq
フォーマットされた出力例:
[
{
"effect": "NoSchedule",
"key": "node-role.kubernetes.io/control-plane"
}
]
方法 4: YAML 出力を使用した kubectl get の使用
YAML 形式で完全なノード仕様を表示し、taints を検索することもできます。
kubectl get node minikube -o yaml | grep -A5 taints:
出力例:
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
unschedulable: false
status:
addresses:
これらの各方法は、同じ情報を異なる形式で提供します。読みやすさと、情報の使用方法に基づいて、ニーズに最適なものを選択してください。
Taints の追加と削除
taints の表示方法がわかったので、それらの追加と削除の方法を学びましょう。これは、Pod のスケジューリングを制御したり、メンテナンスのためにノードを準備したりする必要がある場合に一般的な操作です。
ノードへの Taints の追加
ノードに taint を追加するための構文は次のとおりです。
kubectl taint nodes <node-name> <key>=<value>:<effect>
Minikube ノードに taint を追加して、GPU を搭載していることをマークしましょう。
kubectl taint nodes minikube gpu=true:NoSchedule
次のような出力が表示されるはずです。
node/minikube tainted
次に、taint が追加されたことを確認しましょう。
kubectl describe node minikube | grep -A3 Taints
出力例:
Taints: gpu=true:NoSchedule
node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable: false
Lease:
ご覧のとおり、ノードには、元のコントロールプレーン taint と新しい GPU taint の 2 つの taints があります。
ノードからの Taints の削除
taint を削除するには、同じ taint 定義にマイナス記号(-)を追加します。
kubectl taint nodes <node-name> <key>=<value>:<effect>-
先ほど追加した GPU taint を削除しましょう。
kubectl taint nodes minikube gpu=true:NoSchedule-
次のような出力が表示されるはずです。
node/minikube untainted
taint が削除されたことを確認しましょう。
kubectl describe node minikube | grep -A3 Taints
出力例:
Taints: node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable: false
Lease:
HolderIdentity: minikube
これで、ノードはコントロールプレーン taint のみを持つ状態に戻りました。
Taints を使用するタイミング
Taints は、いくつかのシナリオで特に役立ちます。
- 特殊なハードウェア: 特殊なハードウェア(GPU など)を持つノードに taint を付与して、そのハードウェアを必要とするワークロードのみがそこにスケジュールされるようにします。
- ノードメンテナンス: メンテナンスを実行する前に taint を追加して、新しい Pod がスケジュールされないようにします。
- セキュリティ分離: セキュリティ上の理由から、特定のワークロードを他のワークロードから分離します。
- リソース最適化: 特定のワークロードタイプにノードを割り当てて、最適なリソース利用を実現します。
taints の表示、追加、および削除の方法を理解することにより、Kubernetes クラスタでの Pod スケジューリングを管理するための基本的な知識が得られました。
Tolerations の操作
taints がどのように機能するかを理解したので、tainted ノードで Pod をスケジュールできるようにするメカニズムである tolerations を見てみましょう。
Tolerations の理解
Tolerations は Pod 仕様で指定され、一致する taints を持つノードで Pod をスケジュールできるようにします。Toleration は以下で構成されます。
key: taint key と一致しますoperator:Equal(キーと値が一致)またはExists(キーのみが一致)のいずれかvalue: 一致させる値(Equaloperator を使用する場合)effect: 一致させる effect、またはすべての effect に一致させる場合は空tolerationSeconds: 一致する NoExecute taint を持つノードに Pod がとどまることができるオプションの期間
Tolerations を使用した Pod の作成
コントロールプレーン taint を許容する Pod を作成しましょう。まず、Pod の YAML ファイルを作成します。
nano ~/project/toleration-pod.yaml
次に、次の内容をファイルに追加します。
apiVersion: v1
kind: Pod
metadata:
name: toleration-pod
spec:
containers:
- name: nginx
image: nginx:latest
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
この Pod 仕様には、ノードのコントロールプレーン taint と一致する toleration が含まれています。ファイルを保存して終了します(nano では、Ctrl+O、Enter、Ctrl+X を押します)。
次に、Pod を作成しましょう。
kubectl apply -f ~/project/toleration-pod.yaml
次のような出力が表示されるはずです。
pod/toleration-pod created
Pod がノードにスケジュールされたかどうかを確認しましょう。
kubectl get pods -o wide
出力例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
toleration-pod 1/1 Running 0 12s 10.244.0.5 minikube <none> <none>
Pod は、コントロールプレーン taint と一致する toleration を持っているため、minikube ノードで実行されています。
Tolerations を使用しない Pod でのテスト
比較のために、tolerations を使用しない Pod を作成しましょう。
nano ~/project/no-toleration-pod.yaml
次の内容を追加します。
apiVersion: v1
kind: Pod
metadata:
name: no-toleration-pod
spec:
containers:
- name: nginx
image: nginx:latest
ファイルを保存して終了し、Pod を作成します。
kubectl apply -f ~/project/no-toleration-pod.yaml
次に、Pod のステータスを確認しましょう。
kubectl get pods -o wide
Pod が Pending 状態のままであることに気付くかもしれません。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
no-toleration-pod 0/1 Pending 0 12s <none> <none> <none> <none>
toleration-pod 1/1 Running 0 2m 10.244.0.5 minikube <none> <none>
Pod が保留になっている理由を確認しましょう。
kubectl describe pod no-toleration-pod
events セクションには、次のようなものが表示されるはずです。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 45s default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.
これは、Pod がコントロールプレーン taint を許容しないため、スケジュールできなかったことを確認しています。
クリーンアップ
作成した Pod をクリーンアップしましょう。
kubectl delete pod toleration-pod no-toleration-pod
次のように表示されるはずです。
pod "toleration-pod" deleted
pod "no-toleration-pod" deleted
おめでとうございます!これで、taints と tolerations が連携して Kubernetes で Pod スケジューリングを制御する方法を理解できました。
まとめ
このハンズオン実験では、Kubernetes の taints と tolerations を操作する方法を学びました。これらは、クラスタ内の Pod スケジューリングを制御するための重要な機能です。以下を達成しました。
- Minikube を使用して Kubernetes 環境をセットアップしました。
- taints の概念と、Pod スケジューリングへの影響を理解しました。
- Kubernetes ノードの taints を表示するさまざまな方法を調べました。
- kubectl コマンドを使用して、ノードから taints を追加および削除しました。
- tainted ノードとの相互作用を確認するために、tolerations を使用および使用しない Pod を作成しました。
これらのスキルは、Kubernetes クラスタでのワークロード配置とリソース割り当てを管理するために不可欠です。taints と tolerations を適切に使用することで、ハードウェア要件、ワークロード特性、およびリソース制約に基づいて、Pod が適切なノードにスケジュールされるようにすることができます。
Kubernetes の学習を続ける中で、この知識を基盤として、ノードアフィニティやアンチアフィニティなどのより洗練されたスケジューリング戦略を実装し、クラスタリソースをさらに最適化することができます。


