minikubeでマルチサービスを立ち上げる(2)
(前回)[https://zenn.dev/tkomatsu/articles/bbb3a4e5f63aae869a74]はnginxのサービスの立ち上げを行いました。
今回はphpMyAdmin, mariaDBを立ち上げます。
ソースコードはこちらです。
mariaDBを立ち上げる
phpMyAdminで使用するため、ノード内で共有するデータベースを構築します。
また、データベースのため、Podが異常終了するような場合でもデータが永続化されるようにしていきます。
Deploymentではなく、StatefulSetを用いることにします。
以下の2つのyamlファイルを作成します。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb
spec:
selector:
matchLabels:
app: mariadb
serviceName: "mariadb"
replicas: 1
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: mariadb:latest
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: rootpass
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wp_user
- name: MYSQL_PASSWORD
value: password
volumeMounts:
- name: mariadb-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mariadb-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
apiVersion: v1
kind: Service
metadata:
name: mariadb
spec:
clusterIP: None
selector:
app: mariadb
ports:
- name: mariadb
port: 3306
StatefulSetのマニフェストは基本的にはDeploymentと共通する項目が多いです。
spec.serviceName
にはStatefulSetと紐付けるServiceの名前を記載します。
spec.volumeClaimTemplates[]
を指定することで、PersistentVolumeを使い安定したストレージを使えるようになります。
mariaDBは(公式イメージ)[https://hub.docker.com/_/mariadb]をそのまま使用しています。
環境変数を利用して、データベースの名前やユーザー名、パスワードなどを指定することができます。
マニフェストで指定するにはspec.template.spec.containers[].env[]
にname
とvalue
を記載します。
Serviceではspec.clusterIP
をNone
に指定しています。
None
にすることでヘッドレスサービスとして起動するようになります。
$ kubectl apply -f mariadb/
service/mariadb created
statefulset.apps/mariadb created
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/mariadb-0 1/1 Running 0 2m32s
pod/nginx-c7d66576c-8kq2b 1/1 Running 0 3m7s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m38s
service/mariadb ClusterIP None <none> 3306/TCP 2m32s
service/nginx LoadBalancer 10.96.224.211 192.168.49.50 80:30888/TCP,443:32666/TCP 3m7s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 3m7s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-c7d66576c 1 1 1 3m7s
NAME READY AGE
statefulset.apps/mariadb 1/1 2m32s
うまく立ち上がっているかコマンドを実行して確認します。
$ kubectl run mysql-client --image=mysql:5.7 -it --rm --restart=Never -- mysql -h mariadb-0.mariadb -u wp_user -ppassword
If you don't see a command prompt, try pressing enter.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| wordpress |
+--------------------+
2 rows in set (0.00 sec)
mysql>
$MYSQL_USER
、$MYSQL_PASSWORD
でmysqlを実行し、データベースが作成されていることを確認します。
phpMyAdminをたちあげる
mariaDBサーバーにアクセスできるphpMyAdminを立ち上げていきます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: phpmyadmin
labels:
app: phpmyadmin
spec:
replicas: 1
selector:
matchLabels:
app: phpmyadmin
template:
metadata:
name: phpmyadmin
spec:
containers:
- name: phpmyadmin
image: phpmyadmin:latest
ports:
- containerPort: 5000
env:
- name: PMA_USER
value: wp_user
- name: PMA_PASSWORD
value: password
- name: PMA_HOST
value: mariadb-0.mariadb
このままでも問題ないのですが、mariaDBで設定したユーザー名とパスワードが再び登場しています。
複数のマニフェストにまたがる設定をまとめるためにConfigMapが使用できます。
MetalLBの時にも使用していますね。
ただ、ConfigMapだとパスワードなどのセンシティブなものが平打ちされてしまうので、ここではSecretというものを使用します。
Secretの作成方法はいくつかあるのですが、今回はyamlファイルで作成することにします。
apiVersion: v1
kind: Secret
metadata:
name: mini-secret
type: Opaque
stringData:
mysql_root_password: rootpass
db_name: wordpress
db_user: wp_user
db_password: password
yamlファイルで作る場合は、エンコード済のものを記載する方法(data
)とエンコードなしの文字列を記載する方法(stringData
)があり、今回は内容を確認しやすいよう後者を採用しました。
data
を使う場合は、Base64でエンコードしたものを記載してください。
secretを作成したので、mariaDBとphpMyAdminのyamlファイルを以下のように書き換えます。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb
spec:
serviceName: "mariadb"
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: mariadb:latest
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mini-secret
key: mysql_root_passowrd
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: mini-secret
key: db_name
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mini-secret
key: db_user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mini-secret
key: db_password
volumeMounts:
- name: mariadb-data
mountPath: /var/lib/mysql
replicas: 1
volumeClaimTemplates:
- metadata:
name: mariadb-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: phpmyadmin
labels:
app: phpmyadmin
spec:
replicas: 1
selector:
matchLabels:
app: phpmyadmin
template:
metadata:
labels:
app: phpmyadmin
spec:
containers:
- name: phpmyadmin
image: phpmyadmin
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
env:
- name: PMA_USER
valueFrom:
secretKeyRef:
name: mini-secret
key: db_user
- name: PMA_PASSWORD
valueFrom:
secretKeyRef:
name: mini-secret
key: db_password
- name: PMA_HOST
value: mariadb-0.mariadb
phpMyAdminのServiceも併せて立ち上げましょう。
apiVersion: v1
kind: Service
metadata:
name: phpmyadmin
spec:
selector:
app: phpmyadmin
type: ClusterIP
ports:
- name: http
port: 80
- name: https
port: 443
これまで作成したマニフェストをKubernetesに反映させていきましょう。
kubectl apply -f <manifest file>
正しく設定できていれば、下記のようになっているはずです。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/mariadb-0 1/1 Running 0 7m26s
pod/nginx-c7d66576c-sbml5 1/1 Running 1 7m27s
pod/phpmyadmin-797f98c4b6-vfds2 1/1 Running 0 7m25s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7m53s
service/mariadb ClusterIP None <none> 3306/TCP 7m25s
service/nginx LoadBalancer 10.105.38.183 192.168.49.50 80:31869/TCP,443:30009/TCP 7m26s
service/phpmyadmin ClusterIP 10.105.200.23 <none> 80/TCP,443/TCP 7m25s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 7m27s
deployment.apps/phpmyadmin 1/1 1 1 7m25s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-c7d66576c 1 1 1 7m27s
replicaset.apps/phpmyadmin-797f98c4b6 1 1 1 7m25s
NAME READY AGE
statefulset.apps/mariadb 1/1 7m26s
このままではphpMyAdminに外部からアクセスできないので、nginxからリバースプロキシで接続するように設定します。
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
root /usr/share/nginx/html;
index index.html;
location /phpmyadmin/ {
rewrite ^/phpmyadmin(.*)$ $1 break;
proxy_redirect / /phpmyadmin/;
proxy_pass http://phpmyadmin:80;
}
location / {
try_files $uri $uri/ =404;
}
}
再度、コンテナをビルドして反映させてください。
以上でphpMyAdminの立ち上げが完了しました。
ブラウザで確認してみましょう。
終わりに
今回は以下のオブジェクトの実装を行いました。より詳しく知りたい場合は公式APIリファレンスを参照してください。
- StatefulSet
- Secret
さらに複数のService間接続を確認し、Serviceオブジェクトの有効性を確認しました。
次回はWordpressの実装を行っていきます。
Discussion