Kubernetes中常见的volumes数据卷

华子目录

volumes

  • 容器中文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题
    • 当容器崩溃时,kubelet将重新启动容器,容器中的文件将会丢失,因为容器会以干净的状态重建
    • 当在一个Pod中同时运行多个容器时,常常需要在这些容器之间共享文件
  • Kubernetes数据卷具有明确的生命周期与使用它的Pod具有相同的生命周期
  • Kubernetes数据卷比Pod中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留
  • 当一个Pod不再存在时,Kubernetes数据卷也将不再存在
  • Kubernetes可以支持许多类型的卷,Pod也能同时使用任意数量的卷
  • Kubernetes数据卷不能挂载到其他Kubernetes卷,也不能与其他卷有硬链接。
  • Pod中的每个容器必须单独地指定每个卷的挂载位置

k8s支持的卷的类型

官网:https://kubernetes.io/zh/docs/concepts/storage/volumes/
k8s支持的卷的类型如下:

  • awsElasticBlockStore 、azureDisk、azureFile、cephfs、cinder、configMap、csi
  • downwardAPI、emptyDir、fc (fibre channel)、flexVolume、flocker
  • gcePersistentDisk、gitRepo (deprecated)、glusterfs、hostPath、iscsi、local
  • nfs、persistentVolumeClaim、projected、portworxVolume、quobyte、rbd
  • scaleIO、secret、storageos、vsphereVolume

emptyDir卷

功能

  • 当Pod指定到某个node节点上时,首先创建的是一个emptyDir卷
  • 并且只要Pod在该节点上运行,卷就一直存在。
  • 卷最初是空的。
  • 尽管Pod中的容器挂载 emptyDir卷的路径可能相同也可能不同,但是这些容器都可以读写emptyDir卷中相同的文件。
  • 当Pod因为某些原因被从节点上删除时,emptyDir卷中的数据也会永久删除

emptyDir的使用场景

  • 缓存空间,例如基于磁盘的归并排序
  • 耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行
  • 在Web服务器容器服务数据时,保存内容管理器容器获取的文件
bash 复制代码
[root@k8s-master ~]# mkdir volume
[root@k8s-master ~]# cd volume/

示例

  • 创建一个名为testpod的自主式pod,pod中运行一个busyboxplus和一个nginx,两个容器共用同一个卷
bash 复制代码
#创建一个名为testpod的自主式pod,pod中运行一个busyboxplus和一个nginx,两个容器共用同一个卷
[root@k8s-master volume]# vim pod1.yml
[root@k8s-master volume]# cat pod1.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: testpod
  name: testpod
spec:
  containers:
  - image: busyboxplus
    name: busyboxplus
    command: ["/bin/sh","-c","sleep 10000"]
    volumeMounts:   #声明容器的挂载点
    - name: vol1   #将k8s中名为vol1的卷挂载到容器中/volume1位置
      mountPath: /volume1
  - image: nginx
    name: nginx
    volumeMounts:   #声明容器的挂载点
    - name: vol1   #将k8s中名为vol1的卷挂载到容器中/usr/share/nginx/html位置
      mountPath: /usr/share/nginx/html
  volumes:   #定义Pod中可以使用的所有卷
  - name: vol1   #为卷指定了一个名称vol1,这个名称将在Pod的volumeMounts部分被引用,以便容器可以挂载这个卷。
    emptyDir:  #表明这个卷是一个emptyDir卷,主要用于临时数据的存储
      medium: Memory   #指定了emptyDir卷的存储介质为内存,这意味着卷的内容将存储在节点的RAM中,而不是磁盘上。使用内存作为存储介质可以提供更快的读写速度,但数据不是持久的,一旦Pod被删除或节点发生故障,数据就会丢失。
      sizeLimit: 100Mi  #为emptyDir卷设置了100MiB的大小限制。当卷中的数据量达到这个限制时,写入操作可能会被阻止
bash 复制代码
[root@k8s-master volume]# kubectl apply -f pod1.yml
pod/testpod created
bash 复制代码
[root@k8s-master volume]# kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
testpod   2/2     Running   0          30s   10.244.2.33   k8s-node2.org   <none>           <none>
bash 复制代码
#查看testpod的详细信息
[root@k8s-master volume]# kubectl describe pods testpod


bash 复制代码
#发现了了busyboxplus中的挂载目录/volume1
[root@k8s-master volume]# kubectl exec -it pods/testpod -c busyboxplus -- /bin/sh
/ # ls
bin      etc      lib      linuxrc  mnt      proc     run      sys      usr      volume1
dev      home     lib64    media    opt      root     sbin     tmp      var
/ # cd volume1/    #因为volume1和nginx中的/usr/share/nginx/html是共用的同一个名为vol1的卷,所以数据都是共享的
/volume1 # ls
/volume1 # echo hello world > index.html  #我们在busyboxplus中的volume1挂载目录中创建一个index.html文件,这个index.html文件就自动同步到nginx中的/usr/share/nginx/html目录下
/volume1 # ls
index.html
/volume1 # curl localhost  #因为pod中所有容器都是共享同一个pod中的所有资源,所以在busyboxplus中是可以访问到nginx的
hello world

