3.6. 入力シークレットおよび config map
入力シークレットおよび config map のコンテンツがビルドの出力コンテナーイメージに表示されないようにするには、Docker build と source-to-image build ストラテジーでビルドボリュームを使用します。
シナリオによっては、ビルド操作で、依存するリソースにアクセスするための認証情報や他の設定データが必要になる場合がありますが、この情報をソースコントロールに配置するのは適切ではありません。この場合は、入力シークレットおよび入力 config map を定義することができます。
たとえば、Maven を使用して Java アプリケーションをビルドする場合、プライベートキーを使用してアクセスされる Maven Central または JCenter のプライベートミラーをセットアップできます。そのプライベートミラーからライブラリーをダウンロードするには、以下を指定する必要があります。
-
ミラーの URL および接続の設定が含まれる
settings.xml
ファイル。 -
~/.ssh/id_rsa
などの、設定ファイルで参照されるプライベートキー。
セキュリティー上の理由により、認証情報はアプリケーションイメージで公開しないでください。
以下の例は Java アプリケーションを説明していますが、/etc/ssl/certs
ディレクトリー、API キーまたはトークン、ラインセンスファイルなどに SSL 証明書を追加する場合に同じ方法を使用できます。
3.6.1. シークレットの概要
Secret
オブジェクトタイプはパスワード、OpenShift Container Platform クライアント設定ファイル、dockercfg
ファイル、プライベートソースリポジトリーの認証情報などの機密情報を保持するメカニズムを提供します。シークレットは機密内容を Pod から切り離します。シークレットはボリュームプラグインを使用してコンテナーにマウントすることも、システムが Pod の代わりにシークレットを使用して各種アクションを実行することもできます。
YAML シークレットオブジェクト定義
apiVersion: v1 kind: Secret metadata: name: test-secret namespace: my-namespace type: Opaque 1 data: 2 username: <username> 3 password: <password> stringData: 4 hostname: myapp.mydomain.com 5
- 1
- シークレットにキー名および値の構造を示しています。
- 2
data
フィールドでキーに使用できる形式は、Kubernetes identifiers glossary のDNS_SUBDOMAIN
値のガイドラインに従う必要があります。- 3
data
マップのキーに関連付けられる値は base64 でエンコーディングされている必要があります。- 4
stringData
マップのエントリーが base64 に変換され、このエントリーは自動的にdata
マップに移動します。このフィールドは書き込み専用です。値はdata
フィールドによってのみ返されます。- 5
stringData
マップのキーに関連付けられた値は単純なテキスト文字列で構成されます。
3.6.1.1. シークレットのプロパティー
キーのプロパティーには以下が含まれます。
- シークレットデータはその定義とは別に参照できます。
- シークレットデータのボリュームは一時ファイルストレージ機能 (tmpfs) でサポートされ、ノードで保存されることはありません。
- シークレットデータは namespace 内で共有できます。
3.6.1.2. シークレットの種類
type
フィールドの値で、シークレットのキー名と値の構造を指定します。このタイプを使用して、シークレットオブジェクトにユーザー名とキーの配置を実行できます。検証の必要がない場合には、デフォルト設定の opaque
タイプを使用してください。
以下のタイプから 1 つ指定して、サーバー側で最小限の検証をトリガーし、シークレットデータに固有のキー名が存在することを確認します。
-
kubernetes.io/service-account-token
。サービスアカウントトークンを使用します。 -
kubernetes.io/dockercfg
.必須の Docker 認証には.dockercfg
ファイルを使用します。 -
kubernetes.io/dockerconfigjson
.必須の Docker 認証には.docker/config.json
ファイルを使用します。 -
kubernetes.io/basic-auth
.Basic 認証で使用します。 -
kubernetes.io/ssh-auth
.SSH キー認証で使用します。 -
kubernetes.io/tls
.TLS 認証局で使用します。
検証の必要がない場合には type= Opaque
と指定します。これは、シークレットがキー名または値の規則に準拠しないという意味です。opaque
シークレットでは、任意の値を含む、体系化されていない key:value
ペアも利用できます。
example.com/my-secret-type
などの他の任意のタイプを指定できます。これらのタイプはサーバー側では実行されませんが、シークレットの作成者がその種類のキー/値の要件に従う意図があることを示します。
3.6.1.3. シークレットの更新
シークレットの値を変更する場合、すでに実行されている Pod で使用される値は動的に変更されません。シークレットを変更するには、元の Pod を削除してから新規の Pod を作成する必要があります (同じ PodSpec
を使用する場合があります)。
シークレットの更新は、新規コンテナーイメージのデプロイと同じワークフローで実行されます。kubectl rolling-update
コマンドを使用できます。
シークレットの resourceVersion
値は参照時に指定されません。したがって、シークレットが Pod の起動と同じタイミングで更新される場合、Pod に使用されるシークレットのバージョンは定義されません。
現時点で、Pod の作成時に使用されるシークレットオブジェクトのリソースバージョンを確認することはできません。コントローラーが古い resourceVersion
を使用して Pod を再起動できるように、Pod がこの情報を報告できるようにすることが予定されています。それまでは既存シークレットのデータを更新せずに別の名前で新規のシークレットを作成します。
3.6.2. シークレットの作成
シークレットに依存する Pod を作成する前に、シークレットを作成する必要があります。
シークレットの作成時に以下を実行します。
- シークレットデータでシークレットオブジェクトを作成します。
- Pod のサービスアカウントをシークレットの参照を許可するように更新します。
-
シークレットを環境変数またはファイルとして使用する Pod を作成します (
secret
ボリュームを使用)。
手順
作成コマンドを使用して JSON または YAML ファイルのシークレットオブジェクトを作成できます。
$ oc create -f <filename>
たとえば、ローカルの
.docker/config.json
ファイルからシークレットを作成できます。$ oc create secret generic dockerhub \ --from-file=.dockerconfigjson=<path/to/.docker/config.json> \ --type=kubernetes.io/dockerconfigjson
このコマンドにより、
dockerhub
という名前のシークレットの JSON 仕様が生成され、オブジェクトが作成されます。YAML の不透明なシークレットオブジェクトの定義
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque 1 data: username: <username> password: <password>
- 1
- opaque シークレットを指定します。
Docker 設定の JSON ファイルシークレットオブジェクトの定義
apiVersion: v1 kind: Secret metadata: name: aregistrykey namespace: myapps type: kubernetes.io/dockerconfigjson 1 data: .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== 2
3.6.3. シークレットの使用
シークレットの作成後に、Pod を作成してシークレットを参照し、ログを取得し、Pod を削除することができます。
手順
シークレットを参照する Pod を作成します。
$ oc create -f <your_yaml_file>.yaml
ログを取得します。
$ oc logs secret-example-pod
Pod を削除します。
$ oc delete pod secret-example-pod
関連情報
シークレットデータを含む YAML ファイルのサンプル
4 つのファイルを作成する YAML シークレット
apiVersion: v1 kind: Secret metadata: name: test-secret data: username: <username> 1 password: <password> 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: build.openshift.io/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
3.6.4. 入力シークレットおよび設定マップの追加
認証情報およびその他の設定データをソース管理に配置せずにビルドに提供するには、入力シークレットおよび入力 config map を定義します。
シナリオによっては、ビルド操作で、依存するリソースにアクセスするための認証情報や他の設定データが必要になる場合があります。この情報をソース管理に配置せずに利用可能にするには、入力シークレットおよび入力 config map を定義します。
手順
既存の BuildConfig
オブジェクトに入力シークレットおよび/または設定マップを追加するには、以下を行います。
ConfigMap
オブジェクトがない場合はこれを作成します。$ oc create configmap settings-mvn \ --from-file=settings.xml=<path/to/settings.xml>
これにより、
settings-mvn
という名前の新しい設定マップが作成されます。これには、settings.xml
ファイルのプレーンテキストのコンテンツが含まれます。ヒントまたは、以下の YAML を適用して設定マップを作成できます。
apiVersion: core/v1 kind: ConfigMap metadata: name: settings-mvn data: settings.xml: | <settings> … # Insert maven settings here </settings>
Secret
オブジェクトがない場合はこれを作成します。$ oc create secret generic secret-mvn \ --from-file=ssh-privatekey=<path/to/.ssh/id_rsa> --type=kubernetes.io/ssh-auth
これにより、
secret-mvn
という名前の新規シークレットが作成されます。 これには、id_rsa
プライベートキーの base64 でエンコードされたコンテンツが含まれます。ヒントまたは、以下の YAML を適用して入力シークレットを作成できます。
apiVersion: core/v1 kind: Secret metadata: name: secret-mvn type: kubernetes.io/ssh-auth data: ssh-privatekey: | # Insert ssh private key, base64 encoded
設定マップおよびシークレットを既存の
BuildConfig
オブジェクトのsource
セクションに追加します。source: git: uri: https://github.com/wildfly/quickstart.git contextDir: helloworld configMaps: - configMap: name: settings-mvn secrets: - secret: name: secret-mvn
シークレットおよび設定マップを新規の BuildConfig
オブジェクトに追加するには、以下のコマンドを実行します。
$ oc new-build \ openshift/wildfly-101-centos7~https://github.com/wildfly/quickstart.git \ --context-dir helloworld --build-secret “secret-mvn” \ --build-config-map "settings-mvn"
ビルド時に、settings.xml
および id_rsa
ファイルはソースコードが配置されているディレクトリーにコピーされます。OpenShift Container Platform S2I ビルダーイメージでは、これはイメージの作業ディレクトリーで、 Dockerfile
の WORKDIR
の指示を使用して設定されます。別のディレクトリーを指定するには、 destinationDir
を定義に追加します。
source: git: uri: https://github.com/wildfly/quickstart.git contextDir: helloworld configMaps: - configMap: name: settings-mvn destinationDir: ".m2" secrets: - secret: name: secret-mvn destinationDir: ".ssh"
新規の BuildConfig
オブジェクトの作成時に、宛先のディレクトリーを指定することも可能です。
$ oc new-build \ openshift/wildfly-101-centos7~https://github.com/wildfly/quickstart.git \ --context-dir helloworld --build-secret “secret-mvn:.ssh” \ --build-config-map "settings-mvn:.m2"
いずれの場合も、settings.xml
ファイルがビルド環境の ./.m2
ディレクトリーに追加され、id_rsa
キーは ./.ssh
ディレクトリーに追加されます。
3.6.5. Source-to-Image ストラテジー
Source
ストラテジーを使用すると、定義された入力シークレットはすべて、適切な destinationDir
にコピーされます。destinationDir
を空にすると、シークレットはビルダーイメージの作業ディレクトリーに配置されます。
destinationDir
が相対パスの場合に同じルールが使用されます。シークレットは、イメージの作業ディレクトリーに相対的なパスに配置されます。destinationDir
パスの最終ディレクトリーは、ビルダーイメージにない場合に作成されます。destinationDir
の先行するすべてのディレクトリーは存在している必要があり、そうでない場合にはエラーが生じます。
入力シークレットは全ユーザーに書き込み権限が割り当てられた状態で追加され (0666
のパーミッション)、assemble
スクリプトの実行後には、サイズが 0 になるように切り捨てられます。つまり、シークレットファイルは作成されたイメージ内に存在しますが、セキュリティーの理由で空になります。
入力 config map は、assemble
スクリプトの実行後に切り捨てられません。
3.6.6. Docker ストラテジー
docker ストラテジーを使用すると、Dockerfile で ADD
および COPY
の命令 を使用してコンテナーイメージに定義されたすべての入力シークレットを追加できます。
シークレットの destinationDir
を指定しない場合は、ファイルは、Dockerfile が配置されているのと同じディレクトリーにコピーされます。相対パスを destinationDir
として指定する場合は、シークレットは、Dockerfile の場所と相対的なディレクトリーにコピーされます。これにより、ビルド時に使用するコンテキストディレクトリーの一部として、Docker ビルド操作でシークレットファイルが利用できるようになります。
シークレットおよび config map データを参照する Dockerfile の例
FROM centos/ruby-22-centos7 USER root COPY ./secret-dir /secrets COPY ./config / # Create a shell script that will output secrets and ConfigMaps when the image is run RUN echo '#!/bin/sh' > /input_report.sh RUN echo '(test -f /secrets/secret1 && echo -n "secret1=" && cat /secrets/secret1)' >> /input_report.sh RUN echo '(test -f /config && echo -n "relative-configMap=" && cat /config)' >> /input_report.sh RUN chmod 755 /input_report.sh CMD ["/bin/sh", "-c", "/input_report.sh"]
通常はシークレットがイメージから実行するコンテナーに置かれないように、入力シークレットを最終的なアプリケーションイメージから削除します。ただし、シークレットは追加される階層のイメージ自体に存在します。この削除は、Dockerfile の一部として組み込まれます。
入力シークレットおよび config map のコンテンツがビルド出力コンテナーイメージに表示されないようにして、この削除プロセスを完全に回避するには、代わりに Docker ビルドストラテジーで ビルドボリュームを使用 します。
3.6.7. カスタムストラテジー
Custom ストラテジーを使用する場合、定義された入力シークレットおよび config map はすべて、/var/run/secrets/openshift.io/build
ディレクトリー内のビルダーコンテナーで入手できます。カスタムのビルドイメージは、これらのシークレットおよび config map を適切に使用する必要があります。Custom ストラテジーでは、Custom ストラテジーのオプションで説明されているようにシークレットを定義できます。
既存のストラテジーのシークレットと入力シークレットには違いはありません。ただし、ビルダーイメージはこれらを区別し、ビルドのユースケースに基づいてこれらを異なる方法で使用する場合があります。
入力シークレットは常に /var/run/secrets/openshift.io/build
ディレクトリーにマウントされます。 そうでない場合には、ビルダーが完全なビルドオブジェクトを含む $BUILD
環境変数を解析できます。
レジストリーのプルシークレットが namespace とノードの両方に存在する場合、ビルドがデフォルトで namespace でのプルシークレットの使用に設定されます。