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.
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?
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?
Very nice tutorial, simple and to the point. Thanks!