示例:使用持久卷部署 WordPress 和 MySQL

本教程演示如何使用 Minikube 部署 WordPress 站点和 MySQL 数据库。这两个应用程序都使用 PersistentVolume 和 PersistentVolumeClaim 来存储数据。

PersistentVolume (PV) 是集群中由管理员手动或 Kubernetes 使用 StorageClass 动态提供的存储。 PersistentVolumeClaim (PVC) 是用户对存储的请求,可以由 PV 来满足。PersistentVolume 和 PersistentVolumeClaim 独立于 Pod 生命周期,并通过 Pod 的重启、重新调度甚至删除来保留数据。

目标

  • 创建 PersistentVolumeClaim 和 PersistentVolume
  • 使用以下内容创建 kustomization.yaml
    • 一个 Secret 生成器
    • MySQL 资源配置
    • WordPress 资源配置
  • 通过 kubectl apply -k ./ 应用 kustomization 目录
  • 清理

准备工作

你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用这些 Kubernetes 游乐场之一:

要检查版本,请输入 kubectl version

本页所示示例适用于 kubectl 1.27 及更高版本。

下载以下配置文件

  1. mysql-deployment.yaml

  2. wordpress-deployment.yaml

创建 PersistentVolumeClaim 和 PersistentVolume

MySQL 和 WordPress 各自需要一个 PersistentVolume 来存储数据。它们的 PersistentVolumeClaim 将在部署步骤中创建。

许多集群环境都安装了默认的 StorageClass。当 PersistentVolumeClaim 中未指定 StorageClass 时,将使用集群的默认 StorageClass。

创建 PersistentVolumeClaim 时,会根据 StorageClass 配置动态提供 PersistentVolume。

创建 kustomization.yaml

添加 Secret 生成器

Secret 是一个存储敏感数据(如密码或密钥)的对象。自 1.14 版本起,kubectl 支持使用 kustomization 文件管理 Kubernetes 对象。你可以通过 kustomization.yaml 中的生成器创建 Secret。

从以下命令在 kustomization.yaml 中添加 Secret 生成器。你需要将 YOUR_PASSWORD 替换为你想要使用的密码。

cat <<EOF >./kustomization.yaml
secretGenerator:
- name: mysql-pass
  literals:
  - password=YOUR_PASSWORD
EOF

为 MySQL 和 WordPress 添加资源配置

以下清单描述了一个单实例 MySQL Deployment。MySQL 容器将 PersistentVolume 挂载到 /var/lib/mysql。MYSQL_ROOT_PASSWORD 环境变量从 Secret 设置数据库密码。

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:8.0
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        - name: MYSQL_DATABASE
          value: wordpress
        - 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

以下清单描述了一个单实例 WordPress Deployment。WordPress 容器将 PersistentVolume 挂载到 /var/www/html 以存放网站数据文件。 WORDPRESS_DB_HOST 环境变量设置上面定义的 MySQL Service 的名称,WordPress 将通过 Service 访问数据库。 WORDPRESS_DB_PASSWORD 环境变量设置由 kustomize 生成的 Secret 中的数据库密码。

apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer
---
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
  1. 下载 MySQL 部署配置文件。

    curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml
    
  2. 下载 WordPress 配置文件。

    curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml
    
  3. 将它们添加到 kustomization.yaml 文件中。

    cat <<EOF >>./kustomization.yaml
    resources:
      - mysql-deployment.yaml
      - wordpress-deployment.yaml
    EOF
    

应用并验证

kustomization.yaml 包含了部署 WordPress 站点和 MySQL 数据库所需的所有资源。你可以通过以下方式应用该目录:

kubectl apply -k ./

现在你可以验证所有对象是否存在。

  1. 通过运行以下命令验证 Secret 是否存在

    kubectl get secrets
    

    响应应如下所示:

    NAME                    TYPE                                  DATA   AGE
    mysql-pass-c57bb4t7mf   Opaque                                1      9s
    
  2. 验证 PersistentVolume 是否已动态提供。

    kubectl get pvc
    

    响应应如下所示:

    NAME             STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
    mysql-pv-claim   Bound     pvc-8cbd7b2e-4044-11e9-b2bb-42010a800002   20Gi       RWO            standard           77s
    wp-pv-claim      Bound     pvc-8cd0df54-4044-11e9-b2bb-42010a800002   20Gi       RWO            standard           77s
    
  3. 通过运行以下命令验证 Pod 是否正在运行

    kubectl get pods
    

    响应应如下所示:

    NAME                               READY     STATUS    RESTARTS   AGE
    wordpress-mysql-1894417608-x5dzt   1/1       Running   0          40s
    
  4. 通过运行以下命令验证 Service 是否正在运行

    kubectl get services wordpress
    

    响应应如下所示:

    NAME        TYPE            CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    wordpress   LoadBalancer    10.0.0.89    <pending>     80:32406/TCP   4m
    
  5. 运行以下命令获取 WordPress Service 的 IP 地址

    minikube service wordpress --url
    

    响应应如下所示:

    http://1.2.3.4:32406
    
  6. 复制 IP 地址,然后在浏览器中加载该页面以查看你的站点。

    你应该会看到类似于以下截图的 WordPress 设置页面。

    wordpress-init

清理

  1. 运行以下命令删除你的 Secret、Deployment、Service 和 PersistentVolumeClaim:

    kubectl delete -k ./
    

下一步

最后修改于 2023 年 8 月 24 日下午 6:38 PST:使用 code_sample 简码代替 code 简码 (e8b136c3b3)