ストレージアクセス#

podリソースにて、コンテナを呼び出すことができることはわかりました。 しかし、コンテナは状況によってはデータをコンテナ独自で保持したいと思うときがあります。 Dockerの所ではホスト側のストレージ(ディレクトリ)を共有することや、Docker Engine側で持つストレージを一部渡すことで実現していましたが、K8sの場合でもある程度可能です。

ここではいくつかそれを提示していきたいと思います。

コンテナに付随するストレージ#

コンテナに付随するストレージとしては、 とりあえず2つの方法があるので、ここから学んでおきます。

  • emptyDir

    • コンテナエンジンから適当に「空のディレクトリ」の割り当てを受けます

  • hostPath

    • コンテナエンジンの特定のディレクトリを割り当てます

    • 既に存在しているディレクトリだった場合は引き継いで参照できます

emptyDir はコンテナが生成されたときに空のディレクトリを割り当ててもらうため、ポッドを削除した場合は一緒にその存在も消されてしまいます。ポッドがエラーなどで落ちて再起動した場合は落ちる前の状態の割り当てを受けられます。 hostPath は特定のディレクトリを指定できるため、他のPodが使っているディレクトリでも一致すればマウントできてしまいます。同一ノード内でデータの受け渡しをするというときには便利そうですが、 全てのPodが同一ノードで稼働する保証はまったくないという前提を忘れないでください。

ストレージをPodに持ち込む方法#

ではPodのマニフェストに対して、ストレージを設定してみます。 ストレージを設定する方法は2段階で行います。

  1. 利用したいストレージを volume キーの値として登録します。配列の値で記述し、複数のストレージを定義できます。

  2. volume で登録したストレージ名をPodのspecにてvolumeMountsで登録します。

まずストレージを定義するところを提示します。

Listing 42 ストレージの定義#
spec:
  volumes:
    - name: empty
      emptyDir: {}
    - name: hp
      hostPath:
        path: /data/pv0001
  • ストレージにはそれぞれ名前(name)が必要です

  • ストレージが利用する方式と、方式に求められるパラメーターが必要です

    • emptyDir は何もパラメータを付けなくてもいいのですが、YAMLの記述上値無しが構文エラーになってしまいます。そのため空の値({})を渡すことで回避しています

    • hostPath はコンテナエンジンの動いているホストにおいての適当なディレクトリを指定します

Caution

minikubeによるK8s環境では、停止(minikube stop)させたときにhostPathで指定したディレクトリは自動的に消去されます。 ただし、データを残したいというときもあるため、 /dataディレクトリなど、一部のディレクトリは次回の環境起動時にも再現される仕組みを採っています。 詳しくは永続ボリュームを参照してください。

Pod側のマウント#

Pod側でのマウントは、 volumeMounts を使って行います。

Listing 43 ストレージのマウント指定#
apiVersion: v1
kind: Pod
metadata:
  name: storagepod
  labels:
    name: storagepod
spec:
  volumes:
    - name: empty
      emptyDir: {}
    - name: hp
      hostPath:
        path: /data/pv0001

  containers:
  - name: stragepod
    image: alpine
    resources:
      limits:
        memory: "128Mi"
        cpu: "500m"
    command:
      - "/bin/sleep"
      - "infinity"
    volumeMounts:
      - name: empty
        mountPath: /data/empty
      - name: hp
        mountPath: /data/hp

Pod側は、ストレージがどういうシステムで構成されているかは意識せず、あくまでvolumesで登録したキーに対するマウントポイントという形で行います。

Note

せっかくなので、マニフェストをコピーし、ポッド名などだけを書き換えたポッドを作ってみましょう。 このとき、2つのポッド(上で作ったものと名前を書き換えただけのポッド)のストレージを書き換えたとき、他方でその内容が参照できるでしょうか?

_images/hostpath-share.drawio.png

Fig. 12 2つのポッドが同じパスを参照するhostPathを定義したときの様子#

Tip

minikubeの中でファイルを作成した場合、それを直接取得するのはかなり難しいです。 本番環境では、ファイルを作成したときのストレージをローカルから参照できるものをソースに設定して、コマンドで取得するようなケースが多いようです (たとえばAWSのS3ストレージがマウントできるので、S3ストレージにに保存されたデータをバックアップマシンからアクセスする等)。