基于Wireguard组网Kubernetes(k3s)集群搭建

背景

Wireguard能让处于不同网络的主机组成一个子网,是一种高性能的廉价组网方案。
K3S、Microk8s、kind、MiniKube等是Kubernetes的轻量实现版本,本篇采用k3s做为集群方案。

目录

一、环境准备

1.机器清单

Node Local Specification OS Network IP
Node1 Aliyun 4C8G CentOS 8 VPC/EIP eth0: 172.17.0.32/ EIP: 39.x.x.x
Node2 腾讯云 2C4G CentOS 8 Nat Public IP eth0: 10.x.x.x / Public IP: 81.x.x.x
Node3 Macbook 4C8G MacOS 11.4 WIFI en0: 172.168.0.100
Node4 VM 8C16G CentOS7 Lan Private IP eth0: 172.17.1.116
Node5 VM 4C8G CentOS7 Lan Private IP eth0: 172.17.1.114

2.内核升级

Wireguard需要Kernel 5.x+

centos内核升级
#载入elrepo公钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
#升级安装 elrepo
centos7: rpm -Uvh http://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
centos8: rpm -Uvh http://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm
# 添加清华eprepo mirror
参照 https://mirrors.tuna.tsinghua.edu.cn/help/elrepo/
#载入elrepo-kernel元数据
yum --disablerepo=\* --enablerepo=elrepo-kernel repolist
#查看可用的rpm包
yum --disablerepo=\* --enablerepo=elrepo-kernel list kernel*
内核说明:
kernel-ml: mainline stable 稳定主线版本
kernel-lt: mainline stable 长期支持版本
#安装新内核, 建议安装ml
yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-ml.x86_64 -y
#el7 设置内核启动顺序
awk -F \' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
grub2-set-default 0 <- 上调命令内核顺序号
也可使用下条命令设置
grub2-set-default 'CentOS Linux (5.15.6-1.el7.elrepo.x86_64) 7 (Core))'
CentOS 8+ 使用 grubby --info=ALL 查看内核列表,5.xx.xx 版本已经置于对首了不需要做启动顺序调整了 。

#确认内核
grub2-editenv list
#更新内核工具
yum remove kernel-tools-libs.x86_64 kernel-tools.x86_64 -y #删除旧版工具
yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-ml-tools kernel-ml-devel kernel-ml-headers -y
#重启
reboot
uaname -a

3.工具安装

yum install wireguard wireguard-tools -y
wg show

所有节点都需要执行上面流程

二、网络规划与部署

wireguard 可以直接使用wg命令管理,其他更易用的工具有 Wg Gen Web、NetMaker,这里建议使用NetMaker。

1.安装Netmaker

Netmaker 需要安装到有公网IP的节点上,本例选择了Node1(亲测腾讯云网络有问题,作为管理端会有各种诡异表现)。

安全组防火墙需要放行 TCP:9909 30800 UDP:51820-51830

建议使用docker-compse安装

install netmaker
version: "3.4"
services:
netmaker:
container_name: netmaker
image: gravitl/netmaker:v0.9
volumes:
- /etc/netclient/config:/etc/netclient/config
- /usr/bin/wg:/usr/bin/wg
- dnsconfig:/root/config/dnsconfig
- /data/sqldata/:/root/data
cap_add:
- NET_ADMIN
restart: always
network_mode: host
environment:
SERVER_HOST: "<public ip>"
COREDNS_ADDR: "172.17.0.32"
GRPC_SSL: "off"
DNS_MODE: "on"
CLIENT_MODE: "on"
API_PORT: "9909"
GRPC_PORT: "50056"
SERVER_GRPC_WIREGUARD: "off"
CORS_ALLOWED_ORIGIN: "*"
DATABASE: "sqlite"
VERBOSITY: 3
netmaker-ui:
container_name: netmaker-ui
depends_on:
- netmaker
image: gravitl/netmaker-ui:v0.9
links:
- "netmaker:api"
ports:
- "30800:80"
environment:
BACKEND_URL: "http://<public ip>:9909"
restart: always
# network_mode: host
coredns:
depends_on:
- netmaker
image: coredns/coredns
command: -conf /root/dnsconfig/Corefile
container_name: coredns
restart: always
network_mode: host
volumes:
- dnsconfig:/root/dnsconfig
volumes:
dnsconfig: {}

2.配置网络

  • 访问 http://<public ip>:30800/

创建成功后,我们能在Node列表中看到本机,因为netmaker启动的时候我们设置了CLIENT_MODE:on,如果不需要管理节点做为Node可以设置为Off

  • 创建Access Key 保存AccessToken

3.安装netcliet

Node[2-5]安装Netclient

4.Node个性化配置

Node[4-5] 为Linux内网机,开启UDP Hole Punching
Node3 开启UDP Hole Punching 、Roaming

5. 验证网络

如果所有peer都能连接成功,ping测试一下对端如果ping不通尝试一下开启 Hole Punching

sudo wg show

interface: nm-ali
public key: xxxxx
private key: (hidden)
listening port: 40072
peer: xxxxxx
endpoint: 103.x.x.x:57416
allowed ips: 10.11.22.4/32
latest handshake: 57 seconds ago
transfer: 147.12 KiB received, 538.77 KiB sent
persistent keepalive: every 20 seconds

peer: xxxxx
endpoint: 39.x.x.x:51821
allowed ips: 10.11.22.2/32
latest handshake: 1 minute, 44 seconds ago
transfer: 8.97 MiB received, 2.32 MiB sent
persistent keepalive: every 20 seconds

peer: xxxx
endpoint: 103.x.x.x4:53506
allowed ips: 10.11.22.6/32
latest handshake: 1 minute, 59 seconds ago
transfer: 20.49 KiB received, 16.35 KiB sent
persistent keepalive: every 20 seconds

peer: xxxxx
endpoint: 223.x.x.x:31609
allowed ips: 10.11.22.5/32
transfer: 0 B received, 204.80 KiB sent
persistent keepalive: every 20 seconds

三、集群安装

master 安装

下面安装采用Docker运行时,如果没有安装docker可以去掉--docker

Master
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --node-ip 10.11.22.2 \
--node-external-ip 39.x.x.x --docker --flannel-iface nm-ali" sh -

必要参数 --flannel-iface=nm-ali
更多安装配置参照 https://rancher.com/docs/k3s/latest/en/installation/install-options/server-config/

Agent 安装

  • 获取master token
get token
echo /var/lib/rancher/k3s/server/node-token
  • 初始化Agent
Install Node
curl -sfL https://get.k3s.io |  \
INSTALL_K3S_EXEC="agent --server https://10.150.22.2:6443 \
--token <token> \
--node-ip 10.150.22.3 \
--node-external-ip 10.150.22.3 \
--flannel-iface nm-ali \
--containerd --node-name=tx" sh -

故障排除

  • 节点通过10.11.22.0/24私网IP不可能访问

    1. IP冲突可使用arping测试是否网段与Node IP冲突。
    2. 没有开启 UDP Hole Punching
    3. 公网IP变更且节点没有开启Roaming
  • k3s pod 不可能访问

    1. k3s 没有配置–flannel-iface为wireguard 网卡。
  • Ubuntu20.04 bpfilter: read fail 0

    1. 内核兼容性问题,使用apt-get install linux-image- 安装内核替换自己从elrepo下载的内核

参考