Calico

Calico是三层虚拟网络解决方案(BGP)。每一个节点都是一个vRouter,都需要通过BGP协议学习生成路由规则,从而实现各节点上Pod之间互联互通。

一、BGP通信模型

BGP模型要求所有节点在同一个二层网络中。不一定所有的底层网络都支持BGP。

1、BGP peer(小规模网络使用)

点对点BGP,如果一个网络中有10个BGP,即是1:9的通信模型,形成n*(n-1)个通信网络。

所以在此模型下如果网络规模较大BGP路由学习报文会占据很大的网络带宽。

BGP peer不存在单点问题,BGP peer宕机会有其他的进行替代。

2、BGP Reflector(大规模网络使用)

反射器模型,所有节点都将自己所有拥有的路由信息汇总给Reflector,由Reflector用1:n-1的方式向外进行反射。

BGP Reflector需要做冗余。

二、Overlay Network

1、IPIP

用IP报文来封装IP报文,因此其开销更小。

2、VXLAN

类似于Flannel的VXLAN启动DirectRouting的网络模型,Calico也支持混合使用路由和叠加网络模型。

如果节点在同一子网内使用BGP,如果跨子网则使用VXLAN。

三、架构

Flannel中host-gw模型使用veth-pair

Calico使用内核Iptables和Routes表来完成其中部分功能。

主要组件:

1.每个节点都需要运行组件:
  • BGP客户端(默认启用):需要运行于每个节点,负责将Felix生成的路由信息载入内核并通告到整个网络中。
  • BGP Reflector:专用反射各BGP客户端发来路由信息,将N->N-1转为N->1模型。
  • Felix:需要运行于各节点之上的守护进程,主要负责完成接口管理、路由规划、acl规划(即网络策略,借助iptables实现)、状态报告。
  • BIRD:是vRouter的关键实现,整个BGP的路由表是由BIRD生成的,而路由规划是Felix完成的。BIRD自身可以扮演两种角色。
2.在节点之外需要运行组件:
  • etcd:Calico也会Flannel一样需要依靠etcd来保存一些自身的状态数据,也可以像Flannel一样将API Server当为自身的存储后端。大规模集群中建议额外部署etcd专用于Calico集群,以免和K8S性能上冲突。
  • Route Reflector:路由反射器。
  • Calico编排系统插件:Calico不仅支持给K8S提供虚拟网络,也支持OpenShift、OpenStack。所以Calico是一个通用的虚拟网络。要让Calico能适用于K8S,需要一个Calico的编排系统插件让etcd和Calico插件之间能双向转换通信。
3.K8S所需组件:
  • calico-node:类似于Flanneld需要运行于每个节点之上。calico-node中封装了Felix和BIRD。
  • calico-kube-controller:运行于K8S集群上的中央控制系统。负责Calico和整个K8S的协同,也包括其他核心功能实现。

四、部署

https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises

1、下载calico资源清单

curl https://docs.projectcalico.org/manifests/calico.yaml -O

2、配置

确保Pod的CIDR为192.168.0.0/16,如果非此网点则需要修改calico.yaml。

3、部署

kubectl apply -f calico.yaml

4、验证

calico默认使用IPIP模型。

# 查看路由信息
ip r list

blackhole 10.244.0.0/24 proto bird         # blackhole 表示当前节点。
10.244.0.4 dev cali5411bb555f9 scope link  # 此处可以看到 pod 的数据流出是直接到达内核的
10.244.1.0/24 via 172.16.11.81 dev tunl0 proto bird onlink
# 出现 tunl0 接口,现在报文发送时会发送给 tunl0 接口
# tunl0 宿主机内核

查看calico的地址池

kubectl get ippools -o yaml

验证ipip工作逻辑

tcpdump -i eth0 -nn ip host k8s-node01 and host k8s-node03

02:33:55.805615 IP 172.16.11.81 > 172.16.11.83: IP 10.244.1.16.49490 > 10.244.3.16.10016: Flags [P.], seq 1133911456:1133911482, ack 3769557439, win 85, options [nop,nop,TS val 3535292140 ecr 2812652948], length 26 (ipip-proto-4)

# 从以上抓包结果中可以看出 ipip 在通信时,分为外部 ip 和内部 ip 2层。
# ipip-proto-4 表示此报文为 ipip 报文。

五、calicoctl

 curl -o /usr/bin/kubectl-calico -O -L  "https://github.com/projectcalico/calicoctl/releases/download/v3.21.5/calicoctl-linux-amd64"
kubectl-calico -h

kubectl calico -h
vim /etc/calico/calicoctl.cfg

apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
  datastoreType: "kubernetes" # 此处申明后端存储为kubernetes
  kubeconfig: "/root/.kube/config"

获取节点

kubectl calico get nodes

查看节点状态

kubectl-calico node status

获取地址池

kubectl calico get ippool
kubectl calico get ippool -o yaml

查看地址分配信息

kubectl calico ipam show --allow-version-mismatch

查看每个节点上的地址分配信息

kubectl calico ipam show --show-blocks

查看ipam配置信息

kubectl calico ipam show --show-configuration

+--------------------+-------+
|      PROPERTY      | VALUE |
+--------------------+-------+
| StrictAffinity     | false |   # pod被重建后是否使用原有地址
| AutoAllocateBlocks | true  |   # 是否支持自动分配地址
| MaxBlocksPerHost   |     0 |
+--------------------+-------+

六、配置

kubectl calico get ippools -o yaml
apiVersion: projectcalico.org/v3
items:
- apiVersion: projectcalico.org/v3
  kind: IPPool
  metadata:
    creationTimestamp: "2024-05-06T06:00:24Z"
    name: default-ipv4-ippool
    resourceVersion: "6789"
    uid: 943b85b2-9759-49ce-8f73-78f1f3f8a111
  spec:
    blockSize: 24
    cidr: 192.168.0.0/16
    ipipMode: CrossSubnet      # 将ipipMode改为CrossSubnet或Never
    natOutgoing: true
    nodeSelector: all()
    vxlanMode: Never
kind: IPPoolList
metadata:
  resourceVersion: "9418"

# 改BGP模式需要修改ipipMode
# CrossSubnet表示混杂模式也就是混合模式,表示跨节点子网时才使用IPIP
# Never表示纯BGP模式

# vxlanMode: CrossSubnet ipipMode: Never 表示VxLan的混合模型
  1. 将其重新应用到网络中
kubectl calico apply -f default-ipv4-ippool.yaml

BGP生效再次查看路由信息

ip route list

其他

1、在部署Calico时,发现网卡的过程通常涉及配置Calico以正确识别和使用宿主机的网络接口。

  • IP自动检测机制:默认情况下,它可能会选择第一个找到的有效网卡。
    • first-found:列出所有网卡IP并选择第一个(忽略特定网卡如docker0和lo)。
  • 修改IP_AUTODETECTION_METHOD
    • can-reach:指定一个目标IP或域名,Calico将尝试从所有网卡中找到能够到达该目标IP的网卡,并使用其IP地址。can-reach=x.x.x.x:选择能够到达指定IP地址的网卡。
    • interface:使用正则表达式来指定Calico应该使用的网卡名称。
    • kubernetes-internal-ip:从Kubernetes API获取Pod的IP地址(适用于Kubernetes环境)。
    • first-found:列出所有网卡IP并选择第一个(忽略特定网卡如docker0和lo)。
env:  
- name: IP_AUTODETECTION_METHOD  
  value: "interface=eth0"
env:  
- name: IP_AUTODETECTION_METHOD  
  value: "first-found"  # 显式指定first-found方法,尽管这通常是默认行为

results matching ""

    No results matching ""