calico deep dive

来源:互联网 发布:js获取当前城市名称 编辑:程序博客网 时间:2024/05/21 22:47

1.calico介绍

它在CNM和CNI两大阵营都扮演着比较重要的角色。即有着不俗的性能表现,提供了很好的隔离性,而且还有不错的ACL控制能力。

Calico 是一个三层的数据中心网络方案,而且方便集成 OpenStack 这种 IaaS 云架构,能够提供高效可控的 VM、容器、裸机之间的通信。

通过将整个互联网的可扩展IP网络原则压缩到数据中心级别,Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息向整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。

这样保证最终所有的workload之间的数据流量都是通过IP路由的方式完成互联的。

Calico 节点组网可以直接利用数据中心的网络结构(支持 L2 或者 L3),不需要额外的 NAT、端口映射、隧道或者 VXLAN overlay network,扩展性和性能都很好。与其他容器网络方案相比,Calico 还有一大优势:network policy。用户可以动态定义 ACL 规则,控制进出容器的数据包,实现业务需求。

这里写图片描述

如上图所示,这样保证这个方案的简单可控,而且没有封包解包,节约CPU计算资源的同时,提高了整个网络的性能。

此外,Calico基于iptables还提供了丰富而灵活的网络Policy,保证通过各个节点上的ACLs来提供Workload的多租户隔离、安全组以及其他可达性限制等功能。

1.1 calico架构(BGP模式)

这里写图片描述

结合上面这张图,我们来过一遍Calico的核心组件:

  • Felix(Calico Agent):跑在每台需要运行Workload的节点上的守护进程,主要负责配置路由及ACLs等信息来确保Endpoint的连通状态;根据对接的编排框架的不同,felix主要包含以下功能:
    • 网络接口管理:把接口的一些信息告诉内核,让内核正确的处理这个接口的链路,特殊情况下,会去响应ARP请求,允许ip forwarding等。
    • 路由管理:在节点上把endpoints的路由配置到Linux kernel FIB(forwarding information base), 保障包正确的到达节点的endpoint上,我的理解endpoints是节点上的虚拟网卡
    • ACL管理:准入控制列表,设置内核的ACL,保证只有合法的包才可以在链路上发送,保障安全。
    • 状态报告:把节点的网络状态信息写入etcd。
  • The Orchestrator plugin:通过该插件更好地与编排系统(k8s/mesos/openstack等)进行集成。(The purpose of these plugins is to bind Calico more tightly into the orchestrator, allowing users to manage the Calico network just as they’d manage network tools that were built into the orchestrator.)工作包括:
    • API转化:编排系统 kubernetes openstack等有自己的API,编排插件翻译成calico的数据模型存到calico的数据库中。
    • 信息反馈:把网络状态的一些信息反馈给上层的编排调度系统
  • etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性;用途有:

    • 数据存储
    • 各组件之间通信
  • BGP Client(BIRD):主要负责把Felix写入Kernel的路由信息分发到当前Calico网络,确保Workload间的通信的有效性;

  • BGP Route Reflector(BIRD):大规模部署时使用,摒弃所有节点互联的 mesh 模式(每个BGP客户端之间都会相互连接,会以 N^2次方增长),reflector负责client之间的连接,防止它们需要两两相连。通过一个或者多个BGP Route Reflector来完成集中式的路由分发;为了冗余,可以部署多个reflectors, 它仅仅包含控制面,endpoint之间的数据不经过它们

架构详情请见官网:https://docs.projectcalico.org/v2.6/reference/architecture/

1.2 Calico(BGP)的不足

既然是三层实现,当然不支持VRF
不支持多租户网络的隔离功能,在多租户场景下会有网络安全问题
Calico控制平面的设计要求物理网络得是L2 Fabric,这样vRouter间都是直接可达的

1.3 Calico的IP-in-IP模式

Calico控制平面的设计要求物理网络得是L2 Fabric,这样vRouter间都是直接可达的,路由不需要把物理设备当做下一跳。为了支持L3 Fabric,Calico推出了IPinIP的选项。

1.3.1 ipip模式下连通性验证

在ipip模式创建的ip pool(10.20.0.0/24)里创建子网络,如:

