minikubeのKubernetesでLAMPP環境構築

# 概要
社内のローカル開発環境で使用している、minikubeで構築するKubernetesのLAMPP環境についてご紹介致します。昨今ではKubernetesは珍しい技術ではなく、本番運用で採用されている所も多いと思います。そのため、わざわざローカル環境をKubernetesで構築する必要が無い。というご意見もあるかもしれません・・・ただ、私自身が2年半程この環境で開発を行ってきてメリットを感じているので、もし良ければご参考頂いたり、お役に立てたら幸いだという思いで記事をアップ致しました。
会社では開発環境がWindowsな為minikubeで環境構築致しました。自宅で勉強用に構築した環境もあり、自宅のメインマシンがMacなためmultipass(microk8s)のLAMPP環境も構築しました。元々はWindowsもMacもDocker Desktopだったのですが、昨今大人の事情からWindowsはminikubeへ、Macはmultipass(microk8s)へ移行しました。Macもminikubeを検討しましたが、Macのファイルシステムをminikubeでマウントした際権限やオーナーの設定が思い通りになりませんでした。そこでmultipass(microk8s)で構築し、multipassのファイルシステムをnfsで公開して、Macからそれをマウントする形でKubernetesとMac間のファイル共有を実現しました。なお、WindowsのKubernetesとのファイル共有は、WSL2の機構で実現できたのでminikubeで不自由なく使えています。
なお、PostgreSQLとMySQLの両方のコンテナを含んでいるためLAMPP環境と名打っています。

# 環境要件
＜Windows版＞
◆OS
・Windows10 Pro(x64)
◆ソフトウェア
・minikube v1.23.0
・Ubuntu 20.04 LTS(WSL2)（※１）
・Kubernetes v1.22.1（※２）
・skaffold 0.3.3 （※３）

（※１）WSL2
（※２）記載のバージョンでないと動作しない。minikube start時にバージョン指定する事。
（※３）こちらも記載のバージョンでないと動作しない。skaffoldは以下コマンドでバージョン固定しているので、意識しなくてもこのバージョンが入ります。

