このページではKubernetesのServiceAccountオブジェクトについて説明し、どのようにサービスアカウントが機能するか、使用例、制限、代替手段、追加のガイダンスとなるリソースへのリンクを紹介します。
サービスアカウントは、Kubernetesにおいて、Kubernetesクラスター内で固有のアイデンティティを提供する人間以外のアカウントの一種です。 アプリケーションPod、システムコンポーネント、およびクラスター内外のエンティティは、特定のServiceAccountの認証情報を使用してそのServiceAccountとして識別できます。 このアイデンティティは、APIサーバーへの認証やアイデンティティベースのセキュリティポリシーの実装など、さまざまな状況で役立ちます。
サービスアカウントは、APIサーバー内のServiceAccountオブジェクトとして存在します。 サービスアカウントには次の特性があります:
Namespaced: 各サービスアカウントはKubernetesのnamespaceにバインドされます。
各namespaceは作成時にdefault ServiceAccountを取得します。
Lightweight: サービスアカウントはクラスター内に存在し、Kubernetes APIで定義されています。 特定のタスクを有効にするためにサービスアカウントを素早く作成できます。
Portable: 複雑なコンテナ化されたワークロードの構成バンドルには、システムのコンポーネントのサービスアカウント定義が含まれる場合があります。 サービスアカウントの軽量性と名前空間内のアイデンティティは、構成をポータブルにします。
サービスアカウントは、クラスター内の認証された人間のユーザーであるユーザーアカウントとは異なります。 デフォルトでは、KubernetesのAPIサーバーにユーザーアカウントは存在しません。代わりに、APIサーバーはユーザーのアイデンティティを不透明なデータとして扱います。 複数の方法を使用して、ユーザーアカウントとして認証できます。 一部のKubernetesディストリビューションでは、APIサーバーでユーザーアカウントを表すカスタム拡張APIが追加されることがあります。
| 説明 | ServiceAccount | ユーザーまたはグループ |
|---|---|---|
| ロケーション | Kubernetes API (ServiceAccountオブジェクト) | 外部 |
| アクセス制御 | Kubernetes RBACまたはその他の認可メカニズム | Kubernetes RBACまたはその他のアイデンティティおよびアクセス管理メカニズム |
| 使用目的 | ワークロード、自動化 | 人間 |
クラスターを作成すると、Kubernetesはクラスター内の各Namespaceに対してdefaultという名前のServiceAccountオブジェクトを自動的に作成します。
各Namespaceのdefaultサービスアカウントは、ロールベースのアクセス制御(RBAC)が有効になっている場合、Kubernetesがすべての認証されたプリンシパルに付与するデフォルトのAPI検出権限以外の権限をデフォルトで取得しません。
Namespace内のdefault ServiceAccountオブジェクトを削除すると、コントロールプレーンが新しいServiceAccountオブジェクトを作成します。
NamespaceにPodをデプロイし、Podに手動でServiceAccountを割り当てない場合、KubernetesはそのNamespaceのdefault ServiceAccountをPodに割り当てます。
一般的なガイドラインとして、次のシナリオでサービスアカウントを使用できます:
example NamespaceのPodがkube-node-lease NamespaceのLeaseオブジェクトを読み取り、一覧、監視することを許可します。imagePullSecretを使用してプライベートイメージレジストリに認証する場合。Kubernetesサービスアカウントを使用するには、次の手順を実行します:
kubectlなどのKubernetesクライアントを使用してServiceAccountオブジェクトを作成するか、オブジェクトを定義するマニフェストを使用します。
RBACなどの認可メカニズムを使用してServiceAccountオブジェクトに権限を付与します。
Podの作成時にServiceAccountオブジェクトをPodに割り当てます。
外部サービスからのアイデンティティを使用している場合は、ServiceAccountトークンを取得し、そのサービスから使用します。
詳細な手順については、PodにServiceAccountを割り当てるを参照してください。
各ServiceAccountに必要な最小限の権限を付与するために、Kubernetesビルトインのロールベースのアクセス制御(RBAC)メカニズムを使用できます。 ServiceAccountにアクセスを付与するロールを作成し、そのロールをServiceAccountにバインドします。 RBACを使用すると、ServiceAccountの権限が最小限になるように定義できます。 PodがそのServiceAccountを使用している場合、そのPodは正しく機能するために必要な権限以上の権限を取得しません。
詳細な手順については、ServiceAccount権限を参照してください。
RBACを使用して、クラスターの異なるNamespaceにあるリソースに対して別のNamespaceのServiceAccountがアクションを実行できるようにすることができます。
例えば、dev NamespaceにサービスアカウントとPodがあり、そのPodがmaintenance Namespaceで実行されているJobを見る必要がある場合を考えてみましょう。
Jobオブジェクトをリストする権限を付与するRoleオブジェクトを作成できます。
次に、そのRoleをmaintenance NamespaceのServiceAccountオブジェクトにバインドするRoleBindingオブジェクトを作成します。
そうすることで、dev NamespaceのPodは、そのServiceAccountを使用してmaintenance NamespaceのJobオブジェクトをリストできます。
ServiceAccountをPodに割り当てるには、Podの仕様にあるspec.serviceAccountNameフィールドを設定します。
Kubernetesは、そのServiceAccountの認証情報をPodに自動的に提供します。
v1.22以降では、KubernetesはTokenRequest APIを使用して有効期間が短く自動的にローテーションされるトークンを取得し、そのトークンを投影ボリュームとしてPodにマウントします。
デフォルトではKubernetesは、ServiceAccountがdefault ServiceAccountか指定したカスタムServiceAccountであるかに関わらず、PodにそのServiceAccountの認証情報を提供します。
Kubernetesが指定されたServiceAccountまたはdefault ServiceAccountの認証情報を自動的に注入しないようにするには、Podの使用にあるautomountServiceAccountTokenフィールドをfalseに設定します。
1.22より前のバージョンでは、Kubernetesは有効期間の長い静的なトークンをSecretとしてPodに提供します。
ServiceAccountを標準以外の場所にマウントするための認証情報、またはAPIサーバー以外の対象向けの認証情報が必要な場合は、次のいずれかの方法を使用します:
Kubernetesクラスターの外部で実行されるアプリケーションの場合は、Secretに保存される有効期間の長いServiceAccountトークンの作成を検討するかもしれません。 これにより認証が可能になりますが、Kubernetesプロジェクトではこのアプローチを避けることを推奨しています。 長期間有効なBearerトークンは、一度漏洩するとトークンが悪用される可能性があるため、セキュリティリスクとなります。 代わりとなる手段を検討してください。 例えば、外部アプリケーションは、十分に保護された秘密鍵 と 証明書を使用して認証するか、独自に実装したWebhook認証などのカスタムメカニズムを使用して認証することもできます。
また、TokenRequestを使用して外部アプリケーションのために有効期間の短いトークンを取得することもできます。
Kubernetesは、ServiceAccountに追加できるkubernetes.io/enforce-mountable-secretsというアノテーションを提供しています。
このアノテーションを適用すると、ServiceAccountのシークレットは指定された種類のリソースにのみマウントできるため、クラスターのセキュリティ体制が強化されます。
マニフェストを使用してServiceAccountにアノテーションを追加できます:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubernetes.io/enforce-mountable-secrets: "true"
name: my-serviceaccount
namespace: my-namespace
このアノテーションが"true"に設定されている場合、Kubernetesコントロールプレーンは、このServiceAccountのSecretが特定のマウント制限の対象であることを確認します。
secretsフィールドに表示される必要があります。envFromを使用して参照される各Secretの名前は、PodのServiceAccountのsecretsフィールドに表示される必要があります。imagePullSecretsを使用して参照される各Secretの名前は、PodのServiceAccountのsecretsフィールドに表示される必要があります。これらの制限を理解して適用することで、クラスター管理者はより厳格なセキュリティプロファイルを維持し、適切なリソースのみがシークレットにアクセスできるようにします。
ServiceAccountは、Kubernetes APIサーバーおよび信頼関係が存在する他のシステムに対して、署名されたJSON Web Tokens (JWTs) を使用して認証を行います。
トークンの発行方法(TokenRequestを使用して時間制限付きで発行されるか、Secretを使用して従来のメカニズムで発行されるか)に応じて、ServiceAccountトークンには有効期限、オーディエンス、トークンが有効になる時間などが含まれる場合があります。
ServiceAccountとして機能しているクライアントがKubernetes APIサーバーと通信しようとすると、クライアントはHTTPリクエストにAuthorization: Bearer <token>ヘッダーを含めます。
APIサーバーは、次のようにしてBearerトークンの有効性を確認します:
TokenRequest APIは、ServiceAccountに バインドされたトークン を生成します。 このバインディングは、そのServiceAccountとして機能しているクライアント(Podなど)のライフタイムにリンクされています。 バインドされたPodのサービスアカウントトークンのJWTスキーマとペイロードの例については、トークンボリューム投影を参照してください。
TokenRequest APIを使用して発行されたトークンの場合、APIサーバーは、そのオブジェクトの ユニークID と一致する、ServiceAccountを使用している特定のオブジェクト参照がまだ存在するかどうかも確認します。
PodにSecretとしてマウントされているレガシートークンの場合、APIサーバーはトークンをSecretと照合します。
認証プロセスの詳細については、認証を参照してください。
Kubernetesサービスアカウントの認証情報の検証が必要なサービスがある場合、次の方法を使用できます:
Kubernetesプロジェクトでは、TokenReview APIの使用を推奨しており、この方法ではSecret、ServiceAccount、Pod、NodeなどのAPIオブジェクトにバインドされたトークンが削除されると、そのトークンが無効になります。 例えば、投影されたServiceAccountトークンを含むPodを削除すると、クラスターはただちにそのトークンを無効にし、TokenReviewはただちに失敗します。 代わりにOIDC認証を使用する場合、トークンが有効期限のタイムスタンプに達するまで、クライアントはトークンを有効なものとして扱い続けます。
アプリケーションでは、受け入れるオーディエンスを常に定義し、トークンのオーディエンスがアプリケーションが期待するオーディエンスと一致するかどうかを確認する必要があります。 これにより、トークンのスコープが最小限に抑えられ、アプリケーション内でのみ使用でき、他の場所では使用できないようになります。
SPIFFE CSIドライバープラグインを使用して、SPIFFE SVID をX.509証明書ペアとしてPodに提供します。
このページの項目は、Kubernetesが必要とする機能を提供するサードパーティー製品またはプロジェクトです。Kubernetesプロジェクトの作者は、それらのサードパーティー製品またはプロジェクトに責任を負いません。詳しくは、CNCFウェブサイトのガイドラインをご覧ください。第三者のリンクを追加するような変更を提案する前に、コンテンツガイドを読むべきです。