Kubernetes ノードに適用された Taint の確認方法

KubernetesBeginner
オンラインで実践に進む

はじめに

コンテナオーケストレーションプラットフォームとして広く利用されている 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 つのコンポーネントで構成されています。

  1. Key(キー): taint を識別する文字列(例:gpu, disk, network
  2. Value(値): キーに割り当てられたオプションの文字列(例:true, high-performance
  3. 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 は、いくつかのシナリオで特に役立ちます。

  1. 特殊なハードウェア: 特殊なハードウェア(GPU など)を持つノードに taint を付与して、そのハードウェアを必要とするワークロードのみがそこにスケジュールされるようにします。
  2. ノードメンテナンス: メンテナンスを実行する前に taint を追加して、新しい Pod がスケジュールされないようにします。
  3. セキュリティ分離: セキュリティ上の理由から、特定のワークロードを他のワークロードから分離します。
  4. リソース最適化: 特定のワークロードタイプにノードを割り当てて、最適なリソース利用を実現します。

taints の表示、追加、および削除の方法を理解することにより、Kubernetes クラスタでの Pod スケジューリングを管理するための基本的な知識が得られました。

Tolerations の操作

taints がどのように機能するかを理解したので、tainted ノードで Pod をスケジュールできるようにするメカニズムである tolerations を見てみましょう。

Tolerations の理解

Tolerations は Pod 仕様で指定され、一致する taints を持つノードで Pod をスケジュールできるようにします。Toleration は以下で構成されます。

  • key: taint key と一致します
  • operator: Equal(キーと値が一致)または Exists(キーのみが一致)のいずれか
  • value: 一致させる値(Equal operator を使用する場合)
  • 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+OEnterCtrl+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 スケジューリングを制御するための重要な機能です。以下を達成しました。

  1. Minikube を使用して Kubernetes 環境をセットアップしました。
  2. taints の概念と、Pod スケジューリングへの影響を理解しました。
  3. Kubernetes ノードの taints を表示するさまざまな方法を調べました。
  4. kubectl コマンドを使用して、ノードから taints を追加および削除しました。
  5. tainted ノードとの相互作用を確認するために、tolerations を使用および使用しない Pod を作成しました。

これらのスキルは、Kubernetes クラスタでのワークロード配置とリソース割り当てを管理するために不可欠です。taints と tolerations を適切に使用することで、ハードウェア要件、ワークロード特性、およびリソース制約に基づいて、Pod が適切なノードにスケジュールされるようにすることができます。

Kubernetes の学習を続ける中で、この知識を基盤として、ノードアフィニティやアンチアフィニティなどのより洗練されたスケジューリング戦略を実装し、クラスタリソースをさらに最適化することができます。