Istio is a massive project with a wide range of capabilities and deployment options. We will perform a basic installation on your local machine and deploy a few services onto the mesh. Let’s start by understanding its supported platforms and configuring our environment for deployment.

Preparing Your Environment for Istio

In addition to Istio, we'll be deploying BookInfo, its sample application. Our Istio and BookInfo deployments will lay down several containers. We will use Kubernetes as the platform to manage these containers. Kubernetes is a robust container orchestration system capable of forming clusters (a collection of nodes) and scheduling containers across nodes within the fleet of host machines (nodes) that form the cluster. Nodes are Linux or Windows servers that can run containers with a Kubernetes agent, kubelet, installed. Kubernetes is the first and best supported underlying platform among a variety of to-be-supported underlying systems. As a result, we'll be using Kubernetes throughout our examples. To be clear, Istio is not dependent on Kubernetes. Istio is designed to be platform agnostic and supports multiple deployment platforms including those without a container orchestrator.

Docker Desktop as the Installation Environment

We can deploy Kubernetes in a variety of ways. We'll utilize Docker Desktop as a convenient tool for this. Docker Desktop is an easy-to-install application for your Mac or Windows environment that allows you to run Kubernetes and Istio on your local machine.

Install Docker Desktop and verify that you have a functional Docker environment by running `$ docker run hello-world` on the command line. If you get a “Hello from Docker!” message, you’ve confirmed that Docker isable to pull images, create new instances, and run as expected.

We'll run Kubernetes on Docker Desktop and leverage Kubernetes as the platform to deploy Istio. The Docker Desktop managed Kubernetes server is a single-node Kubernetes cluster that runs locally within your Docker instance. It is not configurable.

The Docker Desktop for Mac Kubernetes integration provides the Kubernetes CLI executable at /usr/local/bin/kubectl. The Docker Desktop for Windows Kubernetes integration provides the Kubernetes CLI executable at C:\>Program Files\Docker\Docker\Resources\bin\kubectl.exe. This location may not be in your shell’s PATH variable, so you may need to type the full path of the command or add it to the PATH. For more information about kubectl, see the official kubectl documentation.

Configuring Docker Desktop

To make sure your Docker Desktop virtual machine has enough memory to run Kubernetes, Istio, and Istio's sample application, BookInfo, you'll need to set it up with at least 4GiB of RAM. All Istio and BookInfo services require this amount of memory to operate effectively.  Pilot, in particular, may have problems running as it requests 2048Mi of memory in an Istio deployment with default settings (see Istio v1.5 at a Glance for a quick overview of Pilot's purpose). Considering 2048Mi is also the default limit for Docker Desktop, Pilot may refuse to start due to insufficient resources if this limit is not increased in your Docker installation.

Instead of increasing the amount of memory allocated to your Docker Desktop installation, you may limit the amount of memory that Pilot requests of your Kubernetes cluster. Depending on whether you're utilizing a package manager like Helm or directly using Kubernetes spec files, there are a couple of options.

Using install/kubernetes/istio-demo.yaml as an example manifest, lets highlights which section of the Pilo spec to edit in order to reduce the 2048Mi of memory requested by Pilot to something smaller like 512Mi.

1apiVersion: extensions/v1beta1
2kind: Deployment
3metadata:
4 name: istio-pilot
5 namespace: istio-system
6...
7 resources:
8 requests:
9 cpu: 500m
10 memory: 2048Mi
11...

When deploying Istio with Helm, you can also offer custom settings. To customize Istio install using Helm, use the --set key=value option in Helm command to override one or more values. An example of reducing Pilot’s requested memory resources is shown below.

1$ helm template install/kubernetes/helm/istio --name istio --namespace istio-system --set pilot.resources.requests.memory="512Mi" | kubectl apply -f -

Deploying Kubernetes

If Kubernetes is not installed on your desktop please refer to Troubleshooting for helpful tips on installing Kubernetes. Verify kubectl installation by running:

1$ kubectl version --short
2Client Version: v1.13.0
3Server Version: v1.13.0

If you see both client and server version numbers, your kubectl client is installed in your PATH and a Kubernetes cluster is accessible. Verify Kubernetes installation and your current context by running `$ kubectl get nodes` which will confirm that your kubeconfig (typically located at ~/.kube/config) is correctly configured to the `docker-desktop` context and your single-node cluster is up:

1$ kubectl get nodes
2NAME STATUS ROLES AGE VERSION
3docker-desktop Ready master 32m v1.13.0

Install Kubernetes Dashboard

The Kubernetes dashboard is a web-based user interface that allows you to manage your cluster and its resources. Containerized applications can be deployed and troubleshooted. The Kubernetes dashboard shows the current state of Kubernetes resources in your cluster as well as any faults that may have occurred. The Kubernetes dashboard can be used to reinforce your understanding of how Istio runs. The easiest and most common way to access the cluster is through kubectl proxy, which creates a local web server that securely proxies data to the Kubernetes dashboard through the Kubernetes API server. Execute the following command to deploy the Kubernetes dashboard:

1$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml

Once deployed, you can access the Kubernetes dashboard using the kubectl command-line tool by running the following command:

1$ kubectl proxy

This command creates a local web server that uses the Kubernetes API server to securely proxy data to the Kubernetes dashboard. It's important to note that the Kubernetes dashboard can only be accessed from the machine where the command is executed.

See kubectl proxy --help for more options and the Kubernetes dashboard documentation for more information. kubectl will make the Kubernetes dashboard available at http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/.

Dashboard deploys with a minimal RBAC configuration by default to secure your cluster data. Only a Bearer Token is currently supported for logging into the Kubernetes dashboard. Create a sample user and use its token, or use an existing token provided by your Docker Desktop deployment, and then run:

1$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | awk '/default-token/ {print $1}')

