示例:使用持久卷部署 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 部署 API,并且专用于 Kubernetes 1.9 及更高版本。如果你希望在更早版本的 Kubernetes 中使用本教程,请相应地更新 API 版本,或者参考本教程的早期版本。目标
- 创建 PersistentVolumeClaim 和 PersistentVolume
- 使用以下内容创建
kustomization.yaml
:- 一个 Secret 生成器
- MySQL 资源配置
- WordPress 资源配置
- 通过
kubectl apply -k ./
应用 kustomization 目录 - 清理
准备工作
你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在至少有两个不作为控制平面主机的节点的集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用这些 Kubernetes 游乐场之一:
要检查版本,请输入 kubectl version
。
本页所示示例适用于 kubectl
1.27 及更高版本。
下载以下配置文件
创建 PersistentVolumeClaim 和 PersistentVolume
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 的状态变为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、Deployment、Service 和 PersistentVolumeClaim:
kubectl delete -k ./
下一步
- 了解有关内省和调试的更多信息
- 了解有关Job的更多信息
- 了解有关端口转发的更多信息
- 了解如何获取容器的 Shell