Kubernetes in action

created : Mon, 31 Jan 2022 04:38:12 +0900
modified : Sun, 12 Mar 2023 21:16:57 +0900
k8s

Part 1. Overview

Chapter 1. Introducing Kubernetes

Changes of software development and deployments.

1.1. Understanding the need for a system like Kubernetes

1.1.1. Moving from monolithic apps to microservices

1.1.2. Providing a consistent environment to applications

1.1.3. Moving to continuous delivery: DevOps and NoOps

1.2. Introducing container technologies

1.2.1. Understanding what contianers are

1.2.2. Intoducing the Docker container platform

1.2.3. Introducing rkt - an alternative to Docker

1.3. Introducing Kubernetes

1.3.1. Understanding its origins

1.3.2. Looking at Kubernetes from the top of a mountain

1.3.3. Understanding the architecture of a Kubernetes cluster

1.3.4. Running an application in Kubernetes

1.3.5. Understanding the benefits of using Kubernetes

1.4. Summary

Chapter 2. First steps with Docker and Kubernetes

2.1. Creating, running, and sharing a container image

docker run <image>:<tag>
FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]
docker ps
docker exec -it <container-name> <command>
docker inspect <container-name>

2.1.7. Stopping and removing a container

docker rm <conatinaer-name>

2.1.8. Pushing the image to an image registry

docker tag <image> <docker-hub-id>/<name>
docker images | head
docker push <docker-hub-id>/<name>

2.2. Setting up a Kubernetes cluster

2.2.1. Running a local single-node Kubernetes cluster with Minikube

2.3. Running your first app on Kubernetes

2.3.1 Deploying your app

kubectl run kubia --image=<image-name> --port=<port>
kubectl get pods

2.3.2. Accessing your web application

kubectl expose rc <pod-name> --type=LoadBalancer --name <service-name>
kubectl get services
kubectl get svc

2.3.3. The logical parts of your system

2.3.4. Horizontally scaling the application

kubectl scale rc <pod-name> --replicas=<number>
kubectl get rc

2.3.5. Examining what nodes your app is running on

2.3.6. Introducing the Kubernetes dashboard

2.4. Summary

Part 2. Core concepts

Chapter 3. Pods: running containers in Kubernetes

3.1. Intorducing pods

3.1.1. Understanding why we need pods

3.1.2. Understanding pods

3.1.3. Organization containers across pods properly

3.2. Creating pods from YAML or JSON descriptors

kubectl get po <podname> -o yaml
  1. Kubernetes API version used in this YAML descriptor
  2. Type of Kubernetes object/resource
  3. Pod metadata(name, labels, annotations, and so on)
  4. Pod specification/contents(list of pod’s containers, volumes, and so on)
  5. Detailed status of the pod and its containers

3.2.2. Creating a simple YAML descriptor for a pod

kubectl explain pods

3.2.3. Using kubectl create to create the pod

3.2.4. Viewing application logs

kubectl logs <container id>
kubectl logs <container id> -c <container-name>

3.2.5. Sending requests to the pod

kubectl port-forward <container-id> 8888:8080

3.3. Organizing pods with labels

3.3.1. Introducing labels

3.3.2. Specifying labels when creating a pod

3.3.3. Modifying labels of existing pods

kubectl get po --show-labels
kubectl get po -L creation_method,env
kubectl label po <pod-name> creation_method=manual

3.4. Listing subsets of pods through label selectors

3.4.1. Listing pods using a label selector

3.4.2. Using multiple conditions in a label selector

3.5. Using labels and selectors to constrain pod scheduling

3.5.1. Using labels for categorizing worker nodes

3.5.2. Scheduling pods to specific nodes

3.5.3. Scheduling to one specific node

3.6. Annotating pods

3.6.1. Looking up an object’s annotations

3.6.2. Adding and modifying annotations

3.7. Using namespaces to group resources

3.7.1. Understanding the need for namespaces

3.7.2. Discovering other namespaces and their pods

3.7.3. Creating a namespace

3.7.4. Managing objects in other namespaces

3.7.5. Understanding the isolation provided by namespaces

3.8. Stopping and removing pods

3.8.1. Deleting a pod by name

3.8.2. Deleting pods using label selectors

Chapter 4. Replication and other controllers: deploying managed pods

4.1. Keeping pods healthy

4.1.1. Introducing liveness probes

4.1.2. Creating an HTTP-based liveness probe

4.1.3. Seeing a liveness probe in action

4.1.4. Configuring addiontal properties of the liveness probe

4.1.5. Creating effective liveness probes

4.2. Introducing ReplicationControllers

4.2.1. The operation of a ReplicationController

4.2.2. Creating a ReplicationController

4.2.3. Seeing the ReplicationController in action

kubectl get rc

4.2.4. Moving pods in and out of the scope of a ReplicationController

