static Podを作成する

Static Podとは、APIサーバーが監視せず、特定のノード上のkubeletデーモンによって直接管理されるPodです。 コントロールプレーンに管理されるPod(たとえばDeploymentなど)とは異なり、kubeletがそれぞれのstatic Podを監視(および障害時には再起動)します。

Static Podは、常に特定のノード上の1つのKubeletに紐付けられます。

kubeletは、各static Podに対して、自動的にKubernetes APIサーバー上にミラーPodの作成を試みます。 つまり、ノード上で実行中のPodはAPIサーバーから検出されますが、APIサーバー自身から制御されることはないということです。 Pod名は、先頭にハイフンを付けたノードのホスト名がサフィックスとして追加されます。

備考:

複数ノードからなるKubernetesクラスターを実行していて、Podをすべてのノード上で実行するためにstatic Podを使用している場合、おそらくstatic Podの代わりにDaemonSetを使用するべきでしょう。

備考:

static Podのspecは、他のAPIオブジェクト(例: ServiceAccountConfigMapSecret等)を参照することはできません。

備考:

static Podは、エフェメラルコンテナをサポートしません。

始める前に

Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:

バージョンを確認するには次のコマンドを実行してください: kubectl version.

このページの説明では、Podを実行するためにCRI-Oを使用しており、ノード上のOSがFedoraであることを前提としています。 他のディストリビューションやKubernetesのインストール方法によっては、操作が異なる場合があります。

static Podを作成する

static Podは、ファイルシステム上でホストされた設定ファイルまたはウェブ上でホストされた設定ファイルを使用して設定できます。

ファイルシステム上でホストされたstatic Podマニフェスト

マニフェストは、JSONまたはYAML形式の標準のPod定義で、特定のディレクトリに置きます。 kubeletの設定ファイルの中で、staticPodPath: <ディレクトリの場所>というフィールドを使用すると、kubeletがこのディレクトリを定期的にスキャンして、YAML/JSONファイルが作成/削除されるたびに、static Podの作成/削除が行われるようになります。 指定したディレクトリをスキャンする際、kubeletはドットから始まる名前のファイルを無視することに注意してください。

注意:

kubeletは、static Podディレクトリ内のドットで始まらないすべてのファイルを処理します。 ファイルの拡張子によるフィルタリングは行われません。 例えば、cp kube-apiserver.yaml kube-apiserver.yaml.backupを実行してマニフェストのバックアップを作成した場合、kubeletは両方のファイルを読み込み、それぞれからstatic Podを作成しようとします。 2つのファイルが同じ名前のPodを定義している場合、その結果の動作は未定義であり、バックアップの古いspecが現在のマニフェストの代わりに気づかないうちに有効になる可能性があります。 バックアップを作成する場合は、static Podディレクトリの(例えば/etc/kubernetes/backup/)に保存してください。

例として、単純なウェブサーバーをstatic Podとして実行する方法を示します:

  1. static Podを実行したいノードを選択します。 この例では、my-node1です。

    ssh my-node1
    
  2. ディレクトリを選び(ここでは/etc/kubernetes/manifestsとします)、ここにウェブサーバーのPodの定義を置きます。 たとえば、/etc/kubernetes/manifests/static-web.yamlに置きます:

    # このコマンドは、kubeletが実行中のノード上で実行してください
    mkdir -p /etc/kubernetes/manifests/
    cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
    EOF
    
  3. そのノードのkubeletで、kubelet設定ファイルstaticPodPathの値を設定します。 詳細については、設定ファイルによるkubeletパラメーターの設定を参照してください。

    別の非推奨の方法として、コマンドライン引数を使用して、そのノードのkubeletがstatic Podマニフェストをローカルで検索するように設定する方法があります。 非推奨のアプローチを使用するには、--pod-manifest-path=/etc/kubernetes/manifests/引数を指定してkubeletを起動します。

  4. kubeletを再起動します。 Fedoraの場合、次のコマンドを実行します:

    # このコマンドは、kubeletが実行中のノード上で実行してください
    systemctl restart kubelet
    

ウェブ上でホストされたstatic Podマニフェスト

