Learning Objectives: Upon completion of this module, you will get to know the difference between a virtual machine and a container, the need for Kubernetes in the world of containerization, and also what Kubernetes is not.
Topics:
  • Docker Essentials
  • What is YAML ?
  • Basics of YAML
  • YAML Structure
  • Syntax of YAML
  • What is Virtualization?
  • What is Containerization?
  • Virtualization vs Containerization
  • Introduction to Kubernetes
  • Myth busters of Kubernetes – What Kubernetes is not?
Learning Objectives: Upon completion of this module, one will get to know about the key components that build a Kubernetes cluster – Master components, Node components and AddOns. We will also see how to install Kubernetes from scratch on Ubuntu VMs.
Topics:
  • Introduction to Kubernetes Master
  • kube-apiserver
  • etcd key-value store
  • kube-scheduler
  • kube-controller-manager
  • cloud-controller-manager
  • Components of Cloud Controller Manager – Node Controller, Volume Controller, Route Controller, Service Controller
  • Introduction to Node Components of Kubernetes
  • Docker
  • kubelet
  • kube-proxy
  • kubectl
  • Add-ons in Kubernetes: Cluster DNS, Kubernetes Dashboard, Container Resource Monitoring, Cluster level logging
Learning Objectives: In this module, you will understand how to deploy an app using Kubectl to the local Kubernetes cluster and why we need a Pod.
Topics:
  • Introduction to Pods
  • Why do we need a Pod?
  • Pod Lifecycle
  • Working with Pods to manage multiple containers
  • Pod Preset
  • What is a Node?
  • kubectl basic commands
  • Containerized app deployment on local kubernetes cluster
  • GCP (Ephemeral) volumes

Config maps ideally stores application configuration in a plain text format whereas Secrets store sensitive data like password in an encrypted format. Both config maps and secrets can be used as volume and mounted inside a pod through a pod definition file.

Config map:

                 kubectl create configmap myconfigmap
 --from-literal=env=dev

Secret:

echo -n ‘admin’ > ./username.txt
echo -n ‘abcd1234’ ./password.txt
kubectl create secret generic mysecret --from-file=./username.txt --from-file=./password.txt

When a node is tainted, the pods don’t get scheduled by default, however, if we have to still schedule a pod to a tainted node we can start applying tolerations to the pod spec.

Apply a taint to a node:

kubectl taint nodes node1 key=value:NoSchedule

Apply toleration to a pod:

spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"

The mapping between persistentVolume and persistentVolumeClaim is always one to one. Even When you delete the claim, PersistentVolume still remains as we set persistentVolumeReclaimPolicy is set to Retain and It will not be reused by any other claims. Below is the spec to create the Persistent Volume.

apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain

You should be creating serviceAccount. A service account creates a token and tokens are stored inside a secret object. By default Kubernetes automatically mounts the default service account. However, we can disable this property by setting automountServiceAccountToken: false in our spec. Also, note each namespace will have a service account

apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa
automountServiceAccountToken: false

A Pod always ensure that a container is running whereas the Job ensures that the pods run to its completion. Job is to do a finite task.

Examples:

kubectl run mypod1 --image=nginx --restart=Never
kubectl run mypod2 --image=nginx --restart=onFailure
○ → kubectl get pods
NAME           READY STATUS   RESTARTS AGE
mypod1         1/1 Running   0 59s
○ → kubectl get job
NAME     DESIRED SUCCESSFUL   AGE
mypod1   1 0            19s

By default Deployment in Kubernetes using RollingUpdate as a strategy. Let’s say we have an example that creates a deployment in Kubernetes

kubectl run nginx --image=nginx # creates a deployment
○ → kubectl get deploy
NAME    DESIRED  CURRENT UP-TO-DATE   AVAILABLE AGE
nginx   1  1 1            0 7s

Now let’s assume we are going to update the nginx image

kubectl set image deployment nginx nginx=nginx:1.15 # updates the image 

Now when we check the replica sets

kubectl get replicasets # get replica sets
NAME               DESIRED CURRENT READY   AGE
nginx-65899c769f   0 0 0       7m
nginx-6c9655f5bb   1 1 1       13s

From the above, we can notice that one more replica set was added and then the other replica set was brought down

kubectl rollout status deployment nginx

# check the status of a deployment rollout

kubectl rollout history deployment nginx

# check the revisions in a deployment

○ → kubectl rollout history deployment nginx
deployment.extensions/nginx
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

We can introduce probes. A liveness probe with a Pod is ideal in this scenario.

