Kubernetes and Docker: Connecting an App in Kind to Docker

Kind stands for kubernetes in docker and is a tool for running a local kubernetes cluster where docker containers act as nodes. This is a great way to get started learning and using kubernetes before relying on a cloud provider. It nicely integrates with tooling, is thoroughly documented, supports mutlti-node clusters and is CNCF certified conformant kubernetes installer. We will be using Kind to deploy an application and then connecting it with a service that was deployed via docker compose. Let’s get started!
Once again we will be using the Python application that we used from our earlier article. If you want to see how to connect multiple docker services together, you can go and check it out! Let’s start by getting Kind setup.
Kind Setup⌗
First make sure that you have the Kind cli installed, which can be found here. It should look like this after installation:
$ kind
kind creates and manages local Kubernetes clusters using Docker container 'nodes'
Usage:
kind [command]
Available Commands:
build Build one of [node-image]
completion Output shell completion code for the specified shell (bash, zsh or fish)
create Creates one of [cluster]
delete Deletes one of [cluster]
export Exports one of [kubeconfig, logs]
get Gets one of [clusters, nodes, kubeconfig]
help Help about any command
load Loads images into nodes
version Prints the kind CLI version
Flags:
-h, --help help for kind
--loglevel string DEPRECATED: see -v instead
-q, --quiet silence all stderr output
-v, --verbosity int32 info log verbosity, higher value produces more output
--version version for kind
Use "kind [command] --help" for more information about a command.
Create a kind cluster:
kind create cluster
Create a local docker image for the application and from within the repo run:
docker build -t poetryanimaldb:1.0 .
Load the image into the cluster with:
kind load docker-image poetryanimaldb:1.0
Set up Postgres via Docker⌗
To set up the postgres container, we are going to use docker compose. You may notice in the repo that there are two files for docker compose. compose.yaml
is for connecting to a running docker container and the other one, compose.kind.yaml
we will be using to connect to kind
.
When we look at the file, the most important part is the top-level element networks
. Since the kind
network was created earlier when we created the Kind
cluster, the external: true
tells docker that the network’s lifecycle is mantained outside of this application and therefore it will not attempt to create it.
The services.postgresql.networks
is used to connect the container to the network.
services:
postgresql:
container_name: postgresql-1
image: postgres:15
environment:
- POSTGRES_DB
- POSTGRES_USER
- POSTGRES_PASSWORD
ports:
- ${POSTGRES_PORT}:5432
restart: always
volumes:
- db_data:/var/lib/postgresql/data
# this is used to connect to the container to the network
networks:
- kind
volumes:
db_data:
networks:
kind:
external: true
To start the docker container:
docker compose -f compose.kind.yaml up -d
Deploy Application to Kind⌗
To interact with the cluster, first make sure that kubectl
is installed - Installation
To use the context with kubectl
:
kubectl cluster-info --context kind-kind
You should see the follwing when running kubectl config current-context
:
$ kubectl config current-context
kind-kind
From within the kubernetes/
folder there is a deployment
manifest that will create 1 pod via a ReplicaSet. The image that we built earlier will be the image that is run in the container from within the pod.
Inside the same folder, there is also a service
manifest which deploys a service of type ClusterIP
. Which makes it only available from within the cluster.
To deploy the application to Kind, apply the files to the cluster:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Use kubectl get services
and kubectl get pods
to check that they are running appropriately
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
python-service ClusterIP 10.96.76.239 <none> 5000/TCP 2m23s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
python-deployment-86b66c64df-zn6fb 1/1 Running 0 2m27s
To interact with it, we can port-forward the service
kubectl port-forward services/python-service 5000:5000
The application should now be available at localhost:5000
🤠