Kubernetes 网络插件 Calico 完全运维指南

2023年 8月 29日 77.2k 0

概述

Calico 是一种开源网络和网络安全解决方案,适用于容器,虚拟机和基于主机的本机工作负载。Calico 支持广泛的平台,包括 Kubernetes,docker,OpenStack 和裸机服务。Calico 后端支持多种网络模式。

  • BGP 模式:将节点做为虚拟路由器通过 BGP 路由协议来实现集群内容器之间的网络访问。
  • IPIP 模式:在原有 IP 报文中封装一个新的 IP 报文,新的 IP 报文中将源地址 IP 和目的地址 IP 都修改为对端宿主机 IP。
  • cross-subnet:Calico-ipip 模式和 calico-bgp 模式都有对应的局限性,对于一些主机跨子网而又无法使网络设备使用 BGP 的场景可以使用 cross-subnet 模式,实现同子网机器使用 calico-BGP 模式,跨子网机器使用 calico-ipip 模式。

-1

calico 切换 BGP 模式

-1 部署完成后默认使用 calico-ipip 的模式,通过在节点的路由即可得知,通往其他节点路由通过 tunl0 网卡出去 -1 修改为 BGP 网络模式,在 system 项目中修改 calico-node daemonset -1 -1 修改CALICO_IPV4POOL_IPIP改为 off,添加新环境变量FELIX_IPINIPENABLED为 false -1 修改完成后对节点进行重启,等待恢复后查看主机路由,与 ipip 最大区别在于去往其他节点的路由,由 Tunnel0 走向网络网卡。 -1

calico 切换 cross-subnet 模式

Calico-ipip 模式和 calico-bgp 模式都有对应的局限性,对于一些主机跨子网而又无法使网络设备使用 BGP 的场景可以使用 cross-subnet 模式,实现同子网机器使用 calico-BGP 模式,跨子网机器使用 calico-ipip 模式。部署集群网络选择 calico 网络插件 -1 默认部署出来是 calico 的 ip-in-ip 的模式 查看宿主机网卡,会发现多了个 tunl0 网卡,这个是建立 ip 隧道的网卡 -1 去其他主机的路由都是走 tunl0 网卡出去
-1 切换到 cross-subnet 模式

kubectl edit ipPool/default-ipv4-ippool

将 ipipMode 改为 crossSubnet -1 在 UI 将 calico-node 的 POD 删了重建 -1 重启检查 calico 网络 -1 可以看见同子网的主机出口走的是 bgp,不同子网主机走的是 tunl0 网卡走 ipip 模式创建应用测试跨主机网络,在不同主机上互相 ping 测试,看看跨主机网络是否正常。

配置 Route reflector

安装 calicoctl

安装方式有以下几种

  • Single host 上面 binary 安装
  • Single host 上面 continer 安装
  • 作为 k8s pod 运行

实际经验:Binary 方式在集群里面的一台 worker 节点安装(比如 RR),calicoctl 会检测 bird/felix 的运行状态。在非 calico node 节点运行只能使用部分命令,不能运行 calico node 相关命令。通过配置 calicoctl 来对 calico 进行控制,通常情况下建议将

curl -O -L  https://github.com/projectcalico/calicoctl/releases/download/v3.13.3/calicoctl

配置可执行权限

chmod +x calicoctl

复制的/usr/bin/目录

cp calicoctl /usr/bin/

配置 calicoctl 连接 Kubernetes 集群

export CALICO_DATASTORE_TYPE=kubernetes
export CALICO_KUBECONFIG=~/.kube/config
calicoctl node status

-1

calico node-to-node mesh

默认情况下 calico 采用 node-to-node mesh 方式 ,为了防止 BGP 路由环路,BGP 协议规定在一个 AS(自治系统)内部,IBGP 路由器之间只能传一跳路由信息,所以在一个 AS 内部,IBGP 路由器之间为了学习路由信息需要建立全互联的对等体关系,但是当一个 AS 规模很大的时候,这种全互联的对等体关系维护会大量消耗网络和 CPU 资源,所以这种情况下就需要建立路由反射器以减少 IBGP 路由器之间的对等体关系数量。 -1