kubeletは、--manifest-url=<URL>引数で指定されたファイルを定期的にダウンロードし、Podの定義が含まれたJSON/YAMLファイルとして解釈します。 kubeletは、ファイルシステム上でホストされたマニフェストでの動作方法と同じように、定期的にマニフェストを再取得します。 static Podのリスト中に変更が見つかると、kubeletがその変更を適用します。

このアプローチを採用する場合、次のように設定します:

  1. YAMLファイルを作成し、kubeletにファイルのURLを渡せるようにするために、ウェブサーバー上に保存します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
    
  2. 選択したノード上のkubeletを--manifest-url=<manifest-url>を使用して実行することで、このウェブ上のマニフェストを使用するように設定します。 Fedoraの場合、/etc/kubernetes/kubeletに次の行が含まれるように編集します:

    KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<マニフェストのURL>"
    
  3. kubeletを再起動します。 Fedoraの場合、次のコマンドを実行します:

    # このコマンドは、kubeletが実行中のノード上で実行してください
    systemctl restart kubelet
    

static Podの動作を観察する

kubeletが起動すると、定義されたすべてのstatic Podが自動的に起動されます。 static Podを設定してkubeletを再起動したため、すでに新しいstatic Podが実行中になっているはずです。

次のコマンドを(ノード上で)実行することで、(static Podを含む)実行中のコンテナを確認できます:

# このコマンドは、kubeletが実行中のノード上で実行してください
crictl ps

出力は次のようになります:

CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
129fd7d382018   docker.io/library/nginx@sha256:...    11 minutes ago    Running    web     0          34533c6729106

備考:

crictlは、イメージのURIとSHA-256チェックサムを出力します。 NAMEは次のような形式になります: docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31

APIサーバー上では、ミラーPodを確認できます:

kubectl get pods
NAME                  READY   STATUS    RESTARTS        AGE
static-web-my-node1   1/1     Running   0               2m

備考:

kubeletにAPIサーバー上のミラーPodを作成する権限があることを確認してください。 もし権限がない場合、APIサーバーによって作成のリクエストが拒否されてしまいます。

static Podに付けたラベルはミラーPodに伝播します。 ミラーPodに付けたラベルは、通常のPodと同じようにセレクターなどから利用できます。

もしkubectlを使用してAPIサーバーからミラーPodを削除しようとしても、kubeletはstatic Podを削除しません

kubectl delete pod static-web-my-node1
pod "static-web-my-node1" deleted

Podはまだ実行中であることがわかります。

kubectl get pods
NAME                  READY   STATUS    RESTARTS   AGE
static-web-my-node1   1/1     Running   0          4s

kubeletが動いているノードに戻って、コンテナを手動で停止してみてください。 しばらくすると、kubeletがそれに気づき、Podを自動的に再起動します。

# このコマンドは、kubeletが実行中のノード上で実行してください
crictl stop 129fd7d382018 # 実際のコンテナIDと置き換えてください
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
89db4553e1eeb   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106

適切なコンテナを特定したら、crictlを使用してそのコンテナのログを取得できます:

# このコマンドは、コンテナが実行中のノード上で実行してください
crictl logs <container_id>
10.240.0.48 - - [16/Nov/2022:12:45:49 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.48 - - [16/Nov/2022:12:45:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.48 - - [16/Nove/2022:12:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"

crictlを使ったデバッグの詳細については、crictlによるKubernetesノードのデバッグを参照してください。

static Podの動的な追加と削除

実行中のkubeletは設定ディレクトリ(この例では/etc/kubernetes/manifests)の変更を定期的にスキャンし、このディレクトリ内にファイルが追加/削除されると、Podの追加/削除を行います。

# これは、ファイルシステムでホストされているstatic Podの設定を使用していることを前提としています
# このコマンドは、コンテナが実行中のノード上で実行してください
#
mv /etc/kubernetes/manifests/static-web.yaml /tmp
sleep 20
crictl ps
# nginxコンテナが実行されていないことを確認できます
mv /tmp/static-web.yaml  /etc/kubernetes/manifests/
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
f427638871c35   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106

次の項目