3.3 访问链路
3.3.1 入方向
集群内访问
对于集群内应用给客户端提供服务, 根据访问客户端的location,可以分为集群内和集群外,这两种访问链路下,整个svc 的网络链路是不一样的。对于集群内访问svc:
•我们首先推荐集群使用svc 的 clusterip,此模式下,访问svc 的clusterip的转发模式取决于svc的internalTraffiffifficPolicy配置,默认是cluster。 所以访问ClusterIP会被iptables/ipvs 规则默认转发到svc 后端的所有endpoint
•某些客户场景是通过lb类型暴露svc服务到集群外部, 同时配置lb的域名解析到lb的ip。而这个lb是提供给集群外和集群内访问。这种情况下,对于集群外部访问,lb可以均匀的转发到集群内后端的ep。但是对于集群内的pod访问svc的lb IP, 流量转发取决于externalTraffiffifficPolicy的设置,一般情况下,ACK为Local模式,此时,客户端pod和lb后端的某个ep在同一个节点上时,流量才会被iptables/ipvs规则转发该节点上的后端ep上,而不会转发到其他节点上的ep。 这时候就产生了疑问,如何实现在集群内访问lb ip呢?可以给svc配置host(通过service.beta.kubernetes.io/alibaba-cloud-loadbalancer-hostname:"${your_service_hostname}"), 不过这种情况下,一般建议配置7层监听,如果是4层监听,可能存在访问回环的问题。
•有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service。可以使用一个无头 Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。对于无头 Services 并不会分配 Cluster IP,kube-proxy 不会处理它们, 而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了选择算符。
集群外访问
•ingress controller的本质是多一层nginx7层代理
•ingress controller本质是多一层nginx7层代理,默认情况下ingress controller svc使用的lb为4层 tcp监听,tls需要通过ingress配置来支持。对于七层节点来说,服务端如果需要采集客户端真实IP地址,需要采集XFF的header来确定客户端的地址需要采集XFF的header来确定客户端的地址
•ingress的后端或者证书更新的时候,svc的ep更新后,ingress也会重新reload backend,这之间是需要一个时间差的,这个差值一般在几秒以内,不会对业务产生影响。所以存在pod已经被从svc 的ep中移除,但是还为从ingress controller的backend移除,依然会存在请求打到老pod,所以建议在pod中设置prestop来进行优雅的关闭连接。
•Loadblance 类型的svc
•依赖slb的负载均衡算法 健康检查,白名单等功能,可以通过SLB的ACL名单, 来控制SLB的访问规则。
•slb支持7层监听,可以将证书放到slb上来完成https的握手,但是slb与后端pod使用http协议通讯。 这时候如果集群内访问SLB IP其实链路是不经过SLB的,会被iptables规则直接转发到目的pod,无法建立http是连接
•默认添加的后端服务器是nodeport类型,Terway模式,优选eni类型,这样SLB会直接转发到目的pod所在的ECS的附属ENI上,避免了后端ECS上的多次转发
•NodePort类型的svc
•依赖节点本身具备公网ip,这种用法会比较消耗eip,需要每个ECS配置EIP来提供被公网访问的能力
•不同的pod所在节点公网能力有所不同,会增加运维成本,建议使用SLB的方式提供对外服务的能力