使用 Kubernetes 桥接 (VS Code)

Bridge to Kubernetes 允许您在开发计算机上运行和调试代码,同时仍然通过其余应用程序或服务连接到 Kubernetes 集群。在本指南中,您将了解如何使用 Bridge to Kubernetes 重定向 Kubernetes 集群与开发计算机上运行的代码之间的流量。

在你开始之前

本文假设您已经拥有自己的具有微服务架构的集群,并且您想要调试集群中的一个 Pod。如果您想了解如何将 Bridge to Kubernetes 与现有示例应用程序结合使用,请参阅将Bridge to Kubernetes 与示例结合使用。如果您使用的是 Azure Kubernetes 服务并希望使用更复杂的示例应用程序,请参阅桥接 Kubernetes (AKS)

先决条件

  • 包含您要调试的应用程序的 Kubernetes 集群。
  • 在 macOS、Windows 10 或更高版本或 Linux 上运行的Visual Studio Code 。

连接到您的集群并调试服务

有几种不同的方法可以使用 Bridge to Kubernetes 启动调试过程。如果您从开源 Kubernetes 扩展开始,未安装 Bridge to Kubernetes,请转到安装并使用本地隧道调试。如果您已安装 Bridge to Kubernetes,请继续执行以下步骤:

  1. 在您的开发计算机上,确保当前上下文设置为应用程序运行所在的集群和命名空间。

  2. 打开要在 Visual Studio Code 中调试的应用程序的工作区。在Clusters下的 Kubernetes 扩展视图中,确保选择您的集群和命名空间。打开命令面板(在 Mac 上为CTRL + SHIFT + PCmd + Shift + P),然后运行命令Bridge to Kubernetes:Configure以启动配置过程。

  3. 选择您想要重定向到本地版本的 Kubernetes 服务。

    选择要连接的服务

    Kubernetes 集群中的所有流量都将针对您的服务重定向到开发计算机中运行的应用程序版本。Bridge to Kubernetes 还会将所有出站流量从应用程序路由回 Kubernetes 集群。

    重要的

    您只能重定向具有单个 Pod 的服务。

  4. 选择服务后,请跳过下一部分并继续执行使用 Bridge to Kubernetes 配置调试器以进行本地隧道调试中的步骤。

安装和使用本地隧道调试

当您安装了开源Kubernetes 扩展并且拥有包含要调试的服务的 Kubernetes 集群时,请按照以下步骤开始使用本地隧道调试。本节中的步骤将引导您完成 Bridge to Kubernetes 的安装并开始本地隧道调试的配置过程。

笔记

VS Code 的 Kubernetes 扩展提供了一个 API 入口点,允许扩展作者从 VS Code Marketplace 贡献其他本地隧道解决方案。Bridge to Kubernetes 是本地隧道调试功能的一种可能实现。

在 VS Code 中开始使用本地隧道调试有两种方法。第一种方法是打开命令面板(在 Mac 上为CTRL + SHIFT + PCmd + Shift + P )并输入Kubernetes: Debug (Local Tunnel)

显示 VS Code 中的调试(本地隧道)命令的屏幕截图

或者,导航到 Kubernetes 集群资源管理器。打开活动集群的资源并找到要调试的服务或 Pod,然后右键单击该服务并选择Debug: Local Tunnel

此时,如果您没有安装任何提供本地调试功能的 VS Code 扩展,您将被重定向到 Marketplace 以选择提供本地调试功能的扩展。选择Bridge to Kubernetes扩展。

显示 VS Code 中的“调试本地隧道”上下文菜单的屏幕截图

安装 Bridge to Kubernetes 扩展后,下次选择Debug: Local Tunnel时,您将跳过安装步骤,直接进入下一步,使用 Bridge to Kubernetes 配置调试器以进行本地隧道调试

使用 Bridge to Kubernetes 配置调试器以进行本地隧道调试

配置调试器进行本地隧道调试的第一步是,系统会提示您输入应用程序用于本地运行的 TCP 端口:

输入端口号

选择您在本地运行应用程序时通常使用的调试启动配置。如果您没有启动配置,您可以让 Bridge to Kubernetes 创建一个启动配置,也可以选择不创建启动配置,在这种情况下,您必须手动启动应用程序或服务。了解更多信息,请参阅启动配置

