首页
k8s安装部署(二)网络插件-Calico vs Kube-OVN

一、 准备工作

在完成基础环境搭建后,需要安装配置好POD使用的网络插件,K8S才能真正使用。

这里介绍两个网络插件的安装使用(Kube-OVN与Calico),安装Kube-OVN时不能有其他网络插件存在。

注:初始化网络插件之前需要设置POD能够被调度到Master节点,否则Master节点会一直处于“Not Ready”状态。

kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-

二、 Calico插件安装

2.1 编辑calico插件的yaml

curl -kLO https://projectcalico.docs.tigera.io/archive/v3.24/manifests/calico.yaml

在 - name: CLUSTER_TYPE 下方添加如下内容

vim calico.yaml
...
			- name: CLUSTER_TYPE
              value: "k8s,bgp"
              # 下方为新增内容
            - name: IP_AUTODETECTION_METHOD
              value: "interface=网卡名称"
...              

修改POD网络,将value值修改为初始化集群时指定的pod-network-cidr。如果是默认的192.168.0.0/16,可以忽略本步骤。

vim calico.yaml
...
            - name: CALICO_IPV4POOL_CIDR
              value: "10.1.0.0/16"
...

2.2 安装calico

kubectl apply -f calico.yaml

2.3 查看POD及节点健康状态

使用如下命令查看POD的健康状态,确保所有POD处于RUNNING状态

kubectl -n kube-system get pods -o wide

使用如下名了查看节点的健康状态,确保节点已经Ready

[root@k8s-55 ~]# kubectl -n kube-system get nodes
NAME     STATUS   ROLES           AGE   VERSION
k8s-50   Ready    control-plane   40m   v1.24.8

2.4 查看网络插件是否正常工作

测试各个节点之间的网络连通性

创建测试POD

cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: overlaytest
spec:
  selector:
      matchLabels:
        name: overlaytest
  template:
    metadata:
      labels:
        name: overlaytest
    spec:
      tolerations:
      - operator: Exists
      containers:
      - image: rancherlabs/swiss-army-knife
        imagePullPolicy: Always
        name: overlaytest
        command: ["sh", "-c", "tail -f /dev/null"]
        terminationMessagePath: /dev/termination-log
EOF

test_pod_connection.sh

#!/bin/bash
echo "=> Start network overlay test"
  kubectl get pods -l name=overlaytest -o jsonpath='{range .items[*]}{@.metadata.name}{" "}{@.spec.nodeName}{"\n"}{end}' |
  while read spod shost
    do kubectl get pods -l name=overlaytest -o jsonpath='{range .items[*]}{@.status.podIP}{" "}{@.spec.nodeName}{"\n"}{end}' |
    while read tip thost
      do kubectl --request-timeout='10s' exec $spod -c overlaytest -- /bin/sh -c "ping -c2 $tip > /dev/null 2>&1"
        RC=$?
        if [ $RC -ne 0 ]
          then echo FAIL: $spod on $shost cannot reach pod IP $tip on $thost
          else echo $shost can reach $thost
        fi
    done
  done
echo "=> End network overlay test"

运行test_pod_connection.sh脚本,即可查看节点之间的网络连通情况。

三、Kube-OVN插件安装

3.1 准备工作

  • Kernel 启动需要开启 ipv6, 如果 kernel 启动参数包含 ipv6.disable=1 需要将其设置为 0。
  • kube-proxy 正常工作,Kube-OVN 可以通过 SVC IP 访问到 kube-apiserver
  • 确认 kubelet 配置参数开启了 CNI,并且配置在标准路径下, kubelet 启动时应包含如下参数 --network-plugin=cni --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d
  • 确认未安装其他网络插件,或者其他网络插件已经被清除,检查 /etc/cni/net.d/ 路径下无其他网络插件配置文件。如果之前安装过其他网络插件,建议删除后重启机器清理残留网络资源。

3.2 一键安装

下载安装脚本

wget https://raw.githubusercontent.com/kubeovn/kube-ovn/release-1.11/dist/images/install.sh

修改配置参数,主要是IFACE参数(该网卡必须配置了IP),其他可以默认

REGISTRY="kubeovn"                     # 镜像仓库地址
VERSION="v1.11.0"                      # 镜像版本/Tag
POD_CIDR="10.16.0.0/16"                # 默认子网 CIDR 不要和 SVC/NODE/JOIN CIDR 重叠
SVC_CIDR="10.96.0.0/12"                # 需要和 apiserver 的 service-cluster-ip-range 保持一致
JOIN_CIDR="100.64.0.0/16"              # Pod 和主机通信网络 CIDR,不要和 SVC/NODE/POD CIDR 重叠 
LABEL="node-role.kubernetes.io/master" # 部署 OVN DB 节点的标签
IFACE="ens192"                               # 容器网络所使用的的宿主机网卡名,如果为空则使用 Kubernetes 中的 Node IP 所在网卡
TUNNEL_TYPE="geneve"                   # 隧道封装协议,可选 geneve, vxlan 或 stt,stt 需要单独编译 ovs 内核模块

执行安装脚本

bash install.sh

注: 部署时可以通过修改脚本中的配置,将默认子网设置为 Underlay 模式,所有未指定子网的 Pod 均会默认运行在 Underlay 网络中。

