2.6. Pod への機密性の高いデータの提供
アプリケーションによっては、パスワードやユーザー名など開発者に使用させない秘密情報が必要になります。
管理者として シークレット
オブジェクトを使用すると、この情報を平文で公開することなく提供することが可能です。
2.6.1. シークレットについて
Secret
オブジェクトタイプはパスワード、OpenShift Container Platform クライアント設定ファイル、プライベートソースリポジトリーの認証情報などの機密情報を保持するメカニズムを提供します。シークレットは機密内容を Pod から切り離します。シークレットはボリュームプラグインを使用してコンテナーにマウントすることも、システムが Pod の代わりにシークレットを使用して各種アクションを実行することもできます。
キーのプロパティーには以下が含まれます。
- シークレットデータはその定義とは別に参照できます。
- シークレットデータのボリュームは一時ファイルストレージ機能 (tmpfs) でサポートされ、ノードで保存されることはありません。
- シークレットデータは namespace 内で共有できます。
YAML Secret
オブジェクト定義
apiVersion: v1 kind: Secret metadata: name: test-secret namespace: my-namespace type: Opaque 1 data: 2 username: dmFsdWUtMQ0K 3 password: dmFsdWUtMg0KDQo= stringData: 4 hostname: myapp.mydomain.com 5
シークレットに依存する Pod を作成する前に、シークレットを作成する必要があります。
シークレットの作成時に以下を実行します。
- シークレットデータでシークレットオブジェクトを作成します。
- Pod のサービスアカウントをシークレットの参照を許可するように更新します。
-
シークレットを環境変数またはファイルとして使用する Pod を作成します (
secret
ボリュームを使用)。
2.6.1.1. シークレットの種類
type
フィールドの値で、シークレットのキー名と値の構造を指定します。このタイプを使用して、シークレットオブジェクトにユーザー名とキーの配置を実行できます。検証の必要がない場合には、デフォルト設定の opaque
タイプを使用してください。
以下のタイプから 1 つ指定して、サーバー側で最小限の検証をトリガーし、シークレットデータに固有のキー名が存在することを確認します。
-
kubernetes.io/service-account-token
。サービスアカウントトークンを使用します。 -
kubernetes.io/basic-auth
。Basic 認証で使用します。 -
kubernetes.io/ssh-auth
.SSH キー認証で使用します。 -
kubernetes.io/tls
。TLS 認証局で使用します。
検証が必要ない場合には type: Opaque
と指定します。これは、シークレットがキー名または値の規則に準拠しないという意味です。opaque シークレットでは、任意の値を含む、体系化されていない key:value
ペアも利用できます。
example.com/my-secret-type
などの他の任意のタイプを指定できます。これらのタイプはサーバー側では実行されませんが、シークレットの作成者がその種類のキー/値の要件に従う意図があることを示します。
シークレットのさまざまなタイプの例については、シークレットの使用 に関連するコードのサンプルを参照してください。
2.6.1.2. シークレットデータキー
シークレットキーは DNS サブドメインになければなりません。
2.6.2. シークレットの作成方法
管理者は、開発者がシークレットに依存する Pod を作成できるよう事前にシークレットを作成しておく必要があります。
シークレットの作成時に以下を実行します。
秘密にしておきたいデータを含む秘密オブジェクトを作成します。各シークレットタイプに必要な特定のデータは、以下のセクションで非表示になります。
不透明なシークレットを作成する YAML オブジェクトの例
apiVersion: v1 kind: Secret metadata: name: test-secret type: Opaque 1 data: 2 username: dmFsdWUtMQ0K password: dmFsdWUtMQ0KDQo= stringData: 3 hostname: myapp.mydomain.com secret.properties: | property1=valueA property2=valueB
data
フィールドまたはstringdata
フィールドの両方ではなく、いずれかを使用してください。Pod のサービスアカウントをシークレットを参照するように更新します。
シークレットを使用するサービスアカウントの YAML
apiVersion: v1 kind: ServiceAccount ... secrets: - name: test-secret
シークレットを環境変数またはファイルとして使用する Pod を作成します (
secret
ボリュームを使用)。シークレットデータと共にボリュームのファイルが設定された Pod の YAML
apiVersion: v1 kind: Pod metadata: name: secret-example-pod spec: containers: - name: secret-test-container image: busybox command: [ "/bin/sh", "-c", "cat /etc/secret-volume/*" ] volumeMounts: 1 - name: secret-volume mountPath: /etc/secret-volume 2 readOnly: true 3 volumes: - name: secret-volume secret: secretName: test-secret 4 restartPolicy: Never
シークレットデータと共に環境変数が設定された Pod の YAML
apiVersion: v1 kind: Pod metadata: name: secret-example-pod spec: containers: - name: secret-test-container image: busybox command: [ "/bin/sh", "-c", "export" ] env: - name: TEST_SECRET_USERNAME_ENV_VAR valueFrom: secretKeyRef: 1 name: test-secret key: username restartPolicy: Never
- 1
- シークレットキーを使用する環境変数を指定します。
シークレットデータと環境変数が設定されたビルド設定の YAML
apiVersion: build.openshift.io/v1 kind: BuildConfig metadata: name: secret-example-bc spec: strategy: sourceStrategy: env: - name: TEST_SECRET_USERNAME_ENV_VAR valueFrom: secretKeyRef: 1 name: test-secret key: username
- 1
- シークレットキーを使用する環境変数を指定します。
2.6.2.1. シークレットの作成に関する制限
シークレットを使用するには、Pod がシークレットを参照できる必要があります。シークレットは、以下の 3 つの方法で Pod で使用されます。
- コンテナーの環境変数を事前に設定するために使用される。
- 1 つ以上のコンテナーにマウントされるボリュームのファイルとして使用される。
- Pod のイメージをプルする際に kubelet によって使用される。
ボリュームタイプのシークレットは、ボリュームメカニズムを使用してデータをファイルとしてコンテナーに書き込みます。イメージプルシークレットは、シークレットを namespace のすべての Pod に自動的に挿入するためにサービスアカウントを使用します。
テンプレートにシークレット定義が含まれる場合、テンプレートで指定のシークレットを使用できるようにするには、シークレットのボリュームソースを検証し、指定されるオブジェクト参照が Secret
オブジェクトを実際に参照していることを確認できる必要があります。そのため、シークレットはこれに依存する Pod の作成前に作成されている必要があります。最も効果的な方法として、サービスアカウントを使用してシークレットを自動的に挿入することができます。
シークレット API オブジェクトは namespace にあります。それらは同じ namespace の Pod によってのみ参照されます。
個々のシークレットは 1MB のサイズに制限されます。これにより、apiserver および kubelet メモリーを使い切るような大規模なシークレットの作成を防ぐことができます。ただし、小規模なシークレットであってもそれらを数多く作成するとメモリーの消費につながります。
2.6.2.2. 不透明なシークレットの作成
管理者は、不透明なシークレットを作成できます。これにより、任意の値を含むことができる非構造化 key:value
のペアを格納できます。
手順
コントロールプレーンノードの YAML ファイルに
Secret
オブジェクトを作成します。以下に例を示します。
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque 1 data: username: dXNlci1uYW1l password: cGFzc3dvcmQ=
- 1
- 不透明なシークレットを指定します。
以下のコマンドを使用して
Secret
オブジェクトを作成します。$ oc create -f <filename>.yaml
Pod でシークレットを使用するには、以下を実行します。
- シークレットの作成方法についてセクションに示すように、Pod のサービスアカウントを更新してシークレットを参照します。
-
シークレットの作成方法についてに示すように、シークレットを環境変数またはファイル (
secret
ボリュームを使用) として使用する Pod を作成します。
関連情報
- Pod でシークレットを使用する方法は、シークレットの作成方法について を参照してください。
2.6.2.3. サービスアカウントトークンシークレットの作成
管理者は、サービスアカウントトークンシークレットを作成できます。これにより、API に対して認証する必要のあるアプリケーションにサービスアカウントトークンを配布できます。
サービスアカウントトークンシークレットを使用する代わりに、TokenRequest API を使用してバインドされたサービスアカウントトークンを取得することをお勧めします。TokenRequest API から取得したトークンは、有効期間が制限されており、他の API クライアントが読み取れないため、シークレットに保存されているトークンよりも安全です。
TokenRequest API を使用できず、読み取り可能な API オブジェクトで有効期限が切れていないトークンのセキュリティーエクスポージャーが許容できる場合にのみ、サービスアカウントトークンシークレットを作成する必要があります。
バインドされたサービスアカウントトークンの作成に関する詳細は、以下の追加リソースセクションを参照してください。
手順
コントロールプレーンノードの YAML ファイルに
Secret
オブジェクトを作成します。secret
オブジェクトの例:apiVersion: v1 kind: Secret metadata: name: secret-sa-sample annotations: kubernetes.io/service-account.name: "sa-name" 1 type: kubernetes.io/service-account-token 2
以下のコマンドを使用して
Secret
オブジェクトを作成します。$ oc create -f <filename>.yaml
Pod でシークレットを使用するには、以下を実行します。
- シークレットの作成方法についてセクションに示すように、Pod のサービスアカウントを更新してシークレットを参照します。
-
シークレットの作成方法についてに示すように、シークレットを環境変数またはファイル (
secret
ボリュームを使用) として使用する Pod を作成します。
関連情報
- Pod でシークレットを使用する方法は、シークレットの作成方法について を参照してください。
- バインドされたサービスアカウントトークンの要求については、バインドされたサービスアカウントトークンの使用 を参照してください。
- サービスアカウントの作成については、サービスアカウントの理解と作成 を参照してください。
2.6.2.4. Basic 認証シークレットの作成
管理者は Basic 認証シークレットを作成できます。これにより、Basic 認証に必要な認証情報を保存できます。このシークレットタイプを使用する場合は、Secret
オブジェクトの data
パラメーターには、base64 形式でエンコードされた以下のキーが含まれている必要があります。
-
username
: 認証用のユーザー名 -
password
: 認証のパスワードまたはトークン
stringData
パラメーターを使用して、クリアテキストコンテンツを使用できます。
手順
コントロールプレーンノードの YAML ファイルに
Secret
オブジェクトを作成します。secret
オブジェクトの例apiVersion: v1 kind: Secret metadata: name: secret-basic-auth type: kubernetes.io/basic-auth 1 data: stringData: 2 username: admin password: t0p-Secret
以下のコマンドを使用して
Secret
オブジェクトを作成します。$ oc create -f <filename>.yaml
Pod でシークレットを使用するには、以下を実行します。
- シークレットの作成方法についてセクションに示すように、Pod のサービスアカウントを更新してシークレットを参照します。
-
シークレットの作成方法についてに示すように、シークレットを環境変数またはファイル (
secret
ボリュームを使用) として使用する Pod を作成します。
関連情報
- Pod でシークレットを使用する方法は、シークレットの作成方法について を参照してください。
2.6.2.5. SSH 認証シークレットの作成
管理者は、SSH 認証シークレットを作成できます。これにより、SSH 認証に使用されるデータを保存できます。このシークレットタイプを使用する場合、Secret
オブジェクトの data
パラメーターには、使用する SSH 認証情報が含まれている必要があります。
手順
コントロールプレーンノードの YAML ファイルに
Secret
オブジェクトを作成します。secret
オブジェクトの例:apiVersion: v1 kind: Secret metadata: name: secret-ssh-auth type: kubernetes.io/ssh-auth 1 data: ssh-privatekey: | 2 MIIEpQIBAAKCAQEAulqb/Y ...
以下のコマンドを使用して
Secret
オブジェクトを作成します。$ oc create -f <filename>.yaml
Pod でシークレットを使用するには、以下を実行します。
- シークレットの作成方法についてセクションに示すように、Pod のサービスアカウントを更新してシークレットを参照します。
-
シークレットの作成方法についてに示すように、シークレットを環境変数またはファイル (
secret
ボリュームを使用) として使用する Pod を作成します。
関連情報
2.6.2.6. Docker 設定シークレットの作成
管理者は Docker 設定シークレットを作成できます。これにより、コンテナーイメージレジストリーにアクセスするための認証情報を保存できます。
-
kubernetes.io/dockercfg
.このシークレットタイプを使用してローカルの Docker 設定ファイルを保存します。secret
オブジェクトのdata
パラメーターには、base64 形式でエンコードされた.dockercfg
ファイルの内容が含まれている必要があります。 -
kubernetes.io/dockerconfigjson
.このシークレットタイプを使用して、ローカルの Docker 設定 JSON ファイルを保存します。secret
オブジェクトのdata
パラメーターには、base64 形式でエンコードされた.docker/config.json
ファイルの内容が含まれている必要があります。
手順
コントロールプレーンノードの YAML ファイルに
Secret
オブジェクトを作成します。Docker 設定の
secret
オブジェクトの例apiVersion: v1 kind: Secret metadata: name: secret-docker-cfg namespace: my-project type: kubernetes.io/dockerconfig 1 data: .dockerconfig:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== 2
Docker 設定の JSON
secret
オブジェクトの例apiVersion: v1 kind: Secret metadata: name: secret-docker-json namespace: my-project type: kubernetes.io/dockerconfig 1 data: .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== 2
以下のコマンドを使用して
Secret
オブジェクトを作成します。$ oc create -f <filename>.yaml
Pod でシークレットを使用するには、以下を実行します。
- シークレットの作成方法についてセクションに示すように、Pod のサービスアカウントを更新してシークレットを参照します。
-
シークレットの作成方法についてに示すように、シークレットを環境変数またはファイル (
secret
ボリュームを使用) として使用する Pod を作成します。
関連情報
- Pod でシークレットを使用する方法は、シークレットの作成方法について を参照してください。
2.6.3. シークレットの更新方法
シークレットの値を変更する場合、値 (すでに実行されている Pod で使用される値) は動的に変更されません。シークレットを変更するには、元の Pod を削除してから新規の Pod を作成する必要があります (同じ PodSpec を使用する場合があります)。
シークレットの更新は、新規コンテナーイメージのデプロイメントと同じワークフローで実行されます。kubectl rolling-update
コマンドを使用できます。
シークレットの resourceVersion
値は参照時に指定されません。したがって、シークレットが Pod の起動と同じタイミングで更新される場合、Pod に使用されるシークレットのバージョンは定義されません。
現時点で、Pod の作成時に使用されるシークレットオブジェクトのリソースバージョンを確認することはできません。コントローラーが古い resourceVersion
を使用して Pod を再起動できるように、Pod がこの情報を報告できるようにすることが予定されています。それまでは既存シークレットのデータを更新せずに別の名前で新規のシークレットを作成します。
2.6.4. シークレットで署名証明書を使用する方法
サービスの通信を保護するため、プロジェクト内のシークレットに追加可能な、署名されたサービス証明書/キーペアを生成するように OpenShift Container Platform を設定することができます。
サービス提供証明書のシークレット は、追加設定なしの証明書を必要とする複雑なミドルウェアアプリケーションをサポートするように設計されています。これにはノードおよびマスターの管理者ツールで生成されるサーバー証明書と同じ設定が含まれます。
サービス提供証明書のシークレット用に設定されるサービス Pod
仕様
apiVersion: v1
kind: Service
metadata:
name: registry
annotations:
service.beta.openshift.io/serving-cert-secret-name: registry-cert1
# ...
- 1
- 証明書の名前を指定します。
他の Pod は Pod に自動的にマウントされる /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt ファイルの CA バンドルを使用して、クラスターで作成される証明書 (内部 DNS 名の場合にのみ署名される) を信頼できます。
この機能の署名アルゴリズムは x509.SHA256WithRSA
です。ローテーションを手動で実行するには、生成されたシークレットを削除します。新規の証明書が作成されます。
2.6.4.1. シークレットで使用する署名証明書の生成
署名されたサービス証明書/キーペアを Pod で使用するには、サービスを作成または編集して service.beta.openshift.io/serving-cert-secret-name
アノテーションを追加した後に、シークレットを Pod に追加します。
手順
サービス提供証明書のシークレット を作成するには、以下を実行します。
-
サービスの
Pod
仕様を編集します。 シークレットに使用する名前に
service.beta.openshift.io/serving-cert-secret-name
アノテーションを追加します。kind: Service apiVersion: v1 metadata: name: my-service annotations: service.beta.openshift.io/serving-cert-secret-name: my-cert 1 spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376
証明書およびキーは PEM 形式であり、それぞれ
tls.crt
およびtls.key
に保存されます。サービスを作成します。
$ oc create -f <file-name>.yaml
シークレットを表示して、作成されていることを確認します。
すべてのシークレットの一覧を表示します。
$ oc get secrets
出力例
NAME TYPE DATA AGE my-cert kubernetes.io/tls 2 9m
シークレットの詳細を表示します。
$ oc describe secret my-cert
出力例
Name: my-cert Namespace: openshift-console Labels: <none> Annotations: service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z service.beta.openshift.io/originating-service-name: my-service service.beta.openshift.io/originating-service-uid: 640f0ec3-afc2-4380-bf31-a8c784846a11 service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z Type: kubernetes.io/tls Data ==== tls.key: 1679 bytes tls.crt: 2595 bytes
このシークレットを使って
Pod
仕様を編集します。apiVersion: v1 kind: Pod metadata: name: my-service-pod spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" volumes: - name: foo secret: secretName: my-cert items: - key: username path: my-group/my-username mode: 511
これが利用可能な場合、Pod が実行されます。この証明書は内部サービス DNS 名、
<service.name>.<service.namespace>.svc
に適しています。証明書/キーのペアは有効期限に近づくと自動的に置換されます。シークレットの
service.beta.openshift.io/expiry
アノテーションで RFC3339 形式の有効期限の日付を確認します。注記ほとんどの場合、サービス DNS 名
<service.name>.<service.namespace>.svc
は外部にルーティング可能ではありません。<service.name>.<service.namespace>.svc
の主な使用方法として、クラスターまたはサービス間の通信用として、 re-encrypt ルートで使用されます。
2.6.5. シークレットのトラブルシューティング
サービス証明書の生成は以下を出して失敗します (サービスの service.beta.openshift.io/serving-cert-generation-error
アノテーションには以下が含まれます)。
secret/ssl-key references serviceUID 62ad25ca-d703-11e6-9d6f-0e9c0057b608, which does not match 77b6dd80-d716-11e6-9d6f-0e9c0057b60
証明書を生成したサービスがすでに存在しないか、またはサービスに異なる serviceUID
があります。古いシークレットを削除し、サービスのアノテーション (service.beta.openshift.io/serving-cert-generation-error
、service.beta.openshift.io/serving-cert-generation-error-num
) をクリアして証明書の再生成を強制的に実行する必要があります。
シークレットを削除します。
$ oc delete secret <secret_name>
アノテーションをクリアします。
$ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-
$ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-num-
アノテーションを削除するコマンドでは、削除するアノテーション名の後に -
を付けます。