こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
今回はWordpress+MySQL環境をGKE上に構築するにあたり、ConfigMapだけではなくSecretをも用いてみたいと思います。
今までの記事は以下を参照ください。
構築する環境
以下が今までに構築した環境です。
ConfigMapを用いて、環境変数をpodに設定しておりました。
今回はConfigMapだけではなくSecretも使用しpodに環境変数をアタッチしていきたいと思います。ConfigMapを使用すると環境変数をpodやdeployment等から分離して扱うことが出来、柔軟性が向上するのですが、暗号化しないでそのままのデータとして管理されるためセキュリティの面で不安が残ります。Secretはbase64でエンコードされたデータを扱うのでセキュリティの面をある程度払拭することが出来ます。(個人的には気休め位だと思いますが。。。)
用意したファイル一覧
wordpress-pod.yaml
前回とほぼ差分は無いですが、spec.containers.envFromの配下にsecretRef欄を追加しています。
この欄でこのpodが使用するSecretを指定しています。ConfigMapとの併用も可能です。
apiVersion: v1
kind: Pod
metadata:
name: wordpress-pod
labels:
app: wordpress
spec:
containers:
- name: wordpress-con
image: wordpress:php8.1-apache
ports:
- containerPort : 80
envFrom:
- configMapRef:
name: wp-cm
- secretRef:
name: wp-sec
wordpress-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: wp-cm
data:
WORDPRESS_DB_HOST: mysql-clusterip
WORDPRESS_DB_NAME : gke-wordpress-database
WORDPRESS_DB_USER : devuser
wordpress-secret.yaml
今回の主テーマとなるSecretファイルです。
"cGFzc3dvcmQK"という文字列は"password"という文字列をbase64でエンコードしたものになります。この辺りは後程。書きっぷりはConfigMapと同じです。
apiVersion: v1
kind: Secret
metadata:
name: wp-sec
data:
WORDPRESS_DB_PASSWORD : cGFzc3dvcmQK
wordpress-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-loadbalancer
spec:
type: LoadBalancer
selector:
app: wordpress
ports:
- protocol: TCP
port: 60000
targetPort: 80
mysql-pod.yaml
これもwordpress-pod.yamlと同じです。
spec.containers.envFromの配下にsecretRef欄を追加しています。
この欄でこのpodが使用するSecretを指定しています。
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
labels:
app: mysql
spec:
containers:
- name: mysql-con
image: mysql:8.0-debian
ports:
- containerPort: 3306
envFrom:
- configMapRef:
name: mysql-cm
- secretRef:
name: mysql-sec
mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-cm
data:
MYSQL_DATABASE : gke-wordpress-database
MYSQL_USER : devuser
MYSQL_ROOT_PASSWORD : password
mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-sec
data:
MYSQL_PASSWORD : cGFzc3dvcmQK
mysql-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-clusterip
spec:
selector:
app: mysql
type: ClusterIP
ports:
- name: mysql
port: 3306
protocol: TCP
targetPort: 3306
構築
コマンドのログは残しておりませんが、それぞれのyamlファイルを"kubectl apply -f (yaml)"でデプロイします。
私の環境下では、デプロイ結果は以下となりました。
$ kubectl get pod,svc,cm,secret -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/mysql-pod 1/1 Running 0 3m23s 10.112.0.130 gk3-my-pool-1-8d22bf08-r8mk <none> <none>
pod/wordpress-pod 1/1 Running 0 3m8s 10.112.0.131 gk3-my-pool-1-8d22bf08-r8mk <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.112.128.1 <none> 443/TCP 9m56s <none>
service/mysql-clusterip ClusterIP 10.112.130.3 <none> 3306/TCP 3m18s app=mysql
service/wordpress-loadbalancer LoadBalancer 10.112.128.108 34.170.136.140 60000:32700/TCP 2m49s app=wordpress
NAME DATA AGE
configmap/kube-root-ca.crt 1 9m7s
configmap/mysql-cm 3 3m29s
configmap/wp-cm 3 2m56s
NAME TYPE DATA AGE
secret/mysql-sec Opaque 1 3m43s
secret/wp-sec Opaque 1 3m1s
LoadBalancerにアタッチされるEXTERNAL-IPとポート番号を指定してWebブラウザでアクセスしてみます。
結果として以下の通り、問題無くアクセス出来ました。
余談
Secretファイルにbase64でエンコードしたデータを格納しましたが、エンコードの仕方ですが以下の様にコマンドを実行すればOKです。echoコマンドの引数にbase64でエンコードしたい文字列を入力して、それをbase64にパイプで引き渡します。出力されたデータをSecretのyamlファイルに入力します。
$ echo password | base64
cGFzc3dvcmQK
base64でエンコードしていない文字列をSecretのyamlに入力し、そのyamlを元に出プ下ろい仕様とすると以下の様なエラーを吐きます。
$ kubectl apply -f wordpress-secret.yaml
Error from server (BadRequest): error when creating "wordpress-secret.yaml": Secret in version "v1" cannot be handled as a Secret: illegal base64 data at input byte 4
$ kubectl apply -f mysql-secret.yaml
Error from server (BadRequest): error when creating "mysql-secret.yaml": Secret in version "v1" cannot be handled as a Secret: illegal base64 data at input byte 4
secretをdescribeすることも出来ます。
ConfigMapだと内部のデータを閲覧することが出来ましたが、Secretだとdescribeをしても中身を確認することは出来ません。
$ kubectl describe secret wordpress-secret
Name: wordpress-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
WORDPRESS_DB_PASSWORD: 9 bytes
また、Secretに環境変数を設定しまうことでpodが上手く作成されない事例が確認出来ました。
今回の私の場合、MySQLのpodの環境変数MYSQL_ROOT_PASSWORDの値をSecretで扱うとpodがrunningになったりcrashしたりerrorになったりしました。
もし、上手くpodがデプロイ出来なくなったりしましたら、Secretを疑ってみても良いかもと思いました。