如何使用Testcontainers的K3容器为对接Kubernetes与Argo Workflows的Java/Spring Boot应用搭建集成测试及本地开发环境?
我太懂这种需求了!之前一直靠Minikube搭本地K8s环境,现在想换成Testcontainers的K3s来做集成测试和本地开发,既能保持轻量化,还能把K8s环境和测试流程深度绑定,确实香。下面我一步步给你拆解怎么实现:
一、先把项目依赖配好
首先得把Testcontainers的K3s模块加到你的Java/Spring Boot项目里,不管用Maven还是Gradle都很简单:
Maven 依赖
<dependency> <groupId>org.testcontainers</groupId> <artifactId>k3s</artifactId> <version>最新稳定版</version> <scope>test</scope> </dependency> <!-- 测试里要操作K8s和Argo的话,加上Kubernetes Client依赖 --> <dependency> <groupId>io.kubernetes</groupId> <artifactId>client-java</artifactId> <version>和K3s版本兼容的稳定版</version> <scope>test</scope> </dependency>
Gradle 依赖
testImplementation 'org.testcontainers:k3s:最新稳定版' testImplementation 'io.kubernetes:client-java:和K3s版本兼容的稳定版'
二、启动K3s Testcontainer并配置集群
接下来在你的测试类(或者专门的环境配置类)里启动K3s容器,这里有几个关键配置必须注意:允许集群外部访问、暴露API端口、可选禁用Traefik避免和Argo的端口冲突:
import org.testcontainers.k3s.K3sContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.junit.jupiter.api.BeforeAll; @Testcontainers public class ArgoWorkflowIntegrationTest { // 启动K3s容器,指定镜像版本,禁用Traefik,允许外部访问API @Container public static final K3sContainer K3S = new K3sContainer("rancher/k3s:v1.27.3-k3s1") .withCommand("server --disable=traefik --tls-san=0.0.0.0") .withExposedPorts(6443); // 测试前初始化Kubernetes Client的配置 @BeforeAll static void setupKubernetesClient() { // 从容器里导出kubeconfig内容 String kubeConfig = K3S.getKubeConfigYaml(); // 把kubeconfig传给Kubernetes Client ApiClient client = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new StringReader(kubeConfig))).build(); Configuration.setDefaultApiClient(client); // 也可以把kubeconfig设置到系统属性,方便其他组件读取 System.setProperty("kubernetes.config", kubeConfig); } }
这里解释下:--tls-san=0.0.0.0是让K3s的API server接受你的本地机器请求,--disable=traefik是因为后面要装Argo,避免端口冲突,如果你不需要可以直接去掉。
三、在K3s里安装Argo Workflows
K3s启动后,我们得在里面装上Argo Workflows。为了测试环境稳定,建议你提前把Argo官方的安装YAML(比如quick-start配置)下载到项目的src/test/resources目录下,然后通过以下步骤安装:
@BeforeAll static void installArgoWorkflows() throws IOException, InterruptedException { // 第一步:创建Argo专属的命名空间 K3S.execInContainer("kubectl", "create", "namespace", "argo"); // 第二步:把本地的Argo安装YAML复制到K3s容器内 MountableFile argoYaml = MountableFile.forClasspathResource("argo-quickstart.yaml"); K3S.copyFileToContainer(argoYaml, "/tmp/argo-quickstart.yaml"); // 第三步:执行安装命令 K3S.execInContainer("kubectl", "apply", "-n", "argo", "-f", "/tmp/argo-quickstart.yaml"); // 第四步:等待Argo的所有Pod都启动完成,确保环境就绪 K3S.execInContainer("kubectl", "wait", "--for=condition=ready", "pod", "-n", "argo", "--all", "--timeout=5m"); }
四、Spring Boot应用适配这个K3s集群
不管是测试还是本地开发,你的Spring Boot应用都得知道怎么连接这个K3s集群:
测试环境适配
在测试方法里,你可以直接用初始化好的Kubernetes Client来操作Argo Workflows,比如提交一个简单的测试工作流并验证状态:
@Test void testSubmitArgoWorkflow() throws ApiException { // 初始化Argo的WorkflowClient WorkflowClient workflowClient = new WorkflowClient(); workflowClient.setApiClient(Configuration.getDefaultApiClient()); // 构建一个简单的测试工作流 Workflow workflow = new Workflow() .apiVersion("argoproj.io/v1alpha1") .kind("Workflow") .metadata(new ObjectMeta().name("test-workflow").namespace("argo")) .spec(new WorkflowSpec() .templates(Collections.singletonList(new WorkflowTemplate() .name("hello") .container(new Container() .image("alpine:3.18") .command(Arrays.asList("echo", "Hello Argo!")))) ) .entrypoint("hello")); // 提交工作流 workflowClient.createNamespacedWorkflow("argo", workflow, null, null, null); // 等待工作流完成并验证状态 Workflow result = workflowClient.readNamespacedWorkflow("test-workflow", "argo", null, null, null); assertEquals("Succeeded", result.getStatus().getPhase()); }
本地开发环境适配
如果要在本地开发时用这个Testcontainers的K3s集群,你可以:
- 写一个单独的启动类,启动K3s容器后,把kubeconfig导出到本地的
~/.kube/config(或者临时文件) - 然后在Spring Boot的
application-dev.yml里配置Kubernetes Client的地址:
kubernetes: config: file:${user.home}/.kube/config api-server-url: ${K3S_API_URL:https://localhost:6443}
这样你本地运行的Spring Boot应用就能直接连接到Testcontainers启动的K3s集群了。
五、一些避坑小贴士
- 端口冲突:如果你的本地6443端口被占用,可以给K3s容器映射到其他端口,比如
.withPortBindings(new PortBinding(Ports.Binding.bindPort(6444), new ExposedPort(6443))),然后把应用的API地址改成https://localhost:6444 - 资源限制:K3s虽然轻量,但运行Argo还是需要一定资源,可以给容器设置内存和CPU限制:
.withResources(new ResourceRequirement().withMemory("4g").withCpu("2")) - 权限问题:测试环境里可以给默认服务账号绑定
cluster-admin角色,确保有足够权限操作Argo Workflows,生产环境可千万别这么干
内容来源于stack exchange

