Prepare for Service-Mesh-Workshop

Install Docker Desktop

For all demos we use Docker Desktop from the stable channel.

Hint: The demos in the workshop should also work with Minikube. Due to better user experience with Docker Desktop, the workshop was designed with Docker Desktop. Everybody who is experienced with Minikube can switch to Minikube.

Install and Register

Follow the link to start Docker Desktop installation together with registration (without registration see below):

Clicking the button Download for Mac (stable) opens the login page. A registration is mandatory for downloading the free Community Edition. After registration and login you can click on Download Docker Desktop for Mac or Download Docker Desktop for Windows inside the onboarding tutorial

Alternative link to download Docker Desktop: Mac:


Install without Registration

Links to download without registration: Mac:

Get Docker:


Get Docker:

Verify Installation

After installation and starting Docker Desktop you can verify a succesful installation by clicking on About Docker Desktop in the context menu. The following dialog will appear:

An alternative way to verify the installation is to use the following shell command:

docker version Client: Docker Engine - Community Version: 19.03.8 API version: 1.40 Go version: go1.12.17 Git commit: afacb8b Built: Wed Mar 11 01:21:11 2020 OS/Arch: darwin/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.8 API version: 1.40 (minimum version 1.12) Go version: go1.12.17 Git commit: afacb8b Built: Wed Mar 11 01:29:16 2020 OS/Arch: linux/amd64 Experimental: false containerd: Version: v1.2.13 GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc: Version: 1.0.0-rc10 GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init: Version: 0.18.0 GitCommit: fec3683

Activate Kubernetes

Right click on Docker Desktop and open the Preferences (or Settings) dialog. A click on Kubernetes menu opens the following dialog:

Check Enable Kubernetes and Apply & Restart to activate Kubernetes. Depending on the internet speed, this step can take some time (only for the first time of execution). A download for all necessary Kubernetes containers gets started in the background.

A succesful installed and started Kubernetes will be shown in the status area (Kubernetes running):

You can see the downloaded containers by clicking on Show system containers (advanced) :

➜ docker images | grep k8s REPOSITORY TAG IMAGE ID CREATED SIZE v1.16.5 fc838b21afbb 4 months ago 159MB v1.16.5 b4d073a9efda 4 months ago 83.5MB v1.16.5 441835dd2301 4 months ago 151MB v1.16.5 0ee1b8a3ebe0 4 months ago 82.7MB 3.3.15-0 b2756210eeab 9 months ago 247MB 1.6.2 bf261d157914 9 months ago 44.1MB 3.1 da86e6ba6ca1 2 years ago 742kB

Docker Desktop also installs kubectl. To verify this part of the installation you can check kubectl with the following shell command:

➜ kubectl version Client Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:26:26Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"darwin/amd64"} Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:18:29Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"linux/amd64"}

Install Kubernetes Dashboard (Optional)

Unfortunately, the Kubernetes dashboard is not installed when Docker Desktop enables Kubernetes. This can be done with the following command when Kubernetes has started:

➜ kubectl apply -f namespace/kubernetes-dashboard created serviceaccount/kubernetes-dashboard created service/kubernetes-dashboard created secret/kubernetes-dashboard-certs created secret/kubernetes-dashboard-csrf created secret/kubernetes-dashboard-key-holder created configmap/kubernetes-dashboard-settings created created created created created deployment.apps/kubernetes-dashboard created service/dashboard-metrics-scraper created deployment.apps/dashboard-metrics-scraper created

To access Kubernetes Dashboard, the following commands must be entered:

➜ kubectl proxy Starting to serve on

The dashboard is now available at this URL:


The token required to log into the dashboard can be created using the following command:

➜ kubectl -n kube-system describe secret default Name: default-token-ksjx2 Namespace: kube-system Labels: <none> Annotations: default f5e5db5a-ebee-4518-b62e-552b1c72a831 Type: Data ==== namespace: 11 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6Il8yNldYcktyUnBYbkhqRDBJcl9iT2dmQXFWdVNIamFGN01KdXFTSEY0MnMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLWtzangyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmNWU1ZGI1YS1lYmVlLTQ1MTgtYjYyZS01NTJiMWM3MmE4MzEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.MP6EYaiZ7vPfkvwL9CJMpcigPEaM909BZBeJAtRYdBHn7NYLhiyyL6FDlVmkuavlwSLv-i8HGVJnbL-WNkFHHRccdnG8ikFcgrHWwMB2bKOCtGagl5qRMj_VzY7hAkAwPuE_Mo4AGWgI_JrCIjSVZd3HqEbjmOeI9hLDiC2_tT9rwfdCz0plfiel-Ubw023cC1rU9343gyiaHNp7jcVkyud9J-_2rkqd3cCIZQRzkl4N_KBpTzWwz00hlnYEWNLcV0XKOXEn2RVp8B8SHMhf-VWQdPtpQtdVrTypGKjVU6d-nL2avVUYnUilIi4ELKwJUa_Ht34teHO0VSfVH_smqQ ca.crt: 1025 bytes

