K8S自己动手系列 - 2.3 - PV & PVC

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 在实验2.2 – Deployment中,我们将原来基于Pod部署的wordpress+mysql成功改造成基于Deployment部署,基于Deployment部署有很多好处,例如:支持滚动升级(Rolling Update),支持水平扩展。

前言

在实验2.2 – Deployment中,我们将原来基于Pod部署的wordpress+mysql成功改造成基于Deployment部署,基于Deployment部署有很多好处,例如:支持滚动升级(Rolling Update),支持水平扩展。

不过有个问题,就是当我们的Deployment修改了,或者Pod删除重建了,数据也随之丢失了,这是我们不希望看到的,本篇文章我们就来尝试一下基于PV & PVC保存数据状态的有状态应用。

场景

对于单实例的有状态应用,我们可以定义Deployment并且replicas只能为1,用指定PVC的方式关联到一个PV上,使用PV提供的状态存储功能。如果要启动多实例,那么Deployment就无法胜任这个任务,必须使用到我们后面会讲到的StatefulSet+PVC Template的方式创建多实例对多PVC的模型。

本文实验所有的源码保存在:
https://github.com/zrbcool/blog-public/tree/master/k8s-hands-on/lab06

实战

PVC定义

  lab06 git:(master)  cat 03-wordpress-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wordpress-pv-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

部署后查看状态

  lab06 git:(master)  kubectl apply -f 03-wordpress-pvc.yaml
persistentvolumeclaim/wordpress-pv-claim created
  lab06 git:(master)  kubectl get pvc
NAME                       STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
wordpress-mysql-pv-claim   Pending                                                     4s

发现PVC处于Pending状态,追查下原因

  lab06 git:(master)  kubectl describe pvc/wordpress-mysql-pv-claim
Name:          wordpress-mysql-pv-claim
Namespace:     default
StorageClass:  
Status:        Pending
Volume:        
Labels:        <none>
Annotations:   kubectl.kubernetes.io/last-applied-configuration:
                 {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"wordpress-mysql-pv-claim","namespace":"default"},"s...
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      
Access Modes:  
VolumeMode:    Filesystem
Events:
  Type       Reason         Age               From                         Message
  ----       ------         ----              ----                         -------
  Normal     FailedBinding  6s (x4 over 36s)  persistentvolume-controller  no persistent volumes available for this claim and no storage class is set
Mounted By:  <none>

接下来我们创建PV

PV定义

查看定义

  lab06 git:(master)  cat 04-wordpress-pv.yaml 
kind: PersistentVolume
apiVersion: v1
metadata:
  name: wordpress-mysql-pv-volume
  labels:
    type: local
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data/pv/wordpress/mysql"

该pv定义是基于hostPath的方式,所以我们要在节点上提前创建好目录,如下:

  lab06 git:(master)  mkdir -p /data/pv/wordpress/mysql

  lab06 git:(master)  kubectl create -f 04-wordpress-pv.yaml 
persistentvolume/wordpress-mysql-pv-volume created
  lab06 git:(master)  kubectl get pv
NAME                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                              STORAGECLASS   REASON   AGE
wordpress-mysql-pv-volume   2Gi        RWO            Retain           Bound    default/wordpress-mysql-pv-claim                           31s
  lab06 git:(master)  kubectl get pvc
NAME                       STATUS   VOLUME                      CAPACITY   ACCESS MODES   STORAGECLASS   AGE
wordpress-mysql-pv-claim   Bound    wordpress-mysql-pv-volume   2Gi        RWO                           118s

此时我们之前定义的pvc也已经成功绑定了

使Deployment使用该PVC

查看定义

  lab06 git:(master)  cat 01-wordpress-mysql-deployment.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: wordpress
  name: wordpress
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress 
    spec:
      containers:
      - image: wordpress:latest
        imagePullPolicy: IfNotPresent
        name: wordpress
        env:
          - name: WORDPRESS_DB_HOST
            value: "127.0.0.1"
          - name: WORDPRESS_DB_USER
            value: "root"
          - name: WORDPRESS_DB_PASSWORD
            value: "passw0rd"
      - image: mysql:5.7.26
        imagePullPolicy: IfNotPresent
        name: mysql
        env:
          - name: MYSQL_ROOT_PASSWORD 
            value: "passw0rd"
          - name: MYSQL_DATABASE
            value: "wordpress"
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: wordpress-mysql-pv-claim 

执行更新并查看效果

  lab06 git:(master)  kubectl apply -f 01-wordpress-mysql-deployment.yaml 
deployment.extensions/wordpress configured
  lab06 git:(master)  kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
wordpress-6cfd879fcd-9mlhb   2/2     Running   0          29s

  lab06 git:(master)  ls -l /data/pv/wordpress/mysql/