4.2.5. Changing the pod template

kubectl edit rc <rc-name>

4.2.6. Horizontally scaling pods

kubectl scale rc <rc-name> --replicas=<num>

4.2.7. Deleting a ReplicationController

kubectl delete rc <rc-name>

4.3. Using ReplicaSets instead of ReplicationControllers

4.3.1. Comparing a ReplicaSet to a ReplicationController

4.3.2. Defining a ReplicaSet

4.3.3. Creating and examing a ReplicaSet

kubectl get rs

4.3.4. Using the ReplicaSet’s more expressive label selectors

4.3.5. Wrapping up ReplicaSets

kubectl delete rs <rs-name>

4.4. Running exactly one pod on each node with DaemonSets

4.4.1. Using a DaemonSet to run a pod one every node

4.4.2. Using a DaemonSet to run pods only on certain nodes

4.5. Running pods that perform a single completable task

4.5.1. Introducing the Job resource

4.5.2. Defining a Job resource

4.5.3. Seeing a Job run a pod

kubectl get jobs

4.5.4. Running multiple pod instances in a Job

4.5.5. Limiting the time allowed for a Job pod to complete

4.6. Scheduling Jobs to run periodically or once in the future

4.6.1. Creating a CronJob

4.6.2. Understanding how scheduled jobs are run

4.7. Summary

Chapter 5. Services: enabling clients to discover and talk to pods

5.1. Intoducing services

5.2. Connecting to services living outside the cluster

5.3. Expsing services to external clients

5.4. Exposing services externally through an Ingress resource

5.5. Signaling when a pod is ready to accept connections

5.6. Using a headless service for discovering individual pods

5.7. Troubleshooting services

5.8. Summary

Chapter6. Volumes: attaching disk storage to containers

6.1. Introducing volumes

6.2. Using volumes to share data between containers

6.2.1. Using an emptyDir volume

6.2.2. Using a Git repository as the starting point for a volume

6.3. Accessing files on the worker node’s filesystem

6.4. Using persistent storage

6.5. Decoupling pods from the underlying storage technology

6.5.1. Introducing PersistentVolumes and PersistentVolumeClaims

6.5.2. Creating a PersistentVolume

6.6. Dynamic provisioning of PersistentVolumes

6.7. Summary

Chapter 7. ConfigMaps and Secrets: configuringg applications

7.1. Configuring containerized applications

7.2. Passing command-line arguments to containers

7.2.1. Defining the command and arguments in Docker

7.3. Setting environment variables for a container

7.4. Decoupling configuration with a ConfigMap

7.5. Using Secrets to pass sensitive data to containers

7.6. Summary

Chapter 8. Accessing pod metadata and other resources from applications

8.1. Passing metadata through the Downward API

8.2. Talking to the Kubernetes API server

kubectl cluster-info
kubectl proxy

Chapter 9. Deployments: updating applications declaratively

9.1. Updating applications running in pods

9.2. Performing an automatic rolling update with a ReplicationController

9.3. Using Deployments for updating apps declaratively

9.4. Summary

Chatper 10. StatefulSets: deploying replicated statful applications

10.6. Summary

Part 3. Beyond the basics

Chapter 11. Understanding Kubernetes internals

11.1 Understanding the architecture

11.1.1. The distribued natrue of Kubernetes components

11.1.2. How kubernetes uses etcd

11.1.3. What the API server does

  1. Authenticating the client with authentication plugins
  2. Authorizing the client with authorization plugins
  3. Validating and/or Modifying the resource in the request with admission control plugins
  4. Validating the resource and storing it persistently

11.1.4. Understanding how the API server notifies clients of resource changes

11.1.5. Understanding the Scheduler

11.1.6. Introducing the controllers running in the Controller Manager

11.1.7. What the Kubelet does

11.1.8. The role of the Kubernetes Service Proxy

11.1.9. Introducing Kubernetes add-ons

11.1.10. Bringing it all together

11.2. How controllers cooperate

11.2.1. Understanding which components are involved

kubectl get events --watch

11.3. Understanding what a running pod is

11.4. Inter-pod networking

11.4.3. Introducing the Container Network Interface

11.5. How services are implemented

11.5.1. Introducing the kube-proxy

11.5.2. How kube-proxy uses iptables

  1. When a service is created in the API server, the virtual IP address is assigned to it immediately.
  2. The API server notifies all kube-proxy agents running on the worker nodes that a new Service has been created.
  3. Each kube-proxy makes that service addressable on the node it’s running on.

11.6. Running highly avaiable clusters

11.6.2. Making Kubernetes Control Plane components highly available

Chapter 12. Securing the Kubernetes API server

12.1. Understanding authentication

11.1.1. Users and groups

kubectl get sa

11.1.4. Assigning a ServiceAccount to a pod