A liveness probe always checks if an application in a pod is running,  if this check fails the container gets restarted. This is ideal in many scenarios where the container is running but somehow the application inside a container crashes.

spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
      httpGet:
        path: /healthz
  • sidecar:

A pod spec which runs the main container and a helper container that does some utility work, but that is not necessarily needed for the main container to work.

  • adapter:

The adapter container will inspect the contents of the app’s file, does some kind of restructuring and reformat it, and write the correctly formatted output to the location.

  • ambassador:

It connects containers with the outside world. It is a proxy that allows other containers to connect to a port on localhost.

The only difference between replication controllers and replica sets is the selectors. Replication controllers don’t have selectors in their spec and also note that replication controllers are obsolete now in the latest version of Kubernetes.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
  selector:
    matchLabels:
      tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3

Reference: https://Kubernetes.io/docs/concepts/workloads/controllers/replicaset/

By declaring pods with the label(s) and by having a selector in the service which acts as a glue to stick the service to the pods.

kind: Service

apiVersion: v1
metadata:
name: my-service
spec:
  selector:
    app: MyApp
ports:
- protocol: TCP
port: 80

Let’s say if we have a set of Pods that carry a label “app=MyApp” the service will start routing to those pods.

Learning Objectives: Upon completion of this module, one will get to know about the key components that build a Kubernetes cluster – Master components, Node components and AddOns. We will also see how to install Kubernetes from scratch on Ubuntu VMs.
Topics:
  • Introduction to Kubernetes Master
  • kube-apiserver
  • etcd key-value store
  • kube-scheduler
  • kube-controller-manager
Learning Objectives: After this module, you should be able to deploy both stateless applications and stateful applications. You will be able to create a stateful set and a headless service. You will also be able to scale the stateful sets and provide rolling updates.
Topics:
  • Stateful set
  • Pod management policies: OrderedReady, Parallel
  • Update strategies: OnDelete, Rolling Update
  • Headless services
  • Persistent Volumes
Learning Objectives: Once you complete this module, you will be able to use federations in Kubernetes using kubefed. You will also be able to log the events of the Kubernetes cluster and use it to debug nodes and pods. You will get aware of how security can be enforced in the cluster that we create using the best practices.
Topics:
  • Federated clusters
  • Debugging by looking at events such as: Pending Pods, Unreachable nodes
  • Auditing and accessing logs in Kubernetes – Log collectors and audit policy
  • Security best practices in Kubernetes

Containers on same pod act as if they are on the same machine. You can ping them using localhost:port itself. Every container in a pod shares the same IP. You can `ping localhost` inside a pod. Two containers in the same pod share an IP and a network namespace and They are both localhost to each other. Discovery works like this: Component A’s pods -> Service Of Component B -> Component B’s pods and Services have domain names servicename.namespace.svc.cluster.local, the dns search path of pods by default includes that stuff, so a pod in namespace Foo can find a Service bar in same namespace Foo by connecting to `bar`

No, because there is only 1 replica, any changes to state full set would result in an outage. So rolling update of a StatefulSet would need to tear down one (or more) old pods before replacing them. In case 2 replicas, a rolling update will create the second pod, which it will not be succeeded, the PD is locked by first (old) running pod, the rolling update is not deleting the first pod in time to release the lock on the PDisk in time for the second pod to use it. If there’s only one that rolling update goes 1 -> 0 -> 1.f the app can run with multiple identical instances concurrently, use a Deployment and roll 1 -> 2 -> 1 instead.

Use the correct auth mode with API server authorization-mode=Node,RBAC Ensure all traffic is protected by TLS Use API authentication (smaller cluster may use certificates but larger multi-tenants may want an AD or some OIDC authentication).

Make kubeless protect its API via authorization-mode=Webhook. Make sure the kube-dashboard uses a restrictive RBAC role policy Monitor RBAC failures Remove default ServiceAccount permissions Filter egress to Cloud API metadata APIs Filter out all traffic coming into kube-system namespace except DNS.

A default deny policy on all inbound on all namespaces is good practice. You explicitly allow per deployment.Use a podsecurity policy to have container restrictions and protect the Node Keep kube at the latest version.

kube-proxy does 2 things

  • for every Service, open a random port on the node and proxy that port to the Service.
  • install and maintain iptables rules which capture accesses to a virtual ip:port and redirect those to the port in (1)

The kube-proxy is a component that manages host sub-netting and makes services available to other components.Kubeproxy handles network communication and shutting down master does not stop a node from serving the traffic and kubeproxy works, in the same way, using a service. The iptables will route the connection to kubeproxy, which will then proxy to one of the pods in the service.kube-proxy translate the destination address to whatever is in the endpoints.

