K8s数据持久化

红米2年前技术文章606

一、为什么需要持久化

为了解决pod里面的容器被删除后数据不丢失,则引入了存储类型,类似于docker中的数据卷。

在kubernetes集群中,其是支持多种存储类型,包括但不限于emptyDir,HostPath,NFS等。

二、数据卷概述

1、为什么需要数据卷

容器部署过程中一般有以下三种数据:

(1)启动时需要的初始数据,例如配置文件;

(2)启动过程中产生的临时数据,该临时数据需要多个容器间共享,例如类似于Redis的数据库;

(3)启动容器过程中产生的持久化数据,例如MySQL的数据目录(datadir);

如下图所示,我们可以基于数据卷的方式实现数据的共享。

持久卷01_d3XH-oLsFS.png

2、数据卷的分类

数据卷:

    (1)kubernetes中的Volume提供了在容器中挂载外部存储的能力;

    (2)Pod需要设置卷来源(po.spec.volumes)和挂载点(po.spec.containers.volumeMounts)两个信息后才可以使用相应的volume;

按类型分类:

    本地数据卷: hostPath,emptyDir等

    网络数据卷: NFS,Ceph,GlusterFS等

    公有云: AWS,EBS等

    K8S资源: configmap,secret等

三、emptyDir存储类型

1、emptyDir概述

emptyDir数据卷是一个临时存储卷,与Pod生命周期绑定在一起,如果Pod删除了,这意味着数据卷也会被删除。

作用:

(1)可以实现持久化的功能;

(2)多个Pod之间不能通信数据,但是同一个Pod的多个容器是可以实现数据共享的;

(3)随着Pod的生命周期而存在,当我们删除Pod时,其数据也会被随之删除。

应用场景(同一个Pod中各个容器之间数据的共享):

(1)缓存空间,例如基于磁盘的归并排序;

(2)为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行;

(3)存储Web服务器的访问日志及错误日志等信息;

📌温馨提示:使用emptyDir持久化数据时,删除容器并不会删除数据,因为容器删除并不能说明Pod被删除哟。

2、创建Pod并使用emptyDir案例

#创建一个命名空间和pod
[root@172-16-121-211 ~]# cat 01-volumes-emptydir-demo.yml
apiVersion: v1
kind: Namespace
metadata:
 name: emptydir-volume

---

apiVersion: v1
kind: Pod
metadata:
 name: hongmi-pod-emptydir
 namespace: emptydir-volume
spec:
 # 定义数据卷的来源
 volumes:
 - name: data
   emptyDir: {}
 # 我们无需为emptyDir指定任何参数,通常写个"{}"即可,表示创建的是一个空目录。
 - name: log
   emptyDir: {}

 containers:
 # 创建一个负责写入数据的容器
 - name: linux-producer
   image: alpine:latest
   # 启动容器后执行的命令,模拟生产数据即可
   command: ["sh","-c","for i in `seq 1000`;do echo $i >> /mydata/topic;sleep 1;done"]
   # 挂载数据卷
   volumeMounts:
     - name: data  # 注意哈,该名称必须在上面的"volumes"的name字段中存在哟~
       mountPath: /mydata  # 指定挂载到容器的位置

 # 创建一个负责读取数据的容器
 - name: linux-consumer
   image: alpine:latest
   # 启动容器后执行的命令,模拟消费数据即可
   command: ["sh","-c","tail -f /mydata2021/topic"]
   # 挂载数据卷
   volumeMounts:
     - name: data  # 注意哈,该名称必须在上面的"volumes"的name字段中存在哟~
       mountPath: /mydata2021

 - name: hongmi-linux
   image: alpine:latest
   command: ["sh","-c","tail -f /etc/hosts"]
   volumeMounts:
     - name: log
       mountPath: /hongmi

[root@172-16-121-211 ~]# kubectl  apply  -f 01-volumes-emptydir-demo.yml
[root@172-16-121-211 ~]# kubectl get pods -n emptydir-volume   -o wide
NAME                  READY   STATUS    RESTARTS   AGE     IP           NODE            NOMINATED NODE   READINESS GATES
hongmi-pod-emptydir   3/3     Running   0          3m17s   10.244.1.5   172-16-121-88   <none>           <none>

查看数据存储情况:

image_eIh2Jp6zev.png

📌 注意:删除Pod则持久化到本地的数据同时将被删除

四、HostPath存储类型

1、概述:

可以解决同一个Node节点的多个Pod数据共享哟,但多个Pod不在同一个Node节点时则无法通过HostPath来查找数据

2、hostPath数据卷:

