每天一点基础K8S--K8S中的常用存储方案--emptyDir、hostPath、NFS

这几天阳了,坐一会儿就腰痛

K8S中的常用存储方案

背景

因为K8S的POD运行了最终的业务,而pod在控制器的管理下可能会出现重建,重建的pod是镜像的新实例,如果一些重要配置文件或者日志文件也会随着pod的重建丢失,因此需要将pod的重要文件放在物理机存储,或者网络存储上。

常见的存储方法有:emptyDir、hostPath、nfs、PV

emptyDir

emptyDir主要用于测试,一次性的。

当 Pod 分派到某个节点上时,emptyDir 卷会被创建,并且在 Pod 在该节点上运行期间,卷一直存在。 就像其名称表示的那样,卷最初是空的。 尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。

用途

  1. 缓存空间,例如基于磁盘的归并排序。
  2. 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
  3. 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。
[root@master-worker-node-1 storage]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata: 
  name: pod-with-volume
spec:
  containers:
  - name: busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['/bin/sh','-c','sleep 1234']
    volumeMounts:
    - mountPath: /mnt
      name: test-emptydir   # 在容器中挂在之前创建的volume
  volumes:          # 先创建一个volume,
  - name: test-emptydir
    emptyDir:
      sizeLimit: 200Mi
/ # df -Th
Filesystem           Type            Size      Used Available Use% Mounted on
overlay              overlay        20.0G      5.9G     14.1G  29% /
tmpfs                tmpfs          64.0M         0     64.0M   0% /dev
tmpfs                tmpfs           3.8G         0      3.8G   0% /sys/fs/cgroup
/dev/sda1            xfs            20.0G      5.9G     14.1G  29% /mnt         # 挂载的卷,虽然限制的200M,但是显示还是主机的空间
/dev/sda1            xfs            20.0G      5.9G     14.1G  29% /etc/hosts
/dev/sda1            xfs            20.0G      5.9G     14.1G  29% /dev/termination-log
/dev/sda1            xfs            20.0G      5.9G     14.1G  29% /etc/hostname
/dev/sda1            xfs            20.0G      5.9G     14.1G  29% /etc/resolv.conf
shm                  tmpfs          64.0M         0     64.0M   0% /dev/shm
tmpfs                tmpfs           7.5G     12.0K      7.5G   0% /var/run/secrets/kubernetes.io/serviceaccount
tmpfs                tmpfs           3.8G         0      3.8G   0% /proc/acpi
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/kcore
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/keys
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/timer_list
tmpfs                tmpfs          64.0M         0     64.0M   0% /proc/sched_debug
tmpfs                tmpfs           3.8G         0      3.8G   0% /proc/scsi
tmpfs                tmpfs           3.8G         0      3.8G   0% /sys/firmware
# 确定pod的UID
[root@master-worker-node-1 storage]# kubectl get pods pod-with-volume -o yaml |  grep uid 
  uid: 2b3d790e-8a8f-4b02-92c5-49716438c5a8

# 在pod所处的node上可以查看相应的路径
[root@only-worker-node-3 ~]# ls -l /var/lib/kubelet/pods/2b3d790e-8a8f-4b02-92c5-49716438c5a8/
containers/ etc-hosts   plugins/    volumes/    
[root@only-worker-node-3 ~]# ls -l /var/lib/kubelet/pods/2b3d790e-8a8f-4b02-92c5-49716438c5a8/volumes/
total 0
drwxr-xr-x. 3 root root 27 Dec 22 15:50 kubernetes.io~empty-dir
drwxr-xr-x. 3 root root 35 Dec 22 15:50 kubernetes.io~projected

[root@only-worker-node-3 ~]# ls -l /var/lib/kubelet/pods/2b3d790e-8a8f-4b02-92c5-49716438c5a8/volumes/kubernetes.io~empty-dir/test-emptydir/
total 0
# 从pod中创建file
[root@master-worker-node-1 storage]# kubectl exec -it pod-with-volume -- sh 
/ # touch /mnt/file-from-pod
/ # ls -l /mnt/
-rw-r--r--    1 root     root             0 Dec 22 08:12 file-from-pod
/ # exit