选择调试器启动配置

您可以选择隔离或不隔离运行。如果您独立运行,则只有您的请求会路由到本地进程;其他开发者可以使用该集群而不受影响。如果您不隔离运行,所有流量都会重定向到您的本地进程。有关此选项的更多信息,请参阅使用路由功能进行隔离开发

选择隔离

选择左侧的Debug图标,然后选择新添加的 Kubernetes 启动配置,例如顶部的Launch via NPM with Kubernetes 。如果您选择该选项,则此启动配置由 Bridge to Kubernetes 创建。

选择调试启动配置文件

笔记

系统将提示您允许EndpointManager运行提升并修改您的主机文件。

当 VS Code 状态栏变为橙色并且 Kubernetes 扩展显示您已连接时,您的开发计算机已连接。

使用 Bridge to Kubernetes 进行调试

连接开发计算机后,流量开始重定向到您要替换的服务的开发计算机。

笔记

在后续启动时,系统不会提示您输入服务名称、端口、启动任务或是否隔离运行。这些值保存在.vscode/tasks.json. 要稍后更改这些设置,请打开命令面板(在 Mac 上为CTRL + SHIFT + PCmd + Shift + P ),然后运行命令Bridge to Kubernetes: Configure。您可以打开.vscode/launch.json.vscode/tasks.json以查看 Bridge to Kubernetes 添加到您的启动配置文件中的特定配置设置。

如果您的集群使用gRPC C core (使用c-ares的 gRPC 实现),则会将环境变量 GRPC_DNS_RESOLVER 添加到您的启动配置文件中,其值为native。此变量指定使用解决方法来避免连接时出现 2 分钟的时间延迟。有关更多信息,请参阅此gRPC 问题

设置断点

使用F9设置断点或选择Run然后选择Toggle Breakpoint

通过打开公共 URL 导航到示例应用程序。当您的代码到达断点时,它应该在调试器中打开。要恢复服务,请按Ctrl+F5或选择“运行”,然后选择“继续”。返回浏览器并验证您是否看到自行车的占位符图像。

更新您的应用程序

当您在本地进行代码更改时,使用集群的其他人是否可以看到它们取决于您是否正在隔离运行。如果您独立运行,则可以进行不影响其他用户的更改。

编辑代码,保存更改,然后按Ctrl + Shift + F5(在 Mac 上为⇧⌘F5 )或选择“运行”,然后“重新启动调试”。重新连接后,刷新浏览器并验证您的更改。

选择“运行”,然后选择“停止调试”或按Shift + F5停止调试器。

笔记

默认情况下,停止调试任务还会断开开发计算机与 Kubernetes 集群的连接。您可以通过在 Visual Studio Code 设置中搜索Bridge to Kubernetes: Disconnect After Debugging并删除调试停止时自动断开旁边的复选框来更改此行为。更新此设置后,当您停止和开始调试时,您的开发计算机将保持连接。要将开发计算机与集群断开连接,请单击状态栏上的 Bridge to Kubernetes 扩展,然后选择Disconnect current session

附加配置

Bridge to Kubernetes 可以处理路由流量和复制环境变量,无需任何额外配置。如果您需要下载挂载到 Kubernetes 集群中的容器的任何文件(例如 ConfigMap 文件),您可以创建一个将KubernetesLocalProcessConfig.yaml这些文件下载到您的开发计算机。有关更多信息,请参阅配置 Kubernetes 桥接

如果你使用的 AKS 群集使用托管标识(Microsoft Entra ID 提供的安全功能),请参阅将托管标识与 Bridge to Kubernetes 结合使用,了解有关如何为此场景配置 Bridge to Kubernetes 的信息。

使用日志记录和诊断

当您的开发计算机连接到 Kubernetes 集群后,日志输出将写入Bridge to Kubernetes窗口。

单击Kubernetes状态栏并选择显示连接诊断信息。此命令在日志输出中打印当前环境变量和 DNS 整体。

