HostPath 卷
学习目标
- 理解 HostPath 卷的概念和特性
- 掌握 HostPath 的配置方法
- 了解 HostPath 的安全风险和最佳实践
核心概念
一句话解释
HostPath 卷将主机节点上的文件或目录挂载到 Pod 中,允许 Pod 访问主机文件系统。
HostPath 特性
┌─────────────────────────────────────┐
│ Node │
│ ┌─────────────────────────────┐ │
│ │ 主机文件系统 │ │
│ │ /var/log │ │
│ │ /etc/config │ │
│ │ /data │ │
│ └─────────────────────────────┘ │
│ ↑ 挂载 │
│ ┌─────────────────────────────┐ │
│ │ Pod │ │
│ │ Container │ │
│ │ /host-logs → /var/log │ │
│ │ /host-config → /etc/config │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
HostPath vs 其他存储
| 特性 | HostPath | emptyDir | PersistentVolume |
|---|---|---|---|
| 数据来源 | 主机文件系统 | 临时目录 | 网络存储 |
| 持久性 | 持久 | 临时 | 持久 |
| 跨节点 | 否 | 否 | 是 |
| 安全风险 | 高 | 低 | 低 |
| 典型用途 | 系统日志、配置 | 缓存 | 数据库 |
HostPath 配置
apiVersion: v1
kind: Pod
metadata:
name: hostpath-demo
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "ls -la /host-logs && sleep 3600"]
volumeMounts:
- name: host-logs
mountPath: /host-logs
volumes:
- name: host-logs
hostPath:
path: /var/log
type: Directory
HostPath 类型
| 类型 | 说明 | 行为 |
|---|---|---|
| 空字符串 | 默认 | 不检查类型 |
| DirectoryOrCreate | 目录或创建 | 不存在时创建目录 |
| Directory | 目录 | 必须存在 |
| FileOrCreate | 文件或创建 | 不存在时创建文件 |
| File | 文件 | 必须存在 |
| Socket | Socket | 必须存在 |
| CharDevice | 字符设备 | 必须存在 |
| BlockDevice | 块设备 | 必须存在 |
类型配置示例
volumes:
# 目录或创建
- name: data-volume
hostPath:
path: /data
type: DirectoryOrCreate
# 文件或创建
- name: config-volume
hostPath:
path: /etc/app.conf
type: FileOrCreate
# 必须是目录
- name: log-volume
hostPath:
path: /var/log
type: Directory
HostPath 应用场景
场景 1:访问系统日志
- 挂载 /var/log 目录
- 收集节点日志
场景 2:访问主机配置
- 挂载 /etc 目录
- 读取主机配置
场景 3:Docker Socket
- 挂载 /var/run/docker.sock
- 管理 Docker 容器
场景 4:持久化数据
- 挂载 /data 目录
- 存储应用数据
场景 5:设备访问
- 挂载 /dev 目录
- 访问硬件设备
安全风险
风险 1:数据泄露
- Pod 可以访问主机敏感文件
- 可能泄露系统配置
风险 2:数据篡改
- Pod 可以修改主机文件
- 可能破坏系统配置
风险 3:权限提升
- 通过主机文件获取更高权限
- 可能突破容器隔离
风险 4:节点绑定
- Pod 绑定到特定节点
- 影响调度灵活性
安全最佳实践
1. 最小权限
- 只挂载必要的目录
- 使用只读挂载
2. 类型检查
- 使用明确的类型
- 避免使用空类型
3. 只读挂载
- readOnly: true
- 防止数据篡改
4. 避免敏感目录
- 不要挂载 /etc/shadow
- 不要挂载 /root
5. 使用替代方案
- 优先使用 PersistentVolume
- 考虑使用 NFS 或云存储
只读挂载
volumeMounts:
- name: host-logs
mountPath: /host-logs
readOnly: true # 只读挂载
实践练习
练习 1:访问主机日志
创建 Pod 访问主机日志:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-logs
spec:
containers:
- name: log-reader
image: busybox
command: ["sh", "-c", "tail -f /host-logs/*.log"]
volumeMounts:
- name: host-logs
mountPath: /host-logs
readOnly: true
volumes:
- name: host-logs
hostPath:
path: /var/log
type: Directory
验证:
kubectl logs hostpath-logs
# 应该显示主机日志内容
练习 2:访问主机文件
创建 Pod 访问主机文件:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-file
spec:
containers:
- name: reader
image: busybox
command: ["sh", "-c", "cat /host-etc/hostname && sleep 3600"]
volumeMounts:
- name: host-etc
mountPath: /host-etc
readOnly: true
volumes:
- name: host-etc
hostPath:
path: /etc
type: Directory
验证:
kubectl logs hostpath-file
# 输出主机名
练习 3:创建目录
创建 Pod 使用 DirectoryOrCreate:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-create
spec:
containers:
- name: writer
image: busybox
command: ["sh", "-c", "echo 'Created by Pod' > /data/test.txt && sleep 3600"]
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
hostPath:
path: /tmp/hostpath-demo
type: DirectoryOrCreate
验证:
# 在节点上查看
ls -la /tmp/hostpath-demo
cat /tmp/hostpath-demo/test.txt
练习 4:Docker Socket
创建 Pod 访问 Docker:
apiVersion: v1
kind: Pod
metadata:
name: docker-socket
spec:
containers:
- name: docker-client
image: docker:latest
command: ["sh", "-c", "docker ps && sleep 3600"]
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
type: Socket
验证:
kubectl logs docker-socket
# 应该显示正在运行的容器列表
小结
| 要点 | 说明 |
|---|---|
| HostPath | 挂载主机文件系统 |
| 类型 | Directory、File、Socket 等 |
| 安全风险 | 数据泄露、篡改、权限提升 |
| 最佳实践 | 最小权限、只读挂载、类型检查 |
| 典型用途 | 系统日志、主机配置、Docker Socket |
| 替代方案 | PersistentVolume、NFS |
练习编辑器
bash
Loading...