有状态服务
Mysql WordPress Persistent Volume

Example: Deploying WordPress and MySQL with Persistent Volumes

本教程向你展示如何使用 Minikube 部署一个 WordPress 站点和一个 MySQL 数据库。

这两个应用程序都使用持久卷(PersistentVolumes)和持久卷声明(PersistentVolumeClaims)来存储数据。

持久卷(PV)是集群中的一块存储,它可以由管理员手动配置,也可以由 Kubernetes 使用存储类(StorageClass)动态配置。

持久卷声明(PVC)是用户对存储的请求,该请求可由一个持久卷来满足。

持久卷和持久卷声明独立于 Pod 的生命周期,并且在 Pod 重启、重新调度甚至删除的过程中都能保留数据。

💡

警告: 此部署不适用于生产环境的使用场景,因为它使用的是单实例的 WordPress 和 MySQL Pod。 在生产环境中部署 WordPress 时,建议考虑使用 WordPress 的 Helm Chart。

💡

注意: 本教程中提供的文件使用的是稳定版(GA)的部署 API,并且专门适用于 Kubernetes 1.9 及更高版本。 如果你希望在更早版本的 Kubernetes 上使用本教程,请相应地更新 API 版本,或者参考本教程的早期版本。

Objectives

💡
  • 创建持久卷声明(PersistentVolumeClaims)和持久卷(PersistentVolumes)
  • 创建一个 kustomization.yaml 文件,其中包含:
    • 一个 Secret 生成器
    • MySQL 资源配置
    • WordPress 资源配置
  • 使用 kubectl apply -k ./ 命令应用 kustomization 目录
  • 进行清理操作

Before you begin

你必须拥有一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为可与你的集群进行通信。建议在至少有两个并非用作控制平面主机的节点的集群上运行本教程。

要检查版本,输入 kubectl version 即可。

本页面展示的示例适用于 kubectl 1.27 版本及以上版本。

请下载以下配置文件:

- mysql-deployment.yaml
- wordpress-deployment.yaml

Create PersistentVolumeClaims and PersistentVolumes

MySQL 和 WordPress 各自都需要一个持久卷(PersistentVolume)来存储数据。它们的持久卷声明(PersistentVolumeClaims)将在部署步骤中创建。

许多集群环境都安装有默认的存储类(StorageClass)。当在持久卷声明中未指定存储类时,集群会转而使用默认的存储类。

当创建一个持久卷声明时,会根据存储类的配置动态地配置一个持久卷。

💡

警告: 在本地集群中,默认的存储类使用 hostPath 配置器。hostPath 卷仅适用于开发和测试场景。对于 hostPath 卷,数据存储在 Pod 所调度到的节点的 /tmp 目录下,并且不会在节点之间移动。如果一个 Pod 发生故障并被重新调度到集群中的另一个节点上,或者该节点重启,那么数据将会丢失。

💡

注意: 如果你要搭建一个需要使用 hostPath 配置器的集群,那么必须在控制器管理器(controller-manager)组件中设置 --enable-hostpath-provisioner 标志。

💡

注意: 如果你运行的 Kubernetes 集群是在 Google Kubernetes 引擎(Google Kubernetes Engine)上,请遵循本指南。

Create a kustomization.yaml

Add a Secret generator

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

Add resource configs for MySQL and WordPress

以下清单描述了一个单实例的 MySQL 部署。MySQL 容器会将持久卷挂载到 /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 部署。WordPress 容器会将持久卷挂载到 /var/www/html 路径,用于存放网站数据文件。WORDPRESS_DB_HOST 环境变量会设置为上述定义的 MySQL 服务的名称,WordPress 将通过该服务来访问数据库。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.D下载 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

Apply and Verify

kustomization.yaml 文件包含了部署一个 WordPress 站点和一个 MySQL 数据库所需的所有资源。你可以通过以下命令来应用该目录:

kubectl apply -k ./

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

可以通过运行以下命令来验证 Secret 是否存在:

kubectl get secrets

响应内容如下类似:

NAME                    TYPE                                  DATA   AGE
mysql-pass-c57bb4t7mf   Opaque                                1      9s

要验证持久卷(PersistentVolume,PV)是否已动态配置:

kubectl get pvc
💡

注意: 持久卷(PV)的配置和绑定可能最长需要花费几分钟的时间。

响应内容如下类似:

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

通过运行以下命令来验证 Pod 是否正在运行:

kubectl get pods
💡

注意: Pod 的状态变为 “正在运行(RUNNING)” 可能最长需要花费几分钟的时间。

响应内容如下类似:

NAME                               READY     STATUS    RESTARTS   AGE
wordpress-mysql-1894417608-x5dzt   1/1       Running   0          40s

通过运行以下命令来验证 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
💡

注意: Minikube 仅能通过节点端口(NodePort)来暴露服务。其外部 IP(EXTERNAL-IP)始终会处于 “等待(pending)” 状态。

通过运行以下命令获取 Service 的IP地址:

minikube service wordpress --url

响应内容如下类似:

http://1.2.3.4:3240

复制该 IP 地址,然后在你的浏览器中加载该页面以查看你的网站。

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

wordpress-init
💡

Warning: 不要让你的 WordPress 安装停留在这个页面上。如果其他用户发现了它,他们可以在你的实例上设置一个网站,并利用它来提供恶意内容。

要么通过创建用户名和密码来完成 WordPress 的安装,要么删除你的实例。

Cleaning up

运行以下命令以删除你的 Secret、Deployment、Service 和持久卷声明(PersistentVolumeClaim):

kubectl delete -k ./