写在前面

在现代网站部署中,容器技术和 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