12.2. Securing the cluster with role-based access control

12.2.1. Introducing the RBAC authorization plugin

| HTTP method | Verb for single resource | Verb for collection | | GET, HEAD | get(and watch for watching) | list (and watch) | | POST | create | n/a | | PUT | update | n/a | | PATCH | patch | n/a | | DELETE | delete | deletecollection |

12.2.2. Introducing RBAC resources


12.3. Summary

Chatper 13. Securing cluster nodes and the network

13.1. Using the host node’s namespaces in a pod

13.1.1. Using the node’s network namespace in a pod

13.1.2. Binding to a host port without using the host’s network namespace

13.2. Configuring the container’s security context

13.2.1. Running a container as a specific user

13.2.2. Preventing a container from running as root

13.2.3. Running pods in privileged mode

13.2.4. Adding individual kernel capabilities to a container

13.3.1. Introducing the PodSecurityPolicy resource

13.3.2. Understanding runAsUser, fsGroup, and supplementalGroups policies

13.3.3. Configuring allowed, default, and disallowed capabilities

13.3.4. Constraining the types of volumes pods can use

13.3.5. Assigning different PodSecurityPolicies to different users and groups

13.4. Isolation the pod network

13.4.2. Allowing only some pods in the namespace to connect to a server pod

13.4.3. Isolating the network between Kubernetes namespaces

13.4.4. Isolating using CIDR notation

13.5. Summary

Chapter 14. Managing pods’ computational resources

14.1. Requesting resources for a pod’s containers

14.2. Limiting resources available to a container

14.3. Understanding pod QoS classes

14.4. Setting default requests and limits for pods per namespace

14.5. Limiting the total resources available in a namespace

14.5.1. Introducing the Resource Quota object

14.6. Monitoring pod resource usage

Chatper 15. Automatic scaling of pods and cluseter nodes

15.1. Horizontal pod autoscaling

15.1.1. Understanding the autoscaling process

15.1.2. Scaling based on CPU utilization

kubectl autoscale deployment <deployment name> --cpu-percent=30 --min=1 --max=5
kubectl get hpa

15.1.3. Scaling based on memory consumption

15.1.4. Scaling based on other and custom metrics

15.1.5. Determining which metrics areappropriate for autoscaling

15.1.6. Scaling down to zero replicas

15.2. Vertical pod autoscaling

15.2.1. Automatically configuring resource requests

15.2.2. Modifying resource requests while a pod is running

15.3. Horizontal scaling of cluster nodes

15.3.1. Introducing the Cluster Autoscaler

15.3.2. Enabling the Cluster Autoscaler

15.3.3. Limiting service disruption during cluster scale-down

kubectl create pdb <pdb name> --selector=<selector; e.g. app=kubia> --min-available=<numeric; e.g. 3>

15.4. Summary

Chapter 16. Advanced schdeuling

16.1. Using taints and tolerations to repel pods from certain nodes

16.1.1. Introducing taints and tolerations

16.1.2. Adding custom taints to a node

16.1.3. Adding toleratiosn to pods

16.1.4. Understanding what taints and tolerations can be used for

16.2. Using node affinity to attract pods to certain nodes

16.2.1. Specifying hard node affinity rules

apiVersion: v1
kind: Pod
metadata:
  name: kubia-gpu
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: gpu
            operation: In
            values:
            - "true"

16.2.2. Prioritizing nodes when scheduling a pod

16.3. Co-locating pods with pod affinity and anti-affinity

16.3.1. Using inter-pod affinity to deploy pods on the same node

16.3.2. Deploying pods in the same rack, availability zone, or geographic region

16.3.3. Expressing pod affinity preferences instad of hard requirements

16.3.4. Schdeduling pods away from each other with pod anti-affinity

16.4. Summary

Chapter 17. Best practices for developing apss

17.1. Bringing everything together

17.2. Understanding the pod’s lifecycle

17.2.1. Applicatiosn must expect to be killed and replocated

17.2.2. Rescheduling of dead or partially dead pods

17.2.3. Starting pods in a specific order

17.2.4. Adding lifecycle hooks

17.2.5. Understanding pod shutdown

17.3. Ensuring all client requests are handled properly

17.3.1. Preventing broken client connections when a pod is starting up

17.3.2. Preventing broken connections during pod shutdown

17.4. Making your apps easy to run and manage in Kubernetes

17.4.1. Making manageable container images

17.4.2. Properly tagging your images and using imagePullPolicy wisely

17.4.3. Using multi-dimensional instead of single-dimensional labels

17.4.4. Describing each resource through annotations

17.4.5. Providing infromation on why the process terminated

17.4.6. Handling application logs

17.5. Best practices for development and testing

17.5.1. Running apps outside of Kubernetes during development

17.5.2. Using Minikube in development

17.6. Summary