1.4.1 通过emptyDir共享数据

EmptyDir是一个特殊的Volume类型,与上述Volume不同的是,如果删除Pod,emptyDir卷中的数据也将被删除,所以一般emptyDir用于Pod中的不同Container共享数据,比如一个Pod存在两个容器A和B,容器A需要使用容器B产生的数据,此时可以采用emptyDir共享数据,类似的使用如Filebeat收集容器内程序产生的日志。

默认情况下,emptyDir 卷支持节点上的任何介质,可能是 SSD、磁盘或网络存储,具体取 决于自身的环境。可以将 emptyDir.medium 字段设置为 Memory,让 Kubernetes 使用 tmpfs(内存支持的文件系统),虽然 tmpfs 非常快,但是 tmpfs 在节点重启时,数据同样会被清除,并且 设置的大小会被计入到 Container 的内存限制当中。

1.4.1.1 使用磁盘类型的emptyDir

1.定义一个yaml文件

[root@k8s-master01 practice]# vim emptydir.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /opt
          name: share-volume
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx2
        command:
        - sh
        - -c
        - sleep 3600
        volumeMounts:
        - mountPath: /mnt
          name: share-volume
      volumes:
      - name: share-volume
        emptyDir: {}
          #medium: Memory

2.重新部署

[root@k8s-master01 practice]# kubectl apply -f emptydir.yaml 

3.查看pod状态

[root@k8s-master01 practice]# kubectl get po
NAME                     READY   STATUS    RESTARTS      AGE
nginx-7c59fc85f5-vzdkp   2/2     Running   0          8s

4.验证-进入nginx的容器创建文件后,在nginx2容器查看 (1)进入nginx容器后,进入/opt目录下创建123文件

[root@k8s-master01 practice]# kubectl exec -it nginx-7c59fc85f5-vzdkp  -c nginx -- sh
root@nginx-d8f544fdd-qgllm:/# cd /opt
root@nginx-d8f544fdd-qgllm:/opt# touch 123

(2)进入nginx2容器后,进入/mnt目录下查看123文件是否创建成功

[root@k8s-master01 practice]# kubectl exec -it nginx-7c59fc85f5-vzdkp  -c nginx2 -- sh
root@nginx-d8f544fdd-qgllm:/# cd /mnt/
root@nginx-d8f544fdd-qgllm:/mnt# ls
123

(3)进入nginx2容器后,进入/mnt目录下查看文件系统类型,观察到当 emptyDir 未指定存储介质(即使用默认的磁盘存储)时,其底层文件系统为 节点磁盘的本地文件系统(如 xfsext4btrfs 等)。

[root@k8s-master01 practice]# kubectl exec -it nginx-7c59fc85f5-vzdkp  -c nginx2 -- sh
root@nginx-d8f544fdd-qgllm:/# df -Th
Filesystem           Type            Size      Used Available Use% Mounted on
overlay              overlay        61.2G      6.3G     54.9G  10% /
tmpfs                tmpfs          64.0M         0     64.0M   0% /dev
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /mnt
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /etc/hosts
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /dev/termination-log
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /etc/hostname
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /etc/resolv.conf
shm                  tmpfs          64.0M         0     64.0M   0% /dev/shm
tmpfs                tmpfs           7.6G     12.0K      7.6G   0% /run/secrets/kubernetes.io/serviceaccount
tmpfs                tmpfs           3.9G         0      3.9G   0% /proc/asound
tmpfs                tmpfs           3.9G         0      3.9G   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           3.9G         0      3.9G   0% /proc/scsi
tmpfs                tmpfs           3.9G         0      3.9G   0% /sys/firmware

1.4.1.2 使用内存类型的emptyDir

1.定义一个yaml文件

[root@k8s-master01 practice]# vim emptydir.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /opt
          name: share-volume
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx2
        command:
        - sh
        - -c
        - sleep 3600
        volumeMounts:
        - mountPath: /mnt
          name: share-volume
      volumes:
      - name: share-volume
        emptyDir: 
          medium: Memory

2.重新部署

[root@k8s-master01 practice]# kubectl apply -f emptydir.yaml 

3.查看pod状态

[root@k8s-master01 ~]# kubectl get po
NAME                     READY   STATUS    RESTARTS   AGE
nginx-74c5b95ffd-txvd7   2/2     Running   0          107s

4.验证-进入nginx的容器创建文件后,在nginx2容器查看 (1)进入nginx容器后,进入/opt目录下创建123文件

[root@k8s-master01 practice]# kubectl exec -it nginx-74c5b95ffd-txvd7 -c nginx -- sh
root@nginx-d8f544fdd-qgllm:/# cd /opt
root@nginx-d8f544fdd-qgllm:/opt# touch 123

(2)进入nginx2容器后,进入/mnt目录下查看123文件是否创建成功

[root@k8s-master01 practice]# kubectl exec -it nginx-74c5b95ffd-txvd7 -c nginx2 -- sh
root@nginx-d8f544fdd-qgllm:/# cd /mnt/
root@nginx-d8f544fdd-qgllm:/mnt# ls
123

(3)进入nginx2容器后,查看文件系统类型,观察到当显式指定 emptyDirmediumMemory 时,Kubernetes 会使用 tmpfs(内存文件系统)作为存储介质。

