Kubernetesでファイル共有をしたがコンテナにあったファイルが空になってしまう

# はじめに

最近Kubernetesのハンズオンを行い、そこから自分でデプロイに挑戦しはじめました。
そこでファイル共有について躓き、ネットにあまり情報がなかったのでまとめます。

# 問題

以下のファイルでポッドを作成しました。

```yml:pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: rails
  labels:
    app: rails
spec:
  containers:
  - name: rails
    image: [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/rails:1.0.0
    ports:
      - containerPort: 3000
    env:
      - name: DB_USERNAME
        value: root
      - name: DB_PASSWORD
        value: password
      - name: DB_DATABASE
        value: myapp
      - name: DB_HOST
        value: db
    volumeMounts:
    - name: public-data
      mountPath: /myapp/public
    - name: tmp-data
      mountPath: /myapp/tmp/sockets

  - name: nginx
    image: [アカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
    ports:
      - containerPort: 80
    volumeMounts:
    - name: public-data
      mountPath: /myapp/public
    - name: tmp-data
      mountPath: /myapp/tmp/sockets

  volumes:
    - name: public-data
      emptyDir: {}
    - name: tmp-data
      emptyDir: {}
```

RailsとNginxのコンテナを作成しています。
そして、ボリュームの`public-data`と`tmp-data`でコンテナ間でファイル共有を行いたいと考えていました。

しかし、実際に共有すると共有したいファイルはすべて空になっていました。
また、`/myapp/tmp/sockets`は空になっておらず、コンテナが起動した後に作成されるファイルのみが共有されていました。

# 解決方法

まず大きな勘違いがありました。
Dockerのボリュームによるファイル共有とKubernetesによるボリュームのファイル共有は全くの別物でした。

Kubernetesの場合は空のファイルとなって共有されます。

ですので、事前に共有したいファイルを、コンテナに存在しないフォルダをVolumeに設定してそこにコピーしておく必要があります。

[Sharing non-persistent volume between containers in a pod](https://stackoverflow.com/questions/65471145/sharing-non-persistent-volume-between-containers-in-a-pod)

この記事を参考に`initContainer`を利用することでコピーを行いました。

```yml:pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: rails
  labels:
    app: rails
spec:
  volumes:
    - name: public-data
      emptyDir: {}
    - name: tmp-data
      emptyDir: {}

  initContainers:
  - name: pre-rails
    image: xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/rails:1.0.0
    command: ['/bin/sh', '-c', 'cp -a /myapp/public/* /mnt/empty-dir-content/']
    volumeMounts:
      - name: public-data
        mountPath: "/mnt/empty-dir-content/"

  containers:
  - name: rails
    image: 945231564387.dkr.ecr.ap-northeast-1.amazonaws.com/rails:1.0.0
    ports:
      - containerPort: 3000
    command: ['/bin/sh', '-c', 'bundle exec puma -C config/puma.rb']
    env:
      - name: DB_USERNAME
        value: admin
      - name: DB_PASSWORD
        value: password
      - name: DB_DATABASE
        value: myapp
      - name: DB_HOST
        value: sample-db.cmb2t0anuznk.ap-northeast-1.rds.amazonaws.com
    volumeMounts:
    - name: tmp-data
      mountPath: /myapp/tmp/sockets

  - name: nginx
    image: xxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
    ports:
      - containerPort: 80
    volumeMounts:
    - name: public-data
      mountPath: /myapp/public
    - name: tmp-data
      mountPath: /myapp/tmp/sockets
```

ポイントは`initContiners`で起動したコンテナが落ちてから、`Containers`が立ち上がるのでRailsコンテナがコマンド実行後に落ちるように設定することです。

`bundle exec puma -C config/puma.rb`をDockerfile内で起動してしまうと、initContainersでコンテナが落ちなくなってしまうので、`yml`にコマンドを移動して実行する変更を加えました。

# おわりに

Kubernetesをはじめると日本語の記事などがDockerより格段にヒットしなくなりました。
初学者なので、おそらくつまるところは同じだと思うので書籍からはわからないところは積極的にアウトプットしていきたいです。

# 参考
- [Sharing non-persistent volume between containers in a pod](https://stackoverflow.com/questions/65471145/sharing-non-persistent-volume-between-containers-in-a-pod)