什么是 LB 直通 Pod ?

Kubernetes 官网提供了 NodePort 类型的 Service,即给所有节点开一个雷同端口用于裸露这个 Service,大多云上 LoadBalancer 类型 Service 的传统实现也都基于 NodePort,即 LB 后端绑各节点的 NodePort,LB 接管外界流量,转发到其中一个节点的 NodePort 上,再通过 Kubernetes 外部的负载平衡,应用 iptables 或 ipvs 转发到 Pod:

TKE 默认的 LoadBalancer 类型 Service 与默认的 Ingress 也都是这样实现的,但目前也反对了 LB 直通 Pod 的形式,即 LB 后端间接绑 Pod IP+Port,不绑节点的 NodePort:

为什么须要 LB 直通 Pod ?

LB 间接绑 NodePort 来实现云上的 Ingress 或 LoadBalancer 类型 Service 是最简略通用的办法,那为什么有了这种实现还不够,还要搞个 LB 直通 Pod 的模式?

首先,咱们剖析下传统 NodePort 实现形式存在的一些问题:

  1. 流量从 LB 转发到 NodePort 之后还须要进行 SNAT,再转发到 Pod,会带来一些额定的性能损耗。
  2. 如果流量过于集中到某几个 NodePort 时(比方应用 nodeSelector 部署网关到固定几台节点上),可能导致源端口耗尽,或者 conntrack 插入抵触。
  3. NodePort 自身也充当负载均衡器,LB 绑定过多节点 NodePort 可能导致负载平衡状态过于扩散,导致全局负载不均。

如果应用 LB 直通 Pod 的形式,以上问题都将隐没,并且还有一些其它益处:

  1. 因为没有 SNAT,获取源 IP 不再须要 externalTrafficPolicy: Local
  2. 实现会话放弃更简略,只须要让 CLB 开启会话放弃即可,不须要设置 Service 的 sessionAffinity

所以应用 LB 直通 Pod 的场景通常有:

  1. 在四层获取客户端实在源 IP,但又不心愿通过应用 externalTrafficPolicy: Local 的形式。
  2. 心愿进一步晋升网络性能。
  3. 让会话放弃更容易。
  4. 解决全局连贯调度的负载不均。

须要什么前提条件 ?

应用 LB 直通 Pod,须要满足以下前提条件:

  1. Kubernetes集群版本须要高于 1.12,因为 LB 直绑 Pod,查看 Pod 是否 Ready,除了看 Pod 是否 Running、是否通过 readinessProbe 外, 还须要看 LB 对 Pod 的衰弱探测是否通过,这依赖于 ReadinessGate 个性,该个性在 Kubernetes 1.12 才开始反对。
  2. 集群网络模式必须开启VPC-CNI弹性网卡模式,因为目前 LB 直通 Pod 的实现是基于弹性网卡的,一般的网络模式临时不反对,这个在将来将会反对。

怎么用 ?

因为目前 LB 直通 Pod 依赖 VPC-CNI,须要保障 Pod 应用了弹性网卡:

  1. 如果集群创立时抉择的是 VPC-CNI 网络插件,那么创立的 Pod 默认就应用了弹性网卡。
  2. 如果集群创立时抉择的是 Global Router 网络插件,起初开启了 VPC-CNI 反对,即两种模式混用,创立的 Pod 默认不应用弹性网卡,须要应用 yaml 创立工作负载,为 Pod 指定 tke.cloud.tencent.com/networks: tke-route-eni 这个 annotation 来申明应用弹性网卡,并且为其中一个容器加上 tke.cloud.tencent.com/eni-ip: "1" 这样的 requests 与 limits,示例:
apiVersion: apps/v1kind: Deploymentmetadata:  labels:    app: nginx  name: nginx-deployment-enispec:  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"

当你用 LoadBalancer 的 Service 裸露服务时,须要申明应用直连模式:

  1. 如果通过控制台创立 Service,能够勾选 采纳负载平衡直连Pod模式:

  1. 如果通过 yaml 创立 Service,须要为 Service 加上 service.cloud.tencent.com/direct-access: "true" 的 annotation:
apiVersion: v1kind: Servicemetadata:  annotations:    service.cloud.tencent.com/direct-access: "true"  labels:    app: nginx  name: nginx-service-enispec:  externalTrafficPolicy: Cluster  ports:  - name: 80-80-no    port: 80    protocol: TCP    targetPort: 80  selector:    app: nginx  sessionAffinity: None  type: LoadBalancer

当应用 Ingress 裸露服务时,同样也须要申明应用直连模式:

  1. 如果通过控制台创立 Ingress,能够勾选 采纳负载平衡直连Pod模式:

  1. 如果通过 yaml 创立 Ingress,须要为 Ingress 加上 ingress.cloud.tencent.com/direct-access: "true" 的 annotation:
apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:  annotations:    ingress.cloud.tencent.com/direct-access: "true"    kubernetes.io/ingress.class: qcloud  name: test-ingress  namespace: defaultspec:  rules:  - http:      paths:      - backend:          serviceName: nginx          servicePort: 80        path: /

参考资料

  • TKE 基于弹性网卡直连 Pod 的网络负载平衡: https://mp.weixin.qq.com/s/fJ...
  • 集群开启 VPC-CNI 模式网络: https://cloud.tencent.com/doc...
  • VPC-CNI 网络模式应用指引: https://cloud.tencent.com/doc...
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!