阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Kubernetes中的emptyDir存储卷和节点存储卷

67次阅读
没有评论

共计 7875 个字符,预计需要花费 20 分钟才能阅读完成。

Kubernetes 支持存储卷类型中,emptyDir 存储卷的生命周期与其所属的 Pod 对象相同,它无法脱离 Pod 对象的生命周期提供数据存储功能,因此 emptyDir 通常仅用于数据缓存或临时存储。不过基于 emptyDir 构建的 gitRepo 存储卷可以在 Pod 对象的生命周期起始时从响应的 Git 仓库中复制相应的数据文件到底层的 emptyDir 中,从而使得它具有了一定意义上的持久性。

emptyDir 存储卷

emptyDir 存储卷是 Pod 对象生命周期中的一个临时目录,类似于 Docker 上的docker 挂载卷,在 Pod 对象启动时即被创建,而在 Pod 对象被移除时会被一并删除。不具有持久能力的 emptyDir 存储卷只能用于某些特殊场景中,例如,用一 Pod 内的多个容器间文件的共享,或者作为容器数据的临时存储目录用于数据缓存系统等。

emptyDir 存储卷则定义于.spec.volumes.emptyDir嵌套字段中,可用字段主要包含两个,具体如下:

medium:此目录所在存储介质的类型,可取值为 defaultMemory,默认为 default,表示使用节点的默认存储介质:Memory 表示基于 RAM 的临时文件系统 tmpfs,空间受于内存,但性能非常好,通常用于为容器中的应用提供缓存空间。

sizeLimit:当前存储卷的空间限额,默认值为 nil,表示不限制;不过在 medium 字段为 Memory 时,建议定义此限额。

1. 创建 Pod 对象配置清单

下面是一个使用了 emptyDir 存储卷的简单示例,它保持于 vol-emptydir.yaml 配置文件:

apiVersion: v1
kind: Pod
metadata:
  name: vol-emptydir-pod
spec:
  volumes:
  - name: html
    emptyDir: { }
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  - name: pagegen
    image: alpine
    volumeMounts:
    - name: html
      mountPath: /html
    command: ["/bin/sh", "-c"]
    args:                        #定义循环,每 10 秒向 /html/ 文件中追加写入当前主机名和时间
    - while true; do
        echo $(hostname) $(date) >> /html/index.html;
        sleep 10;
      done

上面示例中定义的存储卷名称为 html,挂载于容器 nginx 的 /usr/share/nginx/html 目录,以及容器 pagegen 的 /html 目录。容器 pagegen 每隔 10 秒向存储卷上的 index.html 文件中追加一行信息,而容器 nginx 中的 nginx 进程则以其站点主页。如下图所示:

Kubernetes 中的 emptyDir 存储卷和节点存储卷

2. 创建 Pod 对象

kubectl apply -f vol-emptydir.yaml

3. 查看 Pod 状态 Pod 对象的详细信息中会显示存储卷的相关状态,包括其是否创建成功(在 Events 字段中输出)、相关的类型及参数(在 Volumes 字段中输出) 以及容器中挂载状态等信息(在 Containers 字段中输出),如下面命令所示:

