前言
上个实验2.3 – PV & PVC,我们将wordpress+mysql的Deployment绑定PVC,并成功将mysql的数据保存才PV存储卷上。
但是mysql作为数据库应用,当水平扩展后,就是多个独立的数据库实例,数据彼此分离,导致应用在多个实例间的状态不一致,那么这个问题如何解决呢?
答案就是将mysql与wordpress进行分离,我们把wordpress看做一个支持水平扩展的无状态应用,多个wordpress连接同一个mysql数据库。
那么wordpress又如何找到对应的mysql数据库呢?答案就是通过Service
场景
将wordpress与mysql分离成两个Deployment,并为mysql定义Service,wordpress通过ServiceName发现mysql的实例信息,mysql的Deployment使用PVC保存数据状态,完成后wordpress可以水平扩展为多个实例,并且能够保证数据一致性
本文实验所有的源码保存在:
https://github.com/zrbcool/blog-public/tree/master/k8s-hands-on/lab07
实战
对Deployment进行分离
先准备好PVC及PV
lab07 git:(master) kubectl apply -f 01-1-mysql-pvc.yaml
persistentvolumeclaim/wordpress-mysql-pv-claim created
lab07 git:(master) kubectl apply -f 01-2-mysql-pv.yaml
persistentvolume/wordpress-mysql-pv-volume created
lab07 git:(master) kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
wordpress-mysql-pv-claim Bound wordpress-mysql-pv-volume 2Gi RWO 15s
为mysql创建Deployment
lab07 git:(master) cat 01-3-mysql-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: wordpress
type: mysql
name: wordpress-mysql
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
type: mysql
template:
metadata:
labels:
app: wordpress
type: mysql
spec:
containers:
- image: mysql:5.7.26
imagePullPolicy: IfNotPresent
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "passw0rd"
- name: MYSQL_DATABASE
value: "wordpress"
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: wordpress-mysql-pv-claim
lab07 git:(master) kubectl apply -f 01-3-mysql-deployment.yaml
deployment.extensions/wordpress-mysql created
# 这里可以简单测试一下
为mysql创建Service
lab07 git:(master) cat 01-4-mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql-svc
labels:
app: wordpress
type: mysql
spec:
ports:
- port: 3306
protocol: TCP
targetPort: 3306
selector:
app: wordpress
type: mysql
lab07 git:(master) kubectl apply -f 01-4-mysql-svc.yaml
service/wordpress-mysql-svc created
lab07 git:(master) kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
wordpress-mysql-svc ClusterIP 10.98.45.79 <none> 3306/TCP 9s app=wordpress,type=mysql
我们来测试下这个Service是否work,
lab07 git:(master) kubectl run -it --rm --image=mysql:5.7.26 --restart=Never mysql-client -- mysql -h wordpress-mysql-svc -ppassw0rd
If you don't see a command prompt, try pressing enter.
mysql> use wordpress
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
12 rows in set (0.00 sec)
为wordpress创建Deployment
lab07 git:(master) cat 02-1-wordpress-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: wordpress
type: wordpress
name: wordpress-wp
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
type: wordpress
template:
metadata:
labels:
app: wordpress
type: wordpress
spec:
containers:
- image: wordpress:latest
imagePullPolicy: IfNotPresent
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: "wordpress-mysql-svc"
- name: WORDPRESS_DB_USER
value: "root"
- name: WORDPRESS_DB_PASSWORD
value: "passw0rd"
需要注意到wordpress连接的数据库信息已经不再是127.0.0.1了,而是"wordpress-mysql-svc",这样wordpress的Pod就可以通过ServiceName连接到mysql了,我们来试试
lab07 git:(master) kubectl apply -f 02-1-wordpress-deployment.yaml
deployment.extensions/wordpress-wp created
ne>
lab07 git:(master) kubectl get pods
NAME READY STATUS RESTARTS AGE
wordpress-mysql-66df4d4dd6-gwjsx 1/1 Running 0 19m
wordpress-wp-66ffcc84c5-tgbsc 1/1 Running 0 55s
使用NodePort类型的Service暴露wordpress,我们来测试一下:
lab07 git:(master) cat 02-2-wordpress-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
labels:
app: wordpress
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30611
selector:
app: wordpress
type: NodePort
lab07 git:(master) kubectl apply -f 02-2-wordpress-svc.yaml
service/wordpress-svc created
测试OK,可以正常访问,我们来对wordpress的Pod进行扩容,
lab07 git:(master) kubectl scale --replicas=5 deploy/wordpress-wp
deployment.extensions/wordpress-wp scaled
lab07 git:(master) kubectl get pods
NAME READY STATUS RESTARTS AGE
wordpress-mysql-66df4d4dd6-gwjsx 1/1 Running 0 23m
wordpress-wp-66ffcc84c5-76tsh 1/1 Running 0 41s
wordpress-wp-66ffcc84c5-c4r4q 1/1 Running 0 41s
wordpress-wp-66ffcc84c5-qrv2r 1/1 Running 0 41s
wordpress-wp-66ffcc84c5-tgbsc 1/1 Running 0 5m24s
wordpress-wp-66ffcc84c5-w24sv 1/1 Running 0 41s
多次访问网页,发现已经状态一致,所有请求均由一个数据库处理,完成任务!
清除数据
lab07 git:(master) kubectl delete -f .
persistentvolumeclaim "wordpress-mysql-pv-claim" deleted
persistentvolume "wordpress-mysql-pv-volume" deleted
deployment.extensions "wordpress-mysql" deleted
service "wordpress-mysql-svc" deleted
deployment.extensions "wordpress-wp" deleted
service "wordpress-svc" deleted
更多参考
https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/