Cyber Deals - Get up to 65% off on CKA, CKAD, CKS, KCNA, KCSA exams and courses!

Istio

Envoy introduction

# cat labs/01/httpbin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
    service: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      serviceAccountName: httpbin
      containers:
      - image: docker.io/kennethreitz/httpbin
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80

# cat labs/01/sleep.yaml

# Copyright Istio Authors
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

##################################################################################################
# Sleep service
##################################################################################################
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sleep
---
apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
    service: sleep
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: sleep
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sleep
  template:
    metadata:
      labels:
        app: sleep
    spec:
      serviceAccountName: sleep
      containers:
      - name: sleep
        image: governmentpaas/curl-ssl:terraform-14
        command: ["/bin/sleep", "3650d"]
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: /etc/sleep/tls
          name: secret-volume
      volumes:
      - name: secret-volume
        secret:
          secretName: sleep-secret
          optional: true
---
kubectl apply -f labs/01/httpbin.yaml
kubectl apply -f labs/01/sleep.yaml

Verify access from sleep pod

kubectl exec deploy/sleep -- curl httpbin:8000/headers
root@kubernetes:~/istio-workshops/deploy-istio# kubectl exec deploy/sleep -- curl httpbin:8000/headers
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   106  100   106    0     0  15142      0 --:--:-- --:--:-- --:--:-- 15142
{
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin:8000",
    "User-Agent": "curl/7.69.1"
  }
}

create envoy config

admin:
  accessLogPath: /dev/stdout
  address:
    socketAddress:
      address: 0.0.0.0
      portValue: 15000
staticResources:
  listeners:
  - name: httpbin-listener
    address:
      socketAddress:
        address: 0.0.0.0
        portValue: 15001
    filterChains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typedConfig:
          '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          httpFilters:
          - name: envoy.filters.http.router
          routeConfig:
            name: simple_httpbin_route
            virtualHosts:
            - domains:
              - '*'
              name: httpbin_host
              routes:
              - match:
                  prefix: /
                route:
                  cluster: httpbin_service
          statPrefix: httpbin
  clusters:
  - connectTimeout: 5s
    loadAssignment:
      clusterName: httpbin_service
      endpoints:
      - lbEndpoints:
        - endpoint:
            address:
              socketAddress:
                address: httpbin
                portValue: 8000
    name: httpbin_service
    respectDnsTtl: true
    dnsLookupFamily: V4_ONLY
    type: STRICT_DNS
    upstreamConnectionOptions:
      tcpKeepalive: {}

deoply

kubectl create cm envoy --from-file=envoy.yaml=./labs/01/envoy-conf.yaml -o yaml --dry-run=client | kubectl apply -f -
kubectl apply -f labs/01/envoy-proxy.yaml

Verify(note enriched response headers, X-Envoy-Expected-Rq-Timeout-Ms)

root@kubernetes:~/istio-workshops/deploy-istio# kubectl exec deploy/sleep -- curl http://envoy/headers
{
  "headers": {
    "Accept": "*/*",
    "Content-Length": "0",
    "Host": "envoy",
    "User-Agent": "curl/7.69.1",
    "X-Envoy-Expected-Rq-Timeout-Ms": "15000"
  }
}
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   175  100   175    0     0  35000      0 --:--:-- --:--:-- --:--:-- 43750

Change call timeout

routeConfig:
  name: simple_httpbin_route
  virtualHosts:
  - domains:
    - '*'
    name: httpbin_host
    routes:
    - match:
        prefix: /
      route:
        cluster: httpbin_service
        timeout: 1s
kubectl create cm envoy --from-file=envoy.yaml=./labs/01/envoy-conf-timeout.yaml -o yaml --dry-run=client | kubectl apply -f -

## restart envoy
kubectl rollout restart deploy/envoy
kubectl exec deploy/sleep -- curl http://envoy/headers

Test it

kubectl exec deploy/sleep -- curl -v http://envoy/delay/5

Envoy exposes a /stats endpoint we can inspect:

kubectl exec deploy/sleep -- curl http://envoy:15000/stats
kubectl exec deploy/sleep -- curl http://envoy:15000/stats | grep retry

Retrying failed requests

routeConfig:
  name: simple_httpbin_route
  virtualHosts:
  - domains:
    - '*'
    name: httpbin_host
    routes:
    - match:
        prefix: /
      route:
        cluster: httpbin_service
        timeout: 1s
        retryPolicy:
          retryOn: 5xx
          numRetries: 3
