目录
预备知识 1. K8S 上 Service 类型 平台相关基础知识 2. TKE 上四层网络流量暴露方式 3. TKE 上七层网络流量暴露方式 4. TKE 上的 VPC-CNI 5. TKE 上 CLB 直通 Pod 6. TKE 使用已有负载均衡器 7. TKE 使用内网负载均衡器 8. TKE 部署 Nginx Ingress 实际业务场景中最佳实践 1. 对集群内暴露流量 1.1 四层协议 1.2 七层协议 2. 对集群外暴露流量 2.1 七层协议 2.2 四层协议 2.3 端口段规则 2.4 使用Istio
预备知识
1. K8S 上 Service 类型
- ClusterIP
通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
- NodePort
通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。 通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。
- LoadBalancer
使用云提供商的负载局衡器,可以向外部暴露服务。 外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
- ExternalName
通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建。本文暂不讨论这种类型。
参考文档:https://cloud.tencent.com/document/product/457/45487
平台相关基础知识
2. TKE 上四层网络流量暴露方式
TKE 上默认使用 service-controller 来管理 CLB 上四层监听器和规则。这种方式, CLB 后端绑定每个节点的 NodePort,CLB 接收外界流量,转发到其中一个节点的 NodePort 上,再通过 Kubernetes 内部的负载均衡,使用 iptables 或 ipvs 转发到 Pod。
请求细节过程:
- 请求流量进入负载均衡
- 请求被负载均衡转发到某一个节点的 NodePort
- KubeProxy 将来自 NodePort 的流量进行 NAT 转发,目的地址是随机的一个 Pod
- 请求进入容器网络,并根据 Pod 地址转发到对应节点
- 请求来到 Pod 所属节点,转发到 Pod
实现结果如下图:
参考文档:https://cloud.tencent.com/document/product/457/45487
3. TKE 上七层网络流量暴露方式
TKE 上默认使用 l7-lb-controller 作为 Ingress 控制器,它会管理 CLB 上七层监听器和规则。实现原理和请求细节同四层实现,但是在 CLB 层面会根据域名和 URL 来转发到不同的后端 service,同时可以进行 SSL 卸载。
实现细节:
使用 TKE 默认自带的 Ingress,会为每个 Ingress 资源创建一个 CLB 以及 80,443 的 7 层监听器规则(HTTP/HTTPS),并为 Ingress 每个 location 绑定对应 TKE 各个节点某个相同的 NodePort 作为 rs (每个 location 对应一个 Service,每个 Service 都通过各个节点的某个相同 NodePort 暴露流量),CLB 根据请求匹配 location 转发到相应的 rs (即 NodePort),流量到了 NodePort 后会再经过 K8S 的 iptables 或 ipvs 转发给对应的后端 Pod。
实现结果如下图:
4. TKE 上的 VPC-CNI
TKE 通常用的 Global Router 网络模式(网桥方案),还有一种是 VPC-CNI(弹性网卡方案)。VPC-CNI 是 TKE 上一种新的网络模式,为每个 Pod 分配一个 ENI 弹性网卡的 EIP,Pod 间直接通过弹性网卡通信。可以理解为:给每个 Pod 分配了一个内网 IP。
优点:每个 Pod 都可以有内网 IP
缺点:需要分配一个单独的空闲子网
参考文档:https://cloud.tencent.com/document/product/457/41636
5. TKE 上 CLB 直通 Pod
TKE 的 CLB 默认绑定的都是 node 的 IP 和端口,在使用了 VPC-CNI 给 Pod 提供独立内网 IP 之后,CLB 可以直接绑定 Pod。
请求细节过程:
- 请求流量进入负载均衡
- 请求被负载均衡转发到某一个 Pod 的 ENI 弹性网卡
参考文档:https://cloud.tencent.com/document/product/457/41897
参考文档:https://mp.weixin.qq.com/s/fJtlm5Qjm2BfzekC4RegCQ
实现结果如下图,注意图中的 ENI 弹性网卡和 Pod 的实际端口80:
6. TKE 使用已有负载均衡器
先创建 CLB
在 service 的 annotations 添加:
代码语言:javascript复制service.kubernetes.io/tke-existed-lbid: lb-6swtxxxx
参考文档:https://cloud.tencent.com/document/product/457/45491
7. TKE 使用内网负载均衡器
可以通过指定使用已有内网负载均衡器实现。
也可以通过以下方式动态创建:
在 service 的 annotations 添加:
代码语言:javascript复制service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-xxxxxx # value 替换为集群所在 vpc 的其中一个子网 id
8. TKE 部署 Nginx Ingress
当 TKE 的默认 Ingress 实现(CLB 的7层规则)无法满足业务需求时,可以额外部署 Nginx Ingress(一般都用不上)
参考文档:https://cloud.tencent.com/document/product/457/47293
实际业务场景的最佳实践
1. 对集群内暴露流量
【优先】四层协议:
- 【推荐】使用 ClusterIP 类型的 Service,并通过集群内域名访问
- 【可选】使用公网 CLB 的四层规则
- 【不推荐】使用内网 CLB 的四层规则
七层协议:
- 【推荐】使用 ClusterIP 类型的 Service,并通过集群内域名访问,降级为四层协议
- 【可选】使用公网 CLB 的七层规则
- 【不推荐】使用内网 CLB 的七层规则
在集群内使用内网 CLB 需要注意回环问题,故不推荐集群内使用内网 CLB。
2. 对集群外暴露流量
建议生产环境均使用已有 CLB,即先手动创建 CLB,再在相关 Service 或 Ingress 指定 CLB 的 id。
TKE 默认控制器在 Service 使用如下配置:
代码语言:javascript复制service.kubernetes.io/tke-existed-lbid: lb-6swtxxxx
同时 CLB 开启“启用默认放通”,CLB 和 CVM 之间默认放通,则不用根据 NodePort 调整 CVM 上的安全组,如下图:
【优先】七层协议:
- 【推荐】 TKE 自带 Ingress(3. TKE 上七层网络流量暴露方式)
- 【可选】 自行部署Nginx Ingress(8. TKE 部署 Nginx Ingress)
四层协议:
- 【推荐】TKE 自带 LoadBalancer(2. TKE 上四层网络流量暴露方式)
使用Istio:
Istio 有点类似于 Nginx Ingress,都是先 CLB 四层监听器转发到 NodePort,再通过 istio-ingressgateway 这个 service 定义的规则,转发到 istio-ingressgateway-xx 这个 Pod,再转发到集群内其他 Istio Sidecar。