14.2. ボリュームローテーションを使用したバインドされたサービスアカウントトークンの設定

ボリュームの展開を使用してバインドされたサービスアカウントのトークンを要求するように Pod を設定できます。

前提条件

  • cluster-admin ロールを持つユーザーとしてクラスターにアクセスできる。
  • サービスアカウントを作成している。この手順では、サービスアカウントの名前が build-robot であることを前提としています。

手順

  1. オプション: サービスアカウントの発行者を設定します。

    通常、このステップはバインドされたトークンがクラスター内でのみ使用される場合には必要ありません。

    警告

    serviceAccountIssuer フィールドを更新し、使用中のバインドされたトークンがある場合、直前の発行側の値を持つすべてのバインドされたトークンが無効になります。バインドされたトークンのホルダーが発行側の変更に対して明示的なサポートがない場合、ホルダーは Pod が再起動するまでバインドされたトークンを新たに要求しません。

    クラスター内のすべての Pod を手動で再起動するか、ノードのローリング再起動を実行することにより、すべての所有者に新しいバインドされたトークンを要求するように強制できます。いずれかのアクションを実行する前に、Kubernetes API サーバー Pod の新しいリビジョンがサービスアカウント発行者の変更とともにロールアウトされるのを待ちます。

    1. cluster Authentication オブジェクトを編集します。

      $ oc edit authentications cluster
    2. spec.serviceAccountIssuer フィールドを、必要なサービスアカウント発行者の値に設定します。

      spec:
        serviceAccountIssuer: https://test.default.svc 1
      1
      この値は URL である必要があり、バインドされたトークンの受信側はトークンの署名の検証に必要なパブリックキーを取得できます。デフォルトは https://kubernetes.default.svc です。
    3. 変更を適用するためにファイルを保存します。
    4. Kubernetes API サーバー Pod の新しいリビジョンがロールアウトされるまで待ちます。すべてのノードが新規リビジョンに更新されるまで数分かかる場合があります。以下のコマンドを実行します。

      $ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'

      Kubernetes API サーバーの NodeInstallerProgressing 状況条件を確認し、すべてのノードが最新のリビジョンであることを確認します。更新が正常に実行されると、この出力には AllNodesAtLatestRevision が表示されます。

      AllNodesAtLatestRevision
      3 nodes are at revision 12 1
      1
      この例では、最新のリビジョン番号は 12 です。

      出力に以下のようなメッセージが表示される場合は、更新が進行中です。数分待機した後に再試行します。

      • 3 nodes are at revision 11; 0 nodes have achieved new revision 12
      • 2 nodes are at revision 11; 1 nodes are at revision 12
    5. オプション: ノードのローリング再起動を実行するか、クラスター内のすべての Pod を手動で再起動することにより、所有者に新しいバインドされたトークンを要求するように強制します。

      • ローリングノード再起動を実行します。

        警告

        クラスターでカスタムワークロードを実行している場合は、ノードのローリング再起動を実行することはお勧めしません。これは、サービスの中断を引き起こす可能性があるためです。代わりに、クラスター内のすべての Pod を手動で再起動します。

        ノードを順番に再起動します。次のノードを再起動する前に、ノードが完全に使用可能になるまで待ちます。ノードを再びスケジュール可能としてドレイン、再起動、およびマークする方法については、ノードの正常な再起動 を参照してください。

      • クラスター内のすべての Pod を手動で再起動します。

        警告

        このコマンドは、すべての namespace で実行されているすべての Pod を削除するため、このコマンドを実行するとサービスが中断します。これらの Pod は削除後に自動的に再起動します。

        以下のコマンドを実行します。

        $ for I in $(oc get ns -o jsonpath='{range .items[*]} {.metadata.name}{"\n"} {end}'); \
              do oc delete pods --all -n $I; \
              sleep 1; \
              done
  2. ボリュームの展開を使用してバインドされたサービスアカウントのトークンを使用するように Pod を設定します。

    1. 以下の内容を含む pod-projected-svc-token.yaml ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: nginx
      spec:
        containers:
        - image: nginx
          name: nginx
          volumeMounts:
          - mountPath: /var/run/secrets/tokens
            name: vault-token
        serviceAccountName: build-robot 1
        volumes:
        - name: vault-token
          projected:
            sources:
            - serviceAccountToken:
                path: vault-token 2
                expirationSeconds: 7200 3
                audience: vault 4
      1
      既存のサービスアカウントへの参照。
      2
      トークンの展開先となるファイルのマウントポイントに対する相対パス。
      3
      オプションで、サービスアカウントトークンの有効期限を秒単位で設定します。デフォルトは 3600 秒 (1 時間) で、600 秒 (10 分) 以上にする必要があります。トークンの有効期間がその 80% を過ぎている場合や、トークンの生成から 24 時間を経過している場合、kubelet はトークンのローテーションの試行を開始します。
      4
      オプションで、トークンの意図された対象を設定します。トークンの受信側は、受信側のアイデンティティーがトークンの適切対象の要求と一致することを確認し、一致しない場合はトークンを拒否する必要があります。対象はデフォルトで API サーバーの識別子に設定されます。
    2. Pod を作成します。

      $ oc create -f pod-projected-svc-token.yaml

      kubelet は Pod に代わってトークンを要求し、保存し、トークンを設定可能なファイルパスで Pod に対して利用可能にし、有効期限に達するとトークンを更新します。

  3. バインドされたトークンを使用するアプリケーションは、ローテーション時にトークンのリロードを処理する必要があります。

    トークンの有効期間がその 80% を過ぎている場合や、トークンの生成から 24 時間を経過している場合、kubelet はトークンをローテーションします。