#14. KubernetesのvolumeMounts修正

# はじめに

以前にWordPressをKubernetesで構築した際に、`nginxコンテナ`と`appコンテナ`（php-fpm用のコンテナ)にボリュームをマウントして、そこにWordPressのリソースファイルを配置して構築したのですが、appコンテナ内にリソースファイルを配置して、nginxコンテナで`readonly`を指定してボリューム内のWordPressのリソースファイルを読み込むように修正しました。

# Pod構成

#### WordPress Pod
コンテナ:
nginx
app（php-fpm用のコンテナ)

#### MySQL Pod
コンテナ:
mysql

#### 使用したvolume

documentroot　（名前の通りドキュメントルートとして使用）

※本記事ではvolume名のdocumentrootは`documentroot`と記載しており、Nginxのconfigファイルで設定しているドキュメントルートは`ドキュメントルート`と記載しております。

# やりたかったこと

これまでは、nginxコンテナとappコンテナの両方でdocumentrootボリュームを参照し、WordPressのドキュメントルートとして使用していました。しかし、appコンテナでは、リソースファイルをローカルに配置し、そのローカルディレクトリをドキュメントルートとして参照する形に変更することで、nginxコンテナのみがdocumentrootボリュームを参照し、ドキュメントルートとして利用する。
これにより、appコンテナはdocumentrootボリュームを参照する必要がなくなり、documentrootボリュームの役割をnginxコンテナ専用とする形に修正しました。


#### 修正後の処理としては以下のようなイメージ

①`initContainers`のプロセスでdocumentrootボリュームを/wordpress-dataディレクトリにマウント　
※initContainersメインコンテナ（nginx,appコンテナ）作成前の処理なのでメインコンテナ作成処理より前に処理
②initContainersでdocumentrootボリュームをマウント後、documentroot内にappコンテナ内のWordpressのリソースファイルをコピー（appコンテナと同じイメージファイルを使用しているのでappコンテナ内のファイルを使用可能）

③nginxコンテナでドキュメントルートに指定しているディレクトリにdocumentrootボリュームをマウント
※volume内のファイルは別ディレクトリにマウントしても保持される。

ということで以下の通りに修正しました

- 修正前のymlファイル

```
  initContainers:
        - name: init
          image: app:v1.0.0
          envFrom:
            - secretRef:
                name: mysql-secret
          command:
            - "sh"
            - "-c"
            - "cp -r /var/wordpress/* /var/www/dev-k8s.techbull.cloud"
          volumeMounts:
            - name: documentroot
              mountPath: "/var/www/dev-k8s.techbull.cloud"
      containers:
        - name: nginx
          image: Kubernetes/nginx:v1.0.0
          ports:
            - containerPort: 80
          volumeMounts:
            - name: php-socket
              mountPath: "/var/run"
            - name: documentroot
              mountPath: "/var/www/dev-k8s.techbull.cloud"
        - name: app
          image: app:v1.0.0
          envFrom:
            - secretRef:
                name: mysql-secret
          volumeMounts:
            - name: php-socket
              mountPath: "/var/run"
            - name: documentroot
              mountPath: "/var/www/dev-k8s.techbull.cloud"
              
      volumes:
        - name: php-socket
          emptyDir: {}
        - name: documentroot
          emptyDir: {}
  ```

 - 修正後のymlファイル
```
     initContainers:
        - name: init
          image: app:v1.0.0
          command:
            - "sh"
            - "-c"
            - "cp -r /var/www/dev-k8s.techbull.cloud/* /wordpress-data/"
          volumeMounts:
            - name: documentroot
              mountPath: "/wordpress-data"
      containers:
        - name: nginx
          image: Kubernetes/nginx:v1.0.0
          ports:
            - containerPort: 80
          volumeMounts:
            - name: php-socket
              mountPath: "/var/run"
            - name: documentroot
              mountPath: "/var/www/dev-k8s.techbull.cloud"
        - name: app
          image: app:v1.0.0
          env:
            - name: MYSQL_DATABASE
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_DATABASE
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_USER
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: MYSQL_PASSWORD
          volumeMounts:
            - name: php-socket
              mountPath: "/var/run"

      volumes:
        - name: php-socket
          emptyDir: {}
        - name: documentroot
          emptyDir: {}
  ```

  今回の修正に伴い、`Dockerfile`も以下のように修正しています。

※コピー元のディレクトリも変更ているのは、整理のためであり、今回の修正内容とは直接関係ありません。

- 修正前のDockerfile
```
COPY wordpress /var/wordpress
```

- 修正後のDockerfile
```
RUN mkdir /var/www/dev-k8s.techbull.cloud
COPY k8s/wordpress/ /var/www/dev-k8s.techbull.cloud/
```

修正前まではnginxコンテナ、appコンテナで共通のボリュームを参照していたので、

まとめてinitContainers（メインコンテナが立ち上がる前の処理）でWordPressのリソースファイルをNginxのドキュメントルートで指定したディレクトリ配下にコピーしていたのですが、

今回は、nginxコンテナのみボリュームを参照すればよいので、appコンテナのDockerfileの設定で事前にドキュメントルート配下へWordpressのリソースファイルをコピーします。

- 修正後WordPressにアクセスした結果

![image (74).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904736/95e99741-7702-9090-54d4-c30690f56024.png)

問題なくWordPressが表示されました。

# おまけ

実は修正後にWordPressにアクセスした際に、以下の画像のようにNot Foundが出てました。

![image (75).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904736/9ee5a030-c719-92bd-f218-45d3ca08e349.png)

なんでかなぁと思い、実際にコンテナ内に入りドキュメントルートを指定しているディレクトリを確認してみると以下のような状態になっていました。

![image (76).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904736/60d2fc90-d8f3-16dd-e33e-2a43dc353ccc.png)

![image (77).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904736/f1f3f093-184a-d112-fe06-e15256ac2107.png)

見たときはなんでこんなことになっているんだろう？という感じだったのですが、

よく見たらWordPressディレクトリのサブディレクトリも展開された状態でコピーされており、ファイルコピーの処理を行っているDockerfileを確認すると`COPY k8s/wordpress/*`でコピー元を指定しており。これが原因でした。

Dockerfileの`COPY`で`/*`  を指定するとディレクトリからサブディレクトリやファイルを展開してからコピーするらしく、そのせいでサブディレクトリ内のファイル全てがドキュメントルート配下に展開していたらしいです。

- `COPY k8s/wordpress/`に修正後

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904736/e372b55e-a18b-94c1-b817-d1e7074829c4.png)

想定通りにコピーされました。

# まとめ

今回volumeMountsを修正したというのもKubernetesで作成したWordPressをメンターの方にレビューしていただいたことからだったりするのですが、長年エンジニアをやっている方の意見はとても参考になりますし、動作するだけのものを作成するわけではなく、細部にもこだわってアドバイスをいただけるのでとても参考になりました。

今後は、そういった動作以外の部分も重視して構築できるようにするといったところが課題になりそうです。