7.4. Projected ボリュームによるボリュームのマッピング
Projected ボリューム は、いくつかの既存のボリュームソースを同じディレクトリーにマップします。
以下のタイプのボリュームソースをデプロイメントできます。
- シークレット
- Config Map
- Downward API
すべてのソースは Pod と同じ namespace に置かれる必要があります。
7.4.1. Projected ボリュームについて
Projected ボリュームはこれらのボリュームソースの任意の組み合わせを単一ディレクトリーにマップし、ユーザーの以下の実行を可能にします。
- 単一ボリュームを、複数のシークレットのキー、設定マップ、および Downward API 情報で自動的に設定し、各種の情報ソースで単一ディレクトリーを合成できるようにします。
- 各項目のパスを明示的に指定して、単一ボリュームを複数シークレットのキー、設定マップ、および Downward API 情報で設定し、ユーザーがボリュームの内容を完全に制御できるようにします。
RunAsUser
パーミッションが Linux ベースの Pod のセキュリティーコンテキストに設定されている場合、Projected ファイルには、コンテナーユーザー所有権を含む適切なパーミッションが設定されます。ただし、Windows の同等の RunAsUsername
パーミッションが Windows Pod に設定されている場合、kubelet は Projected ボリュームのファイルに正しい所有権を設定できません。
そのため、Windows Pod のセキュリティーコンテキストに設定された RunAsUsername
パーミッションは、OpenShift Dedicated で実行される Windows の Projected ボリュームには適用されません。
以下の一般的なシナリオは、Projected ボリュームを使用する方法を示しています。
- 設定マップ、シークレット、Downward API
-
Projected ボリュームを使用すると、パスワードが含まれる設定データでコンテナーをデプロイできます。これらのリソースを使用するアプリケーションは、Red Hat OpenStack Platform (RHOSP) を Kubernetes にデプロイしている可能性があります。設定データは、サービスが実稼働用またはテストで使用されるかによって異なった方法でアセンブルされる必要がある可能性があります。Pod に実稼働またはテストのラベルが付けられている場合、Downward API セレクター
metadata.labels
を使用して適切な RHOSP 設定を生成できます。 - 設定マップ + シークレット
- Projected ボリュームにより、設定データおよびパスワードを使用してコンテナーをデプロイできます。たとえば、設定マップを、Vault パスワードファイルを使用して暗号解除する暗号化された機密タスクで実行する場合があります。
- ConfigMap + Downward API.
-
Projected ボリュームにより、Pod 名 (
metadata.name
セレクターで選択可能) を含む設定を生成できます。このアプリケーションは IP トラッキングを使用せずに簡単にソースを判別できるよう要求と共に Pod 名を渡すことができます。 - シークレット + Downward API
-
Projected ボリュームにより、Pod の namespace (
metadata.namespace
セレクターで選択可能) を暗号化するためのパブリックキーとしてシークレットを使用できます。この例では、Operator はこのアプリケーションを使用し、暗号化されたトランスポートを使用せずに namespace 情報を安全に送信できるようになります。
7.4.1.1. Pod 仕様の例
以下は、Projected ボリュームを作成するための Pod
仕様の例です。
シークレット、Downward API および設定マップを含む Pod
apiVersion: v1 kind: Pod metadata: name: volume-test spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: container-test image: busybox volumeMounts: 1 - name: all-in-one mountPath: "/projected-volume"2 readOnly: true 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] volumes: 4 - name: all-in-one 5 projected: defaultMode: 0400 6 sources: - secret: name: mysecret 7 items: - key: username path: my-group/my-username 8 - downwardAPI: 9 items: - path: "labels" fieldRef: fieldPath: metadata.labels - path: "cpu_limit" resourceFieldRef: containerName: container-test resource: limits.cpu - configMap: 10 name: myconfigmap items: - key: config path: my-group/my-config mode: 0777 11
- 1
- シークレットを必要とする各コンテナーの
volumeMounts
セクションを追加します。 - 2
- シークレットが表示される未使用ディレクトリーのパスを指定します。
- 3
readOnly
をtrue
に設定します。- 4
- それぞれの Projected ボリュームソースをリスト表示するために
volumes
ブロックを追加します。 - 5
- ボリュームの名前を指定します。
- 6
- ファイルに実行パーミッションを設定します。
- 7
- シークレットを追加します。シークレットオブジェクトの名前を追加します。使用する必要のあるそれぞれのシークレットはリスト表示される必要があります。
- 8
mountPath
の下にシークレットへのパスを指定します。ここで、シークレットファイルは /projected-volume/my-group/my-username になります。- 9
- Downward API ソースを追加します。
- 10
- ConfigMap ソースを追加します。
- 11
- 特定のデプロイメントにおけるモードを設定します。
Pod に複数のコンテナーがある場合、それぞれのコンテナーには volumeMounts
セクションが必要ですが、1 つの volumes
セクションのみが必要になります。
デフォルト以外のパーミッションモデルが設定された複数シークレットを含む Pod
apiVersion: v1 kind: Pod metadata: name: volume-test spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: container-test image: busybox volumeMounts: - name: all-in-one mountPath: "/projected-volume" readOnly: true securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] volumes: - name: all-in-one projected: defaultMode: 0755 sources: - secret: name: mysecret items: - key: username path: my-group/my-username - secret: name: mysecret2 items: - key: password path: my-group/my-password mode: 511
defaultMode
はデプロイメントされるレベルでのみ指定でき、各ボリュームソースには指定されません。ただし、上記のように個々のデプロイメントに関する mode
を明示的に指定できます。
7.4.1.2. パスに関する留意事項
- 設定されるパスが同一である場合のキー間の競合
複数のキーを同じパスで設定する場合、Pod 仕様は有効な仕様として受け入れられません。以下の例では、
mysecret
およびmyconfigmap
に指定されるパスは同じです。apiVersion: v1 kind: Pod metadata: name: volume-test spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: container-test image: busybox volumeMounts: - name: all-in-one mountPath: "/projected-volume" readOnly: true securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] volumes: - name: all-in-one projected: sources: - secret: name: mysecret items: - key: username path: my-group/data - configMap: name: myconfigmap items: - key: config path: my-group/data
ボリュームファイルのパスに関連する以下の状況を検討しましょう。
- 設定されたパスのないキー間の競合
- 上記のシナリオの場合と同様に、実行時の検証が実行される唯一のタイミングはすべてのパスが Pod の作成時に認識される時です。それ以外の場合は、競合の発生時に指定された最新のリソースがこれより前のすべてのものを上書きします (これは Pod 作成後に更新されるリソースについても同様です)。
- 1 つのパスが明示的なパスであり、もう 1 つのパスが自動的にデプロイメントされるパスである場合の競合
- 自動的にデプロイメントされるデータに一致するユーザー指定パスによって競合が生じる場合、前述のように後からのリソースがこれより前のすべてのものを上書きします。
7.4.2. Pod の Projected ボリュームの設定
Projected ボリュームを作成する場合は、Projected ボリュームについて で説明されているボリュームファイルパスの状態を考慮します。
以下の例では、Projected ボリュームを使用して、既存のシークレットボリュームソースをマウントする方法が示されています。以下の手順は、ローカルファイルからユーザー名およびパスワードのシークレットを作成するために実行できます。その後に、シークレットを同じ共有ディレクトリーにマウントするために Projected ボリュームを使用して 1 つのコンテナーを実行する Pod を作成します。
このユーザー名とパスワードの値には、base64 でエンコードされた任意の有効な文字列を使用できます。
以下の例は、base64 の admin
を示しています。
$ echo -n "admin" | base64
出力例
YWRtaW4=
以下の例は、base64 のパスワード 1f2d1e2e67df
を示しています。
$ echo -n "1f2d1e2e67df" | base64
出力例
MWYyZDFlMmU2N2Rm
手順
既存のシークレットボリュームソースをマウントするために Projected ボリュームを使用するには、以下を実行します。
シークレットを作成します。
次のような YAML ファイルを作成し、パスワードとユーザー情報を適切に置き換えます。
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: pass: MWYyZDFlMmU2N2Rm user: YWRtaW4=
以下のコマンドを使用してシークレットを作成します。
$ oc create -f <secrets-filename>
以下に例を示します。
$ oc create -f secret.yaml
出力例
secret "mysecret" created
シークレットが以下のコマンドを使用して作成されていることを確認できます。
$ oc get secret <secret-name>
以下に例を示します。
$ oc get secret mysecret
出力例
NAME TYPE DATA AGE mysecret Opaque 2 17h
$ oc get secret <secret-name> -o yaml
以下に例を示します。
$ oc get secret mysecret -o yaml
apiVersion: v1 data: pass: MWYyZDFlMmU2N2Rm user: YWRtaW4= kind: Secret metadata: creationTimestamp: 2017-05-30T20:21:38Z name: mysecret namespace: default resourceVersion: "2107" selfLink: /api/v1/namespaces/default/secrets/mysecret uid: 959e0424-4575-11e7-9f97-fa163e4bd54c type: Opaque
投影されたボリュームを持つ Pod を作成します。
volumes
セクションを含む、次のような YAML ファイルを作成します。kind: Pod metadata: name: test-projected-volume spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: test-projected-volume image: busybox args: - sleep - "86400" volumeMounts: - name: all-in-one mountPath: "/projected-volume" readOnly: true securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] volumes: - name: all-in-one projected: sources: - secret: name: mysecret 1
- 1
- 作成されたシークレットの名前。
設定ファイルから Pod を作成します。
$ oc create -f <your_yaml_file>.yaml
以下に例を示します。
$ oc create -f secret-pod.yaml
出力例
pod "test-projected-volume" created
Pod コンテナーが実行中であることを確認してから、Pod への変更を確認します。
$ oc get pod <name>
以下に例を示します。
$ oc get pod test-projected-volume
出力は以下のようになります。
出力例
NAME READY STATUS RESTARTS AGE test-projected-volume 1/1 Running 0 14s
別のターミナルで、
oc exec
コマンドを使用し、実行中のコンテナーに対してシェルを開きます。$ oc exec -it <pod> <command>
以下に例を示します。
$ oc exec -it test-projected-volume -- /bin/sh
シェルで、
projected-volumes
ディレクトリーにデプロイメントされるソースが含まれることを確認します。/ # ls
出力例
bin home root tmp dev proc run usr etc projected-volume sys var