istio getting started

installing the istio

 1# downloading the istio compress archive and the script will auto uncompress
 2curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.16.1 sh -
 3# for easier usage
 4export PATH=$PWD/bin:$PATH
 5# check the version
 6./bin/istioctl version
 7# check the requirments
 8./bin/istioctl x precheck
 9# installing components to local k8s cluster
10./bin/istioctl install --set profile=demo -y
11# enable injection in the default namespace
12kubectl label namespace default istio-injection=enabled
13# verify the install result
14istioctl verify-install

Generally commands

 1k get MutatingWebhookConfiguration
 2k get validatingWebhookConfiguration
 3kubectl describe configmap istio-sidecar-injector -n istio-system
 4istioctl proxy-config secret istio-ingressgateway-xxxxxxx.istio-system
 5istioctl analyze
 6istioctl proxy-status
 7# view routes
 8istioctl proxy-config routes deploy/istio-ingressgateway.istio-system
 9# view ingress gateway cluster config
10istioctl proxy-config cluster -n istio-system  istio-ingressgateway-56554558b7-4ptls
11# view the listeners
12istioctl proxy-config listeners  reviews-v3-5c5cc7b6d-hpkd2.apps
13# view specific listener
14istioctl proxy-config listeners  reviews-v3-5c5cc7b6d-hpkd2.apps --port 15001 -o yaml
15# open the envoy admin portal in local host to view all stats and metrics and configs
16istioctl dash envoy deploy/pod-xxxx -n ns
17# view the all clusters in pod
18kubectl exec "$(kubectl get pod -l app=helloworld -o jsonpath='{.items[0].metadata.name}')" -c istio-proxy -- curl -sS 0:15000/clusters

Deploy the Testing Apps

1kubectl apply -f samples/sleep/sleep.yaml
2export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
3kubectl apply -f samples/httpbin/httpbin.yaml

Enable Envoy logs

1apiVersion: telemetry.istio.io/v1alpha1
2kind: Telemetry
3metadata:
4  name: mesh-default
5  namespace: istio-system
6spec:
7  accessLogging:
8    - providers:
9      - name: Envoy

Testing

1# Testing from sleep pod to httpbin
2kubectl exec "$SOURCE_POD" -c sleep -- curl -sS httpbin:8000/status/418
3# View the httpbin istio-proxy logs
4kubectl logs -l app=httpbin -c istio-proxy

Filter the accesslog through telemetry

 1apiVersion: telemetry.istio.io/v1alpha1
 2kind: Telemetry
 3metadata:
 4  name: mesh-default
 5  namespace: istio-system
 6spec:
 7  accessLogging:
 8    - providers:
 9        - name: Envoy
10      filter:
11        expression: "request.url_path != '/status' && request.url_path != '/liveness' && request.url_path != '/readiness'"
  • reapply the config kubectl apply -f telemetry.yaml
  • Then the istio-proxy sidecar (Envoy) will only log entries where the request URL path isn’t /status, /liveness, or /readiness

Also use EnvoyFilter CR to filter

  • First delete telemtry resource kubectl delete -f telemetry.yaml
 1apiVersion: networking.istio.io/v1alpha3
 2kind: EnvoyFilter
 3metadata:
 4 name: access-log
 5spec:
 6 configPatches:
 7 - applyTo: NETWORK_FILTER
 8   match:
 9     context: ANY
10     listener:
11       filterChain:
12         filter:
13           name: "Envoy.filters.network.http_connection_manager"
14   patch:
15     operation: MERGE
16     value:
17       typed_config:
18         "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
19         access_log:
20         - name: Envoy.file_access_log
21           typed_config:
22             "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog"
23             path: /dev/stdout
24             format: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_CODE_DETAILS% \"%RESP(GRPC-STATUS)% %RESP(GRPC-MESSAGE)%\" %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\"\n"
25           filter:
26             and_filter:
27               filters:
28               - header_filter:
29                   header:
30                     name: :Path
31                     string_match:
32                       exact: /status
33                     invert_match: true
34               - header_filter:
35                   header:
36                     name: :Path
37                     string_match:
38                       exact: /liveness
39                     invert_match: true
40               - header_filter:
41                   header:
42                     name: :Path
43                     string_match:
44                       exact: /readiness
45                     invert_match: true

Disable the Envoy response headers when client request from gateway outbounds

 1apiVersion: networking.istio.io/v1alpha3
 2kind: EnvoyFilter
 3metadata:
 4  name: remove-gateway-response-headers
 5  namespace: istio-system
 6spec:
 7  configPatches:
 8    - applyTo: NETWORK_FILTER
 9      match:
10        context: GATEWAY
11        listener:
12          filterChain:
13            filter:
14              name: envoy.filters.network.http_connection_manager
15      patch:
16        operation: MERGE
17        value:
18          typed_config:
19            '@type': >-
20                            type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
21            server_header_transformation: PASS_THROUGH
22    - applyTo: ROUTE_CONFIGURATION
23      match:
24        context: GATEWAY
25      patch:
26        operation: MERGE
27        value:
28          response_headers_to_remove:
29            - x-envoy-upstream-service-time
30            - server

