1: Preface
- 1.1: The sample app and GitHub repo
- Exercise 1
- 1.2: Windows users
- 1.3: Terminology and responsible language
- 1.4: Feedback
- Quiz 1
2: Kubernetes primer
- 2.1: Important Kubernetes background
- 2.1.1: Orchestration
- 2.1.2: Containerization
- 2.1.3: Cloud native
- 2.1.4: Microservices
- 2.1.5: Where did Kubernetes come from
- 2.1.6: Kubernetes and Docker
- 2.1.7: What about Docker Swarm
- 2.1.8: Kubernetes and Borg: Resistance is futile!
- 2.1.9: Kubernetes–what’s in the name
- Exercise 2
- 2.2: Kubernetes: the operating system of the cloud
- 2.2.1: Application scheduling
- Exercise 3
- 2.3: Chapter summary
- Quiz 2
3: Kubernetes principles of operation
- 3.1: Kubernetes from 40K feet
- 3.1.1: Kubernetes: Cluster
- 3.1.2: Kubernetes: Orchestrator
- Exercise 4
- 3.2: Control plane and worker nodes
- 3.2.1: The control plane
- 3.2.1.1: The API server
- 3.2.1.2: The cluster store
- 3.2.1.3: Controllers and the controller manager
- 3.2.1.4: The scheduler
- 3.2.1.5: The cloud controller manager
- 3.2.1.6: Control Plane summary
- 3.2.2: Worker nodes
- 3.2.2.1: Kubelet
- 3.2.2.2: Runtime
- 3.2.2.3: Kube-proxy
- Exercise 5
- 3.3: Packaging apps for Kubernetes
- Exercise 6
- 3.4: The declarative model and desired state
- Exercise 7
- 3.5: Pods
- 3.5.1: Pods and containers
- 3.5.2: Pod anatomy
- 3.5.3: Pod scheduling
- 3.5.4: Pods as the unit of scaling
- 3.5.5: Pod lifecycle
- 3.5.6: Pod immutability
- Exercise 8
- 3.6: Deployments
- Exercise 9
- 3.7: Service objects and stable networking
- Exercise 10
- 3.8: Chapter summary
- Exercise 11
- Quiz 3
4: Getting Kubernetes
- 4.1: Install everything with Docker Desktop
- 4.1.1: Create a Docker account
- 4.1.2: Install Docker Desktop
- 4.1.3: Deploy Docker Desktop’s built-in multi-node Kubernetes cluster
- Exercise 12
- 4.2: Linode Kubernetes Engine (LKE)
- 4.3: Build a Kubernetes cluster in the Linode Cloud
- 4.3.1: Sign up for a Linode account
- 4.3.2: Create your LKE cluster
- Exercise 13
- 4.4: Configure kubectl
- 4.4.1: If you don’t have a kubeconfig file
- 4.4.2: If you already have a kubeconfig file
- Exercise 14
- 4.5: Test your LKE cluster
- Exercise 15
- 4.6: More about kubectl and your kubeconfig file
- Exercise 16
- 4.7: Chapter summary
- Exercise 17
- Quiz 4
5: Working with Pods
- 5.1: Pod theory
- 5.1.0.1: Pods are an abstraction layer
- 5.1.0.2: Pods augment workloads
- 5.1.0.3: Pods enable resource sharing
- 5.1.0.4: Pods and scheduling
- 5.1.1: Deploying Pods
- 5.1.2: Pod lifecycle
- 5.1.2.1: Restart Policies
- 5.1.3: Static Pods vs controllers
- 5.1.4: The pod network
- Exercise 18
- 5.2: Multi-container Pods
- 5.2.1: Multi-container Pods: Init containers
- 5.2.2: Multi-container Pods: Sidecars
- 5.2.3: Pod theory summary
- Exercise 19
- 5.3: Hands-on with Pods
- 5.3.1: Pod manifest files
- 5.3.2: Manifest files: Empathy as Code
- 5.3.3: Deploying Pods from a manifest file
- 5.3.4: Introspecting Pods
- 5.3.4.1: kubectl get
- 5.3.4.2: kubectl describe
- 5.3.4.3: kubectl logs
- 5.3.5: kubectl exec
- 5.3.6: Pod hostnames
- 5.3.7: Check Pod immutability
- 5.3.8: Resource requests and resource limits
- 5.3.9: Multi-container Pod example–init container
- 5.3.10: Multi-container Pod example–sidecar container
- Exercise 20
- 5.4: Clean up
- Exercise 21
- 5.5: Chapter Summary
- Exercise 22
- Quiz 5
6: Virtual clusters with Namespaces
- 6.1: Intro to Namespaces
- Exercise 23
- 6.2: Namespace use cases
- Exercise 24
- 6.3: Default Namespaces
- Exercise 25
- 6.4: Creating and managing Namespaces
- 6.4.1: Configure kubectl for a specific Namespace
- Exercise 26
- 6.5: Deploying objects to Namespaces
- Exercise 27
- 6.6: Clean up
- Exercise 28
- 6.7: Chapter Summary
- Exercise 29
- Quiz 6
7: Kubernetes Deployments
- 7.1: Deployment theory
- 7.1.1: Deployments and Pods
- 7.1.2: Deployments and ReplicaSets
- 7.1.3: A quick word on scaling
- 7.1.4: It’s all about the state
- 7.1.4.1: Declarative vs Imperative
- 7.1.4.2: Controllers and reconciliation
- 7.1.5: Rolling updates with Deployments
- 7.1.6: Rollbacks
- Exercise 30
- 7.2: Create a Deployment
- 7.2.1: Inspecting Deployments
- 7.2.2: Accessing the app
- Exercise 31
- 7.3: Manually scale the app
- Exercise 32
- 7.4: Perform a rolling update
- 7.4.1: Pausing and resuming rollouts
- Exercise 33
- 7.5: Perform a rollback
- 7.5.1: Rollouts and labels
- Exercise 34
- 7.6: Clean up
- Exercise 35
- 7.7: Chapter summary
- Quiz 7
8: Kubernetes Services
- 8.1: Service Theory
- 8.1.1: Labels and loose coupling
- 8.1.2: Behind the scenes with EndpointSlices
- 8.1.3: Service types
- 8.1.3.1: ClusterIP Services - Accessing apps from inside the cluster
- 8.1.3.2: NodePort Services - Accessing apps from outside the cluster
- 8.1.3.3: LoadBalancer Services - Accessing apps via load balancers
- 8.1.4: Summary of Service theory
- Exercise 36
- 8.2: Hands-on with Services
- 8.2.1: Working with Services imperatively
- 8.2.2: The declarative way
- 8.2.2.1: A Service manifest file
- 8.2.2.2: Inspecting Services
- 8.2.2.3: EndpointSlice objects
- Exercise 37
- 8.3: Clean up
- Exercise 38
- 8.4: Chapter Summary
- Exercise 39
- Quiz 8
9: Ingress
- 9.1: Setting the Scene for Ingress
- Exercise 40
- 9.2: Ingress architecture
- Exercise 41
- 9.3: Hands-on with Ingress
- 9.3.1: Install the NGINX Ingress controller
- 9.3.2: Ingress classes
- 9.3.3: Configure host-based and path-based routing
- 9.3.3.1: Deploy the sample environment
- 9.3.3.2: Create the Ingress object
- 9.3.3.3: Inspecting Ingress objects
- 9.3.3.4: Configure DNS name resolution
- 9.3.3.5: Test the Ingress
- Exercise 42
- 9.4: Clean up
- Exercise 43
- 9.5: Chapter summary
- Exercise 44
- Quiz 9
10: Wasm on Kubernetes
- 10.1: Wasm Primer
- 10.1.1: Wasm security
- 10.1.2: Wasm portability
- 10.1.3: Wasm performance
- 10.1.4: Quick recap
- Exercise 45
- 10.2: Understanding Wasm on Kubernetes
- Exercise 46
- 10.3: Hands-on with Wasm on Kubernetes
- 10.3.1: Install and test the pre-requisites
- 10.3.2: Write and compile the Wasm app
- 10.3.3: Build an OCI image and push it to an OCI registry
- 10.3.4: Build and configure a new multi-node Kubernetes cluster for Wasm
- 10.3.5: Deploy and test the app
- 10.3.6: Clean up
- Exercise 47
- 10.4: Chapter Summary
- Exercise 48
- Quiz 10
11: Service discovery deep dive
- 11.1: Setting the scene
- Exercise 49
- 11.2: The service registry
- Exercise 50
- 11.3: Service registration
- Exercise 51
- 11.4: Service discovery
- 11.4.1: ClusterIP routing
- 11.4.2: Summarising service discovery
- Exercise 52
- 11.5: Service discovery and Namespaces
- 11.5.1: Service discovery example
- Exercise 53
- 11.6: Troubleshooting service discovery
- Exercise 54
- 11.7: Clean up
- 11.8: Chapter summary
- Exercise 55
- Quiz 11
12: Kubernetes storage
- 12.1: The big picture
- Exercise 56
- 12.2: Storage Providers
- Exercise 57
- 12.3: The Container Storage Interface (CSI)
- Exercise 58
- 12.4: The Kubernetes persistent volume subsystem
- Exercise 59
- 12.5: Dynamic provisioning with Storage Classes
- 12.5.1: A StorageClass YAML
- 12.5.2: Working with StorageClasses
- 12.5.3: Additional volume settings
- 12.5.3.1: Access mode
- 12.5.3.2: Reclaim policy
- Exercise 60
- 12.6: Hands-on
- 12.6.1: Use an existing StorageClass
- 12.6.2: Create and use a new StorageClass
- Exercise 61
- 12.7: Clean up
- Exercise 62
- 12.8: Chapter Summary
- Exercise 63
- Quiz 12
13: ConfigMaps and Secrets
- 13.1: The big picture
- 13.1.1: What it looks like in a decoupled world
- Exercise 64
- 13.2: ConfigMap theory
- 13.2.1: How ConfigMaps work
- 13.2.2: ConfigMaps and Kubernetes-native apps
- Exercise 65
- 13.3: Hands-on with ConfigMaps
- 13.3.1: Creating ConfigMaps imperatively
- 13.3.2: Inspecting ConfigMaps
- 13.3.3: Creating ConfigMaps declaratively
- 13.3.4: Injecting ConfigMap data into Pods and containers
- 13.3.4.1: ConfigMaps and environment variables
- 13.3.4.2: ConfigMaps and container startup commands
- 13.3.4.3: ConfigMaps and volumes
- Exercise 66
- 13.4: Hands-on with Secrets
- 13.4.1: Are Kubernetes Secrets secure?
- 13.4.2: Creating Secrets
- 13.4.3: Using Secrets in Pods
- Exercise 67
- 13.5: Clean up
- Exercise 68
- 13.6: Chapter Summary
- Exercise 69
- Quiz 13
14: StatefulSets
- 14.1: StatefulSet theory
- 14.1.1: StatefulSet Pod naming
- 14.1.2: Ordered creation and deletion
- 14.1.3: Deleting StatefulSets
- 14.1.4: StatefulSets and Volumes
- 14.1.5: Handling failures
- 14.1.6: Network ID and headless Services
- Exercise 70
- 14.2: Hands-on with StatefulSets
- 14.2.1: Deploy the StorageClass
- 14.2.2: Create a governing headless Service
- 14.2.3: Deploy the StatefulSet
- 14.2.4: Testing peer discovery
- 14.2.5: Scaling StatefulSets
- 14.2.6: Rollouts
- 14.2.7: Test a Pod failure
- 14.2.8: Test a node failure
- 14.2.9: Deleting StatefulSets
- Exercise 71
- 14.3: Clean up
- 14.4: Chapter Summary
- Exercise 72
- Quiz 14
15: API security and RBAC
- 15.1: API security big picture
- Exercise 73
- 15.2: Authentication
- 15.2.1: Checking your current authentication setup
- Exercise 74
- 15.3: Authorization (RBAC)
- 15.3.1: RBAC big picture
- 15.3.2: Users and Permissions
- 15.3.2.1: Looking closer at rules
- 15.3.3: Cluster-level users and permissions
- 15.3.4: Real-world example
- 15.3.5: Summarizing authorization
- Exercise 75
- 15.4: Admission control
- Exercise 76
- 15.5: Chapter summary
- Exercise 77
- Quiz 15
16: The Kubernetes API
- 16.1: Kubernetes API big picture
- 16.1.1: JSON serialization
- 16.1.2: API analogy
- Exercise 78
- 16.2: The API server
- 16.2.1: A word on REST and RESTful
- 16.2.2: Hands-on
- 16.2.3: A word on CRUD
- Exercise 79
- 16.3: The API
- 16.3.1: The core API group
- 16.3.2: Named API groups
- 16.3.3: Inspecting the API
- 16.3.4: Alpha beta and stable
- 16.3.5: Resource deprecation
- 16.3.6: Extending the API
- 16.3.7: Clean up
- Exercise 80
- 16.4: Chapter summary
- Exercise 81
- Quiz 16
17: Threat modeling Kubernetes
- 17.1: Threat modeling
- Exercise 82
- 17.2: Spoofing
- 17.2.1: Securing communications with the API server
- 17.2.2: Securing Pod communications
- Exercise 83
- 17.3: Tampering
- 17.3.1: Tampering with Kubernetes components
- 17.3.2: Tampering with applications running on Kubernetes
- Exercise 84
- 17.4: Repudiation
- Exercise 85
- 17.5: Information Disclosure
- 17.5.1: Protecting cluster data
- 17.5.2: Protecting data in Pods
- Exercise 86
- 17.6: Denial of Service
- 17.6.1: Protecting cluster resources against DoS attacks
- 17.6.2: Protecting the API Server against DoS attacks
- 17.6.3: Protecting the cluster store against DoS attacks
- 17.6.4: Protecting application components against DoS attacks
- Exercise 87
- 17.7: Elevation of privilege
- 17.7.1: Protecting the API server
- 17.7.2: Protecting Pods
- 17.7.2.1: Do not run processes as root
- 17.7.2.2: Capability dropping
- 17.7.2.3: Filter syscalls
- 17.7.2.4: Mandatory Access Controls
- 17.7.2.5: Prevent privilege escalation by containers
- 17.7.3: Standardizing Pod Security with PSS and PSA
- 17.7.4: Pod Security Standards (PSS)
- 17.7.5: Pod Security Admission (PSA)
- 17.7.6: PSA examples
- 17.7.6.1: Alternatives to Pod Security Admission
- 17.7.7: Towards a more secure Kubernetes
- Exercise 88
- 17.8: Chapter summary
- Quiz 17
18: Real-world Kubernetes security
- 18.1: Security in the software delivery pipeline
- 18.1.1: Image Repositories
- 18.1.2: Use approved base images
- 18.1.3: Manage the need for non-standard base images
- 18.1.4: Control access to images
- 18.1.5: Moving images from non-production to production
- 18.1.6: Vulnerability scanning
- 18.1.7: Configuration as code
- 18.1.8: Sign container images
- 18.1.9: Image promotion workflow
- Exercise 89
- 18.2: Workload isolation
- 18.2.1: Cluster-level workload isolation
- 18.2.1.1: Namespaces and soft multi-tenancy
- 18.2.1.2: Namespaces and hard multi-tenancy
- 18.2.2: Node isolation
- 18.2.3: Runtime isolation
- 18.2.4: Network isolation
- 18.2.4.1: Kubernetes and overlay networking
- 18.2.4.2: Kubernetes and BGP
- 18.2.4.3: How this impacts firewalls
- 18.2.4.4: Packet capture
- Exercise 90
- 18.3: Identity and access management (IAM)
- 18.3.1: Managing Remote SSH access to cluster nodes
- 18.3.1.1: Multi-factor authentication (MFA)
- Exercise 91
- 18.4: Security monitoring and auditing
- 18.4.1: Baseline best practices
- 18.4.2: Container and Pod lifecycle events
- 18.4.3: Forensic checkpointing
- 18.4.4: Application logs
- 18.4.5: Actions performed by users
- 18.4.6: Managing log data
- 18.4.7: Alerting for security-relevant events
- 18.4.8: Migrating existing apps to Kubernetes
- Exercise 92
- 18.5: Real-world example
- Exercise 93
- 18.6: Chapter summary
- Quiz 18
19: Terminology
- Exercise 94
- Quiz 19
20: Outro and what next
- 20.1: Docker, containers, and AI
- 20.2: Get involved with the community
- 20.3: Connect with me
21: About the authors
- 21.1: Author: Nigel Poulton
- 21.2: Contributing author: Pushkar Joglekar
