在 Java 测试中使用 Podman 测试容器

Evg*_*yst 14 testcontainers podman testcontainers-junit5

是否可以在 Java 测试中将 Testcontainers 与 Podman 一起使用?

截至 2022 年 3 月,Testcontainers 库未将已安装的 Podman 检测为有效的 Docker 环境。

Podman 可以在采用 Apple 芯片的 MacOS(本地开发环境)和 Linux x86_64(CI/CD 环境)上替代 Docker 吗?

Evg*_*yst 21

可以在 Java 项目中将 Podman 与 Testcontainers 一起使用,该项目在 Linux 和 MacOS(x86_64 和 Apple 芯片)上使用 Gradle。

先决条件

启用 Podman 服务

Testcontainers 库使用套接字文件与 Podman 进行通信。

Linux

为普通用户(无根)启动 Podman 服务并使其监听套接字:

systemctl --user enable --now podman.socket
Run Code Online (Sandbox Code Playgroud)

检查 Podman 服务状态:

systemctl --user status podman.socket
Run Code Online (Sandbox Code Playgroud)

检查套接字文件是否存在:

ls -la /run/user/$UID/podman/podman.sock
Run Code Online (Sandbox Code Playgroud)

苹果系统

Podman 套接字文件/run/user/1000/podman/podman.sock可以在 Podman 管理的 Linux VM 中找到。MacOS 上的本地套接字可以使用 SSH 隧道转发到 Podman 管理的虚拟机上的远程套接字。

可以使用命令找到 Podman 管理的虚拟机的端口podman system connection list --format=json

安装jq来解析JSON:

brew install jq
Run Code Online (Sandbox Code Playgroud)

创建 shell 别名以将本地套接字转发/tmp/podman.sock到远程套接字/run/user/1000/podman/podman.sock

echo "alias podman-sock=\"rm -f /tmp/podman.sock && ssh -i ~/.ssh/podman-machine-default -p \$(podman system connection list --format=json | jq '.[0].URI' | sed -E 's|.+://.+@.+:([[:digit:]]+)/.+|\1|') -L'/tmp/podman.sock:/run/user/1000/podman/podman.sock' -N core@localhost\"" >> ~/.zprofile
source ~/.zprofile
Run Code Online (Sandbox Code Playgroud)

打开 SSH 隧道:

podman-sock
Run Code Online (Sandbox Code Playgroud)

在使用测试容器执行测试之前,请确保 SSH 隧道已打开。

配置 Gradle 构建脚本

build.gradle

test {
    OperatingSystem os = DefaultNativePlatform.currentOperatingSystem;
    if (os.isLinux()) {
        def uid = ["id", "-u"].execute().text.trim()
        environment "DOCKER_HOST", "unix:///run/user/$uid/podman/podman.sock"
    } else if (os.isMacOsX()) {
        environment "DOCKER_HOST", "unix:///tmp/podman.sock"
    }
    environment "TESTCONTAINERS_RYUK_DISABLED", "true"
}
Run Code Online (Sandbox Code Playgroud)

DOCKER_HOST根据操作系统将环境变量设置为 Podman 套接字文件。

使用环境变量禁用 Ryuk TESTCONTAINERS_RYUK_DISABLED

Moby Ryuk可帮助您在指定的延迟后通过给定的过滤器删除容器/网络/卷/图像。

Ryuk 是 Docker 的技术,不支持 Podman。请参阅testcontainers/moby-ryuk#23

Testcontainers 库使用 Ruyk 来删除容器。我们将使用 JVM 关闭钩子显式删除容器,而不是依赖 Ryuk 隐式删除容器:

Runtime.getRuntime().addShutdownHook(new Thread(container::stop));
Run Code Online (Sandbox Code Playgroud)

传递环境变量

作为在 Gradle 构建脚本中配置 Testcontainers 的替代方法,您可以将环境变量传递给 Gradle。

Linux

DOCKER_HOST="unix:///run/user/$UID/podman/podman.sock" \
TESTCONTAINERS_RYUK_DISABLED="true" \
./gradlew clean build -i
Run Code Online (Sandbox Code Playgroud)

苹果系统

DOCKER_HOST="unix:///tmp/podman.sock" \
TESTCONTAINERS_RYUK_DISABLED="true" \
./gradlew clean build -i
Run Code Online (Sandbox Code Playgroud)

完整示例

请参阅完整示例https://github.com/evgeniy-khist/podman-testcontainers


Hol*_*ins 13

我能够以 Evginiy 的出色答案为基础,因为自最初的答案以来,Podman 已经有所改进。在 Mac OS 上,这些步骤对我来说已经足够了,并且让 testcontainers 感到高兴:

编辑~/.testcontainers.properties并添加以下行

ryuk.container.privileged=true
Run Code Online (Sandbox Code Playgroud)

然后运行以下命令

brew install podman
podman machine init
sudo /opt/homebrew/Cellar/podman/4.0.3/bin/podman-mac-helper install
podman machine set --rootful
podman machine start
Run Code Online (Sandbox Code Playgroud)

如果您不想运行 rootful podman,则需要禁用 ryuk:

export TESTCONTAINERS_RYUK_DISABLED="true"
Run Code Online (Sandbox Code Playgroud)

不使用 ryuk 运行基本上可以工作,但延迟容器有时会在自动化测试中导致问题和名称冲突。Evginiy 的关闭挂钩建议可以解决此问题,但需要更改代码。


Gaë*_*l J 8

对于 Linux,它绝对有效,尽管官方 testcontainers 文档对此不太清楚。

# Enable socket
systemctl --user enable podman.socket --now

# Export env var expected by Testcontainers
export DOCKER_HOST=unix:///run/user/${UID}/podman/podman.sock
export TESTCONTAINERS_RYUK_DISABLED=true
Run Code Online (Sandbox Code Playgroud)

资料来源: