自学内容网 自学内容网

k8s 中存储之 emptyDir 卷

目录

1 kubernets支持的卷的类型

2 emptyDir 卷介绍

2.1 emptyDir 的使用场景:

2.2 emptyDir 卷的功能:

3 emptyDir 卷实现容器间数据共享

3.1 实验介绍

3.2 创建 Pod 清单文件

3.3 修改 Pod 清单文件

3.4 声明清单文件并查看 Pod 是否正确创建

3.5 修改容器内的配置实现容器间数据共享性

3.6 测试同一个 Pod 之间数据是否共享


1 kubernets支持的卷的类型

官网:卷 | Kubernetes容器中的文件在磁盘上是临时存放的,这给在容器中运行较重要的应用带来一些问题。 当容器崩溃或停止时会出现一个问题。此时容器状态未保存, 因此在容器生命周期内创建或修改的所有文件都将丢失。 在崩溃期间,kubelet 会以干净的状态重新启动容器。 当多个容器在一个 Pod 中运行并且需要共享文件时,会出现另一个问题。 跨所有容器设置和访问共享文件系统具有一定的挑战性。Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。阅读本文前建议你熟悉一下 Pod。背景 Kubernetes 支持很多类型的卷。 Pod 可以同时使用任意数目的卷类型。 临时卷类型的生命周期与 Pod 相同, 但持久卷可以比 Pod 的存活期长。 当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不过 Kubernetes 不会销毁持久卷。 对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。卷的核心是一个目录,其中可能存有数据,Pod 中的容器可以访问该目录中的数据。 所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。使用卷时, 在 .spec.volumes 字段中设置为 Pod 提供的卷,并在 .spec.containers[*].volumeMounts 字段中声明卷在容器中的挂载位置。 容器中的进程看到的文件系统视图是由它们的容器镜像 的初始内容以及挂载在容器中的卷(如果定义了的话)所组成的。 其中根文件系统同容器镜像的内容相吻合。 任何在该文件系统下的写入操作,如果被允许的话,都会影响接下来容器中进程访问文件系统时所看到的内容。卷挂载在镜像中的指定路径下。 Pod 配置中的每个容器必须独立指定各个卷的挂载位置。卷不能挂载到其他卷之上(不过存在一种使用 subPath 的相关机制),也不能与其他卷有硬链接。卷类型 Kubernetes 支持下列类型的卷:awsElasticBlockStore (已弃用) 在 Kubernetes 1.31 中,所有针对树内 awsElasticBlockStore 类型的操作都会被重定向到 ebs.csi.aws.com CSI 驱动。icon-default.png?t=O83Ahttps://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

2 emptyDir 卷介绍

2.1 emptyDir 的使用场景:

  • 缓存空间,例如基于磁盘的归并排序。

  • 耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。

  • 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。

2.2 emptyDir 卷的功能:

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

emptyDir 用于在 Pod 中实现容器之间的数据共享。与Pod的生命周期一致,当 Pod 被删除时,这个目录页会被删除。

例如,如果在一个 Pod 中有两个容器,其中一个容器需要读取另一个容器中的数据,那么这可以使用emptyDir 卷来实现。容器之间的数据共享如下图所示

3 emptyDir 卷实现容器间数据共享

3.1 实验介绍

使用两个容器组成一个 Pod 用 emptyDir 卷 实现 同 Pod 之间的数据共享

使用 busybox 和 nginx  容器 组成一个Pod

3.2 创建 Pod 清单文件

命令只支持单一容器的Pod创建。对于多容器的Pod 只能手动添加第二个容器的部分。

[root@k8s-master volumes]# kubectl run emptydir \
--image busyboxplus:latest \
--dry-run=client -o yaml > emptydir.yml

3.3 修改 Pod 清单文件

同样的volumes卷也不支持使用命令创建 只能增加 volumes 卷相应配置

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: emptydir
  name: emptydir
spec:
  volumes:
  # 这里定义了一个名为 cache-vol 的存储卷,并且指定了其类型为 emptyDir
  # emptyDir 类型的卷会在 Pod 被调度到节点上时自动创建,
  # 如果 Pod 重新调度到另一个节点,数据会被保留。
  - name: cache-vol
    emptyDir:
      medium: "" # 这里可以指定存储介质,如 memory 或者默认的磁盘存储。留空表示使用默认设置。
      sizeLimit: 1Gi    # 这里设置了卷的最大大小限制为 1GiB
  containers:
  # 第一个容器,使用 busyboxplus 镜像
  - image: busyboxplus:latest
    name: vm-1
    command: ["/bin/sh","-c","sleep 30000000"] # 这里设置了一个长延时命令,使得容器持续运行
    volumeMounts:
    # 将前面定义的 cache-vol 卷挂载到容器内的 /cache 路径
    - mountPath: /cache
      name: cache-vol
  # 第二个容器,使用 nginx 镜像
  - image: nginx:latest
    name: vm-2
    volumeMounts:
    # 同样的 cache-vol 卷也被挂载到第二个容器内的 /usr/share/nginx/html 路径
    # 这样两个容器就可以共享这个卷中的数据了
    - mountPath: /usr/share/nginx/html
      name: cache-vol

3.4 声明清单文件并查看 Pod 是否正确创建

[root@k8s-master volumes]# kubectl apply -f emptydir.yml 