挂载Node文件系统(Pod所在节点)上文件或者目录到Pod中的容器。

如果Pod删除了,宿主机的数据并不会被删除,这一点是否感觉和咱们的数据卷有异曲同工之妙呢?

3、应用场景:

Pod中容器需要访问宿主机文件。

[root@172-16-121-211 hostpath]# ls
00-wordpress-namespace.yaml  01-wordpress-mysql.yaml  02-wordpress-mysql-svc.yml  03-wordpress-web.yaml  04-wordpress-svc.yml
[root@172-16-121-211 hostpath]# pwd
/root/hostpath
[root@172-16-121-211 hostpath]#
[root@172-16-121-211 hostpath]# ls
00-wordpress-namespace.yaml  01-wordpress-mysql.yaml  02-wordpress-mysql-svc.yml  03-wordpress-web.yaml  04-wordpress-svc.yml
[root@172-16-121-211 hostpath]# free -h
             total        used        free      shared  buff/cache   available
Mem:           3.7G        1.1G        148M        162M        2.4G        2.2G
Swap:            0B          0B          0B
[root@172-16-121-211 hostpath]#
[root@172-16-121-211 hostpath]#
[root@172-16-121-211 hostpath]# LS
-bash: LS: command not found
[root@172-16-121-211 hostpath]#
[root@172-16-121-211 hostpath]# ls
00-wordpress-namespace.yaml  01-wordpress-mysql.yaml  02-wordpress-mysql-svc.yml  03-wordpress-web.yaml  04-wordpress-svc.yml
[root@172-16-121-211 hostpath]# cat *
00-wordpress-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
 name: hongmi-wordpress
 
01-wordpress-mysql.yaml  
apiVersion: apps/v1
kind: Deployment
metadata:
 name: hongmi-wordpress-mysql
 namespace: hongmi-wordpress
spec:
 replicas: 1
 selector:
   matchLabels:
     app: hongmi-wordpress-mysql
 template:
   metadata:
     labels:
       app: hongmi-wordpress-mysql
   spec:
     containers:
     - name: mysql
       image: mysql:5.7
       ports:
       - containerPort: 3306
       env:
       - name: MYSQL_ROOT_PASSWORD
         value: somewordpress
       - name: MYSQL_DATABASE
         value: wordpress
       - name: MYSQL_USER
         value: wordpress
       - name: MYSQL_PASSWORD
         value: wordpress
         
#02-wordpress-mysql-svc.yml
apiVersion: v1
kind: Service
metadata:
 name: hongmi-mysql
 namespace: hongmi-wordpress
spec:
 ports:
   - port: 3306
     targetPort: 3306
 selector:
   app: hongmi-wordpress-mysql
   
#03-wordpress-web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: wordpress
 namespace: hongmi-wordpress
spec:
 replicas: 1
 selector:
   matchLabels:
     app: wordpress
 template:
   metadata:
     labels:
       app: wordpress
   spec:
     volumes:
       - name: wordpress-code
         hostPath:
           path: /data/wordpress-code
     #nodeName: k8s102.oldboyedu.com
     containers:
     - name: wordpress
       image: wordpress:latest
       ports:
       - containerPort: 80
       volumeMounts:
         - mountPath: /var/www/html
           name: wordpress-code
       env:
       - name: WORDPRESS_DB_HOST
         value: hongmi-mysql  # 注意哈,这里我写的是暴露MySQL服务的service名称哟~
       - name: WORDPRESS_DB_USER
         value: wordpress
       - name: WORDPRESS_DB_PASSWORD
         value: wordpress

#04-wordpress-svc.yml        
apiVersion: v1
kind: Service
metadata:
 name: wordpress
 namespace: hongmi-wordpress
spec:
 type: NodePort
 ports:
   - port: 80
     nodePort: 32020
     targetPort: 80
 selector:
   app: wordpress

五、NFS存储类型

1、概述

适合不同的node节点的Pod共享存储,但存在单点故障

NFS数据卷:提供对NFS挂载支持,可以自动将NFS共享路径挂载到Pod中。

NFS:英文全称为"Network File System"(网络文件系统),是由SUN公司研制的UNIX表示层协议(presentation layer protocol),能使使用者访问网络上别处的文件就像在使用自己的计算机一样。

NFS是一个主流的文件共享服务器,但存在单点故障,我们需要对数据进行备份,如果有必要可以使用分布式文件系统哈。

2、安装NFS环境并测试

(1)在所有节点上都安装"nfs-utils"软件包,安装该软件包不仅仅会包含NFS服务端软件,还会包含其客户端软件
yum -y install nfs-utils

