k8s多集群通信

1,121 阅读4分钟

用户需求

StatefulSets场景下,单个Pod之间能有固定标识跨集群通信

描述:3个集群中起3个实例组成一个完整的服务。实例间能有固定标识互相独立通信

用户需求描述中说明单集群可能会扩展Pod,如下图中ZZZC机房起2个Pod,SHBT、BJPDC起1个Pod
ps:ZZZC、SHBT、BJPDC都是IDC

image.png

可实现方案(3种)

  1. 每一个Pod前挂一个VIP进行集群外访问,多个Pod起多个Stateful部署,我们容器对接了公司内部的负载均衡。或Ingress
  2. Pod支持固定IP。公司内部的PodIP在内网是互通的
  3. Headless Services支持多集群通信

方案2-固定PodIP

方案实现资料
Calico预留ip pool资源 ipreservation 防止自动分配为Pod指定IP,
By 添加 Annotation cni.projectcalico.org/ipAddrs": "["192.168.0.1"]"
Use a specific IP address with a pod
Cilium不支持can i pin the ip of the pod?
Will cilium IPAM support specified ip address of pod?
Kubu-OVN使用annotation定义StatefulSet固定IP时需要注意以下几点:
* IP必须在所属子网的CIDR内。
* 所使用的IP不能和已有的IP冲突。
* IP数量小于replicas数量时,多出的Pod将无法创建,需要根据StatefulSet的更新策略以及扩容规划调整 ovn.kubernetes.io/ip_pool中的IP数量。
StatefulSet固定IP
hostIP, hostPort限制:
* Pod不能随意漂移物理机。每次重新启动pod时,Kubernetes都可能将pod重新安排到其他节点上,因此应用程序的IP地址将更改。
* 相同端口的应用不能部署在同一物理机。当群集上运行的应用程序数量增加时,这可能会导致端口冲突。
结论:不建议使用,不好管理
Configuration Best Practices
阿里开源-OpenKruise原地升级(对应的是重建升级):
问题1:只允许修改限定的字段,如果尝试修改其他字段会被拒绝。
spec.template.metadata.*
spec.template.spec.containers[x].image
spec.template.metadata.labels/annotations 并且 container 中有配置 env from
更新以下字段会导致IP变化:
spec.template.spec.containers[x].env
spec.template.spec.containers[x].resources
问题2:Pod所在物理机故障,Pod重建至其他物理机,IP会发生变化
结论:支持以上前提下,能获得PodIP与物理机一样的生命周期
github.com/openkruise/…
Advanced StatefulSet
原地升级
阿里Terway(状态:公测中)Terway拥有更为灵活的IPAM(容器地址分配)策略。无需按节点分配地址段,随用随分配,地址无浪费。支持为Pod配置固定IP及独立虚拟交换机、安全组。
仅支持:StatefulSet
为Pod配置固定IP及独立虚拟交换机、安全组
京东云非开源-提供思路
历史原因,集团内很多基础运维业务包括日志、监控、访问策略控制、服务发现等都是以IP作为实例唯一标识
通过对Enhanced Statefulset Controller 、 Scheduler、CNI这几个模块扩展实现
对scheduler做的扩展主要是解决Pod资源预留问题。正常流程中当绑定静态IP的Pod删除后,Pod所占用的资源也会被释放,如果有其他新调度的Pod到这个节点上就会占用当前节点的资源。这时如果绑定静态IP的Pod在此节点重建可能就会因为资源不足而失败。
节点故障会创建同规格节点进行迁移
结论:非开源、定制化开发
支持Pod 绑定静态 IP ,基于K8s的自定义控制器—Enhanced Statefulset
kubernetes原生不支持Static IP for pod

方案3-Headless Services多集群通信

方案进度资料
kubernetes停滞2年了Multi-Cluster Services API
Linkerd迭代中,8.8k Starlinkerd2
istio不支持Headless services issues in multi-cluster multi-network
Make headless services work across multi-network gateways

Linkerd 实现原理

新增了很多组件与概念来实现

image.png 多集群通信使用Service与Gateway交互:

image.png Headless Service Stateful通信:

image.png west、east集群,  west集群启动Headless Service :

nginx-svc

同时每一个Pod都含有DNS name:

pod-0
pod-1

east集群会Copy west集群中的Headless Service和Pod DNS name 到自身集群中并为每个Pod 添加IP,同时命名为(添加west集群后缀进行区分)

nginx-svc-west
pod-0-west
pod-1-west
在east集群中访问pod-0-west时,linkerd2-proxy会拦截将它指向gateway,proxy将请求转发回west集群