卷挂载
学习目标
- 理解 Kubernetes 卷的概念和作用
- 掌握卷挂载的基本配置方法
- 了解不同卷类型的应用场景
核心概念
为什么需要卷
没有卷的问题:
┌─────────────────────────────────────┐
│ Pod │
│ ┌─────────────────────────────┐ │
│ │ Container │ │
│ │ - 数据写入容器文件系统 │ │
│ │ - 容器重启数据丢失 │ │
│ │ - 多容器无法共享数据 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
使用卷的解决方案:
┌─────────────────────────────────────┐
│ Pod │
│ ┌─────────────────────────────┐ │
│ │ Container 1 │ │
│ │ - 读写卷数据 │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ Container 2 │ │
│ │ - 共享同一卷 │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ Volume │ │
│ │ - 持久化存储 │ │
│ │ - 跨容器共享 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
卷的生命周期
Pod 创建 → 卷创建 → 容器挂载 → 容器使用 → Pod 删除 → 卷清理
不同卷类型的生命周期:
- emptyDir: Pod 生命周期
- hostPath: 节点生命周期
- PersistentVolume: 独立生命周期
卷的基本配置
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:1.0
volumeMounts:
- name: data-volume
mountPath: /data
readOnly: false # 是否只读
volumes:
- name: data-volume
emptyDir: {} # 卷类型
常用卷类型
| 卷类型 | 说明 | 生命周期 | 典型用途 |
|---|---|---|---|
| emptyDir | 空目录 | Pod | 临时存储、缓存 |
| hostPath | 主机目录 | 节点 | 访问主机文件 |
| configMap | 配置数据 | Pod | 配置文件 |
| secret | 敏感数据 | Pod | 证书、密钥 |
| persistentVolumeClaim | 持久化存储 | 独立 | 数据库、文件存储 |
卷挂载选项
volumeMounts:
- name: data-volume
mountPath: /data # 挂载路径
readOnly: false # 是否只读
subPath: config.txt # 挂载卷中的子路径
mountPropagation: None # 挂载传播模式
挂载传播模式
| 模式 | 说明 |
|---|---|
| None | 不传播挂载 |
| HostToContainer | 主机挂载传播到容器 |
| Bidirectional | 双向传播(危险) |
多容器共享卷
apiVersion: v1
kind: Pod
metadata:
name: shared-volume
spec:
containers:
- name: writer
image: busybox
command: ["sh", "-c", "echo 'Hello from writer' > /data/message && sleep 3600"]
volumeMounts:
- name: shared-data
mountPath: /data
- name: reader
image: busybox
command: ["sh", "-c", "cat /data/message && sleep 3600"]
volumeMounts:
- name: shared-data
mountPath: /data
readOnly: true
volumes:
- name: shared-data
emptyDir: {}
子路径挂载
volumes:
- name: config-volume
configMap:
name: app-config
volumeMounts:
# 只挂载 ConfigMap 中的特定键
- name: config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
只读挂载
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true # 只读挂载
实践练习
练习 1:基本卷挂载
创建 Pod 使用 emptyDir:
apiVersion: v1
kind: Pod
metadata:
name: volume-demo
spec:
containers:
- name: writer
image: busybox
command: ["sh", "-c", "echo 'Hello from Pod' > /data/test.txt && sleep 3600"]
volumeMounts:
- name: data-volume
mountPath: /data
- name: reader
image: busybox
command: ["sh", "-c", "cat /data/test.txt && sleep 3600"]
volumeMounts:
- name: data-volume
mountPath: /data
readOnly: true
volumes:
- name: data-volume
emptyDir: {}
验证:
kubectl logs volume-demo -c reader
# 输出:Hello from Pod
练习 2:ConfigMap 卷挂载
创建 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
return 200 "Hello from Nginx!";
}
}
创建 Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx-with-config
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
volumes:
- name: nginx-config
configMap:
name: nginx-config
验证:
kubectl exec nginx-with-config -- cat /etc/nginx/conf.d/nginx.conf
练习 3:Secret 卷挂载
创建 Secret:
kubectl create secret generic app-secret \
--from-literal=api-key=sk-123456789
创建 Pod:
apiVersion: v1
kind: Pod
metadata:
name: app-with-secret
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "cat /etc/secrets/api-key && sleep 3600"]
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: app-secret
defaultMode: 0400
验证:
kubectl logs app-with-secret
# 输出:sk-123456789
练习 4:子路径挂载
创建 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: multi-config
data:
app.conf: |
[app]
name=my-app
db.conf: |
[database]
host=mysql.example.com
创建 Pod:
apiVersion: v1
kind: Pod
metadata:
name: subpath-demo
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "cat /etc/config/app.conf && sleep 3600"]
volumeMounts:
- name: config-volume
mountPath: /etc/config/app.conf
subPath: app.conf
volumes:
- name: config-volume
configMap:
name: multi-config
验证:
kubectl exec subpath-demo -- cat /etc/config/app.conf
小结
| 要点 | 说明 |
|---|---|
| 卷概念 | 持久化存储、跨容器共享 |
| emptyDir | 临时存储,Pod 生命周期 |
| 卷挂载 | volumeMounts 配置 |
| 只读挂载 | readOnly: true |
| 子路径挂载 | subPath 配置 |
| 共享卷 | 多容器访问同一卷 |
练习编辑器
bash
Loading...