通过tailscole隧道远程管理k8s.md

  • 本地 DevOps 服务器:安装并登录 Tailscale
  • 实验环境 toolbox:安装二进制,在 tmux 中启动 tailscaled 和端口转发
  • 本地验证
  • 上传 kubeconfig 到 DevOps 平台

一、本地 DevOps 服务器 执行官方脚本systemd安装

在本地服务器执行:

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

启动 Tailscale:

systemctl enable --now tailscaled

登录:

tailscale up --hostname=devops-one

如果输出登录地址,打开地址完成认证。

查看本机 Tailscale 地址:

tailscale ip -4

应为:

100.78.105.87

查看状态:

tailscale status

二、实验环境 toolbox

进入 toolbox:

kubectl exec -it toolbox -- sh

如果容器中还没有安装 Tailscale:

apt-get update
apt-get install -y curl tmux
curl -fsSL https://tailscale.com/install.sh | sh

创建持久化目录:

mkdir -p /data/tailscale

先找到Kubernetes API地址

kubectl config view --minify \
  -o jsonpath='{.clusters[0].cluster.server}'

确认 Kubernetes API 在 toolbox 内可访问:.

curl -k https://kubernetes.default.svc/version

能返回 Kubernetes 版本信息即可。

三、在 tmux 中启动 tailscaled

创建新的 tmux 会话:

tmux new -s tailscale

进入 tmux 后,执行:

mkdir -p /data/tailscale

tailscaled \
  --tun=userspace-networking \
  --state=/data/tailscale/tailscaled.state \
  --socket=/data/tailscale/tailscaled.sock \
  >/data/tailscale/tailscaled.log 2>&1 &

等待启动:

sleep 2

确认 daemon 正常:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  status

四、登录实验环境的 Tailscale

仍然在 tmux 窗口内执行:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  up \
  --hostname=toolbox-k8s-proxy

如果出现登录 URL,用浏览器打开完成认证。

查看 toolbox 的 Tailscale 地址:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  ip -4

当前地址是:

100.77.210.85

五、在 tmux 中启动 Kubernetes API 转发

toolbox 内部的 Kubernetes API 地址是:

https://kubernetes.default.svc:443

在同一个 tmux 窗口继续执行:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  serve \
  --tcp 16443 \
  tcp://kubernetes.default.svc:443

看到类似输出就表示成功:

tcp://100.77.210.85:16443
  -> tcp://kubernetes.default.svc:443

这个命令保持前台运行即可,tmux 会话会维持它。

退出 tmux 但不停止隧道:

Ctrl+B
然后按 D

不要按 Ctrl+C,否则会停止端口转发。

查看会话:

tmux ls

重新进入:

tmux attach -t tailscale

六、本地服务器验证隧道

回到本地 DevOps 服务器执行:

tailscale ping 100.77.210.85

测试 Kubernetes API:

curl -k https://100.77.210.85:16443/version

预期返回:

{
  "major": "1",
  "minor": "33",
  "gitVersion": "v1.33.4"
}

再测试 DevOps 后端容器:

docker exec dev-ops-one-backend-1 \
  wget -qO- --no-check-certificate \
  https://100.77.210.85:16443/version

如果也返回版本信息,说明后端容器可以通过隧道访问实验集群。

七、准备上传到平台的 kubeconfig

先从实验环境导出 kubeconfig:

kubectl config view --raw --minify > /data/tailscale/tunnel-kubeconfig

查看原始 API 地址:

grep "server:" /data/tailscale/tunnel-kubeconfig

将其中的:

server: https://kubernetes.default.svc

改为:

server: https://100.77.210.85:16443

可以使用 sed:

sed -i \
  's#https://kubernetes.default.svc#https://100.77.210.85:16443#g' \
  /data/tailscale/tunnel-kubeconfig

确认:

grep "server:" /data/tailscale/tunnel-kubeconfig

应显示:

server: https://100.77.210.85:16443

以下为完整内容,但是这里引用了文件

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    server: https://kubernetes.default.svc
  name: in-cluster
contexts:
- context:
    cluster: in-cluster
    namespace: user-176-1514
    user: sa
  name: in-cluster
current-context: in-cluster
kind: Config
preferences: {}
users:
- name: sa
  user:
    tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token

遇到导入devops平台报错的问题执行以下操作拿到容器控制api的token

SA_DIR=/var/run/secrets/kubernetes.io/serviceaccount
CA_DATA="$(base64 -w0 "$SA_DIR/ca.crt")"
TOKEN="$(cat "$SA_DIR/token")"

cat > /data/tailscale/platform-kubeconfig.yaml <<EOF
apiVersion: v1
kind: Config
clusters:
- name: experiment
  cluster:
    server: https://100.77.210.85:16443
    certificate-authority-data: ${CA_DATA}
contexts:
- name: experiment
  context:
    cluster: experiment
    user: toolbox-service-account
