MySQL の管理用 GUI ツール Adminer を Kubernetes に設置
MySQL データベースの中身を確認するにあたって、ちょっとした簡単な操作ならば CLI で済ませてしまいますが、いろいろなパターンで操作したい場合には GUI の管理画面を使いたくなります。
phpMyAdmin や Adminer といったツールがあり、目的に対してはどちらでも構わないと思いますが、ここでは Adminer をさっさとセットアップして利用する手順(カンペ)を記載します。
- Adminer - Database management in a single PHP file ― https://www.adminer.org/
- phpMyAdmin ― https://www.phpmyadmin.net/
以下の3パターンを説明します。
- Adminer だけを Kubernetes 上にデプロイする場合
- Adminer を GCP の CloudSQL で使う前提で Kubernetes へデプロイする場合
- 【参考】ローカルでの確認用に Docker Compose で起動する場合
Kubernetes デプロイの方針
通常 Kubernetes 上に何かをデプロイしてサービスとして利用可能にするためには Deployment (Pod)、Service、および Ingress あたりを構築することになります。
しかし MySQL 管理画面という性質上、セキュリティ的にはこれらサービスは一般公開したくないので何かしらのアクセス制限をかけるべきでしょう。そうなると、IPアドレスでの制限あるいは認証による制限などを準備するわけですが、IPアドレスが変わったり、パスワードの記録といった面倒くさい運用が発生してしまいます。
となると、一番手っ取り早いのは一般公開しなければいいわけですね。
そこで、「デプロイするのは Pod のみとし、使いたい時に Pod に対して Port-forward して接続する」という運用で済ませることにします。この手法だと kubectl
を使えることが前提になるので大人数向けではありませんが、利用者がエンジニアあるいは個人に限られる場合にはセキュリティリスクおよび運用負担を最小限に抑えられます。
ポートフォワードに関するドキュメントはこちら
Use Port Forwarding to Access Applications in a Cluster | Kubernetes ― https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/#forward-a-local-port-to-a-port-on-the-pod
Adminer だけをデプロイする場合
変数も必要ありませんし、非常に楽です。接続先DBの指定は Web 画面上から行えますので、ネットワークの到達性があれば任意の場所に接続可能です。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: adminer
namespace: my-namespace
spec:
replicas: 1
selector:
matchLabels:
app: adminer
template:
metadata:
labels:
app: adminer
spec:
containers:
# CONTAINER: 1
- name: app
image: adminer
ports:
- containerPort: 8080
Adminer から CloudSQL を使う構成でデプロイする場合
参考に CloudSQL に接続するための SQL Proxy を使った構成も記載します。
変数の準備
CLOUDSQL_INSTANCE_NAME
- SQL Proxy の command で指定している
-instances=$(CLOUDSQL_INSTANCE_NAME)
のために環境変数を設定します。 - コンフィグを Git で共有することを前提に固有値を外部化していますが、コマンド内に値をベタ書きするのでも構いません。その場合は環境変数の準備を省略可能です。
- もちろん ConfigMap あるいは Secret のマニフェストを用意して設定するでも構いません。
- SQL Proxy の command で指定している
さて、環境変数をセットします。
eval "kubectl -n my-namespace create secret generic cloudsql-credentials --from-literal=CLOUDSQL_INSTANCE_NAME=project-name-012345:us-region:mysql-instance=tcp:3306"
ちょっと分解すると、やっていることは以下の通り
kubectl -n my-namespace
- namespace を指定している
create secret generic cloudsql-instance-secrets
- cloudsql-credentials という名前で Secret (秘匿パラメタ)を作成している
--from-literal=CLOUDSQL_INSTANCE_NAME=project-name-012345:us-region:mysql-instance=tcp:3306"
- 今回はコマンドからベタで作成してしまうので、
--from-literal
を利用して環境変数を key=value で指定 project-name-012345:us-region:mysql-instance=tcp:3306
の部分は、コロン区切りで以下の要素に分解されています。GCP 上の Cloud SQL のダッシュボードにて「接続名」としてコピペ可能になっているはずなのでその値をそのまま当てはめてください- GCPプロジェクト名
- リージョン
- CloudSQL インスタンス名
- ポート番号
- 今回はコマンドからベタで作成してしまうので、
Deployment の準備
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: adminer
namespace: my-namespace
spec:
replicas: 1
selector:
matchLabels:
app: adminer
template:
metadata:
labels:
app: adminer
spec:
containers:
# CONTAINER: 1
- name: app
image: adminer
ports:
- containerPort: 8080
# CONTAINER: 2
- name: cloudsql
image: gcr.io/cloudsql-docker/gce-proxy:1.28.1
imagePullPolicy: IfNotPresent
command:
- "/cloud_sql_proxy"
- "-instances=$(CLOUDSQL_INSTANCE_NAME)"
- "-credential_file=/credentials/credentials.json"
securityContext:
runAsUser: 2 # non-root user
allowPrivilegeEscalation: false
envFrom:
- secretRef:
name: cloudsql-instance-secrets
volumeMounts:
- mountPath: /cloudsql
name: cloudsql
- mountPath: /credentials
name: cloudsql-credentials
volumes:
- name: cloudsql
emptyDir: {}
- name: cloudsql-credentials
secret:
secretName: cloudsql-credentials
CloudSQL Proxy の最新バージョンは以下にて確認してください。
GoogleCloudPlatform/cloudsql-proxy: Cloud SQL proxy client and Go library ― https://github.com/GoogleCloudPlatform/cloudsql-proxy
Port forward での接続方法
ここまで、Kubernetes へのデプロイ方法を2種類説明しました。いずれも Deployment しか利用していませんので、 Pod だけが立ち上がっている状況です。Pod は次のコマンドで確認してみましょう。
kubectl -n my-namespace get pod
---
NAME READY STATUS RESTARTS AGE
adminer-79fa8edc8c-6pa7e 2/2 Running 0 1d15h
Pod が見えたらその名前を控えます。( adminer-7xxxxx-6xxxx
)
# Podの名前を入れること
kubectl -n my-namespace port-forward adminer-7xxxxx-6xxxx 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
このように Forwarding 状態になれば、あとはブラウザで http://localhost:8080 に接続できるはずです。
ローカルで確認する場合(Docker Compose)
- Docker で MySQL を起動する
- その MySQL に対して Adminer で接続して操作したい
これらを実現する構成( docker-compose.yml
)は以下の通り。お手軽すぎるので新規に MySQL を利用するプロジェクトはとりあえずコピペで開始できます。
version: "3.3"
services:
mysql:
image: mysql:5.7
ports:
- 3306:3306
volumes:
- "./tmp/volumes/mysql:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: password
adminer:
image: adminer
restart: always
ports:
- 8080:8080
depends_on:
- mysql
- version を 3.3 としていますが絶対的な理由があるものではありません。適用可能なバージョンは以下のURLを参考にしてください。ただ、この程度の構成であればルーズでも問題ないかと。
- Compose ファイル | Docker ドキュメント ― https://matsuand.github.io/docs.docker.jp.onthefly/compose/compose-file/
- この例では docker-compose.yml ファイルが配置されている場所の tmp/ ディレクトリにMySQLデータベースのファイル群を配置しています。試して気に入らなければ tmp/volumes を削除すれば改めて再セットアップできるのでお手軽です。
まとめ
MySQL の Web GUI 管理ツールである Adminer をセットアップする方法を3例記載しました。
効率がいいときは素直に GUI を使うといいなと改めて感じました。