一、概述

Calico 是一个联网和网络战略供货商。 Calico 支撑一套灵敏的网络选项,因而你能够依据自己的状况选择最有效的选项,包含非掩盖和掩盖网络,带或不带 BGP。 Calico 运用相同的引擎为主机、Pod 和(假如运用 Istio 和 Envoy)应用程序在服务网格层履行网络战略。Calico以其功用、灵敏性而出名。Calico的功用更为全面,更为杂乱。它不只供给主机和pod之间的网络衔接,还涉及网络安全和办理。Calico CNI插件在CNI(container network interface)结构内封装了Calico的功用。

GitHub地址: github.com/projectcali…

官方文档:projectcalico.docs.tigera.io/about/about…

想了解flannel的小伙伴,能够参阅我这篇文章:Kubernetes(k8s)CNI(flannel)网络模型原理

其它CNI插件,能够检查k8s官网:kubernetes.io/docs/concep…

二、Calico 架构和中心组件

Calico不运用堆叠网络比方flannel和libnetwork堆叠网络驱动,它是一个纯三层的办法,运用虚拟路由代替虚拟交流,每一台虚拟路由经过BGP协议传达可达信息(路由)到剩余数据中心;Calico在每一个核算节点运用Linux Kernel完成了一个高效的vRouter来担任数据转发,而每个vRouter经过BGP协议担任把自己上运转的workload的路由信息像整个Calico网络内传达——小规划布置能够直接互联,大规划下可经过指定的BGP route reflector来完成。

Kubernetes(k8s)CNI(Calico)网络模型原理

Calico 的中心组件:

  • Felix:运转在每一台 Host 的 agent 进程,首要担任网络接口办理和监听、路由、ARP 办理、ACL 办理和同步、状态上报等。

  • etcd:分布式键值存储,首要担任网络元数据一致性,确保Calico网络状态的准确性,能够与kubernetes共用;

  • BGP Client(BIRD):Calico 为每一台 Host 布置一个 BGP Client,运用 BIRD 完成,BIRD 是一个单独的持续发展的项目,完成了很多动态路由协议比方 BGP、OSPF、RIP 等。在 Calico 的人物是监听 Host 上由 Felix 注入的路由信息,然后经过 BGP 协议广播告知剩余 Host 节点,从而完成网络互通。

  • BGP Route Reflector:在大型网络规划中,假如仅仅运用 BGP client 形成 mesh 全网互联的计划就会导致规划约束,因为所有节点之间俩俩互联,需求 N^2 个衔接,为了处理这个规划问题,能够选用 BGP 的 Router Reflector 的办法,使所有 BGP Client 仅与特定 RR 节点互联并做路由同步,从而大大削减衔接数。

三、什么是BGP?

鸿沟网关协议(BGP是运转于 TCP上的一种自治体系的路由协议,也是互联网上一个中心的去中心化自治路由协议。网络可达信息包含列出的自治体系(AS)的信息。这些信息有效地结构了 AS 互联的拓朴图并由此铲除了路由环路,一起在 AS 级别上可施行战略决策。在互联网中,一个自治体系(AS)是一个有权自主地决定在本体系中应选用何种路由协议的小型单位。

  • BGP是路由器之间的通信协议,首要用于AS(AutonomousSystem,自治体系)之间的互联。

  • AS内部有多个BGP speaker,分为ibgp、ebgp,ebgp与其它AS中的ebgp树立BGP衔接。

  • AS内部的BGP speaker经过BGP协议交流路由信息,最终每一个BGP speaker拥有整个AS的路由信

能够把calico中的node节点当成一个AS,而node节点中的容器是AS中的router,calico经过BGP解析,将整个网络中容器地址的路由表绘制出来。

Kubernetes(k8s)CNI(Calico)网络模型原理

  • IBGP(Internal BGP):当BGP运转于同一自治体系内部时,被称为IBGP

  • EBGP(External BGP):当BGP运转于不同自治体系之间时,称为EBGP

BGP两种形式:

  • 全互联形式(node-to-node mesh)——全互联形式,每一个BGP Speaker都需求和其他BGP Speaker树立BGP衔接,这样BGP衔接总数就是N^2,假如数量过大会耗费很多衔接。假如集群数量超过100台官方不主张运用此种形式。
  • 路由反射形式Router Reflection(RR)——RR形式中会指定一个或多个BGP Speaker为RouterReflection,它与网络中其他Speaker树立衔接,每个Speaker只要与Router Reflection树立BGP就能够获得全网的路由信息。在calico中能够经过Global Peer完成RR形式。

三、Calico 两种网络形式

1)IPIP 形式

  • 从字面来理解,就是把一个IP数据包又套在一个IP包里,即把 IP 层封装到 IP 层的一个 tunnel,看起来似乎是浪费,实则否则。
  • 它的效果其实基本上就相当于一个基于IP层的网桥!
  • 一般来说,普通的网桥是基于mac层的,根本不需 IP,而这个 ipip 则是经过两端的路由做一个 tunnel,把两个原本不通的网络经过点对点衔接起来。
  • ipip 的源代码在内核 net/ipv4/ipip.c 中能够找到。

