1.5. Pod への機密性の高いデータの提供
アプリケーションによっては、パスワードやユーザー名など開発者に使用させない秘密情報が必要になります。
管理者として シークレット オブジェクトを使用すると、この情報を平文で公開することなく提供することが可能です。
1.5.1. シークレットについて
Secret
オブジェクトタイプはパスワード、OpenShift Container Platform クライアント設定ファイル、プライベートソースリポジトリーの認証情報などの機密情報を保持するメカニズムを提供します。シークレットは機密内容を Pod から切り離します。シークレットはボリュームプラグインを使用してコンテナーにマウントすることも、システムが Pod の代わりにシークレットを使用して各種アクションを実行することもできます。
キーのプロパティーには以下が含まれます。
- シークレットデータはその定義とは別に参照できます。
- シークレットデータのボリュームは一時ファイルストレージ機能 (tmpfs) でサポートされ、ノードで保存されることはありません。
- シークレットデータは namespace 内で共有できます。
YAML シークレットオブジェクト定義
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
ボリュームを使用)。
1.5.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
などの他の任意のタイプを指定できます。これらのタイプはサーバー側では実行されませんが、シークレットの作成者はその種類のキー/値の要件に従うことが意図されていることを示します。
シークレットのさまざまなタイプの例については、シークレットの使用に関連するコードのサンプルを参照してください。
1.5.1.2. シークレット設定の例
以下は、シークレットの設定ファイルのサンプルです。
4 つのファイルを作成する YAML シークレット
apiVersion: v1 kind: Secret metadata: name: test-secret data: username: dmFsdWUtMQ0K 1 password: dmFsdWUtMQ0KDQo= 2 stringData: hostname: myapp.mydomain.com 3 secret.properties: |- 4 property1=valueA property2=valueB
シークレットデータと共にボリュームのファイルが設定された 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: # name must match the volume name below - name: secret-volume mountPath: /etc/secret-volume readOnly: true volumes: - name: secret-volume secret: secretName: test-secret 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: name: test-secret key: username restartPolicy: Never
シークレットデータと環境変数が投入されたビルド設定の YAML
apiVersion: v1 kind: BuildConfig metadata: name: secret-example-bc spec: strategy: sourceStrategy: env: - name: TEST_SECRET_USERNAME_ENV_VAR valueFrom: secretKeyRef: name: test-secret key: username
1.5.1.3. シークレットデータキー
シークレットキーは DNS サブドメインになければなりません。
1.5.2. シークレットの作成方法
管理者は、開発者がシークレットに依存する Pod を作成できるよう事前にシークレットを作成しておく必要があります。
シークレットの作成時に以下を実行します。
- シークレットデータでシークレットオブジェクトを作成します。
- Pod のサービスアカウントをシークレットの参照を許可するように更新します。
-
シークレットを環境変数またはファイルとして使用する Pod を作成します (
secret
ボリュームを使用)。
1.5.2.1. シークレットの作成に関する制限
シークレットを使用するには、Pod がシークレットを参照できる必要があります。シークレットは、以下の 3 つの方法で Pod で使用されます。
- コンテナーの環境変数を事前に設定するために使用される。
- 1 つ以上のコンテナーにマウントされるボリュームのファイルとして使用される。
- Pod のイメージをプルする際に kubelet によって使用される。
ボリュームタイプのシークレットは、ボリュームメカニズムを使用してデータをファイルとしてコンテナーに書き込みます。イメージプルシークレットは、シークレットを namespace のすべての Pod に自動的に挿入するためにサービスアカウントを使用します。
テンプレートにシークレット定義が含まれる場合、テンプレートで指定のシークレットを使用できるようにするには、シークレットのボリュームソースを検証し、指定されるオブジェクト参照が Secret
タイプのオブジェクトを実際に参照していることを確認できる必要があります。そのため、シークレットはこれに依存する Pod の作成前に作成されている必要があります。最も効果的な方法として、サービスアカウントを使用してシークレットを自動的に挿入することができます。
シークレット API オブジェクトは namespace にあります。それらは同じ namespace の Pod によってのみ参照されます。
個々のシークレットは 1MB のサイズに制限されます。これにより、apiserver および kubelet メモリーを使い切るような大規模なシークレットの作成を防ぐことができます。ただし、小規模なシークレットであってもそれらを数多く作成するとメモリーの消費につながります。
1.5.2.2. 不透明なシークレットの作成
管理者は、不透明なシークレットを作成できます。 このシークレットでは、任意の値を含む、構造化されていない key:value
ペアを利用できます。
手順
マスターの YAML ファイルにシークレットオブジェクトを作成します。
例:
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque 1 data: username: dXNlci1uYW1l password: cGFzc3dvcmQ=
- 1
- 不透明なシークレットを指定します。
以下のコマンドを使用してシークレットオブジェクトを作成します。
$ oc create -f <filename>
次に、以下を実行します。
- このシークレットを使ってこのシークレットの参照を許可したい、Pod のサービスアカウントを更新します。
-
シークレットを環境変数またはファイルとして使用する Pod を作成します (
secret
ボリュームを使用)。
1.5.3. シークレットの更新方法
シークレットの値を変更する場合、値 (すでに実行されている Pod で使用される値) は動的に変更されません。シークレットを変更するには、元の Pod を削除してから新規の Pod を作成する必要があります (同じ PodSpec を使用する場合があります)。
シークレットの更新は、新規コンテナーイメージのデプロイメントと同じワークフローで実行されます。kubectl rolling-update
コマンドを使用できます。
シークレットの resourceVersion
値は参照時に指定されません。したがって、シークレットが Pod の起動と同じタイミングで更新される場合、Pod に使用されるシークレットのバージョンは定義されません。
現時点で、Pod の作成時に使用されるシークレットオブジェクトのリソースバージョンを確認することはできません。今後はコントローラーが古い resourceVersion
を使用して再起動できるよう Pod がこの情報を報告できるようにすることが予定されています。それまでは既存シークレットのデータを更新せずに別の名前で新規のシークレットを作成します。
1.5.4. シークレットで署名証明書を使用する方法
サービスの通信を保護するため、プロジェクト内のシークレットに追加可能な、署名されたサービス証明書/キーペアを生成するように OpenShift Container Platform を設定することができます。
サービス提供証明書のシークレットは、追加設定なしの証明書を必要とする複雑なミドルウェアアプリケーションをサポートするように設計されています。これにはノードおよびマスターの管理者ツールで生成されるサーバー証明書と同じ設定が含まれます。
サービス提供証明書のシークレット用に設定されるサービスの Pod 仕様
apiVersion: v1
kind: Service
metadata:
name: registry
annotations:
service.alpha.openshift.io/serving-cert-secret-name: registry-cert1
....
- 1
- 証明書の名前を指定します。
他の Pod は Pod に自動的にマウントされる /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt ファイルの CA バンドルを使用して、クラスターで作成される証明書 (内部 DNS 名の場合にのみ署名される) を信頼できます。
この機能の署名アルゴリズムは x509.SHA256WithRSA
です。ローテーションを手動で実行するには、生成されたシークレットを削除します。新規の証明書が作成されます。
1.5.4.1. シークレットで使用する署名証明書の生成
署名されたサービス証明書/キーペアを Pod で使用するには、サービスを作成または編集して service.alpha.openshift.io/serving-cert-secret-name
アノテーションを追加した後に、シークレットを Pod に追加します。
手順
サービス提供証明書のシークレットを作成するには、以下を実行します。
- サービスの Pod 仕様を編集します。
シークレットに使用する名前に
service.alpha.openshift.io/serving-cert-secret-name
アノテーションを追加します。kind: Service apiVersion: v1 metadata: name: my-service annotations: service.alpha.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-service-pod Name: my-service-pod Namespace: openshift-console Labels: <none> Annotations: kubernetes.io/service-account.name: builder kubernetes.io/service-account.uid: ab-11e9-988a-0eb4e1b4a396 Type: kubernetes.io/service-account-token Data ca.crt: 5802 bytes namespace: 17 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Ii wia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJvcGVuc2hpZnQtY29uc29sZSIsImt1YmVyb cnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhYmE4Y2UyZC00MzVlLTExZTktOTg4YS0wZWI0ZTFiNGEz OTYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6b3BlbnNoaWZ
このシークレットを使って 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.alpha.openshift.io/expiry
アノテーションで RFC3339 形式の有効期限の日付を確認します。注記ほとんどの場合、サービス DNS 名
<service.name>.<service.namespace>.svc
は外部にルーティング可能ではありません。<service.name>.<service.namespace>.svc
の主な使用方法として、クラスターまたはサービス間の通信用として、 re-encrypt ルートで使用されます。
1.5.5. シークレットのトラブルシューティング
サービス証明書の生成は以下を出して失敗します (サービスの service.alpha.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.alpha.openshift.io/serving-cert-generation-error
、 service.alpha.openshift.io/serving-cert-generation-error-num
) をクリアして証明書の再生成を強制的に実行する必要があります。
$ oc delete secret <secret_name> $ oc annotate service <service_name> service.alpha.openshift.io/serving-cert-generation-error- $ oc annotate service <service_name> service.alpha.openshift.io/serving-cert-generation-error-num-
アノテーションを削除するコマンドでは、削除するアノテーションの後に -
を付けます。