使用vscode Container开发调试envoy


由于我最近在研究 envoy 这个项目,这是个cpp的项目,对于我这种cpp新人来说还是比较有压力的,感觉处处都是坑,开个引导文章记录一下。

如果要研究 envoy 项目源码,那肯定是需要代码跳转的,但是如果用 clion 打开,那么你会发现 envoy 是用bazel 构建的,没有CMakeLists.txt无法跳转,bazel-cmakelists 这个工具也已经几年都没迭代了,根本用不了。所以按照官方推荐的使用 vscode 来进行构建开发。

在 envoy 这个项目里面,由于运行环境是基于ubuntu的docker环境跑的,所以提供了vscode container 这种模式给我们开发者进行开发调试。

看了一下 envoy 的开发文档,感觉貌似使用起来是很简单的,但是有些地方踩坑也让我浪费了不少时间。

开发环境的构建

创建 dev container环境

首先,我们需要在我们的机器上安装好 docker desktop,然后用vscode打开我们的envoy项目,打开 envoy/.devcontainer/devcontainer.json 文件,这个时候 vscode 会弹出如下提示:

image-20220318153552941

然后我们点击 Reopen in Container 即可加载构建 vscode Container 开发环境。但是有些小伙伴说,不小心把这个提示关了,怎么手动打开呢?

在mac里我们可以按下:command+shift+p,然后输入 reopen:

image-20220318153821589

生成相应的依赖文件

然后进入到容器内部之后,需要 Refresh Compilation Database ,也就是运行 tools/vscode/refresh_compdb.sh脚本,这个脚本会帮我们生成代码完成的所有依赖项,例如 protobuf 生成的代码、外部依赖项。

但是直接运行的话,会报错:

image-20220318154212923

然后我去看官方文档VSCode Remote - Containers,文档里面和我说一般需要把devcontainer.json 的里面的 remoteUser 设置为 root, 然后我又重新构建了几次,都是直接卡死,原因不明。

然后我跑到宿主机给 vscode 这个用户加权限,结果是找不到这个用户。后面我幡然醒悟,这个权限命令应该在容器内部执行才可以:

# 这个命令需要在容器内部执行
sudo chown -R vscode /workspaces

然后再运行 tools/vscode/refresh_compdb.sh脚本 ,ok了,没有报错。然后检查生成的 complie_commands.json文件也没有问题。

image-20220319152226271

我们再检查一下代码可以正常跳转,并且没有报错了。

开发环境进行envoy调试

当然,除了让我们的开发环境的代码能够跳转其实还不够,最好是可以进行代码的调试,下面我们就看看怎么调试 envoy。

配置一个demo yaml

在代码的 config 下面其实有很多 yaml 模板,可以随便拿一个出来放到envoy根目录下面,我这里也给一个 yaml 例子:

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
      protocol: TCP
      address: 0.0.0.0
      port_value: 9901
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10001
    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
          scheme_header_transformation:
            scheme_to_overwrite: https
          stat_prefix: ingress_http
          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
          http_filters:
          - name: envoy.filters.http.router
  clusters:
  - name: service_envoyproxy_io
    connect_timeout: 30s
    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

生成 vscode 调试文件

在根目录下运行下面命令:

tools/vscode/generate_debug_config.py //source/exe:envoy-static --args "-c envoy.yaml"

上面 --args 参数里面填的就是我们上面的 yaml 文件,这个编译等待的过程是十分漫长的,我 8C16G 的机器差不多花了我1个小时才弄好。

运行好之后,可以看到帮我们生成好了 launch.json 文件:

image-20220319161450614

调试

然后我们按 F5 发现可以进入到我们的 mian 函数的断点中,没有什么问题:

image-20220319161617793

到此为止,我们的 envoy 开发调试为一体的集成环境就打造好了,小伙伴们可以快乐的阅读源码了。

扫码_搜索联合传播样式-白色版 1