(2)将"master"设置为NFS服务端,配置共享"/data/kubernetes"目录
# vim /etc/exports
#cat /etc/exports
/backup/kubernetes  *(rw,no_root_squash)

# mkdir -pv /backup/kubernetes
# ll /backup/kubernetes
总用量 0

# systemctl start nfs  && systemctl enable nfs  #启动nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.

# exportfs   # 查看NFS的挂载信息
/backup/kubernetes
   <world>

# touch /backup/kubernetes/nfs.log  # 创建测试文件,便于客户端挂载测试验证
(3)客户端验证NFS的可用性
mount -t nfs master:/backup/kubernetes  /mnt/  # 手动挂载NFS的服务端进行测试

(4)手动卸载NFS
# umount /mnt  # 手动卸载NFS

(5)所有节点
systemctl start nfs && systemctl enable nfs
showmount -e 172.16.104.15

📌温馨提示: 建议在Kubernetes的每个工作节点都安装nfs-utils软件包,如果只在NFS服务端安装,客户端未安装的话,可能客户端在使用mount命令手动挂在时会挂在不上哟~  

3、测试案例


[root@k8s101.oldboyedu.com ~]# cat 03-volumes-nfs-demo.yaml
apiVersion: v1
kind: Namespace
metadata:
 name: hongmi-volume

---

apiVersion: apps/v1  
kind: Deployment
metadata:
 name: mynginx-deploy
 namespace: hongmi-volume
spec:
 selector:
   matchLabels:
     app: nginx-nfs
 replicas: 3
 template:
   metadata:
     labels:
       app: nginx-nfs
   spec:
     # 配置NFS的数据源
     volumes:
     - name: hongmi-nfs
       nfs:
         server: master    #指定NFS的服务器的地址,如果指定主机名请确保可以正常进行解析哟~
         path: /data/kubernetes  #指定NFS的挂载路径
     containers:
     - name: my-nginx
       image: nginx:1.18
       # 在容器中挂载数据卷
       volumeMounts:
       - name: hongmi-nfs
         mountPath: /usr/share/nginx/html
       ports:
       - containerPort: 80
[root@172-16-104-15 ~]# kubectl apply -f 03-volumes-nfs-demo.yaml
namespace "hongmi-volume" created
deployment "mynginx-deploy" created
[root@172-16-104-15 ~]# kubectl get pods -n hongmi-volume
NAME                              READY     STATUS    RESTARTS   AGE
mynginx-deploy-1210620599-0tqll   1/1       Running   0          6s
mynginx-deploy-1210620599-kp0p8   1/1       Running   0          6s
mynginx-deploy-1210620599-rb8z5   1/1       Running   0          6s

六、PV和PVC的基本使用

1、概述

什么是pv:

全称为:"persistent volume",属于k8s集群的全局资源,因此并不支持名称空间(namespace)。

该资源对象本身并不负责数据的真实存储,而是负责和后端存储进行关联,每个pv都有提前定义好的存储能力。

持久卷是对存储资源数据卷(volume)创建和使用的抽象,使得存储作为集群中的资源管理。

这样我们就可以对数据卷的使用空间,读写权限做一个基本的权限管控,而不是放任Pod使用所有的数据卷资源。

pv的作用:  

PV解决了企业对于存储的依赖问题,比如A公司使用的是nfs作为存储,而B公司使用的是cephfs作为存储,对于运维人员而言可能需要手动维护不同的组件,而一旦使用pv对存储资源进行抽象后,在迁移服务时就无需关心集群底层存储使用的资源,而是直接使用pv即可。

简而言之,就是实现了以下三大特性:

1、后端存储的权限管控(rw,ro);

2、存储能力(比如使用多大的存储空间);

3、后端存储卷(volumes)存储类型的应用解耦。

什么是PVC: 全称为:"persistent volume  claim",   属于k8s集群某一个namespace的局部资源。该资源对象本身并不负责数据的真实存储,而是显式声明需要使用的存储资源需求。

PVC的作用:

让用户不需要关心具体的Volume实现细节。pvc的一个最重要的作用就是去关联符合条件的pv,从而实现对存储资源的使用。

推荐阅读: https://kubernetes.io/docs/concepts/storage/persistent-volumes/

温馨提示:

(1)全局资源指的是所有的namespace都能看到该资源,很明显是全局唯一的。

(2)局部资源指的是该资源只属于某个namespace哟。

(3)PVPVC均属于k8s资源,而k8s的所有资源通常都支持打标签的哟。

2、创建PV资源

