千家信息网

Telepresence:让微服务本地开发不再难

发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,导读云原生的概念越来越深入人心,作为典型技术之一的微服务架构,过去我们还说它是一把双刃剑,带来一定好处的同时,对服务团队的技术要求也提高了很多。但是,随着开源技术的不断发展,越来越多优秀的技术和工具涌
千家信息网最后更新 2025年12月03日Telepresence:让微服务本地开发不再难

导读

云原生的概念越来越深入人心,作为典型技术之一的微服务架构,过去我们还说它是一把双刃剑,带来一定好处的同时,对服务团队的技术要求也提高了很多。但是,随着开源技术的不断发展,越来越多优秀的技术和工具涌现出来,让云原生落地不再困难。为此,博云研究院后续将不定期的总结整理云原生相关的开发、测试、运维等方面的最佳实践,借助博云和开源社区共同的力量,帮助客户更加标准化、简单化开启云原生之路。

背景

基于Spring Boot框架开发微服务,并部署在Kubernetes集群中,是现在很多企业的实施微服务的技术选型。微服务架构下,开发人员主要关注于所在服务团队维护的微服务,通常情况下这些微服务依赖于其它团队开发的微服务,同时也被另外一组微服务所依赖。

在微服务开发过程中,一种传统的做法是通过单元测试对代码进行验证,尽可能早的发现问题,待相关服务开发基本完成以后,统一部署到Kubernetes集群中进行联调。这种方式下,一方面是开发人员花大量的时间设计测试用例,编写测试代码,还要为每个依赖的服务打桩;另一方面,由于集成的时间点比较晚,大量接口不一致导致的问题可能会在集成测试的过程中集中爆发,造成人力物力的浪费。

如果将服务尽早的部署到Kubernetes测试环境中进行联调测试,可以提前发现问题。由于部署的过程在开发过程中需要反复执行,所以很多企业搭建了CICD工具,比较常见的流程是:提交代码 -> Jenkins 拉取源码 -> Maven编译 -> Docker镜像构建 -> 部署 -> 测试。虽然该过程可以自动完成,但是每次调试均需要经历该步骤,耗时比较长,效率很低。同时,Kubernetes集群内部的微服务的特点是,各微服务之间在集群内可以互相访问,集群外部没有很好的方法来获取集群内部的功能,比如读写数据库中的数据等,所以观察服务的运行结果也是比较困难的事情,无法提供像单体应用一样本地单步调试的体验。

Telepresence是一款为Kubernetes微服务框架提供快速本地化开发功能的开源软件。Telepresence在Kubernetes集群中运行的Pod中部署双向网络代理,该Pod将Kubernetes环境(如TCP连接,环境变量,卷)中的数据代理到本地进程。本地进程透明地覆盖其网络,以便DNS调用和TCP连接通过代理路由到远程Kubernetes集群,能够获取远端K8S集群的各项资源。该工具可以实现:

  • 本地服务可以完全访问远程群集中的其他服务;
  • 本地服务可以完全访问Kubernetes的环境变量,Secrets和ConfigMap;
  • K8S中运行的远程服务也可以完全访问本地服务。

实践

1.安装kubectl命令行工具,并配置本地可以访问Kubernetes集群。

  1. 安装Telepresence工具

在OS X中可使用如下命令安装Telepresence工具。

# brew cask install osxfuse# brew install datawire/blackbird/telepresence
  1. 部署Demo微服务

在集成测试环境的Kubernetes集群中部署微服务。

# kubectl get allNAME                             READY   STATUS    RESTARTS   AGEdemo-backend-7bb6cf9994-9qnxp    1/1     Running   0          118sdemo-frontend-84b7f5c75f-8r69n   1/1     Running   0          40hNAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGEservice/demo-backend    ClusterIP   10.233.55.68            8080/TCP         40hservice/demo-frontend   NodePort    10.233.17.241           8081:30001/TCP   40hNAME                            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/demo-backend    1         1         1            1           40hdeployment.apps/demo-frontend   1         1         1            1           40hNAME                                       DESIRED   CURRENT   READY   AGEreplicaset.apps/demo-backend-7bb6cf9994    1         1         1       40hreplicaset.apps/demo-frontend-84b7f5c75f   1         1         1       40h

通过Kubernetes暴露的NodePort访问应用访问该应用,验证服务没有问题。

# curl http://10.20.1.71:30001/Message from backend is: Hello from demo-backend-7bb6cf9994-9qnxp 
  1. 通过Telepresence工具启动本地服务
