启用 CLB 直通 Pod
概述
TKE 提供了 CLB 直通 Pod 的能力,不经过 NodePort,网络链路上少了一跳,带来了一系列好处:
- 链路更短,性能会有所提高。
- 没有 SNAT,避免了流量集中可能导致的源端口耗尽、conntrack 插入冲突等问题。
- 不经过 NodePort,也就不会再经过 k8s 的 iptables/ipvs 转发,从而负载均衡状态就都收敛到了 CLB 这一个地方,可避免负载均衡状态分散导致的全局负载不均问题。
- 由于没有 SNAT,天然可以获取真实源 IP,不再需要
externalTrafficPolicy: Local
。 - 实现会话保持更简单,只需要让 CLB 开启会话保持即可,不需要设置 Service 的
sessionAffinity
。
虽然 CLB 直通 Pod 提供了这么多好处,但默认不会启用,本文介绍如何在 TKE 上启用 CLB 直通 Pod。
前提条件
Kubernetes
集群版本需要高于 1.12,因为 CLB 直绑 Pod,检查 Pod 是否 Ready,除了看 Pod 是否 Running、是否通过 readinessProbe 外, 还需要看 LB 对 Pod 的健康探测是否通过,这依赖于ReadinessGate
特性,该特性在 Kubernetes 1.12 才开始支持。- 集群网络模式必须开启
VPC-CNI
弹性网卡模式,因为目前 LB 直通 Pod 的实现是基于弹性网卡的,普通的网络模式暂时不支持,这个在未来将会支持。
CLB 直通 Pod 启用方法
启用方法是在创建 Service 或 Ingress 时,声明一下要使用 CLB 直通 Pod。
Service 声明 CLB 直通 Pod
当你用 LoadBalancer 的 Service 暴露服务时,需要声明使用直连模式:
- 如果通过控制台创建 Service,可以勾选
采用负载均衡直连Pod模式
:
-
如果通过 yaml 创建 Service,需要为 Service 加上
service.cloud.tencent.com/direct-access: "true"
的 annotation:apiVersion: v1
kind: Service
metadata:
annotations:
service.cloud.tencent.com/direct-access: "true" # 关键
labels:
app: nginx
name: nginx-service-eni
spec:
externalTrafficPolicy: Cluster
ports:
- name: 80-80-no
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: LoadBalancer
CLB Ingress 声明 CLB 直通 Pod
当使用 CLB Ingress 暴露服务时,同样也需要声明使用直连模式:
- 如果通过控制台创建 CLB Ingress,可以勾选
采用负载均衡直连Pod模式
:
-
如果通过 yaml 创建 CLB Ingress,需要为 Ingress 加上
ingress.cloud.tencent.com/direct-access: "true"
的 annotation:apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
ingress.cloud.tencent.com/direct-access: "true"
kubernetes.io/ingress.class: qcloud
name: test-ingress
namespace: default
spec:
rules:
- http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /
启用方法根据集群网络模式有细微差别,见下文分解。
GlobalRouter + VPC-CNI 网络模式混用注意事项
如果 TKE 集群创建时,网络模式选择的 GlobalRouter ,后面再开启的 VPC-CNI ,这样集群的网络模式就是 GlobalRouter + VPC-CNI 两种网络模式混用。
这种集群创建的 Pod 默认没有使用弹性网卡,如果要启用 CLB 直通 Pod,首先在部署工作负载的时候,声明一下 Pod 要使用 VPC-CNI 模式 (弹性网卡),具体操作方法是使用 yaml 创建工作负载 (不通过 TKE 控制台),为 Pod 指定 tke.cloud.tencent.com/networks: tke-route-eni
这个 annotation 来声明使用弹性网卡,并且为其中一个容器加上 tke.cloud.tencent.com/eni-ip: "1"
这样的 requests 与 limits,示例:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment-eni
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
annotations:
tke.cloud.tencent.com/networks: tke-route-eni
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
tke.cloud.tencent.com/eni-ip: "1"
limits:
tke.cloud.tencent.com/eni-ip: "1"