默认情况下 Kubernetes 内部的 pod ip 、svc ip 无法被集群外用户访问,外部访问集群内部的解决方案主要有两种,分别为 ingress 转发和通过 NodePort 暴露端口,但是这两种方式需要配置大量规则不利于集群维护。现在介绍第三种方式,通过本地调试工具 Telepresence 实现。

Telepresence 简介

是一种更契合远程调试部署在 k8s 中的业务的方式,它能够在不修改程序代码的情况下实现集群双向代理,可以实现本地开发环境到集群内部的代理,同时也可以拦截集群内部的流量到本地开发环境,让本地应用程序无感的接入到集群中,这样就可以直接在本地开发调试。

Telepresence 架构

  • Telepresence CLItelepresence 客户端,负责启动 telepresence 守护进程,作为 Ambassador Cloud 的登录验证入口。

  • Telepresence Daemons:运行在开发人员工作站上的守护进程,充当与集群网络的主要通信点,以便与集群通信并处理拦截的流量,由 User Daemon 和 Root Daemon 组成

    • User Daemon:用户守护进程通过与集群中的 Traffic Manager 通信来协调 Intercept 的创建和删除。所有来自和访问集群的请求都要经过这个 Daemon。

    • Root Daemon:根守护进程通过设置虚拟网络设备(VIF,tun 设备)来管理本地工作站和集群之间通信所需的网络。

  • Traffic Manager:流量管理器是部署在远端集群中的流量代理,与开发人员工作站上 telepresence 守护进程之间通信的中心点。它负责将 Traffic Agent 边车容器注入被拦截的应用负载的 Pod 中,代理所有相关的入站和出站流量,并跟踪活动拦截。

      当使用 Preview URL 创建拦截时,流量管理器将与 Ambassador Cloud 建立连接,使 Preview URL 的请求可以路由到集群。这允许大使云访问流量管理器,而不需要将流量管理器对外公开。一旦流量管理器接收到来自Preview URL 的请求,它将请求转发到创建 Preview URL 时指定的入口服务。

  • Traffic Agent:流量代理,当一个拦截被创建时,流量代理作为边车容器注入被拦截的负载的 Pod 中,流量代理将拦截传入的请求并路由到 Traffic Manager,以便将其路由到开发人员的工作站。

  • Ambassador Cloud:通过 telepresence login 命令可以打开浏览器进入界面(需要有桌面版支持,由于外站无法访问,暂怀疑是一个 dashboard)来管理临时 URL,当使用临时 URL 来创建 Intercept 时,Traffic Manager 将与 Ambassador Cloud 连接使这些 URL 能够路由到集群.

Telepresence 安装

Telepresence 工具依赖 kubectl,需先在本地开发环境安装 kubectl

  1. 在本地开发环境下载 Kubectl

    # 1.下载 kubectl 二进制文件
    curl -LO https://dl.k8s.io/release/v1.21.6/bin/linux/amd64/kubectl
    # 2.下载验证文件
    curl -LO "https://dl.k8s.io/v1.21.6/bin/linux/amd64/kubectl.sha256"
    # 3.验证下载的 kubectl 二进制文件
    echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check
    # 4.如果输出为 成功 则验证完成
    kubectl: 成功
    # 5.安装 kubectl
    sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
  2. Kubectl 访问集群还需要 kubeconfig 文件(就是集群的 config)

    # 从集群的 ~/.kube/ 目录下拷贝 config 文件到本地开发环境
  3. 在本地开发环境安装 Telepresence CLI

    # 1.下载二进制文件 (约 50 MB):
    sudo curl -fL https://app.getambassador.io/download/tel2/linux/amd64/latest/telepresence -o /usr/local/bin/telepresence
    # 2.修改文件为可执行文件
    sudo chmod a+x /usr/local/bin/telepresence
  4. 在远端集群中安装 Telepresence Traffic Manager

      第3步中安装的 Telepresence CLI 内部自带 helm,可在本地环境调用以下命令实现在远端安装

     telepresence helm install

Telepresence 使用

假设有两个应用 A 和 B,A 需要调用 B,当两个应用都部署在集群中时,可以很容易的实现通过 Service 互相访问

但是当面对如下两个场景,如何在改动较小的情况下实现 A 到 B 的访问呢,Telepresence 就可以解决这个问题:

  1. 场景一:A 在本地开发环境部署,需要访问集群中部署好的服务 B

  2. 场景二:A 在远端集群环境部署,需要访问部署在本地环境中的 B

将本地开发环境连接到远端集群

可以通过下面的命令来连接或取消连接到集群环境

# 连接集群
telepresence connect
# 取消连接
telepresence quit

查看连接状态

telepresence status

本地开发环境访问集群内部服务

连接集群成功后,可通过 servicename.namespace:port 的方式访问集群内部的 service

curl -ik https://servicename.namespace:port

此时场景一的流量就变为如下的样子:

以本地开发环境Kubesphere 前端访问集群中的 ks-apiserver 为例

没有使用 telepresence 代理之前,无法解析地址:

使用 telepresence 代理之后,可以正常访问服务:

拦截集群内流量到本地开发环境

连接集群成功后,可通过 intecept 命令实现针对指定 service 的流量拦截

$ telepresence intercept <workload> --port <local-port>:<service port name> -n <namespace>
# workload 需要拦截的负载(如某个应用对应的 deployment name)
# local-port 将流量拦截到本地开发环境的目的端口
# service port name 服务端口名,如果为空则使用默认的服务端口
# namespace 服务所在的命名空间

此时场景二的流量就变为如下的样子:

以对 KubeSphere 的后端调试为例,下面的命令将集群中 kubesphere-system 命名空间下的 ks-apiserver deployment 对应的 9090 端口的服务拦截到了本地环境下

# 开始拦截请求
telepresence intercept ks-apiserver --port 9090 --namespace kubesphere-system
# 停止拦截请求
telepresence uninstall -n kubesphere-system -d ks-apiserver

Note:

如果出现报错 Volume Mount Error: sshfs is not installed on your local machine

使用 apt 命令安装 sshfs 即可

此时通过直接访问前端服务,登录请求被发往了本地环境

Telepresence 原理

对于用户来说, Telepresence 提供了3个非常重要的功能:

  1. cluster 域名解析

  2. cluster 流量代理

  3. cluster 流量拦截

在本地开发环境下面,当启动 Telepresence connect 建立连接时,会建立一个名叫 tel0 的 tun 设备

Telepresence 会通过 systemd-resolved 服务将集群命令空间的 cluster domain 添加到这个设备,通过resolvectl status tel0 可以查看到当前有哪些命名被添加了。Telepresence 会通过 kubectl 访问 kube-apiserver 来 watch 整个集群的所有命名空间,因此,当发生变更的时候,DNS domain 会被自动更新。

从图中可以看到该 tun 设备的 DNS Server 地址被设置成了集群中 Telepresence Traffic Manager(以 deploy 的形式部署,负责流量转发等功能)的 Pod 的地址

该 tun 设备的流量会通过隧道代理到 Telepresence Traffic Manager,再由 Telepresence Traffic Manager 实现流量的转发。

当使用telepresence intercept <workload>时,会在目标 workload 中注入一个边车容器 traffic agent(sidecar container),拦截原理其实跟 istio 类似,也是利用 sidecar 注入然后代理流量

参考资料

Telepresence 官方文档快速入门

TUN 设备原理-CSDN博客

Telepresence 实践及踩坑记

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