kubectl create cm envoy --from-file=envoy.yaml=./labs/01/envoy-conf-retry.yaml -o yaml --dry-run=client | kubectl apply -f -
kubectl rollout restart deploy/envoy

kubectl exec deploy/sleep -- curl -v http://envoy/status/500

kubectl exec deploy/sleep -- curl http://envoy:15000/stats | grep retry

Installing Istio

Create namespace and services

kubectl create ns istioinaction
# cat sample-apps/web-api.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: web-api
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
  labels:
    app: web-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-api
      version: v1
  template:
    metadata:
      labels:
        app: web-api
        version: v1
      annotations:
    spec:
      serviceAccountName: web-api
      containers:
      - name: web-api
        image: nicholasjackson/fake-service:v0.7.8
        ports:
        - containerPort: 8080
        env:
        - name: "LISTEN_ADDR"
          value: "0.0.0.0:8080"
        - name: "UPSTREAM_URIS"
          value: "http://recommendation:8080"
        - name: "NAME"
          value: "web-api"
        - name: "MESSAGE"
          value: "Hello From Web API"

---
# Service to expose web frontend

apiVersion: v1
kind: Service
metadata:
  name: web-api
spec:
  selector:
    app: web-api
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
# cat sample-apps/recommendation.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: recommendation
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: recommendation
  labels:
    app: recommendation
spec:
  replicas: 1
  selector:
    matchLabels:
      app: recommendation
      version: v1
  template:
    metadata:
      labels:
        app: recommendation
        version: v1
      annotations:
    spec:
      serviceAccountName: recommendation
      containers:
      - name: recommendation
        image: nicholasjackson/fake-service:v0.7.8
        ports:
        - containerPort: 8080
        env:
        - name: "LISTEN_ADDR"
          value: "0.0.0.0:8080"
        - name: "UPSTREAM_URIS"
          value: "http://purchase-history:8080"
        - name: "NAME"
          value: "recommendation"
        - name: "MESSAGE"
          value: "Hello From Recommendations!"

---
# Service to expose recommendation frontend

apiVersion: v1
kind: Service
metadata:
  name: recommendation
spec:
  selector:
    app: recommendation
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
# cat sample-apps/purchase-history-v1.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: purchase-history
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: purchase-history-v1
  labels:
    app: purchase-history-v1
spec:
  replicas: 1
  selector:
    matchLabels:
        app: purchase-history
        version: v1
  template:
    metadata:
      labels:
        app: purchase-history
        version: v1
      annotations:
    spec:
      serviceAccountName: purchase-history
      containers:
      - name: purchase-history
        image: nicholasjackson/fake-service:v0.7.8
        ports:
        - containerPort: 8080
        env:
        - name: "LISTEN_ADDR"
          value: "0.0.0.0:8080"
        - name: "NAME"
          value: "purchase-history-v1"
        - name: "SERVER_TYPE"
          value: "http"
        - name: "MESSAGE"
          value: "Hello From Purchase History (v1)!"

---
# Service to expose purchase-history-v1 frontend

apiVersion: v1
kind: Service
metadata:
  name: purchase-history
spec:
  selector:
    app: purchase-history
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
# cat sample-apps/sleep.yaml
# Copyright 2017 Istio Authors
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

##################################################################################################
# Sleep service
##################################################################################################
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sleep
---
apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: sleep
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sleep
  template:
    metadata:
      labels:
        app: sleep
    spec:
      serviceAccountName: sleep
      containers:
      - name: sleep
        image: governmentpaas/curl-ssl:terraform-14
        command: ["/bin/sleep", "3650d"]
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: /etc/sleep/tls
          name: secret-volume
      volumes:
      - name: secret-volume
        secret:
          secretName: sleep-secret
          optional: true
---
kubectl apply -n istioinaction -f sample-apps/web-api.yaml
kubectl apply -n istioinaction -f sample-apps/recommendation.yaml
kubectl apply -n istioinaction -f sample-apps/purchase-history-v1.yaml
kubectl apply -n istioinaction -f sample-apps/sleep.yaml

## check pods
kubectl get po -n istioinaction

Istio CLI installation

$ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.8.3 sh -
$ export PATH=$PWD/istio-1.8.3/bin:$PATH
$ istioctl version
no running Istio pods in "istio-system"
1.8.3

Three ways to install IstioT

  • istioctl CLI tool
  • Istio Operator
  • Helm

Installing Istio

kubectl create ns istio-system
# cat labs/02/istiod-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: istiod
    istio: pilot
    release: istio
  name: istiod
  namespace: istio-system
spec:
  type: ClusterIP
  ports:
  - name: grpc-xds
    port: 15010
  - name: https-dns
    port: 15012
  - name: https-webhook
    port: 443
    targetPort: 15017
  - name: http-monitoring
    port: 15014
  selector:
    app: istiod
kubectl apply -f labs/02/istiod-service.yaml

Sample istio operator:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: control-plane
spec:
  profile: minimal
$ istioctl install -y -n istio-system -f labs/02/control-plane.yaml --revision 1-8-3
✔ Istio core installed
✔ Istiod installed
✔ Installation complete
kubectl get pod -n istio-system

# query the Istio control plane's debug endpoints
kubectl exec -n istio-system deploy/istiod-1-8-3 -- pilot-discovery request GET /debug/registryz

Install sidecar for demo app

istioctl kube-inject -f labs/01/httpbin.yaml --meshConfigMapName istio-1-8-3 --injectConfigMapName istio-sidecar-injector-1-8-3  | kubectl apply -f -

Connecting To Observability Systems

kubectl create ns prometheus

## add helm repo
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

Install prometheus with custom values

helm install prom prometheus-community/kube-prometheus-stack --version 13.13.1 -n prometheus -f labs/03/prom-values.yaml

kubectl get po -n prometheus

Open port forward to test Promethues

kubectl -n prometheus port-forward statefulset/prometheus-prom-kube-prometheus-stack-prometheus 9090 --address 0.0.0.0

Grafana

kubectl -n prometheus port-forward svc/prom-grafana 3000:80 --address 0.0.0.0

Add Istio Dashboards to Grafana

kubectl -n prometheus create cm istio-dashboards \
--from-file=pilot-dashboard.json=labs/03/dashboards/pilot-dashboard.json \
--from-file=istio-workload-dashboard.json=labs/03/dashboards/istio-workload-dashboard.json \
--from-file=istio-service-dashboard.json=labs/03/dashboards/istio-service-dashboard.json \
--from-file=istio-performance-dashboard.json=labs/03/dashboards/istio-performance-dashboard.json \
--from-file=istio-mesh-dashboard.json=labs/03/dashboards/istio-mesh-dashboard.json \
--from-file=istio-extension-dashboard.json=labs/03/dashboards/istio-extension-dashboard.json

Label the configmap

kubectl label -n prometheus cm istio-dashboards grafana_dashboard=1

Port forward again and check Grafana

kubectl -n prometheus port-forward svc/prom-grafana 3000:80 --address 0.0.0.0

Scraping the Istio service mesh: control plane

set up a ServiceMonitor to scrape the Istio control-plane components:

# cat labs/03/monitor-control-plane.yaml
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: istio-component-monitor
  namespace: prometheus
  labels:
    monitoring: istio-components
    release: prom
spec:
  jobLabel: istio
  targetLabels: [app]
  selector:
    matchExpressions:
    - {key: istio, operator: In, values: [pilot]}
  namespaceSelector:
    any: true
  endpoints:
  - port: http-monitoring
    interval: 15s

Apply

kubectl apply -f labs/03/monitor-control-plane.yaml

Scraping the Istio service mesh: data plane

# cat labs/03/monitor-data-plane.yaml

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: envoy-stats-monitor
  namespace: prometheus
  labels:
    monitoring: istio-proxies
    release: prom
spec:
  selector:
    matchExpressions:
    - {key: istio-prometheus-ignore, operator: DoesNotExist}
  namespaceSelector:
    any: true
  jobLabel: envoy-stats
  podMetricsEndpoints:
  - path: /stats/prometheus
    interval: 15s
    relabelings:
    - action: keep
      sourceLabels: [__meta_kubernetes_pod_container_name]
      regex: "istio-proxy"
    - action: keep
      sourceLabels: [__meta_kubernetes_pod_annotationpresent_prometheus_io_scrape]
    - sourceLabels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
      action: replace
      regex: ([^:]+)(?::\d+)?;(\d+)
      replacement: $1:$2
      targetLabel: __address__
    - action: labeldrop
      regex: "__meta_kubernetes_pod_label_(.+)"
    - sourceLabels: [__meta_kubernetes_namespace]
      action: replace
      targetLabel: namespace
    - sourceLabels: [__meta_kubernetes_pod_name]
      action: replace
      targetLabel: pod_name

