/k3s-dind

k3s - Lightweight Kubernetes inside a Docker-in-Docker container

Primary LanguageShellApache License 2.0Apache-2.0

k3s-dind

Lightweight k3s Kubernetes inside a Docker-in-Docker container

Quick Start

docker run -d --privileged --name k3s --hostname k3s -p 8443:8443 unboundedsystems/k3s-dind
docker exec k3s get-kubeconfig.sh > ./k3sconfig
export KUBECONFIG=./k3sconfig

kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
k3s       Ready     <none>    1m        v1.14.1-k3s.4

kubectl create ...

What is k3s-dind?

k3s-dind allows you to quickly create a lightweight local Kubernetes cluster, self-contained inside a single Docker-in-Docker (DinD) container.

What would I use it for?

k3s-dind is awesome for:

  • Quickly running automated unit tests in Kubernetes
  • Running your containerized app locally for easier debugging
  • Testing out automation or changes to a Kubernetes cluster
  • Ensuring you're starting with a fresh cluster every time
  • Doing all that stuff in only 512MB of RAM!

Exposing network services

Docker host networking

The Quick Start example above uses Docker's host networking, using the -p 8443:8443 option to docker run to expose the Kubernetes API port. To run Kubernetes services and make them available outside the cluster, you would need to use additional -p options to docker run, because Docker doesn't support exposing additional host networking ports after the container has been started.

For example, to allow your Docker host to connect to a Kubernetes service running on port 8080, you'd need to start k3s-dind like this:

docker run -d --privileged --name k3s --hostname k3s -p 8443:8443 -p 8080:8080 unboundedsystems/k3s-dind

Docker named networks

For more dynamic environments, you can also use k3s-dind with named Docker networks, such as a bridge network. Then, any other containers on the same named network with k3s-dind can access any Kubernetes services exposed by the k3s-dind cluster.

First, create a Docker network, then run k3s-dind attached to that network:

docker network create mynetwork
docker run -d --privileged --name k3s --hostname k3s --network mynetwork unboundedsystems/k3s-dind

# The second argument to get-kubeconfig.sh is the container name of k3s-dind
docker exec k3s get-kubeconfig.sh -yaml k3s > ./k3sconfig

Now, any container on mynetwork can access any service exposed by the k3s-dind cluster:

# Run a container that's on mynetwork and mount the kubeconfig
docker run --rm -it -v ${PWD}/k3sconfig:/k3sconfig --network mynetwork k3integrations/kubectl

# Now we're inside the container we just ran
export KUBECONFIG=/k3sconfig

kubectl get all
NAME             CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
svc/kubernetes   10.43.0.1    <none>        443/TCP   10m

Changing k3s API server port

There are situations where you prefer to use port other than 8443 for k3s API server. For example, you want port 8443 to get ingress traffic, and to use port 6000 (for example) as the "Kubernetes API port". In this case you can use the K3S_API_PORT environment variable like this:

docker run -d --privileged --name k3s --hostname k3s -p 8443:8443 -p 6000:6000 -e K3S_API_PORT=6000 unboundedsystems/k3s-dind

You made Kubernetes that small??

Nope! The awesome folks over at Rancher Labs did all the hard work of creating k3s. We just packaged it into a Docker-in-Docker container.