k8s数据卷 Volume 之 hostPath 与 emptyDir

发布时间 2023-07-27 12:17:44作者: 炎黄子孙,龙的传人

一、为什么需要 volume(数据卷)?

容器中的文件在磁盘上是临时存放的,这给容器中运行比较重要的应用程序带来一些问题。

  • 问题1:当容器升级或者崩溃时,kubelet会重建容器,容器内文件会丢失
  • 问题2:一个Pod中运行多个容器需要共享文件 Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。

二、常用数据卷

  • 本地(hostPath,emptyDir)
  • 网络(NFS,Ceph,GlusterFS)
  • 公有云(AWS EBS)
  • K8S资源(configmap,secret)

三、empryDir

emptyDir卷: 是一个自动创建的、 Pod 所在节点上的临时目录(node上预设定好的存储位置),与Pod生命周期绑定在一起,如果Pod删除了,emptyDir卷也会被删除。
应用场景: Pod中容器之间数据共享,常用于同一个pod内容器(container)之间直接的数据传输。

例子

# 做一个测试yaml
vi emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: write # 业务容器(写数据)
    image: centos
    command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
    volumeMounts:
      - name: data
        mountPath: /data
  - name: read # 辅助容器(读数据)
    image: centos
    command: ["bash","-c","tail -f /data/hello"]
    volumeMounts:
      - name: data
        mountPath: /data
  volumes:
  - name: data
    emptyDir: {}
kubectl apply -f emptydir.yaml

执行后,可以看到两个文件data是共享的,测试可以看到两个文件是共享的。

empryDir在k8s中的存储位置

一般在 /var/lib/kubelet/pods/{pod-id}/volumes/kubernetes.io~empty-dir 下。

四、hostPath

hostPath卷: 挂载Node文件系统(Pod所在节点)上文件或者目录到Pod中的容器。
应用场景: Pod中容器需要访问宿主机文件。但不适合做持久化。

示例

vi hostPath.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  containers:
  - name: write # 业务容器(写数据)
    image: centos
    command: ["bash","-c","for i in {1..1000};do echo $i >> /data/hello;sleep 1;done"]
    volumeMounts:
      - name: data
        mountPath: /ttt
  volumes:
  - name: data
    hostPath:
      path: /tmp
      type: Directory # 文件类型:定义node主机上的 /tmp 是文件夹还是文件。

测试,在 pod 的 /ttt 目录下写入一个123文件后,查看此pod所处节点

# 查看 pod 所在的 node 
kubectl get pods -o wide

进入node1节点tmp下查看

成功

五、emptyDir 与 hostPath 的区别

相同点

  • emptyDir 和 hostPath 类型都可用于 container 之间数据共享。

区别

  • emptyDir 是 pod 级别的。pod 销毁后, emptyDir 也会销毁。

  • emptyDir 被初始化后里面是空的。所有在同一个 pod 中的 container 都可以通过挂载emptyDir后对其进行读写操作。

  • emptyDir 主要用于同一个 pod 中的 container 之间共享数据。(如:log 日志目录)

  • emptyDir 使用 emptyDir 这种 volume 时,一个pod中一般会有2个以上的 container。

  • hostPath 是 node 级别的,node 是持久化的。一个 node 可以创建 N 个 pod 。

emptyDir


apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-app
    image: my-app-image
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  - name: sidecar
    image: busybox
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

hostPath


apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-app
    image: my-app-image
    volumeMounts:
      - name: test-volume
        mountPath: /test-pd
  volumes:
  - name: test-volume 
    hostPath:
      path: /data      # directory on host
      type: Directory  # optional 

# type:
# Other values for type are 'DirectoryOrCreate', 'File', 'FileOrCreate'.