k3s运行openwrt

openwrt运行在容器中,可能本来就是伪需求。但当用k8s管理所有应用时,可能就是想让它跑在集群里,而不是物理机或虚拟机。

这里使用k3s运行openwrt,仅用最基本的openwrt镜像openwrtorg/rootfs:x86-64。本文不考虑openwrt的可维护性,仅考虑运行和连通。

步骤和方法:

  1. 使k3s集群支持macvlan
  • 物理机加载macvlan mod
  • 物理网卡开启混杂promisc
  • 采用multus-cni使k8s集群支持macvlan
  • 使k3s支持multus-cni(k8s,或k3s单独安装CNI可无视这里)
  1. 使openwrt部署使用macvlan的网卡

物理机

参考:macvlan 一种虚拟网卡解决方案

# 物理机加载macvlan mod
modprobe macvlan
lsmod | grep macvlan

# 物理网卡开启混杂promisc
ip link set enp3s0 promisc on

k3s

从GitHub Issues看,k3s和multus-cni都没考虑去做互相的兼容,只能通过手工修改配置解决。

1、修改multus-cni的部署multus-daemonset-thick.yml,配置挂载的cni和cnibin的位置为k3s的路径,参考(旧版本)

      volumes:
        - name: cni
          hostPath:
            path: /var/lib/rancher/k3s/agent/etc/cni/net.d # 原本:/etc/cni/net.d
        - name: cnibin
          hostPath:
            path: /var/lib/rancher/k3s/data/current/bin # 原本:/opt/cni/bin
...
data:
  daemon-config.json: |
    {
        ...
        "binDir": "/var/lib/rancher/k3s/data/current/bin", # 原本:/opt/cni/bin
        ...
    }

2、将CNI network plugins里的macvlan拷贝至k3s的cnibin文件夹内

# 成功
cp macvlan /var/lib/rancher/k3s/data/current/bin
chmod +x /var/lib/rancher/k3s/data/current/bin/macvlan

# 失败,这里尝试过直接使用k3s内置的cni,但不成功
ln -s cni macvlan

multus-cni

到这里就可以正常使用multus-cni了,主要参考Multus CNI Quickstart Guide

1、部署multus-cni

# 如果是k3s,按上文修改后再apply
kubectl apply -f multus-daemonset-thick.yml

2、NetworkAttachmentDefinition

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: macvlan-conf
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "macvlan",
      "master": "enp3s0",
      "mode": "bridge",
      "ipam": {
        "type": "host-local",
        "subnet": "192.168.0.0/24",
        "rangeStart": "192.168.0.200",
        "rangeEnd": "192.168.0.216",
        "routes": [
          { "dst": "0.0.0.0/0" }
        ],
        "gateway": "192.168.0.1"
      }
    }

3、部署openwrt

kind: Deployment
apiVersion: apps/v1
metadata:
  name: openwrt
  namespace: default
  labels:
    k8s-app: openwrt
spec:
  selector:
    matchLabels:
      k8s-app: openwrt
  template:
    metadata:
      name: openwrt
      labels:
        k8s-app: openwrt
      annotations:
        k8s.v1.cni.cncf.io/networks: macvlan-conf # 主要是这个注解,multus-cni会识别到,并按conf配置给pod分配网卡
    spec:
      containers:
        - name: openwrt
          image: openwrtorg/rootfs:x86-64
          securityContext:
            privileged: false

运行后的结果,pod中:

  annotations:
    k8s.v1.cni.cncf.io/network-status: |-
      [{
          "name": "cbr0",
          "interface": "eth0",
          "ips": [
              "10.42.0.240"
          ],
          "mac": "16:ed:d9:da:82:15",
          "default": true,
          "dns": {},
          "gateway": [
              "10.42.0.1"
          ]
      },{
          "name": "default/macvlan-conf",
          "interface": "net1",
          "ips": [
              "192.168.0.206"
          ],
          "mac": "be:48:29:0f:3a:bc",
          "dns": {},
          "gateway": [
              "\u003cnil\u003e"
          ]
      }]
    k8s.v1.cni.cncf.io/networks: macvlan-conf

可以看到分配了ip192.168.0.206,ssh进去看下。

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
2: eth0@if111: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP
    link/ether 16:ed:d9:da:82:15 brd ff:ff:ff:ff:ff:ff
    inet 10.42.0.240/24 brd 10.42.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::14ed:d9ff:feda:8215/64 scope link
       valid_lft forever preferred_lft forever
3: net1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether be:48:29:0f:3a:bc brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.206/24 brd 192.168.0.255 scope global net1
       valid_lft forever preferred_lft forever
    inet6 fe80::bc48:29ff:fe0f:3abc/64 scope link
       valid_lft forever preferred_lft forever

openwrt

这里已经可以ssh了,但是没有webui,可以ssh进去安装下。

opkg install luci
/etc/init.d/uhttpd enable
/etc/init.d/uhttpd start

注意!这样安装的软件包和配置并未持久化,pod重建会重置。本文不考虑openwrt的可维护性,仅考虑运行和连通。

后续

这里openwrt仅运行和连通,后续需要考虑:

  1. macvlan分配的网卡持久化(mac地址、ip地址)
  2. 软件包和配置的持久化
  3. openwrt修改网卡(k8s的Security Context配置:privileged和capabilities)

参考