
Consul Envoy 集成测试 Windows 环境运行指南架构、镜像构建与测试执行【免费下载链接】consulConsul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.项目地址: https://gitcode.com/gh_mirrors/con/consul导读Consul 仓库内的 Envoy 集成测试test/integration/connect/envoy默认面向 Linux 容器设计依赖 Docker 的 Host 网络特性。当需要将这些测试迁移到 Windows 容器环境时团队采用了一套完全不同的单容器Single Container测试架构。本文以 WINDOWS-TEST.md 为主体结合仓库内测试源码、Windows 专用运行脚本与文档系统讲解 Windows 版 Envoy 集成测试的架构差异、镜像构建方式、测试执行命令以及关键的 LF/CRLF 换行符自动转换机制帮助你理解并直接在 Windows 环境运行这些测试。文档定位Windows 测试的入口文档在仓库中WINDOWS-TEST.md 是理解如何在 Windows 上执行 Envoy 集成测试的入口文档同时它也是理解 Linux 测试与 Windows 测试差异的起点。围绕该入口文档仓库还提供了三份配套材料Windows 测试架构解释为什么 Windows 上的测试架构与 Linux 不同以及单容器架构由哪些组件构成Windows 集成测试 Docker 文件说明介绍运行测试所需各 Dockerfile 的用途与单独构建方法Windows 故障排查指南列出为了让既有测试能在 Windows 容器中运行所做的一切适配改动以及常见错误。Linux 与 Windows 的测试架构差异Linux基于 Host 网络的多容器 共享卷架构在 Linux 上测试利用的是 Docker 的Host 网络特性该特性仅对 Linux 容器可用。使用该网络模式的容器共享宿主机的网络命名空间所有容器位于同一网络栈内容器不拥有独立的 IP 地址。每次运行测试时都会创建一个名为workdir的目录所有运行测试所需的文件都会被复制进去随后这个目录以named volume命名卷方式挂载并通过一个以 Kubernetespause镜像打上envoy_workdir_1标签的容器来占据该卷使其在测试期间其他容器陆续启动时保持可访问。Linux 容器允许在运行时对文件系统进行操作这正是这套架构能够成立的前提。Windows无法复制 Linux 架构最终走向单容器Windows 容器没有 Host 网络特性因此迁移初期团队改用NAT 网络。由此带来两个直接后果每个容器拥有彼此隔离的网络栈和独立 IP 地址容器之间只能通过 Docker DNS使用容器名互相通信而不再能通过 localhost 互访既有测试配置文件假设所有服务由 Fortio 运行的服务与 Envoy sidecar proxy 服务都运行在 localhost 上。虽然尝试在运行时修改这些文件取得了部分成功但依然问题不断。对于测试断言中由函数调用或 curl 执行的访问团队通过将这些调用映射到对应的容器名来解决连通性问题。下图展示了在 Windows 上照搬 Linux 架构时的失败连接情况经过多次尝试后团队最终决定与其在 Windows 上复制 Linux 架构不如构建一个包含全部所需组件的单一容器。这一单容器测试架构正是 Windows 上最有效的方案——使用单容器架构意味着可以直接复用 Linux 上同一套测试用例同时还能把启动工具容器的docker run命令替换为docker exec从而显著加快测试执行速度。单容器测试架构的镜像组件单容器方案意味着构建一个 Windows Docker 镜像其中不仅要包含 Consul 与 Envoy还要包含执行既有 Envoy 集成测试所需的全部工具。这些组件可分为主组件与附加工具两类主组件组件用途BatsBash Automated Testing SystemBash 自动化测试系统负责实际执行测试用例.bats断言脚本Fortio微服务HTTP、gRPC压测库与命令行工具也是高级 echo server 与 Web UI。集成测试期间注册进 Consul 的服务就是由它运行的Jaeger开源分布式服务链路追踪软件用于监控与排查复杂的微服务环境在部分测试用例中与 OpenZipkin 配合使用OpenZipkin同样是一款链路追踪软件ZipkinSocat命令行网络工具在两个双向字节流之间建立连接并传输数据。集成测试中用它重定向 Envoy 的 stats 输出需要说明的是Socat 没有官方 Windows 版本测试镜像中采用的是非官方发行版。附加工具工具用途Git Bash仅在 Windows 测试中使用加入镜像是为了在测试执行期间使用部分 Linux 命令JQ轻量灵活的 JSON 命令行处理器多个测试用它修改和过滤 JSON 输出Netcat跨网络读写数据的简单工具类似cat之于文件OpenSSL全面的密码学库提供 TLS 协议的开源实现用于验证测试期间下发的 TLS 证书是否正确预构建核心镜像与集成测试镜像预构建核心镜像在运行集成测试之前必须先预构建测试在 Windows 环境运行所需的核心镜像。虽然入口文档指向仓库外部的build-support-windows/BUILD-IMAGES.md该目录不在当前仓库快照中但仓库内保留了实际承担构建工作的 Dockerfile例如 Dockerfile-consul-envoy-windows# From Consul Version 1.13.3 / 1.12.6 / 1.11.11 ARG VERSION1.16.0-dev # From Envoy version 1.23.1 / 1.21.5 / 1.20.7 ARG ENVOY_VERSION FROM docker.mirror.hashicorp.services/windows/envoy-windows:v${ENVOY_VERSION} as envoy FROM windows/consul:${VERSION} # Copy envoy.exe from FROM windows/envoy-windows:${ENVOY_VERSION} COPY --fromenvoy [C:/Program Files/envoy/, C:/envoy/] RUN SETX /M path %PATH%;C:\envoy;可以看到该 Dockerfile 从windows/envoy-windows:v${ENVOY_VERSION}阶段复制envoy.exe到基础镜像windows/consul:${VERSION}并通过SETX将C:\envoy永久写入容器 PATH最终构建出测试运行使用的windows/consul:local镜像。在 run-tests.windows.sh 的suite_setup中测试框架会使用--build-arg ENVOY_VERSION${ENVOY_VERSION}重新构建该镜像retry_default docker.exe build -t windows/consul:local \ --build-arg ENVOY_VERSION${ENVOY_VERSION} \ -f Dockerfile-consul-envoy-windows .集成测试镜像在执行集成测试的过程中还会基于预构建的核心镜像构建若干测试镜像。关于这些镜像的详细信息以及如何独立运行它们可参考 docker-windows.md。其中典型的例子是test-sds-server镜像它的唯一目的是用 Go 编译出test-sds-server可执行文件用于验证 Envoy 的 SDS 动态证书下发是否正确其构建命令为docker build -t test-sds-server -f Dockerfile-test-sds-server-windows test-sds-server构建完成后可以独立验证该服务是否工作正常docker run --rm -p 1234:1234 --name test-sds-server test-sds-server如果一切正常会输出类似以下的日志20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: nameca-root 20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: namefoo.example.com 20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: namewildcard.ingress.consul 20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: namewww.example.com 20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] SDS listening: addr0.0.0.0:1234运行测试命令与关键参数运行全部测试要运行全部集成测试需要执行以下命令go test -v -timeout30s -tags integration ./test/integration/connect/envoy -runTestEnvoy -wintrue运行单个测试用例要运行单个测试用例需要指定用例名称。例如运行case-badauthz测试执行go test -v -timeout30m -tags integration ./test/integration/connect/envoy -runTestEnvoy/case-badauthz -wintrue⚠️注意-wintrue标志必须像上面命令所示那样显式指定。该标志非常重要它向测试框架表明测试将在 Windows 环境执行。当执行 Envoy 集成测试时所有相关文件与脚本的行尾序列End of Line Sequence会自动从 LF 转换为 CRLF。-wintrue标志的底层实现-wintrue标志并非 go test 的内置参数而是由测试入口文件 main_test.go 通过标准库flag包注册的自定义参数var ( flagWin flag.Bool(win, false, Execute tests on windows) )当该标志为true时测试框架执行的是 Windows 专用脚本 run-tests.windows.sh而不是 Linux 下的run-tests.shfunc runCmdWindows(t *testing.T, c string, env ...string) { t.Helper() param_5 : false if env ! nil { param_5 strings.Join(env, ) } cmd : exec.Command(cmd, /C, bash run-tests.windows.sh, c, param_5) cmd.Env append(os.Environ(), env...) cmd.Stdout os.Stdout cmd.Stderr os.Stderr if err : cmd.Run(); err ! nil { t.Fatalf(command failed: %v, err) } }注意此处通过cmd /C bash run-tests.windows.sh调用——这也是 Windows 测试要求环境具备 Git Bash或 WSL的原因测试断言和容器管理命令均依赖 bash 解释执行。TestEnvoy会调用discoverCases()自动发现所有case-前缀的测试用例目录同时兼容 CE 与 ENT 两份用例并为每个用例执行run_tests、test_teardown等生命周期钩子。LF/CRLF 自动转换机制入口文档强调的行尾序列自动从 LF 转换为 CRLF在源码中有完整实现。当-wintrue时TestEnvoy首先会调用check_dir_files(../../../)递归遍历仓库根目录查找所有.sh与.bash文件见 main_test.go随后调用crlf_file_check检测文件是否包含\r\n若包含则通过crlf_normalize将所有\r\n替换为\n见 main_test.go// Checks for the existence of CRLF line endings. func crlf_verify(text string) int { position : strings.Index(text, \r\n) return position } // Replace CRLF line endings with LF. func crlf_normalize(filename, text string) { text strings.Replace(text, \r\n, \n, -1) data : []byte(text) ioutil.WriteFile(filename, data, 0644) }也就是说这一机制的实际作用是Windows 环境如 Git 检出或编辑器中脚本文件若已被写成 CRLF 行尾测试框架会在执行前将其统一规范化为 LF避免 bash 脚本在 Windows 容器内因行尾符问题执行失败。反过来如果你的环境需要 CRLF则需在测试执行前自行转换。理解这一点对排查脚本在 Windows 下报$\r: command not found之类错误很有帮助。Windows 测试运行流程与关键脚本细节Windows 测试的完整生命周期由 run-tests.windows.sh 驱动其关键环节包括环境变量与默认值变量默认值说明ENVOY_VERSION1.27.0每个测试用例针对的 Envoy 版本会作为构建参数传入镜像XDS_TARGETserver指定 Envoy 的 xDS 会话由 Consul server 直接服务还是经由 client agentclient模式DEBUG空设为非空值时开启set -x逐条回显执行的命令LAMBDA_TESTS_ENABLEDfalse是否启用 AWS Lambda 相关测试用例CONSUL_LICENSE/CONSUL_LICENSE_PATH空Enterprise 测试所需的 license 注入网络与卷测试会创建名为envoy-tests的NAT 网络docker.exe network create -d nat envoy-tests所有容器加入该网络并通过容器名互相通信创建名为envoy_workdir的命名卷并启动envoy_workdir_1基于windows/kubernetes/pause镜像、--netnone、以ContainerAdministrator用户运行来保持卷可用工作目录内容Consul 配置、.bats断言、Envoy bootstrap 等通过WORKDIR_SNIPPET-v envoy_workdir:C:\workdir挂载进各容器。测试执行顺序run_tests函数按以下顺序执行init_vars加载defaults.sh与用例级vars.sh→init_workdir初始化工作目录并复制 Consul 配置consul-base-cfg/*.hcl与用例.bats/.hcl文件 →wipe_volumes清空卷 →stop_and_copy_files将文件拷入共享卷 →start_consul启动主集群视REQUIRE_SECONDARY/REQUIRE_PARTITIONS/REQUIRE_PEERS决定是否启动 secondary、partition、peer 集群→pre_service_setup执行用例级setup.sh→start_services按REQUIRED_SERVICES启动服务与 sidecar →verify在单容器内执行 Bats 断言。服务与 sidecar 的运行方式在单容器架构下服务不再以独立容器方式docker run而是通过docker exec直接进入单容器内执行Fortio 服务如s1、s2在容器内以fortio.exe server -http-port :8080 -grpc-port :8079方式运行Envoy sidecar proxy在容器内执行envoy.exe -c /c/workdir/${CLUSTER}/envoy/${service}-bootstrap.json -l trace --disable-hot-restart --drain-time-s 1其中--disable-hot-restart是特意加上的——Windows 容器间虽然不共享 IPC 命名空间但并发 Envoy 的热重启仍会互相干扰网关mesh/ingress/api/terminating gateway同样以docker exec方式在单容器内启动对应 bootstrap 配置的 envoy 进程。卷写盘的 Windows 限制与stop_and_copy_filesWindows 容器有一个与 Linux 显著不同的限制容器运行期间无法执行文件系统操作。因此不能像 Linux 那样在容器运行时向共享卷写文件。解决办法是 windows-troubleshooting.md 与运行脚本中提到的stop_and_copy_files函数见 run-tests.windows.sh生成一个copy.cmd脚本内容为icacls C:\workdir /grant:r Everyone:(OI)(CI)F /T与XCOPY C:\workdir_bak C:\workdir /e /h /c /i /y停掉envoy_workdir_1占位容器用docker cp将本地workdir拷入容器的workdir_bak将copy.cmd拷入容器重新启动容器并执行该脚本完成卷内容同步删除本地临时copy.cmd。同理wipe_volumes也改用docker exec envoy_workdir_1 cmd /c rd /s /q . 2nul来清空卷避免为删除卷内容额外启动新容器从而加速测试执行。Windows 脚本适配改动一览为了让既有测试能在 Windows 容器中运行仓库做了系统性适配详见 windows-troubleshooting.md核心改动包括在生成 Envoy Bootstrap 文件时新增http-addr、grpc-addr与admin-access-log-path标志同时将-admin-bind的值从0.0.0.0改为127.0.0.1容器内执行命令的 shell 由sh替换为bash所有路径统一改为 Windows 格式移除helpers.windows.bash中的docker_wget/docker_curl改用docker_consul_exec避免在捕获日志时启动中间容器新增stop_and_copy_files函数解决共享卷写入问题见上文对于case-grpc将envoy_stats_flush_interval从 1s 提升到 5s——在 Windows 上原值会导致测试随机通过或失败对于case-wanfed-gw新增global-setup-windows.sh脚本使用windows/consul:local镜像生成所需 TLS 文件并复制到宿主workdircase-consul-exec只能在使用本仓库的consul-dev镜像时运行因为它依赖本仓库独有的实现Windows 下-admin-access-log-path的有效默认值以及consul connect envoy命令能直接启动 Envoy。常见错误与排查根据 windows-troubleshooting.md 中记录的常见问题1. Docker 未运行会出现形如下方的报错指向//./pipe/docker_engine管道无法找到error during connect: This error may indicate that the docker daemon is not running.: Post http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/build?...: open //./pipe/docker_engine: The system cannot find the file specified.2. 镜像缺失或标签错误例如出现Error response from daemon: No such container: envoy_workdir_1说明预构建镜像或占位容器未正确创建需要回到镜像构建步骤检查。3. 从 WSL 运行 Windows 测试会得到如下错误因为 WSL 环境没有 Windows 的cmd.exe可执行文件main_test.go:34: command failed: exec: cmd: executable file not found in $PATH运行前提与环境要求综合入口文档与配套文档在 Windows 上运行 Envoy 集成测试需要满足以下前提Go v1.18 或更高版本以及gotestsum库DockerWindows 容器模式预构建好测试所需的核心镜像含windows/consul:local在PowerShell或Git Bash中执行测试命令Git Bash 下可通过ENVOY_VERSION版本环境变量覆盖测试的 Envoy 版本若在 PowerShell 下运行且需要指定版本需手动修改 run-tests.windows.sh 中ENVOY_VERSION的默认值。结语Consul 的 Windows 版 Envoy 集成测试是复用既有测试资产 针对平台特性做架构适配的典型案例面对 Windows 容器缺少 Host 网络、运行期文件系统不可写等限制团队放弃了在 Windows 上复制 Linux 多容器架构的路线转而构建包含全部测试工具的单容器镜像用docker exec替代docker run提升执行速度并通过-wintrue标志与 CRLF 规范化机制保证了同一套 Go 测试代码与 Bats 断言可以跨平台运行。理解 WINDOWS-TEST.md 及其配套文档与脚本是上手 Windows 下 Consul/Envoy 集成测试、乃至自行扩展 Windows 测试用例的最短路径。【免费下载链接】consulConsul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.项目地址: https://gitcode.com/gh_mirrors/con/consul创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考