This will print something similar to:

1Name: default-token-tktcn
2Namespace: kube-system
3Labels: <none>
4Annotations: kubernetes.io/service-account.name: default
5 kubernetes.io/service-account.uid: 3a0a68b1-4abd-11e9-8561-025000000001
6
7Type: kubernetes.io/service-account-token
8
9Data
10====
11ca.crt: 1025 bytes
12namespace: 11 bytes
13token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXRrdGNuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIzYTBhNjhiMS00YWJkLTExZTktODU2MS0wMjUwMDAwMDAwMDEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.WBOH85PHBVjky9JZLidfzS8EWNunIlFZR8MIJjMgBxQbVnqaVl0RmzcvZqYZRY9W7bwQddkXXHAuw5QQMfy8S-I2KdgxpQEP18tfU9wicv6TWt9bRfw9N7QsvB-twlMCEpRKtHwrORZqgRb7_13UH14RB18DiUAIiMok6rs1Pl5w9y0RXVUk9_RXMA2hJnkZ09cTOqJmQ80Vg4QvgAhuxwgmb6kl2rMjb0LegXihAN6j6Yv_JHZ2Vgjk73Priig0Pbjic6t87XfO51Kgjgw7g0vCF0OlOylvp-5oroPMa3nnnlqh6PGnFzOq0zLqjqYXMXZFI5cWkNmf71Q_qKSOsA

Copy the token and use it to authenticate in the Kubernetes dashboard.

Installing Istio

With Kubernetes deployed and dashboard up, it’s time to install our service mesh. You can download the latest Istio release by executing the following command:

1$ curl -L https://git.io/getLatestIstio | sh -

The script fetches the latest Istio release candidate and untars it.

If you would like to fetch a particular version of Istio, specify the desired version number as so:

1$ curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.1.0 sh -

Istio can also be downloaded from the Istio release page. There are versions for Windows, MacOS, and Linux to pick from. After downloading the distribution for your operating system, extract the compressed file to a directory and acquaint yourself with the contents of the distribution, regardless of the operating system you're using.

Each release includes istioctl, configuration samples, a sample application and platform-specific installation resources. istioctl is a command line utility for service operators to debug and diagnose their Istio service mesh. Alternatively, istioctl can be installed via your preferred package manager.

Explore release contents on MacOS or Linux by changing directory to “istio-x.x.x”. For example:

1$ cd istio-1.1.0

This directory contains the files necessary for installing Istio, sample files and also istioctl, an important command-line tool used to manage your Istio deployment.

1$ ls -l
2total 48
3-rw-r--r-- 1 user staff 11343 Mar 18 16:08 LICENSE
4-rw-r--r-- 1 user staff 5921 Mar 18 16:08 README.md
5drwxr-xr-x 3 user staff 96 Mar 18 16:08 bin
6drwxr-xr-x 7 user staff 224 Mar 18 16:08 install
7-rw-r--r-- 1 user staff 602 Mar 18 16:08 istio.VERSION
8drwxr-xr-x 16 user staff 512 Mar 18 16:08 samples
9drwxr-xr-x 21 user staff 672 Mar 18 16:08 tools

