示例:使用持久卷部署 WordPress 和 MySQL

本教程展示如何使用 Minikube 部署 WordPress 站点和 MySQL 数据库。这两个应用程序都使用 PersistentVolumes 和 PersistentVolumeClaims 来存储数据。

持久卷 (PersistentVolume,PV) 是集群中的一块存储,由管理员手动配置,或者由 Kubernetes 使用 StorageClass 动态配置。 持久卷申领 (PersistentVolumeClaim,PVC) 是用户对存储的请求,可以由 PV 来满足。持久卷和持久卷申领独立于 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 及以上版本。

下载以下配置文件

  1. mysql-deployment.yaml

  2. wordpress-deployment.yaml

创建 PersistentVolumeClaims 和 PersistentVolumes

MySQL 和 WordPress 每个都需要一个持久卷来存储数据。它们的持久卷申领将在部署步骤中创建。

许多集群环境都安装了默认的 StorageClass。当持久卷申领中未指定 StorageClass 时,将使用集群的默认 StorageClass。

当创建持久卷申领时,系统会根据 StorageClass 配置动态配置一个持久卷。

警告

在本地集群中,默认的 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 部署。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 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
  1. 下载 MySQL 部署配置文件。

    curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml
    
  2. 下载 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
    

应用并验证

kustomization.yaml 包含部署 WordPress 站点和 MySQL 数据库的所有资源。您可以通过以下命令应用该目录:

kubectl apply -k ./

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

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

    kubectl get secrets
    

    响应内容应如下所示

    NAME                    TYPE                                  DATA   AGE
    mysql-pass-c57bb4t7mf   Opaque                                1      9s
    
  2. 验证持久卷是否已动态配置。

    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
    
  3. 通过运行以下命令验证 Pod 是否正在运行

    kubectl get pods
    

    说明

    Pod 的状态变为 RUNNING 可能需要几分钟时间。

    响应内容应如下所示

    NAME                               READY     STATUS    RESTARTS   AGE
    wordpress-mysql-1894417608-x5dzt   1/1       Running   0          40s
    
  4. 通过运行以下命令验证 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 暴露服务。EXTERNAL-IP 始终处于 pending 状态。
  5. 运行以下命令获取 WordPress 服务的 IP 地址

    minikube service wordpress --url
    

    响应内容应如下所示

    http://1.2.3.4:32406
    
  6. 复制 IP 地址并在浏览器中加载该页面,即可查看您的站点。

    您应该会看到类似下图的 WordPress 设置页面。

    wordpress-init

    警告

    不要让您的 WordPress 安装停留在该页面。如果其他用户发现它,他们可以在您的实例上建立网站并利用它来提供恶意内容。

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

清理

  1. 运行以下命令删除您的 Secret、Deployments、Services 和 PersistentVolumeClaims

    kubectl delete -k ./
    

接下来


最后修改时间 2023 年 8 月 24 日下午 6:38 PST:使用 code_sample shortcode 代替 code shortcode (e8b136c3b3)