目录

基于k3s+wireguard+kilo构建跨网的k3s集群

之前活动期间购买过多台服务器,但是通过不同账号享受的首单优惠,不在一个网络内,无法通过内网进行连接,之前通过tailscale进行跨网部署,但是后期问题较多,所以重新更换了方案。了解到kilo是基于WireGuard构建的多云网络覆盖,并且专为Kubernetes设计,所以切换到了kilo。 由于服务器的性能,所以采用了k3s作为k8s的实现,kilo作为跨网的网络覆盖。

前提

多台服务器

腾讯云: tx1-master, tx2-agent1, tx3-agent2(不在同一网络)
这是之前购买的三台服务器,但是都是通过不同账号购买,无法通过内网连接,只能通过公网ip进行连接

kilo可以创建多个location,但是每个location必须确保拥有一个公网ip,所以我们需要在每台服务器上安装wireguard,然后将每台服务器的公网ip添加到kilo的location中。

系统

tx1tx2使用的centostx3使用的是debian11,正常来说可以安装wireguard和k3s即可

网络端口

由于跨网络,我们需要提前开放一些端口,需要在相关云主机的控制台里进行配置。

协议 端口 来源 说明
TCP 6443 k3s-agent Kubernetes API Server,master节点需要对agent节点开放6443端口,否则节点无法注册到集群中
UDP 51820 k3s-server和agent节点 kilo网络通信端口,集群内部跨主机网络传输会通过kilo
TCP 10250 k3s-server和k3s-agent Kubelet metrics
TCP 2379-2380 k3s-server和k3s-agent 仅对于具有嵌入式 etcd 的 HA 需要

启用ipv4转发

/etc/sysctl.conf中变更net.ipv4.ip_forward的值为1,然后执行sysctl -p使其生效

安装

安装wireguard

具体可以参考wireguard官方网站的安装手册。安装完成之后,输入wg命令,如果没有报错,说明安装成功。

master节点

安装k3s

curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | \
INSTALL_K3S_VERSION=v1.26.5+k3s1 \
INSTALL_K3S_MIRROR=cn \
K3S_CLUSTER_INIT=true \
INSTALL_K3S_EXEC="--tls-san $server_public_ip --node-external-ip $server_public_ip --flannel-backend none --kube-proxy-arg metrics-bind-address=0.0.0.0 --kube-apiserver-arg feature-gates=EphemeralContainers=true" \
sh -s -

$server_public_ip替换为master节点的公网ip,执行上述命令,即可完成master节点的安装。
简要说明:

  • K3S_CLUSTER_INIT=true: 集群模式,会安装内置的 etcd,而不是 sqlite3;
  • --tls-san $server_public_ip: $server_public_ip改为你自己指定的 k3s server 公网 IP,–tls-san会在TLS 证书上添加其他主机名或 IPv4/IPv6 地址作为使用者备用名称
  • --node-external-ip server_public_ip:指定node的公网IP
  • --flannel-backend none: 不使用flannel作为网络插件,因为我们使用kilo作为网络插件

具体参数的说明可以参考k3s官方文档

查看k3s.service的程序状态

➜  ~ systemctl status k3s.service
● k3s.service - Lightweight Kubernetes
   Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2023-07-19 18:20:03 CST; 5 days ago
     Docs: https://k3s.io
  Process: 11836 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
  Process: 11834 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
  Process: 11831 ExecStartPre=/bin/sh -xc ! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service (code=exited, status=0/SUCCESS)
 Main PID: 11838 (k3s-server)
    Tasks: 211
   Memory: 3.4G
   CGroup: /system.slice/k3s.service
   ......

安装kilo

  1. 指定server节点所在云的kilo拓扑

    k3s kubectl annotate node tx-master-1 kilo.squat.ai/location="txy-1"
    k3s kubectl annotate node tx-master-1 kilo.squat.ai/force-endpoint={{ public_ip }}:51820
    k3s kubectl annotate node tx-master-1 kilo.squat.ai/persistent-keepalive=20
    

    配置可参考kilo官方文档

  2. 修改启动参数
    下载yaml文件
    wget https://raw.githubusercontent.com/squat/kilo/main/manifests/kilo-k3s.yaml

    调整kilo的启动参数为全互联模式

    ...
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
    name: kilo
    namespace: kube-system
    labels:
        app.kubernetes.io/name: kilo
    spec:
    selector:
        matchLabels:
        app.kubernetes.io/name: kilo
    template:
        metadata:
        labels:
            app.kubernetes.io/name: kilo
        spec:
        serviceAccountName: kilo
        hostNetwork: true
        containers:
        - name: kilo
            image: squat/kilo
            args:
            - --kubeconfig=/etc/kubernetes/kubeconfig
            - --hostname=$(NODE_NAME)
    +       - --encapsulate=never
    +       - --mesh-granularity=full
    ...
    ...
    
    • --encapsulate=never 表示不使用 ipip 协议对同一个逻辑区域内的容器网络流量进行加密。
    • --mesh-granularity=full 表示启用全互联模式。
  3. 部署kilo
    安装crds和kilo

    kubectl apply -f https://raw.githubusercontent.com/squat/kilo/main/manifests/crds.yaml
    kubectl apply -f kilo-k3s.yaml
    

部署完成后通过ifconfig会发现多了一个kilo0kube-bridge的网络接口,可以通过wg show kilo0查看网卡的详细信息

agent节点

token=******
server_public_ip=*.*.*.*
node_public_ip=*.*.*.*
curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_TOKEN=$token K3S_URL=https://$server_public_ip:6443 sh -s - --node-external-ip $node_public_ip --kube-proxy-arg "metrics-bind-address=0.0.0.0"

token:通过在主机执行cat /var/lib/rancher/k3s/server/node-token获取
server_public_ip:即为master节点的公网ip
node_public_ip:即为agent节点的公网ip

安装完成后,通过kubectl get nodes查看节点状态,如果状态为Ready,则表示安装成功。

指定agent的拓扑

# tx2-agent1
k3s kubectl annotate node tx2-agent1 kilo.squat.ai/location="txy-2"
k3s kubectl annotate node tx2-agent1 kilo.squat.ai/force-endpoint={{ server_public_ip }}
k3s kubectl annotate node tx2-agent1 kilo.squat.ai/persistent-keepalive=20

# tx2-agent2
k3s kubectl annotate node tx2-agent2 kilo.squat.ai/location="txy-3"
k3s kubectl annotate node tx2-agent2 kilo.squat.ai/force-endpoint={{ server_public_ip }}
k3s kubectl annotate node tx2-agent2 kilo.squat.ai/persistent-keepalive=20

验证

部署1个busybox的DaemonSet,使其落在每一个Node 上。验证网络流向

# busybox.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  selector:
    matchLabels:
      name: busybox
  template:
    metadata:
      labels:
        name: busybox
    spec:
      containers:
      - name: busybox
        image: busybox
        args:
        - sleep
        - "3600"

kubectl apply -f busybox.yaml 部署完成通过kubectl get pods -o wide查看pod的状态,如果状态为Running,则表示部署成功。 通过kubectl exec -it busybox-xxxxx -- sh进入容器,尝试ping其他节点的pod,如果ping通,则表示网络通信正常。
https://qiniu.ckfear.cn/uPic/lINBf4.png-webp

到这里已经完成了k3s+kilo的部署。

参考文档:

  1. https://ewhisper.cn/posts/21355/
  2. https://icloudnative.io/posts/use-wireguard-as-kubernetes-cni/