# cd spring-cloud-kubernetes/demo-backend/# telepresence \    --mount /tmp/known \    --swap-deployment demo-backend \    --docker-run \    --rm \    -v $(pwd):/build \    -v $HOME/.m2/repository:/m2 \    -v=/tmp/known/var/run/secrets:/var/run/secrets \    -p 8080:8080 \    -p 5005:5005 \    maven:3.6-jdk-8-alpine \        mvn \            Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005" \            -Dmaven.repo.local=/m2 \            -f /build \            spring-boot:run

参数详细解析如下。

telepresence:启动telepresence的命令;

--mount /tmp/known:告诉Telepresence将TELEPRESENCE_ROOT挂载到本地的/tmp/known目录;

--swap-deployment foo:假设我们已在集群中运行名为foo的Deployment,下一步将使用本地运行的进程进行替换;

--docker-run:告诉Telepresence接下来以Docker容器方式运行;

--rm:告诉Docker终止时丢弃之前创建的容器,不会对本地造成混乱;

-v$(pwd):/build:将当前目录(pwd命令的结果)挂载到Docker容器内的文件夹/build中,这也是本地源代码的位置;

-v $HOME/.m2/repository:/m2:安装Maven缓存文件夹,这样我们就不必每次运行容器时都下载Maven组件;

-v=/tmp/known/var/run/secrets:/var/run/secrets:将上述的本地/tmp/known目录下的secrets目录挂载到本地容器的/var/run/secrets路径下,类似Fabric8 Kubernetes Client的工具可以通过该目录读取Secretes信息,就像容器是运行在Kubernetes内部一样;

-p 8080:8080 -p 5005:5005:将本地容器的服务端口暴露出来,可以在需要直接向服务发出请求时访问该端口;

maven:3.6-jdk-8-alpine:这是我们将用于构建和运行我们的服务的镜像,它包含了Maven和Java 8等工具;

mvn ... spring-boot:run:要在Docker容器中运行的命令。这里它使用Spring Boot Maven插件,但您可以使用构建工具所需的任何命令。它告诉maven指向已安装的存储库缓存以及源代码所在的位置

-Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005":表示为服务打开5005远程调试端口。在Telepresence的文档中是通过MAVEN_OPTS参数传递Debug配置,该配置实际上是对Maven进程开启Debug模式,并不是demo-backend应用,无法提供远程单步调试的能力。

-Dmaven.repo.local=/m2:表示本地Maven仓库的位置;

-f /build:Maven构建时的主目录,也即源代码的根目录;

spring-boot:run:spring-boot-maven-plugin插件发布的Goal,用于启动Spring Boot应用。

查看Kubernetes集群中的Pod信息。可以看到,之前的Pod demo-backend-7bb6cf9994-9qnxp已经被新的容器替换,使用的是Telepresence提供的镜像。

# kubectl get podNAME                                                             READY   STATUS    RESTARTS   AGEdemo-backend-c9df931b5c83411aad5a329ec9ecbcbb-5b4fdd7b-wzz9r     1/1     Running   0          11sdemo-frontend-84b7f5c75f-8r69n                                   1/1     Running   0          40h

查看本地Docker运行情况。

# docker psCONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS              PORTS                                                                        NAMESc7c10281a32c        maven:3.6-jdk-8-alpine             "/usr/local/bin/mvn-…"   35 seconds ago      Up 33 seconds                                                                                    telepresence-1555471863-056155-58429fd94d372f832        datawire/telepresence-local:0.98   "/sbin/tini -v -- py…"   44 seconds ago      Up 43 seconds       0.0.0.0:5005->5005/tcp, 0.0.0.0:8080->8080/tcp, 127.0.0.1:64163->38022/tcp   telepresence-1555471853-8663979-58429

确认本地开放了8080和5005端口。

# netstat -na | grep -E "5005|8080"tcp6       0      0  ::1.5005               *.*                    LISTENtcp4       0      0  *.5005                 *.*                    LISTENtcp6       0      0  ::1.8080               *.*                    LISTENtcp4       0      0  *.8080                 *.*                    LISTEN

直接通过8080端口访问本地的demo-backend服务。

# curl localhost:8080Hello from demo-backend-c9df931b5c83411aad5a329ec9ecbcbb-5b4fdd7b-wzz9r

通过Kubernetes暴露的NodePort访问应用,可以看到此时到demo-backend的请求已经被转发到本地运行的docker中。

