はじめに
最近Kubernetesのハンズオンを行い、そこから自分でデプロイに挑戦しはじめました。
そこでファイル共有について躓き、ネットにあまり情報がなかったのでまとめます。
問題
以下のファイルでポッドを作成しました。
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
この記事を参考にinitContainer
を利用することでコピーを行いました。
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より格段にヒットしなくなりました。
初学者なので、おそらくつまるところは同じだと思うので書籍からはわからないところは積極的にアウトプットしていきたいです。