第24章 Projected ボリューム
24.1. 概要
Projected ボリューム は、いくつかの既存の ボリュームソース を同じディレクトリーにマップします。
現時点で、以下のタイプのボリュームソースを展開できます。
すべてのソースは Pod と同じ namespace に置かれる必要があります。
Projected ボリュームはこれらのボリュームソースの任意の組み合わせを単一ディレクトリーにマップし、ユーザーの以下の実行を可能にします。
- 単一ボリュームを、複数のシークレットのキー、configmap、および Downward API 情報で自動的に設定し、各種の情報ソースで単一ディレクトリーを合成できるようにします。
- 各項目のパスを明示的に指定して、単一ボリュームを複数シークレットのキー、configmap、および Downward API 情報で設定し、ユーザーがボリュームの内容を完全に制御できるようにします。
24.2. シナリオ例
以下の一般的なシナリオは、展開されるプロジェクトを使用する方法について示しています。
-
ConfigMap、シークレット、Downward API: 展開されるボリュームを使用すると、パスワードが含まれる設定データでコンテナーをデプロイできます。これらのリソースを使用するアプリケーションは OpenStack を Kubernetes にデプロイする可能性がありますが、サービスが実稼働で使用されるか、またはテストで使用されるかに応じて設定データを異なる方法でアセンブルする必要が生じる可能性があります。Pod に実稼働またはテストのラベルが付けられる場合、Downward API セレクター
metadata.labels
を適切な OpenStack 設定を生成するために使用できます。 - ConfigMap + シークレット: Projected ボリュームでは、設定データおよびパスワードを使用してコンテナーをデプロイできます。たとえば、暗号化された機密タスクを Vault パスワードファイルを使用して復号化して、configmap として保存された Ansible Playbook を実行することができます。
-
ConfigMap + Downward API: Projected ボリュームにより、Pod 名 (
metadata.name
セレクターで選択可能) を含む設定を生成できます。このアプリケーションは IP トラッキングを使用せずに簡単にソースを判別できるよう要求と共に Pod 名を渡すことができます。 -
シークレット + Downward API: Projected ボリュームにより、Pod の namespace (
metadata.namespace
セレクターで選択可能) を暗号化するためのパブリックキーとしてシークレットを使用できます。この例では、オペレーターはこのアプリケーションを使用し、暗号化されたトランスポートを使用せずに namespace 情報を安全に送信することができるようになります。
24.3. Pod 仕様の例
以下は、Projected ボリュームを作成するための Pod 仕様の例です。
例24.1 シークレット、Downward API および configmap を含む 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
readOnly
をtrue
に設定します。- 4
- それぞれの展開されるボリュームソースを一覧表示するために
volumes
ブロックを追加します。 - 5
- ボリュームの名前を指定します。
- 6
- ファイルに実行パーミッションを設定します。
- 7
- シークレットを追加します。シークレットオブジェクトの名前を追加します。使用する必要のあるそれぞれのシークレットは一覧表示される必要があります。
- 8
mountPath
の下にシークレットへのパスを指定します。ここでシークレットファイルは /projected-volume/my-group/my-config に置かれます。- 9
- Downward API ソースを追加します。
- 10
- ConfigMap ソースを追加します。
- 11
- 特定の展開におけるモードを設定します。
Pod に複数のコンテナーがある場合、それぞれのコンテナーには volumeMounts
セクションが必要ですが、1 つの volumes
セクションのみが必要になります。
例24.2 デフォルト以外のパーミッションモデルが設定された複数シークレットを含む 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
を明示的に指定できます。
24.4. パスについての留意事項
Projected ボリュームを作成する際に、ボリュームファイルのパスに関連する以下の状況について見てみましょう。
- 設定されるパスが同一である場合のキー間の競合
複数のキーを同じパスで設定する場合、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 つのパスが自動的に展開されるパスである場合の競合
- 自動的に展開されるデータに一致するユーザー指定パスによって競合が生じる場合、前述のように後からのリソースがこれより前のすべてのものを上書きします。
24.5. Pod の Projected ボリュームの設定
以下の例は、既存のシークレットボリュームをマウントするために Projected ボリュームを使用する方法を示しています。
以下の手順は、ローカルファイルからユーザー名およびパスワードの シークレットを作成するために実行できます。その後に、シークレットを同じ共有ディレクトリーにマウントするために Projected ボリュームを使用して 1 つのコンテナーを実行する Pod を作成します。
シークレットが含まれるファイルを作成します。
以下に例を示します。
$ nano secret.yaml
以下を入力し、パスワードおよびユーザー情報を適宜置き換えます。
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: pass: MWYyZDFlMmU2N2Rm user: YWRtaW4=
user
およびpass
の値には、base64 でエンコーティングされた任意の有効な文字列を使用できます。ここで使用される例は base64 でエンコーディングされた値 (user: admin
、pass:1f2d1e2e67df
) になります。$ echo -n "admin" | base64 YWRtaW4= $ echo -n "1f2d1e2e67df" | base64 MWYyZDFlMmU2N2Rm
以下のコマンドを使用してシークレットを作成します。
$ oc create -f <secrets-filename>
以下に例を示します。
$ oc create -f secret.yaml secret "mysecret" created
シークレットが以下のコマンドを使用して作成されていることを確認できます。
$ oc get secret <secret-name> $ oc get secret <secret-name> -o yaml
以下に例を示します。
$ oc get secret mysecret NAME TYPE DATA AGE mysecret Opaque 2 17h
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
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: name: user - secret: name: pass
設定ファイルから 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