第12章 サービスアカウント

12.1. 概要

ユーザーが OpenShift Container Platform CLI または web コンソールを使用する場合、API トークンは OpenShift API に対して認証を行いますが、一般ユーザーの認証情報が利用できない場合、通常各種コンポーネントが API 呼び出しを別個に実行します。以下はその例になります。

  • レプリケーションコントローラーが Pod を作成するか、または削除するために API 呼び出しを実行する。
  • コンテナー内のアプリケーションが検出の目的で API 呼び出しを実行する。
  • 外部アプリケーションがモニタリングおよび統合目的で API 呼び出しを実行する。

サービスアカウントは、一般ユーザーの認証情報を共有せずに API アクセスをより柔軟に制御する方法を提供します。

12.2. ユーザー名およびグループ

すべてのサービスアカウントには、一般ユーザーのようにロールを付与できるユーザー名が関連付けられています。ユーザー名はそのプロジェクトおよび名前から派生します。

system:serviceaccount:<project>:<name>

たとえば、view (表示) ロールを top-secret プロジェクトの robot サービスアカウントに追加するには、以下を実行します。

$ oc policy add-role-to-user view system:serviceaccount:top-secret:robot
重要

プロジェクトで特定のサービスアカウントにアクセスを付与する必要がある場合は、-z フラグを使用できます。サービスアカウントが属するプロジェクトから -z フラグを使用し、<serviceaccount_name> を指定します。これによりタイプミスの発生する可能性が減り、アクセスを指定したサービスアカウントのみに付与できるため、この方法を使用することを強くお勧めします。以下は例になります。

 $ oc policy add-role-to-user <role_name> -z <serviceaccount_name>

プロジェクトから実行しない場合は、以下の例に示すように -n オプションを使用してこれが適用されるプロジェクトの namespace を指定します。

すべてのサービスアカウントは以下の 2 つのグループのメンバーでもあります。

system:serviceaccounts
システムのすべてのサービスアカウントが含まれます。
system:serviceaccounts:<project>
指定されたプロジェクトのすべてのサービスアカウントが含まれます。

たとえば、すべてのプロジェクトのすべてのサービスアカウントが top-secret プロジェクトのリソースを表示できるようにするには、以下を実行します。

$ oc policy add-role-to-group view system:serviceaccounts -n top-secret

managers プロジェクトのすべてのサービスアカウントが top-secret プロジェクトのリソースを編集できるようにするには、以下を実行します。

$ oc policy add-role-to-group edit system:serviceaccounts:managers -n top-secret

12.3. デフォルトのサービスアカウントおよびロール

3 つのサービスアカウントがすべてのプロジェクトで自動的に作成されます。

サービスアカウント使用法

builder

ビルド Pod で使用されます。これには system:image-builder ロールが付与されます。このロールは、内部 Docker レジストリーを使用してイメージをプロジェクトのイメージストリームにプッシュすることを可能にします。

deployer

デプロイメント Pod で使用され、system:deployer ロールが付与されます。このロールは、プロジェクトでレプリケーションコントローラーや Pod を表示したり、変更したりすることを可能にします。

default

別のサービスアカウントが指定されていない限り、その他すべての Pod を実行するために使用されます。

プロジェクトのすべてのサービスアカウントには system:image-puller ロールが付与されます。このロールは、内部コンテナーイメージレジストリーを使用してイメージをイメージストリームからプルすることを可能にします。

12.4. サービスアカウントの管理

サービスアカウントは、各プロジェクトに存在する API オブジェクトです。サービスアカウントを管理するには、sa または serviceaccount オブジェクトタイプと共に oc コマンドを使用するか、または web コンソールを使用することができます。

現在のプロジェクトの既存のサービスアカウントの一覧を取得するには、以下を実行します。

$ oc get sa
NAME       SECRETS   AGE
builder    2         2d
default    2         2d
deployer   2         2d

新規のサービスアカウントを作成するには、以下を実行します。

$ oc create sa robot
serviceaccount "robot" created

サービスアカウントの作成後すぐに、以下の 2 つのシークレットが自動的に追加されます。

  • API トークン
  • OpenShift Container レジストリーの認証情報

これらはサービスアカウントを記述すると表示できます。

$ oc describe sa robot
Name:		robot
Namespace:	project1
Labels:		<none>
Annotations:	<none>

Image pull secrets:	robot-dockercfg-qzbhb

Mountable secrets: 	robot-token-f4khf
                   	robot-dockercfg-qzbhb