The installation directory contains Istio installation YAML files for Kubernetes in install/, sample applications in samples/, the istioctl client binary in the bin/ directory. The istio.VERSION configuration file contains a list of Istio components and their version numbers for the release’s distribution.

istioctl is the Istio configuration command line utility. istioctl is used for setting routing rules, policies, and injecting Envoy as a service proxy manually, among other things. It is also used to create, list, modify, and delete configuration resources in the Istio system. Let’s add it to your PATH environment variable:

1$ export PATH=$PWD/bin:$PATH

Verify your istioctl installation by running:

1$ istioctl version

This should validate path and istioctl command options (see Example 4.7). If not, see Troubleshooting.

1version.BuildInfo{
2Version:"1.1.0", GitRevision:"82797c0c0649a3f73029b33957ae105260458c6e",
3User:"root",
4Host:"996cd064-49c1-11e9-813c-0a580a2c0506", GolangVersion:"go1.10.4",
5DockerHub:"docker.io/istio",
6BuildStatus:"Clean",
7GitTag:"1.1.0-rc.6"
8}

Now that we have downloaded an Istio distribution and verified it’s CLI tool, istioctl, is functional on our local machine, let’s perform a basic installation.

Istio Installation Options

There are numerous installation and deployment architectures to choose from. Typically, installations fit into one of the following categories:

Choice of Security Configuration
  • Install with strict mutual TLS authentication.
    • Recommended for fresh kubernetes cluster. This method enforces authentication between sidecars by default.
  • Install with permissive mutual TLS authentication between sidecars.
    • Recommended if you have existing clusters and services.
    • Recommended if you have applications where services with an Istio sidecar need to be able to communicate with other non-Istio Kubernetes services
  • Custom deployments that include or exclude certain default Istio components.
    • Recommended if a function of one of Istio’s components isn’t necessary or desired in your environment (e.g. removal of Citadel if mTLS is not to be used).
Choice of Deployment Utility
  • Render Kubernetes manifests directly with kubectl.
    • Recommended for understanding Istio’s underpinnings more explicitly.
  • Render Kubernetes manifests with a package / configuration management system like Helm or Ansible.
    • Recommended for production deployments with templated configuration.

Registering Istio’s Custom Resources

Use the following command to apply Istio’s CustomResourceDefinition objects to your cluster:

1$ for i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i; done

This installation does not leverage Helm (a package manager for Kubernetes). The generally preferred method for any installation of Istio that may find its way into production is to use Helm or Ansible; both included in the distribution you just downloaded. With Helm or Ansible you get more flexibility in which components you install and can fine-tune your setup.

1$ kubectl api-resources | grep istio
2meshpolicies authentication.istio.io false MeshPolicy
3policies authentication.istio.io true Policy
4adapters config.istio.io true adapter
5apikeys config.istio.io true apikey
6attributemanifests config.istio.io true attributemanifest
7authorizations config.istio.io true authorization
8bypasses config.istio.io true bypass
9checknothings config.istio.io true checknothing
10circonuses config.istio.io true circonus
11cloudwatches config.istio.io true cloudwatch
12...

Istio actually registers new types of resources, Custom Resource Definitions (CRDs) which represent things like Gateways or Services. We can manipulate (create/update/delete) them just like any other Kubernetes object:

1$ kubectl get crd | grep istio
2adapters.config.istio.io 2019-03-24T03:17:08Z
3apikeys.config.istio.io 2019-03-24T03:17:07Z
4attributemanifests.config.istio.io 2019-03-24T03:17:07Z
5authorizations.config.istio.io 2019-03-24T03:17:07Z
6bypasses.config.istio.io 2019-03-24T03:17:07Z
7checknothings.config.istio.io 2019-03-24T03:17:07Z
8circonuses.config.istio.io 2019-03-24T03:17:07Z
9cloudwatches.config.istio.io 2019-03-24T03:17:08Z
10clusterrbacconfigs.rbac.istio.io 2019-03-24T03:17:07Z
11deniers.config.istio.io 2019-03-24T03:17:07Z
12destinationrules.networking.istio.io 2019-03-24T03:17:07Z
13dogstatsds.config.istio.io 2019-03-24T03:17:08Z
14edges.config.istio.io 2019-03-24T03:17:08Z
15envoyfilters.networking.istio.io 2019-03-24T03:17:07Z
16...

