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.yamlCreate 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
EOFAdd 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.yaml2.D下载 WordPress 部署配置文件。
curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml3.将它们添加到 kustomization.yaml 文件中。
cat <<EOF >>./kustomization.yaml
resources:
- mysql-deployment.yaml
- wordpress-deployment.yaml
EOFApply 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-initWarning: 不要让你的 WordPress 安装停留在这个页面上。如果其他用户发现了它,他们可以在你的实例上设置一个网站,并利用它来提供恶意内容。
要么通过创建用户名和密码来完成 WordPress 的安装,要么删除你的实例。
Cleaning up
运行以下命令以删除你的 Secret、Deployment、Service 和持久卷声明(PersistentVolumeClaim):
kubectl delete -k ./