Calico的IPIP形式作业原理如下图:

Kubernetes(k8s)CNI(Calico)网络模型原理

Calico运用的这个tunl0设备,是一个IP地道(IP tunnel)设备

在上面的比如中,IP包进入IP地道设备之后,就会被Linux内核的IPIP驱动接收。IPIP驱动会将这个IP包直接封装在一个宿主机网络的IP包中,如下所示:

Kubernetes(k8s)CNI(Calico)网络模型原理

2)BGP 形式

  • 鸿沟网关协议(Border Gateway Protocol, BGP)是互联网上一个中心的去中心化自治路由协议。
  • 它经过保护IP路由表或‘前缀’表来完成自治体系(AS)之间的可达性,归于矢量路由协议。
  • BGP不运用传统的内部网关协议(IGP)的目标,而运用基于途径、网络战略或规矩集来决定路由。因而,它更适合被称为矢量性协议,而不是路由协议。
  • BGP,通俗的讲就是讲接入到机房的多条线路(如电信、联通、移动等)融合为一体,完成多线单IP,BGP 机房的长处:服务器只需求设置一个IP地址,最佳访问路由是由网络上的主干路由器依据路由跳数与其它技术目标来确定的,不会占用服务器的任何体系。
  • BGP网络相比较IPIP网络,最大的不同之处就是没有了地道设备 tunl0。 前面介绍过IPIP网络pod之间的流量发送tunl0,然后tunl0发送对端设备。BGP网络中,pod之间的流量直接从网卡发送目的地,削减了tunl0这个环节。

Kubernetes(k8s)CNI(Calico)网络模型原理

四、装置Calico插件

1)经过helm装置Calico

官方文档:projectcalico.docs.tigera.io/getting-sta…

# 添加源
helm repo add projectcalico https://projectcalico.docs.tigera.io/charts
# helm repo update  
# 下载
helm pull  projectcalico/tigera-operator --version v3.24.5
# 解压
tar -xf tigera-operator-v3.24.5.tgz
# 装置,默认命名空间:calico-system
helm install calico ./tigera-operator  --namespace tigera-operator --create-namespace
# 检查tigera-operator所有资源
kubectl get all -n tigera-operator

2)经过yaml文件装置

wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml
# 检查
kubectl get all -n kube-system|grep calico

3)k8s flannel网络切换calico

1、卸载flannel插件

### 1、检查已装置flannel信息
cat /etc/cni/net.d/10-flannel.conflist
### 2、删除flannel布署资源
kubectl delete -f kube-flannel.yml
### 3、铲除flannel遗留信息,在集群各节点整理flannel网络的残留文件
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni
rm -rf /etc/cni/net.d

2、开端装置Calico插件

# 下载
wget https://docs.projectcalico.org/manifests/calico.yaml
# 装置
kubectl apply -f calico.yaml
# 检查
kubectl get all -n kube-system|grep calico
# 假如节点NotReady,重启以下容器或许kubelet试试
systemctl restart containerd docker

Kubernetes(k8s)CNI(Calico)网络模型原理

五、网络战略

关于网络战略,能够参阅我这篇文章:【云原生】k8s 中的 hostNetwork 和 NetworkPolicy(网络战略)解说与实战操作

六、简略运用

官方文档:projectcalico.docs.tigera.io/security/ku…

1)网络战略示例

1、答应来自同一命名空间中的 Pod 的进口流量

答应来自同一命名空间中的 Pod 的进口流量,在以下示例中,传入带有标签的 Pod 的 label color: red,仅当它们来自 pod 带有label color: red,才被答应转到80端口。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-same-namespace
  namespace: default
spec:
  podSelector:
    matchLabels:
      color: blue
  ingress:
  - from:
    - podSelector:
        matchLabels:
          color: red
    ports:
      - port: 80

2、答应来自不同命名空间中的 Pod 的进口流量