Once Istio’s custom resources are registered with Kubernetes, Istio control plane components may be installed.

Installing Istio Control Plane Components

The istio-demo.yaml specification file contains Istio configuration that allows services to run in mutual TLS permissive mode. If you have existing services or applications in your Kubernetes cluster, it is recommended to use mTLS permissive mode. If you're setting up a fresh cluster, security best practises recommend using istio-demo-auth.yaml to encrypt service traffic between sidecars.

1$ kubectl apply -f install/kubernetes/istio-demo.yaml

Please wait for a few minutes to let the installation run, for the Docker images to properly download and for the deployments to succeed. The application of this extensive yaml file has Kubernetes realize many new Custom Resource Definitions.

You might also use istio-demo-auth.yaml, which enforces mutual TLS authentication between all clients and servers. You might consider that initial deployment of Istio with strict mTLS enforcement configured is most successfully used within fresh Kubernetes cluster where all workloads will be Istio-enabled. To apply Istio setup with mutual TLS authentication, use the command below:

1$ kubectl apply -f install/kubernetes/istio-demo-auth.yaml

Istio's control plane is installed in its own istio-system namespace, and it supervises services in all other namespaces with sidecar proxies, or in other words, all other namespaces with services on the mesh. The control plane is deployed in the istio-system namespace act as a cluster-wide, which means that behaves in a single-tenant fashion.

1$ kubectl get namespaces
2NAME STATUS AGE
3default Active 49d
4docker Active 49d
5istio-system Active 2m15s
6kube-public Active 49d
7kube-system Active 49d

Verify installation of the control plane into the istio-system namespace using commands:

1$ kubectl get namespaces
2NAME STATUS AGE
3default Active 49d
4docker Active 49d
5istio-system Active 2m15s
6kube-public Active 49d
7kube-system Active 49d
8
9Example 4.11 - istio-system namespace created to contain Istio control plane components.
10
11Verify installation of the control plane into the istio-system namespace using commands:
12
13$ kubectl get svc -n istio-system
14NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
15grafana ClusterIP 10.108.237.105 <none> 3000/TCP 11d
16istio-citadel ClusterIP 10.108.165.14 <none> 8060/TCP,15014/TCP 11d
17istio-egressgateway ClusterIP 10.107.148.169 <none> 80/TCP,443/TCP,15443/TCP 11d
18...
19
20$ kubectl get pod -n istio-system
21NAME READY STATUS RESTARTS AGE
22grafana-57586c685b-jr2pd 1/1 Running 0 5m45s
23istio-citadel-645ffc4999-8j4v6 1/1 Running 0 5m45s
24istio-cleanup-secrets-1.1.0-4c9pc 0/1 Completed 0 5m48s
25istio-egressgateway-5c7fd57fdb-85g26 1/1 Running 0 5m46s
26istio-galley-978f9447f-mj5xj 1/1 Running 0 5m46s
27istio-grafana-post-install-1.1.0-g49gh 0/1 Completed 0 5m48s
28istio-ingressgateway-8ccdc79bc-8mk4p 1/1 Running 0 5m46s
29istio-pilot-649455846-klc8c 2/2 Running 0 5m45s
30istio-policy-7b7d7f644b-sqsp8 2/2 Running 4 5m45s
31istio-security-post-install-1.1.0-v4ffp 0/1 Completed 0 5m48s
32istio-sidecar-injector-6dcc9d5c64-tklqz 1/1 Running 0 5m45s
33istio-telemetry-6d494cd676-n6pkz 2/2 Running 4 5m45s
34istio-tracing-656f9fc99c-nn9hd 1/1 Running 0 5m44s
35kiali-69d6978b45-7q7ms 1/1 Running 0 5m45s
36prometheus-66c9f5694-2xzpm 1/1 Running 0 5m45s

We've only deployed half of the service mesh so far, the control plane. You may not have noticed service proxies prior to deploying the sample application, and thus the data plane, because we have not deployed any services (applications) to run on the mesh. You may believe that no proxies are running, but you would be overlooking the fact that two proxies are already running. Our service proxy is up and operating on both the ingress and egress gateways. Let's have a look.

Deploy Sample Application

Let's get started by deploying our first set of services (an application) to the service mesh. We'll utilise BookInfo, an Istio sample application that demonstrates many aspects of the value proposition of service meshes. The Kubernetes manifest files for BookInfo may be found in the samples/bookinfo/ subdirectory in your release distribution folder.  Let's take a moment to familiarise with this application.

