多服务器下的非内网k3s集群部署

WireGuard 实现 k3s 的非局域网部署

环境介绍

服务器介绍

服务器名称 | 公网 IP 地址 | 内网 IP 地址 | 虚拟网络 IP 地址 | 操作系统
master | 42. xx. xx.12 | 10.0.16.8 | 192.168.1.1 | Centos 7.6 64bit
node1 | 122. xx. xxx.111 | 10.0.0.6 | 192.168.1.2 | Centos 7.6 64bit
node2 | 122. xx. xx.155 | 172.17.0.3 | 192.168.1.3 | Centos 7.6 64bit

部署前准备

在所有节点开启 IP 地址转发：

Copy
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.proxy_arp = 1" >> /etc/sysctl.conf

# 检测状态
sysctl -p /etc/sysctl.conf

如果 echo 失败，自行使用 vi/vim 修改。

所有节点开启修改主机名称

Copy
# master执行
hostnamectl set-hostname k3s-master

# node1执行
hostnamectl set-hostname k3s-node1

# node2执行
hostnamectl set-hostname k3s-node2

添加 iptables 规则，允许本机的 NAT 转换：

Copy
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.1.1/24 -o eth0 -j MASQUERADE

wg0 : 为你定义的虚拟网卡
192.168.1.1 : 为你的虚拟 IP 地址段 （不同节点执行需要注意更改此 ip 地址）
eth0: 为你的物理网卡

构建虚拟局域网

在搭建跨云的 k3s 集群前，我们需要把 WireGuard 安装好，WireGuard 对内核是有要求的，所以内核已经要升级到 5.15.2-1.el7.elrepo.x86_64 及以上。

省略安装内核，本文使用 centos7.6 内核不需要额外更新。

内核版本一定要是比较高的，不然启动WireGuard会报错。

安装 WireGuard

所有节点执行

安装流程非常简单，我这里系统内核比较新，其中就已经包含了 WireGuard 的内核模块，只需要安装 wireguard-tools 这个 yum 包就行了。

Copy
yum install epel-release https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
yum install yum-plugin-elrepo kmod-wireguard wireguard-tools -y

配置 WireGuard

wireguard-tools 包提供了我们所需的工具 wg 和 wg-quick，可以使用它们来分别完成手动部署和自动部署。

先按照官方文档描述的形式，生成 master 节点用于加密解密的密钥

Copy
wg genkey | tee privatekey | wg pubkey > publickey

然后在当前目录下就生成了 privatekey 和 publickey 两个文件

privatekey 是密钥，是用来配置到本机，publickey 公钥需要配置到其他机器。

Copy
cat privatekey publickey

EMWcI01iqM4zkb7xfbaaxxxxxxxxDo2GJUA=
0ay8WfGOIHndWklSIVBqrsp5LDWxxxxxxxxxxxxxxQ=

现在我们需要与上述主机对等联网的 node1  node2 ，其公网 IP（这边需要填写的是能与主机通信的 IP）是 122. xx. xxx.111，122. xx. xx.155。

我们首先依照上面的流程安装 WireGuard 并生成好 node1 node2 的密钥。

然后编写 master 完整的配置文件，以供 wg-quick 使用，在主机 A 的 /etc/wireguard/wg0.conf 中写入。

Copy
[Interface]
PrivateKey = EMWcI01iqM4zkb7xfbaaxxxxxxxxDo2GJUA=
Address = 192.168.1.1
ListenPort = 5418

[Peer]
PublicKey = 腾讯云2 publickey
EndPoint = 122.xx.xxx.111:5418
AllowedIPs = 192.168.1.2/32

[Peer]
PublicKey = 阿里云publickey
EndPoint = 122.xx.xx.155:5418
AllowedIPs = 192.168.1.3/32

配置说明 ：

Interface : 小节是属于 master（也就是本机）的配置.
Address : 是分配给 master 虚拟 IP，
ListenPort : 是主机之间通讯使用的端口，是 UDP 协议的。
Peer : 是属于需要通信的 node2 、node2 的信息，有多少需要通信的主机，就添加多少个 Peer 小节。
EndPoint : 是 node1 、node2 的公网 IP 与 WireGuard 监听的 UDP 端口。

注意：如果你的机器通过内网也能通信，直接用内网 IP 也可以，当然要注意这个 IP 需要所有加入局域网的主机都能通信才行。

