Prepare for Service-Mesh-Workshop

Install Docker Desktop

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

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:


Install without Registration

Links to download without registration:

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
  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
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
  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


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:

➜  kubectl -n kube-system describe secret default | grep -E '^token' | cut -f2 -d':' | tr -d " "


➜ $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 | ISTIO_VERSION=1.6.0 sh -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   102  100   102    0     0    122      0 --:--:-- --:--:-- --:--:--   122
100  4294  100  4294    0     0   3657      0  0:00:01  0:00:01 --:--:-- 4193k

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/Temp/istio-1.6.0/bin directory to your environment path variable with:
	 export PATH="$PATH:/Users/michael/Temp/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/Temp/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

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

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: