• 042.Kubernetes集群网络-flannel及calico


    一 Flannel组件

    1.1 flannel介绍

    Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平网络空间中。若需要实现这个网络假设,需要实现不同节点上的Docker容器之间的互相访问,然后运行Kubernetes。目前已经有多个开源组件支持容器网络模型。如Flannel、Open vSwitch、直接路由和Calico。
    Flannel之所以可以搭建Kubernetes依赖的底层网络,是因为它能实现以下两点。
    1. 它能协助Kubernetes,给每一个Node上的Docker容器都分配互相不冲突的IP地址。
    2. 它能在这些IP地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内。
    flannel架构图:
    clipboard
    如上图所示,Flannel首先创建了一个名为flannel0的网桥,而且这个网桥的一端连接docker0网桥,另一端连接一个叫作flanneld的服务进程。flanneld进程上连etcd,利用etcd来管理可分配的IP地址段资源,同时监控etcd中每个Pod的实际地址,并在内存中建立了一个Pod节点路由表;flanneld进程下连docker0和物理网络,使用内存中的Pod节点路由表,将docker0发给它的数据包包装起来,利用物理网络的连接将数据包投递到目标flanneld上,从而完成Pod到Pod之间的直接地址通信。
    Flannel之间的底层通信协议的可选技术包括UDP、VxLan、AWS VPC等多种方式。通过源flanneld封包、目标flanneld解包,最终docker0收到的就是原始的数据,对容器应用来说是透明的,感觉不到中间Flannel的存在。
    Flannel每次分配的地址段都在同一个公共区域获取,从而实现不同Node上的Pod分配的IP不产生冲突。而且在Flannel分配好地址段后,其余操作由Docker完成的,Flannel通过修改Docker的启动参数将分配给它的地址段传递进去:
    --bip=172.17.18.1/24
    通过如上方式,Flannel就控制了每个Node上的docker0地址段的地址,从而保障了所有Pod的IP地址在同一个水平网络中且不产生冲突。Flannel完美地实现了对Kubernetes网络的支持,但是它引入了多个网络组件,在网络通信时需要转到flannel0网络接口,再转到用户态的flanneld程序,到对端后还需要走这个过程的反过程,所以也会引入一些网络的时延损耗。另外,Flannel模型默认采用了UDP作为底层传输协议,UDP本身是非可靠协议,虽然两端的TCP实现了可靠传输,但在大流量、高并发的应用场景下还建议多次测试。

    提示:更多flannel实现和部署参考:《008.Docker Flannel+Etcd分布式网络部署》。

    二 Calico组件

    2.1 calco组件简介

    Calico是一个基于BGP的纯三层的网络方案,与OpenStack、Kubernetes、AWS、GCE等云平台都能够良好地集成。Calico在每个计算节点都利用Linux Kernel实现了一个高效的vRouter来负责数据转发。每个vRouter都通过BGP1协议把在本节点上运行的容器的路由信息向整个Calico网络广播,并自动设置到达其他节点的路由转发规则。
    Calico保证所有容器之间的数据流量都是通过IP路由的方式完成互联互通的。Calico节点组网时可以直接利用数据中心的网络结构(L2或者L3),不需要额外的NAT、隧道或者Overlay Network,没有额外的封包解包,能够节约CPU运算,提高网络效率。
    clipboard
    Calico在小规模集群中可以直接互联,在大规模集群中可以通过额外的BGP route reflector来完成。Calico基于iptables还提供了丰富的网络策略,实现了Kubernetes的Network Policy策略,提供容器间网络可达性限制的功能。

    2.2 Calico架构

    clipboard
    Calico的主要组件:
    Felix:Calico Agent,运行在每个Node上,负责为容器设置网络资源(IP地址、路由规则、iptables规则等),保证跨主机容器网络互通。
    etcd:Calico使用的后端存储。
    BGP Client:负责把Felix在各Node上设置的路由信息通过BGP协议广播到Calico网络。
    Route Reflector:通过一个或者多个BGP Route Reflector来完成大规模集群的分级路由分发。
    CalicoCtl:Calico命令行管理工具。

    2.3 Calico步骤过程

    在Kubernetes中部署Calico的主要步骤如下:
    1. 修改Kubernetes服务的启动参数,并重启服务。
      1. 设置Master上kube-apiserver服务的启动参数:--allow-privileged=true(因为calico-node需要以特权模式运行在各Node上)。
      2. 设置各Node上kubelet服务的启动参数:--networkplugin=cni(使用CNI网络插件)。
    1. 创建Calico服务,主要包括calico-node和calico policy controller。需要创建的资源对象如下:
      1. 创建ConfigMap calico-config,包含Calico所需的配置参数。
      2. 创建Secret calico-etcd-secrets,用于使用TLS方式连接etcd。
      3. 在每个Node上都运行calico/node容器,部署为DaemonSet。
      4. 在每个Node上都安装Calico CNI二进制文件和网络配置参数(由install-cni容器完成)。
      5. 部署一个名为calico/kube-policy-controller的Deployment,以对接Kubernetes集群中为Pod设置的Network Policy。

    2.4 正式部署

    [root@k8smaster01 ~]# curl
    https://docs.projectcalico.org/v3.6/getting-started/kubernetes/installation/hosted/canal/canal.yaml
    -O
    [root@k8smaster01 ~]# POD_CIDR="<your-pod-cidr>"
    sed -i -e "s?10.10.0.0/16?$POD_CIDR?g" canal.yaml
    如上yaml文件包括Calico所需全部配置,如下为重点部分分段解析:
    • ConfigMap解析
      1 kind: ConfigMap
      2 apiVersion: v1
      3 metadata:
      4   name: calico-config
      5   namespace: kube-system
      6 data:
      7   typha_service_name: "none"
      8   calico_backend: "bird"
      9   veth_mtu: "1440"
     10   cni_network_config: |-
     11     {
     12       "name": "k8s-pod-network",
     13       "cniVersion": "0.3.0",
     14       "plugins": [
     15         {
     16           "type": "calico",
     17           "log_level": "info",
     18           "datastore_type": "kubernetes",
     19           "nodename": "__KUBERNETES_NODE_NAME__",
     20           "mtu": __CNI_MTU__,
     21           "ipam": {
     22               "type": "calico-ipam"
     23           },
     24           "policy": {
     25               "type": "k8s"
     26           },
     27           "kubernetes": {
     28               "kubeconfig": "__KUBECONFIG_FILEPATH__"
     29           }
     30         },
     31         {
     32           "type": "portmap",
     33           "snat": true,
     34           "capabilities": {"portMappings": true}
     35         }
     36       ]
     37     }
    对主要参数说明如下。
    etcd_endpoints:Calico使用etcd来保存网络拓扑和状态,该参数指定etcd服务的地址,可手动设置。
    calico_backend:Calico的后端,默认为bird。
    cni_network_config:符合CNI规范的网络配置。其中type=calico表示kubelet将从/opt/cni/bin目录下搜索名为calico的可执行文件,并调用它来完成容器网络的设置。ipam中的type=calico-ipam表示kubelet将在/opt/cni/bin目录下搜索名为calico-ipam的可执行文件,用于完成容器IP地址的分配。
    提示:如果etcd服务配置了TLS安全认证,则还需指定相应的ca、cert、key等文件。
    • Secret解析
      1 apiVersion: v1
      2 kind: Secret
      3 type: Opaque
      4 metadata:
      5   name: calico-etcd-secrets
      6   namespace: kube-system
      7 data:
      8   # Populate the following with etcd TLS configuration if desired, but leave blank if
      9   # not using TLS for etcd.
     10   # The keys below should be uncommented and the values populated with the base64
     11   # encoded contents of each file that would be associated with the TLS data.
     12   # Example command for encoding a file contents: cat <file> | base64 -w 0
     13   # 如果配置了TLS ,则需要设置相应的证书和密钥文件路径
     14   # etcd-key: null
     15   # etcd-cert: null
     16   # etcd-ca: null
    • DaemonSet解析
      1 kind: DaemonSet
      2 apiVersion: extensions/v1beta1
      3 metadata:
      4   name: calico-node
      5   namespace: kube-system
      6   labels:
      7     k8s-app: calico-node
      8 spec:
      9   selector:
     10     matchLabels:
     11       k8s-app: calico-node
     12   updateStrategy:
     13     type: RollingUpdate
     14     rollingUpdate:
     15       maxUnavailable: 1
     16   template:
     17     metadata:
     18       labels:
     19         k8s-app: calico-node
     20       annotations:
     21         scheduler.alpha.kubernetes.io/critical-pod: ''
     22     spec:
     23       nodeSelector:
     24         beta.kubernetes.io/os: linux
     25       hostNetwork: true
     26       tolerations:
     27         - effect: NoSchedule
     28           operator: Exists
     29         - key: CriticalAddonsOnly
     30           operator: Exists
     31         - effect: NoExecute
     32           operator: Exists
     33       serviceAccountName: calico-node
     34       terminationGracePeriodSeconds: 0
     35       initContainers:
     36         - name: upgrade-ipam
     37           image: calico/cni:v3.6.0
     38           command: ["/opt/cni/bin/calico-ipam", "-upgrade"]
     39           env:
     40             - name: KUBERNETES_NODE_NAME
     41               valueFrom:
     42                 fieldRef:
     43                   fieldPath: spec.nodeName
     44             - name: CALICO_NETWORKING_BACKEND
     45               valueFrom:
     46                 configMapKeyRef:
     47                   name: calico-config
     48                   key: calico_backend
     49           volumeMounts:
     50             - mountPath: /var/lib/cni/networks
     51               name: host-local-net-dir
     52             - mountPath: /host/opt/cni/bin
     53               name: cni-bin-dir
     54         - name: install-cni
     55           image: calico/cni:v3.6.0
     56           command: ["/install-cni.sh"]
     57           env:
     58             - name: CNI_CONF_NAME
     59               value: "10-calico.conflist"
     60             - name: CNI_NETWORK_CONFIG
     61               valueFrom:
     62                 configMapKeyRef:
     63                   name: calico-config
     64                   key: cni_network_config
     65             - name: KUBERNETES_NODE_NAME
     66               valueFrom:
     67                 fieldRef:
     68                   fieldPath: spec.nodeName
     69             - name: CNI_MTU
     70               valueFrom:
     71                 configMapKeyRef:
     72                   name: calico-config
     73                   key: veth_mtu
     74             - name: SLEEP
     75               value: "false"
     76           volumeMounts:
     77             - mountPath: /host/opt/cni/bin
     78               name: cni-bin-dir
     79             - mountPath: /host/etc/cni/net.d
     80               name: cni-net-dir
     81       containers:
     82         - name: calico-node
     83           image: calico/node:v3.6.0
     84           env:
     85             - name: DATASTORE_TYPE
     86               value: "kubernetes"
     87             - name: WAIT_FOR_DATASTORE
     88               value: "true"
     89             - name: NODENAME
     90               valueFrom:
     91                 fieldRef:
     92                   fieldPath: spec.nodeName
     93             - name: CALICO_NETWORKING_BACKEND
     94               valueFrom:
     95                 configMapKeyRef:
     96                   name: calico-config
     97                   key: calico_backend
     98             - name: CLUSTER_TYPE
     99               value: "k8s,bgp"
    100             - name: IP
    101               value: "autodetect"
    102             - name: IP_AUTODETECTION_METHOD
    103               value: "can-reach=172.24.8.2"
    104             - name: CALICO_IPV4POOL_IPIP
    105               value: "Always"
    106             - name: FELIX_IPINIPMTU
    107               valueFrom:
    108                 configMapKeyRef:
    109                   name: calico-config
    110                   key: veth_mtu
    111             - name: CALICO_IPV4POOL_CIDR
    112               value: "10.10.0.0/16"
    113             - name: CALICO_DISABLE_FILE_LOGGING
    114               value: "true"
    115             - name: FELIX_DEFAULTENDPOINTTOHOSTACTION
    116               value: "ACCEPT"
    117             - name: FELIX_IPV6SUPPORT
    118               value: "false"
    119             - name: FELIX_LOGSEVERITYSCREEN
    120               value: "info"
    121             - name: FELIX_HEALTHENABLED
    122               value: "true"
    123           securityContext:
    124             privileged: true
    125           resources:
    126             requests:
    127               cpu: 250m
    128           livenessProbe:
    129             httpGet:
    130               path: /liveness
    131               port: 9099
    132               host: localhost
    133             periodSeconds: 10
    134             initialDelaySeconds: 10
    135             failureThreshold: 6
    136           readinessProbe:
    137             exec:
    138               command:
    139               - /bin/calico-node
    140               - -bird-ready
    141               - -felix-ready
    142             periodSeconds: 10
    143           volumeMounts:
    144             - mountPath: /lib/modules
    145               name: lib-modules
    146               readOnly: true
    147             - mountPath: /run/xtables.lock
    148               name: xtables-lock
    149               readOnly: false
    150             - mountPath: /var/run/calico
    151               name: var-run-calico
    152               readOnly: false
    153             - mountPath: /var/lib/calico
    154               name: var-lib-calico
    155               readOnly: false
    156       volumes:
    157         - name: lib-modules
    158           hostPath:
    159             path: /lib/modules
    160         - name: var-run-calico
    161           hostPath:
    162             path: /var/run/calico
    163         - name: var-lib-calico
    164           hostPath:
    165             path: /var/lib/calico
    166         - name: xtables-lock
    167           hostPath:
    168             path: /run/xtables.lock
    169             type: FileOrCreate
    170         - name: cni-bin-dir
    171           hostPath:
    172             path: /opt/cni/bin
    173         - name: cni-net-dir
    174           hostPath:
    175             path: /etc/cni/net.d
    176         - name: host-local-net-dir
    177           hostPath:
    178             path: /var/lib/cni/networks
    在该Pod中包括如下两个容器:
    • install-cni:在Node上安装CNI二进制文件到/opt/cni/bin目录下,并安装相应的网络配置文件到/etc/cni/net.d目录下,设置为initContainers并在运行完成后退出。
    • calico-node:Calico服务程序,用于设置Pod的网络资源,保证Pod的网络与各Node互联互通。它还需要以hostNetwork模式运行,直接使用宿主机网络。
    calico-node服务的主要参数如下。
    • CALICO_IPV4POOL_CIDR:Calico IPAM的IP地址池,Pod的IP地址将从该池中进行分配。
    • CALICO_IPV4POOL_IPIP:是否启用IPIP模式。启用IPIP模式时,Calico将在Node上创建一个名为tunl0的虚拟隧道。
    • IP_AUTODETECTION_METHOD:获取Node IP地址的方式,默认使用第1个网络接口的IP地址,对于安装了多块网卡的Node,可以使用正则表达式选择正确的网卡,例如"interface=eth.*"表示选择名称以eth开头的网卡的IP地址。
    • FELIX_IPV6SUPPORT:是否启用IPv6。
    • FELIX_LOGSEVERITYSCREEN:日志级别。
    • securityContext.privileged=true:以特权模式运行。
    另外,如果启用RBAC权限控制,则可以设置ServiceAccount。
    IP Pool可以使用两种模式:BGP或IPIP。使用IPIP模式时,设置CALICO_IPV4POOL_IPIP="always",不使用IPIP模式时,设置CALICO_IPV4POOL_IPIP="off",此时将使用BGP模式。
    • calico-kube-controllers解析
    calico-kube-controllers容器,用于对接Kubernetes集群中为Pod设置的Network Policy
      1 apiVersion: extensions/v1beta1
      2 kind: Deployment
      3 metadata:
      4   name: calico-kube-controllers
      5   namespace: kube-system
      6   labels:
      7     k8s-app: calico-kube-controllers
      8   annotations:
      9     scheduler.alpha.kubernetes.io/critical-pod: ''
     10 spec:
     11   replicas: 1
     12   strategy:
     13     type: Recreate
     14   template:
     15     metadata:
     16       name: calico-kube-controllers
     17       namespace: kube-system
     18       labels:
     19         k8s-app: calico-kube-controllers
     20     spec:
     21       nodeSelector:
     22         beta.kubernetes.io/os: linux
     23       tolerations:
     24         - key: CriticalAddonsOnly
     25           operator: Exists
     26         - key: node-role.kubernetes.io/master
     27           effect: NoSchedule
     28       serviceAccountName: calico-kube-controllers
     29       containers:
     30         - name: calico-kube-controllers
     31           image: calico/kube-controllers:v3.6.0
     32           env:
     33             - name: ENABLED_CONTROLLERS
     34               value: node
     35             - name: DATASTORE_TYPE
     36               value: kubernetes
     37           readinessProbe:
     38             exec:
     39               command:
     40               - /usr/bin/check-status
     41               - -r
    如果启用RBAC权限控制,则可以设置ServiceAccount。用户在Kubernetes集群中设置了Pod的Network Policy之后,calicokube-controllers就会自动通知各Node上的calico-node服务,在宿主机上设置相应的iptables规则,完成Pod间网络访问策略的设置。
    [root@k8smaster01 ~]# docker pull calico/cni:v3.9.0
    [root@k8smaster01 ~]# docker pull calico/node:v3.9.0
    [root@k8smaster01 ~]# docker pull calico/kube-controllers:v3.9.0 #建议提前pull镜像
    [root@k8smaster01 ~]# kubectl apply -f calico.yaml
    clipboard

    2.5 查看验证

    [root@k8smaster01 ~]# kubectl get pods --all-namespaces -o wide #查看部署
    clipboard
    [root@k8smaster01 ~]# ll /etc/cni/net.d/
    calico-node在正常运行之后,会根据CNI规范,在/etc/cni/net.d/目录下生成如下文件和目录,并在/opt/cni/bin/目录下安装二进制文件calico和calico-ipam,供kubelet调用。
    • 10-calico.conf:符合CNI规范的网络配置,其中type=calico表示该插件的二进制文件名为calico。
    • calico-kubeconfig:Calico所需的kubeconfig文件。
    • calico-tls目录:以TLS方式连接etcd的相关文件。
    [root@k8smaster01 ~]# ifconfig tunl0
    tunl0: flags=193<UP,RUNNING,NOARP> mtu 1440
    inet 10.10.190.128 netmask 255.255.255.255
    tunnel txqueuelen 1000 (IPIP Tunnel)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
    查看服务器的网络接口设置,会生产名为tunl0的接口,网络地址为10.10.190.128/32,此IP从calico-node设置的IP地址池(CALICO_IPV4POOL_CIDR="10.10.0.0/16")中进行分配的。同时,docker0对于Kubernetes设置Pod的IP地址将不再起作用。
    [root@k8smaster01 ~]# ip route #查看路由表
    clipboard
    如上可查看到不同节点的相应路由,从而通过Calico就完成了Node间容器网络的设置。在后续的Pod创建过程中,kubelet将通过CNI接口调用Calico进行Pod网络的设置,包括IP地址、路由规则、iptables规则等。
    如果设置CALICO_IPV4POOL_IPIP="off",即不使用IPIP模式,则Calico将不会创建tunl0网络接口,路由规则直接使用物理机网卡作为路
    由器进行转发。

    2.6 运行测试

    [root@k8smaster01 ~]# kubectl run nginx --replicas=2 --labels="run=load-balancer-example" --image=nginx --port=80
    [root@k8smaster01 ~]# kubectl expose deployment nginx --type=NodePort --name=example-service #暴露端口
    [root@k8smaster01 ~]# kubectl get service #查看服务状态
    [root@k8smaster01 ~]# kubectl describe service example-service #查看信息
    clipboard
    [root@k8smaster01 ~]# curl 10.97.91.153:80
    clipboard
    [root@k8smaster01 ~]# kubectl get pod -o wide #查看endpoint
    clipboard
    [root@k8smaster01 ~]# curl 10.10.32.129:80 #访问endpoint,与访问服务ip结果相同
    [root@k8smaster01 ~]# curl 10.10.154.1:80

    部署参考文档:https://docs.projectcalico.org/v3.6/getting-started/kubernetes/installation/flannel
    https://github.com/projectcalico/calico/blob/master/v3.8/getting-started/kubernetes/installation/hosted/calico.yaml
  • 相关阅读:
    网络协议
    工具
    GPG 导入导出 Key
    文件系统 相关
    内核常见结构体定义的位置
    sysctl 命令
    git 使用技巧
    busybox 对suid的支持
    vue开发中遇到的一些问题
    http环境下解决navigator.getUserMedia` undefined 的问题
  • 原文地址:https://www.cnblogs.com/itzgr/p/12558767.html
Copyright © 2020-2023  润新知