使用 Telepresence 在本地调试 Kubernetes 微服务

作者:喵叔

原文: blog.betacat.io/post/develo…

微服务作为一种全新的软件架构现在正变得越来越火。基本原因我觉得有两点:一方面软件系统越做越复杂,通过拆分将一个大系统解耦成一个个独立的子系统,我们就降低了整个系统的复杂性。另一方面,Kubernetes 的出现使得编排这么多子系统变得简单,可以说 Kubernetes 是目前为止微服务最好的载体。

Kubernetes 解决了微服务运行时的环境问题,但对开发环境就不那么友好了。比方说如果我们要在本地开发调试一个服务A,但服务A可能依赖服务B、C,而服务B又有一层依赖D,我们就需要在本地把服务B、C、D都搭建起来才能调试服务A。这显然是一个很痛苦的过程。

使用 Telepresence 在本地调试 Kubernetes 微服务

业界有朋友用 docker-compose 来模拟集群中的场景。这个方案的不足之处在于它需要把 Kubernetes 的那一套逻辑用 docker-compose.yml 文件重写一遍,这给我们带来了维护成本。另一方面,有的时候依赖树太大,本地机器完全无法同时运行这么多服务。

ratesvc:
  image: kubeapps/ratesvc:latest
  environment:
    - JWT_KEY=secret  # <------------------------ 手工维护
  command:
    - /ratesvc
    - --mongo-url=mongodb://root@mongodb  # <---- 手工维护
    - --mongo-database=ratesvc

mongodb:
  image: bitnami/mongodb:3
  environment:
    - MONGODB_ROOT_PASSWORD=password123

auth:
  image: kubeapps/oauth2-bitnami:latest
  volumes:
    - ./config.yaml:/config/monocular.yaml  # <-- 手工维护
  ...

volumnes:  # <----------------------------------- 手工维护
  monocular-data:
复制代码

另一种解决方案就是我这里要介绍的 Telepresence 了,它能够在不修改程序代码的情况下,让本地应用程序无感的接入到 Kubernetes 集群中,这样你就可以直接在本地开发调试微服务了。

简介

Telepresence 是一个 CNCF基金会下的项目。它的工作原理是在本地和 Kubernetes 集群中搭建一个透明的双向代理,这使得我们可以在本地用熟悉的 IDE 和调试工具来运行一个微服务,同时该服务还可以无缝的与 Kubernetes 集群中的其他服务进行交互,好像它就运行在这个集群中一样。

这是一个 Telepresence 工作原理图,它将集群中的数据卷、环境变量、网络都代理到了本地(除了数据卷外,其他两个对应用程序来说都是透明的):

使用 Telepresence 在本地调试 Kubernetes 微服务

有了这些代理之后:

  1. 本地的服务就可以完整的访问到远程集群中的其他服务
  2. 本地的服务直接访问到 Kubernetes 里的各种资源,包括环境变量、secrets、config map
  3. 甚至集群中的服务还能直接访问到本地暴露出来的接口

安装

macOS:

brew cask install osxfuse  # required by sshfs to mount the pod's filesystem
brew install datawire/blackbird/telepresence
复制代码

其他平台请参考: www.telepresence.io/reference/i…

如果官方的安装包没有覆盖到你的平台,其实也可以从源代码安装,因为它本身就是用 Python3 写的,熟悉 Python 的朋友安装这个程序应该不难,我自己就在 CentOS 7 上安装成功了。

使用场景

假设我们有两个服务 A 和 B,服务 A 是依赖于服务 B 的。下面分两个场景来看看如何用 Telepresence 来调试 A 和 B。

使用 Telepresence 在本地调试 Kubernetes 微服务

调试服务 A

服务 A 在本地运行,服务 B 运行在远端集群中。借助 Telepresence 搭建的代理,A 就能直接访问到 B。比方说我们的服务 B 是这样一个程序,它监听在8000端口上。每当有人访问时它就返回 Hello, world!

$ kubectl run service-b --image=datawire/hello-world --port=8000 --expose
$ kubectl get service service-b
NAME        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
service-b   10.0.0.12    <none>        8000/TCP   1m
复制代码

现在在本地用默认参数启动 Telepresence ,等它连接好集群:

$ telepresence
T: Starting proxy with method 'vpn-tcp', which has the following limitations: All processes are affected, only one telepresence can run per machine, and you
T: can't use other VPNs. You may need to add cloud hosts and headless services with --also-proxy. For a full list of method limitations see
T: https://telepresence.io/reference/methods.html
T: Volumes are rooted at $TELEPRESENCE_ROOT. See https://telepresence.io/howto/volumes.html for details.
T: Starting network proxy to cluster using new Deployment telepresence-1566230249-7112632-14485

T: No traffic is being forwarded from the remote Deployment to your local machine. You can use the --expose option to specify which ports you want to
T: forward.

T: Setup complete. Launching your command.
@test_cluster|bash-4.2#
复制代码

这时候就可以开始调试服务 A 了,因为服务 B 暴露出来的接口本地已经可以直接访问到:

$ curl http://service-b:8000/
Hello, world!
复制代码

这里要说明一下这背后发生的事情:

  1. 当运行 Telepresence 命令的时候,它创建了一个 Deployment ,这个 Deployment 又创建了一个用来做代理的 Pod ,我们可以这样查看到它 kubectl get pod -l telepresence
  2. 同时它还在本地创建了一个全局的 VPN,使得本地的所有程序都可以访问到集群中的服务。 Telepresence 其实还支持其他的网络代理模式(使用 --method 切换), vpn-tcp 是默认的方式,其他的好像用处不大, inject-tcp 甚至要在后续的版本中取消掉。
  3. 当本地的 curl 访问 http://service-b:8000/ 时,对应的 DNS 查询和 HTTP 请求都被 VPN 路由到集群中刚刚创建的 Pod 去处理。

除此之外 Telepresence 还将远端的文件系统通过 sshfs 挂载到本地 $TELEPRESENCE_ROOT 下面(你也可以用参数 --mount <MOUNT_PATH> 指定挂载的路径)。这样,我们的应用程序就可以在本地访问到远程的文件系统:

$ ls $TELEPRESENCE_ROOT/var/run/secrets/kubernetes.io/serviceaccount
ca.crt  namespace  token
复制代码

如果我们退出 Telepresence 对应的 Shell,它也会做一些清理工作,比如取消本地 VPN、删除刚刚创建的 Deployment 等。

调试服务 B

服务 B 与刚才的不同之处在于,它是被别人访问的,要调试它,首先得要有真实的访问流量。我们如何才能做到将别人对它的访问路由到本地来,从而实现在本地捕捉到集群中的流量呢?

Telepresence 提供这样一个参数, --swap-deployment <DEPLOYMENT_NAME[:CONTAINER]> ,用来将集群中的一个 Deployment 替换为本地的服务。对于上面的 service-b ,我们可以这样替换:

$ telepresence --swap-deployment service-b --expose 8000:8000
复制代码

这个时候集群中的服务 A 再想访问服务 B 的8000端口时,Telepresence 就会将这个请求转发到本地的8000端口。它的工作原理就是将集群中的 service-b 替换为 Telepresence 创建的 proxy ,然后这个 proxy 再将请求转发到本地客户端。

即,将原始的网络:

使用 Telepresence 在本地调试 Kubernetes 微服务

替换为这个结构:

这样我们就有机会在本地查看具体的请求数据,调试逻辑,以及生成新的回复。

原文 

https://juejin.im/post/5d6a85566fb9a06b2a20564c

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 使用 Telepresence 在本地调试 Kubernetes 微服务

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址