docker network create --driver calico --ipam-driver calico-ipam  --subnet 10.20.0.0/24 net1docker network create --driver calico --ipam-driver calico-ipam  --subnet 10.20.0.0/24 net2docker network create --driver calico --ipam-driver calico-ipam  --subnet 10.20.0.0/24 net3

上面创建了net1,net2和net3三个不同的网络。上面的命令在任意一个节点上执行即可。由于所有节点使用的是同一套etcd,在每个节点上都可以通过docker network ls命令查看到生成的网络信息
参考官网上的一个例子,在node1和node2上分别创建几个容器来测试下容器网络的连通性。

#node1docker run --net net1 --name workload-A -tid busyboxdocker run --net net2 --name workload-B -tid busyboxdocker run --net net1 --name workload-C -tid busybox#node2docker run --net net3 --name workload-D -tid busyboxdocker run --net net1 --name workload-E -tid busybox

可以在node1上使用如下命令来试验连通性:

#同一网络内的容器(即使不在同一节点主机上)可以使用容器名来访问docker exec workload-A ping -c 4 workload-C.net1docker exec workload-A ping -c 4 workload-E.net1#不同网络内的容器需要使用容器ip来访问(使用容器名会报:bad address)docker exec workload-A ping -c 2  `docker inspect --format "{{ .NetworkSettings.Networks.net2.IPAddress }}" workload-B`

同一网络内的容器是能相互通信的;不同网络内的容器相互是不通的。不同节点上属于同一网络的容器也是能相互通信的,这样就实现了容器的跨主机互连。

2.calico部署

前提

