ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

在 VSCode Dev Container 中搭建 Envoy 开发与调试环境:从编译数据库到 GDB/LLDB 断点调试

在 VSCode Dev Container 中搭建 Envoy 开发与调试环境:从编译数据库到 GDB/LLDB 断点调试 在 VSCode Dev Container 中搭建 Envoy 开发与调试环境从编译数据库到 GDB/LLDB 断点调试【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoyEnvoy 是一个云原生高性能边缘/中间/服务代理其代码库规模庞大本地源码级调试的门槛一直较高。本文以仓库内 .devcontainer/README.md 为骨架结合 .devcontainer 目录下的容器配置与 tools/vscode/generate_debug_config.py 等工具源码完整讲解如何通过 VSCode Remote - Containers 在隔离容器中构建 Envoy、生成编译数据库compilation database、配置 GDB/LLDB 并实施断点调试最终在本地验证代理转发与 OpenTelemetry 追踪行为。读完本文你将掌握一键打开 Envoy Dev Container 并刷新编译数据库的完整流程、远程构建执行RBE等高级用法、从envoy.yaml编写到launch.json生成的调试链路、以及 macOS含 Apple Silicon上 GDB/LLDB 的选择与排障方法。Dev Container为 Envoy 开发量身定制的实验性环境.devcontainer目录为 Envoy 开发者提供了一套实验性的容器化开发工具核心目标是将 Envoy 庞大的 Bazel 构建链、LLVM 工具链和调试依赖封装进一个可复现的 Docker 环境中让开发者直接在 VSCode Remote - Containers 模式下编写、编译与调试代码。其关键组件包括文件作用.devcontainer/devcontainer.json容器运行时参数、VS Code 设置与扩展清单.devcontainer/Dockerfile.inDockerfile 模板基于 Envoy 官方构建镜像生成.devcontainer/init.sh初始化命令initializeCommand负责生成最终 Dockerfile.devcontainer/setup.sh容器创建后脚本postCreateCommand配置 Bazel 与工具链.devcontainer/clangd-wrapper.shclangd 包装脚本限制内存占用防止系统崩溃容器运行参数解读从 devcontainer.json 可以看出容器以envoybuild非 root 用户运行并携带了调试与网络相关的关键参数--cap-addSYS_PTRACE允许调试器GDB/LLDB对进程执行ptrace这是源码级断点调试的前提--cap-addNET_RAW、--cap-addNET_ADMIN赋予容器网络原始套接字与管理能力供 Envoy 的流量测试与网络相关功能使用--security-optseccompunconfined解除 seccomp 限制避免调试器附加进程时被系统调用过滤器拦截--volumeenvoy-build:/build将 Bazel 输出目录持久化到命名卷避免每次重建容器后全量重新编译--volume${env:HOME}:${env:HOME}挂载宿主机主目录方便复用 Bazel 缓存与凭据--networkhost直接使用宿主机网络简化本地端口访问如管理端口9902、代理端口10000。同时容器内预设了ENVOY_SRCDIR环境变量指向工作区并透传宿主机的HTTP_PROXY/HTTPS_PROXY/NO_PROXY设置devcontainer.json。从模板生成镜像.devcontainer/init.sh读取 ci/envoy_build_sha.sh 中固定的构建镜像标签并通过sed将 Dockerfile.in 中的%%ENVOY_BUILD_IMAGE%%占位符替换为实际镜像生成最终的.devcontainer/Dockerfile。模板镜像内安装python3、net-tools、iputils-ping、procps、psmisc、vim、openssh-client、aspell等开发辅助工具并把用户主目录迁移到/build即持久化卷挂载点确保 Bazel 输出不占用容器可写层。容器内的 Bazel 初始化.devcontainer/setup.sh在容器创建后自动执行以下操作检查user.bazelrc中是否已包含build --configclang没有则追加——即默认使用 clang 编译配置setup.sh修正/buildBUILD_DIR目录属主避免权限问题调用ci/do_ci.sh pre_refresh_compdb预先构建llvm_toolchain//:clangd确保 LLVM 工具链在容器内提前就位ci/do_ci.sh将工具链中的clang-format、clangd软链接到/usr/local/bin供 VS Code 的 clangd 插件直接调用。快速上手打开容器并刷新编译数据库第一步以 Dev Container 模式打开仓库安装 VSCode 的 Dev Containers 扩展后从 GitHub 克隆仓库或使用git clone https://gitcode.com/GitHub_Trending/en/envoy获取本仓库然后用 VSCode 打开仓库根目录。IDE 检测到.devcontainer目录后会弹出提示确认以 Reopen in Container 模式重新打开。窗口左下角出现 Container 或 Dev Container 蓝色标签即代表已进入容器模式。第二步运行 Refresh Compilation Database 任务进入容器后在命令面板中运行Refresh Compilation Database任务其底层执行的是 ci/do_ci.sh refresh_compdbci/do_ci.sh refresh_compdb该任务会依次执行setup_clang_toolchain初始化 clang 工具链调用tools/proto_format/proto_format.sh fix规范 proto 文件格式可用SKIP_PROTO_FORMAT环境变量跳过运行tools/gen_compilation_database.py生成compile_commands.json编译数据库执行pkill clangd重启 clangd使其重新加载编译数据库。由于需要对 Envoy 做一次部分构建来生成全部依赖含 protobuf 生成代码与外部依赖该任务耗时较长具体时长取决于机器性能。注意以下两类改动后必须重新运行该任务否则代码补全与跳转会失效修改 BUILD 文件导致目标增删文件或依赖关系变化修改 API proto 文件。tools/vscode/README.md还补充了两个实用提示一是 C/C 代码补全建议禁用 Microsoft C/C 扩展而改用vscode-clangd二是中国开发者可能需要预先设置http_proxy、https_proxy、all_proxy以便拉取依赖。另外若在 Proxmox 等虚拟化环境下遇到 hyperscan 构建报A minimum of SSSE3 compiler support is required可执行cat /proc/cpuinfo | grep ssse3检查 CPU 特性若为空则需将虚拟机默认 CPU 类型从kvm64改为max。高级用法使用远程构建执行RBE加速编译在仓库根目录创建.devcontainer/devcontainer.env并写入以下内容然后重建容器GCP_SERVICE_ACCOUNT_KEYbase64 encoded service account key BAZEL_REMOTE_INSTANCERBE Instance BAZEL_REMOTE_CACHEgrpcs://remotebuildexecution.googleapis.com BAZEL_BUILD_EXTRA_OPTIONS--configremote-ci --configremote --jobsNumber of jobs密钥会持久化到容器内的~/.bazelrc。默认情况下--configremote隐含--remote_download_toplevel仅下载顶层产物可根据运行场景在BAZEL_BUILD_EXTRA_OPTIONS中追加--remote_download_toplevelminimal或all进行调整。对应地devcontainer.json 中注释的--env-file.devcontainer/devcontainer.env需要在需要 RBE 时取消注释。改善磁盘性能Docker for Mac/Windows 的跨平台文件挂载存在已知的磁盘性能问题会导致容器内全量格式化文件非常缓慢。文档建议将挂载一致性更新为delegated模式把写入缓存推迟到宿主机从而显著提升容器内文件的读写吞吐。本地开发完整设置与调试指南这一部分提供了从零搭建 Envoy 本地开发调试环境的完整演练已在 Apple M1 Max 与 Intel Core i9 的 macOS Sequoia15.5上验证通过。对不熟悉 C 或更习惯 CMake/Make 的开发者而言Envoy 基于 Bazel 的构建体系配合 Dev Container大大降低了本地开发门槛。前置条件macOS Sequoia15.5或兼容系统VSCode 或 Cursor IDE资源充足的 Docker DesktopDev Containers 扩展。仓库准备与容器初始化克隆仓库后在 VSCode 中打开接受 Dev Container 模式提示。进入容器后打开新终端Terminal → New Terminal执行编译数据库刷新ci/do_ci.sh refresh_compdb该过程需要 30–60 分钟视机器性能而定且每当修改 proto 定义或 Bazel 结构后都应重跑以保持代码补全正确。构建问题排查磁盘空间不足若编译过程中报 no space left on device说明 Docker 资源配额不足解决步骤打开 Docker Desktop进入Settings→Resources将Memory Limit提升到至少 8GB推荐 16GB将Disk usage limit提升到至少 100GB若设置项呈灰色不可改先执行Troubleshoot→Reset to factory defaults恢复出厂重启 Docker Desktop 后重新配置资源上限并Apply and restart。构建成功标志日志末尾出现类似如下输出总 action 数可能不同Build completed successfully, 11415 total actions调试配置生成编写 Envoy 配置文件在仓库根目录创建envoy.yaml文件名可自定需为标准 Envoy 配置。以下示例配置用于调试 OpenTelemetry 追踪在10000端口接收 HTTP 流量并转发到www.envoyproxy.io同时将追踪数据通过 gRPC 上报到本地5002端口的 OpenTelemetry Collectoradmin: address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 9902 static_resources: listeners: - name: listener_0 address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 10000 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: type: type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http # Enable tracing tracing: provider: name: envoy.tracers.opentelemetry typed_config: type: type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig grpc_service: envoy_grpc: cluster_name: opentelemetry_collector timeout: 100s service_name: envoy-proxy random_sampling: value: 100 access_log: - name: envoy.access_loggers.stdout typed_config: type: type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog http_filters: - name: envoy.filters.http.router typed_config: type: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router route_config: name: local_route virtual_hosts: - name: local_service domains: [*] routes: - match: prefix: / route: host_rewrite_literal: www.envoyproxy.io cluster: service_envoyproxy_io clusters: - name: service_envoyproxy_io type: LOGICAL_DNS # Comment out the following line to test on v6 networks dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: service_envoyproxy_io endpoints: - lb_endpoints: - endpoint: address: socket_address: address: www.envoyproxy.io port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: type: type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: www.envoyproxy.io # OpenTelemetry Collector cluster - name: opentelemetry_collector type: STRICT_DNS dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: type: type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: {} load_assignment: cluster_name: opentelemetry_collector endpoints: - lb_endpoints: - endpoint: address: socket_address: address: localhost port_value: 5002配置要点说明admin在9902端口暴露管理接口供后续验证/clusters、/config_dump、/stats等端点tracing.provider类型为envoy.tracers.opentelemetry其OpenTelemetryConfig通过envoy_grpc指向名为opentelemetry_collector的集群并设置 100s 上报超时与service_namerandom_sampling.value: 100100% 随机采样便于调试时捕获全部 tracetransport_socket上游使用 TLS 并携带 SNIwww.envoyproxy.ioopentelemetry_collector 集群通过HttpProtocolOptions显式声明 HTTP/2 协议gRPC 上报依赖此配置。生成调试配置运行调试配置生成器tools/vscode/generate_debug_config.py //source/exe:envoy-static --args -c envoy.yaml从 generate_debug_config.py 的源码可以看到该脚本的完整工作流解析参数--debugger默认gdb、--args默认空、--config默认自动检测、--overwrite默认关闭通过bazel info workspace获取工作区路径若根目录存在compile_commands.json则从其第一条记录读取directory作为执行根目录以便 clangd 导航断点get_execution_root以-c dbg调试模式构建指定 Bazel 目标build_binary_with_debug_info依据调试器类型生成 GDB 或 LLDB 配置并写入.vscode/launch.json已有同名配置时仅更新固定字段--overwrite可整体重建原文件备份为launch.json.bak。编译器配置自动检测与手动覆盖脚本在 ARM64/aarch64Apple Silicon架构上自动选用clang配置以获得更好的 C20 concepts 兼容性其他架构使用 Bazel 默认配置auto_detect_config可用--config显式指定# Force use of clang configuration tools/vscode/generate_debug_config.py //source/exe:envoy-static --args -c envoy.yaml --config clang # Force use of gcc configuration tools/vscode/generate_debug_config.py //source/exe:envoy-static --args -c envoy.yaml --config gcc其他常用选项# Use LLDB debugger instead of GDB (recommended for macOS) tools/vscode/generate_debug_config.py //source/exe:envoy-static --args -c envoy.yaml --debugger lldb # Overwrite existing configuration completely tools/vscode/generate_debug_config.py //source/exe:envoy-static --args -c envoy.yaml --overwrite重要该命令可能耗时超过一小时且每次代码改动后都需要重新执行以更新调试二进制与 launch 配置。ARM64/Apple Silicon 提示在 ARM64 系统上若遇到 GCC 编译 C20 concepts 兼容性错误源于 protobuf 依赖在 ARM64 GCC 组合下的兼容问题脚本会自动切换到 clang 配置解决。生成的launch.json默认使用 GDBGNU Debugger。Envoy 社区推荐的两类调试器为GDB广泛用于 C 等多种语言的调试器与 LLDBLLVM 项目的调试器通常与 Clang 编译产物配合使用Clang 是 C 的编译器之一。按下 F5 即可启动调试。配置 LLDBmacOS 推荐部分 Mac 机器上 GDB 会报错此时建议改用 LLDB。在 VSCode 中通过CmdP输入launch.json打开文件将 GDB 配置替换为{ version: 0.2.0, configurations: [ { name: LLDB //source/exe:envoy-static, type: lldb, request: launch, program: /build/.cache/bazel/_bazel_vscode/2d35de14639eaad1ac7060a4dd7e3351/execroot/envoy/bazel-out/k8-dbg/bin/source/exe/envoy-static, args: [-c, envoy.yaml], cwd: ${workspaceFolder}, stopOnEntry: false, sourceMap: { /proc/self/cwd: ${workspaceFolder} } } ] }注意program路径中的哈希串需替换为你机器上 GDB 配置里实际生成的路径且需确保容器内已安装 CodeLLDB 扩展。对照 generate_debug_config.py 的实现可以看到LLDB 配置的核心差异在于sourceMap它将容器内编译路径/proc/self/cwd映射回工作区/proc/self/cwd/external映射到外部依赖执行根、/proc/self/cwd/bazel-out映射到 Bazel 输出目录在 Darwin arm64 平台上则简化为.: ${workspaceFolder}这与 macOS 上调试器对源路径的处理方式一致。GDB 配置则通过debugger_args传入--directoryexecroot完成同样的源码定位gdb_config。另外generate_debug_config.py 支持通过环境变量BAZEL_BUILD_OPTION_LIST与BAZEL_STARTUP_OPTION_LIST注入额外的 Bazel 构建/启动选项可用于在 CI 或带代理的网络环境中定制构建参数。设置断点主入口断点在 source/exe/main.cc 的main函数处添加断点这是 Envoy 进程的启动入口自定义调试断点按需添加其他断点。例如调试追踪功能时可在source/extensions/tracers/opentelemetry/opentelemetry_tracer_impl.cc的追踪器实现中打点观察 OpenTelemetry span 的创建与导出逻辑。启动调试会话按F5或通过Run→Start Debugging启动等待 1–2 分钟让调试器附加到进程Envoy 代码库庞大Envoy 大部分源码位于仓库根目录的source目录source/exe/main.cc处的断点应首先触发继续执行Run→Continue即可看到 Envoy 启动并输出日志。验证调试环境Envoy 启动成功后基于前述配置可通过以下入口验证管理接口访问 http://localhost:9902代理端点访问 http://localhost:10000应依据配置被重定向到 envoyproxy.io管理端点在宿主机浏览器中访问Clustershttp://localhost:9902/clusters查看集群与端点状态Config Dumphttp://localhost:9902/config_dump导出当前生效的完整配置Statshttp://localhost:9902/stats查看运行时统计指标这些管理端点由envoy.yaml中 admin 配置的9902端口提供配合 api/envoy/admin 下的 proto 定义如clusters.proto、config_dump.proto可进一步理解其数据结构。同时由于配置中启用了 OpenTelemetry 追踪并采样 100%可在本地 Collector 侧观察由 Envoy 上报的 trace验证调试效果。小结Envoy 的 Dev Container 方案将复杂的 Bazel 构建、LLVM 工具链与调试环境收敛为一次打开即用的开发体验Refresh Compilation Database任务为 clangd 提供精确的代码导航generate_debug_config.py以-c dbg模式构建带调试信息的二进制并自动生成 GDB/LLDB 的launch.json配合SYS_PTRACE等容器能力实现源码级断点调试。对 macOS 与 Apple Silicon 用户脚本内置的 clang 自动检测与 LLDB 推荐路径能显著降低环境搭建成本。掌握这套流程后无论是排查路由/追踪问题还是为 Envoy 贡献代码都能在容器内获得接近本机 IDE 的开发体验。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表