![Kubernetes 网络策略阻止 NFS PVC 挂载](https://linux22.com/image/786486/Kubernetes%20%E7%BD%91%E7%BB%9C%E7%AD%96%E7%95%A5%E9%98%BB%E6%AD%A2%20NFS%20PVC%20%E6%8C%82%E8%BD%BD.png)
我已根据以下要求在集群中安装了 Ganesha NFS 服务器配置程序作为 STS文档。我只使用已安装的块存储 PVC 来运行它。
我为每个命名空间部署了一个单独的 NFS 服务器,并且我想限制命名空间中哪些 pod 可以访问 NFS 服务器。我为 ingress 创建了以下网络策略,允许name=nfs-server
从同一命名空间中带有标签app-name=my-app
(所有端口)的 pod 访问 NFS 服务器(标记为):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
name: allow-ingress-nfs
name: allow-ingress-nfs
namespace: "my-namespace"
spec:
ingress:
- from:
- podSelector:
matchLabels:
app-name: my-app
podSelector:
matchLabels:
name: nfs-server
policyTypes:
- Ingress
这是 NFS 服务器 pod(来自 STS):
apiVersion: v1
kind: Pod
metadata:
labels:
name: nfs-server
name: nfs-server-0
namespace: "my-namespace"
spec:
containers:
- args:
- -provisioner=my-namespace-nfs
env:
- name: POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: SERVICE_NAME
value: nfs-server
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
image: registry.k8s.io/sig-storage/nfs-provisioner:v4.0.8
name: nfs-server
volumeMounts:
- mountPath: /export
name: export
volumes:
- name: export
persistentVolumeClaim:
claimName: nfs-export
我尝试从以下 pod 挂载该 NFS 服务器的 PVC:
apiVersion: v1
kind: Pod
metadata:
labels:
app-name: my-app
name: nginx
name: nginx-74c5d976b7-g782p
namespace: "my-namespace"
spec:
containers:
image: my/image
imagePullPolicy: Always
name: nginx
volumeMounts:
- mountPath: /mnt/files
name: files
readOnly: true
volumes:
- name: files
persistentVolumeClaim:
claimName: files
这是 PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
finalizers:
- kubernetes.io/pvc-protection
name: files
namespace: "my-namespace"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 20Gi
storageClassName: my-namespace-nfs
volumeMode: Filesystem
volumeName: pvc-uuid
这是 NFS 存储类:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: my-namespace-nfs
mountOptions:
- vers=4.1
provisioner: my-namespace-nfs
reclaimPolicy: Delete
volumeBindingMode: Immediate
然而,pods 陷入了CreatingContainer
以下错误:
Mounting command: mount
Mounting arguments: -t nfs -o vers=4.1 10.245.245.191:/export/pvc-name /var/lib/kubelet/pods/id/volumes/kubernetes.io~nfs/pvc-name
Output: mount.nfs: Connection timed out
我在 DigitalOcean Kubernetes 1.27(他们使用 Cilium)中使用非共享 CPU 节点和 GKE 1.26 观察到了同样的行为
如果我删除所有网络策略,问题就完全消失。
不确定这是否会影响什么,但我不会在特权模式下运行 Ganesha,并且我通过内存/CPU 限制它。
答案1
服务器(pod)没有NFS
提供返回必要信息的规定,这就是为什么在尝试挂载卷时会出现连接超时NFS
。
让我们为 NFS 服务器创建一个出口网络策略,以允许它与客户端 pod 进行通信,类似于下面的示例,如果仍然不起作用,则可能是防火墙问题。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-nfs
namespace: "my-namespace"
spec:
podSelector:
matchLabels:
name: nfs-server
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app-name: my-app
答案2
它不起作用并且表现“随机”的原因是入口网络策略只允许从同一节点连接到 pod。
https://kubernetes.io/docs/concepts/services-networking/network-policies/
当 Pod 被隔离以进行访问时,唯一允许进入 Pod 的连接是从 Pod 的节点以及适用于 pod 入口的某些 NetworkPolicy 的入口列表所允许的入口。