current-context: experiment
users:
- name: toolbox-service-account
  user:
    token: ${TOKEN}
EOF

chmod 600 /data/tailscale/platform-kubeconfig.yaml

itops导入显示以下报错

request to https://100.77.210.85:16443/api/v1/nodes failed, reason: Hostname/IP does not match certificate's altnames: IP: 100.77.210.85 is not in the cert's list: 10.200.0.1, 192.168.2.101, 192.168.2.100, 192.168.2.102, 192.168.2.103

使用不校验ca证书的配置:

- cluster: 里面 
加入 insecure-skip-tls-verify: true
删除 certificate-authority-data
apiVersion: v1
kind: Config
clusters:
- name: experiment
  cluster:
    insecure-skip-tls-verify: true
    server: https://100.77.210.85:16443
contexts:
- name: experiment
  context:
    cluster: experiment
    user: toolbox-service-account
current-context: experiment
users:
- name: toolbox-service-account
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjhhQmxPd0hPb2wzUW9QYkpvaDVfbzBFRW10V2UxNnpQcnlDbWkwSm1URkEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxODIyMTkwNDczLCJpYXQiOjE3OTA2NTQ0NzMsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiMWVjMjk1ODYtZjlmNS00MTY3LWFlMGItZDU4OTUxZGNmODI3Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJ1c2VyLTE3Ni0xNTE0Iiwibm9kZSI6eyJuYW1lIjoiazhzLXcyLTAwNSIsInVpZCI6ImUyNWIyZjY4LWQ1MDYtNDFmZS04NWZlLWRlMDc2YzNkZmI3OCJ9LCJwb2QiOnsibmFtZSI6InRvb2xib3giLCJ1aWQiOiIwNjI3NjRmNi02N2E4LTQ0YzgtODNjMC1iOTNmNDMyMGE2ZTUifSwic2VydmljZWFjY291bnQiOnsibmFtZSI6InN0dWRlbnQiLCJ1aWQiOiJiMzYzZmU1OC1hNzc2LTQzN2EtODE5MS04OTZiMDA2MmQ4NzYifSwid2FybmFmdGVyIjoxNzkwNjU4MDgwfSwibmJmIjoxNzkwNjU0NDczLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6dXNlci0xNzYtMTUxNDpzdHVkZW50In0.EzRxUus0tDzbNAOdilgY71Cel1DquWQIbljKXNX0YDDgBaJZNpPCUhUZZcnPmxMsiqnlSpQte5rIwSi0sp14hMYYlShm16bqU9m_ZANtp5Rr8lqcGQD8HVL4IeRxU3-XcxHIM3iB4PccHsTn6DHLAhnktiBfc56A51s7DzD1OTC56jolRcAjdwmkltX_MTXWNJFNEMf7CDVQlJYY8_83wbkm7vn720vghm3S4bBmRRmnFOYKwnWHuHxH5HIkZeCDSukvwc3Vurjp-stvUJULaAFWImbuY_dv1UvBh5m0ZOMHzVFuH9XOh39OVU64d4LXBC8P07oFQUdW-YKxfq-SfA

八、在 DevOps 平台添加集群

在前端打开:

http://本地服务器地址:18081

进入:

集群管理 -> 添加集群

上传:

/data/tailscale/tunnel-kubeconfig

平台中最终使用的地址是:

server: https://100.77.210.85:16443

不要使用:

server: https://127.0.0.1:16443

也不要使用:

server: https://kubernetes.default.svc

集群内配置nodeport实现隧道内机器访问+内网穿透

保留两个 Service:

# StatefulSet 内部使用,提供稳定 Pod DNS  nonoservice
# 外部访问使用    nodeport
  1. 确认服务端能访问 NodePort

在 toolbox-k8s-proxy 上执行:

curl http://192.168.2.104:30081

如果返回:

Pod: stateful-demo-0

说明后端可达。

  1. 启动 Tailscale Serve
tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  serve \
  --bg \
  http://192.168.2.104:30081

第一次使用时,如果出现:

Serve is not enabled on your tailnet

打开它提示的授权链接,授权后重新执行上面的命令。

  1. 查看状态

必须继续使用自定义 socket:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  serve status

应看到类似:

https://toolbox-k8s-proxy.tail46632a.ts.net/
|-- proxy http://192.168.2.104:30081
  1. 隧道内机器访问

在 Windows 本机或其他已加入同一个 Tailnet 的设备上访问:

https://toolbox-k8s-proxy.tail46632a.ts.net/

或者:

curl https://toolbox-k8s-proxy.tail46632a.ts.net/

如果本机配置了 HTTP/HTTPS 代理,需要把以下域名加入直连:

*.ts.net

否则请求可能被本地代理拦截。

  1. 验证确实访问了多个 Pod

连续请求:

for i in $(seq 1 10); do
  curl -sk https://toolbox-k8s-proxy.tail46632a.ts.net/
  echo
