k8s部署nginx.md

在一个应用中挂载多个目录(如 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
# nginx-html-pv.yaml
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
---
# nginx-conf-pv.yaml
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
# nginx-html-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-html-pvc
spec:
storageClassName: nfs-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
selector:
matchLabels:
type: html
---
# nginx-conf-pvc.yaml
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
# nginx-deployment-multi-volume.yaml
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
# nginx-single-pv.yaml
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
---
# nginx-single-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-complete-pvc
spec:
storageClassName: nfs-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 6Gi
---
# nginx-deployment-subpath.yaml
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
# 对于方法1
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

# 对于方法2
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
# 方法1:多个PVC
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

# 或者方法2:单个PVC + 子路径
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
# 检查PV和PVC状态
kubectl get pv
kubectl get pvc

# 检查Pod状态
kubectl get pods -l app=nginx

# 进入Pod验证挂载
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 的典型配置:

1
2
3
# 推荐:使用多个PVC,因为html和conf可能有不同的需求
# html - 需要较大容量,可能频繁读写
# conf - 小容量,主要读操作

初始化数据(可选):

您可以在 NFS 服务器上预先放置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 在NFS服务器上
echo "<h1>My Nginx Site</h1>" > /data/nfs/nginx-html/index.html

# 创建nginx配置
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内容和配置文件分别进行管理和备份。