Minikube
1
|
$ sudo pacman -S minikube libvirt qemu-desktop dnsmasq iptables-nft
|
1
2
3
4
|
$ sudo usermod -aG libvirt $(whoami)
$ sudo systemctl start libvirtd.service
$ sudo systemctl enable libvirtd.service
$ sudo systemctl status libvirtd.service
|
set the kvm2 provider in minikube:
1
|
$ minikube config set driver kvm2
|
With minikube you can quickly create a local Kubernetes cluster. To get started, use the following flags:
--profile sets the cluster name to default.
--memory sets the cluster to use 16GB of memory.
--kubernetes-version specifies the cluster kubernetes version to v1.26.1.
1
|
$ minikube start --memory=16384 --cpus=4 --kubernetes-version=v1.26.1
|
Create a route to services deployed with type LoadBalancer and sets their Ingress to their ClusterIP.. Run this command in a different terminal
Install Istio with Helm
Install and configure Istio in a Kubernetes cluster using Helm.
1
2
|
$ proxychains helm repo add istio https://istio-release.storage.googleapis.com/charts
$ proxychains helm repo update
|
The general syntax for helm installation is:
1
|
$ helm install <release> <chart> --namespace <namespace> --create-namespace [--set <other_parameters>]
|
<chart> A path to a packaged chart, a path to an unpacked chart directory or a URL.
<release> A name to identify and manage the Helm chart once installed.
<namespace> The namespace in which the chart is to be installed.
Create the namespace, istio-system, for the Istio components:
1
|
$ kubectl create namespace istio-system
|
Install the Istio base chart which contains cluster-wide Custom Resource Definitions (CRDs) which must be installed prior to the deployment of the Istio control plane:
1
|
$ helm install istio-base istio/base -n istio-system --set defaultRevision=default
|
Validate the CRD installation with the helm ls command:
1
2
3
|
$ helm ls -n istio-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
istio-base istio-system 1 ... ... ... ... deployed base-1.16.1 1.16.1
|
In the output locate the entry for istio-base and make sure the status is set to deployed.
Install the Istio discovery chart which deploys the istiod service:
1
|
$ helm install istiod istio/istiod -n istio-system --wait
|
Verify the Istio discovery chart installation:
1
2
3
4
|
$ helm ls -n istio-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
istio-base istio-system 1 ... ... ... ... deployed base-1.16.1 1.16.1
istiod istio-system 1 ... ... ... ... deployed istiod-1.16.1 1.16.1
|
Get the status of the installed helm chart to ensure it is deployed:
1
|
$ helm status istiod -n istio-system
|
Check istiod service is successfully installed and its pods are running:
1
2
3
|
$ kubectl get deployments -n istio-system --output wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
istiod 1/1 1 1 10m discovery docker.io/istio/pilot:1.16.1 istio=pilot
|
(Optional) Install an ingress gateway:
1
2
|
$ git clone git@github.com:istio/istio.git
$ cd istio
|
1
2
3
|
$ kubectl create namespace istio-ingress
# $ helm install istio-ingress manifests/charts/gateways/istio-ingress/ -n istio-ingress
$ helm install istio-ingress istio/gateway -n istio-ingress --wait
|
The namespace the gateway is deployed in must not have a istio-injection=disabled label.
1
|
$ kubectl label namespace default istio-injection=enabled
|
Examples: Bookinfo Application
Deploy the sample application
1
|
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
|
As each pod becomes ready, the Istio sidecar will be deployed along with it.
Verify everything is working correctly up to this point.
1
|
$ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
|
Open the application to outside traffic
The Gateway configuration resources allow external traffic to enter the Istio service mesh and make the traffic management and policy features of Istio available for edge services.
Configuring ingress using a gateway
The application is deployed but not accessible from the outside. To make it accessible, you need to create an Istio Ingress Gateway, which maps a path to a route at the edge of your mesh.
1
|
$ vim samples/bookinfo/networking/bookinfo-gateway.yaml
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
# The selector matches the ingress gateway pod labels.
# If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 8080
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
|
The gateways list specifies that only requests through your frontend-gateway are allowed. All other external requests will be rejected with a 404 response.
1
|
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
|
Determining the ingress IP and ports
Every Gateway is backed by a service of type LoadBalancer. The external load balancer IP and ports for this service are used to access the gateway. Kubernetes services of type LoadBalancer are supported by default in clusters running on most cloud platforms but in some environments (e.g., test) you may need to do the following:
-
minikube - start an external load balancer by running the following command in a different terminal:
-
kind - follow the guide for setting up MetalLB to get LoadBalancer type services to work.
-
other platforms - you may be able to use MetalLB to get an EXTERNAL-IP for LoadBalancer services.
Set the following environment variables to the name and namespace where the Istio ingress gateway is located in your cluster:
1
2
|
$ export INGRESS_NAME=istio-ingressgateway
$ export INGRESS_NS=istio-system
|
If you installed Istio using Helm, the ingress gateway name and namespace are both istio-ingress:
1
2
|
$ export INGRESS_NAME=istio-ingress
$ export INGRESS_NS=istio-ingress
|
Run the following command to determine if your Kubernetes cluster is in an environment that supports external load balancers:
1
2
3
|
$ kubectl get svc "$INGRESS_NAME" -n "$INGRESS_NS"
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 172.21.109.129 130.211.10.121 ... 17h
|
If the EXTERNAL-IP value is set, your environment has an external load balancer that you can use for the ingress gateway. If the EXTERNAL-IP value is <none> (or perpetually <pending>), your environment does not provide an external load balancer for the ingress gateway.
If your environment does not support external load balancers, you can try accessing the ingress gateway using node ports. Otherwise, set the ingress IP and ports using the following commands:
1
2
3
4
5
|
$ export INGRESS_HOST=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
$ export SECURE_INGRESS_PORT=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
$ export TCP_export INGRESS_PORT=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')INGRESS_PORT=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
|
In certain environments, the load balancer may be exposed using a host name, instead of an IP address. In this case, the ingress gateway’s EXTERNAL-IP value will not be an IP address, but rather a host name, and the above command will have failed to set the INGRESS_HOST environment variable. Use the following command to correct the INGRESS_HOST value:
1
|
$ export INGRESS_HOST=$(kubectl -n "$INGRESS_NS" get service "$INGRESS_NAME" -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
|
Accessing ingress services
1
2
3
|
$ curl -s -I "http://$INGRESS_HOST:$INGRESS_PORT/status/200"
HTTP/1.1 200 OK
server: istio-envoy
|
Access any other URL that has not been explicitly exposed. You should see an HTTP 404 error.
Use a wildcard * value for the host in the Gateway and VirtualService configurations. You can then use $INGRESS_HOST:$INGRESS_PORT in the browser URL.
Run the following command to retrieve the external address of the Bookinfo application.
1
|
$ echo "http://$GATEWAY_URL/productpage"
|
Paste the output from the previous command into your web browser and confirm that the Bookinfo product page is displayed.
View the dashboard
Deploy the Kiali dashboard, along with Prometheus, Grafana, and Jaeger.
1
2
|
$ kubectl apply -f samples/addons
$ kubectl rollout status deployment/kiali -n istio-system
|
Access the Kiali dashboard.
1
|
$ istioctl dashboard kiali
|
To see trace data, you must send requests to your service. The number of requests depends on Istio’s sampling rate and can be configured using the Telemetry API. With the default sampling rate of 1%, you need to send at least 100 requests before the first trace is visible. To send a 100 requests to the productpage service, use the following command:
1
|
$ for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done
|
Traffic Management
Ingress
Request Timeouts
Circuit Breaking
Request Routing
Security
Authentication
JWT
Observability
Metrics
Visualizing Metrics with Grafana
Querying Metrics from Prometheus
Logs
Send access logs with OpenTelemetry collector
Distributed Tracing
OpenCensus Agent
Cleanup
Uninstall
1
|
$ helm ls -n istio-system
|
1
2
|
$ helm delete istio-ingress -n istio-ingress
$ kubectl delete namespace istio-ingress
|
1
|
$ helm delete istiod -n istio-system
|
1
|
$ helm delete istio-base -n istio-system
|
1
|
$ kubectl delete namespace istio-system
|
1
2
3
|
$ kubectl delete gateway frontend-gateway
$ kubectl delete virtualservice frontend-ingress
$ kubectl delete --ignore-not-found=true -f samples/httpbin/httpbin.yaml
|
Cleanup Istio ingress gateway
1
2
|
$ helm uninstall istio-ingress -n istio-ingress
$ kubectl delete ns istio-ingress
|
Remove Kiali
1
|
$ kubectl delete -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/kiali.yaml
|
Reference
Istio Getting Started
Istio Ingress Gateway
Ingress
Request Timeouts
Circuit Breaking
Request Routing
JWT claim based routing
OpenCensus Agent
Visualizing Metrics with Grafana
Querying Metrics from Prometheus
Send access logs with OpenTelemetry collector