示例:使用 Persistent Volumes 部署 WordPress 和 MySQL

本示例描述了如何通过 Minikube 在 Kubernetes 上安装 WordPress 和 MySQL。这两个应用都使用 PersistentVolumes 和 PersistentVolumeClaims 保存数据。

PersistentVolume(PV)是一块集群里由管理员手动提供,或 kubernetes 通过 StorageClass 动态创建的存储。 PersistentVolumeClaim(PVC)是一个满足对 PV 存储需要的请求。PersistentVolumes 和 PersistentVolumeClaims 是独立于 Pod 生命周期而在 Pod 重启,重新调度甚至删除过程中保存数据。

警告:

deployment 在生产场景中并不适合,它使用单实例 WordPress 和 MySQL Pods。考虑使用 WordPress Helm Chart 在生产场景中部署 WordPress。

说明:

本教程中提供的文件使用 GA Deployment API,并且特定于 kubernetes 1.9 或更高版本。如果您希望将本教程与 Kubernetes 的早期版本一起使用,请相应地更新 API 版本,或参考本教程的早期版本。

教程目标

  • 创建 PersistentVolumeClaims 和 PersistentVolumes
  • 创建 kustomization.yaml 使用
    • Secret 生成器
    • MySQL 资源配置
    • WordPress 资源配置
  • 应用整个 kustomization 目录 kubectl apply -k ./
  • 清理

准备开始

你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 如果你还没有集群,你可以通过 Minikube 构建一 个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:

要获知版本信息,请输入 kubectl version.

此例在kubectl 1.14 或者更高版本有效。

下载下面的配置文件:

  1. mysql-deployment.yaml

  2. wordpress-deployment.yaml

创建 PersistentVolumeClaims 和 PersistentVolumes

MySQL 和 Wordpress 都需要一个 PersistentVolume 来存储数据。他们的 PersistentVolumeClaims 将在部署步骤中创建。

许多群集环境都安装了默认的 StorageClass。如果在 PersistentVolumeClaim 中未指定 StorageClass,则使用群集的默认 StorageClass。

创建 PersistentVolumeClaim 时,将根据 StorageClass 配置动态设置 PersistentVolume。

警告:

在本地群集中,默认的 StorageClass 使用hostPath供应器。 hostPath卷仅适用于开发和测试。使用 hostPath 卷,您的数据位于 Pod 调度到的节点上的/tmp中,并且不会在节点之间移动。如果 Pod 死亡并被调度到群集中的另一个节点,或者该节点重新启动,则数据将丢失。

说明:

如果要建立需要使用hostPath设置程序的集群,则必须在 controller-manager 组件中设置--enable-hostpath-provisioner标志。

说明:

如果你已经有运行在 Google Kubernetes Engine 的集群,请参考 this guide

创建 kustomization.yaml

创建 Secret 生成器

A Secret 是存储诸如密码或密钥之类的敏感数据的对象。从 1.14 开始,kubectl支持使用 kustomization 文件管理 Kubernetes 对象。您可以通过kustomization.yaml中的生成器创建一个 Secret。

通过以下命令在kustomization.yaml中添加一个 Secret 生成器。您需要用您要使用的密码替换YOUR_PASSWORD

  1. cat <<EOF >./kustomization.yaml
  2. secretGenerator:
  3. - name: mysql-pass
  4. literals:
  5. - password=YOUR_PASSWORD
  6. EOF

补充 MySQL 和 WordPress 的资源配置

以下 manifest 文件描述了单实例 MySQL 部署。MySQL 容器将 PersistentVolume 挂载在/var/lib/mysqlMYSQL_ROOT_PASSWORD环境变量设置来自 Secret 的数据库密码。

application/wordpress/mysql-deployment.yaml 示例:使用 Persistent Volumes 部署 WordPress 和 MySQL - 图1

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: wordpress-mysql
  5. labels:
  6. app: wordpress
  7. spec:
  8. ports:
  9. - port: 3306
  10. selector:
  11. app: wordpress
  12. tier: mysql
  13. clusterIP: None
  14. ---
  15. apiVersion: v1
  16. kind: PersistentVolumeClaim
  17. metadata:
  18. name: mysql-pv-claim
  19. labels:
  20. app: wordpress
  21. spec:
  22. accessModes:
  23. - ReadWriteOnce
  24. resources:
  25. requests:
  26. storage: 20Gi
  27. ---
  28. apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
  29. kind: Deployment
  30. metadata:
  31. name: wordpress-mysql
  32. labels:
  33. app: wordpress
  34. spec:
  35. selector:
  36. matchLabels:
  37. app: wordpress
  38. tier: mysql
  39. strategy:
  40. type: Recreate
  41. template:
  42. metadata:
  43. labels:
  44. app: wordpress
  45. tier: mysql
  46. spec:
  47. containers:
  48. - image: mysql:5.6
  49. name: mysql
  50. env:
  51. - name: MYSQL_ROOT_PASSWORD
  52. valueFrom:
  53. secretKeyRef:
  54. name: mysql-pass
  55. key: password
  56. ports:
  57. - containerPort: 3306
  58. name: mysql
  59. volumeMounts:
  60. - name: mysql-persistent-storage
  61. mountPath: /var/lib/mysql
  62. volumes:
  63. - name: mysql-persistent-storage
  64. persistentVolumeClaim:
  65. claimName: mysql-pv-claim