To populate the page, users call the productpage microservice, which then calls the details and reviews microservices. The book information can be found in the details microservice. The reviews microservice contains book reviews and subsequently calls the ratings microservice to retrieve reviews. The ratings microservice contains book ranking in the form of a 1 to 5 star book review.  There are three versions of the reviews microservice: Each of the four application services are written in a different language - Python, Ruby, Java, Nodejs, which further demonstrates the value of a service mesh.

  • reviews v1 has no ratings (does not call the ratings service).
  • reviews v2 has ratings of 1 to 5 black stars (calls the ratings service).
  • reviews v3 has ratings of 1 to 5 red stars (calls the ratings service).

The application does not need to be changed to run the sample using Istio. Instead, we'll configure and run the services in an Istio-enabled environment, with service proxies injected alongside each service as sidecars. Istio's service proxies can be injected as sidecars to application services either manually or automatically. As we deploy our sample application, let's have a look at how automated sidecar injection works.

Deploying Sample App with Automatic Sidecar Injection

Istio will deploy a sidecar injector in order to have Envoy deployed as sidecars to each of our services. Let's check for the presence of the sidecar injector deployment and its namespace label, which specifies that pods in a specific namespace will have sidecar injected automatically upon deployment (admission):

1$ kubectl -n istio-system get deployment -l istio=sidecar-injector
2NAME READY UP-TO-DATE AVAILABLE AGE
3istio-sidecar-injector 1/1 1 1 82m

Label the default namespace with istio-injection=enabled

1$ kubectl label namespace default istio-injection=enabled

And confirm which namespaces have the istio-injection label associated:

1$ kubectl get namespace -L istio-injection
2NAME STATUS AGE ISTIO-INJECTION
3default Active 1h enabled
4Docker Active 1h enabled
5istio-system Active 1h disabled
6kube-public Active 1h
7kube-system Active 1h

The istio-demo.yaml deployment we ran has automatic injection configured.

We can now deploy the sample app after installing the sidecar injector with modifying admission webhook and the namespace designated for automatic sidecar injection.

1$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

With sample application deployed, you can confirm that automatic sidecar injection is working in your environment by inspecting any one of the BookInfo pods and noting the istio-proxy container as a new addition to the application pod.

1$ kubectl describe po/productpage-v1-....
2...
3istio-proxy:
4 Container ID: docker://f28abdf1f0acf92687711488f7fcca8cc5968e2ed39d8275bf57cc46b5ae2257
5 Image: docker.io/istio/proxyv2:1.1.7
6 Image ID: docker-pullable://istio/proxyv2@sha256:e6f039115c7d5ef9c8f6b049866fbf9b6f5e2255d3a733bb8756b36927749822
7 Port: 15090/TCP
8 Host Port: 0/TCP
9 Args:
10 proxy
11 sidecar
12...

Networking with the Sample App

After the Bookinfo services are up and running, you'll need to make the application accessible from outside your Kubernetes cluster, such as through a browser. This is accomplished through the usage of an Istio Gateway. You'll need to specify the application's ingress gateway:

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

Confirm the gateway has been created:

1$ kubectl get gateway
2
3NAME AGE
4bookinfo-gateway 7m

Find where the productpage has been exposed as a service available to handle requests from outside of the cluster to interact with the freshly deployed application.

1$ echo "http://$(kubectl get nodes -o template --template='{{range.items}}{{range.status.addresses}}{{if eq .type "InternalIP"}}{{.address}}{{end}}{{end}}{{end}}'):$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[0].nodePort}')/productpage"
2
3http://x.x.x.x:31380/productpage

Uninstall Istio

It's a common mistake to assume that deleting the istio-system namespace will uninstall Istio. Deleting the istio-system removes Istio’s control plane components, but leaves CRDs, sidecars and other artifacts resident in your cluster. Uninstalling Istio is as simple as executing this command from within your istio release folder:

1$ kubectl delete -f install/kubernetes/istio-demo.yaml

This will not delete all of the Istio custom resource definitions, mesh configuration and sample application, however. In order to delete these, run:

1$ for i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl delete -f $i; done
2$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
3$ kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml

You can verify the success of Istio and BookInfo’s removal by running:

1$ kubectl get crds
2$ kubectl get pods

Related Resources

Layer5, the cloud native management company

An empowerer of engineers, Layer5 helps you extract more value from your infrastructure. Creator and maintainer of service mesh standards. Maker of Meshery, the cloud native management plane.