在以下示例中,仅当传入流量来自带有标签 color: red的 Pod 时,才答应传入流量,在带有标签的命名空间中带有标签shape: square,在端口上 80.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-same-namespace
  namespace: default
spec:
  podSelector:
    matchLabels:
      color: blue
  ingress:
  - from:
    - podSelector:
        matchLabels:
          color: red
      namespaceSelector:
        matchLabels:
          shape: square
    ports:
    - port: 80

2)固定Pod IP

【示例1】pod 运用注解 cni.projectcalico.org/ipAddrs

# vi fixed-ip-test-pod.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
  annotations:
    cni.projectcalico.org/ipAddrs: "[\"10.244.1.200\"]"
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

Kubernetes(k8s)CNI(Calico)网络模型原理
【示例2】操控器 单pod 运用注解 cni.projectcalico.org/ipAddrs

# vi fixed-ip-test-deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fixed-ip-test
  namespace: default
  labels:
    k8s-app: cloudnativer-test
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  selector:
    matchLabels:
      k8s-app: cloudnativer-test
  template:
    metadata:
      labels:
        k8s-app: cloudnativer-test
      annotations:
        cni.projectcalico.org/ipAddrs: "[\"10.244.1.220\"]"
    spec:
      containers:
      - name: fixed-ip-test
        image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

【示例3】操控器 多pod固定IP池

需求创建额外IP池(除了默认IP池),运用注解cni.projectcalico.org/ipv4pools。

这儿先装置一个客户端东西calicoctl

wget https://github.com/projectcalico/calico/releases/download/v3.24.5/calicoctl-linux-amd64
mv calicoctl-linux-amd64 /usr/local/bin/calicoctl 
chmod +x /usr/local/bin/calicoctl

编排

# vi fixed-ip-test-deployment2.yaml
# apiVersion: projectcalico.org/v3
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
  name: new-pool1
spec:
  blockSize: 31
  cidr: 10.244.3.220/24
  ipipMode: Never
  natOutgoing: true
---
# apiVersion: projectcalico.org/v3
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
  name: new-pool2
spec:
  blockSize: 31
  cidr: 10.244.4.221/24
  ipipMode: Never
  natOutgoing: true
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fixed-ip-test2
  namespace: default
  labels:
    k8s-app: cloudnativer-test
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  selector:
    matchLabels:
      k8s-app: cloudnativer-test
  template:
    metadata:
      labels:
        k8s-app: cloudnativer-test
      annotations:
        # 【注意】不能运用单引号
        "cni.projectcalico.org/ipv4pools": "[\"new-pool1\",\"new-pool2\"]"
    spec:
      containers:
      - name: fixed-ip-test
        image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

检查

# 检查ip池
calicoctl get ippool
kubectl get pods -owide

Kubernetes(k8s)CNI(Calico)网络模型原理

【温馨提示】要更改用于Pod的默认IP范围,请修正calico.yaml清单文件中CALICO_IPV4POOL_CIDR部分。

七、Calico VS Flannel

现在比较常用的是flannelcalico,flannel的功用比较简略,不具有杂乱网络的装备能力,不支撑网络战略;calico是比较超卓的网络办理插件,单具有杂乱网络装备能力的一起,往往意味着本身的装备比较杂乱,所以相对而言,比较小而简略的集群运用flannel,考虑到日后扩容,未来网络或许需求参加更多设备,装备更多战略,则运用calico更好。

1)Flannel

  • 优势:布置简略,功用一般。
  • 劣势:没办法完成固定 IP 的容器漂移,没法做子网隔离,对上层设计依靠程度高,没有 IPAM , IP 地址浪费,对 Docker 启动办法有绑定。

2)Calico

  • Calico还以其先进的网络功用而出名。网络战略是其最受追捧的功用之一。
  • 支撑固定 IP 的装备。
  • 此外,Calico还能够与服务网格Istio集成,以便在服务网格层和网络根底架构层中解释和施行集群内作业负载的战略。这意味着用户能够装备强壮的规矩,描绘Pod应怎么发送和承受流量,提高安全性并操控网络环境。

两个插件运用的都比较广泛,假如需求设置网络战略,规划更杂乱的网络,固定IP等,就主张运用Calico;假如仅仅简略的运用网络插件的通讯功用就选择Flannel。

关于Kubernetes(k8s)CNI(Calico)网络模型原理介绍与布置就先到这儿了,有疑问的小伙伴,欢迎给我留言,后续会持续更新【云原生+大数据】相关的文章,请小伙伴耐性等候~