容器服务 TKE 上服务暴露的几种方式

预备知识

1. K8S 上 Service 类型

  • ClusterIP

通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。

  • NodePort

通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。 通过请求 :,可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer

使用云提供商的负载局衡器,可以向外部暴露服务。 外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。

  • ExternalName

通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建。本文暂不讨论这种类型。

参考文档:https://cloud.tencent.com/document/product/457/45487

平台相关基础知识

腾讯云容器服务(Tencent Kubernetes Engine ,TKE)基于原生 Kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,完全兼容原生 Kubernetes API ,同时扩展了腾讯云的云硬盘、负载均衡等 kubernetes 插件,为容器化的应用提供高效部署、资源调度、服务发现和动态伸缩等一系列完整功能,解决用户开发、测试及运维过程的环境一致性问题,提高了大规模容器集群管理的便捷性,帮助用户降低成本,提高效率。

2. TKE 上四层网络流量暴露方式

TKE 上默认使用 service-controller 来管理 CLB 上四层监听器和规则。这种方式, CLB 后端绑定每个节点的 NodePort,CLB 接收外界流量,转发到其中一个节点的 NodePort 上,再通过 Kubernetes 内部的负载均衡,使用 iptables 或 ipvs 转发到 Pod。

img

img

请求细节过程:

  • 请求流量进入负载均衡
  • 请求被负载均衡转发到某一个节点的 NodePort
  • KubeProxy 将来自 NodePort 的流量进行 NAT 转发,目的地址是随机的一个 Pod
  • 请求进入容器网络,并根据 Pod 地址转发到对应节点
  • 请求来到 Pod 所属节点,转发到 Pod

实现结果如下图:

img

参考文档: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。

实现结果如下图:

img

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

img

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

img

img

实现结果如下图,注意图中的 ENI 弹性网卡和 Pod 的实际端口80:

img

6. TKE 使用已有负载均衡器

先创建 CLB

在 service 的 annotations 添加:

service.kubernetes.io/tke-existed-lbid: lb-6swtxxxx

参考文档:https://cloud.tencent.com/document/product/457/45491

7. TKE 使用内网负载均衡器

可以通过指定使用已有内网负载均衡器实现。

也可以通过以下方式动态创建:

在 service 的 annotations 添加:

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 使用如下配置:

service.kubernetes.io/tke-existed-lbid: lb-6swtxxxx

同时 CLB 开启“启用默认放通”,CLB 和 CVM 之间默认放通,则不用根据 NodePort 调整 CVM 上的安全组,如下图:

img

【优先】七层协议:

  • 【推荐】 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。

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

posted @ 2020-09-11 18:01  腾讯云原生  阅读(1640)  评论(0编辑  收藏  举报