【Kubernetes存储篇】常见存储方案及场景分析

一、持久化存储理论

官方中文参考文档:

1、为什么要做数据持久化存储?

在k8s中部署的应用都是以pod容器的形式运行的,假如我们部署MySQL、Redis等数据库,需要对这些数据库产生的数据做备份。因为Pod是有生命周期的,如果pod不挂载数据卷,那pod被删除或重启后这些数据会随之消失,如果想要长久的保留这些数据就要用到pod数据持久化存储。

2、常见持久化存储方案

  • emptyDir:是一种临时性的卷,它的生命周期与 Pod 相同。emptyDir 卷是在 Pod 被调度到节点上时创建的,并且在 Pod 被删除时一并删除。emptyDir 卷通常用于在容器之间共享文件或者缓存数据。
  • HostPath:是一种本地存储卷,可以将宿主机目录映射到容器中,删除Pod后宿主机卷不会跟随删除,但是调用到不通节点,卷内容会不一致(MySQL数据在Node1节点存储,删除MySQL Pod后调度到Node2上了,导致数据不一致)。
  • NFS:是一种共享卷,需要依赖于NFS服务端,所有Pod共享NFS卷内容,不需要考虑Pod调度在不同节点导致数据不一致问题,但是NFS基于网络传输,会占用带宽。
  • PVC:用来实现持久化存储,可以将存储资源独立出来,方便管理和共享。

二、案例:持久化存储方案

1、emptydir临时存储卷

临时卷,当Pod被删除时,卷也会删除,用于存储一些不重要的数据。

创建Pod资源,使用emptydir卷方式挂载 ,YAML如下:

cat emptydir-pod.yaml 

---
apiVersion: v1
kind: Pod
metadata:
  name: empty-pod
  labels: 
    type: empty-pod
spec:
  containers:
  - name: empty-pod
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts: 
    - name: volume-empty  # 挂载路径名称,必须与下面卷名称一致
      mountPath: /usr/share/nginx/html  # 卷挂载目录
  volumes:
  - emptyDir: {
    
    }         # emptyDir类型,{}表示一个空的配置
    name: volume-empty   # 卷名称

执行YAML文件:

kubectl apply -f emptydir-pod.yaml

如何查看本地挂载卷路径位置呢?

第一步:确认Pod当前所在节点,可以使用以下命令确认:

kubectl get pods empty-pod -o wide

第二步:确认Pod的uid值,可以使用以下名称确认:

kubectl get pods empty-pod -o yaml|grep uid
uid: 9f76e568-05a9-41c3-9fb2-c43505214b99

第三步:在Pod所在节点中的/var/lib/kubelet/pods/uid 目录下:

cd /var/lib/kubelet/pods/9f76e568-05a9-41c3-9fb2-c43505214b99
cd volumes/kubernetes.io~empty-dir/volume-empty  # 此目录对应Pod中/usr/share/nginx/html 目录

确认本地卷对应目录后,我们进入路径,创建index.html文件:

cd /var/lib/kubelet/pods/9f76e568-05a9-41c3-9fb2-c43505214b99/volumes/kubernetes.io~empty-dir/volume-empty

echo "qinzt666" > index.html 

访问Pod网站内容:

kubectl get pods empty-pod -o wide
curl 10.244.235.233

在这里插入图片描述

我们删除Pod后宿主机上此目录也会跟随删除

kubectl delete pods empty-pod

在这里插入图片描述

2、hostPath本地存储卷

本地存储卷,指定宿主机目录,与容器目录做映射,删除Pod,宿主机目录不会跟随删除,hostPath可以支持很多挂载类型,如挂载目录,挂载文件等,如下图,此图来自官方:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFuKgorE-1686472737397)(D:\MD归档文档\IMG\image-20230610135129908.png)]

创建Pod资源,使用hostPath卷方式挂载 ,YAML如下:

cat hostpath-pod.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-pod
  labels: 
    type: hostpath-pod
spec:
  containers:
  - name: hostpath-pod
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts: 
    - name: volume-hostpath  # 挂载路径名称,必须与下面卷名称一致
      mountPath: /usr/share/nginx/html  # 容器挂载目录
  volumes:
  - hostPath:
      path: /data1              # 宿主机挂载目录
      type: DirectoryOrCreate   # 卷类型,DirectoryOrCreate表示目录,宿主机不存在则创建空目录
    name: volume-hostpath       # 卷名称

执行YAML文件:

kubectl apply -f hostpath-pod.yaml

在Pod调度节点的宿主机挂载卷位置创建 index.html 文件

kubectl get pods hostpath-pod -o wide

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aRI1MJWD-1686472737397)(D:\MD归档文档\IMG\image-20230610150624530.png)]

echo "hello world qinzt 666 ...." >/data1/index.html

访问Pod网站内容,Pod 的IP地址如上图也可以查看到:

curl 10.244.235.198

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U3A8LZ2Q-1686472737398)(D:\MD归档文档\IMG\image-20230610150808795.png)]

删除此Pod,节点上的数据依旧存在。

kubectl delete pod hostpath-pod
ls /data1/

index.html

3、NFS网络共享存储卷

NFS共享存储卷,需要先搭建NFS服务端,Pod共享NFS服务端数据,解决了Pod调度在不通Node节点,导致数据不一致问题,但是NFS需要依赖网络带宽。

搭建NFS服务端:所有Node节点上都需要安装 nfs-utils

yum install nfs-utils -y
mkdir /data/volumes -p

vim /etc/exports
/data/volumes *(rw,no_root_squash)

加载配置生效 && 启动NFS服务

exportfs -arv
systemctl enable nfs --now

在其他Node节点上面测试 NFS 是否可以正常挂载:

yum install nfs-utils -y
mkdir /test
mount 16.32.15.200:/data/volumes /test

df -hT /test/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TRbzOJDc-1686472737398)(D:\MD归档文档\IMG\image-20230610194008907.png)]

如上图测试无问题,卸载挂载:

umount /test

OK,至此NFS服务端已经搭建完成,测试没有问题了。

编写 YAML 使用 NFS 类型存储卷:

cat nfs-deployment.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-test
  namespace: default
  labels:
    type: nfs
spec:
  replicas: 3
  selector:
    matchLabels:
      type: nfs
  template:
    metadata:
      labels:
        type: nfs
    spec:
      volumes:
      - name: nfs-test-volume     # 卷名称
        nfs: 
          server: 16.32.15.200    # NFS服务端IP地址
          path: /data/volumes     # NFS服务端共享目录
      containers:
      - name: nfs-test
        image: nginx
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: nfs-test-volume             # 挂载卷名称
          mountPath: /usr/share/nginx/html  # 容器内挂载目录

执行YAML 资源清单文件:

kubectl apply -f nfs-deployment.yaml

在 宿主机NFS共享卷创建 index.html 文件

echo "qinzt coolest 666." > /data/volumes/index.html

访问 Pod网站,由于没有创建Service资源,我们使用Pod IP地址进行访问。

kubectl get pods -o wide

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-37x2Mi68-1686472737398)(D:\MD归档文档\IMG\image-20230610202255398.png)]

上面curl 两个节点上的Pod都可以访问,说明挂载nfs存储卷成功了,nfs支持多个客户端挂载,可以创建多个pod,挂载同一个nfs服务器共享出来的目录;但是nfs如果宕机了,数据也就丢失了,所以需要使用分布式存储,常见的分布式存储有glusterfs和cephfs。

猜你喜欢

转载自blog.csdn.net/weixin_45310323/article/details/131154887