Alternatively, the token can be determined with the following command: Mac:

➜ kubectl -n kube-system describe secret default | grep -E '^token' | cut -f2 -d':' | tr -d " " eyJhbGciOiJSUzI1NiIsImtpZCI6Il8yNldYcktyUnBYbkhqRDBJcl9iT2dmQXFWdVNIamFGN01KdXFTSEY0MnMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLWtzangyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmNWU1ZGI1YS1lYmVlLTQ1MTgtYjYyZS01NTJiMWM3MmE4MzEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.MP6EYaiZ7vPfkvwL9CJMpcigPEaM909BZBeJAtRYdBHn7NYLhiyyL6FDlVmkuavlwSLv-i8HGVJnbL-WNkFHHRccdnG8ikFcgrHWwMB2bKOCtGagl5qRMj_VzY7hAkAwPuE_Mo4AGWgI_JrCIjSVZd3HqEbjmOeI9hLDiC2_tT9rwfdCz0plfiel-Ubw023cC1rU9343gyiaHNp7jcVkyud9J-_2rkqd3cCIZQRzkl4N_KBpTzWwz00hlnYEWNLcV0XKOXEn2RVp8B8SHMhf-VWQdPtpQtdVrTypGKjVU6d-nL2avVUYnUilIi4ELKwJUa_Ht34teHO0VSfVH_smqQ


➜ $TOKEN=((kubectl -n kube-system describe secret default | Select-String "token:") -split " +")[1] echo $TOKEN

Enter the token with copy/paste into the login window and click on Sign in to log in:

Setup Istio

We use Istio 1.6.x in this workshop. More background information can be found on this page:

Change Settings in Docker Desktop

Recommended settings to run Istio in Docker Desktop:

The recommended settings are 4 CPUs and 8 GB RAM, as shown on this screenshot:

Download Istio

➜ curl -L | sh - % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 107 100 107 0 0 137 0 --:--:-- --:--:-- --:--:-- 137 100 3896 100 3896 0 0 3804 0 0:00:01 0:00:01 --:--:-- 3804 Downloading istio-1.6.0 from ... Istio 1.6.0 Download Complete! Istio has been successfully downloaded into the istio-1.6.0 folder on your system. Next Steps: See to add Istio to your Kubernetes cluster. To configure the istioctl client tool for your workstation, add the /Users/michael/Work/michael/ServiceMeshWorkshop/istio-1.6.0/bin directory to your environment path variable with: export PATH="$PATH:/Users/michael/Work/michael/ServiceMeshWorkshop/istio-1.6.0/bin" Begin the Istio pre-installation verification check by running: istioctl verify-install Need more information? Visit

Take the following snippet from the output of the previous download:

➜ export PATH="$PATH:/Users/michael/Work/michael/ServiceMeshWorkshop/istio-1.6.0/bin"

Hint: the value of the download folder which will be set as PATH variable depends on the folder where you started the download.

Install Istio

Make sure your Kubernetes Context is set for Docker Desktop Kubernetes:

➜ kubectl config current-context docker-desktop

or set the current context:

➜ kubectl config set current-context docker-desktop Property "current-context" set.

Now it's time to install Istio into your new Kubernetes cluster. For demonstration purposes we use Istio's demo profile. Information about the profiles can be found here:

To install Istio with demo profile follow the instructions on this site:
➜ istioctl install --set profile=demo Detected that your cluster does not support third party JWT authentication. Falling back to less secure first party JWT. See for details. ✔ Istio core installed ✔ Istiod installed ✔ Egress gateways installed ✔ Ingress gateways installed ✔ Addons installed ✔ Installation complete

The warning about JWT authentication can be ignored.

To verify our Istio installation we can enter this command:

