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

支持的持久化存储类型

查看K8S支持哪些存储

kubectl explain pods.spec.volumes

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常用的如下:

  • emptyDir :临时性存储卷类型
  • hostPath :在节点上使用本地磁盘进行数据存储
  • nfs:通过 Network File System(网络文件系统)共享文件系统进行数据存储
  • persistentVolumeClaim:持久卷声明,是K8S的一个特定类型的存储资源
  • glusterfs:通过分布式文件系统GlusterFS进行数据存储
  • cephfs:通过分布式文件系统Ceph进行数据存储
  • configMap: 通过ConfigMap资源存储应用程序的配置文件
  • secret:通过Secret资源存储应用程序的机密信息

本篇对前三种进行展开介绍,并例举实践中的使用

EmptyDir

emptyDir类型的Volume是在Pod分配到Node上时被创建,K8S会在Node上自动分配一个目录,无需指定宿主机Node上对应的目录文件。 这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。
emptyDir 主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。

实践

创建一个pod,挂载临时目录emptyDir

vim emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-empty
spec:
  containers:
  - name: container-empty
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: cache-volume  # 匹配volumes.name。把卷挂载到容器里
      mountPath: /cache   # 挂载到容器里的目录下 
  volumes:
  - name: cache-volume 
    emptyDir:{}

更新资源清单文件

kubectl apply -f emptydir.yaml
kubectl describe pods pod-empty

在这里插入图片描述

查看分配到Node上的临时目录存在的位置

1、查看pod的uid

kubectl get pods pod-empty -o yaml | grep uid

在这里插入图片描述

uid: adff4bf3-62ac-41fe-9b25-abcae1c8598a

2、查看pod调度到哪个节点

kubectl get pods -o wide | grep empty

在这里插入图片描述

3、登录到k8s-node1上

ps. 安装tree 方便看目录结构

 yum install tree -y

根据 uid 看目录

tree /var/lib/kubelet/pods/adff4bf3-62ac-41fe-9b25-abcae1c8598a

在这里插入图片描述

由上可知,临时目录在本地的/var/lib/kubelet/pods/adff4bf3-62ac-41fe-9b25-abcae1c8598a/volumes/kubernetes.io~empty-dir/cache-volume/下

pod删了,临时目录也没了

kubectl delete -f emptydir.yaml

在这里插入图片描述

在这里插入图片描述

该类型可使用的场景:测试数据

HostPath

hostPath Volume是指Pod挂载宿主机上的目录或文件。 hostPath Volume使得容器可以使用宿主机的文件系统进行存储,hostpath(宿主机路径):节点级别的存储卷,在pod被删除,这个存储卷还是存在的,不会被删除。
所以只要同一个pod被调度到同一个节点上来,在pod被删除重新被调度到这个节点之后,对应的数据依然是存在的。

查看hostPath存储卷的用法

kubectl explain pods.spec.volumes.hostPath

在这里插入图片描述

hostPath的type类型:
在这里插入图片描述

实践

创建一个pod,挂载hostPath存储卷

vim hostpath.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath
spec:
  containers:
  - name: container-nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: hostpath-volume
      mountPath: /hostpath-nginx
  - name: container-tomcat
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: hostpath-volume
      mountPath: /hostpath-tomcat
  volumes:
  - name: hostpath-volume
    hostPath:
      path: /data-hostpath  # 必须字段,指定存储目录
      type: DirectoryOrCreate # 表示本地有/data-hostpath目录,就用本地的,本地没有就会在pod调度到的节点自动创建一个

更新资源清单文件

kubectl apply -f hostpath.yaml

查看pod调度到了哪个物理节点

kubectl get pods -o wide | grep hostpath

在这里插入图片描述

由上面可以知道pod调度到了k8s-node1上,登录到k8s-node1机器,查看是否在这台机器创建了存储目录

ll /data-hostpath/

在这里插入图片描述

上面可以看到已经创建了存储目录/data-hostpath,这个【/data-hostpath】会作为pod的持久化存储目录

在k8s-node1上的/data-hostpath下创建一个目录

cd /data-hostpath

mkdir aa

测试存储卷是否可以正常使用

1、登录到nginx容器

kubectl exec -it pod-hostpath -c container-nginx -- /bin/bash 
cd /hostpath-nginx/ 

/hostpath-nginx/目录存在,说明已经把宿主机目录挂载到了容器里

ls

在这里插入图片描述

2、登录到tomcat容器

kubectl exec -it pod-hostpath -c container-tomcat -- /bin/bash
cd /hostpath-tomcat/

/hostpath-tomcat/目录存在,说明已经把宿主机目录挂载到了容器里

ls

在这里插入图片描述

通过上面测试可以看到,同一个pod里的 container-nginx 和 container-tomcat 这两个容器是共享存储卷的

删除pod,指定调度到另外的node上

kubectl delete -f hostpath.yaml
vim hostpath.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath
spec:
  nodeName: k8s-node2 # 指定调度到node2节点上
  containers:
  - name: container-nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: hostpath-volume
      mountPath: /hostpath-nginx
  - name: container-tomcat
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: hostpath-volume
      mountPath: /hostpath-tomcat
  volumes:
  - name: hostpath-volume 
    hostPath: 
      path: /data-hostpath
      type: DirectoryOrCreate

更新资源清单文件

kubectl apply -f hostpath.yaml

看容器里的目录,登录到nginx容器

kubectl exec -it pod-hostpath -c container-nginx -- /bin/bash 
cd /hostpath-nginx 
ls

在这里插入图片描述

aa 文件不在了

hostpath存储卷缺点:单节点,pod删除之后重新创建必须调度到同一个node节点,数据才不会丢失

NFS

以上 emptyDir 和 hostPath 是两种本地存储解决方案,仅适用于单个节点上的容器。如果需要在多个Pod或多节点之间共享持久化存储,可使用NFS。
NFS存储允许多个Pod从网络共享中读取数据,还支持高可用性配置,可以使用多个NFS服务器来提供容错和负载均衡。此外NFS还支持更高级的存储管理功能,如快照和备份,以及可配置的访问控制策略。

实践

1、搭建NFS服务
以k8s的控制节点(k8s-master1)作为NFS服务端

yum install nfs-utils -y

该命令的主要作用是使用yum包管理器自动安装nfs-utils软件包,以支持NFS协议的功能。

2、在宿主机创建NFS需要的共享目录,作为NFS服务端

mkdir /data/volumes -pv 

-p表示:创建目录的过程中,如果父级不存在,则自动创建父目录。
-v表示:可向用户展示更多信息,例如显示执行mkdir创建了哪些目录等。

3、配置NFS共享服务器上的/data/volumes目录

执行以下命令启动NFS

systemctl start nfs

编辑配置NFS服务访问的目录/data/volumes的访问权限

vim /etc/exports
# 允许任何客户端挂载
/data/volumes *(rw,no_root_squash)

参数说明:

  • /data/volumes:要共享的目录
  • ‘**’:允许哪些客户端挂载NFS共享的目录,“*”表示允许任何能访问NFS服务的网段客户端挂载NFS共享的目录
  • rw 该主机对该共享目录有读写权限
  • no_root_squash 登入:用户具有根目录的完全管理访问权限
    在这里插入图片描述

4、使NFS配置生效

执行以下命令使NFS配置生效

exportfs -arv

在这里插入图片描述

service nfs restart

查看nfs是否启动成功

systemctl enable nfs

查看nfs是否启动成功

systemctl status nfs

在这里插入图片描述

Active: active
看到nfs是active,说明nfs正常启动了

5、k8s-node2和k8s-node1上也安装nfs驱动

yum install nfs-utils -y

systemctl enable nfs --now

在k8s-node1上手动挂载

mkdir /test 
mount 192.168.40.182:/data/volumes /test/

以上【192.168.40.182】为服务端(k8s-master1)的IP

df -h

在这里插入图片描述
nfs可以被正常挂载

手动卸载

umount /test

6、创建Pod,挂载NFS共享出来的目录

vim nfs.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-test
spec:
  replicas: 3
  selector:
    matchLabels:
      storage: nfs
  template: 
    metadata:
      labels:
         storage: nfs
    spec:
      containers:
      - name: container-nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          protocol: TCP
        volumeMounts:
        - name: nfs-volumes
          mountPath: /usr/share/nginx/html
      volumes:
      - name: nfs-volumes
        nfs:
          server: 192.168.40.182 # 安装nfs服务的地址
          path: /data/volumes    # nfs的共享目录

更新资源清单文件

kubectl apply -f nfs.yaml

查看pod是否创建成功

kubectl get pods -owide

在这里插入图片描述

登录到nfs服务器,在共享目录创建一个index.html

cd /data/volumes/

vim index.html 

在这里插入图片描述

请求pod,看结果
在这里插入图片描述

通过上面可以看到,在共享目录创建的index.html已经被pod挂载了
登录到pod验证下

kubectl exec -it nfs-test-65db89988d-4hs7h  -- /bin/bash
cat /usr/share/nginx/html/index.html 

在这里插入图片描述

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

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