Bridge to Kubernetes此外,您还可以在开发计算机的 TEMP 目录中的目录中找到诊断日志。在 Windows 10 上,该文件位于%TEMP%\Bridge to Kubernetes. 在 Mac 上,可以通过echo $TMPDIR从终端窗口运行来找到 TEMP 目录。在 Linux 上,它是/tmp/Bridge to Kubernetes.

在隔离模式下运行

通过 Bridge to Kubernetes,您还可以为您正在使用的服务设置一个隔离版本,这意味着使用集群的其他人不会受到您的更改的影响。这种隔离模式是通过将您的请求路由到每个受影响服务的副本,但正常路由所有其他流量来实现的。要访问隔离应用程序的本地端点 URL,请在隔离模式下启动调试器,打开状态栏上的 Kubernetes 菜单,然后选择端点条目。您可以在Bridge to Kubernetes 的工作原理中找到有关路由如何在隔离模式下工作的更多信息。

标头传播

要按照设计方式使用 Bridge to Kubernetes,您需要确保将 Bridge to Kubernetes 标头从传入请求传播到您的服务向集群中其他服务发出的任何请求。所有 HTTP 请求 API,无论使用何种语言,都提供一些特定于框架的方法来执行此操作。例如,对于 C# 中的 .NET 代码,您可以使用类似于以下的代码:

 var request = new HttpRequestMessage();
request.RequestUri = new Uri("http://mywebapi/api/values/1");
if (this.Request.Headers.ContainsKey("kubernetes-route-as"))
{
    // Propagate the dev space routing header
    request.Headers.Add("kubernetes-route-as", this.Request.Headers["kubernetes-route-as"] as IEnumerable<string>);
}
var response = await client.SendAsync(request);

笔记

为了避免影响每个请求的代码,您可以创建一个继承自System.Net.Http.DelegatingHandlerSendAsync的类,并使用与前面示例类似的代码重写该方法。您可以在网络上找到使用此技术的代码;一个例子是在 Bridge to Kubernetes 中正确传播“kubernetes-route-as”

对于 Node.js 服务,您可以使用类似于以下的代码,取自Bridge to Kubernetes 存储库中的 todo-app 示例:

     server.get("/api/stats", function (req, res) {
        var options = {
            host: process.env.STATS_API_HOST,
            path: '/stats',
            method: 'GET'
        };
        const val = req.get('kubernetes-route-as');
        if (val) {
            console.log('Forwarding kubernetes-route-as header value - %s', val);
            options.headers = {
                'kubernetes-route-as': val
            }
        }
        var req = http.request(options, function(statResponse) {
            res.setHeader('Content-Type', 'application/json');
            var responseString = '';
            //another chunk of data has been received, so append it to `responseString`
            statResponse.on('data', function (chunk) {
                responseString += chunk;
            });
            statResponse.on('end', function () {
                res.send(responseString);
            });
        });

        req.on('error', function(e) {
            console.log('problem with request: ' + e.message);
          });

          req.end();
    });

与其他服务通信

当您与同一 Kubernetes 集群中的另一个服务通信时(例如使用 HTTP 请求),您通常会在请求的 URL 中使用硬编码的服务名称,但这在某些情况下不起作用,例如使用远程 SSH 时, WSL 和代码空间。本文介绍如何使用 Kubernetes 服务环境变量来指定这些场景的连接 URL。

故障排除

如果您在激活 Bridge to Kubernetes 扩展时遇到此错误:

“更新依赖项失败:超出最大重试次数”

首先,使用 按钮重试激活。如果多次失败,请参阅https://github.com/microsoft/mindaro/issues/32

当您在远程 SSH 会话中使用 Bridge to Kubernetes 时,如果 EndpointManager 失败,问题可能是 Bridge to Kubernetes 由于权限问题而无法修改主机文件。要启用远程 SSH 或以非提升用户身份运行,您应该更新代码以使用 Kubernetes 服务环境变量,并配置 VS Code 以使用它们,如服务环境变量主题中所述

下一步

了解有关 Bridge to Kubernetes 的更多信息,请参阅Bridge to Kubernetes 的工作原理

如果您需要同时并行调试多个服务,请参见同时调试多个服务

有关 Bridge to Kubernetes 当前支持的功能和未来路线图的信息可以在Bridge to Kubernetes 路线图中找到。