Tutorial Let's install our first service mesh.
I spent enough time on some theory on Day 77. Let's dig right into getting a service mesh up and running.
- Install the Istio service mesh with Demo Profile
- Deploy Bookinfo Application into the service mesh
- Test it's functionality
- Externally expose the application
I highly advise using something like minikube or a cloud-based K8s cluster that allows you to have load-balancer functionality.
- A Kubernetes cluster running 1.22, 1.23, 1.24, 1.25
- KinD
- Minikube
- Civo K8s
- EKS
- Access to a Loadbalancer service
- Metallb
- port-forwarding (not preferred)
- Cloud Load-balancer
- Inlets
- Linux or macOS to run istoctl
Environment setup In my case, I spun up a Civo K3s cluster with 3-nodes, 2 CPU per node, and 4GB of RAM per node. This is important because you will need enough resources to run the service mesh control plane, which, is Istiod in our case. If you need a cluster in a pinch register for free credit @ civo.com.
- Verify your cluster is up and operational and make sure there aren't any errors. The commands below will output nodes and their IPs and OS info and the running pods in all namespaces, respectively.
kubectl get nodes -o wide kubectl get pods -A
- Download Istio, which will pick up the latest version (at the time of writing its 1.16.1)
curl -L https://istio.io/downloadIstio | sh -
- Change to the Istio directory
cd istio-1.16.1
- Add the istioctl binary to your path
export PATH=$PWD/bin:$PATH
- Check to verify that your environment is ready to go:
And the output
istioctl x precheck
✔ No issues found when checking the cluster. Istio is safe to install or upgrade! To get started, check out https://istio.io/latest/docs/setup/getting-started/
- Let's proceed to install Istio. We use the demo profile because it allows us to provide a minimal configuration to demonstrate functionality.
You will see the following output:
istioctl install --set profile=demo -y
✔ Istio core installed ✔ Istiod installed ✔ Egress gateways installed ✔ Ingress gateways installed ✔ Installation complete
- Next, we can verify all the components are deployed as expected by running the command below, which proceeds to output all the Istio components.
Your output should look similar in that all components are working. I changed my External-IP to bring.your.LB.IP, whcih means your IP will be different. Why do you need mine :P
kubectl get all -n istio-system
NAME READY STATUS RESTARTS AGE pod/istiod-885df7bc9-f9k7c 1/1 Running 0 31m pod/istio-ingressgateway-6688c7f65d-szxf9 1/1 Running 0 31m pod/istio-egressgateway-7475c75b68-mpxf7 1/1 Running 0 31m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/istiod ClusterIP 10.43.249.242 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 31m service/istio-egressgateway ClusterIP 10.43.75.47 <none> 80/TCP,443/TCP 31m service/istio-ingressgateway LoadBalancer 10.43.51.40 bring.your.LB.IP 15021:31000/TCP,80:32697/TCP,443:30834/TCP,31400:30953/TCP,15443:30733/TCP 31m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/istiod 1/1 1 1 31m deployment.apps/istio-ingressgateway 1/1 1 1 31m deployment.apps/istio-egressgateway 1/1 1 1 31m NAME DESIRED CURRENT READY AGE replicaset.apps/istiod-885df7bc9 1 1 1 31m replicaset.apps/istio-ingressgateway-6688c7f65d 1 1 1 31m replicaset.apps/istio-egressgateway-7475c75b68 1 1 1 31m
- While everything looks good, we also want to deploy an application and simulataneously add it to the Service Mesh.
Let's label our default namespace with the istio-injection=enabled label. This tells Istiod to push the sidecar to any new microservice deployed to the namespace.
Verify it
kubectl label namespace default istio-injection=enabled
kubectl get ns --show-labels
- Let's deploy our app. Make sure you are the in the same directory as before. If not, change to istio-1.16.1
Let's give it one minute and check the application
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
Let's see the outputkubectl get all
The one thing to notice here is that all pods have 2/2 containers ready, meaning, the sidecar is now present.NAME READY STATUS RESTARTS AGE pod/details-v1-698b5d8c98-l8r5t 2/2 Running 0 7m30s pod/reviews-v3-6dc9897554-8pgtx 2/2 Running 0 7m30s pod/reviews-v1-9c6bb6658-lvzsr 2/2 Running 0 7m30s pod/reviews-v2-8454bb78d8-9tm2j 2/2 Running 0 7m30s pod/productpage-v1-bf4b489d8-q29jp 2/2 Running 0 7m29s pod/ratings-v1-5967f59c58-s9f88 2/2 Running 0 7m30s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 80m service/details ClusterIP 10.43.198.240 <none> 9080/TCP 7m31s service/ratings ClusterIP 10.43.121.72 <none> 9080/TCP 7m30s service/reviews ClusterIP 10.43.173.247 <none> 9080/TCP 7m30s service/productpage ClusterIP 10.43.142.39 <none> 9080/TCP 7m30s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/details-v1 1/1 1 1 7m30s deployment.apps/reviews-v3 1/1 1 1 7m30s deployment.apps/reviews-v1 1/1 1 1 7m30s deployment.apps/reviews-v2 1/1 1 1 7m30s deployment.apps/productpage-v1 1/1 1 1 7m30s deployment.apps/ratings-v1 1/1 1 1 7m30s NAME DESIRED CURRENT READY AGE replicaset.apps/details-v1-698b5d8c98 1 1 1 7m30s replicaset.apps/reviews-v3-6dc9897554 1 1 1 7m30s replicaset.apps/reviews-v1-9c6bb6658 1 1 1 7m30s replicaset.apps/reviews-v2-8454bb78d8 1 1 1 7m30s replicaset.apps/productpage-v1-bf4b489d8 1 1 1 7m30s replicaset.apps/ratings-v1-5967f59c58 1 1 1 7m30s
-
One test I'll run is to verify that I can connect to any one of these pods and get a response. Let's deploy a sleep pod. If you were in the same istio-1.16.1 directory, then you can run this command.
kubectl apply -f samples/sleep/sleep.yaml
Let's check to see that the pod is deployed to the default namespace AND has the sidecar injected:
kubectl get pods
sleep-75bbc86479-xw5lw 2/2 Running 0 36s
-
I'm going to use the sleep pod to curl over to the product-page. Please use yours which has a different name, to curl.
kubectl exec sleep-75bbc86479-xw5lw -c sleep -- curl -sS productpage:9080
And we should see something similar to the below which tells us the app is working!:
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1683 100 1683 0 0 69202 0 --:--:-- --:--:-- --:--:-- 70125 <!DOCTYPE html> <html> <head> <title>Simple Bookstore App</title> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="static/bootstrap/css/bootstrap.min.css"> <!-- Optional theme --> <link rel="stylesheet" href="static/bootstrap/css/bootstrap-theme.min.css"> </head> <body> <p> <h3>Hello! This is a simple bookstore application consisting of three services as shown below</h3> </p>
-
Let's deploy the Istio ingress gateway configuration and virtual-service configuration. The Ingress Gateway Configuration is an abstraction for the Istio-ingress-gateway and simply tells it which host and port is listening for requests. The virtual-service configuration tells the gateway how to route the request (or who to route it to). If you didn't navigate away from the original folder, run the following command:
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
You will see two objects created:
gateway.networking.istio.io/bookinfo-gateway created virtualservice.networking.istio.io/bookinfo created
-
Because we don't have external DNS setup, we'll gather the information we need and piece together our URL: Grab the External IP, and the HTTP2 port, which would be TCP port 80 from the Istio Ingress Gateway.
kubectl get svc -n istio-system
Store it in a variable
export INGRESS_HOST=[IP_from_Istio_ingress_gateway] export INGRESS_PORT=80
now curl this host:
curl INGRESS_HOST:INGRESS_PORT/productpage
And the RESULT:
!DOCTYPE html> <html> <head> <title>Simple Bookstore App</title>
I decided to jump into getting a service mesh up and online. It's easy enough if you have the right pieces in place, like a Kubernetes cluster and a load-balancer service. Using the demo profile, you can have Istiod, and the Ingress/Egress gateway deployed. Deploy a sample app with a service definition, and you can expose it via the Ingress-Gateway and route to it using a virtual service.
Want to get deeper into Service Mesh? Head over to #70DaysofServiceMesh!
See you on Day 79 and beyond of #90DaysofServiceMesh