➜ istioctl verify-install Deployment: istio-egressgateway.istio-system checked successfully PodDisruptionBudget: istio-egressgateway.istio-system checked successfully Service: istio-egressgateway.istio-system checked successfully ServiceAccount: istio-egressgateway-service-account.istio-system checked successfully Deployment: istio-ingressgateway.istio-system checked successfully PodDisruptionBudget: istio-ingressgateway.istio-system checked successfully Role: istio-ingressgateway-sds.istio-system checked successfully RoleBinding: istio-ingressgateway-sds.istio-system checked successfully Service: istio-ingressgateway.istio-system checked successfully ServiceAccount: istio-ingressgateway-service-account.istio-system checked successfully ConfigMap: istio-grafana-configuration-dashboards-istio-mesh-dashboard.istio-system checked successfully ConfigMap: istio-grafana-configuration-dashboards-istio-performance-dashboard.istio-system checked successfully ConfigMap: istio-grafana-configuration-dashboards-istio-service-dashboard.istio-system checked successfully ConfigMap: istio-grafana-configuration-dashboards-istio-workload-dashboard.istio-system checked successfully ConfigMap: istio-grafana-configuration-dashboards-mixer-dashboard.istio-system checked successfully ConfigMap: istio-grafana-configuration-dashboards-pilot-dashboard.istio-system checked successfully ConfigMap: istio-grafana.istio-system checked successfully Deployment: grafana.istio-system checked successfully PeerAuthentication: grafana-ports-mtls-disabled.istio-system checked successfully Service: grafana.istio-system checked successfully ClusterRole: kiali.default checked successfully ClusterRole: kiali-viewer.default checked successfully ClusterRoleBinding: kiali.default checked successfully ConfigMap: kiali.istio-system checked successfully Secret: kiali.istio-system checked successfully Deployment: kiali.istio-system checked successfully Service: kiali.istio-system checked successfully ServiceAccount: kiali-service-account.istio-system checked successfully ClusterRole: prometheus-istio-system.default checked successfully ClusterRoleBinding: prometheus-istio-system.default checked successfully ConfigMap: prometheus.istio-system checked successfully Deployment: prometheus.istio-system checked successfully Service: prometheus.istio-system checked successfully ServiceAccount: prometheus.istio-system checked successfully Deployment: istio-tracing.istio-system checked successfully Service: jaeger-query.istio-system checked successfully Service: jaeger-collector.istio-system checked successfully Service: jaeger-collector-headless.istio-system checked successfully Service: jaeger-agent.istio-system checked successfully Service: zipkin.istio-system checked successfully Service: tracing.istio-system checked successfully ClusterRole: istiod-istio-system.default checked successfully ClusterRole: istio-reader-istio-system.default checked successfully ClusterRoleBinding: istio-reader-istio-system.default checked successfully ClusterRoleBinding: istiod-pilot-istio-system.default checked successfully ServiceAccount: istio-reader-service-account.istio-system checked successfully ServiceAccount: istiod-service-account.istio-system checked successfully ValidatingWebhookConfiguration: istiod-istio-system.default checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully CustomResourceDefinition: checked successfully ConfigMap: istio.istio-system checked successfully Deployment: istiod.istio-system checked successfully ConfigMap: istio-sidecar-injector.istio-system checked successfully MutatingWebhookConfiguration: istio-sidecar-injector.default checked successfully PodDisruptionBudget: istiod.istio-system checked successfully Service: istiod.istio-system checked successfully EnvoyFilter: metadata-exchange-1.4.istio-system checked successfully EnvoyFilter: stats-filter-1.4.istio-system checked successfully EnvoyFilter: metadata-exchange-1.5.istio-system checked successfully EnvoyFilter: tcp-metadata-exchange-1.5.istio-system checked successfully EnvoyFilter: stats-filter-1.5.istio-system checked successfully EnvoyFilter: tcp-stats-filter-1.5.istio-system checked successfully EnvoyFilter: metadata-exchange-1.6.istio-system checked successfully EnvoyFilter: tcp-metadata-exchange-1.6.istio-system checked successfully EnvoyFilter: stats-filter-1.6.istio-system checked successfully EnvoyFilter: tcp-stats-filter-1.6.istio-system checked successfully Checked 25 custom resource definitions Checked 3 Istio Deployments Istio is installed successfully

Every line of this lengthy output should end with successfully and the last lines should look like this:

Checked 25 custom resource definitions Checked 3 Istio Deployments Istio is installed successfully

A shorter way to verify the CRDs:

➜ kubectl get crds | grep '' | wc -l 25

Analyze Istio Installation

So lets check what happened during Istio installation: A new namespace istio-system was created:

➜ kubectl get ns NAME STATUS AGE default Active 17m docker Active 16m istio-system Active 2m32s kube-node-lease Active 17m kube-public Active 17m kube-system Active 17m

and these pods where started in this namespace:

➜ kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE grafana-74dc798895-kzb92 1/1 Running 0 3m57s istio-egressgateway-69bf865cf8-gjw75 1/1 Running 0 3m56s istio-ingressgateway-569d44555d-t6pnw 1/1 Running 0 3m57s istio-tracing-8584b4d7f9-qmh8c 1/1 Running 0 3m57s istiod-84cc4dfcd8-9s5dn 1/1 Running 0 4m9s kiali-6f457f5964-msftj 1/1 Running 0 3m57s prometheus-79878ff5fd-9vcst 2/2 Running 0 3m57s

Hint: since Istio 1.5 the control plane consists of only one pod named istiod

Install Shell-Completion for Kubernetes and Istio

Working with Kuberntes and Istio is mainly done with shell commands. To avoid typing errors you should install the appropriate shell-completions.



IDE, Maven and Gradle

To change the Java code of the services in our exercises, everybody can use their preferred IDE. Building the services (war files) will be done with Maven and Gradle. Therefore Maven AND Gradle must be installed. Either together with the IDE or on itself.

Pre-Pull Base Docker Images

Just in case the network at the workshop location is slow, please pull the following Docker images to get it into your local Docker cache:

➜ docker pull michaelhofmann/smw-openliberty:latest ➜ docker pull michaelhofmann/smw-java:latest

We will use these images as base images for our services.

Log Streaming with Stern

Everybody who wants a better experience with log streaming can use stern: