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只守门,不修路。
最后,公开记录这些决策的过程本身就有价值。面试官问"你怎么设计网络"时,能拿出带时间戳的架构笔记,比背诵教科书强得多。
热门跟贴