以下 manifest 文件描述了单实例 WordPress 部署。WordPress 容器将网站数据文件位于/var/www/html的 PersistentVolume。WORDPRESS_DB_HOST环境变量集上面定义的 MySQL Service 的名称,WordPress 将通过 Service 访问数据库。WORDPRESS_DB_PASSWORD环境变量设置从 Secret kustomize 生成的数据库密码。

application/wordpress/wordpress-deployment.yaml 示例:使用 Persistent Volumes 部署 WordPress 和 MySQL - 图2

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: wordpress
  5. labels:
  6. app: wordpress
  7. spec:
  8. ports:
  9. - port: 80
  10. selector:
  11. app: wordpress
  12. tier: frontend
  13. type: LoadBalancer
  14. ---
  15. apiVersion: v1
  16. kind: PersistentVolumeClaim
  17. metadata:
  18. name: wp-pv-claim
  19. labels:
  20. app: wordpress
  21. spec:
  22. accessModes:
  23. - ReadWriteOnce
  24. resources:
  25. requests:
  26. storage: 20Gi
  27. ---
  28. apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
  29. kind: Deployment
  30. metadata:
  31. name: wordpress
  32. labels:
  33. app: wordpress
  34. spec:
  35. selector:
  36. matchLabels:
  37. app: wordpress
  38. tier: frontend
  39. strategy:
  40. type: Recreate
  41. template:
  42. metadata:
  43. labels:
  44. app: wordpress
  45. tier: frontend
  46. spec:
  47. containers:
  48. - image: wordpress:4.8-apache
  49. name: wordpress
  50. env:
  51. - name: WORDPRESS_DB_HOST
  52. value: wordpress-mysql
  53. - name: WORDPRESS_DB_PASSWORD
  54. valueFrom:
  55. secretKeyRef:
  56. name: mysql-pass
  57. key: password
  58. ports:
  59. - containerPort: 80
  60. name: wordpress
  61. volumeMounts:
  62. - name: wordpress-persistent-storage
  63. mountPath: /var/www/html
  64. volumes:
  65. - name: wordpress-persistent-storage
  66. persistentVolumeClaim:
  67. claimName: wp-pv-claim
  1. 下载 MySQL deployment 配置文件。

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

    1. curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml
  3. 补充到 kustomization.yaml 文件。

    1. cat <<EOF >>./kustomization.yaml
    2. resources:
    3. - mysql-deployment.yaml
    4. - wordpress-deployment.yaml
    5. EOF

应用和验证

kustomization.yaml包含用于部署 WordPress 网站的所有资源以及 MySQL 数据库。您可以通过以下方式应用目录

  1. kubectl apply -k ./

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

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

    1. kubectl get secrets

    响应应如下所示:

    1. NAME TYPE DATA AGE
    2. mysql-pass-c57bb4t7mf Opaque 1 9s
  2. 验证是否已动态配置 PersistentVolume:

    1. kubectl get pvc

    说明: 设置和绑定 PV 可能要花费几分钟。

    响应应如下所示:

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

    1. kubectl get pods

    说明: 等待 Pod 状态变成RUNNING可能会花费几分钟。

    响应应如下所示:

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

    1. kubectl get services wordpress

    响应应如下所示:

    1. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    2. wordpress ClusterIP 10.0.0.89 <pending> 80:32406/TCP 4m

    说明: Minikube 只能通过 NodePort 公开服务。EXTERNAL-IP 始终处于挂起状态

  5. 运行以下命令以获取 WordPress 服务的 IP 地址:

    1. minikube service wordpress --url

    响应应如下所示:

    1. http://1.2.3.4:32406
  6. 复制 IP 地址,然后将页面加载到浏览器中来查看您的站点。

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

    wordpress-init

警告:

不要在此页面上保留 WordPress 安装。如果其他用户找到了它,他们可以在您的实例上建立一个网站并使用它来提供恶意内容。

通过创建用户名和密码来安装 WordPress 或删除您的实例。

清理现场

  1. 运行一下命令删除您的 Secret,Deployments,Services and PersistentVolumeClaims:

    1. kubectl delete -k ./

接下来