Route reflector 角色介绍

早期 calico 版本提供专门的 route reflector 镜像,在新版本 calico node 内置集成 route reflector 功能。Route reflector 可以是以下角色:

  • 集群内部的 node 节点
  • 集群外部节点运行 calico node
  • 其他支持 route reflector 的软件或者设备。

这里以一个集群内部的 node 节点为例:

关闭 node-to-node mesh

cat <<EOF | calicoctl apply -f -

apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
 name: default
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: false
  asNumber: 63400
EOF

设置 Route reflector

配置 Route reflector 支持多种配置方式如:1、支持配置全局 BGP peer,。2、支持针对单个节点进行配置 BGP Peer。也可以将 calico 节点充当 Route reflector 这里以配置 calico 节点充当 Router reflector 为例。配置节点充当 BGP Route Reflector可将 Calico 节点配置为充当路由反射器。为此,要用作路由反射器的每个节点必须具有群集 ID-通常是未使用的 IPv4 地址。要将节点配置为集群 ID 为 244.0.0.1 的路由反射器,请运行以下命令。这里将节点名为 rke-node4 的节点配置为 Route Reflector,若一个集群中要配置主备 rr,为了防止 rr 之间的路由环路,需要将集群 ID 配置成一样

calicoctl patch node rke-node4 -p '{"spec": {"bgp": {"routeReflectorClusterID": "244.0.0.1"}}}'

给节点打上对应的 label 标记该节点以表明它是 Route Reflector,从而允许 BGPPeer 资源选择它。

kubectl label node rke-node4 route-reflector=true

创建 BGPPeer

export CALICO_DATASTORE_TYPE=kubernetes
export CALICO_KUBECONFIG=~/.kube/config
cat <<EOF | calicoctl apply -f -
kind: BGPPeer
apiVersion: projectcalico.org/v3
metadata:
  name: peer-with-route-reflectors
spec:
  nodeSelector: all()
  peerSelector: route-reflector == 'true'
EOF

查看 BGP 节点状态

node 上查看,peer type 由 node-to-node mesh 变为 node specific -1 Route Reflector 上节点查看,节点已正常建立连接 -1

设置 veth 网卡 mtu

通常,通过使用最高 MTU 值(不会在路径上引起碎片或丢包)来实现最高性能。对于给定的流量速率,最大带宽增加,CPU 消耗可能下降。对于一些支持 jumbo frames 的网络设备,可以配置 calico 支持使用。下表列举了,常见几种 MTU 配置下 calico 对应的网卡 mtu 的配置 -1 IPIP 和 VXLAN 协议中的 IP 中使用的额外报文头,通过头的大小减小了最小 MTU。(IP 中的 IP 使用 20 字节的标头,而 VXLAN 使用 50 字节的标头)。如果在 Pod 网络中的任何地方使用 VXLAN,请将 MTU 大小配置为“物理网络 MTU 大小减去 50”。如果仅在 IP 中使用 IP,则将 MTU 大小配置为“物理网络 MTU 大小减去 20” 。

将工作负载端点 MTU 和隧道 MTU 设置为相同的值

配置方法:升级集群 -1 配置网卡 MTU,此时通过 system 项目下 calico-config 文件可以看见对应的 mtu 设置 -1 创建 workload 查看 POD 网卡 MTU 为 9001 -1

设置全局 AS 号

默认情况下,除非已为节点指定每个节点的 AS,否则所有 Calico 节点都使用 64512 自治系统。可以通过修改默认的 BGPConfiguration 资源来更改所有节点的全局默认值。以下示例命令将全局默认 AS 编号设置为 64513。

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

设置单个主机和 AS 号

例如,以下命令将名为 node-1 的节点更改为属于 AS 64514。

calicoctl patch node node-1 -p '{"spec": {"bgp": {“asNumber”: “64514”}}}'

修改节点地址范围