Launch the sample Catalog service

Create istioinaction namespace and enabled the istio proxy sidecar

 1# create namespace
 2k create namespace istioinaction
 3# set default namespace when operation the k8s
 4k config set-context $(k config current-context) --namespace istioinaction
 5# clone Catalog service code 
 6git clone https://github.com/istioinaction/book-source-code.git
 7# build the docker image
 8cd services/catalog && ./docker-build.sh
 9# apply the catalog kubernetes resources
10k apply -f services/catalog/kubernetes/catalog.yaml
11# testing catalog service api
12curl -s http://catalog.istioinaction/items/1

Launch the sample Webapp service

  • Build the istioinaction/webapp docker image
1# build the webapp image
2cd services/webapp && ./docker-build.sh
  • Apply the webapp k8s resources
1k apply -f services/catalog/kubernetes/webapp.yaml
  • Testing the webapp service
1curl -s http://webapp.istioinaction/api/catalog/items/1
2# forward the service to local
3k port-forward deploy/webapp 8080:8080

Create virtualService and gateway for webapp

  • enter and apply resource manifests
1cd ./book-source-code/ch2 && k apply -f ingress-gateway.yaml
  • the ingress-gateway.yaml like following
 1apiVersion: networking.istio.io/v1alpha3
 2kind: Gateway
 3metadata:
 4  name: outfitters-gateway
 5  namespace: istioinaction
 6spec:
 7  selector:
 8    istio: ingressgateway # use istio default controller
 9  servers:
10  - port:
11      number: 80
12      name: http
13      protocol: HTTP
14    hosts:
15    - "*"
16---
17apiVersion: networking.istio.io/v1alpha3
18kind: VirtualService
19metadata:
20  name: webapp-virtualservice
21  namespace: istioinaction
22spec:
23  hosts:
24  - "*"
25  gateways:
26  - outfitters-gateway
27  http:
28  - route:
29    - destination:
30        host: webapp
31        port:
32          number: 80

Check and debug the gateway and virtualservice

1# view the routes details
2istioctl proxy-config routes deploy/istio-ingressgateway.istio-system
3k get gateway --all-namespaces
4k get virtualservice --all-namespaces

Chaos debug service

  • Execute Chaos for catalog, this script make catlog service problem run ./bin/chaos.sh 500 100
 1#!/usr/bin/env bash
 2
 3if [ $1 == "500" ]; then
 4
 5    POD=$(kubectl get pod | grep catalog | awk '{ print $1 }')
 6    echo $POD
 7
 8    for p in $POD; do
 9        if [ ${2:-"false"} == "delete" ]; then
10            echo "Deleting 500 rule from $p"
11            kubectl exec -c catalog -it $p -- curl  -X POST -H "Content-Type: application/json" -d '{"active":
12        false,  "type": "500"}' localhost:3000/blowup
13        else
14            PERCENTAGE=${2:-100}
15            kubectl exec -c catalog -it $p -- curl  -X POST -H "Content-Type: application/json" -d '{"active":
16            true,  "type": "500",  "percentage": '"${PERCENTAGE}"'}' localhost:3000/blowup
17            echo ""
18        fi
19    done
20
21
22fi
  • apply the VirutalService to catalog and retry the catalog while when execute script call api ,the correct more result while true; do curl http://localhost/api/catalog; sleep .5; done
 1apiVersion: networking.istio.io/v1alpha3
 2kind: VirtualService
 3metadata:
 4  name: catalog
 5spec:
 6  hosts:
 7  - catalog
 8  http:
 9  - route:
10    - destination:
11        host: catalog
12    retries:
13      attempts: 3
14      retryOn: 5xx
15      perTryTimeout: 2s

Circuit breaking

 1$ kubectl apply -f - <<EOF
 2apiVersion: networking.istio.io/v1alpha3
 3kind: DestinationRule
 4metadata:
 5  name: httpbin
 6spec:
 7  host: httpbin
 8  trafficPolicy:    
 9    loadBalancer:
10      consistentHash:
11        httpCookie:
12          name: user
13          ttl: 0s
14    connectionPool:
15      tcp:
16        maxConnections: 1
17      http:
18        http1MaxPendingRequests: 1
19        maxRequestsPerConnection: 1
20    outlierDetection:
21      consecutive5xxErrors: 1
22      interval: 1s
23      baseEjectionTime: 3m
24      maxEjectionPercent: 100
25EOF

Use VirtualService to redirect the request to other host

 1apiVersion: networking.istio.io/v1alpha3
 2kind: VirtualService
 3metadata:
 4  name: redirect-302
 5  namespace: istio-system
 6spec:
 7  gateways:
 8  - istio-gateway
 9  hosts:
10  - origin.test.com
11  http:
12  - redirect:
13      authority: redirect.demo.com
14    headers:
15      response:
16        set:
17          location: "https://redirect.demo.com"

Extends the functionality