一些废话
k8s 的 cni 其中一个重要的功能是将 Pod 的网络栈接管后使用某种协议封包从而在 node 之间传输。比如:
- flanal:基于 udp 的私有协议
- cilium:vxlan
- calico:IPIP
在通过路由和转发将数据包发送至目标地址所在的 Node 节点上,让 Node 节点上运行的网络组件解包后将原始网络数据通过 CNI 接口传递给 Pod 容器。
这样一来,要完成传统网络与 k8s 的 SDN 网络互联互通,需要解决封包格式与路由条目这两个问题。
好在我们的 calico 这个网络组件诞生就是为了和传统网络协议所兼容。通过简单的配置,可以使 calico 对虚拟网络的数据不封包,直接三层转发。即 calico 的 BGP 模式。
calico 在每个 Node 节点上运行 BGP 协议以和集群其他节点交换路由表,使每个 Node 节点都变成了一台 BGP 路由器。从而使得 k8s 的虚拟网络,在原有的网络上直接三层转发。
同时,我们还可以在内网的 DNS 服务器上为集群的域名配置解析委派,将 cluster.local 域转发至集群 coreDNS 进行解析,即可完成集群域名互通。
实操
在(一)中,我们使用 cilium 替换了 kubeadm 预装的 kube-proxy 组件。但我们这里要用 calico ,就需要把 kube-proxy 请回来。
在生成默认配置后,我们需要向 kubeadm.init.yaml 文件追加以下内容:
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
ipvs:
strictARP: true
kubeadm 会在初始化集群时传将上面的配置传给 kube-proxy。kube-proxy 默认会使用 iptables 规则做 DNAT 来实现 service,效率略低,因此我们改用了 ipvs 模式,也就是经典 lvs。同时,我们这里设置 ipvs 的 ARP 模式为 strict,方便后期使用 metal-lb 的 2 层模式。
在 启动第一个 controlplane 节点 中,将 --skip-phases=addon/kube-proxy 参数去掉,即:
kubeadm init \
--config kubeadm.init.yaml \
--upload-certs
calico 从 3.15 开始学坏了,你往集群里直接安装的不是 calico ,而是一个叫做 tigeraOperator 的控制器。这个控制器会通过 Installation.operator.tigera.io 这个 CRD 里设置的安装参数来帮你安装 calico。不过,比起之前 calico 放弃 helm 安装,这个 tigeraOperator 是支持 helm 的,并且支持使用 helm values 设置 Installation 这个 CRD。
helm repo add projectcalico https://projectcalico.docs.tigera.io/charts
helm install calico projectcalico/tigera-operator \
--version v3.22.1 \
--set installation.registry=192.168.1.10:8082' \
--set tigeraOperator.registry=null \
--set calicoctl.image='calico/ctl'
还记得 192.168.1.10:8082 么,这是我们在(一)中搭建的私库。由于 tigeraOperator 写死了要在镜像名里带上仓库地址,installation.registry 留空会导致直接使用 docker.io 仓库——这样每个 node 都需要直接连接公网仓库下载一次镜像,过于浪费带宽了。我们还是提前把镜像下载好 push 进咱们自己的仓库里吧。
设置
虽说 calico 使用 BGP 协议与路由器或者三层交换机协商路由表,但其实用的是 iBGP 协议,和运营商、IDC 之间的 eBGP 还是有区别的。
用 BGP 呢首先就要有 AS 号,这个号和 IP 地址一样是需要统一分配和购买的。好在 64512 - 65534 这一段是专门分配用来做私有编号的,就像 IP 里面的私有地一样。这里我们就用 64512:
kind: BGPConfiguration
apiVersion: crd.projectcalico.org/v1
metadata:
generation: 1
name: default
spec:
asNumber: 64512
logSeverityScreen: Info
nodeToNodeMeshEnabled: false
serviceClusterIPs:
- cidr: 10.43.0.0/16
---
kind: BGPPeer
apiVersion: crd.projectcalico.org/v1
metadata:
generation: 1
name: router-or-l3sw
spec:
asNumber: 64512
peerIP: 192.168.1.1
这里我们预设了 192.168.1.1 这个 ip 是你的路由器或者三层交换机——不管是啥,你需要在这个设备上开启 BGP 协议,使用同样的 AS 号码 64512来开启 iBGP,同时设置集群所有 node 的 IP 为 peer,并设置 Route Reflector。之后导入上文的 calico 的 CRD 配置,就可以去路由器上观察 BGP 状态和路由表了。
使用
- Pod 容器 IP 和 Service 服务 clusterip 集群 IP 均可直接访问,注意需要添加端口访问。
- Pod 容器 IP 直接使用服务本身监听的端口访问。Service 服务 clusterip 集群 IP 使用服务映射端口访问。
- Pod 容器 IP 每次重启、部署、更新均会发生变更。Service 服务 clusterip 集群 IP 不会。
- 集群服务可以通过域名访问。格式是【服务名】.【命名空间】.svc.cluster.local:【服务端口】。