基于 istio 的 k8s 多集群实践 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GopherDaily
V2EX    Kubernetes

基于 istio 的 k8s 多集群实践

  •  1
     
  •   GopherDaily 2023-04-05 17:00:34 +08:00 2237 次点击
    这是一个创建于 967 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设我们在阿里云上有一个托管的 k8s 集群, cn-shanghai, 在线下的某个机房有一个自己维护的 k8s 集群, wuxi. 现在我们希望通过基于 Istio 的 Mesh 来实现这两个集群之间的互联互通.

    效果展示

    对最终效果, 我们希望:

    • 如果被调用方在两个集群都存在, 则优先调用本集群服务
    • 如果被调用方在本集群不存在, 则调用降级到其他集群

    我们先在 cn-shanghai 部署 helloworld-v1, 随后在 wuxi 尝试调用 helloworld.

     kubectl --context cn-shanghai get pods | grep helloworld helloworld-v1-776f57d5f6-sxjtw 2/2 Running 0 162m kubectl --context wuxi exec -ti sleep-5597f78777-hq7vk -- curl helloworld.dev:5000/hello Hello version: v1, instance: helloworld-v1-776f57d5f6-sxjtw 

    而当我们在 wuxi 部署 helloworld-v2 时, 从 wuxi 发布的调用均匀分布在两个集群.

     kubectl --context wuxi get pods | grep helloworld helloworld-v2-7bd9f44595-db94r 2/2 Running 0 14s kubectl --context wuxi exec -ti sleep-5597f78777-hq7vk -- curl helloworld.dev:5000/hello Hello version: v1, instance: helloworld-v1-776f57d5f6-sxjtw kubectl --context wuxi exec -ti sleep-5597f78777-hq7vk -- curl helloworld.dev:5000/hello Hello version: v2, instance: helloworld-v2-7bd9f44595-db94r 

    显然, 当本集群存在被调用方时, 我们更希望调用尽量集中在集群内. 通过选择合适的 LocalityLoadBalancerSetting, 很轻松就可以实现类似需求.

     kubectl --context wuxi apply -f demo-dr.yaml destinationrule.networking.istio.io/helloworld created kubectl --context wuxi exec -ti sleep-5597f78777-hq7vk -- curl helloworld.dev:5000/hello Hello version: v2, instance: helloworld-v2-7bd9f44595-db94r kubectl --context wuxi exec -ti sleep-5597f78777-hq7vk -- curl helloworld.dev:5000/hello Hello version: v2, instance: helloworld-v2-7bd9f44595-db94r kubectl --context wuxi exec -ti sleep-5597f78777-hq7vk -- curl helloworld.dev:5000/hello Hello version: v2, instance: helloworld-v2-7bd9f44595-db94r 

    Istio 的多集群方案

    Istio 在文档中介绍了多种多集群的方案, 我们选择的是网络隔离下的多主, Install Multi-Primary on different networks.

    Multiple primary clusters on separate networks

    多主架构中, 每个集群都拥有独立的 control plane (istiod) 来管理本集群的 mesh. 相较于单集群架构的主要区别在于:

    • 每个集群的 istiod 都同时监听所有集群的资源变化.
    • 集群之间的访问需要通过 Network Gateway.

    对熟悉 Istio 的同学来说, 上图的架构应该是非常容易理解的, 唯一需要深入探究的应该是 Network Gateway 相关内容. Istio 通过几个方面实现了网络隔离下的跨集群调用:

    • 需要用户创建 Ingress Gateway 并指定暴露给其他集群的服务.
    • Istio 在向 Envoy 推送 Endpoint 之前, 将非本集群的地址替换为对应的 Network Gateway.
    • 在发送给 Network Gateway 的请求中, 通过 SNI 记录目标服务.

    wuxi 的 NetworkGateway 监听了 15443 端口并针对相关服务做路由.

    k --context wuxi get -n ingress-cluster pods -l app=cluster-wuxi NAME READY STATUS RESTARTS AGE cluster-wuxi-6fdbb84466-zgwwr 1/1 Running 0 3h7m istioctl --context wuxi proxy-config listener cluster-wuxi-6fdbb84466-zgwwr.ingress-cluster --port 15443 | grep helloworld 0.0.0.0 15443 SNI: outbound_.5000_._.helloworld.dev.svc.cluster.local; App: istio,istio-peer-exchange,istio-http/1.0,istio-http/1.1,istio-h2 Cluster: outbound_.5000_._.helloworld.dev.svc.cluster.local 

    cn-shanghai 内 Envoy 接收到 Endpoint 中, wuxi 机房 Pod 的 IP 都被替换为 NetworkGateway 的对外地址.

     kubectl --context wuxi get -n ingress-cluster svc cluster-wuxi NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cluster-wuxi NodePort 172.23.234.78 10.18.10.196 15021:32125/TCP,15443:30880/TCP,15012:30500/TCP,15017:32230/TCP 3h50m istioctl --context cn-shanghai proxy-config endpoints sleep-75b85f5796-f6k89 --cluster "outbound|5000||helloworld.dev.svc.cluster.local" ENDPOINT STATUS OUTLIER CHECK CLUSTER 10.18.10.196:30880 HEALTHY OK outbound|5000||helloworld.dev.svc.cluster.local 172.20.171.185:5000 HEALTHY OK outbound|5000||helloworld.dev.svc.cluster.local 

    Envoy LB 相关的配置中, 支持 priority 和 weight 两个属性, 当指定本地优先时, Istio 在向 Envoy 推送信息时会将集群内 Endpoint 的 priority 设置为 1, 进而实现本地优先.

    istioctl --context wuxi proxy-config endpoints sleep-5597f78777-hq7vk --cluster "outbound|5000||helloworld.dev.svc.cluster.local" -o json | jq '.[].hostStatuses[] | [.address, .priority]' [ { "socketAddress": { "address": "172.22.0.30", "portValue": 5000 } }, null ] [ { "socketAddress": { "address": "10.0.139.33", "portValue": 32652 } }, 1 ] 

    坑与妥协

    我们线下和云上的两个集群, Node 之间是互通的, 所以并不一定需要将 Network Gateway 的 Service 设置为 LoadBalancer. 当你选择直接使用 NodePort 时, Istio 允许你通过注解 traffic.istio.io/nodeSelector 来申明对应的节点. 但是需要注意两点:

    ExternalIP 这个要求基本使得这个方案不需要任何的操作性. 换一个思路, 我们选择了部分固定的节点, 将对应 IP 直接设置为 Service 的 externalIPs, 这时候将 traffic.istio.io/nodeSelector 设置为 {} 即可.

    和大部分 k8s 使用者一样, 我们依赖 CoreDNS 提供的域名解析服务, 而 Istio 并没有直接解决这个问题. 已有的一些解决方案在复杂度和成熟度上并没有特别令人满意, 所以我们直接土法炼钢, 在 CI/CD 流程中直接同步 Service 到所有集群.

    GopherDaily
        1
    GopherDaily  
    OP
       2023-04-06 13:08:39 +08:00
    up 下
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2932 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 14:01 PVG 22:01 LAX 06:01 JFK 09:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86