Create it

kubectl apply -f labs/03/monitor-data-plane.yaml

generate some load to the data plane

for i in {1..10}; do kubectl exec deploy/sleep -n default -- curl http://httpbin.default:8000/headers; done

Installing Kiali

Kiali is a networking graph dashboard that shows connectivity paths between services.

kubectl create ns kiali-operator

helm install \
--set cr.create=true \
--set cr.namespace=istio-system \
--namespace kiali-operator \
--repo https://kiali.org/helm-charts \
--version 1.29.1 \
kiali-operator \
kiali-operator

kubectl get po -n kiali-operator

Create Kiali CR:

# cat labs/03/kiali.yaml
apiVersion: kiali.io/v1alpha1
kind: Kiali
metadata:
  namespace: istio-system
  name: kiali
spec:
  istio_namespace: "istio-system"
  istio_component_namespaces:
    prometheus: prometheus
  auth:
    strategy: token
  deployment:
    accessible_namespaces:
    - '**'
    image_version: operator_version
  external_services:
    prometheus:
      cache_duration: 10
      cache_enabled: true
      cache_expiration: 300
      url: "http://prom-kube-prometheus-stack-prometheus.prometheus:9090"
kubectl apply -f labs/03/kiali.yaml

kubectl get po -n istio-system

kubectl -n istio-system port-forward deploy/kiali 20001 --address 0.0.0.0

Create service account for Kiali

kubectl create serviceaccount kiali-dashboard -n istio-system
kubectl create clusterrolebinding kiali-dashboard-admin --clusterrole=cluster-admin --serviceaccount=istio-system:kiali-dashboard

## get token
kubectl get secret -n istio-system -o jsonpath="{.data.token}" $(kubectl get secret -n istio-system | grep kiali-dashboard | awk '{print $1}' ) | base64 --decode

you can switch to anonymous login with the following command:

kubectl apply -f labs/03/kiali-no-auth.yaml

Creating An Ingress Gateway For Istio

Install Istio ingress gateway

# cat labs/04/ingress-gateways.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio-ingress-gw-install
spec:
  profile: empty
  values:
    gateways:
      istio-ingressgateway:
        autoscaleEnabled: false
  components:
    ingressGateways:
    - name: istio-ingressgateway
      namespace: istio-system
      enabled: true
      k8s:
        overlays:
        - apiVersion: apps/v1
          kind: Deployment
          name: istio-ingressgateway
          patches:
          - path: spec.template.spec.containers[name:istio-proxy].lifecycle
            value:
              preStop:
                exec:
                  command: ["sh", "-c", "sleep 5"]
Disclaimer: Views expressed in articles are those of the respective authors and do not necessarily reflect the views of their employers or this site. While we aim for accuracy, please verify information before relying on it, and let us know if you spot an error.
Tags:
Share:

Related Posts

Red hat

Red Hat Knowledge Base

Reference Documents for Red Hat Products Red Hat Subscription Management Cheatsheet sosreport methods Subscription Reference Troubleshooting Failed to …

Ansible

rancher

1. Introduction to Rancher & RKE 1.1. Rancher Architecture 1.2. Disocvering RKE 1.2.1. Node Preparation 1.2.2. Creating the Cluster Configuration …

Ansible

Install Ansible AWX using AWX Operator (on Kubernetes)

Install Ansible AWX using AWX Operator (on Kubernetes) Setup a Kubernete s Cluster Deploy AWX Operator Create AWX Deployment Get Admin Password Get …

Ansible

Azure Certifications

Microsoft Certified: Security, Compliance, and Identity Fundamentals Manage identity and access in Azure Active Directory Zero Trust Guidance Center …

Ansible

GCP Nested Virtualization

Note: This is purely based on GCP Documentation and for my own quick reference with additonal notes.

Ansible

openstack

1. Setup your OpenStack Infra 1.1. Install OS 1.2. Update 1.3. Update /etc/hosts 1.4. Stop and Disable Firewall 1.5. Stop and Disable NetworkManager …