根据官方文档(https://docs.projectcalico.org/v2.6/getting-started/kubernetes/installation/),calico部署前,已有的k8s集群需做好以下配置:

  • 1.kubelet需要加如下启动参数
--network-plugin=cni --cni-conf-dir=/etc/cni/net.d           --cni-bin-dir=/opt/cni/bin

备注:后两个参数在启动calico-node pod的install-cni容器的时候也会指定挂载进容器,需要和这里设置的一样。

  • 2.kube-proxy必须采用iptables proxy mode(1.2 以后是默认模式)
--proxy-mode=iptables
  • 3.kubec-proxy 组件不能采用 –masquerade-all 启动,因为会与 Calico policy 冲突

说明

我部署的是calico2.6.2版本,该版本涉及的各组件版本信息请见:https://docs.projectcalico.org/v2.6/releases/#v2.6.2
Calico 依赖 etcd 在不同主机间共享和交换信息,存储 Calico 网络状态。Calico 网络中的每个主机都需要运行 Calico 组件,提供容器 interface 管理、动态路由、动态 ACL、报告状态等功能。

2.1 calicoctl部署

2.1.1 calicoctl安装

到这获取calicoctl并安装:https://github.com/projectcalico/calicoctl/releases/

wget -O /usr/local/bin/calicoctl https://github.com/projectcalico/calicoctl/releases/download/v1.6.1/calicoctlchmod +x calicoctl

2.1.2 calicoctl配置

calicoctl默认是会读取/etc/calico/calicoctl.cfg的配置文件(也可以通过–config选项来指定要读取的配置文件),配置里指定etcd集群的地址,文件的格式类似如下:
vim /etc/calico/calico.cfg

ETCD_ENDPOINTS="https://10.142.21.21:2379,https://10.142.21.22:2379,https://10.142.21.23:2379"ETCD_CA_CERT_FILE="/etc/calico/certs/ca_cert.crt"ETCD_CERT_FILE="/etc/calico/certs/cert.crt"ETCD_KEY_FILE="/etc/calico/certs/key.pem"CALICO_IP="10.142.21.21"CALICO_IP6=""CALICO_NO_DEFAULT_POOLS="true"CALICO_LIBNETWORK_ENABLED="true"CALICO_HOSTNAME="k8smaster01"

2.1.3 常用calicoctl命令

查看ip pool

calicoctl get ipPool

查看节点状态信息

calicoctl node status

创建ipPool

calicoctl apply -f - << EOFapiVersion: v1kind: ipPoolmetadata:  cidr: 10.233.64.0/18spec:  ipip:    enabled: true  nat-outgoing: trueEOF

修改calico网络模式,由BGP改为ipip:

calicoctl apply -f - << EOFapiVersion: v1kind: ipPoolmetadata:  cidr: 10.233.64.0/18spec:  ipip:    enabled: true    mode: always  nat-outgoing: trueEOF

2.2 calico核心组件部署

主要涉及3个组件:calico/node:v2.6.2、calico/cni:v1.11.0、calico/kube-controllers:v1.0.0,使用kubernetes部署,使用的yaml文件请见:https://github.com/projectcalico/calico/blob/v2.6.2/master/getting-started/kubernetes/installation/hosted/calico.yaml
下面以我的实际文件为例进行讲解:

2.2.1 calico-config(configmap)

kind: ConfigMapapiVersion: v1metadata:  name: calico-config  namespace: kube-systemdata:  # Configure this with the location of your etcd cluster.  etcd_endpoints: "https://10.142.21.21:2379"  # Configure the Calico backend to use.  calico_backend: "bird"  # The CNI network configuration to install on each node.  cni_network_config: |-    {        "name": "k8s-pod-network",        "cniVersion": "0.1.0",        "type": "calico",        "etcd_endpoints": "__ETCD_ENDPOINTS__",        "etcd_key_file": "__ETCD_KEY_FILE__",        "etcd_cert_file": "__ETCD_CERT_FILE__",        "etcd_ca_cert_file": "__ETCD_CA_CERT_FILE__",        "log_level": "info",        "mtu": 1500,        "ipam": {            "type": "calico-ipam"        },        "policy": {            "type": "k8s",            "k8s_api_root": "https://__KUBERNETES_SERVICE_HOST__:__KUBERNETES_SERVICE_PORT__",            "k8s_auth_token": "__SERVICEACCOUNT_TOKEN__"        },        "kubernetes": {            "kubeconfig": "__KUBECONFIG_FILEPATH__"        }    }  # If you're using TLS enabled etcd uncomment the following.  # You must also populate the Secret below with these files.  etcd_ca: "/calico-secrets/etcd-ca"  etcd_cert: "/calico-secrets/etcd-cert"  etcd_key: "/calico-secrets/etcd-key"

说明:
1.这个configmap给calico-node配置env使用
2.calico-config的data.etcd_endpoints(endpoints为etcd的真实环境地址)

2.2.2 calico-etcd-secrets(secret)

# The following contains k8s Secrets for use with a TLS enabled etcd cluster.# For information on populating Secrets, see http://kubernetes.io/docs/user-guide/secrets/apiVersion: v1kind: Secrettype: Opaquemetadata:  name: calico-etcd-secrets  namespace: kube-systemdata:  # Populate the following files with etcd TLS configuration if desired, but leave blank if  # not using TLS for etcd.  # This self-hosted install expects three files with the following names.  The values  # should be base64 encoded strings of the entire contents of each file.  etcd-key: 太长了,省略...  etcd-cert: 太长了,省略...  etcd-ca: 太长了,省略...

说明:
1. 这个secret用来给calico-node和kube-controller连接etcd使用
2. calico-etcd-secrets的etcd-key、etcd-cert、etcd-ca,分别使用/etc/ssl/etcd/ssl/目录下的node-k8smaster01-key.pem、node-k8smaster01.pem、ca.pem(根据实际环境的证书数据填写。)的base64编码(生成base64编码:base64 /etc/ssl/etcd/ssl/node-k8smaster01-key.pem)

2.2.3 calico-node(daemonset)

# This manifest installs the calico/node container, as well# as the Calico CNI plugins and network config on# each master and worker node in a Kubernetes cluster.kind: DaemonSetapiVersion: extensions/v1beta1metadata:  name: calico-node  namespace: kube-system  labels:    k8s-app: calico-nodespec:  selector:    matchLabels:      k8s-app: calico-node  template:    metadata:      labels:        k8s-app: calico-node      annotations:        scheduler.alpha.kubernetes.io/critical-pod: ''        /cheduler.alpha.kubernetes.io/tolerations: |          [{"key": "dedicated", "value": "master", "effect": "NoSchedule" },           {"key":"CriticalAddonsOnly", "operator":"Exists"}]    spec:      hostNetwork: true      serviceAccountName: calico-node      # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force      # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods.      terminationGracePeriodSeconds: 0      containers:        # Runs calico/node container on each Kubernetes node.  This        # container programs network policy and routes on each        # host.        - name: calico-node          image: quay.io/calico/node:v2.6.2          env:            # The location of the Calico etcd cluster.            - name: ETCD_ENDPOINTS              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_endpoints            # Choose the backend to use.            - name: CALICO_NETWORKING_BACKEND              valueFrom:                configMapKeyRef:                  name: calico-config                  key: calico_backend            # Cluster type to identify the deployment type            - name: CLUSTER_TYPE              value: "k8s,bgp"            # Disable file logging so `kubectl logs` works.            - name: CALICO_DISABLE_FILE_LOGGING              value: "true"            # Set Felix endpoint to host default action to ACCEPT.            - name: FELIX_DEFAULTENDPOINTTOHOSTACTION              value: "ACCEPT"            # Disable IPv6 on Kubernetes.            - name: FELIX_IPV6SUPPORT              value: "false"            # Set Felix logging to "info"            - name: FELIX_LOGSEVERITYSCREEN              value: "info"            # Set MTU for tunnel device used if ipip is enabled            - name: FELIX_IPINIPMTU              value: "1440"            # Location of the CA certificate for etcd.            - name: ETCD_CA_CERT_FILE              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_ca            # Location of the client key for etcd.            - name: ETCD_KEY_FILE              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_key            # Location of the client certificate for etcd.            - name: ETCD_CERT_FILE              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_cert            # Auto-detect the BGP IP address.            - name: IP              value: ""            - name: FELIX_HEALTHENABLED              value: "true"          securityContext:            privileged: true          resources:            requests:              cpu: 250m          livenessProbe:            httpGet:              path: /liveness              port: 9099            periodSeconds: 10            initialDelaySeconds: 10            failureThreshold: 6          readinessProbe:            httpGet:              path: /readiness              port: 9099            periodSeconds: 10          volumeMounts:            - mountPath: /lib/modules              name: lib-modules              readOnly: true            - mountPath: /var/run/calico              name: var-run-calico              readOnly: false            - mountPath: /calico-secrets              name: etcd-certs        # This container installs the Calico CNI binaries        # and CNI network config file on each node.        - name: install-cni          image: quay.io/calico/cni:v1.11.0          command: ["/install-cni.sh"]          env:            # The location of the Calico etcd cluster.            - name: ETCD_ENDPOINTS              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_endpoints            # The CNI network config to install on each node.            - name: CNI_NETWORK_CONFIG              valueFrom:                configMapKeyRef:                  name: calico-config                  key: cni_network_config          volumeMounts:            - mountPath: /host/opt/cni/bin              name: cni-bin-dir            - mountPath: /host/etc/cni/net.d              name: cni-net-dir            - mountPath: /calico-secrets              name: etcd-certs      volumes:        # Used by calico/node.        - name: lib-modules          hostPath:            path: /lib/modules        - name: var-run-calico          hostPath:            path: /var/run/calico        # Used to install CNI.        - name: cni-bin-dir          hostPath:            path: /opt/cni/bin        - name: cni-net-dir          hostPath:            path: /etc/cni/net.d        # Mount in the etcd TLS secrets.        - name: etcd-certs          secret:            secretName: calico-etcd-secrets

备注:
1.calico-node的CALICO_IPV4POOL_CIDR参数(注:需要根据实际环境更改)
2.每个pod里除pause外有两个容器:calico-node和install-cni,其中calico-node这个容器里起了多个进程,有:calico-felix、bird、bird6、confd(confd根据etcd上状态信息,与本地模板,生成并更新BIRD配置)
3.根据环境里的所有节点的taints,为daemon/calico-node添加tolerations参数,使其能在每个节点上都能部署。例如如下参数:

spec:   tolerations:- key: "nginx-ingress-controller"  operator: "Equal"      value: "true"    effect: "NoSchedule"   hostNetwork: true

这是为了taints的节点能够部署calico-node。其中的key和value为标记的taints。

2.2.4 calico-kube-controllers(deployment)

# This manifest deploys the Calico Kubernetes controllers.# See https://github.com/projectcalico/kube-controllersapiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: calico-kube-controllers  namespace: kube-system  labels:    k8s-app: calico-kube-controllers  annotations:    scheduler.alpha.kubernetes.io/critical-pod: ''    scheduler.alpha.kubernetes.io/tolerations: |      [{"key": "dedicated", "value": "master", "effect": "NoSchedule" },       {"key":"CriticalAddonsOnly", "operator":"Exists"}]spec:  # The controllers can only have a single active instance.  replicas: 1  strategy:    type: Recreate  template:    metadata:      name: calico-kube-controllers      namespace: kube-system      labels:        k8s-app: calico-kube-controllers    spec:      # The controllers must run in the host network namespace so that      # it isn't governed by policy that would prevent it from working.      hostNetwork: true      serviceAccountName: calico-kube-controllers      containers:        - name: calico-kube-controllers          image: quay.io/calico/kube-controllers:v1.0.0          env:            # The location of the Calico etcd cluster.            - name: ETCD_ENDPOINTS              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_endpoints            # Location of the CA certificate for etcd.            - name: ETCD_CA_CERT_FILE              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_ca            # Location of the client key for etcd.            - name: ETCD_KEY_FILE              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_key            # Location of the client certificate for etcd.            - name: ETCD_CERT_FILE              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_cert          volumeMounts:            # Mount in the etcd TLS secrets.            - mountPath: /calico-secrets              name: etcd-certs      volumes:        # Mount in the etcd TLS secrets.        - name: etcd-certs          secret:            secretName: calico-etcd-secrets

2.2.5 calico-policy-controller(deployment)

# This deployment turns off the old "policy-controller". It should remain at 0 replicas, and then# be removed entirely once the new kube-controllers deployment has been deployed above.apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: calico-policy-controller  namespace: kube-system  labels:    k8s-app: calico-policyspec:  # Turn this deployment off in favor of the kube-controllers deployment above.  replicas: 0  strategy:    type: Recreate  template:    metadata:      name: calico-policy-controller      namespace: kube-system      labels:        k8s-app: calico-policy    spec:      hostNetwork: true      serviceAccountName: calico-kube-controllers      containers:        - name: calico-policy-controller          image: quay.io/calico/kube-controllers:v1.0.0          env:            # The location of the Calico etcd cluster.            - name: ETCD_ENDPOINTS              valueFrom:                configMapKeyRef:                  name: calico-config                  key: etcd_endpoints

2.2.6 calico-kube-controllers(serviceaccount)

apiVersion: v1kind: ServiceAccountmetadata:  name: calico-kube-controllers  namespace: kube-system

2.2.7 calico-node(serviceaccount)

apiVersion: v1kind: ServiceAccountmetadata:  name: calico-node  namespace: kube-system

2.3 遇到的坑

3.cni-plugin

1.流量出去的过程

1.IP地址比较

<1>calico模式: calico方案中容器启动后在容器中可以看到内部ip地址是启动kube-proxy时指定的–cluster-cidr=10.233.64.0/18中的一个:
这里写图片描述

<2>docker bridge模式: 单纯使用docker bridge模式起容器的话可以看到内部ip地址是docker0网桥那个网段的内部地址:
这里写图片描述

2.路由比较

<1>calico模式: cni-plugin会在指定的network ns中创建veth pair。位于容器中的veth,将被设置ip,并设置169.254.1.1为默认路由,在容器内可以看到:
这里写图片描述
因为169.254.1.1是无效IP,因此,cni-plugin还要在容器内设置一条静态arp:
这里写图片描述
在主机上查看网络接口,可以找到和上述mac地址一致的一个calixxx接口:
这里写图片描述

由以上可见:169.254.1.1的mac地址被设置为了veth设备在host中的一端veth的mac地址,容器中所有的报文就会发送到主机的veth端。

<2>bridge模式: 同样会创建veth pair。位于容器中的veth,将被设置ip,并设置bridge0网桥172.17.0.1为默认路由,在容器内可以看到:
这里写图片描述
因为172.17.0.1是docker0网桥的有效IP,因此,这里就没有再像calico模式一样设设置一条静态arp了。
在主机上查看网络接口,可以找到对应在主机上的vethxxx接口:
这里写图片描述

整体流量具体怎么走的,请参考(有时间再整理):
http://blog.csdn.net/liukuan73/article/details/78635711
http://blog.csdn.net/liukuan73/article/details/78837424
http://cizixs.com/2017/03/30/kubernetes-introduction-service-and-kube-proxy?utm_source=tuicool&utm_medium=referral
http://www.lijiaocn.com/%E9%A1%B9%E7%9B%AE/2017/03/27/Kubernetes-kube-proxy.html

2.流量进来的过程

cni-plugin创建了endpoint之后,会将其保存到etcd中,felix从而感知到endpoint的变化。之后,felix会在host端设置一条静态arp:
这里写图片描述
这样在host上就可以访问容器的地址。

非k8s

calico-cni-plugin中将k8s场景下的使用和非k8s场景下的使用分离开了。

if orchestrator == "k8s" {    if result, err = k8s.CmdAddK8s(args, conf, nodename, calicoClient, endpoint); err != nil {        return err    }} else {    // Default CNI behavior - use the CNI network name as the Calico profile.    profileID := conf.Name......

非k8s的场景中,github.com/projectcalico/cni-plugin/calico.go:

// There's no existing endpoint, so we need to do the following:// 1) Call the configured IPAM plugin to get IP address(es)// 2) Configure the Calico endpoint// 3) Create the veth, configuring it on both the host and container namespace.

过程很简单,首先查看calico是中是否已经存在了同名的endpoint,如果不存在则创建。

然后在host上创建veth设备,host端命令默认以”caliXX”,容器端命名指定的ifname.

最后更新endpoint的信息,并提交到calico中。

cni-plugin/k8s/k8s.go:

...if _, err := calicoClient.WorkloadEndpoints().Apply(endpoint); err != nil {    // Cleanup IP allocation and return the error.    utils.ReleaseIPAllocation(logger, conf.IPAM.Type, args.StdinData)    return nil, err...

k8s
如果是在k8s下使用,主要是添加对k8s注解的解读,实现指定IP等功能。

github.com/projectcalico/cni-plugin/k8s/k8s.go:

func CmdAddK8s(args *skel.CmdArgs, conf utils.NetConf, nodename string, calicoClient *calicoclient.Client, endpoint *api.WorkloadEndpoint) (*current.Result, error) {    var err error    var result *current.Result    k8sArgs := utils.K8sArgs{}    err = types.LoadArgs(args.Args, &k8sArgs)    ......    ipAddrsNoIpam := annot["cni.projectcalico.org/ipAddrsNoIpam"]    ipAddrs := annot["cni.projectcalico.org/ipAddrs"]    ......

设置endpoint,创建veth的过程与非k8s场景下的使用相同。

BIRD

Bird是一个BGP client,它会主动读取felix在host上设置的路由信息,然后通过BGP协议广播出去。

birdc是bird的client,可以用来查看bird的状态,例如:

查看配置的协议:

$birdcl -s /var/run/calico/bird.ctl show protocolsBIRD 1.5.0 ready.name     proto    table    state  since       infostatic1  Static   master   up     2017-07-25kernel1  Kernel   master   up     2017-07-25device1  Device   master   up     2017-07-25direct1  Direct   master   up     2017-07-25Mesh_10_39_0_105 BGP      master   up     2017-07-25  EstablishedMesh_10_39_0_108 BGP      master   up     05:12:01    EstablishedMesh_10_39_0_109 BGP      master   up     03:24:19    EstablishedMesh_10_39_0_110 BGP      master   up     2017-07-25  EstablishedMesh_10_39_0_112 BGP      master   up     2017-08-01  EstablishedMesh_10_39_0_140 BGP      master   up     2017-08-01  Established

查看所有的路由:

$birdcl -s /var/run/calico/bird.ctl show routeBIRD 1.5.0 ready.0.0.0.0/0          via 10.39.0.1 on eth0 [kernel1 2017-07-25] * (10)192.168.106.64/26  via 10.39.0.108 on eth0 [Mesh_10_39_0_108 05:12:02] * (100/0) [i]192.168.8.19/32    dev calibfe34e88015 [kernel1 2017-08-04] * (10)192.168.70.0/26    via 10.39.0.110 on eth0 [Mesh_10_39_0_110 2017-07-25] * (100/0) [i]192.168.75.192/26  via 10.39.0.140 on eth0 [Mesh_10_39_0_140 2017-08-01] * (100/0) [i]192.168.79.0/26    via 10.39.0.109 on eth0 [Mesh_10_39_0_109 03:28:16] * (100/0) [i]192.168.8.22/32    dev cali68272c96e2e [kernel1 02:52:03] * (10)192.168.8.9/32     dev calia4b4c4fe2bc [kernel1 2017-07-25] * (10)192.168.60.128/26  via 10.39.0.140 on eth0 [Mesh_10_39_0_140 2017-08-01] * (100/0) [i]192.168.8.0/26     blackhole [static1 2017-07-25] * (200)192.168.8.7/32     dev cali4712b101c8e [kernel1 2017-07-26] * (10)10.39.0.0/24       dev eth0 [direct1 2017-07-25] * (240)192.168.8.60/32    dev calife44c1f2fa1 [kernel1 2017-07-25] * (10)192.168.8.61/32    dev cali80bf21ab5d3 [kernel1 2017-08-04] * (10)192.168.8.55/32    dev cali4a97c0ab796 [kernel1 2017-07-25] * (10)192.168.8.42/32    dev cali69de609d5af [kernel1 2017-08-05] * (10)172.17.0.0/16      dev docker0 [direct1 2017-07-25] * (240)192.168.8.32/32    dev cali28e5159257d [kernel1 2017-07-25] * (10)192.168.136.0/26   via 10.39.0.105 on eth0 [Mesh_10_39_0_105 2017-07-25] * (100/0) [i]192.168.141.64/26  via 10.39.0.112 on eth0 [Mesh_10_39_0_112 2017-08-01] * (100/0) [i]192.168.8.36/32    dev cali225764131fc [kernel1 2017-07-25] * (10)

可以到birdc中查看更多的命令。

路由广播

calico-node容器剖析
Felix TODO
BIRD TODO
confd 通过监听etcd修改BGP配置 AS number, logging levels, IPAM信息等
数据流
主要靠三个东西: 让内核响应ARP请求 用route让endpoint(workload)互通 用iptables进行安全隔离

calico/kube-controllers 容器
此容器里包含以下控制器:

policy controller: 监控网络策略 配置calico策略
profile controller: 监控namespaces和配置calico profiles
workloadendpoint controller: 监控pod标签的变化和更新calico workload endpoints
node controller: 监听k8s移除节点,和移除calico相关联的数据
配置calico CNI插件
calico CNI最小化配置:

{
“name”: “any_name”,
“cniVersion”: “0.1.0”,
“type”: “calico”,
“ipam”: {
“type”: “calico-ipam”
}
}
如果calico-node容器自定义了一个NODENAME而不是 node的hostname CNI插件必须配置相同的node name

{
“name”: “any_name”,
“nodename”: “”,
“type”: “calico”,
“ipam”: {
“type”: “calico-ipam”
}
}
其它相关配置: datastore type, Etcd location

logging:

{
“name”: “any_name”,
“cniVersion”: “0.1.0”,
“type”: “calico”,
“log_level”: “DEBUG”,
“ipam”: {
“type”: “calico-ipam”
}
}
IPAM

使用calico IPAM分配ip地址池

{
“name”: “any_name”,
“cniVersion”: “0.1.0”,
“type”: “calico”,
“ipam”: {
“type”: “calico-ipam”,
“assign_ipv4”: “true”,
“assign_ipv6”: “true”,
“ipv4_pools”: [“10.0.0.0/24”, “20.0.0.0/16”],
“ipv6_pools”: [“2001:db8::1/120”]
}
}
kubernetes 配置

calico需要访问kubernets api server,找到pod的标签,所以需要配置apiserver相关信息

{
“name”: “any_name”,
“cniVersion”: “0.1.0”,
“type”: “calico”,
“kubernetes”: {
“kubeconfig”: “/path/to/kubeconfig”
},
“ipam”: {
“type”: “calico-ipam”
}
}
允许kubernetes networkpolicy

设置了这个就必须运行calico/kube-controllers 把 policy,profile,workloadendpoint都设置成允许

{
“name”: “any_name”,
“cniVersion”: “0.1.0”,
“type”: “calico”,
“policy”: {
“type”: “k8s”
},
“kubernetes”: {
“kubeconfig”: “/path/to/kubeconfig”
},
“ipam”: {
“type”: “calico-ipam”
}
}

参考

1.http://lameleg.com/tech/calico-architecture.html
2.http://www.lijiaocn.com/%E9%A1%B9%E7%9B%AE/2017/08/04/calico-arch.html
3.http://blog.csdn.net/felix_yujing/article/details/55213239
4.https://mritd.me/2017/07/31/calico-yml-bug/