我有一个 Kubernetes 集群设置,其中 Kube 命名空间中有 2 个 StatefulSet:
- NFSserver Statefulset 定义为“无头”服务,该服务具有 1 个带有附加持久卷的 pod,并运行导出该卷的 NFS 服务器。
- DataClient Statefulset 有多个 pod 使用 NFSv4 挂载上面导出的 NFS 共享
数据客户端负责创建数据,然后将其存储在 NFS 服务器卷上。
DataClients 对 NFS 卷执行大量数据读取/写入,因此我尝试尽可能优化传输。我目前为 NFSserver 使用“无头”服务(例如 POD 的 IP 地址由 KUBEDNS 提供),这意味着 NFS 数据包直接使用 NFSserver POD 的 IP 地址。
我的问题是,使用无头服务时,NFSserver 的 IP 地址可能会发生变化(例如,为更新 DockerImage 而删除 pod)。客户端需要监视服务器 IP 并在其发生变化时进行更新吗?然后,所有客户端都需要“强制”卸载 NFS 卷(安装在旧 IP 地址上),然后立即使用新 IP 重新安装。使用 KUBEDNS 将提供新的 IP 地址。
我的第一个问题是:如果我使用 CLUSTER IP 服务但分配一个在删除/重新创建 POD 时不会改变的服务 IP 地址,是否会对性能产生影响?我的想法是,拥有一个服务 IP 和一个单独的 pod IP 会导致每个 NFS 数据包出现“两跳”的情况。我对 kube-proxy 了解不多,无法访问 kuberenetes 节点来查看 IPtables 配置。我刚刚阅读了关于 kube-proxy 使用 IPtables 路由数据包的文章,所以也许性能并没有受到影响。
其他详情:
- Kubernetes 集群在 20 多个 OpenStack VM 节点上运行
- 持久卷是附加到运行 NFS 服务器 POD 的 OpenStack VM 节点的 OpenStack 卷,然后挂载到 POD 容器中
- NFS 客户端可能位于 20 多个 VM 节点中的任意一个上。不可能将所有客户端都放在与 NFS 服务器相同的节点上。
- 我没有节点级访问权限,因此无法查看节点的 openstack/Linux 级别上发生的情况。我只能访问容器。
- 在此集群中,kubernetes 命名空间标识单个 NFS 服务器及其所有客户端。可能有多个命名空间,每个命名空间都有一个 NFS 服务器和多个客户端。
不幸的是,提供 Kubernetes 基础设施的服务不支持 ReadWriteMany 卷,我(不是专家)认为它可以取代 NFS。
如果 NFS 正常工作,它确实能满足我们的需求。我发现它非常挑剔,经常挂起,客户端速度缓慢,原因不明。欢迎提出建议。
答案1
您描述的两跳情况在您运行多个节点时肯定会出现问题,并且由于 Kubernetes 服务中默认实现的负载平衡机制,请求会进入 NFS Pod 不存在的节点。为了避免不对称路由问题,目标节点会将请求发送回其最初到达的节点,然后再发送到客户端。
幸运的是,由于你正在运行单个 NFS Pod,因此你可以设置外部流量策略到local
服务级别;这实际上禁用了集群节点上的负载平衡,并且流量被直接发送到目标节点,在本地处理所有流量。
externalTrafficPolicy
以下是设置为 的Kubernetes 服务的示例local
:
kind: Service
apiVersion: v1
metadata:
name: store-backend
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: store
role: backend
ports:
- name: https
port: 443
此外,您还可以实现在 Pod 中使用特定 IP 地址提供的功能Calico 项目。