done

页面可能显示不同的:

Pod: stateful-demo-0
Pod: stateful-demo-1
Pod: stateful-demo-2

这说明 Service 正在做负载转发。

实现任意人公网访问

Tailscale Serve只能让同一个 Tailnet 内的设备访问。公网匿名访问需要使用:

Tailscale Funnel

在 toolbox-k8s-proxy 上执行:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  funnel \
  --bg \
  http://192.168.2.104:30081

查看状态:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  funnel \
  status

如果第一次提示未启用,打开它给出的授权链接。启用后,公网用户可以访问类似:

https://toolbox-k8s-proxy.tail46632a.ts.net/

区别是:

Serve:只有 Tailnet 成员可以访问
Funnel:任意公网用户可以访问

唯一需要注意的是:如果 192.168.2.104 这台节点故障,Funnel 后端入口会失效。实验环境可以保持这样;生产环境再考虑用 HAProxy、Ingress 或负载均衡器代理多个节点。

查看当前 Serve 配置

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  serve \
  status

查看当前公网 Funnel 配置:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  funnel \
  status

重启后的恢复方式

由于 toolbox 没有 systemd,容器重启后需要重新启动 tmux 和 tailscaled:

tmux new -s tailscale

然后重新执行:

tailscaled \
  --tun=userspace-networking \
  --state=/data/tailscale/tailscaled.state \
  --socket=/data/tailscale/tailscaled.sock \
  >/data/tailscale/tailscaled.log 2>&1 &

sleep 2

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  serve \
  --tcp 16443 \
  tcp://kubernetes.default.svc:443

因为登录状态保存在:

/data/tailscale/tailscaled.state

通常不需要再次执行 tailscale up。

需要特别确认 /data 是持久化目录。否则 toolbox 容器删除后,Tailscale 登录状态也会丢失。

tailscale排查命令

卸载systemd安装的tailscale

systemctl disable --now tailscaled
dnf remove tailscale

Toolbox 手动运行模式

先定义 socket,后续命令更短:

TS_SOCKET=/data/tailscale/tailscaled.sock

检查进程、tmux 和 socket:

pgrep -af tailscaled
tmux ls
test -S "$TS_SOCKET" && echo "socket OK" || echo "socket missing"

检查 Tailscale 状态和 IP:

tailscale --socket="$TS_SOCKET" status
tailscale --socket="$TS_SOCKET" ip -4
tailscale --socket="$TS_SOCKET" version

检查网络条件:

tailscale --socket="$TS_SOCKET" netcheck
tailscale --socket="$TS_SOCKET" ping 100.78.105.87

netcheck 重点看:

UDP: true
Nearest DERP
MappingVariesByDestIP

通过 DERP 中继也能正常使用,只是延迟更高;不一定必须建立 direct 连接。

检查端口转发:

tailscale --socket="$TS_SOCKET" serve status

应包含:

tcp://100.77.210.85:16443
  -> tcp://kubernetes.default.svc:443

检查 toolbox 到 Kubernetes API:

curl -k --connect-timeout 5 \
  https://kubernetes.default.svc/version

查看日志:

tail -n 100 /data/tailscale/tailscaled.log
tail -f /data/tailscale/tailscaled.log

查看 tmux 中两个窗口:

tmux attach -t tailscale

切换窗口:

Ctrl+B,然后按 N

退出但保持运行:

Ctrl+B,然后按 D

手动启动 daemon:

tailscaled \
  --tun=userspace-networking \
  --state=/data/tailscale/tailscaled.state \
  --socket=/data/tailscale/tailscaled.sock

另一个 tmux 窗口启动转发:

tailscale \
  --socket=/data/tailscale/tailscaled.sock \
  serve \
  --tcp 16443 \
  tcp://kubernetes.default.svc:443

停止手动进程:

pkill -x tailscaled

注意:userspace 模式通常不会出现 tailscale0 网卡,而且不要在 toolbox 内使用普通 curl 回连自己的 100.77.210.85,应从另一台 Tailscale 设备测试。

systemd 托管模式

检查服务:

systemctl status tailscaled --no-pager
systemctl is-active tailscaled
systemctl is-enabled tailscaled

启动、停止、重启:

systemctl start tailscaled
systemctl stop tailscaled
systemctl restart tailscaled
systemctl enable --now tailscaled

查看日志:

journalctl -u tailscaled -n 100 --no-pager
journalctl -u tailscaled -f
journalctl -u tailscaled --since "30 minutes ago"

检查默认 socket:

ls -l /var/run/tailscale/tailscaled.sock
tailscale status
tailscale ip -4
tailscale netcheck
tailscale serve status

查看 systemd 启动参数:

systemctl cat tailscaled
systemctl show tailscaled \
  -p ActiveState \
  -p SubState \
  -p MainPID \
  -p ExecMainStatus

滚动至顶部