Calico小结

本文的主要内容是对Calico的部署以及简单使用的总结,相关的详细概念还请参考官网。(https://www.projectcalico.org)

一、Calico简述

  Calico是一个纯三层的方案,为虚机及容器提供多主机间通信,没有使用重叠网络驱动,采用虚拟路由代替虚拟交换,每一台虚拟路由器通过BGP协议传播可达信息到其他虚拟或物理路由器。
  Calico架构图如图所示(网上找的,Calico的官网连结构图都没有)。


calico.jpg

  从图中可以看出Calico的主要组件有:

  1. Felix:Calico agent,运行在每台workload节点,主要负责配置路由及ACLs等信息,确保endpoint的连通状态;
  2. Etcd:分布式kv存储,主要负责网络元数据一致性,确保Calico网络状态的准确性;
  3. BGP Client(BIRD):主要负责把Felix写入kernel的路由信息分发到当前Calico网络,确保workload间的通信的有效性;
  4. BGP Route Reflector(BIRD):一般在大规模部署时采用,与所有节点互联的mesh模式不同,通过一个或多个BGP Route Reflector来完成集中式的路由分发

二、实验环境

  • 3台阿里云的虚机
  • 配置kubernetes集群,master,node1,node2
  • Calico对应版本3.8
    k8s集群搭建不在赘述,Calico部署请参照官网(https://www.projectcalico.org),并部署calicoctl。

三、Calico的部署方式

  Calico的部署方式有两种,第一种是IP in IP模式,第二种是BGP模式。通过设置calico.yaml(官网下载)中CALICO_IPV4POOL_IPIP的值来实现。
通过实验发现:

  • 阿里云不支持Calico的BGP模式
  • AWS支持Calico的BGP模式,但是要把EC2的联网-更改源/目标,检查关闭

四、Calico IPAM的形式

  • Using host-local IPAM

 将IPAM的type设置为host-local

{
    "name": "any_name",
    "cniVersion": "0.1.0",
    "type": "calico",
"kubernetes": {
        "kubeconfig": "/path/to/kubeconfig",
        "node_name": "node-name-in-k8s
    },
    "ipam": {
        "type": "host-local",
        "ranges": [
            [
                { "subnet": "usePodCidr" }
            ],
            [
                { "subnet": "2001:db8::/96" }
            ]
        ],
        "routes": [
            { "dst": "0.0.0.0/0" },
            { "dst": "2001:db8::/96" }
        ]
    }
}
  • Using Kubernetes annotations

 基于每个命名空间或每个pod指定IP池

cni.projectcalico.org/ipv4pools:
annotations:
    "cni.projectcalico.org/ipv4pools": "[\"default-ipv4-ippool\"]"
cni.projectcalico.org/ipv6pools:
annotations:
    "cni.projectcalico.org/ipv6pools": "[\"2001:db8::1/120\"]"

  请求特定的IP地址

cni.projectcalico.org/ipAddrs:
annotations:
      "cni.projectcalico.org/ipAddrs": "[\"192.168.0.1\"]"
cni.projectcalico.org/ipAddrsNoIpam:
annotations:
      "cni.projectcalico.org/ipAddrsNoIpam": "[\"10.0.0.1\"]"

 申请浮动IP

annotations:
      "cni.projectcalico.org/floatingIPs": "[\"10.0.0.1\"]"
  • Using IP pools node selectors
     使用IP pools的nodeSelector

  • 相关实例介绍

  1. namespace绑定IPPool

(1)创建IPPool

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: external-pool
spec:
  cidr: 172.16.0.0/26
  blockSize: 29
  ipipMode: Always
  natOutgoing: true
---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: internal-pool
spec:
  cidr: 192.169.0.0/24
  blockSize: 29
  ipipMode: Always
  natOutgoing: true
calicoctl apply -f pools.yaml

(2)将IPPool绑定到对应的namespace

kubectl create namespace external-ns
kubectl create namespace internal-ns
kubectl annotate namespace external-ns "cni.projectcalico.org/ipv4pools"=‘[“external-pool"]’
kubectl annotate namespace internal-ns "cni.projectcalico.org/ipv4pools"=‘[“internal-pool"]’

(3)创建namespace下的pod进行验证

kubectl run nginx --image nginx --namespace external-ns --replicas 3
kubectl run nginx --image nginx --namespace internal-ns --replicas 3
  1. node绑定IPPool

(1)删除默认ippool

calicoctl delete ippools default-ipv4-ippool

(2)为node添加label

kubectl label nodes master rack=0
kubectl label nodes node1 rack=0
kubectl label nodes node2 rack=1

(3)创建ippool

calicoctl create -f -<

(4)部署应用并查看服务IP

kubectl run nginx --image nginx --replicas 5
  1. pod 绑定IPPool

(1)创建ippool

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: my.ippool-1
spec:
  cidr: 10.1.0.0/16
  ipipMode: CrossSubnet
  natOutgoing: true
  nodeSelector: all()

(2)在pod的yaml文件中添加ippool

annotations:
    "cni.projectcalico.org/ipv4pools": "[\"your-ippool\"]"

五、BGP相关介绍

BGP协议这里不在说明,感兴趣的可以自己查看。这里介绍一些Calico与BGP相关的知识。
BGPPeer的方式:

  • Node-to-Node mesh:个人理解是每个节点之间都存在路由
  • Route Reflector (路由放射):将Calico的节点设置为路由反射器,减少节点之间的路由。
  • 个人理解设置一个节点作为全局的BGP peer。
  • 这种方式貌似和机架相关。
    上面标红的两种方式没有特别理解,还请了解大佬多多指教,谢谢。

RR模式的实现
(1)配置禁用全局全连接(node-to-node mesh)

$ cat << EOF | calicoctl create -f -
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: false
  asNumber: 64512
EOF

(2)配置BGP node 与 Route Reflector的连接建立规则,通过BGPPeer 资源告诉其他的calico node与反射路由节点建立连接

cat << EOF | calicoctl create -f -
kind: BGPPeer
apiVersion: projectcalico.org/v3
metadata:
  name: peer-to-rrs
spec:
  # 规则1:普通 bgp node 与 rr 建立连接
  nodeSelector: !has(i-am-a-route-reflector)
  peerSelector: has(i-am-a-route-reflector)

(3)配置Route Reflector节点

#(1).先导出 node node1 的配置,准备修改
$ calicoctl get node master -o yaml > rr0.yaml
apiVersion: projectcalico.org/v3
kind: Node
metadata:
  creationTimestamp: null
  name: master
spec:
  bgp:
    ipv4Address: 172.17.201.143/20
    ipv4IPIPTunnelAddr: 10.244.219.64

# (2).修改上述 rr01.yml 的配置如下
apiVersion: projectcalico.org/v3
kind: Node
metadata:
  name: master
  labels:
    # 设置标签
    i-am-a-route-reflector: true
spec:
  bgp:
    ipv4Address: 172.17.201.143/20
    ipv4IPIPTunnelAddr: 10.244.219.64
    # 设置集群ID
    routeReflectorClusterID: 224.0.0.1

# (3).应用修改后的 rr node 配置
$ calicoctl apply -f rr01.yml

(4)对比路由表

六、Network Policy

  Calico与其他虚拟网络的最大不同是引入了Network Policy,Calico的Netork Policy 包括GlobalNetworkPolicy,GlobalNetWorkSet,NetworkPolicy,NetworkSet,HostEndPoint,WorkloadEndPoint等内容,详细信息请参考官方网站。
下面主要介绍一些简单的应用:
首先通过NodePort的方式搭建Webserver服务,通过公网IP加NodePort访问返回webserver信息。

  • 通过GlobalNetworkPolicy限制访问

(1)为node1和node2添加hostendpoint

Node1:
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: node1-eth0
  labels:
    type: host-endpoint
    role: node1-ingress
spec:
  interfaceName: eth0
  node: node1

Node2:
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: node2-eth0
  labels:
    type: host-endpoint
    role: node2-ingress
spec:
  interfaceName: eth0
  node: node2

(2)创建Global network policy

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
 name: drop-ingress
spec:
 order: 20
 preDNAT: true
 applyOnForward: true
 ingress:
 - action: Deny
 selector: role == 'node1-ingress'

(3)通过nodeport访问,可以发现,node1提供的服务无法访问,node2可以访问

  • 通过NetworkPolicy限制访问

(1)设置NetworkPolicy禁止所有访问

Deny.yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: deny-wep-webserver
  namespace: webserver
spec:
  types:
  - Ingress
  ingress:
  - action: Deny

(2)创建NetworkPolicy允许部分网段访问

Allow.yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-nets-wep-webserver
  namespace: webserver
spec:
  types:
  - Ingress
  ingress:
  - action: Allow
    source:
      nets:
      - 10.244.166.0/24
  • 通过使用NetworkSet限制访问

(1)创建NetworkPolicy禁止所有方式访问webserver

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: deny-wep-webserver
  namespace: webserver
spec:
  selector: run == 'webserver'
  types:
  - Ingress
  ingress:
  - action: Deny

(2)创建NetworkSet,在其中加入可以访问webserver的nets范围

apiVersion: projectcalico.org/v3
kind: NetworkSet
metadata:
  name: node1-nts
  namespace: webserver
  labels:
    role: db
spec:
  nets:
  - 10.244.166.0/24

(3)创建NetworkPolicy允许NetworkSet中的网段访问webserver

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: access-wep-webserver
  namespace: webserver
spec:
  selector: run == 'webserver'
  types:
  - Ingress
  ingress:
  - action: Allow
    source:
      selector: role == 'db'

End

以上是近期对Calico的一些总结,只是针对Calico的功能进行了尝试,哪里存在问题还请指正。接下来还要对Calico进行深一步的了解。

你可能感兴趣的:(Calico小结)