1概述
复杂嵌套环境架构:
- Mac(本地开发机)
- Ubuntu Server(宿主机)
- Docker(在 Ubuntu 上运行)
- Docker 内部运行多个 VM(vm-1, vm-2, vm-3,承载 K8s 节点)
- K8s 集群实际运行在上述 VM 网络内
Telepresence 的核心作用:
Telepresence 能够跨越上述多层网络边界,将本地 Mac 运行的 Go 程序“无缝接入”到远端 K8s 集群中。本地代码能够直接使用集群内 DNS 访问远端 Service、ConfigMap、Database,同时集群内的流量也能被劫持(Intercept)到本地进程,实现本地闭环。
前置条件:要使用
intercept功能,K8s 集群中必须存在一个对应的 Service(即使底层是一个轻量级的占位 Pod)。
2Mac 本地安装 Telepresence
# 1. Ensure that no old binary exists. This is very important because Apple Silicon macs track the executable's
# signature and just updating it in place will not work.
sudo rm -f /usr/local/bin/telepresence
# 2. Download the binary.
sudo curl -fL https://github.com/telepresenceio/telepresence/releases/latest/download/telepresence-darwin-arm64 -o /usr/local/bin/telepresence
# 3. Make the binary executable:
sudo chmod a+x /usr/local/bin/telepresence
3配置 kubeconfig(打通网络的核心)
3.1暴露 API Server 6443 端口
如果控制面(master 节点,如 vm-1)是作为容器运行的,必须在 docker-compose.yml 中将其 6443 端口映射到 Ubuntu 宿主机:
services:
vm-1: # 你的 master 节点
# ... 你的原有配置
ports:
- "6443:6443" # ← 增加这一行,把 vm-1 的 6443 暴露到宿主机
3.2提取内层 VM 的 kubeconfig
进入 K8s master 节点,将配置文件复制到 Ubuntu 宿主机:
docker cp vm-1:/root/.kube/config ~/k8s-remote-config.yaml
3.3转移配置至 Mac 并修改
将提取出的配置拷贝至 Mac 本地,在 Mac 上执行:
mkdir -p ~/.kube/configs
scp ubuntu@192.168.1.7:~/k8s-remote-config.yaml ~/.kube/configs/remote-dind.yaml
3.4修改 kubeconfig 中的 server 地址
关键修改:编辑 ~/.kube/configs/remote-dind.yaml:
- 将
server的 IP 修改为 Ubuntu 宿主机的局域网 IP。
server: https://192.168.x.x:6443 # ← 改成 Ubuntu Server 的 IP
- 删除
certificate-authority-data字段(如果存在)。
certificate-authority-data: xxxxxxxx(很长的一串)
- 增加
insecure-skip-tls-verify: true绕过证书校验。
clusters:
- cluster:
server: https://192.168.1.7:6443
insecure-skip-tls-verify: true # ← 加上这一行(关键)
name: remote-dind
修改前后的对比示例,修改前(大概长这样):
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t...
server: https://10.96.0.1:6443
修改后(应该变成这样):
- cluster:
server: https://192.168.1.7:6443
insecure-skip-tls-verify: true
不需要修改 client-certificate-data 和 client-key-data 这两行,保留原来的内容就可以。
3.5环境生效与测试
在 Mac 环境中挂载配置并验证:
export KUBECONFIG=~/.kube/configs/remote-dind.yaml
kubectl get nodes
(为了后续操作更方便,建议将 export KUBECONFIG=... 写入 ~/.zshrc 实现永久生效。)
echo 'export KUBECONFIG=~/.kube/configs/remote-dind.yaml' >> ~/.zshrc
source ~/.zshrc
4安装 Traffic Manager
Telepresence 需要在 K8s 集群侧安装一个流量管理器。在 Mac 上执行以下命令(会自动通过 kubeconfig 部署到集群):
# 1. 尝试卸载可能存在的历史遗留
telepresence uninstall --everything 2>/dev/null || true
# 2. 安装到 ambassador 命名空间 (官方推荐环境隔离做法)
telepresence helm install --namespace ambassador
成功后会提示:Traffic Manager installed successfully。
解释:
telepresence helm install:在你的 K8s 集群中安装 Telepresence 的核心组件(Traffic Manager)。--namespace ambassador:把组件安装到ambassador这个 namespace。ambassador不是固定的,只是官方推荐的名称(因为 Telepresence 以前属于 Ambassador 公司)。- 你也可以改成
telepresence或default,但推荐使用ambassador。
5连接集群
使用标准命令建立从 Mac 到 K8s 的隧道连接:
telepresence connect --manager-namespace ambassador
成功后会提示已连接到相应的 context 和 namespace。
6部署 Go 空服务(占位锚点)
为了让 Telepresence 有目标可以注入 Envoy 代理,我们需要在 K8s 中部署一个轻量级的“占位”应用。针对国内网络环境,推荐使用华为云 SWR 的 Nginx 镜像。
创建 go-k8s-app.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-k8s-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: go-k8s-app
template:
metadata:
labels:
app: go-k8s-app
spec:
containers:
- name: go-k8s-app
# 华为云 SWR 公开加速节点,秒拉官方 nginx:alpine
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:alpine
ports:
- containerPort: 80 # Nginx 的真实监听端口
name: http
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: go-k8s-app
namespace: default
spec:
type: ClusterIP
selector:
app: go-k8s-app
ports:
- port: 8080 # 前台分机号:集群内部其它服务访问本服务所使用的端口
targetPort: http
name: http
部署:
确保在包含 go-k8s-app.yaml 文件的本地Mac目录下执行 apply:
kubectl apply -f go-k8s-app.yaml --validate=false
或者使用下面这种方式:
# 使用下面这条命令部署(加上 --kubeconfig 参数最稳)
kubectl apply -f go-k8s-app.yaml --kubeconfig=/Users/$(whoami)/.kube/configs/remote-dind.yaml --validate=false
--validate=false表示关闭验证。
查看部署结果:
在Mac上执行:
kubectl get pods
kubectl get svc go-k8s-app
kubectl get pods -l app=go-k8s-app
预期结果会看到一个 Pod 正在运行(初始是 nginx),和一个 Service。输出结果示例:
➜ kubectl get pods
NAME READY STATUS RESTARTS AGE
go-k8s-app-854f9d975b-cq792 1/1 Running 0 17s
➜ kubectl get svc go-k8s-app
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
go-k8s-app ClusterIP 10.104.98.192 <none> 8080/TCP 33s
➜ kubectl get pods -l app=go-k8s-app
NAME READY STATUS RESTARTS AGE
go-k8s-app-854f9d975b-cq792 1/1 Running 0 37s
7执行流量拦截 (Intercept)
确认服务就绪后,执行流量劫持。假设你本地(Mac)的 Go 服务监听在 4306 端口:
标准的两段式拦截流程(推荐):
# 1. 显式连接(消除隐式连接警告,如果上面执行过这里则不用重复执行)
telepresence connect --manager-namespace ambassador
# 2. 执行纯净拦截,禁用文件挂载(消除 Error 报错)
# 语法结构:telepresence intercept <服务名> --port <本地项目端口>:<集群Service对内暴露的端口> --mount=false
telepresence intercept go-k8s-app --port 4306:8080 --mount=false
拦截成功后:
- 在 IDE (GoLand/VSCode) 中启动监听在
4306的 Go 项目。 - K8s 集群内发往
go-k8s-app:8080的请求,将在 Service 层被拦截,并直接路由到你本机监听4306的代码中。
端口调整提示:如果你的本地代码改为了其他端口(例如
8080),只需先退出当前拦截 (telepresence leave go-k8s-app),再重新执行拦截命令即可:telepresence intercept go-k8s-app --port 8080:8080。全程不需要修改 YAML 文件内容。
异常排障补充:
如果之前连接过可能出现connector.CreateIntercept: name resolver error: Unauthorized问题,可以采用彻底杀掉本地幽灵进程方式,让 Telepresence 把本地残余的网络代理和缓存全部清空:
# 断开当前连接
telepresence quit
# 强制杀掉所有后台 Daemon 进程
telepresence quit -s
# 重新建立纯净连接并拦截
telepresence connect --manager-namespace ambassador
telepresence intercept go-k8s-app --port 4306:8080 --mount=false
⚠️ 避坑警告:如果执行拦截时曾出现
Volume Mount Error: remote volume mounts are disabled: sshfs is not installed on your local machine,强烈建议不要尝试安装 macFUSE 和 sshfs。在 Apple Silicon (M系列芯片) 的 Mac 上,这会触发系统底层的内核安全机制,需要降低系统安全级别,并极易引发无限弹出System Extension Blocked的死循环。 解决方案:直接在intercept命令尾部加上--mount=false即可完美消除报错,保持系统安全且不影响任何网络调试功能。
8运维、重置与清理(排障核心)
在反复测试或遇到诸如 Unauthorized、already exists 等幽灵状态报错时,必须使用以下手段彻底净化环境。
8.1强刷 K8s 资源状态
如果你修改了 YAML 文件但 Kubernetes 提示 unchanged,或 Pod 卡在错误状态,直接强制重置:
kubectl replace --force -f go-k8s-app.yaml
8.2终极清理脚本(解决各类本地幽灵状态)
保存为 cleanup-telepresence.sh。此脚本加入了云端登出与强杀进程机制,能彻底解决同一个环境反复测试导致的缓存冲突。
#!/bin/bash
echo "=== 开始终极清理 Telepresence 状态 ==="
# 1. 退出云端登录(彻底解决 Unauthorized 报错)
echo "[1/4] 清除云端认证缓存..."
telepresence logout 2>/dev/null || true
# 2. 释放拦截并强制断开守护进程
echo "[2/4] 断开连接并强杀后台守护进程..."
telepresence leave --all 2>/dev/null || true
telepresence quit -s 2>/dev/null || true
# 兜底:强杀所有残存的僵尸进程
killall telepresence 2>/dev/null || true
# 3. 卸载集群侧组件
echo "[3/4] 卸载 K8s 集群内的 Traffic Manager..."
telepresence helm uninstall --namespace ambassador 2>/dev/null || true
telepresence uninstall -a 2>/dev/null || true
# 4. 清理占位资源
echo "[4/4] 清理 K8s 业务测试资源..."
kubectl delete deployment go-k8s-app --force --grace-period=0 2>/dev/null || true
kubectl delete service go-k8s-app --force --grace-period=0 2>/dev/null || true
echo "清理完成!您的环境已回归绝对纯净状态。"
8.3深度环境物理抹除(核弹级重置)
如果执行了清理脚本后依然存在诡异网络问题,请执行以下物理抹除命令,销毁 Mac 本地的所有持久化缓存和日志:
# 1. 强制删除整个控制面命名空间
kubectl delete namespace ambassador --force --grace-period=0 2>/dev/null || true
# 2. 抹除 Mac 本地的状态配置、缓存和日志
rm -rf ~/Library/Application\ Support/telepresence
rm -rf ~/Library/Logs/telepresence
rm -rf ~/.cache/telepresence
echo "本地物理缓存与日志已全数抹除。"
9常用命令速查备忘
# 建立纯净连接
telepresence connect --manager-namespace ambassador
# 查看当前连接状态与可拦截的工作负载
telepresence status
telepresence list
# 执行拦截 (本地应用端口 : 远端Service暴露端口),并禁用挂载引擎
telepresence intercept <service-name> --port 4306:8080 --mount=false
# 取消特定拦截
telepresence leave <service-name>
# 优雅断开本地隧道连接
telepresence quit