Kubernetes 集群中快速部署一个私有 Tailscale DERP 服务器
前言
本文的目的是在 K8s 集群内搭建 Tailscale 的 DERP 服务器。
背景知识
Tailscale
Tailscale 允许您轻松管理对私有资源的访问(本质上是个 VPN 工具),快速 SSH 进入网络上的设备,并且可以在世界上的任何地方安全地工作。
在您的设备、虚拟机和服务器之间创建一个安全的 WireGuard 网状网络 -- 即使它们被防火墙或子网隔开。
DERP
Tailscale 运行 DERP 中继服务器来帮助连接您的节点。除了使用 tailscale 提供的 DERP 服务器之外,您还可以运行自己的服务器。
Tailscale 运行分布在世界各地的 DERP 中继服务器,将您的 Tailscale 节点点对点作为 NAT 遍历期间的一个边通道,并作为 NAT 遍历失败和无法建立直接连接的备用。
Tailscale 在许多地方运行 DERP 服务器。截至 2022 年 9 月,这份名单包括:
•Australia (Sydney)
•Brazil (São Paulo)
•Canada (Toronto)
•Dubai (Dubai)
•France (Paris)
•Germany (Frankfurt)
•Hong Kong (Hong Kong)
•India (Bangalore)
•Japan (Tokyo)
•Netherlands (Amsterdam)
•Poland (Warsaw)
•Singapore (Singapore)
•South Africa (Johannesburg)
•Spain (Madrid)
•United Kingdom (London)
•United States (Chicago, Dallas, Denver, Honolulu, Los Angeles, Miami, New York City, San Francisco, and Seattle)
?Notes:
不包括中国。
Tailscale 客户端自动选择最近的低延迟中继。为了提供低延迟连接,Tailscale 正在根据需要不断扩展和增加更多的 DERP 服务器。
为了实现低延迟和稳定性, 因此需要搭建 DERP 服务器。
步骤
根据最后参考文档中的任选一份最简的 docker-compose 配置,转换为 K8s 的配置(可以使用工具:kompose
[1] 转换), 转换后的配置如下:
?Notes:
为了方便以 Env 方式配置域名,这里使用了 StatefulSets.
---
apiVersion: v1
kind: Service
metadata:
name: derper-tok
labels:
io.kompose.service: derper-tok
spec:
ports:
- port: 443
name: https
- port: 80
name: http
- protocol: UDP
port: 3478
name: stun
clusterIP: None
selector:
io.kompose.service: derper-tok
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
annotations:
kompose.cmd: kompose convert -f docker-compose.yml
kompose.version: 1.26.1 (a9d05d509)
labels:
io.kompose.service: derper-tok
name: derper-tok
namespace: tailscale
spec:
replicas: 3
selector:
matchLabels:
io.kompose.service: derper-tok
serviceName: derper-tok
template:
metadata:
annotations:
kompose.cmd: kompose convert -f docker-compose.yml
kompose.version: 1.26.1 (a9d05d509)
labels:
io.kompose.service: derper-tok
spec:
containers:
- env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: DOMAIN
value: example.com
- name: DERP_ADDR
value: :443
- name: DERP_CERT_DIR
value: /app/certs
- name: DERP_CERT_MODE
value: letsencrypt
- name: DERP_DOMAIN
value: $(MY_POD_NAME).$(DOMAIN)
- name: DERP_HTTP_PORT
value: "80"
- name: DERP_STUN
value: "true"
- name: DERP_VERIFY_CLIENTS
value: "true"
image: fredliang/derper:latest
imagePullPolicy: Always
name: derper-tok
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
volumeMounts:
- mountPath: /var/run/tailscale/tailscaled.sock
name: tailscale-socket
hostNetwork: true
volumes:
- hostPath:
path: /run/tailscale/tailscaled.sock
type: Socket
name: tailscale-socket
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
具体说明如下:
•为什么用 StatefulSets, 而不是 Deployment 或 DaemonSet, 主要是我自己的期望如下:•希望可以使用 derper-tok-{1..3}.example.com
这样的域名,这样的话,使用 StatefulSets 的话,derper-tok-1
就是 POD Name, 方便配置。•如果用 Deployment 或 DaemonSet, Pod name 随机,域名就需要想办法一个一个配置了。•这里 K8s 的 Service 纯粹是因为创建 StatefulSets 需要一个 service 而已,实际上并没用到•通过 MY_POD_NAME
DOMAIN
DERP_DOMAIN
就将域名根据 POD name 组合起来了•DERP_CERT_MODE
现在新版的 DERP 支持 let's encrypt 自动申请证书,比之前方便很多•DERP_VERIFY_CLIENTS: true
保证只有自己能使用自己的 DERP 服务器,需要配合 tailscale 使用•fredliang/derper:latest
镜像直接是使用的该镜像•securityContext
需要确保有 NET_ADMIN
的能力,privileged: true
也最好加上保证更大的权限。•hostNetwork: true
直接使用主机网络,也就是:443, 3478 端口直接监听 K8s Node 的端口,简单粗暴。如果端口有冲突需要调整端口,或者不要使用这种模式。•volumeMounts
和 volumes
: 这里我安装的 tailscale 在该 K8s Node 上的 socket 为:/run/tailscale/tailscaled.sock
, 将其挂载到 DERP 容器的 /var/run/tailscale/tailscaled.sock
, 配合 DERP_VERIFY_CLIENTS: true
, DERP 服务器就会自动验证客户端,保证安全。
就这样,kubectl apply
即可。
???
总结
本文比较纯粹,就是说明了一个场景:在 K8s 中安装 DERP 服务器。相关的上下文介绍不多,感兴趣的可以自行了解。
后面有时间可能会出一篇 K8s 中安装 tailscale 的文章。
安装完成后,在 tailscale 控制台上配置 ACL, 加入本次新建的几个 DERP 域名到 derpMap
即可。最后可以通过:tailscale netcheck
进行验证。