在一个大规模集群下,部署一个仅包含一两个 Pod 的测试应用。通过 Service 进行服务暴露时,负载均衡将对所有的后端 NodePort 进行健康检查,此健康检查的请求量对测试应用有很大影响。此时可以在集群中通过 Label 指定一小部分节点作为后端,缓解健康检查带来的压力。详情请参见 关于健康检查探测频率过高的说明。
Kubernetes 提供了 Service 特性 ExternalTrafficPolicy。当 ExternalTrafficPolicy 设置为 Local 时,可以避免流量通过 NAT 在节点间的转发,减少了 NAT 操作也使得源 IP 得到了保留。NodePort 仅会将流量转发到当前节点的 Pod。Local 模式特点如下:
优点:
避免了 NAT 与节点间转发带来的性能损失。
为服务端保留了请求来源 IP。
缺点:
没有工作负载的节点,NodePort 将无法提供服务。
注意事项
Service Local 模式本身就具有节点选择能力,所以:
请不要在 Service Local 模式下,使用指定接入层后端的能力。
请不要在 Service Local 模式下,在 Node 上使用 node.kubernetes.io/exclude-from-external-load-balancers Label驱逐后端节点。
负载均衡的同步是需要时间的。当 Local 类型的服务工作负载数量很少时,工作负载的飘移或滚动更新会很快。此时后端如未来得及同步,后端的服务可能会出现不可用的情况。
仅适用于处理低流量、低负载的业务,不建议在生产环境中使用。
示例:Service 开启 Local 转发(externalTrafficPolicy: Local)
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
externalTrafficPolicy: Local
ports:
-name: 80-80-no
port:80
protocol: TCP
targetPort:80
selector:
app: nginx
type: LoadBalancer
Local 默认后端选择
默认情况下,当 Service 开启 Local 模式之后,仍会按默认方式挂载几乎所有节点的 NodePort 作为后端。负载均衡会根据健康检查的结果,避免流量进入没有工作负载的后端节点。为了避免这些没有工作负载的后端被绑定,用户可以通过 service.kubernetes.io/local-svc-only-bind-node-with-pod: "true" 注解,在 Local 模式下指定绑定有工作负载节点作为后端。更多信息请参考 Kubernetes Service Local。
由于 Local 模式下,进入节点的请求流量不会在节点间转发。所以当节点上的工作负载数量不一致的时候,同样的后端权重可能会使得每一个节点上的负载不平均。此时用户可以通过 service.cloud.tencent.com/local-svc-weighted-balance: "true" 进行加权平衡。使用此注解时,NodePort 后端的权重将由节点上工作负载的数量决定,从而避免不同节点上工作负载数量不同带来的负载不均的问题。其中,Local 加权平衡必须和 Local 绑定同时使用。示例如下: