Running k3d and Istio locally

Jürgen Etzlstorfer
4 min readMay 24, 2021

I often have the need to run a workload on Kubernetes, but just temporarily and therefore I don’t want to create a fully-fledged cluster in the cloud. Some smaller, local setup often works in my case and I believe this would be the case for a lot of developers.

We’ll run the bookinfo app later as a demo — follow along with the blog!

Enter k3s/d

RancherLab has done a phenomenal job in providing the minimal Kubernetes distribution k3s which is great for edge computing and IoT. In my case, I want to run it on my MacBook which wouldn’t work out-of-the-box. K3d on the other hand provides a wrapper for k3s to run it in docker. Problem solved!

K3d + Istio

For my use case, I also want to run a service mesh and my initial thought was to use Istio, as it is widely used and eventually I want to run the cloud-native application life-cycle orchestrator Keptn locally which also makes use of Istio. (However, in this blog I focus solely on k3d + Istio)

Run it locally

Running k3d + Istio locally on Mac, Linux or Windows doesn’t require any voodoo. Just be careful with some options when running it. I’ll explain them in the following, so you can follow my approach.

Prerequisites: Docker and some kind of shell. I am running on zsh on MacOS but pretty sure the same steps work on Linux and WSL.

Install k3d

Get the k3d CLI following their docs

wget -q -O - https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash

Start a local cluster

k3d cluster create myistiocluster -p "8082:80@agent[0]" -p "8443:443@agent[0]" --k3s-server-arg '--no-deploy=traefik' --agents 1

In this case we need to make sure to disable traefik to avoid port conflicts. I’ll also map local ports 8082 and 8443 to the ports of k3d to make them available for later use.

Cluster now running — great!

INFO[0000] Prep: Network
INFO[0004] Created network 'k3d-myistiocluster' (2bf77591ba17a66612be91bf07bba5fd9be46a89ce6cb9f9071d2cea2016b5d6)
INFO[0004] Created volume 'k3d-myistiocluster-images'
INFO[0005] Creating node 'k3d-myistiocluster-server-0'
INFO[0005] Creating node 'k3d-myistiocluster-agent-0'
INFO[0005] Creating LoadBalancer 'k3d-myistiocluster-serverlb'
INFO[0005] Starting cluster 'myistiocluster'
INFO[0005] Starting servers...
INFO[0005] Starting Node 'k3d-myistiocluster-server-0'
INFO[0015] Starting agents...
INFO[0015] Starting Node 'k3d-myistiocluster-agent-0'
INFO[0027] Starting helpers...
INFO[0027] Starting Node 'k3d-myistiocluster-serverlb'
INFO[0029] (Optional) Trying to get IP of the docker host and inject it into the cluster as 'host.k3d.internal' for easy access
INFO[0033] Successfully added host record to /etc/hosts in 3/3 nodes and to the CoreDNS ConfigMap
INFO[0033] Cluster 'myistiocluster' created successfully!

Make sure to configure kubectl to point to your new cluster

kubectl config use-context k3d-myistiocluster

Install Istio

Next, get the Istio CLI.

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.10.0 sh -

Install Istio into the local cluster.

./istio-1.10.0/bin/istioctl install

Now let’s verify that Istio is running in the cluster:

kubectl get pods -ANAMESPACE      NAME                                      READY   STATUS    RESTARTS   AGE
kube-system local-path-provisioner-5ff76fc89d-dr9wm 1/1 Running 0 5m28s
kube-system metrics-server-86cbb8457f-df8wl 1/1 Running 0 5m28s
kube-system coredns-854c77959c-8jbkc 1/1 Running 0 5m28s
istio-system istiod-79dd646bcd-mptql 1/1 Running 0 3m2s
istio-system svclb-istio-ingressgateway-87dxt 3/3 Running 0 2m14s
istio-system svclb-istio-ingressgateway-8jhx2 3/3 Running 0 2m14s
istio-system istio-ingressgateway-8579cc48f8-hlnc8 1/1 Running 0 2m15s

Next, let’smdeploy the bookinfo demo application that comes with Istio. Make sure to move into the folder of the Istio installer that we’ve downloaded earlier.

cd istio-1.10.0kubectl label namespace default istio-injection=enabledkubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

Let’s verify that all services are available:

kubectl get svcNAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 10m
details ClusterIP 10.43.209.51 <none> 9080/TCP 3m45s
ratings ClusterIP 10.43.163.170 <none> 9080/TCP 3m45s
reviews ClusterIP 10.43.149.170 <none> 9080/TCP 3m45s
productpage ClusterIP 10.43.242.170 <none> 9080/TCP 3m45s

Now, let’s create the Ingress Gateway for our application to be able to access it via localhost.

kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

Finally, we can verify that everything is working by opening a browser on http://localhost:8082/productpage and having a look at the productpage

open http://localhost:8082/productpage

Congrats — Installation done!

You’ve successfully set up a local Kubernetes cluster + Istio and exposed it on localhost. If you ever want to stop and restart your cluster, you can do via the following commands:

# stop the cluster
k3d cluster stop myistiocluster
# start it again
k3d cluster start myistiocluster

Have fun and let me know how it works for you — you can ping me on Twitter via @jetzlstorfer.

--

--