K8S之持久化存储

持久化存储

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

支持的持久化存储类型

查看K8S支持哪些存储

bash 复制代码
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

bash 复制代码
vim emptydir.yaml
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:{}

更新资源清单文件

bash 复制代码
kubectl apply -f emptydir.yaml
bash 复制代码
kubectl describe pods pod-empty

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

1、查看pod的uid

bash 复制代码
kubectl get pods pod-empty -o yaml | grep uid

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

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

bash 复制代码
kubectl get pods -o wide | grep empty

3、登录到k8s-node1上

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

bash 复制代码
 yum install tree -y

根据 uid 看目录

bash 复制代码
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删了,临时目录也没了

bash 复制代码
kubectl delete -f emptydir.yaml

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

HostPath

hostPath Volume是指Pod挂载宿主机上的目录或文件。 hostPath Volume使得容器可以使用宿主机的文件系统进行存储,hostpath(宿主机路径):节点级别的存储卷 ,在pod被删除,这个存储卷还是存在的,不会被删除。

所以只要同一个pod被调度到同一个节点上来,在pod被删除重新被调度到这个节点之后,对应的数据依然是存在的。

查看hostPath存储卷的用法

bash 复制代码
kubectl explain pods.spec.volumes.hostPath

hostPath的type类型:

实践

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

bash 复制代码
vim hostpath.yaml 
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调度到的节点自动创建一个

更新资源清单文件

bash 复制代码
kubectl apply -f hostpath.yaml

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

bash 复制代码
kubectl get pods -o wide | grep hostpath

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

bash 复制代码
ll /data-hostpath/

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

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

bash 复制代码
cd /data-hostpath

mkdir aa

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

1、登录到nginx容器

bash 复制代码
kubectl exec -it pod-hostpath -c container-nginx -- /bin/bash 
bash 复制代码
cd /hostpath-nginx/ 

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

bash 复制代码
ls

2、登录到tomcat容器

bash 复制代码
kubectl exec -it pod-hostpath -c container-tomcat -- /bin/bash
bash 复制代码
cd /hostpath-tomcat/

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

bash 复制代码
ls

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

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

bash 复制代码
kubectl delete -f hostpath.yaml
bash 复制代码
vim hostpath.yaml 
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

更新资源清单文件

bash 复制代码
kubectl apply -f hostpath.yaml

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

bash 复制代码
kubectl exec -it pod-hostpath -c container-nginx -- /bin/bash 
bash 复制代码
cd /hostpath-nginx 
bash 复制代码
ls

aa 文件不在了

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

NFS

以上 emptyDir 和 hostPath 是两种本地存储解决方案,仅适用于单个节点上的容器。如果需要在多个Pod或多节点之间共享持久化存储,可使用NFS。

NFS存储允许多个Pod从网络共享中读取数据,还支持高可用性配置,可以使用多个NFS服务器来提供容错和负载均衡。此外NFS还支持更高级的存储管理功能,如快照和备份,以及可配置的访问控制策略。

实践

1、搭建NFS服务

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

bash 复制代码
yum install nfs-utils -y

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

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

bash 复制代码
mkdir /data/volumes -pv 

-p表示:创建目录的过程中,如果父级不存在,则自动创建父目录。

-v表示:可向用户展示更多信息,例如显示执行mkdir创建了哪些目录等。

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

执行以下命令启动NFS

bash 复制代码
systemctl start nfs

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

bash 复制代码
vim /etc/exports
powershell 复制代码
# 允许任何客户端挂载
/data/volumes *(rw,no_root_squash)

参数说明:

  • /data/volumes:要共享的目录
  • '**':允许哪些客户端挂载NFS共享的目录,"*"表示允许任何能访问NFS服务的网段客户端挂载NFS共享的目录
  • rw 该主机对该共享目录有读写权限
  • no_root_squash 登入:用户具有根目录的完全管理访问权限

4、使NFS配置生效

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

bash 复制代码
exportfs -arv
bash 复制代码
service nfs restart

查看nfs是否启动成功

bash 复制代码
systemctl enable nfs

查看nfs是否启动成功

bash 复制代码
systemctl status nfs

Active: active

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

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

bash 复制代码
yum install nfs-utils -y

systemctl enable nfs --now

在k8s-node1上手动挂载

bash 复制代码
mkdir /test 
bash 复制代码
mount 192.168.40.182:/data/volumes /test/

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

bash 复制代码
df -h

nfs可以被正常挂载

手动卸载

bash 复制代码
umount /test

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

bash 复制代码
vim nfs.yaml 
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的共享目录

更新资源清单文件

bash 复制代码
kubectl apply -f nfs.yaml

查看pod是否创建成功

bash 复制代码
kubectl get pods -owide

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

bash 复制代码
cd /data/volumes/

vim index.html 

请求pod,看结果

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

登录到pod验证下

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

上面说明挂载nfs存储卷成功了,nfs支持多个客户端挂载,可以创建多个pod,挂载同一个nfs服务器共享出来的目录;

但是nfs如果宕机了,数据也就丢失了,想要高可用可使用分布式存储,常见的分布式存储有glusterfs和cephfs。

相关推荐
chuanauc3 小时前
Kubernets K8s 学习
java·学习·kubernetes
小张是铁粉3 小时前
docker学习二天之镜像操作与容器操作
学习·docker·容器
烟雨书信3 小时前
Docker文件操作、数据卷、挂载
运维·docker·容器
IT成长日记3 小时前
【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
运维·docker·容器·volume·prune
这儿有一堆花3 小时前
Docker编译环境搭建与开发实战指南
运维·docker·容器
LuckyLay3 小时前
Compose 高级用法详解——AI教你学Docker
运维·docker·容器
Uluoyu3 小时前
redisSearch docker安装
运维·redis·docker·容器
IT成长日记7 小时前
【Docker基础】Docker数据持久化与卷(Volume)介绍
运维·docker·容器·数据持久化·volume·
疯子的模样12 小时前
Docker 安装 Neo4j 保姆级教程
docker·容器·neo4j
虚伪的空想家12 小时前
rook-ceph配置dashboard代理无法访问
ceph·云原生·k8s·存储·rook