Kubernetes基本概念之Volume

一、简介

Volume是Pod中能够被多个容器共享的磁盘目录。我们知道,默认情况下Docker容器中的数据都是非持久化的,在容器消亡后数据也会消失。因此Docker提供了Volume机制以便实现数据的持久化。Kubernetes中Volume的概念与Docker中的Volume类似,但不完全相同。具体区别如下:

  • Kubernetes中的Volume与Pod的生命周期相同,但与容器的生命周期不相关。当容器终止或重启时,Volume中的数据也不会丢失。
  • 当Pod被删除时,Volume才会被清理。并且数据是否丢失取决于Volume的具体类型,比如emptyDir类型的Volume数据会丢失,而PV类型的数据则不会丢失。

Kubernetes提供了非常丰富的Volume类型,下面是一些常用的Volume类型:

emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、gitRepo、secret、nfs、iscsi、
glusterfs、persistentVolumeClaim、rbd、flexVolume、cinder、cephfs、flocker、downwardAPI、fc、azureFile、configMap、vsphereVolume

注意,这些 volume 并非全部都是持久化的,比如 emptyDir、secret、gitRepo 等,这些 volume 会随着 Pod 的消亡而消失。


 

二、本地存储

2.1 emptyDir

顾名思义,它的初始内容为空,在同一个Pod中的所有容器均可以读写这个emptyDir volume。

emptyDir类型的volume是在Pod分配到Node时创建的,kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。这个目录的初始内容为空,当 Pod 从 Node 上被删除(Pod 被删除,或者 Pod 发生迁移),emptyDir 也会被删除,并且数据永久丢失。

 一个简单的例子:

创建包含两个容器的busybox pod,每个容器都有映像busybox并运行“sleep 3600”命令。使两个容器都在'/etc/foo'处安装一个空的dir。
连接到第二个busybox,将'/etc/passwd'文件的第一列写入'/etc/foo/passwd'。连接到第一个busybox并将“/etc/foo/passwd”文件写入标准输出
 kubectl run busybox --image=busybox --restart=Never --dry-run -o yaml  -- /bin/sh -c "sleep 3600"  > pod.yaml 
复制粘贴容器定义并键入结尾有注释的行:
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: busybox
  name: busybox
spec:
  dnsPolicy: ClusterFirst
  restartPolicy: Never
  containers:
  - args:
    - /bin/sh
    - -c
    - sleep 3600
    image: busybox
    name: busybox
    resources: {}
    volumeMounts:
    - name: myvolume
      mountPath: /etc/foo
  - args:
    - /bin/sh
    - -c
    - sleep 3600
    image: busybox
    name: busybox2   ### 注意修改成其他名称,不要和上面的名称重复
    volumeMounts:
    - name: myvolume
      mountPath: /etc/foo
  volumes:
  - name: myvolume
    emptyDir: {}
status: {}

创建pod

[root@han-test ckad-test]# kubectl apply -f pod.yaml -n ckad-test 
pod/busybox created
[root@han-test ckad-test]# kubectl get pod -n ckad-test 
NAME      READY   STATUS    RESTARTS   AGE
busybox   2/2     Running   0          35s
[root@han-test ckad-test]# 

连接到第二个容器:

[root@han-test ckad-test]# kubectl -n ckad-test exec busybox -c busybox2 -it  -- /bin/sh 
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # cat /etc/passwd |cut -f 1 -d ":" > /etc/foo/passwd
/ # cat /etc/foo/passwd 
root
daemon
bin
sys
sync
mail
www-data
operator
nobody
/ # exit

连接到第一个容器: 

[root@han-test ckad-test]# kubectl -n ckad-test exec busybox -c busybox -it  -- /bin/sh 
/ # mount |grep foo
/dev/vda1 on /etc/foo type xfs (rw,seclabel,relatime,attr2,inode64,noquota)
/ # cat /etc/foo/passwd 
root
daemon
bin
sys
sync
mail
www-data
operator
nobody
/ # exit
[root@han-test ckad-test]# 

emptyDir类型的volume适合于以下场景:

  • 临时空间。某些应用程序无需永久保存的临时目录,无需永久保存。
  • 一个容器需要从另一容器中获取数据的目录(多容器共享目录)

 


2.2 hostPath

挂载Node文件系统上的文件或者目录到pod中的容器

hostPath类型的volume允许用户挂在Node上的文件系统到Pod中,如果 Pod 需要使用 Node 上的文件,可以使用 hostPath。

 一个简单的例子:

scp pod.yaml hostPath.yaml
这里不再重复,修改相应的volumes行:
vim hostPath.yaml 
...
  volumes:
  - name: myvolume
    hostPath:
      path: /etc/foo
...

创建hostPath pod

[root@han-test ckad-test]# kubectl -n ckad-test delete pod busybox  
pod "busybox" deleted
[root@han-test ckad-test]# kubectl apply -f hostPath.yaml -n ckad-test 
pod/busybox created
[root@han-test ckad-test]# kubectl get pod -n ckad-test 
NAME      READY   STATUS    RESTARTS   AGE
busybox   2/2     Running   0          35s
[root@han-test ckad-test]# 

重复上面操作

[root@han-test ckad-test]# kubectl -n ckad-test exec busybox -c busybox2 -it -- /bin/sh
/ # cat /etc/passwd | cut -f 1 -d ':' > /etc/foo/passwd 
/ # cat /etc/foo/passwd
root
daemon
bin
sys
sync
mail
www-data
operator
nobody
/ # exit
[root@han-test ckad-test]# kubectl -n ckad-test exec busybox -c busybox -it -- /bin/sh 
/ # cat /etc/foo/passwd 
root
daemon
bin
sys
sync
mail
www-data
operator
nobody
/ # exit
[root@han-test ckad-test]#
重复emptyDir例子操作

访问宿主机上的目录文件

[root@han-test ckad-test]# cat /etc/foo/passwd 
root
daemon
bin
sys
sync
mail
www-data
operator
nobody

即使pod删除,文件还是会存在 

hostPath volume通常用于以下场景:

  • 容器中的应用程序产生的日志文件需要永久保存,可以使用宿主机的文件系统进行存储。
  • 需要访问宿主机上Docker引擎内部数据结构的容器应用,通过定义hostPath为/var/lib/docker目录,使容器内应用可以直接访问Docker的文件系统。

在使用hostPath volume时,需要注意:

  • 在不同的Node上具有相同配置的Pod,可能会因为宿主机上的目录和文件不同,而导致对Volume上目录和文件的访问结果不一致。

 


 

 三、网络存储

nfs

NFS 是 Network File System 的缩写,即网络文件系统。Kubernetes 中通过简单地配置就可以挂载 NFS 到 Pod 中,而 NFS 中的数据是可以永久保存的,同时 NFS 支持同时写操作。

volumes:
- name: nfs
  nfs:
    # FIXME: use the right hostname
    server: 10.254.234.223
    path: "/"

 关于静态存储、动态供给,请参考:Kubernetes对象之PersistentVolume,PersistentVolumeClaimStorageClass

参考文章

 

posted @ 2020-05-28 15:27  Pythia丶陌乐  阅读(406)  评论(0编辑  收藏  举报