#这条命令的作用是使用/dev/zero作为输入源,创建一个名为bigfile的文件,该文件的大小为99MB
/volume1 # dd if=/dev/zero of=bigfile bs=1M count=99
99+0 records in
99+0 records out
/volume1 # dd if=/dev/zero of=bigfile bs=1M count=100
100+0 records in
99+1 records out
/volume1 # dd if=/dev/zero of=bigfile bs=1M count=101  #因为我们对emptyDir卷设置的最大空间是100M,这个101M超出了,所以会报错
dd: writing 'bigfile': No space left on device
101+0 records in
99+1 records out
  • dd: 这是一个在Unix和类Unix系统中用于转换和复制文件的命令。它可以用来创建文件的副本,同时对其进行各种转换。
  • if=/dev/zero: if代表输入文件(input_file)。/dev/zero是一个特殊的设备文件,读取它会产生无限的零(0x00字节)。使用/dev/zero作为输入源意味着你正在创建一个全部由零字节组成的文件。
  • of=bigfile: of代表输出文件(output_file)。这里指定输出文件的名称为bigfile
  • bs=1M: bs代表块大小(block_size)。这里设置为1M,意味着每次读取或写入操作处理的数据块大小为1MB(兆字节)
  • count=99: count代表要复制的块的数量。这里设置为99,意味着从输入文件读取99个块并写入到输出文件。由于每个块的大小是1MB,所以最终生成的文件大小将是99MB
bash 复制代码
#回收
[root@k8s-master volume]# kubectl delete -f pod1.yml
pod "testpod" deleted

hostPath卷

功能

  • hostPath卷能将node主机节点文件系统上的文件或目录挂载到Pod中,不会因为pod关闭而被删除
  • hostPath想当于docker -v操作
  • hostPath卷会创建在被调度的node主机上

用法

  • 运行一个需要访问Docker引擎内部机制的pod中的容器,挂载/var/lib/docker路径
  • 在容器中运行cAdvisor(监控) 时,以hostPath方式挂载/sys
  • 允许Pod指定给定的hostPath在运行Pod之前是否应该存在,是否应该创建以及应该以什么方式存在

安全隐患

  • 具有相同配置(例如从podTemplate创建)的多个Pod会由于node节点上文件不同而在不同节点上有不同的行为
  • 当Kubernetes按照计划添加资源感知的调度时,这类调度机制将无法考虑由hostPath使用的资源
  • 基础主机上创建的文件或目录只能由root用户写入。需要在特权容器中以root身份运行进程,或者修改主机上的文件权限以便容器能够写入hostPath卷

示例

  • 创建一个名为testpod的自主式pod,运行一个名为nginx的容器,再声明一个hostPath类型的卷
bash 复制代码
#创建一个名为testpod的自主式pod,运行一个名为nginx的容器,在声明一个hostPath类型的卷
[root@k8s-master volume]# vim pod2.yml
[root@k8s-master volume]# cat pod2.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: testpod
  name: testpod
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:   #容器挂载点声明
    - name: vol2   #将k8s中名为vol2的卷挂载到容器中的/usr/share/nginx/html位置
      mountPath: /usr/share/nginx/html  #挂载点目录
  volumes:   #pod中的卷
  - name: vol2  #指定一个名为vol2的卷
    hostPath:  #这个卷的类型是hostPath类型
      path: /huazi   #在被调度的node节点上创建huazi这个目录
      type: DirectoryOrCreate   #当/huazi目录不存在时自动建立
bash 复制代码
[root@k8s-master volume]# kubectl apply -f pod2.yml
pod/testpod created
bash 复制代码
[root@k8s-master volume]# kubectl describe pods testpod
bash 复制代码
#我们发现调度到了node2主机上
[root@k8s-master volume]# kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
testpod   1/1     Running   0          17s   10.244.2.34   k8s-node2.org   <none>           <none>
bash 复制代码
#我们发现在node2节点上创建了/huazi/这个目录
[root@k8s-node2 ~]# ls /
afs  boot  etc       home   lib    media  opt   root  sbin  sys  usr
bin  dev   guangpan  huazi  lib64  mnt    proc  run   srv   tmp  var
bash 复制代码
#当我们第一次访问的时候是403,因为nginx中/usr/share/nginx/html目录下没有index.html文件
[root@k8s-master volume]# curl 10.244.2.34
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>
bash 复制代码
#在node2上,进入/huazi目录中,创建index.html文件
[root@k8s-node2 ~]# cd /huazi/
[root@k8s-node2 huazi]# echo hello world > index.html
bash 复制代码
#这时再访问,就有效果了
[root@k8s-master volume]# curl 10.244.2.34
hello world
bash 复制代码
#回收
[root@k8s-master volume]# kubectl delete -f pod2.yml
pod "testpod" deleted

nfs卷

功能

  • nfs卷允许将一个现有的nfs服务器上的目录挂载到Kubernetes中的Pod中。这对于在多个Pod之间共享数据或持久化存储数据非常有用

应用

  • 例如,如果有多个容器需要访问相同的数据集,或者需要将容器中的数据持久保存到外部存储,nfs卷可以提供一种方便的解决方案

示例:部署一台nfs服务器并在所有k8s节点中安装nfs-utils

这里,我就在harbor主机上部署nfs服务器

  • 部署nfs服务端
bash 复制代码
[root@harbor ~]# yum install nfs-utils -y
  • 部署nfs客户端
bash 复制代码
[root@k8s-master ~]# yum install nfs-utils -y
bash 复制代码
[root@k8s-node1 ~]# yum install nfs-utils -y
bash 复制代码
[root@k8s-node2 ~]# yum install nfs-utils -y
  • 启动服务端
bash 复制代码
[root@harbor ~]# systemctl enable --now nfs-server
  • 服务端创建nfs共享目录
bash 复制代码
[root@harbor ~]# mkdir /nfsdata
  • 编辑服务端的/etc/exports文件
bash 复制代码
[root@harbor ~]# vim /etc/exports
[root@harbor ~]# cat /etc/exports
/nfsdata  *(rw,sync,no_root_squash)
bash 复制代码
[root@harbor ~]# exportfs -rv
exporting *:/nfsdata
  • 客户端连接服务端
bash 复制代码
#172.25.254.250是nfs服务端的ip
[root@k8s-master ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *
bash 复制代码
[root@k8s-node1 ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *
bash 复制代码
[root@k8s-node2 ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *
  • 创建一个名为testpod的自主式pod,运行一个nginx容器,容器中挂载名为vol3的卷,vol3卷的类型为nfs
bash 复制代码
#创建一个名为testpod的自主式pod,运行一个nginx容器,容器中挂载名为vol3的卷,vol3卷的类型为nfs
[root@k8s-master volume]# vim pod3.yml
[root@k8s-master volume]# cat pod3.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: testpod
  name: testpod
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - name: vol3   #将名字为vol3的卷,挂载到nginx容器中的/usr/share/nginx/html位置
      mountPath: /usr/share/nginx/html
  volumes:  #pod存储卷定义的开始
  - name: vol3  #pod存储卷的名称
    nfs:   #pod存储卷的类型是NFS
      server: 172.25.254.250  #NFS服务器的IP地址
      path: /nfsdata  #nfs服务器上的共享目录
bash 复制代码
[root@k8s-master volume]# kubectl apply -f pod3.yml
pod/testpod created
bash 复制代码
[root@k8s-master volume]# kubectl describe pods testpod
bash 复制代码
[root@k8s-master volume]# kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
testpod   1/1     Running   0          97s   10.244.2.35   k8s-node2.org   <none>           <none>
bash 复制代码
#当我们第一次访问的时候是403,因为nginx中/usr/share/nginx/html目录下没有index.html文件
[root@k8s-master volume]# curl 10.244.2.35
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>
bash 复制代码
#在nfs服务器上,进入/nfsdata共享目录中,创建index.html文件
[root@harbor ~]# cd /nfsdata/
[root@harbor nfsdata]# echo hello world > index.html
bash 复制代码
#再次访问,就看到效果了
[root@k8s-master volume]# curl 10.244.2.35
hello world
相关推荐
MinterFusion15 分钟前
如何在开放麒麟(openKylin)下安装GTK(v0.1.0)
linux·操作系统·软件安装·gtk·明德融创·openkylin·linux图形软件开发
Lzg_na16 分钟前
FAT文件系统详解
linux
看着博客敲代码17 分钟前
enum4linux 报 Server doesn‘t allow session 与 SMB 主机信息枚举
linux·安全·网络安全
你想考研啊18 分钟前
七、pod控制器
kubernetes
重生之小比特20 分钟前
【Linux系统】09 环境变量
linux·运维·服务器
Teecertlabs28 分钟前
【机密计算顶会解读】15:LDR——面向嵌入式TEE系统的高效安全Linux驱动
linux·操作系统·机密计算·可信执行环境
程序员-Benothing28 分钟前
Linux网络性能分析:ss、netstat、iftop、sar实战
linux·运维·服务器
其实防守也摸鱼29 分钟前
Codex 下载与本地部署实战指南
linux·服务器·前端·数据库·算法·ai
岳麓丹枫00130 分钟前
故障案例分析:系统负载居高不下,多次出现 OOM
linux·postgresql
2401_8628808233 分钟前
Linux中断、中断子系统、内核同步互斥机制
linux·驱动开发·嵌入式硬件