DevOps转行进行中,我在巴黎郊区的La Celle-Saint-Cloud搭了一个极简双节点k3s家庭实验室。公开记录每个架构决策有两个目的:理清自己的选择,同时向未来雇主证明我能在真实环境下运维Kubernetes集群。

今天的主题:如何在不折腾站点到站点VPN、不配置自定义路由表、不花钱上云的情况下,连接两台k3s节点。

打开网易新闻 查看精彩图片

硬件配置

打开网易新闻 查看精彩图片

两台异构机器:

Server节点:老旧Ivy Bridge台式机,Intel i7-3770K(2012年),32GB内存,RTX 2060 12GB留给未来PyTorch负载。通过网线接入1Gb交换机。

Worker节点:GEEKOM A8迷你PC,AMD Ryzen 7 8745HS(Zen 4架构,8核16线程,28W TDP),32GB内存,1TB NVMe SSD。网线接入同一交换机

笔记本:HP Pavilion Gaming,运行Ubuntu 24.04,主力工作站。

两台节点都跑Ubuntu 24.04.4 LTS,内核6.17,k3s v1.35.4,containerd运行时2.2.3。拓扑故意不对称:服务器拿GPU做机器学习,worker节点留给CI/CD和无状态应用。

核心问题:随处访问集群,但不暴露内网

在家办公时,笔记本和两台节点在同一局域网——简单。一旦出门(咖啡馆、出差),我需要:

• 在任何地方运行kubectl get pods

• SSH进节点调试

• 但不在家用路由器上开放6443或22端口

三个正经选项:

1. 手动站点到站点VPN,比如WireGuard:自己写配置、生成密钥、传播对等节点、调MTU。可行,但耗时间。

2. 公网暴露堡垒机:一台节点通过公网SSH访问,其余藏在后面。攻击面变大,没兴趣。

3. 托管网格VPN:Tailscale、Twingate、NetBird。Tailscale个人设备免费到100台,底层基于WireGuard,5分钟装好。

我选了Tailscale。

安装过程

每台机器(服务器、worker、笔记本)执行:

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

sudo tailscale up --ssh

--ssh标志启用Tailscale托管的SSH(通过Tailscale ACL认证,不用散落的SSH密钥)。

直接的192.168.1.x:41641很重要:同一局域网内,Tailscale能检测对等节点,不走DERP中继。延迟和带宽等于原生局域网。离开局域网后,流量经DERP(Tailscale托管)路由,延迟稍高但仍可用。

即时收益:MagicDNS全局解析ml-hellomichka和hellomichka-a8,不用再记IP。

反直觉决策:Tailscale只用于控制面

网上经典的"Tailscale + k3s"家庭实验室错误:强制所有Kubernetes流量(Flannel CNI、kubelet、etcd)走Tailscale,通过--flannel-iface=tailscale0和--node-ip=100.x.x.x。

打开网易新闻 查看精彩图片

我的选择是不这么做。kubectl get nodes -o wide的证明:INTERNAL-IP值是局域网IP(192.168.1.52、192.168.1.103),不是Tailscale IP(100.x.x.x)。

为什么?

两台节点物理上连在同一1Gb交换机。Kubernetes数据平面(pod到pod流量、kubelet到API server、etcd复制)走这条高速路径。Tailscale的100.x.x.x隧道在物理上绕了远路——经过软件加密、可能还有DERP中继——把千兆带宽压到几百兆,延迟从亚毫秒跳到几十毫秒。

控制面(kubectl、SSH、偶尔看日志)才是需要"随处访问"的部分。这部分流量很小:API server的6443端口,SSH的22端口。Tailscale的加密隧道和MagicDNS在这里完美工作。

实际效果

笔记本在咖啡馆:kubectl get pods走Tailscale隧道,延迟~40ms,完全可用。SSH进节点排查问题,同样路径。

笔记本在家:Tailscale检测到同一局域网,流量直接走192.168.1.x,延迟<1ms。

数据平面始终走192.168.1.x,不受Tailscale状态影响。Pod到pod通信、容器镜像拉取、etcd心跳——全部满速千兆。

关键配置细节

k3s安装时,我没有加--flannel-iface=tailscale0或--node-ip=100.x.x.x。默认配置让Flannel使用默认网络接口(eth0),绑定到局域网IP。

Tailscale只负责让控制面流量"可达",不负责让Kubernetes"运行"。两者解耦:Tailscale掉线,集群照样转;局域网故障,Tailscale救不了数据平面。

这种分离也是安全边界。Tailscale的ACL可以细粒度控制谁能访问6443和22,但数据平面流量根本不经过Tailscale——即使Tailscale账户被入侵,攻击者也只能打到控制面,不能直接摸到pod网络。

为什么不是WireGuard原生

完全可行。但Tailscale省掉:密钥管理、对等节点发现、NAT穿透调试、DNS配置。对个人实验室,这些时间省下来更值。

--ssh标志是隐藏福利:不用维护~/.ssh/authorized_keys,Tailscale ACL统一管理访问权限。换设备时,登录Tailscale即获得SSH访问权。

局限和权衡

这个设计假设两台节点始终在同一物理网络。如果节点分散在不同地点(比如一台在父母家),数据平面走Tailscale是唯一选择,带宽和延迟的代价必须付。

我的场景是固定双节点,优化目标是最大化本地性能,同时保留远程管理能力。Tailscale-only-for-control-plane是这个约束下的最优解。

另一个隐性成本:Tailscale的免费 tier 有100设备上限,对单用户实验室无限够用。但MagicDNS的域名是公开的(tailxxxxx.ts.net),虽然不暴露IP,但主机名可被扫描。对安全敏感场景,这是可接受的信息泄露。

给同类搭建者的建议

先画流量图:哪些需要"随处访问",哪些只需要"本地高速"。控制面和数据平面分离是Kubernetes的固有设计,家庭实验室可以借这个结构做网络层面的优化。

不要盲目复制网上的--flannel-iface=tailscale0教程。问自己:节点物理位置在哪?数据平面流量有多大?延迟敏感吗?

我的答案:同一交换机、千兆级、延迟敏感。所以Tailscale只守门,不修路。

最后,公开记录这些决策的过程本身就有价值。面试官问"你怎么设计网络"时,能拿出带时间戳的架构笔记,比背诵教科书强得多。