6.4. Projected ボリュームによるボリュームのマッピング

Projected ボリューム は、いくつかの既存のボリュームソースを同じディレクトリーにマップします。

以下のタイプのボリュームソースを展開できます。

  • シークレット
  • Config Map
  • Downward API
注記

すべてのソースは Pod と同じ namespace に置かれる必要があります。

6.4.1. Projected ボリュームについて

Projected ボリュームはこれらのボリュームソースの任意の組み合わせを単一ディレクトリーにマップし、ユーザーの以下の実行を可能にします。

  • 単一ボリュームを、複数のシークレットのキー、設定マップ、および Downward API 情報で自動的に設定し、各種の情報ソースで単一ディレクトリーを合成できるようにします。
  • 各項目のパスを明示的に指定して、単一ボリュームを複数シークレットのキー、設定マップ、および Downward API 情報で設定し、ユーザーがボリュームの内容を完全に制御できるようにします。
重要

RunAsUser パーミッションが Linux ベースの Pod のセキュリティーコンテキストに設定されている場合、Projected ファイルには、コンテナーユーザー所有権を含む適切なパーミッションが設定されます。ただし、Windows の同等の RunAsUsername パーミッションが Windows Pod に設定されている場合、kubelet は Projected ボリュームのファイルに正しい所有権を設定できません。

そのため、Windows Pod のセキュリティーコンテキストに設定された RunAsUsername パーミッションは、OpenShift Container Platform で実行される 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 情報を安全に送信できるようになります。

6.4.1.1. Pod 仕様の例

以下は、Projected ボリュームを作成するための Pod 仕様の例です。

シークレット、Downward API および設定マップを含む Pod

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts: 1
    - name: all-in-one
      mountPath: "/projected-volume"2
      readOnly: true 3
  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
readOnlytrue に設定します。
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:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  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 を明示的に指定できます。

6.4.1.2. パスについての留意事項

設定されるパスが同一である場合のキー間の競合

複数のキーを同じパスで設定する場合、Pod 仕様は有効な仕様として受け入れられません。以下の例では、mysecret および myconfigmap に指定されるパスは同じです。

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  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 つのパスが自動的に展開されるパスである場合の競合
自動的に展開されるデータに一致するユーザー指定パスによって競合が生じる場合、前述のように後からのリソースがこれより前のすべてのものを上書きします。

6.4.2. Pod の Projected ボリュームの設定

Projected ボリュームを作成する場合は、Pprojected ボリュームについてで説明されているボリュームファイルパスの状態を考慮します。

以下の例では、Projected ボリュームを使用して、既存のシークレットボリュームソースをマウントする方法が示されています。以下の手順は、ローカルファイルからユーザー名およびパスワードのシークレットを作成するために実行できます。その後に、シークレットを同じ共有ディレクトリーにマウントするために Projected ボリュームを使用して 1 つのコンテナーを実行する Pod を作成します。

手順

既存のシークレットボリュームソースをマウントするために Projected ボリュームを使用するには、以下を実行します。

  1. 以下を入力し、パスワードおよびユーザー情報を適宜置き換えて、シークレットを含むファイルを作成します。

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque
    data:
      pass: MWYyZDFlMmU2N2Rm
      user: YWRtaW4=

    user および pass の値には、base64 でエンコーティングされた任意の有効な文字列を使用できます。

    以下の例は、base64 の admin を示しています。

    $ echo -n "admin" | base64

    出力例

    YWRtaW4=

    以下の例は、base64 のパスワード 1f2d1e2e67df を示しています。

    $ echo -n "1f2d1e2e67df" | base64

    出力例

    MWYyZDFlMmU2N2Rm

  2. 以下のコマンドを使用してシークレットを作成します。

    $ oc create -f <secrets-filename>

    以下に例を示します。

    $ oc create -f secret.yaml

    出力例

    secret "mysecret" created

  3. シークレットが以下のコマンドを使用して作成されていることを確認できます。

    $ 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
  4. volumes セクションが含まれる以下のような Pod 設定ファイルを作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-projected-volume
    spec:
      containers:
      - name: test-projected-volume
        image: busybox
        args:
        - sleep
        - "86400"
        volumeMounts:
        - name: all-in-one
          mountPath: "/projected-volume"
          readOnly: true
      volumes:
      - name: all-in-one
        projected:
          sources:
          - secret:      1
              name: user
          - secret:      2
              name: pass
    1 2
    作成されたシークレットの名前。
  5. 設定ファイルから Pod を作成します。

    $ oc create -f <your_yaml_file>.yaml

    以下に例を示します。

    $ oc create -f secret-pod.yaml

    出力例

    pod "test-projected-volume" created

  6. 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

  7. 別のターミナルで、oc exec コマンドを使用し、実行中のコンテナーに対してシェルを開きます。

    $ oc exec -it <pod> <command>

    以下に例を示します。

    $ oc exec -it test-projected-volume -- /bin/sh
  8. シェルで、projected-volumes ディレクトリーに展開されるソースが含まれることを確認します。

    / # ls

    出力例

    bin               home              root              tmp
    dev               proc              run               usr
    etc               projected-volume  sys               var