1. 背景介绍
微服务项目的本地开发,比以往单体项目的本地开发有更多的限制。举几个典型例子:
- 本地开发服务 A,可能依赖的一些中间件资源对本机网络不可见(比如 集群中的 mysql,现在是通过集群ip + 端口映射才能访问,并不能像集群中运行的代码那样通过集群内的服务名,或者内网 ip 直接访问)
- 服务 A 依赖服务 B、C、D,后者已经在测试环境存在,本地运行服务 A 时,无法访问到集群内的其他服务(可能内部服务的端口并未打到外面,可能内部服务的 ip 不固定)
- 其他服务 B、C、D 要访问服务 A,现在想对服务A做本地开发或者调试,希望调用本地的代码执行
综上,微服务项目的本地开发,需要解决两个问题:1. 如何让本地代码访问到集群内的资源,2. 如何让集群内的服务访问到我本地运行的代码。
Telepresence 是一个能够解决微服务项目本地化运行和开发的工具,能够完成送进去 和 打出来的目标,方便操作。
2. Telepresence 的具体使用
2.1 安装 kubectl
Telepresence
底层是通过 kubectl
来跟集群通信的,需确保本地有 kubectl
命令、能够访问到目标集群,并且有必要的权限。
可以直接安装 kubectl
,或者 docker-desktop
里面会自带该命令
bash
# 验证是否已有 kubectl 命令
kubectl version
# 安装 kubectl
brew install kubectl
# 或者安装 docker-for-mac-desktop,里面会包含该命令
brew install docker-desktop
2.2 准备一个 k8s 集群
本文以 docker-desktop
自带的 kubernetes 功能来创建 k8s 集群做演示,也可使用自己已有的 k8s 集群。
在 docker-desktop 中创建 k8s 集群,等待几秒重启:
2.3 配置 kubectl,准备测试资源
配置 kubectl
通过 docker-desktop
启动的 k8s 集群,docker 会自动创建 kubectl
使用的 ~/.kube/config
文件(如果该文件已存在,docker 也会将本地集群的配置与原有配置文件合并)。
如果是已有的其他集群(比如云服务商提供的集群服务,或者其他自建的集群),可以在相应的管理控制面板或者找管理员索要 kubeconfig
文件。将新的 kubeconfig
文件保存为 ~/.kube/config
(如果该文件存在,需要进行配置文件合并,已保留访问多个集群的能力)。如果是已有集群,确保你有足够的权限。
合并多个 kubeconfig
文件:
bash
# 备份旧文件
mv ~/.kube/config ~/.kube/config-back
# 使用 KUBECONFIG 声明读取两个 config 文件,最终用 kubectl 格式化输出为新文件
KUBECONFIG=~/.kube/config-back:/path/to/your/new/kubeconfig kubectl config view --flatten > ~/.kube/config
验证集群的连接
bash
# 查看当前可连接到的集群
kubectl config get-clusters
# 查看当前链接的集群
kubectl config current-context
# 切换集群
# kubectl config use-context xxxxx
# 查看 namespace 列表
kubectl get namespaces
# 指定 namespace,查看 pod 列表
kubectl get pods --namespace default
准备测试资源
在集群内,创建一个 nginx
节点,下文会验证连接到集群内能访问到该节点,以及能拦截该节点的流量到本地
bash
# 在集群创建一个 nginx 的节点,namespace 默认为 default
kubectl create deployment nginx --image=nginx --name=nginx-test
# 查看 pod
kubectl get pods
# 查看 pod 并获得内网 ip
kubectl get pod -o wide
# 创建 svc,方便后续使用集群内的域名测试。不需要打到集群外可见
kubectl expose deployment nginx --port=80
在本地再起一个其他 web 服务,方便后文验证将前一步的 nginx
流量拦截到本地:
bash
# 有很多办法在本地启动可以测试的 web 服务,视你自己的情况决定(但注意新开 console,不要关闭,后文要用)
# 使用 python 启动 web 服务
python3 -m http.server 8080
# 使用 node 启动 web 服务
npx http-server -p 8080
# 使用 php 启动 web 服务
php -S 0.0.0.0:8080
2.4 安装和配置 Telepresence
安装 Telepresence
mac 推荐使用 brew
。其他平台或其他安装方式,详见官网 telepresence.io/docs/instal...。
bash
brew install telepresenceio/telepresence/telepresence-oss
安装代理
Telepresence
的原理,简单的说:在目标集群里安装一个代理,让你的机器连接这个代理,从而实现把你的流量送到集群里,以及把集群的某些流量拦截送给你。代理只需要安装一次,后续不需要再执行
安装代理:
bash
# 需要有必要的权限,如果提示权限不足,按照输出提示去解决
# 会安装到默认的 namespace
telepresence helm install
# 安装到指定的 namespace(安到哪里,后面连接的时候就连到哪里)
telepresence helm install --namespace xxx
2.5 使用 Telepresence
连接到集群
需要连接到前一步安装代理的 namespace,确保有必要的权限
bash
# 默认连接到 default namespace
telepresence connect
# 指定 manager-namespace,指定要连接的目标 namespace
telepresence connect --manager-namespace xxx --namespace xxxx
注意输出,需要输一次本机的密码(Telepresence
在本地也要做一些网络更改,才能把流量送到集群。虽然他的运行模式像个 vpn,但其实并未真实连接一个 vpn 软件,而是通过更底层的网卡劫持流量)。大概十来秒,输出成功信息。
可以访问集群中的一个内网资源,验证链接成功,不需要把集群内的项目打端口出来,本地也无需做 dns 解析:
bash
curl 10.1.0.102 # 通过 kubectl get pod -o wide 可以拿到内网 ip
curl nginx
curl nginx.default
curl nginx.default.svc
curl nginx.default.svc.cluster.local
这些内网的服务名或者域名都可以在本机访问成功,可以证明 connect 之后,已经能访问到内网的资源。此时再启动依赖其他内网服务的微服务项目,也能正常运行,不再展示,自行操作。
拦截集群中的某个服务到本地
要先使用 connect
连接到集群的某个命名空间,然后可以拦截其中的一个服务到本地
bash
# 服务名可以替换
# 使用本地的 8080 代理该 deployment 容器里的第一个暴漏端口
telepresence intercept nginx -p 8080
# 或者显示指明
telepresence intercept nginx -p 8080:80
# 测试拦截效果
curl nginx
# 能看到不在是 nginx 的输出,而是之前启动的运行在的 8080 web 服务
退出
不管是加入到集群,还是拦截了某个服务,都可以通过 quit
来退出
bash
# 彻底退出(能停止拦截)
telepresence quit
一些必要的其他命令
bash
# 查看连接状态
telepresence status
# 展示已有的拦截器
telepresence list
# 离开某个拦截器
telepresence leave xxx
# 彻底退出(能停止拦截)
telepresence quit
3. 总结
Telepresence
使用简单,一次配置之后,只需要两句命令完成加入 集群 和 拦截服务,大大提高本地开发微服务项目的便利。
Telepresence
共有四种模式,自行探索和使用:
intercept
:拦截流量,pod 本身还在,里面运行的其他后台进程还都在replace
:替换,彻底替换掉 podwrietap
:窃听,可以观察入口和出口流量ingest
:把 pod 的环境搬到本地,不拦截流量