[root@k8s-master01 practice]# kubectl exec -it nginx-74c5b95ffd-txvd7 -c nginx2 -- sh
root@nginx-d8f544fdd-qgllm:/# df -Th
Filesystem           Type            Size      Used Available Use% Mounted on
overlay              overlay        61.2G      6.3G     54.9G  10% /
tmpfs                tmpfs          64.0M         0     64.0M   0% /dev
tmpfs                tmpfs           7.6G         0      7.6G   0% /mnt
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /etc/hosts
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /dev/termination-log
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /etc/hostname
/dev/mapper/rl_bogon-root
                     xfs            61.2G      6.3G     54.9G  10% /etc/resolv.conf
shm                  tmpfs          64.0M         0     64.0M   0% /dev/shm
tmpfs                tmpfs           7.6G     12.0K      7.6G   0% /run/secrets/kubernetes.io/serviceaccount
tmpfs                tmpfs           3.9G         0      3.9G   0% /proc/asound
tmpfs                tmpfs           3.9G         0      3.9G   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           3.9G         0      3.9G   0% /proc/scsi
tmpfs                tmpfs           3.9G         0      3.9G   0% /sys/firmware

1.4.1.3 EmptyDir大小限制

两种类型的 EmptyDir 都支持限制卷的大小,只需要添加 sizeLimit 字段即可:

...
...
      volumes:
      - name: share-volume
        emptyDir: 
          medium: Memory
          sizeLimit: 10Mi
1.4.1.3.1 使用磁盘类型的emptyDir限制大小

1、编写yaml文件,并设置emptyDir限制大小为10M

[root@k8s-master01 practice]# vim emptydir.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /opt
          name: share-volume
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx2
        command:
        - sh
        - -c
        - sleep 3600
        volumeMounts:
        - mountPath: /mnt
          name: share-volume
      volumes:
      - name: share-volume
        emptyDir: 
          sizeLimit: 10Mi  # 修改点:添加存储限制

2、应用并验证

# 创建
[root@k8s-master01 practice]# kaf emptydir.yaml 

# 查看pod
[root@k8s-master01 ~]# kgp
NAME                    READY   STATUS    RESTARTS   AGE
nginx-8fc5b4675-jc9cj   2/2     Running   0          15s

# 观察到虽然限制大小为10m,但是实际查看没有进行限制,但是在mnt目录下创建大于10M以上的文件会导致pod状态由running变为completed(某种场景下可以用于清除日志)
[root@k8s-master01 ~]# k exec -it nginx-8fc5b4675-jc9cj -c nginx2 -- / # df -h | grep mnt
                         61.2G      6.3G     54.9G  10% /mnt
/ # dd if=/dev/zero of=/mnt/file bs=1M count=20
/ # ls -lh file
-rw-r--r--    1 root     root       20.0M Mar 20 13:11 file
/ # exit

# 观察到新起一个pod,同时原本的pod状态由Running变为ContainerStatusUnknown
[root@k8s-master01 ~]# kgp
NAME                    READY   STATUS                   RESTARTS   AGE
nginx-8fc5b4675-5b5fz   2/2     Running                  0          4m35s
nginx-8fc5b4675-jc9cj   0/2     ContainerStatusUnknown   1          26m

# 再次查看pod异常情况,提示文件大小超出10Mi
[root@k8s-master01 ~]# kd po nginx-8fc5b4675-jc9cj
...
...
  Normal   Created    29m    kubelet            Created container: nginx2
  Normal   Started    29m    kubelet            Started container nginx2
  Warning  Evicted    7m11s  kubelet            Usage of EmptyDir volume "share-volume" exceeds the limit "10Mi".

3、环境复原

[root@k8s-master01 practice]# k delete -f emptydir.yaml
1.4.1.3.2 使用内存类型的emptyDir限制大小

1、编写yaml文件,并设置emptyDir限制大小为10M

[root@k8s-master01 practice]# vim emptydir.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /opt
          name: share-volume
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx2
        command:
        - sh
        - -c
        - sleep 3600
        volumeMounts:
        - mountPath: /mnt
          name: share-volume
      volumes:
      - name: share-volume
        emptyDir: 
          medium: Memory
          sizeLimit: 10Mi

2、应用并验证

# 创建
[root@k8s-master01 practice]# kaf emptydir.yaml 

# 查看pod
[root@k8s-master01 ~]# kgp
NAME                    READY   STATUS    RESTARTS   AGE
nginx-b9dcb48dd-rx8qn   2/2     Running   0          9s

# 观察到限制大小为10m
[root@k8s-master01 practice]# kubectl exec -it nginx-b9dcb48dd-rx8qn -c nginx2 -- sh
/ # df -h | grep mnt
tmpfs                    10.0M         0     10.0M   0% /mnt

3、环境复原

[root@k8s-master01 practice]# k delete -f emptydir.yaml

1.4.1.4 小结

关于使用磁盘的emptyDir和使用内存的emptyDir对比如下:

  • 1)使用磁盘的emptyDir,限制大小后不会显示具体限制的大小
  • 2)使用磁盘的emptyDir,文件系统类型为节点磁盘的本地文件系统类型
  • 3)使用磁盘的emptyDir,超出最大限制时,Pod 将会变成 Completed 状态,同时将会创建一个POD
  • 4)使用内存的emptyDir,不会超出限制的大小,如不限制将会使用机器内存的最大值,或容器内存限制之和的最大值
  • 5)使用内存的emptyDir,文件系统类型为tmpfs