Docker for Windows で Kubernetes(1)の続き。
**e-Learning OSSの「Irohaboard」**のmanifestを作ってみる。
今回は、以下のような要件にする。
- Irohaboard (Web,PHP)側はスケール可能
- DBはデータベースが1つだが永続的にデータを保持
ざっくりステップ
- Irohaboard の各Dockerイメージを作成
- 各種マニフェスト作成
- デプロイ
ソースはここ。
Dockerイメージ作成
- Irohaboard 本体用(Apache , PHP)
- Irohaboard データベース用(MySQL/Mariadb)
Irohaboard の仕様に合わせてデプロイ、**「http://<your url>/install」**にアクセスしてセットアップを行った後に利用開始できるところまでイメージを作る。
Irohaboard 本体用イメージ
マニフェストに合わせて調整した部分。
セッション情報はデータベースに格納
- テーブルとしてセッションテーブルは作成済みとなるので、向きだけ変える
- デフォルトは'php'であり、php.iniに定義されている保存方式をとる
Configure::write('Session', array(
'defaults' => 'database'
));
database.php の設定
予め設定する必要があるファイルであるが、ほとんどは固定よさそうだったので問題なかったので、以下のみをチューナブルにした。
- MySQL のホスト情報・・・これはマニフェストのサービスリソースから参照させる
- MySQL root パスワード(デフォルト:root)
- テンプレートファイルを作って、ビルド時に値を埋め込む(entrykit利用)
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => true,
'host' => '{{ var "MYSQL_HOST" }}',
'login' => 'root',
'password' => '{{ var "MYSQL_ROOT_PASSWORD" | default "root" }}',
'database' => 'irohaboard',
'prefix' => 'ib_',
'encoding' => 'utf8'
);
}
Dockerfile でビルド時にテンプレートを使ってコンフィグファイルを作れる「entrykit」を使っているので上記のようなファイルを作っている。
Irohaboard データベース用イメージ
Irohaboardでは初めにデータベースを作っておく必要がある。
MySQLのコンテナ( https://hub.docker.com/_/mysql/ )ではイニシャルで指定したデータベースを作ってくれる機能があるが、デフォルトだと推奨文字コードのUTF-8で作られないので、 /docker-entrypoint-initdb.d にSQLファイルを置くパターンにした。
create database irohaboard default character set utf8
FROM mysql:5.7
LABEL maintainer="hoge@example.com"
WORKDIR /tmp
COPY initdb.sql /docker-entrypoint-initdb.d/
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]
docker-entrypoint.sh を編集する、パターンもあるが元の仕組みをイレギュラーに変更するのが気に入らなかった。
Manifest 作成
Docker for Windows(SingleNode)としての注意点が少しあったので、補足。
PV のパス指定
Irohaboard のデータベース用の領域にPersistentVolumes(PV)を使う事にする。VolumeプラグインとしてhostPath使うが、この時のパスの指定は下記のようにした。
path: /host_mnt/c/Users/<user name>/.docker/Volumes/mysql-pv
この時、Docker for Windows ではC:がシェアドライブとして設定する必要がある。シェアされていない場合、PVを作らずPersistentVolumeClaimsにより要求すると、Windows側でポップアップが上がり**C:**ドライブの共有を求められる。
中身をハックしていないけども、manifest (kubernetes)で指定する際には/host_mntにC:がマウントされている
Windows Subsystem for Linux では /mnt/c にマウントされているので、紛らわしい・・・
Ingress
L7のHTTPルーティングにはNGINX Ingress Controllerを使う。
PS> kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml
PS> kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/cloud-generic.yaml
PS> kubectl -n ingress-nginx get service,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/default-http-backend ClusterIP 10.100.83.10 <none> 80/TCP 1d
service/ingress-nginx LoadBalancer 10.99.108.131 localhost 80:30580/TCP,443:32007/TCP 1d
NAME READY STATUS RESTARTS AGE
pod/default-http-backend-7c5bc89cc9-7t2kd 1/1 Running 2 1d
pod/nginx-ingress-controller-5b6864749-ttqnc 1/1 Running 2 1d
Ingress を定義したマニフェストを作る際、
名前ベースのバーチャルホスティング想定時、- host
に使うアドレスとして、Docker for Windowsのホスト上からアクセスするためのちょうど良いのがある。実は、Docker for Windowsインストール時に hosts がアップデートされている。(WSLから/etc/hostsファイルで参照できる)
# This file is automatically generated by WSL based on the Windows hosts file:
# %WINDIR%\System32\drivers\etc\hosts. Modifications to this file will be overwritten.
127.0.0.1 localhost
127.0.1.1 DESKTOP-QVCDBPV.localdomain DESKTOP-QVCDBPV
192.168.0.18 host.docker.internal
192.168.0.18 gateway.docker.internal
見ての通り、「host.docker.internal」と「gateway.docker.internal」があり、これがホストの内部につながるネットワークインタフェースとして形成されてる。これを指定することで、Ingressのテストで利用できる。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: irohaboard
namespace: irohaboard
spec:
rules:
- host: gateway.docker.internal
http:
paths:
- path: /
backend:
serviceName: irohaboard-service
servicePort: 80
Secret
Secretは使わなくてもよかったが、MySQLのパスワードのところだけ利用した。
apiVersion: v1
kind: Secret
metadata:
name: iroha-db-secrets
namespace: irohaboard
type: Opaque
data:
mysqlrootpassword: cm9vdA==
つづく、、、