文章目录
Kubernetes 存储
Volume 与存储卷详解
背景
容器磁盘上的文件生命周期是短暂的,这会导致以下问题:
- 容器崩溃时数据丢失:当容器崩溃后,kubelet 会重启容器,但容器中的文件会丢失,恢复到镜像的初始状态。
- 多容器间文件共享需求:在同一个 Pod 中运行的多个容器通常需要共享文件。
Kubernetes 通过 Volume 抽象 解决了这些问题。Pod 中的容器通过 Pause 容器 共享 Volume,从而实现数据的持久化和共享。
emptyDir 存储卷
- 特点:
- 当 Pod 被分配到节点时,emptyDir 卷会被创建。
- 只要 Pod 在该节点上运行,emptyDir 卷就会存在。
- 卷最初是空的,Pod 中的容器可以读取和写入 emptyDir 卷中的相同文件。
- 当 Pod 从节点中删除时,emptyDir 中的数据会被永久删除。
- 适用场景:
- 临时数据存储。
- 多容器间文件共享。
emptyDir 存储卷示例
- 创建 YAML 文件
在/opt/volumes
目录下创建pod-emptydir.yaml
文件:apiVersion: v1 kind: Pod metadata: name: pod-emptydir namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /data/ command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done'] volumes: - name: html emptyDir: { }
- 应用 YAML 文件
使用以下命令创建 Pod:kubectl apply -f pod-emptydir.yaml
- 查看 Pod 状态
确认 Pod 已成功运行:
输出示例:kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-emptydir 2/2 Running 0 36s 10.244.2.19 node02 <none> <none>
- 验证数据共享
busybox
容器会每隔 2 秒将当前日期写入/data/index.html
文件。myapp
容器通过挂载的 emptyDir 卷读取/usr/share/nginx/html/index.html
文件。- 使用
curl
命令访问 Nginx 服务,验证是否能够获取日期信息:
输出示例:curl 10.244.2.19
Thu May 27 18:17:11 UTC 2021 Thu May 27 18:17:13 UTC 2021 Thu May 27 18:17:15 UTC 2021 Thu May 27 18:17:17 UTC 2021 Thu May 27 18:17:19 UTC 2021 Thu May 27 18:17:21 UTC 2021 Thu May 27 18:17:23 UTC 2021
hostPath 存储卷
- 功能:将 Node 节点上的文件或目录挂载到 Pod 中。
- 特点:
- 实现持久化存储,但数据与 Node 节点绑定。
- 如果 Node 节点故障,数据会丢失。
- 适用于单节点数据持久化或调试场景。
hostPath 存储卷示例
-
在 Node 节点上创建挂载目录
- 在
node01
上:mkdir -p /data/pod/volume1 echo 'node01.xy101.com' > /data/pod/volume1/index.html
- 在
node02
上:mkdir -p /data/pod/volume1 echo 'node02.xy101.com' > /data/pod/volume1/index.html
- 在
-
创建 Pod 资源 YAML 文件
apiVersion: v1 kind: Pod metadata: name: pod-hostpath namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html readOnly: false volumes: - name: html hostPath: path: /data/pod/volume1 type: DirectoryOrCreate
-
应用 YAML 文件
kubectl apply -f pod-hostpath.yaml
-
验证 Pod 状态
kubectl get pods -o wide
输出示例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-hostpath 1/1 Running 0 37s 10.244.2.35 node02 <none> <none>
-
访问测试
curl 10.244.2.35
输出示例:
node02.xy101.com
-
验证数据持久化
- 删除 Pod 并重新创建:
kubectl delete -f pod-hostpath.yaml kubectl apply -f pod-hostpath.yaml
- 再次访问 Pod:
输出示例:curl 10.244.2.37
node02.xy101.com
- 删除 Pod 并重新创建:
NFS 共享存储卷
- 功能:将 NFS 服务器的共享目录挂载到 Pod 中。
- 特点:
- 实现跨节点的数据持久化和共享。
- 数据存储在 NFS 服务器上,即使 Pod 或 Node 故障,数据也不会丢失。
NFS 存储卷示例
-
在 NFS 服务器上配置 NFS 服务
- 创建共享目录并设置权限:
mkdir /data/volumes -p chmod 777 /data/volumes
- 编辑
/etc/exports
文件:/data/volumes 192.168.80.0/24(rw,no_root_squash)
- 启动 NFS 服务:
systemctl start rpcbind systemctl start nfs
- 验证 NFS 共享:
输出示例:showmount -e
Export list for stor01: /data/volumes 192.168.80.0/24
- 创建共享目录并设置权限:
-
创建 Pod 资源 YAML 文件
apiVersion: v1 kind: Pod metadata: name: pod-vol-nfs namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html nfs