如何使用hybridnet为混合云场景提供容器网络_云原生应用交付平台-阿里云帮助中心
一、背景
CNStack 是阿里云推出的一款开放的一站式企业级云原生技术中台。在异构的混合云基础设施上,对资源进行统一纳管和优化调度,以开放的、云原生的方式为平台及业务系统提供生产可用的产品及组件,帮助用户打造满足大规模、高性能、合规性和业务连续性等要求的分布式应用系统,提升企业数字化转型的整体效能。
hybridnet 是 CNStack 使用的容器网络实现,同时也是阿里云推出的唯二开源通用 K8s 网络插件实现之一。
解释下“通用”俩字,阿里云目前存在两种开源 K8s 网络插件实现:terway、hybridnet。与 hybridnet 网络插件不同,terway 网络插件是与阿里云基础设施紧密结合的,并不考虑在非阿里云公有云基础设施环境部署的情况,而 hybridnet 更像是类似 flannel、calico 的社区解决方案,支持在任意环境拉起和部署。
二、架构
数据链路概述
在一个 hybridnet 集群内,流量的行为总体描述如下:
1. 同一节点上的 pod 之间通信的流量只在节点内部转发
2. overlay pod 与其他 pod (包括 underlay pod)互相访问的流量都是隧道流量
3. underlay pod 访问非 overlay pod 的流量(包括节点、集群外 ip 地址)为非隧道流量
4. 集群内节点访问 overlay pod 的流量为隧道流量(不经过 NAT)
5. overlay pod 访问集群内节点以及集群外部 ip 的流量为 NAT 流量(SNAT 成对应节点 ip)
数据链路完全基于策略路由实现,这让 hybridnet 跟 kube-proxy、felix 的 iptables/ipvs 规则以及其他类似的 service/networkpolicy 实现能够良好地适配,其流量路径如图:
三、overlay模式部署
3.1、部署helm
官网地址:
https://helm.sh/docs/intro/install/
https://github.com/helm/helm/releases
[root@k8s-master1 ~]# wget https://get.helm.sh/helm-v3.9.0-linux-amd64.tar.gz
[root@k8s-master1 ~]# tar xvf helm-v3.9.0-linux-amd64.tar.gz
[root@k8s-master1 ~]# mv linux-amd64/helm /usr/local/bin/
[root@k8s-master2 ~]# helm version
version.BuildInfo{Version:"v3.9.0", GitCommit:"7ceeda6c585217a19a1131663d8cd1f7d641b2a7", GitTreeState:"clean", GoVersion:"go1.17.5"}
3.2、添加repo
[root@k8s-master1]# helm repo add hybridnet https://alibaba.github.io/hybridnet/
"hybridnet" has been added to your repositories
[root@k8s-master1]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "hybridnet" chart repository
Update Complete. ⎈Happy Helming!⎈
[root@k8s-master1]# helm install hybridnet hybridnet/hybridnet -n kube-system --set init.cidr=10.200.0.0/16 #配置overlay pod网络, 如果不指定--set init.cidr=10.200.0.0/16默认会使用100.64.0.0/16 NAME: hybridnet
NAME: hybridnet
LAST DEPLOYED: Mon Mar 27 15:06:22 2023
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
3.3、检查
[root@k8s-master1][15:15:12][OK] ~/hybridnet
# kubectl get pod -A|grep hybridnet
kube-system hybridnet-daemon-2k9bd 2/2 Running 1 (16m ago) 20m
kube-system hybridnet-daemon-bdglk 2/2 Running 1 (16m ago) 20m
kube-system hybridnet-daemon-f6gnw 2/2 Running 1 (15m ago) 20m
kube-system hybridnet-daemon-g9kwm 2/2 Running 0 20m
kube-system hybridnet-daemon-ln4c8 2/2 Running 1 (15m ago) 20m
kube-system hybridnet-daemon-xvktn 2/2 Running 1 (16m ago) 20m
kube-system hybridnet-manager-8648c47f95-56mt8 1/1 Running 0 20m
kube-system hybridnet-manager-8648c47f95-7lxx5 1/1 Running 0 20m
kube-system hybridnet-manager-8648c47f95-x9v2t 1/1 Running 0 20m
kube-system hybridnet-webhook-79d8c5c86b-9g52p 1/1 Running 0 20m
kube-system hybridnet-webhook-79d8c5c86b-ctcbn 1/1 Running 0 20m
kube-system hybridnet-webhook-79d8c5c86b-ms7h4 1/1 Running 0 20m
[root@k8s-master1][15:27:14][OK] ~/hybridnet
# kubectl get network
NAME NETID TYPE MODE V4TOTAL V4USED V4AVAILABLE LASTALLOCATEDV4SUBNET V6TOTAL V6USED V6AVAILABLE LASTALLOCATEDV6SUBNET
init 4 Overlay 65534 14 65520 init 0 0 0
[root@k8s-master1][15:27:21][OK] ~/hybridnet
# kubectl get subnets.networking.alibaba.com
NAME VERSION CIDR START END GATEWAY TOTAL USED AVAILABLE NETID NETWORK
init 4 100.64.0.0/16 65534 14 65520 init
3.4、验证(PodIP固定)
这里说明一下,只有StatefulSet控制器的pod才能保持ip不变
3.4.1、创建应用
[root@k8s-master1][15:37:52][OK] ~/hybridnet
# kubectl get pod -o wide|grep web
web-0 1/1 Running 0 10s 100.64.0.8 k8s-node3 <none> <none>
web-1 1/1 Running 0 8s 100.64.0.12 k8s-node3 <none> <none>
可以看到,新创建的pod已经使用了我们subnet默认网段。
3.4.2、删除应用
[root@k8s-master1][15:37:56][OK] ~/hybridnet
# kubectl delete pod web-1
pod "web-1" deleted
[root@k8s-master1][15:39:07][OK] ~/hybridnet
# kubectl get pod -o wide|grep web
web-0 1/1 Running 0 84s 100.64.0.8 k8s-node3 <none> <none>
web-1 1/1 Running 0 3s 100.64.0.12 k8s-node3 <none> <none>
可以看到,重新创建的pod依然使用的之前的ip
3.4.3、分析原因
[root@k8s-master1][15:40:38][OK] ~/hybridnet
# kubectl get ipinstances.networking.alibaba.com -A
NAMESPACE NAME IP GATEWAY PODNAME NODE SUBNET NETWORK
default 100-64-0-12 100.64.0.12/16 web-1 k8s-node3 init init
default 100-64-0-14 100.64.0.14/16 nfs-client-provisioner-756c8c965d-bzpzv k8s-node2 init init
default 100-64-0-8 100.64.0.8/16 web-0 k8s-node3 init init
kube-system 100-64-0-3 100.64.0.3/16 coredns-7f6cbbb7b8-gpqk2 k8s-master1 init init
kube-system 100-64-0-4 100.64.0.4/16 metrics-server-55776b9d5d-cr5gf k8s-node3 init init
kube-system 100-64-0-6 100.64.0.6/16 coredns-7f6cbbb7b8-rcvmf k8s-master1 init init
monitoring 100-64-0-10 100.64.0.10/16 prometheus-kube-state-metrics-64d7f97598-94ln9 k8s-node2 init init
monitoring 100-64-0-11 100.64.0.11/16 prometheus-grafana-74f4f5f8f9-6vgb5 k8s-node1 init init
monitoring 100-64-0-13 100.64.0.13/16 alertmanager-prometheus-kube-prometheus-alertmanager-0 k8s-node1 init init
monitoring 100-64-0-2 100.64.0.2/16 prometheus-kube-prometheus-operator-6df74d6c5f-shq6t k8s-node1 init init
monitoring 100-64-0-7 100.64.0.7/16 prometheus-prometheus-kube-prometheus-prometheus-0 k8s-node2 init init
每个 hybridnet 集群要正常工作,至少需要存在一个 Network 和 Subnet。可以说 Network 和 Subnet 对象就是 hybridnet 对用户提供的配置入口。对于每个 pod 的 ip,hybridnet 会自动创建一个 IPInstance 对象,该 CRD 是 namespace scope 的,与 pod 处于相同 namespace。IPInstance 对象主要的功能是用来持久化 hybridnet 地址分配信息,当然也可以用来提供给用户查询和审计,对于用户来讲,通常是只读的。