total 188480
-rw-r----- 1 999 999       56 Jun 10 23:42 auto.cnf
-rw------- 1 999 999     1675 Jun 10 23:42 ca-key.pem
-rw-r--r-- 1 999 999     1107 Jun 10 23:42 ca.pem
...
drwxr-x--- 2 999 999    12288 Jun 10 23:42 sys
drwxr-x--- 2 999 999     4096 Jun 10 23:42 wordpress

可见,Pod已经在/data/pv/wordpress/mysql/下产生数据了,接下来我们来试一下配置数据后,删除Pod,使Deployment控制Pod重建,配置数据是否能够保存
通过下面命令删除Pod使其重建

  lab06 git:(master)  kubectl get pod  
NAME                         READY   STATUS    RESTARTS   AGE
wordpress-6cfd879fcd-9mlhb   2/2     Running   0          7m34s
  lab06 git:(master)  kubectl delete pod/wordpress-6cfd879fcd-9mlhb
pod "wordpress-6cfd879fcd-9mlhb" deleted
  lab06 git:(master)  kubectl get pod                              
NAME                         READY   STATUS    RESTARTS   AGE
wordpress-6cfd879fcd-29qg9   2/2     Running   1          11s

刷新网页,发布的测试文件还在,测试成功

新问题

查看官网说明:

意思是说,对于这个单实例的有状态Deployment不要对其进行扩容,同时当Deployment定义发生更新时也不能使用滚动更新,而应该先删除再创建,也就是strategy: type: Recreate
修改后的文件如下:

  lab06 git:(master)  cat 01-wordpress-mysql-deployment.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: wordpress
  name: wordpress
spec:
  strategy:
    type: Recreate
  replicas: 1 
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress 
    spec:
      containers:
      - image: wordpress:latest
        imagePullPolicy: IfNotPresent
        name: wordpress
        env:
          - name: WORDPRESS_DB_HOST
            value: "127.0.0.1"
          - name: WORDPRESS_DB_USER
            value: "root"
          - name: WORDPRESS_DB_PASSWORD
            value: "passw0rd"
      - image: mysql:5.7.26
        imagePullPolicy: IfNotPresent
        name: mysql
        env:
          - name: MYSQL_ROOT_PASSWORD 
            value: "passw0rd"
          - name: MYSQL_DATABASE
            value: "wordpress"
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: wordpress-mysql-pv-claim

清除数据

  lab06 git:(master)  kubectl delete -f .
deployment.extensions "wordpress" deleted
service "wordpress-svc" deleted
persistentvolumeclaim "wordpress-mysql-pv-claim" deleted
persistentvolume "wordpress-mysql-pv-volume" deleted
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
3月前
|
存储 Kubernetes 应用服务中间件
k8s 1.24.3版本使用nfs-provisioner4.0.0动态创建PV
k8s 1.24.3版本使用nfs-provisioner4.0.0动态创建PV
694 0
|
5天前
|
存储 Kubernetes API
使用 Kubeadm 部署 Kubernetes(K8S) 安装 -- 持久化存储(PV&PVC)
使用 Kubeadm 部署 Kubernetes(K8S) 安装 -- 持久化存储(PV&PVC)
12 0
|
3月前
|
存储 Kubernetes 监控
【云原生】Kubernetes----PersistentVolume(PV)与PersistentVolumeClaim(PVC)详解
【云原生】Kubernetes----PersistentVolume(PV)与PersistentVolumeClaim(PVC)详解
|
3月前
|
存储 Kubernetes 容器
|
3月前
|
存储 Kubernetes 监控
K8s挂载PVC日志采集“轻量级”玩法
本文介绍一种使用K8s挂载PVC日志采集时的轻量级部署方式。
425 0
K8s挂载PVC日志采集“轻量级”玩法
|
10天前
|
canal Kubernetes Docker
基于Kubernetes v1.25.0和Docker部署高可用集群(03部分)
基于Kubernetes v1.25.0和Docker部署高可用集群(03部分)
|
5天前
|
Kubernetes 安全 数据安全/隐私保护
Kubernetes(K8S) 集群安全机制
Kubernetes(K8S) 集群安全机制
14 2
|
11天前
|
Kubernetes Ubuntu Linux
基于Kubernetes v1.25.0和Docker部署高可用集群(02部分)
基于Kubernetes v1.25.0和Docker部署高可用集群(02部分)
|
13天前
|
Kubernetes API 调度
Airbnb的动态kubernetes集群扩缩容
Airbnb的动态kubernetes集群扩缩容
29 5
|
13天前
|
存储 Kubernetes Java
基于Kubernetes v1.25.0和Docker部署高可用集群(说明篇)
docker与kubernetes的区别是:docker是管理当前主机上的容器,k8s是管理多台主机、跨平台的分布式管理系统。Kubernetes的设计初衷是支持可插拔架构,从而利于扩展kubernetes的功能