[root@k8s-master volumes]# kubectl get pods -o wide 
NAME                       READY   STATUS      RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
emptydir                   2/2     Running     0          100s    10.244.2.62   k8s-node2   <none>           <none>
nginx-v1-dbd4bc45b-49hhw   1/1     Running     0          3d17h   10.244.2.54   k8s-node2   <none>           <none>
nginx-v2-bd85b8bc4-nqpv2   1/1     Running     0          3d17h   10.244.1.35   k8s-node1   <none>           <none>
testpod                    0/1     Completed   0          3d4h    10.244.2.58   k8s-node2   <none>           <none>

# 查看详细信息
[root@k8s-master volumes]# kubectl describe pods emptydir 
Name:             emptydir
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node2/192.168.239.120
Start Time:       Sun, 06 Oct 2024 15:36:13 +0800
Labels:           run=emptydir
Annotations:      <none>
Status:           Running
IP:               10.244.2.62
IPs:
  IP:  10.244.2.62
Containers:
  vm-1:
    Container ID:  docker://3753f0470e30bc30302cd6dbf6a53f7ad2d870a6b35a537816091b3c993441d4
    Image:         busyboxplus:latest
    Image ID:      docker-pullable://busyboxplus@sha256:9d1c242c1fd588a1b8ec4461d33a9ba08071f0cc5bb2d50d4ca49e430014ab06
    Port:          <none>
    Host Port:     <none>
    Command:
      /bin/sh
      -c
      sleep 30000000
    State:          Running
      Started:      Sun, 06 Oct 2024 15:36:14 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /cache from cache-vol (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-jnl6t (ro)
  vm-2:
    Container ID:   docker://0596c82e0e086cf4cc2d668c271067332211d0d439695f2419f1385d03caaa09
    Image:          nginx:latest
    Image ID:       docker-pullable://nginx@sha256:127262f8c4c716652d0e7863bba3b8c45bc9214a57d13786c854272102f7c945
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 06 Oct 2024 15:36:15 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /usr/share/nginx/html from cache-vol (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-jnl6t (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  cache-vol:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  <unset>
  kube-api-access-jnl6t:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  118s  default-scheduler  Successfully assigned default/emptydir to k8s-node2
  Normal  Pulling    117s  kubelet            Pulling image "busyboxplus:latest"
  Normal  Pulled     117s  kubelet            Successfully pulled image "busyboxplus:latest" in 89ms (89ms including waiting). Image size: 12855024 bytes.
  Normal  Created    117s  kubelet            Created container vm-1
  Normal  Started    117s  kubelet            Started container vm-1
  Normal  Pulling    117s  kubelet            Pulling image "nginx:latest"
  Normal  Pulled     117s  kubelet            Successfully pulled image "nginx:latest" in 75ms (75ms including waiting). Image size: 187694648 bytes.
  Normal  Created    117s  kubelet            Created container vm-2
  Normal  Started    116s  kubelet            Started container vm-2


# 测试 Pod 是否可以访问,由于是新的卷挂载上去会覆盖了原先的nginx里的index.html
[root@k8s-master volumes]# curl 10.244.2.62
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>

3.5 修改容器内的配置实现容器间数据共享性

# 进入 busyboxplus 容器
[root@k8s-master volumes]# kubectl exec -it pods/emptydir -c vm-1 -- /bin/sh
/ # ls 
bin      cache    dev      etc      home     lib      lib64    linuxrc  media    mnt      opt      proc     root     run      sbin     sys      tmp      usr      var
/ # cd cache/

# 增加一个 index.html 文件
# 注意:在这里添加文件就相当于在 nginx 容器 /usr/share/nginx/html/ 中添加文件
# 因为选择的 emptyDir 卷是同一个,这样就实现了容器间数据的共享性
/cache # echo this is at vm-1 container write nginx html file apply to vm-2 container > index.html

# ctrl + pq 退出这个容器
/cache # exec attach failed: error on attach stdin: read escape sequence
command terminated with exit code 126


# 进入 nginx 容器
[root@k8s-master volumes]# kubectl exec -it pods/emptydir -c vm-2 -- /bin/sh
# ls 
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 查看 nginx 容器中的 index.html 是否存在
# ls /usr/share/nginx/html
index.html

3.6 测试同一个 Pod 之间数据是否共享

# 查看 Pod 的IP地址
[root@k8s-master volumes]# kubectl get pods -o wide
NAME                       READY   STATUS      RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
emptydir                   2/2     Running     0          8m1s    10.244.2.62   k8s-node2   <none>           <none>
nginx-v1-dbd4bc45b-49hhw   1/1     Running     0          3d17h   10.244.2.54   k8s-node2   <none>           <none>
nginx-v2-bd85b8bc4-nqpv2   1/1     Running     0          3d17h   10.244.1.35   k8s-node1   <none>           <none>
testpod                    0/1     Completed   0          3d4h    10.244.2.58   k8s-node2   <none>           <none>

# 访问 Pod
[root@k8s-master volumes]# curl 10.244.2.62 
this is at vm-1 container write nginx html file apply to vm-2 container


# 进入 busyboxplus 中访问本地发现去访问了 nginx ,这是因为同一个 Pod 之间的网络是共享的,
# 他们处于同一个网络栈中,实现了 Pod 之间的网络共享性
[root@k8s-master volumes]# kubectl exec -it pods/emptydir -c vm-1 -- /bin/sh

/ # curl localhost
this is at vm-1 container write nginx html file apply to vm-2 container


原文地址:https://blog.csdn.net/weixin_68398469/article/details/142728018

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!