kubernetes的存储机制hostpath管理
hostPath
参考资料:
https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath
hostPath 可以将宿主机上的目录挂载到 Pod 中作为数据的存储目录
hostPath 一般用在如下场景:
- 容器应用程序中某些文件需要永久保存
- Pod删除,hostPath数据对应在宿主机文件不受影响,即hostPath的生命周期和Pod不同,而和节点相同
- 宿主机和容器的目录都会自动创建
- 某些容器应用需要用到容器的自身的内部数据,可将宿主机的/var/lib/[docker|containerd]挂载到Pod中
- 容器复用宿主机的文件
hostPath 使用注意事项:
- 不支持数据的漫游,hostpath只有在其所在宿主机可用,其它节点不可用
- 不同宿主机的目录和文件内容不一定完全相同,所以Pod迁移前后的访问效果不一样
- 不适合Deployment这种分布式的资源,更适合于DaemonSet
- 宿主机的目录不属于独立的资源对象的资源,所以对资源设置的资源配额限制对hostPath目录无效
警告:
使用 hostPath 类型的卷存在许多安全风险。如果可以,你应该尽量避免使用 hostPath 卷。 例如,你可以改为定义并使用 local PersistentVolume
#配置属性
kubectl explain pod.spec.volumes.hostPath
path #指定哪个宿主机的目录或文件将被共享给Pod使用
type #指定路径的类型,一共有7种,默认的类型是没有指定
空字符串 #默认配置,在关联hostPath存储卷之前不进行任何检查,如果宿主机没有对应的目录,会自
动创建
DirectoryOrCreate #宿主机上不存在path,就自动创建0755权限的空目录
Directory #path必须存在,挂载已存在的目录
FileOrCreate #宿主机上不存在挂载文件,就创建0644权限的空文件
File #必须存在的文件
Socket #事先必须存在的Socket文件路径
CharDevice #事先必须存在的字符设备文件路径
BlockDevice #事先必须存在的块设备文件路径
#配置格式:
volumes: - name: volume_name hostPath: path: /path/to/host
宿主机磁盘目录是文件 定义系统时区 东八区
[root@master1 storage]# ll /usr/share/zoneinfo/Asia/Shanghai -rw-r--r--. 5 root root 561 Nov 6 2025 /usr/share/zoneinfo/Asia/Shanghai [root@master1 storage]# date Fri May 22 11:00:30 PM CST 2026
[root@master1 storage]# timedatectl Local time: Fri 2026-05-22 23:03:22 CST Universal time: Fri 2026-05-22 15:03:22 UTC RTC time: Fri 2026-05-22 15:03:21 Time zone: Asia/Shanghai (CST, +0800) System clock synchronized: yes NTP service: active RTC in local TZ: no [root@master1 storage]# ll /etc/localtime lrwxrwxrwx. 1 root root 35 May 7 15:28 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai [root@master1 storage]#
nginx容器不定义时区 默认是utc时间 第二个容器是东八区时区
[root@master1 storage]# cat storage-hostpath-timezone.yaml apiVersion: apps/v1 kind: Deployment metadata: name: storage-hostpath-timezone spec: replicas: 1 selector: matchLabels: app: storage-hostpath template: metadata: labels: app: storage-hostpath spec: containers: - name: c01 image: registry.cn-beijing.aliyuncs.com/wangxiaochun/nginx:1.20.0 - name: c02 image: registry.cn-beijing.aliyuncs.com/wangxiaochun/nginx:1.20.0 command: ["sh","-c","sleep 3600"] volumeMounts: - name: localtime mountPath: /etc/localtime #容器此为文件是普通文件,挂载节点目录成功 volumes: - name: localtime hostPath: path: /usr/share/zoneinfo/Asia/Shanghai #配置时区方法2: 此文件用于影响时区,必选 type: File
kubectl apply -f storage-hostpath-timezone.yaml
[root@master1 storage]# kubectl get pod NAME READY STATUS RESTARTS AGE controller-deployment-demo-5f884bb8-2ppvf 1/1 Running 0 3m22s controller-deployment-demo-5f884bb8-7svwh 1/1 Terminating 7 (112m ago) 5d23h controller-deployment-demo-5f884bb8-fscrl 1/1 Running 9 (9m34s ago) 6d3h controller-deployment-demo-5f884bb8-rfsbv 1/1 Running 8 (9m34s ago) 5d23h storage-hostpath-timezone-7dd555df9b-pktvv 2/2 Running 0 11s
utc时间
[root@master1 storage]# kubectl exec -it storage-hostpath-timezone-7dd555df9b-pktvv -c c01 -- sh # # date Fri May 22 15:08:43 UTC 2026
# ls -l /etc/localtime lrwxrwxrwx 1 root root 27 May 11 2021 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC
[root@master1 storage]# kubectl exec -it storage-hostpath-timezone-7dd555df9b-pktvv -c c02 -- sh # # date Fri May 22 23:10:18 CST 2026
范例: 实现 Redis 数据的持久化
[root@master1 storage]# cat storage-hostpath-redis.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hostpath-redis spec: replicas: 1 selector: matchLabels: app: hostpath-redis template: metadata: labels: app: hostpath-redis spec: nodeName: node1.org containers: - name: hostpath-redis image: registry.cn-beijing.aliyuncs.com/wangxiaochun/redis:6.2.5 volumeMounts: - name: redis-backup mountPath: /data volumes: - name: redis-backup hostPath: path: /backup/redis #宿主机的目录会自动创建
nodeName: node1.org 只调度在这个节点上
#关键点:spec.containers.volumeMounts的name属性和spec.volumes的那么属性完全一致,因为他们是基于name来关联的。
#注意:redis的镜像将数据保存到了容器的/data 目录下。
目前宿主机上面没有这个目录
[root@node1 ~]# ls /backup/redis ls: cannot access '/backup/redis': No such file or directory
创建资源对象
kubectl apply -f storage-hostpath-redis.yaml
[root@master1 storage]# [root@master1 storage]# kubectl get node NAME STATUS ROLES AGE VERSION master1.org Ready control-plane 12d v1.35.4 node1.org Ready <none> 12d v1.35.4 node2.org Ready <none> 12d v1.35.4
[root@master1 storage]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES controller-deployment-demo-5f884bb8-2ppvf 1/1 Running 0 25m 10.244.1.153 node1.org <none> <none> controller-deployment-demo-5f884bb8-fscrl 1/1 Running 9 (31m ago) 6d3h 10.244.1.147 node1.org <none> <none> controller-deployment-demo-5f884bb8-rfsbv 1/1 Running 8 (31m ago) 6d 10.244.1.149 node1.org <none> <none> hostpath-redis-dfcddb5b4-th7ph 1/1 Running 0 92s 10.244.1.155 node1.org <none> <none>
kubectl exec -it hostpath-redis-dfcddb5b4-th7ph -- bash
root@hostpath-redis-dfcddb5b4-th7ph:/data# redis-cli 127.0.0.1:6379> config get dir 1) "dir" 2) "/data"
root@hostpath-redis-dfcddb5b4-th7ph:/data# pwd
/data
生成rdb文件
root@hostpath-redis-dfcddb5b4-th7ph:/data# redis-cli 127.0.0.1:6379> 127.0.0.1:6379> set name tom OK 127.0.0.1:6379> save OK 127.0.0.1:6379> exit root@hostpath-redis-dfcddb5b4-th7ph:/data# ls dump.rdb root@hostpath-redis-dfcddb5b4-th7ph:/data#
存在宿主机上面
#在对应的worker节点主机查看数据目录自动生成
[root@node1 ~]# ls /backup/redis dump.rdb
#删除pod,重新创建
kubectl delete -f storage-hostpath-redis.yaml deployment.apps "hostpath-redis" deleted from default namespace
文件还在
[root@node1 ~]# ls /backup/redis dump.rdb
#重新创建Pod,验证数据是否还在
kubectl apply -f storage-hostpath-redis.yaml
[root@master1 storage]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES controller-deployment-demo-5f884bb8-2ppvf 1/1 Running 0 34m 10.244.1.153 node1.org <none> <none> controller-deployment-demo-5f884bb8-fscrl 1/1 Running 9 (40m ago) 6d3h 10.244.1.147 node1.org <none> <none> controller-deployment-demo-5f884bb8-rfsbv 1/1 Running 8 (40m ago) 6d 10.244.1.149 node1.org <none> <none> hostpath-redis-dfcddb5b4-lcqqd 1/1 Running 0 49s 10.244.1.156 node1.org <none> <none>
#确认数据还存在
[root@master1 storage]# kubectl exec -it hostpath-redis-dfcddb5b4-lcqqd -- redis-cli keys '*' 1) "name" [root@master1 storage]# [root@master1 storage]# kubectl exec -it hostpath-redis-dfcddb5b4-lcqqd -- redis-cli get name "tom"
hostpath 持久化数据 要固定写死pod 节点,不能让他调度别的节点,不然下次数据用不了 ,如果这个节点挂了,数据就丢了,不能真正实现完全安全
需要弄个备份机器 专门做备份,写个脚本rsync同步数据 加入定时任务定时 备份数据到备份机器
浙公网安备 33010602011771号