此操作建议在部署完集群后立刻进行。默认情况下 calico 在集群层面分配一个 10.42.0.0/16 的 CIDR 网段,在这基础上在单独为每个主机划分一个单独子网采用 26 位子网掩码对应的集群支持的节点数为 2^10=1024 节点,单个子网最大支持 64 个 POD,当单个子网对应 IP 消耗后,calico 会重新在本机上划分一个新的子网如下,在集群对端主机可以看见对应的多个 CIDR 路由信息。 -1 注意:块大小将影响节点 POD 的 IP 地址分配和路由条目数量,如果主机在一个 CIDR 中分配所有地址,则将为其分配一个附加 CIDR。如果没有更多可用的块,则主机可以从分配给其他主机的 CIDR 中获取地址。为借用的地址添加了特定的路由,这会影响路由表的大小。将块大小从默认值增加(例如,使用/24 则为每个块提供 256 个地址)意味着每个主机更少的块,会减少路由。但是对应的集群可容纳主机数也对应减少为 2^8。从默认值减小 CIDR 大小(例如,使用/28 为每个块提供 16 个地址)意味着每个主机有更多 CIDR,因此会有更多路由。calico 允许用户修改对应的 IP 池和集群 CIDR创建和替换步骤注意:删除 Pod 时,应用程序会出现暂时不可用

  • 添加一个新的 IP 池。
  • 注意:新 IP 池必须在同一群集 CIDR 中。
  • 禁用旧的 IP 池(注意:禁用 IP 池只会阻止分配新的 IP 地址。它不会影响现有 POD 的联网)
  • 从旧的 IP 池中删除 Pod。
  • 验证新的 Pod 是否从新的 IP 池中获取地址。
  • 删除旧的 IP 池。

定义 ippool 资源

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: my-ippool
spec:
  blockSize: 24
  cidr: 192.0.0.0/16
  ipipMode: Always
  natOutgoing: true

修改对应的 blockSize 号创建新的

calicoctl apply -f pool.yaml

将旧的 ippool 禁用

calicoctl patch ippool default-ipv4-ippool -p '{"spec": {"disabled": “true”}}'

创建 workload 测试

根据节点标签定义对应的 ippool

Calico 能够进行配置,为不同拓扑指定 IP 地址池。例如可能希望某些机架、地区、或者区域能够从同一个 IP 池中获取地址。这对于降低路由数量或者配合防火墙策略的要求会很有帮助。给节点配置对应 label

kubectl label nodes kube-node-0 rack=0
kubectl label nodes kube-node-1 rack=1

通过标签定义对应的节点 IPpool

calicoctl create -f -<<EOF
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: rack-0-ippool
spec:
  cidr: 192.168.0.0/24
  ipipMode: Always
  natOutgoing: true
  nodeSelector: rack == "0"
EOF
calicoctl create -f -<<EOF
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: rack-1-ippool
spec:
  cidr: 192.168.1.0/24
  ipipMode: Always
  natOutgoing: true
  nodeSelector: rack == "1"
EOF

关闭 SNAT

默认情况下,calico 访问集群外网络是通过 SNAT 成宿主机 ip 方式,在一些金融客户环境中为了能实现防火墙规则,需要直接针对 POD ip 进行进行规则配置,所以需要关闭 natOutgoing

kubectl edit ippool/default-ipv4-ippool

将 natOutgoing: true修改为natOutgoing: false此时,calico 网络访问集群外的 ip 源 ip 就不会 snat 成 宿主机的 ip 地址。

固定 POD IP

固定单个 ip

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1 # tells deployment to run 1 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
      annotations:
        "cni.projectcalico.org/ipAddrs": "[\"10.42.210.135\"]"
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

固定多个 ip,只能通过 ippool 的方式

cat ippool1.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: pool-1
spec:
  blockSize: 31
  cidr: 10.21.0.0/31
  ipipMode: Never
  natOutgoing: true
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1 # tells deployment to run 1 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
      annotations:
        "cni.projectcalico.org/ipv4pools": "[\"pool-1\"]"
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

相关文章

KubeSphere 部署向量数据库 Milvus 实战指南
探索 Kubernetes 持久化存储之 Longhorn 初窥门径
征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
那些年在 Terraform 上吃到的糖和踩过的坑
无需 Kubernetes 测试 Kubernetes 网络实现
Kubernetes v1.31 中的移除和主要变更

发布评论