写在前面
在现代网站部署中,容器技术和 Kubernetes 已成为主流选择。本文将介绍如何基于 Kubernetes 快速部署 WordPress,实现应用与数据库的分离管理、自动化扩展和高可用架构。通过实战操作,你将掌握在 K8S 中运行典型 Web 应用的基本流程。
1. 编写deployment的资源清单
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
spec:
## 这里的副本数量先起了一个测试
replicas: 1
## 标签选择器
selector:
matchExpressions:
- key: apps
operator: Exists
template:
metadata:
labels:
apps: mysql
spec:
containers:
- name: mysql
## 镜像:mysql:8.0.32-oracle
image: '192.168.0.77:32237/uat/mysql:8.0.32-oracle'
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: wordpress
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "true"
- name: wordpress
## 镜像:wordpress:6.5.4-apache
image: '192.168.0.77:32237/uat/wordpress:6.5.4-apache'
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: "127.0.0.1:3306"
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: wordpress
- name: WORDPRESS_DB_NAME
value: wordpress
2. 编写service的资源清单
kind: Service
apiVersion: v1
metadata:
name: web
spec:
## 标签选择器要和deployment对应
selector:
apps: mysql
## 这里我为了方便调试选择了nodeport
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
## 暴露的端口号
nodePort: 30082
我们用本地的ip+端口就可以访问了
优化
但是当我们把副本数量>1的时候,我们就会发现一个奇怪的现象就是,当我们不断地刷新页面就会发现我们又会回到注册页面,通俗的来讲就是数据不同步了。
为什么会数据不同步?
每个 Pod 内部都启动一个 MySQL + 一个 WordPress,Pod A 的 WordPress 用的是 Pod A 的 MySQL,Pod B 的 WordPress 用的是 Pod B 的 MySQL,那最终结果就是副本之间各自有一套自己的数据库,所以才会数据不同步。
优化架构:
我们可以用多个副本的WordPress实例来共享一个MySQL 这样就能实现数据同步了,然后我们可以通过nfs 存储将MySQL 的数据目录给挂载出来就可以了。
--- 1. Ubuntu 安装nfs服务端
apt update
apt install -y nfs-kernel-server
--- 2. 创建共享目录并设置共享
mkdir -p /data/nfs
chown nobody:nogroup /data/nfs/
chmod 777 /data/nfs/
--- 3. 配置导出目录
/data/nfs 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash)
## 这里的192.168.0.0 是你的子网ip,可以根据实际情况自行修改
--- 4. 导出配置并启动服务
exportfs -ar
systemctl restart nfs-kernel-server
## 查看状态
exportfs -v
--- 5. 安装客户端测试一下
apt install -y nfs-common
mount 192.168.0.78:/data/nfs /mnt
df -Th |grep mnt
192.168.0.78:/data/nfs nfs4 24G 15G 7.5G 67% /mnt
## 出现以上信息表示成功
umount /mnt
创建共享数据库,注意要在同一个名称空间下
--- deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: worpress-mysql
namespace: wordpress
spec:
replicas: 1
selector:
matchExpressions:
- key: apps
operator: Exists
template:
metadata:
labels:
apps: mysql
spec:
volumes:
- name: data
nfs:
server: 192.168.0.78
path: /data/nfs/mysql
containers:
- name: mysql
image: '192.168.0.77:32237/uat/mysql:8.0.32-oracle'
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: wordpress
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "true"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
--- service
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: wordpress
spec:
selector:
apps: mysql
ports:
- port: 3306
targetPort: 3306
## 这里使用clusteriP来保护数据库
type: ClusterIP
下面我们创建多副本的WordPress
--- deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress
spec:
replicas: 2
selector:
matchExpressions:
- key: apps
operator: Exists
template:
metadata:
labels:
apps: wordpress
spec:
## 这里我们需要将WordPress的存储路径给挂载出来,否则会出现图片上传不了的问题
volumes:
- name: uploads
nfs:
server: 192.168.0.78
path: /data/nfs/wordpress
containers:
- name: wordpress
image: '192.168.0.77:32237/uat/wordpress:6.5.4-apache'
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: mysql
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: wordpress
- name: WORDPRESS_DB_NAME
value: wordpress
volumeMounts:
- name: uploads
mountPath: /var/www/html/wp-content/uploads
评论