容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。

一、emptyDir存储卷

容器之间共享数据无持久化

当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除。

vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: demo.pod
  name: demo.pod
spec:                      
  volumes:                    #定义一个存储卷
  - name: tan-vol             #定义存储卷名字
    emptyDir: {}
  containers:
  - image: soscscs/myapp:v1
    name: myapp
    ports:
    - containerPort: 80
    resources: {}
    volumeMounts:
    - name: tan-vol
      mountPath: /mnt/
  - image: busybox:1.28
    name: busybox
    volumeMounts:             #设置挂载数据卷
    - name: tan-vol           #设置挂载数据卷名字
      mountPath: /data/       #设置挂载目录(容器内)
    command:                  #设置操作命令
    - sh
    - -c
    - "while true; do echo '123' >> /data/scj.txt; sleep 2; done"
 
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
 
kubectl apply -f pod.yaml

 拓展:利用emptyDir和ELK实现对k8s容器中的日志进行采集

方案流程

  1. Nginx 容器生成的日志会被写入到挂载在 /var/log/nginx/emptyDir 共享卷中。
  2. Fluentd 或 Filebeat 容器会读取这个共享卷中的日志文件,并将它们转发到 Elasticsearch 集群的服务 IP。
  3. Elasticsearch 接收日志数据,并进行索引和存储。
  4. Kibana 通过与 Elasticsearch 交互,提供对日志数据的可视化界面,帮助用户进行日志分析和排障。

二、hostPath存储卷

hostPath卷将 node 节点的文件系统中的文件或目录挂载到集群中。
hostPath可以实现持久存储,但是在node节点故障时,也会导致数据的丢失。

vim demo3.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: demo3
  name: demo3
spec:
  volumes:
  - name: tanjun-vol
    hostPath:
      path: /data/tangjun
      type: DirectoryOrCreate
  containers:
  - image: soscscs/myapp:v1
    name: myapp
    ports:
    - containerPort: 80
    resources: {}
    volumeMounts:
    - name: tangjun-vol
      mountPath: /usr/share/nginx/html
      readOnly: false
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
 
kubectl apply -f demo3.yaml 

测试不同节点数据是否能共享

vim demo3.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: demo3
  name: demo5-pod               #修改资源名
spec:
  nodeName: node02         #指定node节点创建资源
  volumes:
  - name: tangjun-vol
    hostPath:
      path: /data/tangjun
      type: DirectoryOrCreate
  containers:
  - image: soscscs/myapp:v1
    name: demo
    ports:
    - containerPort: 80
    resources: {}
    volumeMounts:
    - name: tangjun-vol
      mountPath: /usr/share/nginx/html
      readOnly: false
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
 
kubectl apply -f demo3.yaml

拓展:实现hostPath存储卷配合ELK收集k8s集群日志

  1. 在 Kubernetes 集群中,部署了一个运行 Nginx 容器的 Pod。该 Pod 使用了 hostPath 存储卷,将宿主机的一个目录挂载到容器内,作为 Nginx 日志文件的存储路径。
  2. 在宿主机上部署了日志收集工具,如 Filebeat 或 Fluentd,这些工具会持续监控 hostPath 存储卷中生成的日志文件。
  3. 日志收集工具将采集到的日志数据发送到 Elasticsearch 集群中。
  4. Elasticsearch 接收到日志后,对其进行索引和存储,以便后续查询和分析。
  5. 部署 Kibana,Kibana 通过与 Elasticsearch 的集成,提供日志的搜索、过滤和可视化功能,帮助用户分析日志数据。

三、nfs共享存储卷

跨node节点的Pod共享数据

配置nfs,任选一台服务器
 
systemctl disable --now firewalld.service
setenforce 0
 
yum install -y rpcbind nfs-utils
systemctl enable --now rpcbind nfs
mkdir /opt/nfs  #创建共享目录
vim /etc/exports
/opt/nfs 192.168.10.0/24(rw,sync,no_root_squash)
 
exportfs -avr   #共享
     
 
确保两台node节点的rpcbind是开启状态

总结:

Pod存储卷:volumes(与containers字段同一层级)
emptyDir:可实现Pod中的容器之间共享目录数据,但没有持久化数据的能力,存储卷会随着Pod生命周期结束而一并删除

hostPath:将node节点上的目录或文件挂载到Pod容器中,有持久化数据的能力,但是只能在单个node节点上持久化数据,不能实现跨node节点的Pod共享数据

nfs:将nfs服务的共享目录挂载到Pod容器中,有持久化数据的能力,且也能实现跨node节点的Pod共享数据

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