kubectl describe pods/vol-emptydir-pod
Containers:
  nginx:
    Mounts:
      /usr/share/nginx/html from html (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-xxqkj (ro)
  pagegen:
    Command:
      /bin/sh
      -c
    Args:
      while true; do echo $(hostname) $(date) >> /html/index.html; sleep 10; done
    Mounts:
      /html from html (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-xxqkj (ro)

4. 访问 Pod 中 Nginx pagegen 容器每隔 10 秒向 html/index.html 追加写入信息,Nginx 容器挂载的也是此临时存储,所以 Nginx 的网页文件也是从这里获取。

curl http://172.20.1.18
vol-emptydir-pod Fri Jun 12 02:47:29 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:39 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:49 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:59 UTC 2020
vol-emptydir-pod Fri Jun 12 02:48:09 UTC 2020
vol-emptydir-pod Fri Jun 12 02:48:19 UTC 2020

5. 进入容器 以下分别进入 Nginx 容器以及 pagegen 容器查看其挂载

通过 -c 来指定容器名称进入指定容器

kubectl exec -it pods/vol-emptydir-pod -c nginx -- /bin/sh
# ls /usr/share/nginx/html
index.html
# head -3 /usr/share/nginx/html/index.html
vol-emptydir-pod Fri Jun 12 02:47:29 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:39 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:49 UTC 2020

进入 pagegen 容器

kubectl exec -it pods/vol-emptydir-pod -c pagegen -- /bin/sh
/ # ls /html/
index.html
/ # head -3 /html/index.html
vol-emptydir-pod Fri Jun 12 02:47:29 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:39 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:49 UTC 2020
/ # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh -c while true; do echo $(hostname) $(date) >> /html/index.html; sleep 10; done
  286 root      0:00 /bin/sh
  303 root      0:00 sleep 10
  304 root      0:00 ps aux

作为边车(sidecar)的容器 pagegen,其每隔 10 秒生成一行信息追加到存储卷上的 index.html 文件中,因此,通过主容器 nginx 的应用访问到文件内存也会处理不停的变动中。另外,emptyDir 存储卷也可以基于 RAM 创建 tmpfs 文件系统的存储卷,常用于为容器的应用提高高性能缓存,下面是一个配置示例:

cat vol-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: vol-emptydir-pod
spec:
  volumes:
  - name: html
    emptyDir:
      medium: Memory                #指定临时存储到内存
      sizeLimit: 256Mi              #给予的内存空间大小
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  - name: pagegen
    image: alpine
    volumeMounts:
    - name: html
      mountPath: /html
    command: ["/bin/sh", "-c" ]
    args:
    - while true; do
        echo $(hostname) $(date) >> /html/index.html;
        sleep 10;
      done

emptyDir 卷简单易用,但仅能用于临时存储,另外还存在一些类型的存储卷构建在 emptyDir 之上,并额外提供了 emptyDir 没有的功能。

节点存储卷 hostPath

hostPath 类型的存储卷是指将工作节点上某文件系统的目录或文件挂载于 Pod 中的一种存储卷,它可独立于 Pod 资源的生命周期,因而具有持久性。但它是工作节点本地的存储空间,仅适用于特定情况下的存储卷使用需求,例如,将工作节点上的文件系统关联为 Pod 的存储卷,从而使得容器访问接待您文件系统上的数据。这一点在运行有管理任务的系统级 Pod 资源需要访问节点上的文件时比较有用。

配置 hostPath 存储卷的嵌套字段共有两个:一个是用于指定工作节点上的目录路径的必须按字段 path 一个是指定存储卷类型的 type,它支持使用的卷类型包含如下几种:

•DirectoryOrCreate:指定的路径不存在时自动将其创建为权限是 0755 的空目录,属主属组均为 kubelet。

•Directory:必须存在的目录路径

•FileOrCreate:指定的路径不存在时自动将其创建为权限 0644 的空文件,属主和属组同是 kubelet。

•File:必须存在的文件路径

•Socket:必须存在的 Socket 文件路径

•CharDevice:必须存在的字符设备文件路径

•BlockDevice:必须存在的块设备文件路径

Kubernetes 中的 emptyDir 存储卷和节点存储卷

下面是定义在 vo-hostpath.yaml 配置文件中的 Pod 资源,它运行着日志收集代理应用 filebeat,负责收集工作节点及容器相关的日志信息发往 Redis 服务器,它使用了三个 hostPath 类型的存储卷:

1. 创建资源配置清单

apiVersion: v1
kind: Pod
metadata:
  name: vo-hostpath-pod
spec:
  containers:
  - name: filebeat
    image: ikubernetes/filebeat:5.6.7-alpine
    env:                            #定义变量
    - name: REDIS_HOST              #变量名
      value: redis.ilinux.io:6379   #变量值
    - name: LOG_LEVEL                   #变量明
      value: info                   #变量值
    volumeMounts:                   #卷挂载配置
    - name: varlog                  #挂载名称为 varlog 的卷
      mountPath: /var/log           #挂载到容器中的 /var/log 目录中
    - name: socket                  #挂载名称为 socket 的卷
      mountPath: /var/run/docker.sock# 挂载到容器中的 /var/run/docker.sock
    - name: varlibdockercontainers  #挂载名称为 varlibdockercontainers 的卷
      mountPath: /var/lib/docker/containers# 挂载到容器中的 /var/lib/docker/containers 目录中
      readOnly: true                #为只读挂载
  volumes:                          #卷配置
  - name: varlog                    #自定义的卷名称
    hostPath:                       #节点路径配置
      path: /var/log                #在节点上的路径
      type: DirectoryOrCreate        #节点上不存在 /var/log 目录时,则自动创建权限为 0755 的目录,属性信息为 kubelet 用户
  - name: varlibdockercontainers
    hostPath:
      path: /var/lib/docker/containers
      type: Directory
  - name: socket
    hostPath:
      path: /var/run/docker.sock
      type: Socket                        #节点上必须存在 /var/run/docker.sock,否则创建 Pod 失败

2. 创建 Pod 对象

kubectl apply -f vo-hostpath.yaml

3. 查看 Pod 对象详细信息 如下命令可以到 Pod 的挂载信息

kubectl describe pods/vo-hostpath-pod | grep -A 12 Volumes
Volumes:
  varlog:
    Type:          HostPath (bare host directory volume)
    Path:          /var/log
    HostPathType:
  varlibdockercontainers:
    Type:          HostPath (bare host directory volume)
    Path:          /var/lib/docker/containers
    HostPathType:
  socket:
    Type:          HostPath (bare host directory volume)
    Path:          /var/run/docker.sock
    HostPathType:

如下这台 Pod 运行在了 Node02 节点之上,那么就会把 Node02 上的 /var/log、/var/lib/docker/containers 目录以及 /var/run/docker.sock 文件挂载至我们创建的 Pod 之中。

kubectl get pods -o wide | grep vo-hostpath-pod
vo-hostpath-pod               1/1     Running            0          3m37s   172.20.2.28   k8s-node02   <none>           <none>

4. 进入 Pod 查看挂载信息


kubectl exec -it pods/vo-hostpath-pod -- /bin/sh

#查看 /var/log
/ # ls /var/log
alternatives.log          chrony                    kern.log                  syslog.2.gz               vmware-vmsvc-root.1.log
alternatives.log.1        cloud-init-output.log     kern.log.1                syslog.3.gz               vmware-vmsvc-root.2.log
apt                       cloud-init.log            kern.log.2.gz             syslog.4.gz               vmware-vmsvc-root.3.log
auth.log                  containers                kern.log.3.gz             syslog.5.gz               vmware-vmsvc-root.log
auth.log.1                dist-upgrade              kern.log.4.gz             syslog.6.gz               vmware-vmtoolsd-root.log
auth.log.2.gz             dpkg.log                  landscape                 syslog.7.gz               wtmp
auth.log.3.gz             dpkg.log.1                lastlog                   tallylog                  wtmp.1
auth.log.4.gz             dpkg.log.2.gz             lxd                       unattended-upgrades
bootstrap.log             faillog                   pods                      vmware-network.1.log
btmp                      installer                 syslog                    vmware-network.2.log
btmp.1                    journal                   syslog.1                  vmware-network.log

#查看 /var/lib/docker/containers 信息
/ # ls  /var/lib/docker/containers/
222ff7ab4b939691d4690ebd353e4dae39782d48dba190f6473d02f65e35e9c5  9b362d8f03d2f87573487a8d6a266c1a77b6e2cfb28654ba5a3016008155564f
2ddb2bd4c2dfd44b48a430502e8f0479651ac2084b14070c7bd6f128907e6d27  d2e2af23b3a406d941a1f19a989c6a529b7cfda32a75579ff171148e3bce771d
2f0c31b8e6fff99953a096af8153b37b572f71a3e98a9e09665486b6ca6d940f  e0d8e9913767ef45c700648f20f025440f1313be242b6f0cf3577b1b92d61acb
31baeb1aef75acf16544042add63293e8547008c1ae1d40ab62f8fd24fa203a4  ee09c6588feb6665d24f61a887fe4a9d4df366625f80e9b7b0520c6066b3a754
3dbada0509671af1193b39b86f72d1ed9022914f7ba7886bd975cfa70c554559  ef1fcc1b0de6817b2d2c8b81a187e72a93c960c816ee118bf5ba9d1a07fff7d6
47686a866a3e9f1e0b82bb582072c612b95ea0d1c68951ea44b3f751eb49dbcb  f52a7a55801bec13b26f2c02fbc5c32cb758f690de5480ff246f379ebbb3fac7
6bc85638f22115f3479ef025b94159a7d8e5e5988fb508c28d118f510c767e0f  f6b5e6bc12ba8121d2aceca137eaf31929d46664648154b45800697a8bd5a23c
9afc7bb18dc7d858f514ec001ad47c6fd6d5ac67f25aa0e777c4762b9ccfaf45

#查看 /var/run/docker.sock 文件
/ # ls -lrth  /var/run/docker.sock
srw-rw----    1 root     ping           0 May  8 03:27 /var/run/docker.sock
/ # exit;

这类 Pod 资源通常受控于 daemonset 类型的 Pod 控制器,它运行于集群中的每个工作节点之上,负责收集工作节点上系统级的相关逐句,因此使用 hostPath 存储卷也是理所应当的。

读者在创建上述 Pod 资源时,如果有可用的 Redis 服务器,则可通过 REDIS_HOST 传递给 Pod 资源,待其 Ready 之后即可通过 Redis 服务器查看到由其发送的日志信息。在 filebeat 应用架构中。这些日志信息会发到 Elasticsearch,并通过 Kibana 进行展示。

另外,使用 hostPath 存储卷时需要注意到,不同节点上的文件或许并不完全相同,于是,那些要求事先必须存在的文件或目录的满足状态也可能会有所不同;另外基于资源可用状态的调度器 Pod 时,hostPath 资源的可用性状态不会被考虑在内;再者,在节点中创建的文件或目录默认仅有 root 可写,若期望容器内的进程拥有写权限,则要么将它们运行为特权容器,要么修改节点上的目录权限。

那些并非执行系统级管理任务的且不受控于 Daemonset 控制器的无状态应用在 Pod 资源被重新调度至其它节点运行时,此前创建的文件或目录大多数都不会存在。因此 hostPath 存储卷虽然能持久保存数据,但对被调度器按需调度的应用来说并不适用,这时需要用到的是独立于集群节点的持久性存储卷、即网络存储卷。

好啦!今天的分享到这里就结束了,希望大家持续关注马哥教育官网,每天都会有大量优质内容与大家分享!

文章来源于网络,侵删!

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-12-03发表,共计7875字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中