(1)创建pv的存储目录,注意该目录是NFS的挂载目录哟~
mkdir -pv /data/kubernetes/pv0{1,2,3}

(2)编写pv的资源清单
# cd /oldboyedu/persistentVolume
# cat 01-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
 name: pv01
 labels:
   type: ssd
spec:
 capacity:  # 定义PV存储容量的大小
   storage: 10Gi
 accessModes:  # 指定访问模式
   - ReadWriteMany
 persistentVolumeReclaimPolicy: Recycle  # 指定PV的回收策略
 nfs:  # 指定PV后端的支持存储设备类型
   path: "/data/kubernetes/pv01"
   server: 172.200.1.101 #改为nfs的服务器ip
   readOnly: false

# cat 02-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
 name: pv02
 labels:
   type: ssd
spec:
 capacity:  # 定义PV存储容量的大小
   storage: 30Gi
 accessModes:  # 指定访问模式
   - ReadWriteMany
 persistentVolumeReclaimPolicy: Recycle  # 指定PV的回收策略
 nfs:  # 指定PV后端的支持存储设备类型
   path: "/data/kubernetes/pv02"
   server: 172.200.1.101。#改为nfs的服务器ip
   readOnly: false

# cat 03-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
 name: pv03
 labels:
   type: ssd
spec:
 capacity:  # 定义PV存储容量的大小
   storage: 50Gi
 accessModes:  # 指定访问模式
   - ReadWriteMany
 persistentVolumeReclaimPolicy: Recycle  # 指定PV的回收策略
 nfs:  # 指定PV后端的支持存储设备类型
   path: "/data/kubernetes/pv03"
   server: 172.200.1.101 #改为nfs的服务端ip
   readOnly: false

(3)创建pv资源
# kubectl apply -f .
persistentvolume "pv01" created
persistentvolume "pv02" created
persistentvolume "pv03" created

常用的字段如下:

NAME: 有关PV资源的名称。

CAPACITY:   该PV资源的容量大小。

ACCESSMODES(访问模式):   是用来对PV进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括以下几种方式:

ReadWriteOnce(RWO): 读写权限,但是只能被单个节点挂载。

ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载。

ReadWriteMany(RWX): 读写权限,可以被多个节点挂载。

ReadWriteOncePod: 卷可以由单个Pod以读写方式挂载。这仅支持CSI卷和Kubernetes 1.22+版

RECLAIMPOLICY(回收策略):  

目前新版本中PV支持的策略有三种:

Retain(保留): 保留数据,需要管理员手工清理数据,这是默认策略哟。

Recycle(回收): 清除PV中的数据,效果相当于执行"rm -rf /data/kubernetes/ *"。

Delete(删除): 与PV相连的后端存储同时删除。

STATUS(状态):     一个PV的生命周期中,可能会处于四种不同的阶段:

Available(可用): 表示可用状态,还未被任何PVC绑定。

Bound(已绑定): 表示PV已经被PVC绑定。

Released(已释放): PVC被删除,但是资源还未被集群重新声明。

Failed(失败): 表示该PV的自动回收失败。

CLAIM: 被那个pvc声明使用

3、创建PVC

(1)创建namespace,以便于将PVC放入该名称空间
# cat ns-hongmi-tomcat.yaml
apiVersion: v1
kind: Namespace
metadata:
 name: hongmi-tomcat

# kubectl apply -f ns-hongmi-tomcat.yaml

(2)创建PVC
# cat 01-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: tomcat-mysql-pvc
 namespace: hongmi-tomcat
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 35Gi

温馨提示:

(1)当我们创建的PVC申请的存储大小要小于PV现有存储大小时,K8S会自动评估PVC和与哪一个后端PV进行绑定(Bound),如果PVC找不到合适的PV则pvc始终会停留在"Pending"状态

(2)如下图所示,本案例PVC仅申请了35G内存,但实际上PVC会自动去关联全局资源,匹配最合适的PV,这个过程是由K8s集群自动实现的,无需运维人员手动绑定,绑定成功请注意观察PV和PVC的状态均为"Bound"。

(3)如下图所示,如果将PVC申请的数量过大(本案例是32GB),就会导致PVC无法自动关联全局PV资源,因此PVC的状态始终为"Pending",因为此时并没有一个PV的存储能力能够满足该PVC

4、PV和PVC生命周期

PV是群集中的资源。PVC是对这些资源的请求,并且还充当对资源的检查。

PV和PVC之间的相互作用遵循以下生命周期:

Provisioning ——-> Binding ——–>Using——>Releasing——>Recycling

  • 供应准备—Provisioning---通过集群外的存储系统或者云平台来提供存储持久化支持。

    • - 静态提供Static:集群管理员创建多个PV。 它们携带可供集群用户使用的真实存储的详细信息。 它们存在于Kubernetes API中,可用于消费

    • - 动态提供Dynamic:当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试为PVC动态配置卷。 此配置基于StorageClasses:PVC必须请求一个类,并且管理员必须已创建并配置该类才能进行动态配置。 要求该类的声明有效地为自己禁用动态配置。

  • 绑定—Binding---用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前,pvc会保持未绑定状态。

  • 使用—Using---用户可在pod中像volume一样使用pvc。

  • 释放—Releasing---用户删除pvc来回收存储资源,pv将变成“released”状态。由于还保留着之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他pvc使用。

  • 回收—Recycling---pv可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。

    • - 保留策略:允许人工处理保留的数据。

    • - 删除策略:将删除pv和外部关联的存储资源,需要插件支持。

    • - 回收策略:将执行清除操作,之后可以被新的pvc使用,需要插件支持

5、新建一个mysql实例进行测试

[root@172-16-121-211 ~]# cat mysql-deploy.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
 name: mysql
 namespace: hongmi-tomcat
spec:
 replicas: 1
 selector:
   matchLabels:
     app: hongmi-mysql
 template:
   metadata:
     labels:
       app: hongmi-mysql
   spec:
     volumes:
       - name: datadir
         persistentVolumeClaim:
           claimName: tomcat-mysql-pvc  # 指定PVC的名称,注意要创建的Pod的名称空间中必须存在该PVC哟~
           readOnly: false  # PVC是否只读,默认值就为false,如果想要只读请设置为"true"
       - name: logbin  # 我们可以定义多个存储卷,但下面若不挂载,则始终不会应用它哟!
         emptyDir: {}

     containers:
       - name: mysql
         image: mysql:5.7
         ports:
           - containerPort: 3306
         env:
           - name: MYSQL_ROOT_PASSWORD
             value: '123456'
         volumeMounts:
           - name: datadir
             mountPath: /var/lib/mysql

结果展示

6、标签选择器

(1)创建一个pv04,标签为hdd
[root@172-16-121-211 ~]# cat 04-pv.yml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv04
  labels:
    type: hdd
spec:
  capacity:  # 定义PV存储容量的大小
    storage: 50Gi 
  accessModes:  # 指定访问模式
    - ReadWriteMany 
  persistentVolumeReclaimPolicy: Recycle  # 指定PV的回收策略
  nfs:  # 指定PV后端的支持存储设备类型
    path: "/backup/kubernetes/pv04"
    server: 172.16.104.15
    readOnly: false

(2)创建一个pvc,标签选择器为hdd
[root@172-16-121-211 ~]# cat 04-pvc.yml  
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: tomcat-mysql-pvc2
  namespace: hongmi-tomcat
spec:
  selector:
    matchLabels:
      type: hdd
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 25Gi

结果展示:

image_H_s1YJNlb5.png

返回列表

上一篇:pg_restore

下一篇:pg_probackup

相关文章

nginx配置反向代理某个url

nginx配置反向代理某个url

本文讲的这个漏洞 主要是为了解决漏洞扫描的问题我先介绍下这个漏洞主要是因为访问https://172.16.120.17:18090/ws/v1/cluster/info这个 yarn rest的一个...

Doris性能测试

Doris性能测试

1.性能测试(1)环境信息硬件环境 软件环境l Doris 部署 3BE 3FE;l 内核版本:Linux version 5.5.0-96-genericl 操作系统版本:CentOS Linux...

xargs-管道命令符

有时候我们的脚本却需要 echo '516' | kill 这样的效果,例如 ps -ef | grep 'ddd' | kill 这样的效果,筛选出符合某条件的进程pid然后结束。这种需求对于我们来...

Flume使用案例之监控端口数据

监控端口数据目标:Flume监控一端Console,另一端Console发送消息,使被监控端实时显示。分步实现:1. 安装telnet工具yum -y install telnet2. 创建Flume...

数据湖技术之iceberg(六)Iceberg表数据组织与查询

数据湖技术之iceberg(六)Iceberg表数据组织与查询

1     Iceberg表数据组织与查询1) 下载avro-tools jar包由于后期需要查看avro文件内容,我们可以通过avro-tool.jar来查看...

CentOS6.x下的ntp服务

CentOS6.x下的ntp服务配置192.168.1.1(node01) 负责与外网同步时间,同时作为内网的ntp服务192.168.1.2(node02) 和内网192.168.1.1去同步时间,...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。