# curl http://10.20.1.71:30001Message from backend is: Hello from demo-backend-80d454f85d8b43118f5740d9f25260ba-854fcd9fbd-lzkb7
  1. 通过IDE进行代码开发和单步调试
  • 启动IDEA,在上述源代码路径上打开工程。

  • 配置远程调试,连接本地5005端口。

  • 设置断点,并访问应用,在IDEA中可以进行单步调试。

  • 修改代码并保存,然后点击Build -> Build Project。

在demo-backend项目的pom文件中,配置了devtools的依赖。

            org.springframework.boot        spring-boot-devtools        true    

而当IntelliJ IDEA重新构建时,会更新该目录下的文件demo-backend/target/classes。通过mvn spring-boot:run方式启动应用时,Devtools监听的classpath,也即上述目录,当目录内的文件发生变化后,会启动restart,执行新的代码。

  .   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )  '  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::        (v2.1.3.RELEASE)11:17:44.328 [restartedMain] INFO  c.b.s.c.k.b.KubernetesBackendApplication - Starting KubernetesBackendApplication on Waret with PID 58351 (/Users/Waret87/WorkSpace/telepresence/spring-cloud-kubernetes/demo-backend/target/classes started by Waret87 in /Users/Waret87/WorkSpace/telepresence/spring-cloud-kubernetes/demo-backend)11:17:44.331 [restartedMain] INFO  c.b.s.c.k.b.KubernetesBackendApplication - No active profile set, falling back to default profiles: default...11:17:45.931 [restartedMain] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''11:17:45.934 [restartedMain] INFO  c.b.s.c.k.b.KubernetesBackendApplication - Started KubernetesBackendApplication in 1.873 seconds (JVM running for 2.282)11:20:35.483 [Thread-6] INFO  o.s.s.c.ThreadPoolTaskExecutor - Shutting down ExecutorService 'applicationTaskExecutor'  .   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )  '  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::        (v2.1.3.RELEASE)11:20:36.838 [restartedMain] INFO  c.b.s.c.k.b.KubernetesBackendApplication - Starting KubernetesBackendApplication on Waret with PID 58351 (/Users/Waret87/WorkSpace/telepresence/spring-cloud-kubernetes/demo-backend/target/classes started by Waret87 in /Users/Waret87/WorkSpace/telepresence/spring-cloud-kubernetes/demo-backend)11:20:36.838 [restartedMain] INFO  c.b.s.c.k.b.KubernetesBackendApplication - No active profile set, falling back to default profiles: default...11:20:37.272 [restartedMain] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''11:20:37.272 [restartedMain] INFO  c.b.s.c.k.b.KubernetesBackendApplication - Started KubernetesBackendApplication in 0.467 seconds (JVM running for 173.62)

再次访问服务,可以看到新的代码已经生效。

# curl http://10.20.1.71:30001Message from backend is: Hello World from demo-backend-c9df931b5c83411aad5a329ec9ecbcbb-5b4fdd7b-wzz9r

总结

通过上面的实践我们可以看到,Telepresence项目很好的解决了开发测试和部署上线之间的衔接问题,是对Kubernetes生态环境很好的补充。该项目已捐献给CNCF基金会,社区的文档也是比较完善的,更详细的原理和用法可参考文档。

本文由博云研究院原创发表,转载请注明出处。

服务 集群 运行 开发 工具 容器 目录 测试 应用 代码 命令 环境 端口 技术 文件 过程 问题 配置 源代码 进程 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 闻道网络安全工程师 文档数据库读写性能 嘉兴火猴网络技术 捷科网络技术 网络安全技术论文致谢女朋友 域名连接服务器ip查询 白嫖的服务器 小学网络安全教育班队会纪实 考勤机数据库如何导入管理系统 小型服装店用什么数据库 梅州一学校违反网络安全法 数据库查询数据的长度 数据库开发岗位缩写 网络安全在我身边的宣传知识 生死狙击2服务器几点开放 东财网络安全管理中心 软件开发人员发展趋势 软件开发二级等保是什么 清华同方数据库采用的什么分类法 数据库神器 海南高宇网络技术有限公司游戏是虚假宣传吗 软件开发企业内部组织架构 男生学软件开发一年要多少钱 考勤机数据库如何导入管理系统 达梦数据库日期传参转换错误 网络安全学会了去搞人家 服务器上的网络数据怎么清除 浏览器访问服务器程序需要密码吗 网络安全责任险的等待期 推广护苗网络安全
0