◆設定ファイル一式
[Github](https://github.com/take-t14/k8s-lampp-windows) （※４）

＜Mac版＞
◆OS
・Mac OS Big Sur 11.2.2
◆ソフトウェア
・multipass 1.7.0+mac
・multipassd 1.7.0+mac
・Kubernetes v1.21.4（※５）
・skaffold 1.1.0（※６）
・Homebrew 3.2.11

（※５）記載のバージョンでないと動作しない。microk8sのinstall時に「--channel=1.21/stable」を指定する事。
（※６）こちらも記載のバージョンでないと動作しない。skaffoldは以下コマンドでバージョン固定しているので、意識しなくてもこのバージョンが入ります。

◆設定ファイル一式
[Github](https://github.com/take-t14/k8s-lampp-mac) （※４）

（※４）設定ファイルが多いためGithubへアップしました。社内の情報は公開できないので、社内の設定等は仮の値に置き換えました。sslの鍵もブランクのファイルに置き換えているため、この鍵では正常に動作しません。使用される場合は個人の環境で適切なものを入れてください。

# KubernetesのLAMPP環境のメリット・デメリット
## メリット
- minikubeやmultipass(microk8s)のインストールと設定さえすればスクリプト一発で環境構築できる為、チームで同じ環境を横展開しやすい。（※７）
- 環境が壊れてもスクリプト一発実行で再構築できる。（※８）
- インフラ構築の勉強になる
- 本番の運用を想定した複雑なインフラ構築・検証・開発・デバッグが出来る。
- 本番環境とOSやミドルウェアのバージョン等々を極力同じにして検証出来る。ミドルウェアバージョンアップの検証も容易に準備出来る。PHPやPostgreSQL等を複数バージョン構築する事も可能。
- Kubernetesダッシュボードがとても便利で、クラスター全体の構成や状態をリッチで分かりやすいUI（GCPのようなUI）でひと目で把握できる。エラーログもそこで確認可能。
- コンテナイメージの管理・起動・ポート指定等の煩雑で面倒なところを、設定さえしておけばKubernetesが自動でやってくれる。minikubeやmultilass(microk8s)をターミナル起動時に起動するように設定していれば、何もしなくても自動で起動した状態に出来る。
- XAMPPだとファイルパスがWindowsのパスとなります。また、ファイルシステムもNTFSなのでパーミッション、オーナーの設定が出来なかったり、ファイル名の大文字小文字の区別無しだったりと、ファイルシステムによる制限や挙動の違いを生み出します。これがローカルでは動いたけど本番では動かないという問題を発生させがちだが、そうした問題を解決できる。

（※７）スクリプトは要実装。Githubにアップしている「k8s-lampp-all-build.sh」が環境構築用スクリプトとなります
（※８）年一回ぐらいのペースで壊れたりします・・・でもminikubeやmultipass(microk8s)の環境を削除して再構築後、「k8s-lampp-all-build.sh」一発実行で復帰します。
 
## デメリット
- Kubernetesの学習コストが高い。  
- コンテナに向かないソフトウェアの検証には不向き。（大抵は検証可能です。ほんの一部検証に向かないソフトがあったりします。）
- Kubernetesのバージョンをアップデートすると、Kubernetesの変更内容によっては既存の設定ファイルが使えなくなるので容易にアップデートできない。（※９）

（※９）業務に使用する場合はアップデートをして使えなくなると業務に支障があるため、minikube start時にKubernetesのバージョン固定したり、multipass(microk8s)のinstall時にKubernetesのバージョンを固定して運用する。

#やってみての感想
かなり勉強になりました。kubernetesのyamlによる設定や環境のデバッグは慣れるまで大変でしたが、慣れれば好きなようにいじくり回せるようになりました。また、インフラの挙動もとても勉強となりました。nginx→Apache→php-fpmと連携する部分や、php-fpm→postfixとメール送信するところ。また、php-fpmからDBアクセスする部分など、各サーバ同士の連携で色々とつまづきポイントがありましたが、なんとか全てクリアして設定ファイルにまとめることが出来ました。
特に大変だったのは、postgreSQLの永続ボリュームの使用でした。永続ボリュームはWindowsなので、hostPath（Windosのパス）を指定する必要があります。それは問題なく行えたのですが、NTFSの為パーミッションが設定できません（rootの777固定となる）。postgreSQLはrootでは起動できない為、root以外のユーザで起動となります。ところがDB保存先を永続ボリュームとすると、rootの777となっており、権限エラーとなります。回避した方法は、ループバックデバイスを使用しました。isoファイルや仮想OSの仮想ディスクファイル等、ファイルをディスクと見立ててボリュームとして使う技術ですね。Dockerは通常ループバックデバイスは使用禁止となっていますので、yamlでループバックデバイスの使用が許可されるオプション「securityContext: privileged: true」を指定しました。ここに行き着くまでに相当苦労しました・・・ただこの試行錯誤をした際はWSL1時代でして、WSL2のボリュームをマウントすればパーミッション設定が出来るようになってこの問題は解決します。上記「環境要件」のWindows版GithubのKubernetesの設定ファイルは、WSL2のボリュームをマウントしてやっています。これによってisoマウントの機構は必要無くなりました。
あと、メールも地味に苦労しました。postfixで簡単にメールサーバを立てられるのですが、phpからメール送信するにはphpが動作するサーバでsendmailが使えないといけません。ところがphpのコンテナにsendmailやpostfix入れようものなら、systemctlでサービス起動することをDockerは禁止されているため動かせません。どうしたものか・・・と悩んで調べたら、ssmtpという優れものを見つけてそれを試すといけました。ssmtpはsendmail互換のメール送信コマンドを提供してくれるものです。デーモンとして起動していなくても、単発でメール送信時にコマンドを呼び出して動作するので、phpのコンテナからでも問題なく動作してくれました。
コンテナ技術は便利ですが、制約が様々あるので躓きポイントが結構あります。
ですが、一度完成してノウハウがたまると、同じ環境を何度でもどこでもすぐに展開できるのでとても使い勝手はいいです。
今後更に運用を意識して、他のツールと連携したり、CI/CDに組み込んだりできたら面白そうだなと考えています。

# その後の拡張
その後利用しているうちに尾ひれはひれと拡張しました。細かい拡張は汎用的な内容で無いためGithubへアップはしておりません。Supervisorを導入して複数のデーモンプロセスを1つのコンテナに同居させたのですが、なかなか使い勝手が良かったです。phpのメール送信も、SupervisorでPHP-FPMとsendmailを同居させればssmtpを使わなくても行けそうです。PostgreSQLを２つ起動してストリーミングレプリケーションし、Pgpool-Ⅱで負荷分散したりもしました。コンテナに向かないソフトウェアも一部あって検証が難しいケースもありましたが、ほとんどのソフトウェアは動きますし、本番の運用を想定した複雑なインフラ構築・検証もこなせます。  
なお、本番環境でPostgreSQLの負荷分散を行うのであれば、上記のようなPostgreSQLのコンテナを２つ作ってPgpool-Ⅱを導入するよりは、 Crunchy PostgreSQL Operatorや Zalando PostgreSQL Operator、 KubeDBとPgpool-Ⅱを組み合わせた方が良さそうです。（[参考サイトPgpool-II 4.2.4 文書](https://www.pgpool.net/docs/latest/ja/html/example-kubernetes.html)より）

# 参考サイト
[参考サイトPgpool-II 4.2.4 文書](https://www.pgpool.net/docs/latest/ja/html/example-kubernetes.html)