概要
Kubernetesの理解を深めるために、以下のKubernetes公式チュートリアルに取り組みました。
https://kubernetes.io/ja/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/
ただ実施するのでは味気ないので、理解が曖昧な箇所は深堀りしながら進めました。
環境
Windows 11
Rancher Desktop:1.8.1
準備
以下の3ファイルを準備します。
- mysql-deployment.yaml
- wordpress-deployment.yaml
- kustomization.yaml
1.mysql-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels: #「labels」という項目は色々な場所に出てくるので注意が必要。ここではKey=app,value=wordpressというラベルをServiceに付与している。
app: wordpress
spec:
ports:
- port: 3306 #Serviceの3306ポートへのアクセスをPodの3306ポートに紐づける。
selector: #ServiceをどのPodと紐づけるかを指定するのがselector。ここではapp: wordpress/tier: mysqlラベルが付与されたPodを紐づけている。
app: wordpress
tier: mysql
clusterIP: None #"None"を指定することで、"Headless"とよばれるServiceになる。Headless Serviceではクラスタ内DNSからPodのIPを取得し、Podに負荷分散する(DNSラウンドロビン)。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce #単一ノードからRead/Writeが可能。
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels: #Deploymentに付与するラベル。
app: wordpress
spec:
selector:
matchLabels: #どのPodをDeploymentの対象とするかを指定する。今回はapp: wordpressとtier: mysqlの2つのラベルを持つPodをDeploymentの対象にしている。
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels: #Podに付与するラベル。spec.selector.matchLabelsと一致している必要がある。
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:8.0
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password #mysql-passというsecretリソースの、passwordというkeyに対応するvalueを取得する
- name: MYSQL_DATABASE
value: wordpress #ここではsecretリソースから取得せず、そのままPWをべた書きしている。
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql #マウント先
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
PVCのマニフェストはあるが、PVが無いのはなぜ?
PVCのマニフェストの中でStorageClassを指定していないため、デフォルトのStorageClassが使われます。
$ kubectl get sc -A
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 81d
local-pathというStorageClassです。クラスター作成時から存在していました。
PROVISIONERがrancher.io/local-pathとなっていて、このProvisionerがPVを自動的にプロビジョニングするので、PVを明示的に作成しなくてもOKのようです。
また、DeploymentのマニフェストにReplicaset数の指定がありませんでした。
この場合、Replicaset数とPod数はどうなるのか、後ほど確認してみます。
2.wordpress-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer #LoadBalancerでは外部疎通性のある仮想IPが払い出されますが、利用できる環境がクラウド環境などに限られるので今回はIPが払い出されません。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:6.2.1-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
- name: WORDPRESS_DB_USER
value: wordpress
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
3.kustomization.yaml
Kustomizeとは、Kubernetesのマニフェスト管理ツールです。
kustomization.yamlという名前のファイルで管理するようです。他の名前は不可。
secretGenerator:
- name: mysql-pass
literals:
- password=<お好きなパスワードを指定>
resources:
- mysql-deployment.yaml
- wordpress-deployment.yaml
リソース作成
用意した3ファイルが存在するディレクトリで実行
$ kubectl apply -k ./
secret/mysql-pass-m9tcmtc8h7 created
service/wordpress created
service/wordpress-mysql created
persistentvolumeclaim/mysql-pv-claim created
persistentvolumeclaim/wp-pv-claim created
deployment.apps/wordpress created
deployment.apps/wordpress-mysql created
リソースが作成されていることを確認していきます。
Secret
$ kubectl get secret
NAME TYPE DATA AGE
mysql-pass-m9tcmtc8h7 Opaque 1 2m15s
PVC
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
wp-pv-claim Bound pvc-4334b6cd-9ace-4938-bbdb-064be1e95f6e 20Gi RWO local-path 5m33s
mysql-pv-claim Bound pvc-f9f14a60-603c-4d67-8f38-17abd603fc0c 20Gi RWO local-path 5m33s
PV
先に述べた通り、PVが自動作成されています。
なお、PVC経由で作成されたPVの名前は「pvc-」から始まります。
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-4334b6cd-9ace-4938-bbdb-064be1e95f6e 20Gi RWO Delete Bound default/wp-pv-claim local-path 5m45s
pvc-f9f14a60-603c-4d67-8f38-17abd603fc0c 20Gi RWO Delete Bound default/mysql-pv-claim local-path 5m45s
Replicaset
Replicaset数はそれぞれ1つずつになっています。
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
wordpress-77f4df4cbc 1 1 1 7m42s
wordpress-mysql-6745f5dc49 1 1 1 7m42s
Pod
Pod数もそれぞれ1つずつになっています。
$ kubectl get pod
NAMESPACE NAME READY STATUS RESTARTS AGE
default wordpress-77f4df4cbc-zkh8p 1/1 Running 0 8m1s
default wordpress-mysql-6745f5dc49-m778z 1/1 Running 0 8m1s
最後にアクセスできるかを確認します。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 74d
wordpress LoadBalancer 10.43.129.204 <pending> 80:30652/TCP 10m
wordpress-mysql ClusterIP None <none> 3306/TCP 10m
wordpress ServiceのPORT(S)が80:30652となっています。
80がLoadBalancerのポートで、30652がノードのポートです。
今回LoadBalancerにはEXTERNAL-IPが割り当てられていない(pending)ため、直接ノードにアクセスすることになります。
ノードのIPは172.27.28.244だったので、URLはhttp://172.27.28.244:30652です。
参考