{"id":16799999,"url":"https://github.com/dajudge/kindcontainer","last_synced_at":"2025-04-04T17:06:23.962Z","repository":{"id":36958761,"uuid":"232764255","full_name":"dajudge/kindcontainer","owner":"dajudge","description":"Testcontainers that start Kubernetes in Docker.","archived":false,"fork":false,"pushed_at":"2024-10-08T18:11:24.000Z","size":607,"stargazers_count":108,"open_issues_count":10,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-14T09:31:09.912Z","etag":null,"topics":["java","kubernetes","testing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dajudge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-09T08:51:24.000Z","updated_at":"2024-10-08T05:29:04.000Z","dependencies_parsed_at":"2023-11-14T14:29:14.677Z","dependency_job_id":"e6ccdba4-5963-4b8e-94e0-b8915ca32563","html_url":"https://github.com/dajudge/kindcontainer","commit_stats":null,"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajudge%2Fkindcontainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajudge%2Fkindcontainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajudge%2Fkindcontainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dajudge%2Fkindcontainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dajudge","download_url":"https://codeload.github.com/dajudge/kindcontainer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247217175,"owners_count":20903009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","kubernetes","testing"],"created_at":"2024-10-13T09:30:25.270Z","updated_at":"2025-04-04T17:06:23.944Z","avatar_url":"https://github.com/dajudge.png","language":"Java","readme":"[![CI](https://github.com/dajudge/kindcontainer/actions/workflows/build.yaml/badge.svg)](https://github.com/dajudge/kindcontainer/actions/workflows/build.yaml)\n[![Maven central](https://img.shields.io/maven-central/v/com.dajudge.kindcontainer/kindcontainer)](https://search.maven.org/artifact/com.dajudge.kindcontainer/kindcontainer)\n\nKindcontainer\n---\nA Java-based [Testcontainers](https://www.testcontainers.org/) container implementation that provides ephemeral\nKubernetes clusters for integration testing.\n\n\u003c!-- TOC --\u003e\n  * [Kindcontainer](#kindcontainer)\n* [Container Flavors](#container-flavors)\n* [Usage](#usage)\n  * [Add dependency](#add-dependency)\n    * [Maven](#maven)\n    * [Gradle](#gradle)\n  * [Use in JUnit 4 test](#use-in-junit-4-test)\n    * [With `KindContainer`](#with-kindcontainer)\n    * [With `K3sContainer`](#with-k3scontainer)\n    * [With `ApiServerContainer`](#with-apiservercontainer)\n* [Quick guides](#quick-guides)\n  * [Running different versions of Kubernetes](#running-different-versions-of-kubernetes)\n  * [Using the `kubectl` and `helm` fluent APIs](#using-the-kubectl-and-helm-fluent-apis)\n  * [Using custom docker images](#using-custom-docker-images)\n    * [Kubernetes images](#kubernetes-images)\n    * [`kubectl` and `helm` images for fluent APIs](#kubectl-and-helm-images-for-fluent-apis)\n    * [`etcd` image for `ApiServerContainer`](#etcd-image-for-apiservercontainer)\n    * [`sshd` and `nginx` image for webhook testing](#sshd-and-nginx-image-for-webhook-testing)\n  * [Testing admission webhooks](#testing-admission-webhooks)\n* [Examples](#examples)\n\u003c!-- TOC --\u003e\n\n# Container Flavors\n\nThe Kindcontainer libraries offers three different Kubernetes container implementations:\n\n* `ApiServerContainer`\n* `K3sContainer`\n* `KindContainer`\n\nWhile `ApiServerContainer` (as the name suggests) starts only a Kubernetes API Server (plus the required etcd),\nboth `K3sContainer` and `KindContainer` are feature rich Kubernetes containers that can e.g. spin up `Pods`\nand even provision `PersistentVolumes`.\n\n# Usage\n\n## Add dependency\n\nFirst you need to add the Kindcontainer dependency to your build. Kindcontainer is available on maven central.\n\n### Maven\n\nAdd the Kindcontainer dependency:\n\n```xml\n\n\u003cproject\u003e\n    \u003cdependencies\u003e\n        \u003cdependency\u003e\n            \u003cgroupId\u003ecom.dajudge.kindcontainer\u003c/groupId\u003e\n            \u003cartifactId\u003ekindcontainer\u003c/artifactId\u003e\n            \u003cversion\u003e1.4.6\u003c/version\u003e\n            \u003cscope\u003etest\u003c/scope\u003e\n        \u003c/dependency\u003e\n    \u003c/dependencies\u003e\n\u003c/project\u003e\n```\n\n### Gradle\n\nAdd the Kindcontainer dependency:\n\n```groovy\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    testImplementation \"com.dajudge.kindcontainer:kindcontainer:1.4.6\"\n}\n```\n\n## Use in JUnit 4 test\n\nOnce you have the Kindcontainer dependency configured you can create JUnit test case easily.\n\n### With `KindContainer`\n\n```java\npublic class SomeKindTest {\n    @ClassRule\n    public static final KindContainer\u003c?\u003e KUBE = new KindContainer\u003c\u003e();\n\n    @Test\n    public void verify_node_is_present() {\n        // Create a fabric8 client and use it!\n        try (KubernetesClient client = new DefaultKubernetesClient(fromKubeconfig(KUBE.getKubeconfig()))) {\n            assertEquals(1, client.nodes().list().getItems().size());\n        }\n    }\n}\n```\n\nLook [here](src/test/java/com/dajudge/kindcontainer/readme/junit4/SomeKindTest.java) for the reference test.\n\n### With `K3sContainer`\n\n```java\npublic class SomeK3sTest {\n    @ClassRule\n    public static final K3sContainer\u003c?\u003e K3S = new K3sContainer\u003c\u003e();\n\n    @Test\n    public void verify_node_is_present() {\n        // Create a fabric8 client and use it!\n        try (KubernetesClient client = new DefaultKubernetesClient(fromKubeconfig(K3S.getKubeconfig()))) {\n            assertEquals(1, client.nodes().list().getItems().size());\n        }\n    }\n}\n```\n\nLook [here](src/test/java/com/dajudge/kindcontainer/readme/junit4/SomeK3sTest.java) for the reference test.\n\n### With `ApiServerContainer`\n\nIf you don't need a full-fledged Kubernetes distribution for your testing, using the `ApiServerContainer`\nmight be an option for you that shaves off a lot of the startup overhead of the `KindContainer`. The\n`ApiServerContainer` only starts a Kubernetes API-Server (and the required etcd), which can already be enough\nif all you want to test is if your custom controller/operator handles its CRDs properly or creates the required\nobjects in the control plane.\n\n```java\npublic class SomeApiServerTest {\n    @ClassRule\n    public static final ApiServerContainer\u003c?\u003e KUBE = new ApiServerContainer\u003c\u003e();\n\n    @Test\n    public void verify_no_node_is_present() {\n        // Create a fabric8 client and use it!\n        try (KubernetesClient client = new DefaultKubernetesClient(fromKubeconfig(KUBE.getKubeconfig()))) {\n            assertTrue(client.nodes().list().getItems().isEmpty());\n        }\n    }\n}\n```\n\nLook [here](src/test/java/com/dajudge/kindcontainer/readme/junit4/SomeApiServerTest.java) for the reference test.\n\n# Quick guides\n\nHere's a couple challenges frequently seen in the wild and how you can solve them with Kindcontainer.\n\n## Running different versions of Kubernetes\n\nKindcontainer supports running different (selected and tested) versions of Kubernetes. The default version is the\nlatest supported stable version for each container. You can change the version by passing a version enum to the\nconstructor. The following example illustrates this process for the `KindContainer` implementation, but it works\nanalogous for the other two containers as well.\n\n```java\nKindContainer\u003c?\u003e container=new KindContainer\u003c\u003e(KindContainerVersion.VERSION_1_24_1);\n```\n\n## Using the `kubectl` and `helm` fluent APIs\n\nKindcontainer makes it easy to perform common tasks either during setup of the container\nor later on during the test by offering fluent APIs to the `kubectl` and `helm` commands.\n\nIf you're acquainted with the `kubectl` and `helm` commands, you'll feel right at home with\nthe fluent APIs in no time.\n\nYou can use them directly during container instantiation like this:\n\n```java\n// Kubectl example\npublic class SomeKubectlTest {\n    @ClassRule\n    public static final ApiServerContainer\u003c?\u003e KUBE = new ApiServerContainer\u003c\u003e()\n            .withKubectl(kubectl -\u003e {\n                kubectl.apply\n                        .fileFromClasspath(\"manifests/serviceaccount1.yaml\")\n                        .run();\n            });\n}\n\n// Helm3 example\npublic class SomeHelmTest {\n    @ClassRule\n    public static final KindContainer\u003c?\u003e KUBE = new KindContainer\u003c\u003e()\n            .withHelm3(helm -\u003e {\n                helm.repo.add.run(\"mittwald\", \"https://helm.mittwald.de\");\n                helm.repo.update.run();\n                helm.install\n                        .namespace(\"kubernetes-replicator\")\n                        .createNamespace()\n                        .run(\"kubernetes-replicator\", \"mittwald/kubernetes-replicator\");\n            });\n}\n```\n\nThe fluent APIs are far from complete, but they cover the most common use cases. If you're\nmissing a command, feel free to open an issue or even better, a pull request.\n\n## Using custom docker images\n\nIn some environments it might be necessary to use custom docker images for the containers Kindcontainer starts.\n\n___Attention___: You need to make sure that the images you are using are compatible with the images used by\nkindcontainer\nby default. These are the images used by Kindcontainer if you don't override them:\n\n|         Purpose         |              Image               |              Version               |\n|:-----------------------:|:--------------------------------:|:----------------------------------:|\n|  `ApiServerContainer`   | `registry.k8s.io/kube-apiserver` |   `v${major}.${minor}.${patch}`    |\n|     `K3sContainer`      |          `rancher/k3s`           | `v${major}.${minor}.${patch}-k3s1` |\n|     `KindContainer`     |          `kindest/node`          |   `v${major}.${minor}.${patch}`    |\n|         `etcd`          |      `registry.k8s.io/etcd`      |             `3.5.12-0`             |\n|    Fluent API `helm`    |          `alpine/helm`           |              `3.14.0`              |\n|  Fluent API `kubectl`   |        `bitnami/kubectl`         |       `1.21.9-debian-10-r10`       |\n|    Webhooks `nginx`     |             `nginx`              |              `1.23.3`              |\n| Webhooks OpenSSH Server |   `linuxserver/openssh-server`   |          `9.0_p1-r2-ls99`          |         \n\n### Kubernetes images\n\nYou can customize the docker image of the Kubernetes container you're starting. This can be\nby suffixing the kubernetes version you want to run with a call to `withImage()` like this:\n\n```java\nKindContainer\u003c?\u003e container = new KindContainer\u003c\u003e(KindContainerVersion.VERSION_1_24_1.withImage(\"my-registry.com/kind:1.24.1\"));\n```\n\n### `kubectl` and `helm` images for fluent APIs\n\nThe fluent APIs for  `helm` and `kubectl` are implemented using support containers. To customize which images are being\nused to start those support containers you can use the `withKubectlImage()` and `withHelm3Image()` methods:\n\n```java\nK3sContainer\u003c?\u003e container = new K3sContainer\u003c\u003e()\n        .withKubectlImage(DockerImageName.parse(\"my-registry/kubectl:1.21.9-debian-10-r10\"))\n        .withHelm3Image(DockerImageName.parse(\"my-registry/helm:3.7.2\"));\n```\n\n### `etcd` image for `ApiServerContainer`\n\n`ApiServerContainer` has a hard dependency on `etcd` that's started in a separate container. To customize which image is\nbeing used to start that support container use method `withEtcdImage()`:\n\n```java\nApiServerContainer\u003c?\u003e container = new ApiServerContainer\u003c\u003e().withEtcdImage(DockerImageName.parse(\"my-registry.com/etcd:.4.13-0\"));\n```\n\n### `sshd` and `nginx` image for webhook testing\n\nTesting dynamic admission control webhooks requires support containers with `nginx` and `sshd`. To customize which\nimages\nare being used to start those support containers use the `withNginxImage()` and `withOpensshServerImage()` methods.\n\n```java\nApiServerContainer\u003c?\u003e container = new ApiServerContainer()\n        .withNginxImage(DockerImageName.parse(\"my-registry/nginx:1.23.3\"))\n        .withOpensshServerImage(DockerImageName.parse(\"my-registry/openssh-server:9.0_p1-r2-ls99\"));\n```\n\n## Testing admission webhooks\nYou can use Kindcontainer to test your admission controllers.\n* Make sure you start your webhooks before you start the Kindcontainer\n* Start your webhooks without HTTPS/TLS\n* Make sure your webhooks listen at `http://localhost:\u003cport\u003e`\n* Register each webhook with `withAdmissionController()`\n\nExample:\n```java\nApiServerContainer\u003c?\u003e container = new ApiServerContainer().withAdmissionController(admission -\u003e {\n          admission.validating()    // use mutating() for a mutating admission controller\n            .withNewWebhook(\"validating.kindcontainer.dajudge.com\")\n              .atPort(webhookPort)\n              .withNewRule()\n                .withApiGroups(\"\")\n                .withApiVersions(\"v1\")\n                .withOperations(\"CREATE\", \"UPDATE\")\n                .withResources(\"configmaps\")\n                .withScope(\"Namespaced\")\n              .endRule()\n            .endWebhook()\n            .build();\n        })\n```\n\n# Examples\n\nYou can find examples in the [kindcontainer-examples](https://github.com/dajudge/kindcontainer-examples) repository.\n","funding_links":[],"categories":["Testcontainers and Kubernetes","测试"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdajudge%2Fkindcontainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdajudge%2Fkindcontainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdajudge%2Fkindcontainer/lists"}