# 也会在pod所在node目录下存在该文件
[root@master-worker-node-1 storage]# ssh node3
Last login: Thu Dec 22 16:09:05 2022 from 192.168.122.89
[root@only-worker-node-3 ~]# ls -l /var/lib/kubelet/pods/2b3d790e-8a8f-4b02-92c5-49716438c5a8/volumes/kubernetes.io~empty-dir/test-emptydir/
total 0
-rw-r--r--. 1 root root 0 Dec 22 16:12 file-from-pod
#使用emptyDir中的sizeLimit参数时需要注意,如果没有指定emptyDir.medium参数,默认是将使用node节点的块设备。
[root@master-worker-node-1 storage]# kubectl exec -it pod-with-volume -- df -Th |  grep mnt
/dev/sda1      xfs       20G  5.9G   15G  30% /mnt
# 如果此时pod在容器中的volume目录下写入的问题超过200M时,将kill pod
[root@master-worker-node-1 storage]# kubectl exec -it pod-with-volume -- dd if=/dev/zero of=/mnt/test bs=1M count=300 
300+0 records in
300+0 records out
314572800 bytes (315 MB, 300 MiB) copied, 0.468132 s, 672 MB/s
[root@master-worker-node-1 storage]# kubectl describe pods pod-with-volume | tail 
Events:
  Type     Reason               Age   From               Message
  ----     ------               ----  ----               -------
  Normal   Scheduled            112s  default-scheduler  Successfully assigned default/pod-with-volume to only-worker-node-3
  Normal   Pulled               111s  kubelet            Container image "centos" already present on machine
  Normal   Created              111s  kubelet            Created container centos
  Normal   Started              111s  kubelet            Started container centos
  Warning  Evicted              19s   kubelet            Usage of EmptyDir volume "test-emptydir" exceeds the limit "200Mi".
  Normal   Killing              19s   kubelet            Stopping container centos
  Warning  ExceededGracePeriod  9s    kubelet            Container runtime did not kill the pod within specified grace period.

# 如果指定medium参数为memory时,将占用pod的内存空间,而且主机重启也会造成数据丢失。
[root@master-worker-node-1 storage]# cat 1.yaml |  tail -5
  volumes:
  - emptyDir:
      medium: Memory
      sizeLimit: 200Mi
    name: test
[root@master-worker-node-1 storage]# kubectl apply -f 1.yaml 
pod/pod-volume2 created

[root@master-worker-node-1 storage]# kubectl exec -it pod-volume2 -- df -Th |  grep mnt
tmpfs                tmpfs         200.0M         0    200.0M   0% /mnt

# 此时volume在POd中的目录不能大于200M
[root@master-worker-node-1 storage]# kubectl exec -it pod-volume2 -- dd if=/dev/zero of=/mnt/test bs=1M count=300 
dd: error writing '/mnt/test': No space left on device
201+0 records in
200+0 records out
209715200 bytes (200.0MB) copied, 0.317512 seconds, 629.9MB/s
command terminated with exit code 1
[root@master-worker-node-1 storage]# kubectl exec -it pod-volume2 -- ls -lh /mnt
total 200M   
-rw-r--r--    1 root     root      200.0M Dec 22 12:56 test

hostPath

hostPath是将主机节点文件系统上的文件或目录挂载到Pod 中,如果pod删除,hostpath中的文件不会被删除。
使用hostPath时需要注意安全问题。同时由于pod的数据存储在单node上,pod在其他node重建将无法访问,可以使用nfs或者其他共享文件系统解决。

type的取值
9549a7e573396e9d9a9b68f9803f5208.png

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: index
      mountPath: /usr/share/nginx/html/index.html
      readOnly: true            # 为了安全因素,可以按需开启是否只读
  volumes:
  - name: index
    hostPath:
      path: /tmp/index.html
      type: File            # type取值较多,可以参见上面的截图
      
 [root@master-worker-node-1 storage]# kubectl apply -f hostpath-1.yaml 
pod/nginx created
[root@master-worker-node-1 storage]# kubectl get pods -o wide 
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE                 NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          27s   10.244.31.14   only-worker-node-3   <none>           <none>


[root@master-worker-node-1 storage]# curl 10.244.31.14
111

NFS

nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。 不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。
#在node2先运行nfs,把/mnt目录共享出来
[root@master-worker-node-2 ~]# cat >> /etc/exports <<eof
> /mnt  *(rw)
> eof

[root@master-worker-node-2 ~]# exportfs 
/mnt          	<world>
apiVersion: v1
kind: Pod
metadata:
  name: pod-nfs
spec:
  containers:
  - name: nginx
    image: nginx:stable-alpine-perl
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: nfs
  volumes:
  - name: nfs
    nfs:
      server: 192.168.122.106
      path: /mnt

[root@master-worker-node-1 storage]# kubectl get pods -o wide 
NAME      READY   STATUS    RESTARTS   AGE     IP             NODE                 NOMINATED NODE   READINESS GATES
pod-nfs   1/1     Running   0          3m15s   10.244.31.16   only-worker-node-3   <none>           <none>

# 在nfs共享目录下添加一个index.html文件
[root@master-worker-node-2 ~]# echo node2-nfs > /mnt/index.html 


# 测试发现可以正常访问
[root@master-worker-node-1 storage]# curl 10.244.31.16
node2-nfs

小结

1、emptyDir基本用于测试环境中

2、hostPath和NFS可以结合使用,比如node主机通过NFS挂载某个文件系统,然后将文件系统以hostPath的方式分享给POD,这样克服了hostPath是单个node范围的缺点

posted @   woshinidaye  阅读(1614)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示