# Kubernetes and istio deep dive ## Show notes ### Kubernetes - [x] Kubernetes Components - [x] overview - [x] pod - [x] pod resources - [x] guaranteed - [x] burstable - [x] best effort - [x] deployment - [x] Liveness, Readiness and Startup Probes - [x] liveness - [x] Define a liveness command - [x] Define a liveness HTTP request - [x] readiness - [x] Define readiness probes - [x] rollout strategy - [x] recreate - [x] ramped - [ ] Blue/Green - [x] canary - [x] statefulset - [x] What/When to use - [x] service - [x] what is service - [x] Multi-port Services - [x] Headless Services - [x] Type ExternalName - [x] endpoints - [x] extras - [x] top - [x] logs - [x] stern ### istio - [x] envoy - [x] Traffic management - [x] Engress - [x] Request Routing - [x] Traffic shifting - [x] Observability - [x] kaili ## Ref ### Kubernetes components ![](https://i.imgur.com/exTLyKO.png) ### pod For a Pod to be given a QoS class of Guaranteed: ``` apiVersion: v1 kind: Pod metadata: name: qos-demo namespace: qos-example spec: containers: - name: qos-demo-ctr image: nginx resources: limits: memory: "200Mi" cpu: "700m" requests: memory: "200Mi" cpu: "700m" ``` A Pod is given a QoS class of Burstable if: ``` apiVersion: v1 kind: Pod metadata: name: qos-demo-2 namespace: qos-example spec: containers: - name: qos-demo-2-ctr image: nginx resources: limits: memory: "200Mi" requests: memory: "100Mi" ``` QoS class of BestEffort ``` apiVersion: v1 kind: Pod metadata: name: qos-demo-3 namespace: qos-example spec: containers: - name: qos-demo-3-ctr image: nginx ``` ### Service In Kubernetes, a Service is a method for exposing a network application that is running as one or more Pods in your cluster. ``` apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app.kubernetes.io/name: MyApp ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Pod metadata: name: nginx labels: app.kubernetes.io/name: proxy spec: containers: - name: nginx image: nginx:stable ports: - containerPort: 80 name: http-web-svc --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app.kubernetes.io/name: proxy ports: - name: name-of-service-port protocol: TCP port: 80 targetPort: http-web-svc ``` #### Multi-port Services ``` apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app.kubernetes.io/name: MyApp ports: - name: http protocol: TCP port: 80 targetPort: 9376 - name: https protocol: TCP port: 443 targetPort: 9377 ``` #### Headless service For headless Services, a cluster IP is not allocated, kube-proxy does not handle these Services, and there is no load balancing or proxying done by the platform for them. How DNS is automatically configured depends on whether the Service has selectors defined: ``` apiVersion: v1 kind: Service metadata: name: my-service spec: clusterIP: None selector: app.kubernetes.io/name: MyApp ports: - name: http protocol: TCP port: 80 targetPort: 9376 ``` #### Type ExternalName Services of type ExternalName map a Service to a DNS name, not to a typical selector such as my-service or cassandra. You specify these Services with the spec.externalName parameter. ``` apiVersion: v1 kind: Service metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com ``` ### Deployment ``` apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` recreate: terminate the old version and release the new one ``` spec: replicas: 3 strategy: type: Recreate ``` ramped: release a new version on a rolling update fashion, one after the other ``` spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 2 # how many pods we can add at a time maxUnavailable: 0 # maxUnavailable define how many pods can be unavailable # during the rolling update ``` blue/green: release a new version alongside the old version then switch traffic canary: release a new version to a subset of users, then proceed to a full rollout #### Configure Liveness, Readiness and Startup Probes ##### Define a liveness command ``` apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-exec spec: containers: - name: liveness image: registry.k8s.io/busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5 ``` ##### Define a liveness HTTP request ``` apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-http spec: containers: - name: liveness image: registry.k8s.io/liveness args: - /server livenessProbe: httpGet: path: /healthz port: 8080 httpHeaders: - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3 ``` #### Protect slow starting containers with startup probes The trick is to set up a startup probe with the same command, HTTP or TCP check, with a failureThreshold * periodSeconds long enough to cover the worse case startup time. ``` ports: - name: liveness-port containerPort: 8080 hostPort: 8080 livenessProbe: httpGet: path: /healthz port: liveness-port failureThreshold: 1 periodSeconds: 10 startupProbe: httpGet: path: /healthz port: liveness-port failureThreshold: 30 periodSeconds: 10 ``` #### Define readiness probes ``` readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5 ``` ### StatefulSets StatefulSet is the workload API object used to manage stateful applications. ``` apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx # has to match .spec.template.metadata.labels serviceName: "nginx" replicas: 3 # by default is 1 minReadySeconds: 10 # by default is 0 template: metadata: labels: app: nginx # has to match .spec.selector.matchLabels spec: terminationGracePeriodSeconds: 10 containers: - name: nginx image: registry.k8s.io/nginx-slim:0.8 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "my-storage-class" resources: requests: storage: 1Gi ``` ### istio Architecture ![](https://i.imgur.com/q8QomuZ.png) #### envoy Istio uses an extended version of the Envoy proxy. Envoy is a high-performance proxy developed in C++ to mediate all inbound and outbound traffic for all services in the service mesh. Envoy proxies are the only Istio components that interact with data plane traffic. Envoy proxies are deployed as sidecars to services, logically augmenting the services with Envoy’s many built-in features, for example: - Dynamic service discovery - Load balancing - TLS termination - HTTP/2 and gRPC proxies - Circuit breakers - Health checks - Staged rollouts with %-based traffic split - Fault injection - Rich metrics #### Istiod Istiod provides service discovery, configuration and certificate management. Istiod converts high level routing rules that control traffic behavior into Envoy-specific configurations, and propagates them to the sidecars at runtime. Pilot abstracts platform-specific service discovery mechanisms and synthesizes them into a standard format that any sidecar conforming with the Envoy API can consume.