Service Mesh  sandbox 

What is a service mesh, and where to use one?

What is a service mesh?

Examples

Istio

Uses Envoy
Sidecar or Ambient mode

https://istio.io/latest/docs/concepts/traffic-management/

Components

  • Virtual Service
  • Destination Rule
  • Gateway
  • Service Entry (can register external services)

How does Traffic flow through Istio?

Some important components to be aware of, in order

  • Ingress Gateway
  • Gateway
  • Virtual Service
  • Service Entry
  • Deployment
  • App pod proxy container
  • App pod app container

Istio Ingress Gateway (configures the cloud load balancer)

apiVersion: v1
kind: Service
metadata:
  annotations:
    meta.helm.sh/release-name: istio-ingressgateway
    meta.helm.sh/release-namespace: istio-system
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
    service.beta.kubernetes.io/aws-load-balancer-internal: "true"
    service.beta.kubernetes.io/aws-load-balancer-name: nlb-istio
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: ..
    service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    ..
  finalizers:
  - service.kubernetes.io/load-balancer-cleanup
  labels:
    app: istio-ingressgateway
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: istio-ingressgateway
    app.kubernetes.io/version: 1.20.0
    helm.sh/chart: gateway-1.20.0
    istio: ingressgateway
  name: istio-ingressgateway
  namespace: istio-system
  ..
spec:
  ..
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  ..
  type: LoadBalancer

Istio Gateway

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  annotations:
  name: app-gateway
  namespace: app-namespace
spec:
  selector:
    istio: ingressgateway # maps to istio ingress gateway defined above
  servers:
  - hosts:
    - app-name.example.com
    port:
      name: http
      number: 80
      protocol: HTTP
    tls:
      httpsRedirect: true
  - hosts:
    - app-name.example.com
    port:
      name: https
      number: 443
      protocol: HTTPS # can be http
    tls:
      credentialName: app-name-cert # do i need this?
      mode: SIMPLE

Istio Virtual Service

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: app-name
  namespace: app-namespace
spec:
  gateways:
  - app-gateway # refers to the gateway created above
  hosts:
  - app-name.example.com
  http:
  - route:
    - destination:
        host: app-name
        port:
          number: 80

Logging

Deploy this to enable access logging on a specific app. Ref

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: app-access-logs
  namespace: app-namespace
spec:
  selector:
    matchLabels:
      service.istio.io/canonical-name: app-name
  accessLogging:
    - providers:
      - name: envoy

Log response body for a particular app using lua http filters.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: app-resp-log
  namespace: app-namespace
spec:
  workloadSelector:
    labels:
      service.istio.io/canonical-name: app-name
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: ANY
      listener:
        filterChain:
          filter:
            name: envoy.filters.network.http_connection_manager
    patch:
      operation: INSERT_BEFORE
      value: 
       name: envoy.lua
       typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
          inlineCode: |
            function envoy_on_response(response_handle) 
                local body = response_handle:body()
                local jsonString = tostring(body:getBytes(0, body:length()))
                response_handle:logErr("Status: "..response_handle:headers():get(":status"))
                response_handle:logErr("BodyJSONString: "..jsonString)
            end            

Modify log level on running containers. Ref

kubectl -n namespace exec -i -t pod/podname -c istio-proxy -- /bin/sh
$ curl -X POST http://localhost:15000/logging?level=debug