Closed as not planned
Description
Testcontainers depends on Docker, and raw Docker is an issue in a Kubernetes managed environment (i.e. Jenkins X). It ends up either using the /var/run/docker.sock escape hatch or dind. Both approaches have issues. Would you like to be aiming at adding native Kubernetes support? Native Kubernetes support would even make Docker optional in a Kubernetes environment.
See also: #449
Reacted by Steve, JP Huynh, Kamil Kiewisz, Asxing , imochurad, Simas Čepaitis, Christian Brunotte, Evgeniy Zatsepin, Steve Todorov, strubel and 62 more
Reacted by lynch19
Activity
jstrachan commentedon Jan 12, 2019
it’s easy to create containers as Pods in kubernetes using a java client for kubernetes- like this one:
https://github.com/fabric8io/kubernetes-client
bsideup commentedon Jan 12, 2019
Hi @deas & @jstrachan,
First of all, I'm sure @rnorth @kiview have something to add and might have an opposite opinion, please don't read my answer as a strong position of the whole team, it is just my perspective on it :)
We, of course, want to support as many platforms as possible! But we also need to keep focus and understand the problem we're solving.
Native k8s support is something we hear quite often. But does it actually solve the problem? Or is it the problem?
Just a theoretical example: if we focus on integrating Testcontainers with runc (without Docker daemon) and root-less containers, or Kata Containers, it will work locally, on CI environments, and on k8s. Because by doing it we will solve the problem of a Docker daemon requirement.
But if we add k8s support (worth mentioning that k8s is not a container engine like Docker, but orchestrator), we will have to support two completely different ways of spinning up containers in one code base.
If somebody wants to volunteer himself to contribute & support it - that could be an option, but so far nobody did, and it means that our small team will have to develop & support both "ways".
So, do we solve a problem by supporting k8s APIs or add another one?
@jstrachan
That's true. But starting containers is a very small part of Testcontainers.
We could adapt the DSL to some extent (although we do use some Docker specific APIs in a few places). But the amount of limitations is huge. Networks can't be done the Docker way, file mounting will not work as expected (or not at all), and many more tiny details which are hidden behind Testcontainers, accumulated after years of development.
To keep the conversation going, I suggest we first define the problem and find how we can quickly solve it :)
kiview commentedon Jan 12, 2019
I agree with @bsideup regarding splitting the actual issue at hand:
1 is definitely something I'd like keep in mind when going forward with Testcontainers (at least having an internal software architecture that allows for other engines). As far as I understand, this would solve issues with JenkinsX, wouldn't it?
2 is something I could see as a different module (like we already have now with docker-compose support), but probably not something that will be built into Testcontainers core, like the container engine abstraction.
deas commentedon Jan 13, 2019
Ok, so here is my story.
Testcontainers was saving my ass wrt integration testing which requires a bunch of containers for me (on the dev box). Unfortunately, Kubernetes introduced new challenges. I just had a quick glimpse and I know pretty much nothing about Testcontainers other that it uses docker-compose under the covers.
At first I thought it should pretty much boil down to swapping docker-compose with kubernetes equivalent calls. Well in fact, they already made docker-compose play with kubernetes: https://github.com/docker/compose-on-kubernetes . Helm may be another alternative to spin things up.
Other than spinning things up, I guess you guys do various docker calls to check the state of containers and do other things, right? Hence, appears there is other functionality which should be implemented if we are aiming at parity with docker-compose.
bsideup commentedon Jan 13, 2019
Testcontainers does not use Docker Compose at all :) We have a module for it, but the core and every other container are implemented with Docker API and only it :)
kiview commentedon Jan 13, 2019
@deas I kind of like your narrative here:
This is exactly something I want to look into for some time now (but sadly didn't have the time yet), a common abstraction between Docker Compose, Docker Swarm Mode and Kubernetes, relying on the existing abstraction built into recent Docker Compose versions.
As @bsideup has mentioned, the current Docker Compose support is already implemented as its own module and we might be able to come up with something similar for the other orchestrators.
However, Docker Compose support already doesn't have real feature parity compared to using Testcontainers directly, since we are adding an additional layer of indirection, so I would expect the same for other orchestrator implementations.
deas commentedon Jan 13, 2019
Don't want to open a can of worms, but is it actually still reasonable to work on the container/pod/microvm level in Testcontainers?
kiview commentedon Jan 13, 2019
I don't really get this question, could you clarify a bit more?
People start to use Testcontainers for all kinds of use cases and we are really happy see this. We also try to support as much of them as reasonable possible.
However, we also have to look at the history and main use case of Testcontainers, which is IMO (the opinion of the other team members might differ) white box integration testing. This is where Testcontainers is strongest and where I also see the most development happening (and it's also the most probable way how people start to use Testcontainers).
Then there is an increasing amount of user which use Testcontainers for black box integration testing as well as for system testing or acceptance testing. This is also great and definitely a desired use case. However, the maximum size of those tests and systems should be as such, that they are still runnable on a local developer machine. That's how we mainly think about Testcontainers, a tool to give developers fast feedback while developing with the added benefit, of also having the same tests executed in your CI environment without any additional setup or environment duplication necessary (and we do our best here, to support as many CI systems as possible).
I'm not sure if this answers your question, but it explains why I generally struggle to see the need for actual Kubernetes integration. Still we are generally open to ideas and would greatly appreciate contributions from the Kubernetes community in order to tackle those topics.
Regarding your other question:
We are using the Docker API for multiple different features, like file mounting/copying, executing commands in containers, networking, etc.
Another big part of the Testcontainers UX are ẀaitStrategies (blocking test execution until the application in the container is ready, not just the container is running), but since they can also work in a black box way, this concepts could probably be adopted for orchestrators.
deas commentedon Jan 14, 2019
Again, just been jumping into Testcontainers so you can be sure I am missing a bit.
My use case was: Run maven integration tests on that composite. I was dropping a
docker-compose.yamland everything was fine on my dev box. I use that very same file to spin up that composite and work on the system locally. I was very surprised how easy my problems were solved so far.Hence, I was wondering why there is a need to deal with the parts (containers/pod/microvm) of that composite. And in fact WaitsStrategies and things along those lines fall in that category. Still not sure whether some of the functionality could also be covered by a tool at the composite level (e.g.
docker-composeorhelm).61 remaining items
sharkymcdongles commentedon Dec 23, 2022
kiview commentedon Dec 23, 2022
Hey @jaybi4, thanks for sharing your view.
I don't see real issues with the plans and considerations you have outlined here. You can use k8s as the executor for you GitlabCI and still use Testcontainers, since Testcontainers works equally well with a remote Docker daemon. And there are many ways to provide a remote Docker daemon for your Testcontainers workloads (you might also want to check out https://www.testcontainers.cloud/, which greatly mitigates any kind of "works on my machine issues").
In addition, the alternatives for Docker Desktop we see emerging tend to provide Docker compatible REST-APIs (Colima, Rancher Desktop, Podman Desktop). While they don't provide a 100% compatible API in all cases, they are doing a good job improving in the recent pasts. That's also the reason why Testcontainers works with those Docker Desktop alternatives if configured correctly.
I think this is not a factor that influences which API to use for creating and instrumenting ephemeral integration testing environments. We also see users switching to Cloud IDEs (such as Codespaces), how would they work with Testcontainers if Testcontainers uses k8s as its container runtime environment? How would CIs such as GitHub Actions work? In my opinion, this would simply create an even bigger external dependency (having k8s available instead of having a Docker daemon available). Or we would need to develop another abstraction layer, which allows either Docker or k8s as the container runtime. And while this might be theoretically possible, there are big risks of an impedance mismatch in concepts between Docker and k8s and it would be a considerable engineering effort.
I'd also like to point out, that Testcontainers supports testing of k8s components, through our k3s module or https://github.com/dajudge/kindcontainer.
So when we talk about k8s support, it is often difficult to understand what is meant with k8s support, depending on the context.
jaybi4 commentedon Dec 23, 2022
Thanks a lot @sharkymcdongles , I'll keep this for the future me😁
@kiview thanks for your complete answer. Maybe the fact that I haven't tried yet to integrate Testcontainers and k8s is what makes my issues not real. In that case, thanks again for the clarification. I'll forward any issues/concerns I face when I'll integrate Testcontainers and k8s.
sharkymcdongles commentedon Dec 23, 2022
@kiview what people mean by k8s support would mean deploying containers directly into k8s and running tests there rather than via a local docker daemon. So instead of docker compose up, you would deploy multiple containers as pods or as a single pod to k8s where the tests would run.
One option(this is just a very basic example I wrote in 1 min and not fully fleshed out and is provided as a simple example): testcontainers runs outside the cluster and uses a kubeconfig or other auth to a kubeapi for a cluster, which will then deploy all of the various containers needed to run the tests. In this instance, there is no docker daemon involved meaning it will run with any container runtime interface since kubernetes would be handling the deployment and running of the containers. You also wouldn't need socat container since calls would be able to run via the kube internal networking or via localhost if the jobs are spun up in a singular pod.
Even if kubernetes support like the above isn't something on the radar I would at least thing native support for containerd would be a nice addition since docker is losing out more and more everyday.
kiview commentedon Dec 23, 2022
This is what some people mean, while others simply mean being able to run Testcontainers based tests in their k8s powered CI, the reality is much more complex 😉 (as is an implementation of k8s as the container runtime, as also others have found out in the past).
Can you back this up with data in the context of development (not operations)? It does not really reflect what I perceive as a Testcontainers maintainer, supporting a wide range of different users.
I hope this answer and the previous answers by me and @bsideup in this thread help to understand the view of the Testcontainers project on this topic. We don't plan to dive into more discussions around this in the short-term future.
sharkymcdongles commentedon Dec 23, 2022
This is already achievable as I showed above and works fine. It would just be nice to not need privileged containers to do it, but this isn't a problem from testcontainers.
You shouldn't need to do anything with the k8s container runtime to implement this. To do this you would generate objects to pass to the kubeapi. There shouldn't be any need to touch the container runtime directly. The most complicated issue would be adjusting the library to generate manifests instead of deploying directly to the docker socket because this would be fully new code and not reusable or even repurposable. I suppose you could make some shim thing to translate the docker plans into k8s manifests to make it easier and then it is just spec transformation instead of actual logic. Then the way to verify and fetch logs and metrics would also need it's own adjustment.
But yes it is a larger effort than a quick one.
It isn't about operations so much as it is about the ecosystem around containers in general. Many Linux distros are phasing out or dumping docker completely e.g. Fedora, RHEL, and CentOS:
https://access.redhat.com/solutions/3696691
When you install "docker" on newer versions, you actually get podman with an aliased wrapper to mimic docker instead. Ubuntu seems to be following suit as well. Kubernetes also killed docker completely and now uses containerd or crio. In general, we will see this trend continue especially now that Kubernetes and GCP are pushing non-docker setups heavily.
Another reason why switching makes sense is performance. Docker is more of a shim/api for talking to containerd and then allowing containerd to create cgroups and processes. With podman and more current implementations, this entire shim layer is removed allowing for direct communication with containerd meaning pulls are quicker, containers perform better and containers boot up faster. By some metrics, you can see 30% compute performance increases. I can try and dig some up after the holiday if you want because I am on mobile right now and heading out for the weekend.
@kiview
seveneves commentedon Dec 28, 2022
@sharkymcdongles
The link doesn't work. Can you please repost it as code in github? It'd be a great resource for someone like me moving to gitlab
sharkymcdongles commentedon Dec 28, 2022
Sorry, I thought I put it to never expire. I added it there because for some reason code formatting wasn't working on GitHub. It may still not work, but are my helm values for the gitlab-runner helm chart:
The mounts are integral to this working because of overlay2. You also need to ensure you use ubuntu containerd nodes and the ubuntu image for the runner image due to the kernel patch for overlay2.
Then you can just run jobs as normal by setting the service image to dind-rootless instead of dind e.g.
spuranam commentedon Mar 28, 2023
Anyone tried https://github.com/joyrex2001/kubedock
rcgeorge23 commentedon Apr 27, 2023
Yes, we’re kubedock pretty successfully for testing (reasonably large london fintech). We are still ironing out some issues but generally it seems pretty stable.
olivierboudet commentedon Apr 27, 2023
I use it also for a single project, no issue.
jonesbusy commentedon Jan 16, 2024
No issues with testcontainer java and node. But not able to make it work for .NET. Looks like kubedock doesn't create bind sidecar to mount the socket for ryuk reapper. But only happen for dotnet container.
If anyone is facing the same... I'm not sure where the problem is
ketanbijwe commentedon Feb 8, 2024
This solved my problem of running testcontainer for the test (in maven) in EKS 1.24
ErikEngerd commentedon Aug 26, 2024
Since remote docker daemons are supported, it would also be possible to run a virtual machine with a docker setup inside a kubernetes pod using kubevirt (kubevirt.io). I have used kubevirt in the past and that works quite well and robust. The VM could be a simple debian VM with a docker daemon providing remote access. Then create your test pod as usual with, for jenkins for example, an agent container, other containers you need, and kubevirt. Then all would work transparently and much better then having to host one big VM for all docker jobs. Also from the networking side it would easy since 'localhost' can still be used.
The issues with kuberntes are real, it is just more complex having to manage VMs outside of kubernetes but since you can also use kubevirt it all becomes more easily manageable from within kubernetes.
jglick commentedon Aug 26, 2024
Since running a Docker daemon inside a Kubernetes cluster ranges from tricky to (in a properly secured cluster) impossible, I think the only satisfactory “Kubernetes support” would mean having TC APIs transparently switch to creating
Pods, either directly or via an intermediate service. Whatever process directly creates the pods would need to be authorized to create, managed, and delete pods in a specific namespace, preferably one separate from that where test code runs. (Hierachical Namespace Controller would make this easier to manage and secure.) My understanding is that such a switch of backend is out of scope for the project currently.