Kubernetes V1.17开启 拓扑感知服务路由

Kubernetes V1.17开启 拓扑感知服务路由

1、名词解释:

拓扑域:表示在集群中某个节点,可操作区域,也就是拓扑域名。
Endpoint: IP-Port 一般来说是Node当中pod的ip+port。
Service:一组依靠labelselector的pod,起到流量均衡分发管理的作用。

2、给所有组件打开ServiceTopology和Endpointslice

集群版本在V1.17以上
Kube-proxy 以iptables或IPVS模式运行(alpha阶段暂时只实现这两种模式)。
Service K8S的service资源,关联一组endpoint,准发到某个endpoint。
启用了Endpoint Slices
给所有组件打开ServiceTopology和Endpointslice这两个Feature gate:
--feature-gates=ServiceTopology=true,EndpointSlice=true

3、kube-apiserver 组件修改

kube-apiserver 前期启动OwnerReferencesPermissionEnforcement 插件请删除不然一直提示  Warning  FailedToUpdateEndpointSlices  8m24s (x7 over 11m)  endpoint-slice-controller  (combined from similar events): Error updating Endpoint Slices for Service kube-system/kube-dns: Error creating EndpointSlice for Service kube-syste
m/kube-dns: endpointslices.discovery.k8s.io "kube-dns-x8qmh" is forbidden: cannot set blockOwnerDeletion if an ownerReference refers to a resource you can‘t set finalizers on: , <nil>

4、更新配置文件及重启所有组件

5、验证endpointslices 是否正常

:/opt/kube14# kubectl get endpointslices
NAME                   ADDRESSTYPE   PORTS        ENDPOINTS                    AGE
kube-dns-kh5ls         IPv4          53,9153,53   10.83.98.136,10.90.153.135   15m
metrics-server-gqgqm   IPv4          443          10.93.92.195                 15m

6、 验证ServiceTopology

在 Service spec 里加上 topologyKeys 字段,表示该 Service 优先顺序选用的拓扑域列表,对应节点标签的 key;当访问此 Service 时,会找是否有 endpoint 有对应 topology key 的拓扑信息并且 value 跟当前节点也一样,如果是,那就选定此 topology key 作为当前转发的拓扑域,并且筛选出其余所有在这个拓扑域的 endpoint 来进行转发;如果没有找到任何 endpoint 在当前 topology key 对应拓扑域,就会尝试第二个 topology key,依此类推;如果遍历完所有 topology key 也没有匹配到 endpoint 就会拒绝转发,就像此 service 没有后端 endpoint 一样。

有一个特殊的 topology key “*“,它可以匹配所有 endpoint,如果 topologyKeys 包含了 *,它必须在列表末尾,通常是在没有匹配到合适的拓扑域来实现就近转发时,就打消就近转发的念头,可以转发到任意 endpoint 上。

当前 topology key 支持以下可能的值(未来会增加更多):

kubernetes.io/hostname: 节点的 hostname,通常将它放列表中第一个,表示如果本机有 endpoint 就直接转发到本机的 endpoint。
topology.kubernetes.io/zone: 节点所在的可用区,通常将它放在 kubernetes.io/hostname 后面,表示如果本机没有对应 endpoint,就转发到当前可用区其它节点上的 endpoint(部分云厂商跨可用区通信会收取额外的流量费用)。
topology.kubernetes.io/region: 表示节点所在的地域,表示转发到当前地域的 endpoint,这个用的应该会比较少,因为通常集群所有节点都只会在同一个地域,如果节点跨地域了,节点之间通信延时将会很高。
*: 忽略拓扑域,匹配所有 endpoint,相当于一个保底策略,避免丢包,只能放在列表末尾。
topologyKeys 与 externalTrafficPolicy=Local 不兼容,是互斥的,如果 externalTrafficPolicy 为 Local,就不能定义 topologyKeys,反之亦然。
topology key 必须是合法的 label 格式,并且最多定义 16 个 key。
# 以kube-dns 为例:
---
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 192.66.0.2
  topologyKeys: ["kubernetes.io/hostname", "topology.kubernetes.io/zone", "*"] # 添加参数
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
  - name: metrics
    port: 9153
    protocol: TCP
# 验证ServiceTopology 是否生效
进去node 节点
无kube-dns 容器节点
:~# ipvsadm -Ln | grep :53
TCP  10.66.0.2:53 rr
  -> 10.83.98.136:53              Masq    1      0          0
  -> 10.90.153.135:53             Masq    1      0          0
UDP  10.66.0.2:53 rr
  -> 10.83.98.136:53              Masq    1      0          0
  -> 10.90.153.135:53             Masq    1      0          0
# 有kube-dns 容器节点
[ ~]# ipvsadm -Ln| grep :53
TCP  10.66.0.2:53 rr
  -> 10.90.153.135:53             Masq    1      0          0
UDP  10.66.0.2:53 rr
  -> 10.90.153.135:53             Masq    1      0          0
# 直接就是当前node 节点容器IP

相关推荐