Tokens:            	robot-token-f4khf
                   	robot-token-z8h44

システムはサービスアカウントに API トークンとレジストリーの認証情報が常にあることを確認します。

生成される API トークンとレジストリーの認証情報は期限切れになることはありませんが、シークレットを削除することで取り消すことができます。シークレットが削除されると、新規のシークレットが自動生成され、これに置き換わります。

12.5. 許可されたシークレットの管理

API 認証情報を提供するほかに、Pod のサービスアカウントは Pod が使用できるシークレットを決定します。

Pod は以下の 2 つの方法でシークレットを使用します。

  • イメージプルシークレットの使用: Pod のコンテナーのイメージをプルするために使用される認証情報を提供します。
  • マウント可能なシークレットの使用。シークレットの内容をファイルとしてコンテナーに挿入します。

サービスアカウントの Pod がシークレットをイメージプルシークレットとして使用できるようにするには、以下を実行します。

$ oc secrets link --for=pull <serviceaccount-name> <secret-name>

サービスアカウントの Pod がシークレットをマウントできるようにするには、以下を実行します。

$ oc secrets link --for=mount <serviceaccount-name> <secret-name>
注記

シークレットをそれらを参照するサービスアカウントのみに制限することはデフォルトで無効にされています。これは、serviceAccountConfig.limitSecretReferences がマスター設定ファイルで false (デフォルト設定) に設定されている場合はシークレットを --for=mount オプションを使ってサービスアカウントの Pod にマウントする必要がないことを意味します。ただし serviceAccountConfig.limitSecretReferences の値にかかわらず、--for=pull オプションを使用してイメージプルシークレットの使用を有効にする必要はあります。

以下の例では、シークレットを作成し、これをサービスアカウントに追加しています。

$ oc create secret generic secret-plans \
    --from-file=plan1.txt \
    --from-file=plan2.txt
secret/secret-plans

$ oc create secret docker-registry my-pull-secret \
    --docker-username=mastermind \
    --docker-password=12345 \
    --docker-email=mastermind@example.com
secret/my-pull-secret

$ oc secrets link robot secret-plans --for=mount

$ oc secrets link robot my-pull-secret --for=pull

$ oc describe serviceaccount robot
Name:               robot
Labels:             <none>
Image pull secrets:	robot-dockercfg-624cx
                   	my-pull-secret

Mountable secrets: 	robot-token-uzkbh
                   	robot-dockercfg-624cx
                   	secret-plans

Tokens:            	robot-token-8bhpp
                   	robot-token-uzkbh

12.6. コンテナー内でのサービスアカウントの認証情報の使用

Pod が作成されると、Pod はサービスアカウントを指定し (またはデフォルトのサービスアカウントを使用し)、サービスアカウントの API 認証情報と参照されるシークレットを使用することができます。

Pod のサービスアカウントの API トークンが含まれるファイルは /var/run/secrets/kubernetes.io/serviceaccount/token に自動的にマウントされます。

このトークンは Pod のサービスアカウントとして API 呼び出しを実行するために使用できます。以下の例では、トークンによって識別されるユーザーについての情報を取得するために users/~ API を呼び出しています。

$ TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"

$ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
    "https://openshift.default.svc.cluster.local/oapi/v1/users/~" \
    -H "Authorization: Bearer $TOKEN"

kind: "User"
apiVersion: "user.openshift.io/v1"
metadata:
  name: "system:serviceaccount:top-secret:robot"
  selflink: "/oapi/v1/users/system:serviceaccount:top-secret:robot"
  creationTimestamp: null
identities: null
groups:
  - "system:serviceaccount"
  - "system:serviceaccount:top-secret"

12.7. サービスアカウントの認証情報の外部での使用

同じトークンを、API に対して認証する必要のある外部アプリケーションに配布することができます。

以下の構文を使用してサービスアカウントの API トークンを表示します。

$ oc describe secret <secret-name>

例:

$ oc describe secret robot-token-uzkbh -n top-secret
Name:		robot-token-uzkbh
Labels:		<none>
Annotations:	kubernetes.io/service-account.name=robot,kubernetes.io/service-account.uid=49f19e2e-16c6-11e5-afdc-3c970e4b7ffe

Type:	kubernetes.io/service-account-token

Data

token:	eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

$ oc login --token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Logged into "https://server:8443" as "system:serviceaccount:top-secret:robot" using the token provided.

You don't have any projects. You can try to create a new project, by running

    $ oc new-project <projectname>

$ oc whoami
system:serviceaccount:top-secret:robot