在一个应用中挂载多个目录(如 Nginx 的 html 和 conf.d)是很常见的需求。有几种方法可以实现:
方法1:使用多个 PVC(推荐)
为每个目录创建独立的 PV 和 PVC:
1. 创建多个静态 PV
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| apiVersion: v1 kind: PersistentVolume metadata: name: nginx-html-pv labels: app: nginx type: html spec: capacity: storage: 5Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-storage nfs: server: 192.168.1.100 path: /data/nfs/nginx-html ---
apiVersion: v1 kind: PersistentVolume metadata: name: nginx-conf-pv labels: app: nginx type: config spec: capacity: storage: 1Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-storage nfs: server: 192.168.1.100 path: /data/nfs/nginx-conf
|
2. 创建对应的 PVC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nginx-html-pvc spec: storageClassName: nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 5Gi selector: matchLabels: type: html ---
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nginx-conf-pvc spec: storageClassName: nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 1Gi selector: matchLabels: type: config
|
3. 在 Deployment 中使用多个 Volume
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: html-storage mountPath: /usr/share/nginx/html - name: config-storage mountPath: /etc/nginx/conf.d command: ['/bin/sh', '-c'] args: - | # 如果html目录为空,创建默认页面 if [ ! -f /usr/share/nginx/html/index.html ]; then echo "<h1>Welcome to Nginx</h1><p>HTML content from NFS</p>" > /usr/share/nginx/html/index.html fi # 如果conf.d目录为空,创建默认配置 if [ ! -f /etc/nginx/conf.d/default.conf ]; then cat > /etc/nginx/conf.d/default.conf << 'EOF' server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } } EOF fi nginx -g 'daemon off;' volumes: - name: html-storage persistentVolumeClaim: claimName: nginx-html-pvc - name: config-storage persistentVolumeClaim: claimName: nginx-conf-pvc
|
方法2:使用单个 PV,但挂载子路径(简化方案)
如果两个目录在同一个 NFS 共享下,可以使用子路径:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| apiVersion: v1 kind: PersistentVolume metadata: name: nginx-complete-pv spec: capacity: storage: 6Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs-storage nfs: server: 192.168.1.100 path: /data/nfs/nginx ---
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nginx-complete-pvc spec: storageClassName: nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 6Gi ---
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: nginx-storage mountPath: /usr/share/nginx/html subPath: html - name: nginx-storage mountPath: /etc/nginx/conf.d subPath: conf.d volumes: - name: nginx-storage persistentVolumeClaim: claimName: nginx-complete-pvc
|
部署步骤
1. 在 NFS 服务器上准备目录
1 2 3 4 5 6 7 8 9 10
| sudo mkdir -p /data/nfs/nginx-html sudo mkdir -p /data/nfs/nginx-conf sudo chmod 777 /data/nfs/nginx-html sudo chmod 777 /data/nfs/nginx-conf
sudo mkdir -p /data/nfs/nginx/html sudo mkdir -p /data/nfs/nginx/conf.d sudo chmod -R 777 /data/nfs/nginx
|
2. 应用配置
1 2 3 4 5 6 7 8 9 10 11
| kubectl apply -f nginx-html-pv.yaml kubectl apply -f nginx-conf-pv.yaml kubectl apply -f nginx-html-pvc.yaml kubectl apply -f nginx-conf-pvc.yaml kubectl apply -f nginx-deployment-multi-volume.yaml
kubectl apply -f nginx-single-pv.yaml kubectl apply -f nginx-single-pvc.yaml kubectl apply -f nginx-deployment-subpath.yaml
|
3. 验证部署
1 2 3 4 5 6 7 8 9 10
| kubectl get pv kubectl get pvc
kubectl get pods -l app=nginx
kubectl exec -it <nginx-pod-name> -- ls -la /usr/share/nginx/html/ kubectl exec -it <nginx-pod-name> -- ls -la /etc/nginx/conf.d/
|
两种方法的对比
| 方法 |
优点 |
缺点 |
适用场景 |
| 多个PVC |
- 独立管理 - 不同存储策略 - 更好的隔离 |
- 更多资源配置 - 管理复杂 |
生产环境,需要不同存储需求 |
| 子路径 |
- 配置简单 - 资源少 - 统一管理 |
- 共享存储配额 - 权限一致 |
开发测试,简单应用 |
实际应用建议
对于 Nginx 的典型配置:
初始化数据(可选):
您可以在 NFS 服务器上预先放置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| echo "<h1>My Nginx Site</h1>" > /data/nfs/nginx-html/index.html
cat > /data/nfs/nginx-conf/default.conf << 'EOF' server { listen 80; server_name _; location / { root /usr/share/nginx/html; index index.html; } location /health { return 200 "healthy\n"; } } EOF
|
总结
- 多个PVC方案更灵活,适合生产环境
- 子路径方案更简单,适合开发和测试
- 根据实际存储需求(容量、性能、备份策略)选择合适方案
- 确保NFS服务器上的目录结构和权限正确
对于Nginx这种需要多个配置目录的应用,推荐使用多个PVC方案,这样可以对HTML内容和配置文件分别进行管理和备份。