Istio Minikube Tutorial: Deploying a hello world example application with Istio in Kubernetes


Last couple of days I was playing with Istio and I couldn’t find a working upto date tutorial that can teach me how to run a basic hello world application with Istio in Kubernetes.

Istio is an open source service mesh that provides a uniform way to integrate microservices, manage traffic flow across microservices, enforce policies, and aggregate telemetry data.

In this quick tutorial you will learn how to install Istio on Minikube and then deploy a helloworld sample application on it.

Install Minikube

Minikube is one of the solution to deploy a single node Kubernetes cluster.

If you are using Mac, then you can use brew package manager to install Minikube

brew cask install minikube

For other operating systems you can refer to the documentation.

Also, make sure you have Virtual Box installed.

In case kubectl is not installed, then you need to install that as well. On Mac, you can use following

brew install kubernetes-cli

Create a local Kubernetes cluster

You can create a single Kubernetes cluster by running the following command.

minikube start --memory=4096 --cpus=4

The above will download a virtual machine and install Kubernetes on top of it. We have explicitly specified resources for our virtual machine.

You can check your cluster is running fine by executing following command.

The successful output should like as shown below.

minikube v0.34.1 on darwin (amd64)
Creating virtualbox VM (CPUs=4, Memory=4096MB, Disk=20000MB) ...
"minikube" IP address is 192.168.99.106
Configuring Docker as the container runtime ...
Preparing Kubernetes environment ...
Pulling images required by Kubernetes v1.13.3 ...
Launching Kubernetes v1.13.3 using kubeadm ...
Configuring cluster permissions ...
Verifying component health .....
kubectl is now configured to use "minikube"
Done! Thank you for using minikube!

Download and install Istio

Execute the following commands

curl -L https://git.io/getLatestIstio | sh -
cd istio-1.0.6
export PATH=$PWD/bin:$PATH

Next, we will create Istio’s Custo Resource Definitions via kubectl apply.

kubectl apply -f install/kubernetes/helm/istio/templates/crds.yaml

Then, we will install Istio without mutual TLS authentication between sidecards

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

It took close to 5 minutes for Kubernetes to download and start all the istio related pods.

You can check if all the pods are running by executing following command.

kubectl get pod -n istio-system
NAME                                      READY   STATUS              RESTARTS   AGE
grafana-59b8896965-84nrv                  0/1     ContainerCreating   0          42s
istio-citadel-6f444d9999-5mwhn            0/1     ContainerCreating   0          41s
istio-cleanup-secrets-lnbkv               0/1     ContainerCreating   0          43s
istio-egressgateway-6d79447874-8rmzl      0/1     ContainerCreating   0          42s
istio-galley-685bb48846-fvqrp             0/1     ContainerCreating   0          42s
istio-grafana-post-install-ghqlc          0/1     ContainerCreating   0          43s
istio-ingressgateway-5b64fffc9f-sf9w8     0/1     ContainerCreating   0          42s
istio-pilot-7f558fc848-gvkh8              0/2     ContainerCreating   0          41s
istio-policy-547d64b8d7-tskpj             0/2     ContainerCreating   0          42s
istio-security-post-install-hmgf7         0/1     ContainerCreating   0          43s
istio-sidecar-injector-5d8dd9448d-dfjzc   0/1     ContainerCreating   0          41s
istio-telemetry-c5488fc49-pdhzl           0/2     ContainerCreating   0          41s
istio-tracing-6b994895fd-9tcnx            0/1     ContainerCreating   0          40s
prometheus-76b7745b64-47spl               0/1     ContainerCreating   0          41s
servicegraph-cb9b94c-x7wlw                0/1     ContainerCreating   0          41s

As you can see, statuses of all the pods is ContainerCreating .

In 5 minutes or so you will have containers in running state as shown below.

NAME                                      READY   STATUS      RESTARTS   AGE
grafana-59b8896965-84nrv                  1/1     Running     0          4m51s
istio-citadel-6f444d9999-5mwhn            1/1     Running     0          4m50s
istio-cleanup-secrets-lnbkv               0/1     Completed   0          4m52s
istio-egressgateway-6d79447874-8rmzl      1/1     Running     0          4m51s
istio-galley-685bb48846-fvqrp             1/1     Running     0          4m51s
istio-grafana-post-install-ghqlc          0/1     Completed   0          4m52s
istio-ingressgateway-5b64fffc9f-sf9w8     1/1     Running     0          4m51s
istio-pilot-7f558fc848-gvkh8              2/2     Running     0          4m50s
istio-policy-547d64b8d7-tskpj             2/2     Running     0          4m51s
istio-security-post-install-hmgf7         0/1     Completed   0          4m52s
istio-sidecar-injector-5d8dd9448d-dfjzc   1/1     Running     0          4m50s
istio-telemetry-c5488fc49-pdhzl           2/2     Running     0          4m50s
istio-tracing-6b994895fd-9tcnx            1/1     Running     0          4m49s
prometheus-76b7745b64-47spl               1/1     Running     0          4m50s
servicegraph-cb9b94c-x7wlw                1/1     Running     2          4m50s

Deploying a helloworld example application

We all start by adding istio-injection label to default namespace

kubectl label namespace default istio-injection=enabled --overwrite

Istio comes bundled with a hello world example application. All example applications are in the samples directory. To create the helloworld appliction we will run the following command.

kubectl create -f samples/helloworld/helloworld.yaml

The above command assumes you are inside istio-1.0.6 directory.

The helloworld.yaml is shown below.

apiVersion: v1
kind: Service
metadata:
  name: helloworld
  labels:
    app: helloworld
spec:
  ports:
  - port: 5000
    name: http
  selector:
    app: helloworld
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: helloworld-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
        version: v1
    spec:
      containers:
      - name: helloworld
        image: istio/examples-helloworld-v1
        resources:
          requests:
            cpu: "100m"
        imagePullPolicy: IfNotPresent #Always
        ports:
        - containerPort: 5000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: helloworld-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
        version: v2
    spec:
      containers:
      - name: helloworld
        image: istio/examples-helloworld-v2
        resources:
          requests:
            cpu: "100m"
        imagePullPolicy: IfNotPresent #Always
        ports:
        - containerPort: 5000
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: helloworld-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
  - "*"
  gateways:
  - helloworld-gateway
  http:
  - match:
    - uri:
        exact: /hello
    route:
    - destination:
        host: helloworld
        port:
          number: 5000

Now, to invoke the service we will have to determine the ingress IP and port.

export INGRESS_HOST=$(sudo minikube ip)
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')

Next, you can make cURL request to the helloworld application by running following command.

curl http://$INGRESS_HOST:$INGRESS_PORT/hello

The output will be Hello version: v1, instance: helloworld-v1-7c45d5f8c4-fhv87

If you make another call, output will be following

Hello version: v2, instance: helloworld-v2-69f69868b4-f7jc9

This is because the service is doing round robin to two pods. The first pod runs version v1 of the application and second pod runs version v2 of the application.

2 thoughts on “Istio Minikube Tutorial: Deploying a hello world example application with Istio in Kubernetes

  1. David

    I get an error when executing the kubectl apply command:
    ~/istio-1.1.1 > kubectl apply -f install/kubernetes/helm/istio/templates/crds.yaml
    error: SchemaError(io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler): invalid object doesn’t have additional properties

    Any idea?

    Reply
  2. klap

    Hi, I have a problem when using the next command:

    is not working with the latest Istio version (1.1.1)

    The error is:

    ~/istio-1.1.1 > kubectl apply -f install/kubernetes/helm/istio/templates/crds.yaml
    error: SchemaError(io.k8s.api.autoscaling.v2beta1.HorizontalPodAutoscaler): invalid object doesn’t have additional properties

    Any idea?

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s