K8s发现和负载均衡-Service
K8s发现和负载均衡-Service
基于1.25
什么是Service
K8s中,Pod随时消亡,控制器Pod集合不断变化,每个服务调用者不知道发送到哪个IP,Service就是为了解决这个问题,提供了以下的能力:
- Pod有自己的IP
- Service被赋予唯一的DNS Name
- Service通过标签选择器选择一组Pod
- Service实现负载均衡,可以将请求均衡放到一组Pod
ServiceSpec
// ServiceSpec describes the attributes that a user creates on a service. |
服务类型
Service Type 目前支持ClusterIP、NodePort、LoadBalancer、ExternalName四种类型
ClusterIP
默认的服务类型
- 是NodePort、LoadbBalancer的基础
- 单独的IP网段
- 先通过VIP再通过Kube-Proxy到各个Pod
- 如果使用ipvs,可以通过ipvsadm命令查看负载均衡的转发规则
- ClusterIP Service会创建域名对应所属的SRV记录
- ClusterIP Service优点是VIP位于Pod前面,可以有效避免直接DNS解析
- 缺点是请求量大,kube-proxy处理性能发生瓶颈,可能出现gPRC等长链接不生效的问题
NodePort
NodePort通过每个节点的IP地址和静态端口(NodePort)暴露Service
- K8s控制面通过
--service-node-port-range
分配端口号(30000-32767) - Service,可以通过任何一个集群节点IP+NodePort访问
- NodePort Service 请求路径是由K8s的节点IP直接到Pod,不会经过CLuster IP,转发逻辑依旧是Kube-Porxy实现
- NodePort Service域名的解析结果是一个CLUSTER- IP,在集群内部请求负载均衡的逻辑跟实现ClusterIP Service是一致的
- 缺点:
- NodePort 本身端口有限制,请求量大,kube-proxy成为瓶颈
- 在访问时与节点IP地址强绑定不利于节点IP地址频繁变动的场景
LoadBalancer
LoadBalancer使用云提供商的负载均衡对外暴露Service
外部负载均衡器可以将流量路由到自动创建的NodePort Service
开源LoadBancer:
LoadBalancer Service:域名解析的成功是一个CLUSTER-IP,LoadBalancer类型的Service还会分配一个EXTERBNAL-IP,集群外的机器可以通过EXTERBNAL-IP来访问
LoadBalancer Service默认情况下同时还会创建NodePort Service,也通过
alllocateLoadBalancerNodePorts:false
拒绝创建NodePort Service
Headless Service
可以把spec.clusterIP
设置为None创建Headless Service
- 此时该Service域名解析的结果就是Service关联的所有的PodIP地址
- 使用该域名访问的时候,请求会直接到达Pod,相当于仅仅用DNS用了负载均衡,而不是用K8s大kube-proxy作负载均衡
各种Port的区别
containerPort:作用于Pod内部容器
- 告知K8s的容器的Service端口
nodePort:
- 只存在于LoadBalancer和NodePort类型的Service中,用于访问指定Service
port:只作用于CLUSTER-IP和EXTERNAL-IP
- 对于LoadBalancer、NodePort和ClusterIP类型都有作用
- 集群外可以通过
EXTERNAL-IP:port
访问 - 集群内可以通过
ClusterIP:port
访问
targetPort:Pod的外部访问端口,转发路径
- NodeIP:nodePort->PodIP:targetPort
- CLUSTER-IP:port->PodIP:targetPort
- EXTERNAL-IP:port->PodIP:targetPort
实际过程中,最好保证targetPort、containerdPort和Pod中实际监听端口一致
Service和Pod的DNS
K8s为Service的Pod创建DNS记录,可以使用一致的DNS名称而非IP地址访问Service
- kubelete配置Pod的DNS以便运行中的容器通过名称来寻找而不是IP地址查找Service
- 集群中的Service赋予了DNS名称,默认情况下客户端的Pod的DNS搜索列表会查找Pod自身命名空间和集群默认域
ExternalTrafficPolicy
ExternalTrafficPolicy表示此Service是否希望外部流量路由到节点本地或者集群访问,有俩个选项
- Cluster:隐藏客户端源IP,可能导致第二跳跳转到另外一个节点上,有比较好的负载均衡
- 不管其他节点是否可以承接流量,先转移到其他节点,再找对应的Pod
- Local:保留客户端源IP,避免LB和NodePort类型的Service第二跳,但是存在不负载均衡的风险
- 只有Pod所在节点可以承接流量,其他节点无法承接流量