环境
Mac 本地 + 局域网 Ubuntu Server + Docker-in-Docker K8s:
- Mac(本地)
- Ubuntu Server(宿主机)
- Docker(在 Ubuntu 上)
- Docker 里面跑了多个 VM(vm-1, vm-2, vm-3 是 Ubuntu 虚拟机)
- K8s 集群实际跑在这些 VM 里面
Telepresence 可以让我们在本地运行 Go 程序,但让它“看起来”就像跑在 K8s 集群里一样,能访问集群内的 Service、ConfigMap、Database 等。
第一步:Mac 本地安装 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
或者在 Mac 上执行:
# 使用 brew 安装(推荐)
brew install telepresence
# 验证安装
telepresence version
第二步:配置 kubeconfig(最关键的一步)
步骤 1:在 Ubuntu 宿主机暴露 6443 端口(重要)
由于 vm-1 是 docker-compose 启动的容器,请修改 docker-compose.yml:
services:
vm-1: # 你的 master 节点
# ... 你的原有配置
ports:
- "6443:6443" # ← 增加这一行,把 vm-1 的 6443 暴露到宿主机
考虑到我的环境, Ubuntu 宿主机上没有 ~/.kube/config,kubeconfig 在 其中一个 VM(通常是 master 节点,如 vm-1)里面。
步骤 2:在 VM 中找到并复制 kubeconfig
先进入我的 K8s master VM(假设是 vm-1):
# 在 Ubuntu 宿主机上执行,进入 vm-1
docker exec -it vm-1 bash
进入 VM 后执行:
# 在 vm-1 容器内执行
cat ~/.kube/config
如果有内容,复制出来(推荐用下面方式直接复制到 Ubuntu 宿主机):
方式 A(推荐):从 VM 直接复制到 Ubuntu 宿主机
在 Ubuntu 宿主机 新开一个终端,执行:
# 把 vm-1 里的 kubeconfig 复制到 Ubuntu 宿主机
docker cp vm-1:/root/.kube/config ~/k8s-remote-config.yaml
方式 B:手动复制(如果 docker cp 不方便)
在 vm-1 里面:
cat ~/.kube/config
复制内容,然后在 Ubuntu 宿主机上:
cat > ~/k8s-remote-config.yaml << 'EOF'
# 把复制的内容粘贴在这里
EOF
步骤 3:把 config 复制到 Mac 并修改
在 Ubuntu 宿主机 执行:
# 把文件复制到你的 Mac
scp ~/k8s-remote-config.yaml youruser@你的Mac的IP:~/.kube/configs/remote-dind.yaml
或者在 Mac 上执行(更直接):
# 在 Mac 执行
mkdir -p ~/.kube/configs
scp youruser@192.168.x.x:~/k8s-remote-config.yaml ~/.kube/configs/remote-dind.yaml
# 如:
scp ubuntu@192.168.1.7:~/k8s-remote-config.yaml ~/.kube/configs/remote-dind.yaml
步骤 4:修改 kubeconfig 中的 server 地址
在 Mac 上编辑文件:
vim ~/.kube/configs/remote-dind.yaml
找到 server: 这一行,必须改成 Ubuntu Server 的局域网 IP:
server: https://192.168.x.x:6443 # ← 改成 Ubuntu Server 的 IP
(注意:因为 K8s API Server 暴露在 Ubuntu 宿主机上)
在 cluster: 下面添加一行 insecure-skip-tls-verify:
clusters:
- cluster:
server: https://192.168.1.7:6443
insecure-skip-tls-verify: true # ← 加上这一行(关键)
name: remote-dind
删除下面这一行(如果存在):
certificate-authority-data: xxxxxxxx(很长的一串)
修改前后的对比示例,修改前(大概长这样):
- 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 这两行,保留原来的内容就可以。
步骤 5:设置并测试
验证(在 Ubuntu 宿主机执行):
$ curl -k https://127.0.0.1:6443/version
{
"major": "1",
"minor": "35",
"emulationMajor": "1",
"emulationMinor": "35",
"minCompatibilityMajor": "1",
"minCompatibilityMinor": "34",
"gitVersion": "v1.35.0",
"gitCommit": "66452049f3d692768c39c797b21b793dce80314e",
"gitTreeState": "clean",
"buildDate": "2025-12-17T12:32:07Z",
"goVersion": "go1.25.5",
"compiler": "gc",
"platform": "linux/amd64"
}
如果返回 K8s 版本信息,则成功。
在 Mac 上执行:
export KUBECONFIG=~/.kube/configs/remote-dind.yaml
kubectl get nodes
NAME STATUS ROLES AGE VERSION
vm-1 Ready control-plane 60m v1.35.0
vm-2 Ready <none> 58m v1.35.0
vm-3 Ready <none> 57m v1.35.0
kubectl get pods -A
第三步:在 K8s 集群中安装 Traffic Manager
在 Mac 上执行(会通过 kubeconfig 自动部署到远程 K8s):
# 推荐方式
telepresence helm install
# OR
telepresence helm install --namespace ambassador
# 如果想安装到 default namespace(更简单):
telepresence helm install --namespace default
解释:
telepresence helm install:在你的 K8s 集群中安装 Telepresence 的核心组件(Traffic Manager)。--namespace ambassador:把组件安装到ambassador这个 namespace。ambassador不是固定的,只是官方推荐的名称(因为 Telepresence 以前属于 Ambassador 公司)。- 你也可以改成
telepresence或default,但推荐使用ambassador。
第四步:连接 Telepresence
# 基础连接
telepresence connect
# 推荐命令(适合你的 DinD 环境)
telepresence connect --docker --manager-namespace ambassador
成功后会显示类似:
Connected to context ...
Telepresence proxy: ON
第五步:使用 Telepresence测试拦截(Intercept)你的服务
# 查看当前集群中可以拦截的服务
telepresence list --docker
# 拦截你的 Golang 服务(把 go-app 替换成你 Deployment/Service 的名称)
telepresence intercept go-app --port 8080:8080 --docker
拦截成功后,你就可以:
- 在 Mac 本地用 GoLand / IDEA 直接运行或 Debug 你的 Go 项目(端口使用 8080)。
- 本地代码可以访问集群内的其他 Service、数据库等。
- 集群内的其他 Pod 也可以通过 Service 名称访问到你本地的代码。
完整常用命令
# 连接
telepresence connect --docker --manager-namespace ambassador
# 查看状态
telepresence status --docker
# 列出可拦截服务
telepresence list --docker
# 拦截服务
telepresence intercept <service-name> --port 8080:8080 --docker
# 取消拦截
telepresence leave go-app --docker
# 断开连接
telepresence quit --docker
常用命令总结
telepresence connect # 连接
telepresence intercept <service> --port 8080:8080 # 拦截
telepresence list # 查看可拦截服务
telepresence status # 查看状态
telepresence quit # 断开连接
telepresence uninstall --everything # 完全卸载(清理 Traffic Manager)
针对 Docker-in-Docker 的常见问题处理
网络问题:如果连接后无法解析 Service DNS,尝试:
telepresence connect --docker # 使用 Docker 模式的 daemon(有时更稳定)权限问题:确保远程 K8s 中的用户有足够权限(cluster-admin)。
端口冲突:Telepresence 默认会接管本地 DNS,如果冲突可以加参数:
telepresence connect --dns 8.8.8.8
请按顺序执行后,告诉我以下信息,我继续帮你排查:
kubectl get nodes的输出- 执行
telepresence helm install时的完整输出(尤其是是否有报错) telepresence connect的完整输出- 你的 K8s 是 kind、k3s、k3d 还是其他方式部署的?
把输出贴出来,我可以给你更针对性的修复命令。
SSH远程部署
- 文件同步
以 MacOS 版 IDEA 为例:点击 IDEA 的 [Settings] => [Build, Excution, Deployment] => [Development]:

