ServiceAccountトークンは、ポッドで実行されているアプリケーションとKubernetes API間の安全な通信を可能にする認証資格情報として機能します。 ポッドにServiceAccountトークンをSecretsとして自動的にマウントする従来の方法に関連するセキュリティリスクに対処するには、Container Service for Kubernetes (ACK) が提供するサービスアカウントトークンボリュームプロジェクション機能を使用します。 この機能を使用すると、ServiceAccountトークンまたは関連する証明書をボリュームプロジェクションとしてコンテナにマウントでき、秘密の公開のリスクを軽減できます。
機能紹介
サービスアカウントは、ポッドとクラスターのAPIサーバー間の通信のIDを提供します。 従来の方法でサービスアカウントを使用すると、次の課題に直面する場合があります。
サービスアカウントのJSON Webトークン (JWT) は、
オーディエンス
IDにバインドされていません。 サービスアカウントのユーザーは、別のユーザーになりすまして、なりすまし攻撃を開始できます。従来、各サービスアカウントはシークレットに格納され、対応するアプリケーションノードにファイルとして配信されていました。 システムコンポーネントによって使用されるサービスアカウントには、不要な権限が与えられます。 攻撃者はこれらのサービスアカウントを取得して特権エスカレーション攻撃を開始することができます。その結果、Kubernetesコントロールプレーンの攻撃対象範囲が広くなります。
JWTはタイムバウンドではありません。 前述の攻撃で侵害されたJWTは、サービスアカウントが存在する限り有効なままです。 この問題は、サービスアカウントの秘密鍵をローテーションすることによってのみ軽減できます。 ただし、client-goは自動キーローテーションをサポートしていません。 手動キー回転を実行する必要がありますが、これは複雑です。
サービスアカウントごとにシークレットを作成する必要があります。 これにより、大規模なワークロード展開における弾力性と容量が低下する可能性があります。
ServiceAccountトークンボリューム予測機能は、ServiceAccountsのセキュリティを強化し、より安全で柔軟な方法でServiceAccount関連の認証情報をポッドに提供します。 この機能により、ポッドはServiceAccountsをボリュームプロジェクションの形式でコンテナーにマウントでき、Secretsへの依存を回避できます。
前提条件
Kubernetes 1.20を実行するACKマネージドクラスター、ACK専用クラスター、またはACKサーバーレスクラスターが作成されます。 詳細については、「ACKマネージドクラスターの作成」、「ACK専用クラスターの作成」、および「ACKサーバーレスクラスターの作成」をご参照ください。
ServiceAccountトークンボリューム予測機能は、クラスター作成プロセス中に有効になります。
デフォルトでは、ServiceAccountトークンボリュームプロジェクション機能は、Kubernetes 1.22以降を実行するクラスターで有効になっています。 クラスターをアップグレードするには、「手動でACKクラスターをアップグレード」をご参照ください。
APIサーバーとシステムコンポーネントのコントローラーマネージャーは、ServiceAccountトークンのボリューム予測をバインドする機能ゲートを自動的に有効にし、APIサーバーの起動パラメーターに次の設定を追加します。
パラメーター
説明
デフォルト値
コンソール設定
service-account-issuer
ServiceAccountトークンの発行者。トークンペイロードの
iss
フィールドに対応します。https:// kubernetes.de fault.svc
サポートされています。
api-audiences
APIサーバーサービスのリクエストトークンを検証するために使用されるAPIの識別子。
https:// kubernetes.de fault.svc
サポートされています。 複数
オーディエンス
コンマで区切って設定できます (,
) 。service-account-signing-key-file
トークンに署名する秘密キーのファイルパス。
/etc/kubernetes/pki/sa.key
サポートされていません。 デフォルト値: /etc/kubernetes/pki/sa.key。
手順1: ServiceAccountオブジェクトの作成
デフォルトでは、各名前空間にdefault
ServiceAccountが付属しており、kubectl get serviceaccounts
コマンドを実行して表示できます。 ポッドで実行されているプロセスに追加のIDを割り当てるには、次のコードを使用して新しいServiceAccountを作成します。
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
EOF
ServiceAccountの作成後、kubectl get serviceaccounts/build-robot -o yaml
コマンドを実行して、ServiceAccountの完全な情報を表示できます。
手順2: ServiceAccountトークンを使用するポッドアプリケーションのデプロイボリュームプロジェクション
ServiceAccountをボリュームとしてポッドにプロジェクトし、ポッド内のコンテナーがトークンを使用してクラスターのAPIサーバーにアクセスし、ServiceAccountで認証できるようにします。 たとえば、トークンのaudience
、有効期限 (expirationSeconds
) 、およびその他のプロパティを指定し、ポッドで実行されるアプリケーションにこれらを投影できます。
次のサンプルコードでnginx.yamlという名前のファイルを作成します。 この構成では、ポッドがServiceAccountを使用し、
audience
がvault
で、有効期限が2時間であることを指定します。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 volumes: - name: vault-token projected: sources: - serviceAccountToken: path: vault-token expirationSeconds: 7200 audience: vault
次のコマンドを実行して、ボリュームプロジェクションを使用するポッドで実行中のアプリケーションをデプロイします。
kubectl apply -f nginx.yaml
ポッドにマウントされているトークンの有効期限を確認します。
次のコマンドを実行して、ポッドが期待どおりに実行されることを確認します。
kubectl get pod nginx
期待される出力:
NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 3m15s
ポッドのコンテナにマウントされたトークンをダウンロードします。
kubectl exec -t nginx -- cat /var/run/secrets/tokens/vault-token > vault-token
次のコマンドを実行して、トークンの有効期限を取得します。
cat vault-token |awk -F '.' '{print $2}' |base64 -d 2>/dev/null |jq '.exp' | xargs -I {} date -d @{}
サンプル出力:
Mon Aug 26 15:45:59 CST 2024
定期的に、できれば5分ごとにターゲットトークンをリロードすることで、ポッドが最新の回転トークンをリアルタイムで取得できることを確認します。 公式Kubernetesは、client-goバージョン10.0.0以降での自動トークン取得をサポートしています。
コンテナ内のServiceAccountトークンのファイル権限は、644から600に更新されます。 バインドされたServiceAccountトークンボリューム予測を使用すると、ファイル権限は600に設定され、
fsGroup
機能が有効になっている場合は640に設定されます。