前言
本文的目的是在 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
轉換), 轉換後的配置如下:
?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
進行驗證。
參考文件
- Custom DERP Servers · Tailscale
- fredliang/derper - Docker Image | Docker Hub
- Tailscale 基礎教程:部署私有 DERP 中繼伺服器 – 雲原生實驗室
- headscale 保底設施之 DERP 中繼伺服器自建 | 俊瑤先森 (junyao.tech)
- 我的伺服器系列:tailscale 使用自定義 derper 伺服器(docker 部署) - 霖的個人開發筆記 (linshenkx.cn)
- Tailscale on Kubernetes · Tailscale
本文由部落格一文多發平臺 OpenWrite 釋出!