示例:使用持久卷部署 WordPress 和 MySQL
本教程向你展示如何使用 Minikube 部署 WordPress 站点和 MySQL 数据库。这两个应用都使用 PersistentVolume 和 PersistentVolumeClaim 来存储数据。
一个 PersistentVolume (PV) 是集群中的一块存储,它或由管理员手动配置,或由 Kubernetes 使用 StorageClass 动态配置。一个 PersistentVolumeClaim (PVC) 是用户对存储的请求,可以由 PV 来满足。PersistentVolume 和 PersistentVolumeClaim 独立于 Pod 的生命周期,在 Pod 重启、重新调度甚至删除后仍保留数据。
警告
此部署不适用于生产环境用例,因为它使用单实例的 WordPress 和 MySQL Pod。请考虑使用 WordPress Helm Chart 在生产环境中部署 WordPress。说明
本教程提供的文件使用了 GA Deployment API,并且仅适用于 Kubernetes 1.9 及更高版本。如果你希望在早期版本的 Kubernetes 中使用本教程,请相应地更新 API 版本,或参考本教程的早期版本。目标
- 创建 PersistentVolumeClaims 和 PersistentVolumes
- 创建一个包含以下内容的
kustomization.yaml
文件- 一个 Secret 生成器
- MySQL 资源配置
- WordPress 资源配置
- 通过
kubectl apply -k ./
应用 kustomization 目录 - 清理
开始之前
你需要有一个 Kubernetes 集群,并且 kubectl 命令行工具已经配置为与你的集群通信。建议你在至少有两个非控制平面节点的主机上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用以下 Kubernetes 游乐场之一。
要检查版本,请输入 kubectl version
。
本页面所示示例适用于 kubectl
1.27 及更高版本。
下载以下配置文件
创建 PersistentVolumeClaims 和 PersistentVolumes
MySQL 和 Wordpress 各需要一个 PersistentVolume 来存储数据。它们的 PersistentVolumeClaim 将在部署步骤中创建。
许多集群环境都安装了默认的 StorageClass。如果在 PersistentVolumeClaim 中没有指定 StorageClass,则会使用集群的默认 StorageClass。
创建 PersistentVolumeClaim 后,将根据 StorageClass 配置动态地配置 PersistentVolume。
警告
在本地集群中,默认的 StorageClass 使用hostPath
供应器。hostPath
卷仅适用于开发和测试。使用 hostPath
卷时,你的数据存储在 Pod 被调度到的节点的 /tmp
目录下,并且不会在节点之间移动。如果 Pod 发生故障并被调度到集群中的另一个节点,或者节点重启,数据就会丢失。说明
如果你要启动一个需要使用hostPath
供应器的集群,则必须在 controller-manager
组件中设置 --enable-hostpath-provisioner
标志。说明
如果你有一个运行在 Google Kubernetes Engine 上的 Kubernetes 集群,请按照此指南进行操作。创建一个 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
下载 MySQL 部署配置文件。
curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml
下载 WordPress 配置文件。
curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml
将它们添加到
kustomization.yaml
文件中。cat <<EOF >>./kustomization.yaml resources: - mysql-deployment.yaml - wordpress-deployment.yaml EOF
应用并验证
kustomization.yaml
包含部署 WordPress 站点和 MySQL 数据库所需的所有资源。你可以通过以下方式应用该目录:
kubectl apply -k ./
现在你可以验证所有对象是否存在。
通过运行以下命令验证 Secret 是否存在:
kubectl get secrets
响应应该如下所示:
NAME TYPE DATA AGE mysql-pass-c57bb4t7mf Opaque 1 9s
验证 PersistentVolume 是否被动态配置。
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 的 Status 变成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
暴露 Service。EXTERNAL-IP 始终处于 Pending 状态。运行以下命令获取 WordPress Service 的 IP 地址:
minikube service wordpress --url
响应应该如下所示:
http://1.2.3.4:32406
复制 IP 地址,并在浏览器中加载该页面以查看你的站点。
你应该会看到类似于以下截图的 WordPress 设置页面。
警告
不要将你的 WordPress 安装停留在本页面。如果其他用户发现它,他们可能会在你的实例上设置一个网站并用于提供恶意内容。
你可以通过创建用户名和密码来安装 WordPress,或者删除你的实例。
清理
运行以下命令删除你的 Secret、Deployments、Services 和 PersistentVolumeClaims:
kubectl delete -k ./
下一步
- 了解更多关于内省和调试的信息
- 了解更多关于Job的信息
- 了解更多关于端口转发的信息
- 学习如何获取容器的 Shell