AllowedIPs : 是指本机发起连接的哪些 IP 应该将流量转发到这个节点去，比如我们给主机 B 分配了内网 IP 192.168.1.2，那么在主机 A 上发送到 192.168.1.2 的数据包，都应该转发到这个 EndPoint 上，它其实起的是一个过滤作用。而且多个 Peer 时，这里配置的 IP 地址不能有冲突。

各个节点生产的 privatekey 和 publickey 分别如下：

Copy
# master 节点
[root@k3s-master ~]# cat privatekey publickey
EMWcI01iqM4zkb7xfbaaxxxxxxxxDo2GJUA=
0ay8WfGOIHndWklSIVBqrsp5LDWxxxxxxxxxxxxxxQ=
# node1 节点
[root@k3s-node1 ~]# cat privatekey publickey
QGdNkzpnIkuvUU+00C6XYxxxxxxxxxK0D82qJVc=
3izpVbZgPhlM+S5szOogTDTxxxxxxxxxuKuDGn4=
# node2 节点
[root@k3s-node2 ~]# cat privatekey publickey
WOOObkWINkW/hqaAME9r+xxxxxxxxxm+r2Q=
0f0dn60+tBUfYgzw7rIihKbqxxxxxxxxa6Wo=

各个节点配置文件如下：

Copy
# master 节点
cat /etc/wireguard/wg0.conf
[Interface]
PrivateKey = EMWcI01iqM4zkb7xfbaaxxxxxxxxDo2GJUA=
Address = 192.168.1.1
ListenPort = 5418

[Peer]
PublicKey = 3izpVbZgPhlM+S5szOogTDTxxxxxxxxxuKuDGn4=
EndPoint = 122.xx.xxx.111:5418
AllowedIPs = 192.168.1.2/32

[Peer]
PublicKey = 0f0dn60+tBUfYgzw7rIihKbqxxxxxxxxa6Wo=
EndPoint = 122.xx.xx.155:5418
AllowedIPs = 192.168.1.3/32

Copy
# node1 节点
cat /etc/wireguard/wg0.conf
[Interface]
PrivateKey = QGdNkzpnIkuvUU+00C6XYxxxxxxxxxK0D82qJVc=
Address = 192.168.1.2
ListenPort = 5418

[Peer]
PublicKey = 0ay8WfGOIHndWklSIVBqrsp5LDWxxxxxxxxxxxxxxQ=
EndPoint = 42.xx.xx.12:5418
AllowedIPs = 192.168.1.1/32

[Peer]
PublicKey = 0f0dn60+tBUfYgzw7rIihKbqxxxxxxxxa6Wo=
EndPoint = 122.xx.xx.155:5418
AllowedIPs = 192.168.1.3/32

Copy
# node2 节点
cat /etc/wireguard/wg0.conf
[Interface]
PrivateKey = WOOObkWINkW/hqaAME9r+xxxxxxxxxm+r2Q=
Address = 192.168.1.3
ListenPort = 5418

[Peer]
PublicKey = 0ay8WfGOIHndWklSIVBqrsp5LDWxxxxxxxxxxxxxxQ=
EndPoint = 42.xx.xx.12:5418
AllowedIPs = 192.168.1.1/32

[Peer]
PublicKey = 3izpVbZgPhlM+S5szOogTDTxxxxxxxxxuKuDGn4=
EndPoint = 122.xx.xx.155:5418
AllowedIPs = 192.168.1.2/32

启动 WireGuard

配置文件写好后，使用 wg-quick 工具来创建虚拟网卡。

Copy
wg-quick up wg0

上面命令中的 wg0 对应的是 /etc/wireguard/wg0.conf 这个配置文件，其自动创建的网卡设备，名字就是 wg0，这对应关系自不必多言。

将 node1 、node2 的网卡设备都安装配置好后，就能使用 wg 命令来观察组网情况了.

Copy
[root@k3s-master ~]# wg
interface: wg0
public key: 0ay8WfGOIHndWklSIVBqrsp5LDWxxxxxxxxxxxxxxQ=
private key: (hidden)
listening port: 5418

peer: 0f0dn60+tBUfYgzw7rIihKbqxxxxxxxxa6Wo=
endpoint: 122.xx.xx.155:5418
allowed ips: 192.168.1.3/32
latest handshake: 3 minutes, 3 seconds ago
transfer: 35.40 KiB received, 47.46 KiB sent