Container Runtime

  • Kubelet
  • kube-proxy

Kubernetes Worker node is a machine where workloads get deployed. The workloads are in the form of containerised applications and because of that, every node in the cluster must run the container run time such as docker in order to run those workloads. You can have multiple masters mapped to multiple worker nodes or a single master having a single worker node. Also, the worker nodes are not gossiping or doing leader election or anything that would lead to odd-quantities. The role of the container run time is to start and managed containers. The kubelet is responsible for running the state of each node and it receives commands and works to do from the master. It also does the health check of the nodes and make sure they are healthy. Kubelet is also responsible for metric collectins of pods as well. The kube-proxy is a component that manages host subnetting and makes services available to other components.

Yes using replication controller but it may reschedule to another host if you have multiple nodes in the cluster

A replication controller is a supervisor for long-running pods. An RC will launch a specified number of pods called replicas and makes sure that they keep running. Replication Controller only supports the simple map-style `label: value` selectors. Also, Replication Controller and ReplicaSet aren’t very different. You could think of ReplicaSet as Replication Controller. The only thing that is different today is the selector format. If pods are managed by a replication controller or replication set you can kill the pods and they’ll be restarted automatically. The yaml definition is as given below:

  • apiVersion: v1
  • kind: ReplicationController
  • metadata:
  • name: test
  • spec:
  • replicas: 3
  • selector:
  • app: test
  • template:
  • metadata:
  • name: test
  • labels:
  • app: test
  • spec:
  • containers:
  • name: test
  • image: image/test
  • ports:
  • containerPort: 80

well you need to have some way of triggering the reload. ether do a check every minute or have a reload endpoint for an api or project the configmap as a volume, could use inotify to be aware of the change. Depends on how the configmap is consumed by the container. If env vars, then no. If a volumeMount, then the file is updated in the container ready to be consumed by the service but it needs to reload the file

The container does not restart. if the configmap is mounted as a volume it is updated dynamically. if it is an environment variable it stays as the old value until the container is restarted.volume mount the configmap into the pod, the projected file is updated periodically. NOT realtime. then have the app recognise if the config on disk has changed and reload

Yes, the scheduler will make sure (as long as you have the correct resources) that the number of desired pods are met. If you delete a pod, it will recreate it. Also deleting a service won’t delete the Replica set. if you remove Service or deployment you want to remove all resources which Service created. Also having a single replica for a deployment is usually not recommended because you cannot scale out and are treating in a specific way

Any app should be `Ingress` -> `Service` -> `Deployment` -> (volume mount or 3rd-party cloud storage)

You can skip ingress and just have `LoadBalancer (service)` -> `Deployment` (or Pod but they don’t auto restart, deployments do)

loadBalancerIP is not a core Kubernetes concept, you need to have a cloud provider or controller like metallb set up the loadbalancer IP. When MetalLB sees a Service of type=LoadBalancer with a ClusterIP created, MetalLB allocates an IP from its pool and assigns it as that Service’s External LoadBalanced IP.the externalIP, on the other hand, is set up by kubelet so that any traffic that is sent to any node with that externalIP as the final destination will get routed.`ExternalIP` assumes you already have control over said IP and that you have correctly arranged for traffic to that IP to eventually land at one or more of your cluster nodes and its is a tool for implementing your own load-balancing. Also you shouldn’t use it on cloud platforms like GKE, you want to set `spec.loadBalancerIP` to the IP you preallocated. When you try to create the service using .`loadBalancerIP` instead of `externalIP`, it doesn’t create the ephemeral port and the external IP address goes to `<pending>` and never updates.

You need to add a liveness and readiness probe to query each container,  if the probe fails, the entire pod will be restarted .add liveness object that calls any api that returns 200 to you from another container and both liveness and readiness probes run in infinite loops for example, If X depended to Y So add liveness  in X that check the health of Y.Both readiness/liveness probes always have to run after the container has been started .kubelet component performs the liveness/readiness checks and set initialDelaySeconds and it can be anything from a few seconds to a few minutes depending on app start time. Below is the configuration spec

  • livenessProbe spec:
  • livenessProbe:
  • httpGet:
  • path: /path/test/
  • port: 10000
  • initialDelaySeconds: 30
  • timeoutSeconds: 5
  • readinessProbe spec:
  • readinessProbe:
  • httpGet:
  • path: /path/test/
  • port: 10000
  • initialDelaySeconds: 30
  • timeoutSeconds: 5