如何使用 Tailscale 实现 K3s 集群多云组网

Posted by Mike on 2025-01-25

前因

根据 k3s 官网文档,我本来是基于 Wireguard 进行全球组网的,后面经过测试,如果某个节点因为大陆反向阻挡了或者主动屏蔽了海外流量的话,会导致这个节点流量会异常增加(数据来源自哪吒监控), 所有想探索一下有没有其他方式。

在 k3s v1.27.3v1.26.6 及更高版本中,支持 Tailscale 集成,以便节点使用 Tailscale VPN 服务在节点之间构建网格。

在这之前先简单介绍我之前怎么部署的

嵌入式 k3s 多云解决方案

K3s 使用 Wireguard 为集群流量建立 VPN 网格。每个节点都必须有一个唯一的 IP,通过该 IP 可以访问它们, 集群 (CNI) 流量将使用 Wireguard 隧道。

  • 控制节点配置参数
1
2
# SERVER_EXTERNAL_IP 这个通常是节点的公网 ip
--node-external-ip=<SERVER_EXTERNAL_IP> --flannel-backend=wireguard-native --flannel-external-ip
  • 计算节点配置参数
1
2
# AGENT_EXTERNAL_IP 这个通常是节点的公网ip
--node-external-ip=<AGENT_EXTERNAL_IP>

改造

安装 Tailscale

1
$ curl -fsSL https://tailscale.com/install.sh | sh

我的节点基本都已经安装了 Tailscale,这步可以跳过。如果你安装比较慢可以考虑试试我的镜像源,但不一定好使哈。

tailscale 镜像使用帮助

已经登录的,或者已经配置了 route 都没关系,不用管。

申请 tailscale 密钥

在 Tailscale 控制台生成一个身份验证密钥 $AUTH-KEY,该密钥可对集群中的所有节点重复使用 Settings > Keys

申请 URL

注意点:

  • 勾选 Reusable, 开启 Key 重复使用
  • 记好 Key, 仅可见一次,key 有效期不用管,注册后可以通过节点的属性设置有效期

开启自动允许路由(可选)

使用 tailscale 组网的话,每个节点会自动发布自己节点的路由

配置路径 Access controls URL

1
2
3
4
5
6
7
8
9
10
11
// Example/default ACLs for unrestricted connections.
{
"autoApprovers": {
"routes": {
"10.42.0.0/16": ["ysicing@github"],
},
},
// Declare static groups of users. Use autogroups for all users or users with a specific role.
// "groups": {
// "group:example": ["alice@example.com", "bob@example.com"],
// },

节选如上, 具体 podCIDR 根据你的情况确定,后面的用户也根据你实际情况来写,由于我是用 Github 登录的,我的账号信息就是 ysicing@github

编辑 K3s 配置文件

编辑所有的 /etc/systemd/system/k3s.service, 由于我是手搓的配置,文件名都一样。如果你通过脚本安装的可能是 k3s.service/k3s-agent.service

注释掉所有 --flannel-external-ip,--flannel-backend wireguard-native,--node-external-ip 参数

新增 --vpn-auth="name=tailscale,joinKey=tskey-auth-..." \ 参数,joinKey 的值就是对应的上面步骤申请的密钥

完成上述步骤重启即可

1
2
$ systemctl daemon-reload
$ systemctl restart k3s

观察生效

1
$ kubectl get nodes -o wide

所有节点的 INTERNAL-IP 都是 100 打头开始的就行。

问题 QA

节点 INTERNAL-IP 不变

  • 首先检查有没有开启 ipv6,没有的话开启支持 ipv6

如果不出意外编辑 /etc/sysctl.conf,把 1 改成 0,编辑结果如下

1
2
3
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0

生效 sysctl -p

然后重启 K3s 看看, 如果还不变的话,可能需要看看 k3s 日志

如果日志如下, 提示没法识别 ipv6

1
Feb 07 22:23:02 node1 k3s[1448143]: E0207 22:23:02.346550 1448143 kubelet_node_status.go:701] "Failed to set some node status fields" err="failed to validate secondaryNodeIP: node IP: \"fd7a:115c:a1e0:ab12:4843:cd96:6278:6544\" not found in the host's network interfaces" node="node1"

需要给 k3s 新增启动参数

1
--kubelet-arg "node-ip=0.0.0.0" \

然后重载并重启 k3s 再观察。

调整优势

  • 可以支持 NAT 机器加入组网中
  • 节点如果双栈支持,避免 ipv4 被打,集群节点失联

本文转载自:「 Solitudes 的博客 」,原文:https://url.hi-linux.com/6JD5C ,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com