peer: 3izpVbZgPhlM+S5szOogTDTxxxxxxxxxuKuDGn4=
endpoint: 122.xx.xxx.111:5418
allowed ips: 192.168.1.2/32
latest handshake: 5 minutes, 6 seconds ago
transfer: 24.84 KiB received, 35.21 KiB sent

可以看到列出了对等联网的节点信息，还有通信测量数据。然后可以通过 ping 其他主机的虚拟 IP 或者 ssh 其他主机的 IP 地址，来检查网络通信是否正常。

自动化

系统重启后，WireGuard 创建的网卡设备就会丢失，有自动化的脚本。

Copy
systemctl enable wg-quick@wg0

使用上述命令生成systemd守护脚本，开机会自动运行 up 指令。

完成 WireGuard 的安装配置以后，我们就可以接下来安装 k3s 的集群了。

安装 K3S 集群

master 节点安装

Copy
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - --node-external-ip 42.xx.xx.12 --advertise-address 42.xx.xx.12 --node-ip 192.168.1.1 --flannel-iface wg0

参数说明：

--node-external-ip 42.xx.xx.12 为节点设置外部 IP，阿里云 VPC 的外网 IP 并未直接绑定到虚拟机网卡上，所以我要设置这个参数，避免 k3s 组件在设置 loadbalance 时，将内网 IP 当作公网 IP 使用。

--advertise-address 42.xx.xx.12 用于设置 kubectl 工具以及子节点进行通讯使用的地址，可以是 IP，也可以是域名，在创建 apiserver 证书时会将此设置到有效域中。

--node-ip 10.20.30.1 如果不设置这个参数，那么第一张网卡设备上的 IP 就会被选中，所以这个 IP 常是内网 IP。但我自行组建了虚拟局域网，所以需要指定虚拟局域网的 IP（也就是 WireGuard 的 IP）。

--flannel-iface wg0 wg0 是 WireGuard 创建的网卡设备，我需要使用虚拟局域网来进行节点间的通信，所以这里需要指定为 wg0。

另外就是，由于 WireGuard 的所有流量都是加密传输的，通过它来进行节点间的通信，就已经能够保证通信安全，也就没有必要改用其它的 CNI 驱动，使用默认的就可以了。

在主节点执行上述命令后，一分钟不到就可以看到脚本提示安装完成。通过命令查看下主控端的运行情况。

Copy
systemctl status k3s

如果运行正常，那么就看看容器的运行状态是否正常。

Copy
kubectl get pods -A

-A 参数用于查看所有命名空间，如果容器都处于 running 状态，那么安装就成功了，接下来要可以添加被控节点。

Agent 安装

有了上述安装主控的经验，安装 work 节点更加简单，参数需要一定的调整。

node1 节点：

Copy
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.1.1:6443 K3S_TOKEN=K10720eda8a278bdc7b9b6d787c9676a92119bb2cf95048d6a3cd85f15717edfbe5::server:e98b986e8202885cb54da1b7e701f67e sh -s - --node-external-ip 122.xx.xxx.111 --node-ip 192.168.1.2 --flannel-iface wg0

node2 节点：

Copy
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.1.1:6443 K3S_TOKEN=K10720eda8a278bdc7b9b6d787c9676a92119bb2cf95048d6a3cd85f15717edfbe5::server:e98b986e8202885cb54da1b7e701f67e sh -s - --node-external-ip 122.xx.xx.155 --node-ip 192.168.1.3 --flannel-iface wg0

参数说明：

K3S_Token 根据文档说明，去 /var/lib/rancher/k3s/server/node-token 获取即可。

K3S_URL 需要设置主控的通信地址端口，端口默认是 6443，IP 地址就是虚拟网域的 IP，这样流量就会通过 WireGuard 加密传输。

另外两个参数也不必多说，与主控一样的逻辑。执行后稍等一会，安装成功后，照例查看服务运行状态。

Copy
systemctl status k3s-agent

如果有报错就根据报错查找解决方案。

都安装好以后在 master 节点检查。

Copy
kubectl get nodes -o wide

没有问题的话就显示三个节点 master , node1 和 node2 ，三个节点都是 Ready 状态。

至此多云 K3S 集群已经搭建完毕。

如果某些命令报权限错误，请用管理员权限 sudo 执行。