NETWORK_TYPE          # 设置为 vlan
VLAN_INTERFACE_NAME   # 设置为宿主机上承担容器流量的网卡,例如 eth1
VLAN_ID               # 交换机所接受的 VLAN Tag,若设置为 0 则不做 VLAN 封装
POD_CIDR              # 设置为物理网络 CIDR, 例如 192.168.1.0/24
POD_GATEWAY           # 设置为物理网络网关,例如192.168.1.1
EXCLUDE_IPS           # 排除范围,避免容器网段和物理网络已用 IP 冲突,例如 192.168.1.1..192.168.1.100
EXCHANGE_LINK_NAME    # 是否交换默认 provider-network 下 OVS 网桥和桥接网卡的名字,默认为 false
LS_DNAT_MOD_DL_DST    # DNAT 时是否对 MAC 地址进行转换,可加速 Service 的访问,默认为 true

3.3 动态创建Underlay 网络

通过CRD动态创建Underlay网络,该方式可在安装后动态的创建某个 Underlay 子网供 Pod 使用。需要配置 ProviderNetworkVlanSubnet 三种自定义资源。

3.3.1 创建 ProviderNetwork

ProviderNetwork 提供了主机网卡到物理网络映射的抽象,将同属一个网络的网卡进行统一管理, 并解决在复杂环境下同机器多网卡、网卡名不一致、对应 Underlay 网络不一致等情况下的配置问题。

创建如下 ProviderNetwork 并应用:

cat <<EOF | kubectl create -f - 
apiVersion: kubeovn.io/v1
kind: ProviderNetwork
metadata:
  name: net-vlan
spec:
  defaultInterface: ens224
  customInterfaces:
    - interface: eth2
      nodes:
        - node1
  excludeNodes:
    - node2
EOF

注意:ProviderNetwork 资源名称的长度不得超过 12。

  • defaultInterface: 为默认使用的节点网卡名称。 ProviderNetwork 创建成功后,各节点(除 excludeNodes 外)中会创建名为 br-net1(格式为 br-NAME)的 OVS 网桥,并将指定的节点网卡桥接至此网桥。
  • customInterfaces: 为可选项,可针对特定节点指定需要使用的网卡。
  • excludeNodes: 可选项,用于指定不桥接网卡的节点。该列表中的节点会被添加 net1.provider-network.ovn.kubernetes.io/exclude=true 标签。

其它节点会被添加如下标签:

Key Value 描述
net1.provider-network.ovn.kubernetes.io/ready true 节点中的桥接工作已完成,ProviderNetwork 在节点中可用
net1.provider-network.ovn.kubernetes.io/interface eth1 节点中被桥接的网卡的名称
net1.provider-network.ovn.kubernetes.io/mtu 1500 节点中被桥接的网卡的 MTU

如果节点网卡上已经配置了 IP,则 IP 地址和网卡上的路由会被转移至对应的 OVS 网桥。

3.3.2 创建 VLAN

Vlan 提供了将 Vlan Tag 和 ProviderNetwork 进行绑定的能力。

创建如下 VLAN 并应用:

cat <<EOF | kubectl create -f - 
apiVersion: kubeovn.io/v1
kind: Vlan
metadata:
  name: vlan114
spec:
  id: 114
  provider: net-vlan
EOF
  • id: 为 VLAN ID/Tag,Kube-OVN 会对对该 Vlan 下的流量增加 Vlan 标签,为 0 时不增加任何标签。
  • provider: 为需要使用的 ProviderNetwork 资源的名称。多个 VLAN 可以引用同一个 ProviderNetwork。

3.3.3 创建 Subnet

将 Vlan 和一个子网绑定,如下所示:

cat <<EOF | kubectl create -f - 
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
  name: subnet114
spec:
  protocol: IPv4
  cidrBlock: 192.168.114.0/24
  gateway: 192.168.114.1
  vlan: vlan114
EOF

vlan 的值指定为需要使用的 VLAN 名称即可。多个 Subnet 可以引用同一个 VLAN。

3.3.4 修改子网 CIDR

https://kubeovn.github.io/docs/v1.11.x/ops/change-default-subnet/#cidr

使用 kubectl edit 修改子网 cidrBlockgatewayexcludeIps

kubectl edit subnet test-subnet

3.4 容器创建

可以在创建 Pod 时通过 annotation 来指定 Pod 运行时所需的子网、IP、Mac。

通过ovn.kubernetes.io/logical_switch来指定默认网卡的子网。

当指定了IP时,kube-ovn-controller 运行时将会跳过地址随机分配阶段,经过冲突检测后直接使用指定地址,

cat <<EOF | kubectl create -f - 
apiVersion: v1
kind: Pod
metadata:
  name: use114
  namespace: default
  annotations:
    ovn.kubernetes.io/logical_switch: subnet114
    ovn.kubernetes.io/ip_address: 192.168.114.199
    ovn.kubernetes.io/mac_address: 00:00:00:53:6B:B7
spec:
  containers:
    - name: test
      image: rancherlabs/swiss-army-knife
      command:
        - sleep
        - "infinity"
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
EOF

在使用 annotation 定义单个 Pod IP/Mac 时需要注意以下几点:

  1. 所使用的 IP/Mac 不能和已有的 IP/Mac 冲突。
  2. IP 必须在所属子网的 CIDR 内。
  3. 可以只指定 IP 或 Mac,只指定一个时,另一个会随机分配。

进入容器验证

[root@k8s-50 ~]# kubectl exec -it use114.199 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@use114:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
97: eth0@if98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 00:00:00:53:6b:b7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.114.199/24 brd 192.168.114.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::200:ff:fe53:6bb7/64 scope link
       valid_lft forever preferred_lft forever
root@use114:~#