- 输入服务器名称

- 填写服务器的基本信息如:ip,用户名以及密码

- 将本地的项目文件路径和远程服务器上的某一路径进行映射

真实环境:
- Mac(本地)
- Ubuntu Server(宿主机)
- Docker(在 Ubuntu 上)
- Docker 里面跑了多个 VM(vm-1, vm-2, vm-3 是 CentOS 虚拟机)
- K8s 集群实际跑在这些 VM 里面
所以 Ubuntu 宿主机上确实没有 ~/.kube/config,kubeconfig 应该在 其中一个 VM(通常是 master 节点,如 vm-1)里面。
第五步:安装并使用 Telepresence 在 Mac 上:
# 安装
brew install telepresence
# 安装 Traffic Manager(通过 Mac 安装到远程 K8s)
telepresence helm install --namespace ambassador
➜ telepresence helm install --namespace ambassador
Traffic Manager installed successfully
# 连接(强烈推荐 --docker 模式)
telepresence connect --docker --manager-namespace ambassador
➜ ~ telepresence connect --docker --manager-namespace ambassador
✔ Launched Daemon 21.0s
✔ Connected to context kubernetes-admin@kubernetes, namespace default (https://192.168.1.7:6443)
连接成功后:
# 查看服务
telepresence list
➜ ~ telepresence list
No Workloads (Deployments, StatefulSets, ReplicaSets, or Rollouts)
# 拦截你的 Go 服务(把 go-app 换成你的 Service 名称)
telepresence intercept go-app --port 8080:8080 --docker
然后在 Mac 的 GoLand / IDEA 中直接运行你的项目即可调试。
清理命令(需要时使用)
telepresence quit --docker
telepresence uninstall --everything
# 删除端口转发容器
docker rm -f k8s-api-forward
kubectl apply -f go-k8s-app.yaml --kubeconfig=/Users/$(whoami)/.kube/configs/remote-dind.yaml --validate=false
deployment.apps/go-k8s-app created
service/go-k8s-app created
echo $KUBECONFIG
kubectl config current-context
/Users/finnley/.kube/configs/remote-dind.yaml
kubernetes-admin@kubernetes
一键强制替换(最符合“销毁重建”语义)
kubectl replace --force -f go-k8s-app.yaml
方法二:先删后建(最稳妥的常规操作) 如果你想看清每一步,或者想等资源彻底清理干净再创建,可以分两步走:
- 销毁(根据文件定义删除):
kubectl delete -f go-k8s-app.yaml
重建(再次应用):
kubectl apply -f go-k8s-app.yaml
检查是否成功:
kubectl get pods
kubectl get svc go-k8s-app
步骤 2:用 Telepresence 拦截
# 1. 连接 Telepresence
telepresence connect --docker --manager-namespace ambassador
# 2. 拦截(把本地 8080 端口映射到集群的 go-k8s-app 服务)
telepresence intercept go-k8s-app --port 8080:8080 --docker
成功后,你会看到提示说拦截成功。
步骤 3:在本地 Mac 运行你的 Go 项目 现在在 GoLand / IDEA 中直接运行你的 Go 项目,监听端口 8080。 此时:
你本地运行的 Go 代码 = 集群中的 go-app 服务 集群内其他服务可以通过 go-app:8080 访问到你本地的代码 你本地代码也可以通过 Service 名称访问集群内的其他服务(如数据库)
常见问题解答
go-app 是什么? 它是你给这个服务的名字,你可以改成 my-go-service、just-do-it 等,只要前后一致即可。 端口 8080:8080 是什么意思? 左边的 8080:本地 Mac 的端口 右边的 8080:K8s Pod/Service 的端口
我不想先部署 nginx 占位,有没有更简单的方法? 有,但第一次使用推荐上面这种方式,更稳定。
**✅ 问题已定位**。
虽然 Pod 已经 Running,但 **Telepresence 无法识别 Deployment 中的端口**。这是 Telepresence 比较常见的严格匹配问题。
---
### **最终修复方案(请严格按顺序执行)**
#### 1. 修改 `go-k8s-app.yaml`(加上端口名称)
请**完整替换**为以下内容:
```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
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http # ← 必须加上 name
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
2.重新部署
# 清理旧的
kubectl delete deployment go-k8s-app --force --grace-period=0
# 重新部署
kubectl apply -f go-k8s-app.yaml
3.验证 Deployment 端口配置
kubectl get deployment go-k8s-app -o yaml | grep -A 10 "ports:"
4.执行 Telepresence 拦截(使用端口名称)
telepresence quit --docker 2>/dev/null || true
telepresence connect --docker --manager-namespace ambassador
# 关键命令:使用端口名称
telepresence intercept go-k8s-app --port 8080:http --docker
请现在执行上面 1~4 步,然后把以下输出贴给我:
kubectl get pods -l app=go-k8s-app的输出telepresence intercept go-k8s-app --port 8080:http --docker的完整输出
额外说明:
- 你的本地 Go 服务需要监听 8080 端口(左边的数字是本地端口)。
- 如果你本地想用 4311 端口,就用
--port 4311:http
我们这次应该能成功。把输出发给我。
清理
1. 先清理旧的 Deployment/Service(重要)
# 1. 清理旧资源
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
# 2. 部署新资源
kubectl apply -f go-k8s-app.yaml
# 3. 等待 Pod 就绪
kubectl get pods -l app=go-k8s-app -w
# 4. Telepresence
telepresence connect --docker --manager-namespace ambassador
telepresence intercept go-k8s-app --port 8080:80 --docker
部署:
kubectl apply -f go-k8s-app.yaml
检查是否正常:
kubectl get pods -l app=go-k8s-app
kubectl get svc go-k8s-app
3.Telepresence 操作
# 重新连接(保险起见)
telepresence quit --docker 2>/dev/null || true
telepresence connect --docker --manager-namespace ambassador
# 拦截服务(关键:端口映射要正确)
telepresence intercept go-k8s-app --port 8080:80 --docker
解释端口映射:
8080:80= 本地 Mac 端口 8080 : K8s 容器端口 80
4.在 Mac 本地启动你的 Go 服务
重要:现在在 GoLand / IDEA 中启动你的 Go 项目:
- 把你的 Go 服务监听端口改为 8080(推荐),或者改成其他端口(如 3000),然后对应修改上面的
--port 3000:80
启动后,在浏览器访问 http://localhost:8080 测试是否正常。
请按顺序执行上面流程,然后告诉我以下结果:
kubectl get pods -l app=go-k8s-app的输出telepresence intercept ...的完整输出
有任何错误请直接贴出来,我马上调整。