Skip to content

Commit

Permalink
updating Kubernetes tutorial to use local registry with KIND, and pro…
Browse files Browse the repository at this point in the history
…vide steps to create containers with spring boot

Signed-off-by: salaboy <Salaboy@gmail.com>
  • Loading branch information
salaboy committed Feb 11, 2025
1 parent 5d6b631 commit 555fa34
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 5 deletions.
42 changes: 39 additions & 3 deletions spring-boot-examples/kubernetes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ We install Dapr on a Kubernetes cluster and then we will deploy both the `produc

## Creating a cluster and installing Dapr

If you don't have any Kubernetes cluster you can use Kubernetes KIND to create a local cluster.
If you don't have any Kubernetes cluster you can use Kubernetes KIND to create a local cluster. We will create a cluster
with a local container registry, so we can push our container images to it. This is covered in the
[KIND documentation here](https://kind.sigs.k8s.io/docs/user/local-registry/).

```bash
kind create cluster
./kind-with-registry.sh
```

Once you have the cluster up and running you can install Dapr:
Expand All @@ -23,6 +25,39 @@ helm upgrade --install dapr dapr/dapr \
--wait
```

## Creating containers using Spring Boot and pushing to local registry

Now that we have our cluster set up with a local container registry, we need to build our `producer-app` and `consumer-app` containers.
For this we will use Spring Boot build it functions to create container images using [Buildpacks](https://buildpacks.io):

From inside the `spring-boot-examples/producer-app` directory you can run the following command to create a container:
```bash
mvn spring-boot:build-image
```

Once we have the container image created, we need to tag and push to the local registry, so the image can be used from our local cluster.
Alternatively, you can push the images to a public registry and update the Kubernetes manifests accordingly.

```bash
docker tag producer-app:0.14.0-SNAPSHOT localhost:5001/sb-producer-app
docker push localhost:5001/sb-producer-app
```

From inside the `spring-boot-examples/consumer-app` directory you can run the following command to create a container:
```bash
mvn spring-boot:build-image
```

Once we have the container image created, we need to tag and push to the local registry, so the image can be used from our local cluster.
Alternatively, you can push the images to a public registry and update the Kubernetes manifests accordingly.

```bash
docker tag consumer-app:0.14.0-SNAPSHOT localhost:5001/sb-consumer-app
docker push localhost:5001/sb-consumer-app
```

Now we are ready to install our application into the cluster.

## Installing and interacting with the application

Now that we have a running Kubernetes cluster, we need to first install the components needed by the application.
Expand All @@ -38,7 +73,8 @@ Then PostgreSQL:
helm install postgresql oci://registry-1.docker.io/bitnamicharts/postgresql --set global.postgresql.auth.database=dapr --set global.postgresql.auth.postgresPassword=password
```

Once we have these components up and running we can install the application by running:
Once we have these components up and running we can install the application by running from inside
the `spring-boot-examples/kubernetes/` directory:

```bash
kubectl apply -f .
Expand Down
2 changes: 1 addition & 1 deletion spring-boot-examples/kubernetes/consumer-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ spec:
app: consumer-app
spec:
containers:
- image: salaboy/sb-consumer-app
- image: localhost:5001/sb-consumer-app
name: consumer-app
imagePullPolicy: Always
ports:
Expand Down
64 changes: 64 additions & 0 deletions spring-boot-examples/kubernetes/kind-with-registry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/sh
set -o errexit

# 1. Create registry container unless it already exists
reg_name='kind-registry'
reg_port='5001'
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
docker run \
-d --restart=always -p "127.0.0.1:${reg_port}:5000" --network bridge --name "${reg_name}" \
registry:2
fi

# 2. Create kind cluster with containerd registry config dir enabled
# TODO: kind will eventually enable this by default and this patch will
# be unnecessary.
#
# See:
# https://github.com/kubernetes-sigs/kind/issues/2875
# https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration
# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
- |-
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
EOF

# 3. Add the registry config to the nodes
#
# This is necessary because localhost resolves to loopback addresses that are
# network-namespace local.
# In other words: localhost in the container is not localhost on the host.
#
# We want a consistent name that works from both ends, so we tell containerd to
# alias localhost:${reg_port} to the registry container when pulling images
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
for node in $(kind get nodes); do
docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
[host."http://${reg_name}:5000"]
EOF
done

# 4. Connect the registry to the cluster network if not already connected
# This allows kind to bootstrap the network but ensures they're on the same network
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
docker network connect "kind" "${reg_name}"
fi

# 5. Document the local registry
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry-hosting
namespace: kube-public
data:
localRegistryHosting.v1: |
host: "localhost:${reg_port}"
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF
2 changes: 1 addition & 1 deletion spring-boot-examples/kubernetes/producer-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ spec:
app: producer-app
spec:
containers:
- image: salaboy/sb-producer-app
- image: localhost:5001/sb-producer-app
name: producer-app
imagePullPolicy: Always
ports:
Expand Down

0 comments on commit 555fa34

Please sign in to comment.