Cloud Native DevOps with Kubernetes, read against EKS
Cloud Native DevOps with Kubernetes, read against EKS
Chapter 1, Revolution in the Cloud
This is the best essay in the book, and it needs little correction. The "developer productivity engineering" team (p. 45) is what is now called platform engineering. The claim that ops skills "will only become more important" (p. 43) has held up.
| book says | page | correct, and on AWS |
|---|---|---|
| virtualised workloads "run about 30% slower than the equivalent containers" | 36 | on EKS the comparison does not arise, because your containers run inside EC2 instances, and Nitro offloads most of the overhead that figure measured |
| Lambda is billed "in increments of 100 milliseconds", with about 50 MiB of deployed files | 41 | 1 ms billing since December 2020; container images up to 10 GB alongside zip packages; the 900-second timeout is unchanged (Lambda API model) |
| Knative "is currently under active development" | 41, 265 | Knative reached 1.0 in 2021 and is a CNCF project; on AWS, the managed alternatives are Lambda and Fargate |
Chapters 2–4, first steps, getting Kubernetes, objects
Chapter 3's recommendation, "use managed Kubernetes if you can," is correct and is the reason EKS exists. What has changed is everything around it:
| book says | page | correct, and on AWS |
|---|---|---|
| Docker Desktop "isn't currently available for Linux" | 49 | it has been since 2022; commercial use in larger companies needs a paid subscription. kind and minikube are the free local clusters |
| Docker Hub as the registry; docker login | 55 | ECR: aws ecr get-login-password | docker login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com (CLI customisation, not checked here) |
| container runtime "usually Docker … rkt and CRI-O" | 62 | dockershim removed in 1.24; containerd on the EKS AMIs; rkt was retired |
| "master nodes"; three for HA | 61–63, 123 | EKS runs the control plane across three Availability Zones; kubectl get nodes never shows it, and the master role label is gone upstream |
| "Amazon Elastic Container Service for Kubernetes"; charges for masters; "more expensive" | 69 | renamed Elastic Kubernetes Service; the control-plane fee was cut in 2020, and GKE has charged a management fee since 2020 too. Extended-support versions cost more. Check current pricing |
| Fargate support for EKS "by 2019" | 78 | arrived December 2019 as Fargate profiles (CreateFargateProfile in the API model) |
| self-hosting on AWS: "use kops" | 76 | kops is maintained; its README lists AWS and GCP as officially supported. On AWS, prefer EKS, plus eksctl or Terraform |
| Heptio HKS, Stackpoint, Containership, Tarmak, TK8, Kubeformation, Puppet module | 70–74 | Heptio became part of VMware in 2018; most of the rest are gone or dormant. Check before relying on any |
| RKE installer | 73 | RKE1 reached end of life in 2025; check SUSE's RKE2 |
| Helm 2 with Tiller (helm-auth.yaml, helm init) | 92–94 | Helm 3 removed Tiller in 2019; Helm 4 is current (4.3.0 was used here). helm inspect still works as an alias of helm show |
| a type: LoadBalancer Service "will create an AWS load balancer" | 40 | the in-tree provider makes a Classic Load Balancer. Install the AWS Load Balancer Controller and set loadBalancerClass: service.k8s.aws/nlb for an NLB that targets Pods |
Chapter 5, Managing Resources
This chapter has aged best. The resource model, the probe semantics and the "LimitRange as a backstop" rule all still apply. The AWS details are what change:
| book says | page | correct, and on EKS |
|---|---|---|
| one Kubernetes CPU = "one AWS vCPU" | 97 | still true. On x86 a vCPU is a hyperthread; on Graviton it is a full core, which is why the same request often goes further there |
| "Always specify resource requests and limits" | 99, 110 | requests, always. For limits, current practice is memory limit = request, and CPU limits only where throttling is wanted; Kubernetes troubleshooting on EKS has the throttling failure |
| gRPC health checks need the grpc-health-probe binary and an exec probe | 101 | native grpc: probes, GA since 1.27 |
| no way to protect a namespace from deletion | 105 | still no built-in flag; a ValidatingAdmissionPolicy (GA 1.30) can deny it. EKS has deletionProtection for the cluster (API model) |
| 110 Pods per node "unless there is a strong reason" | 111 | on EKS the VPC CNI caps Pods by the instance's ENIs: 17 on a t3.medium. Prefix delegation raises that |
| VPA "dry-run mode" | 111 | updateMode: "Off"; in-place Pod resize is beta and on by default in 1.33 |
| kube-job-cleaner for finished Jobs | 115 | ttlSecondsAfterFinished, GA in 1.23 |
| reserved instances are fixed and "can't be altered or refunded" | 115 | Savings Plans (2019) cover any instance family, plus Fargate and Lambda; Convertible RIs can be exchanged |
| Spot "pricing varies according to demand"; keep preemptible nodes under two-thirds | 116 | no bidding since 2017; prices move slowly, and the real risk is the two-minute interruption notice. Karpenter handles the notice through its interruption queue; managed node groups take capacityType: SPOT (API model) |
| the descheduler to fix a cluster that has become lopsided | 118–119 | still exists (kubernetes-sigs). On EKS, topologySpreadConstraints prevent the problem at scheduling time, and Karpenter consolidation repacks nodes |
Chapter 6, Operating Clusters
| book says | page | correct, and on EKS |
|---|---|---|
| "Kubernetes clusters need at least three master nodes"; size them as m3.medium | 123–126 | not your concern on EKS. A provisioned control-plane tier exists for heavy API load (controlPlaneScalingConfig in the API model) |
| "Kubernetes version 1.12 officially supports clusters of up to 5,000 nodes"; federate beyond that | 124–125 | 5,000 is still the upstream tested limit; AWS has announced much larger EKS clusters, so check your quota. KubeFed is archived; on AWS, use Argo CD ApplicationSets across clusters |
| "Don't enable cluster autoscaling just because it's there" | 129 | the advice has flipped. On EKS, node autoscaling (Karpenter or Auto Mode) is how you stop paying for idle nodes. PDBs make it safe; see Karpenter on AWS |
| Sonobuoy Scanner sends results to Heptio | 132 | the hosted scanner is gone. EKS is a Certified Kubernetes distribution |
| K8Guard, Copper | 133 | check; for policy at admission time, use ValidatingAdmissionPolicy or Kyverno |
| kube-bench | 134 | use job-eks.yaml (the CIS EKS benchmark); control-plane checks do not apply |
| GKE "will include audit logging by default" | 134 | on EKS, control-plane logs, audit included, are not exported unless you enable them (logging in CreateCluster, API model) |
| chaoskube, kube-monkey, PowerfulSeal | 135–136 | check each project's status. AWS FIS has EKS actions (node-group termination and Pod-level faults); check the current action list |
Chapter 7, Kubernetes Power Tools
The kubectl habits in this chapter still pay off:
kubectl explain, -o json | jq, --watch, kubectl diff, and declarative over imperative (the Alice and Bob story, p. 144). The broken commands are in the hazards table. The rest:| book says | page | correct, and on EKS |
|---|---|---|
| read the API server's logs with kubectl logs on the kube-apiserver Pod | 147, 231 | no such Pod on EKS. Enable control-plane logging and query CloudWatch Logs |
| busybox:1.28 because later versions break DNS lookups | 152 | that was a musl nslookup quirk. Pin a tag, and use an image with real tools (netshoot) for DNS debugging |
| kubesquash, kubed-sh, kube-shell, Click | 153–157 | check each one. kubectl debug with ephemeral containers (GA 1.25) is the built-in way into a running Pod |
| Stern for multi-Pod logs | 157 | Stern lives on as stern/stern; kubectl logs -l app=demo --prefix --all-containers covers the simple case |
| contexts named gke_… | 154 | aws eks update-kubeconfig --name <cluster> --alias <name> writes an exec-plugin context; kubectx and kube-ps1 work unchanged (CLI not checked here) |
Chapter 8, Running Containers
The chapter's security advice holds today: run as non-root, use a read-only root filesystem, disable privilege escalation, drop capabilities. What has changed is how a cluster enforces it, plus a few details. This version decodes cleanly:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
spec:
securityContext: # Pod level: user and seccomp
runAsUser: 1000
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: demo
image: cloudnatived/demo:hello
securityContext: # container level: escalation and capabilities
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
| book says | page | correct, and on EKS |
|---|---|---|
| a process's environment "is also limited to 32 KiB" | 167 | Linux limits a single argument or environment string to 128 KiB and the total to a fraction of the stack limit. The practical limit is a ConfigMap's 1 MiB |
| no need to set USER in the Dockerfile; runAsUser is enough | 169 | set a numeric USER too. With runAsNonRoot: true, a non-numeric or missing USER fails to start unless runAsUser is set everywhere |
| PodSecurityPolicy for cluster-wide enforcement | 172–173 | Pod Security Admission; EKS's default is privileged, so label your namespaces |
| use nfs or glusterfs volumes for locking | 175 | the in-tree GlusterFS plugin is gone. On AWS, EFS through its CSI driver is the shared filesystem |
| "we don't recommend that you run databases in Kubernetes" | 175 | still right. RDS or Aurora |
| imagePullSecrets for a private registry | 176–177 | not needed for ECR: the node's IAM role pulls (with Fargate, the Pod execution role does). Keep pull secrets for third-party registries |
Chapter 9, Managing Pods
| book says | page | correct, and on EKS |
|---|---|---|
| affinity on GCP zones with the beta zone label | 185 | topology.kubernetes.io/zone. EBS volumes are zonal, so use volumeBindingMode: WaitForFirstConsumer |
| affinities that "won't move the Pod … (This feature may be added in the future.)" | 185 | still not added; the descheduler or Karpenter drift do it |
| node taints shown on docker-for-desktop | 189 | on EKS, put taints on the managed node group (taints in CreateNodegroup) or the Karpenter NodePool, not with kubectl taint, which the next replacement node will not carry |
| StatefulSets for Redis, MongoDB, Cassandra | 192 | still the controller to use, but on AWS the managed service (ElastiCache, DocumentDB, Keyspaces) usually wins; persistentVolumeClaimRetentionPolicy is GA in 1.32 |
| Ingress controllers: "nginx-ingress … the official one", Contour, Traefik | 201 | ingress-nginx was retired in March 2026. On EKS, the AWS Load Balancer Controller (ALB for Ingress, NLB for Services, plus Gateway API) |
| cert-manager for TLS on the Ingress | 200 | still good; on an ALB, an ACM certificate via alb.ingress.kubernetes.io/certificate-arn needs no Secret at all |
| Istio "an optional add-on" to GKE | 201–202 | Istio runs self-managed on EKS; Istio on EKS. AWS App Mesh reached end of support on 30 September 2026 |
| cloud load balancers' default algorithm "is usually random"; use Envoy for least-request | 202 | ALB target groups offer round robin, least outstanding requests and weighted random; NLB hashes flows |
The book's fanout Ingress, rewritten for EKS (decodes cleanly against
networking.k8s.io/v1):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fanout-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello
port:
number: 80
Chapter 10, Configuration and Secrets
Two things in this chapter still apply unchanged: the ConfigMap techniques (
envFrom, $(VAR) in args, file mounts) and the Helm checksum annotation. The checksum must go on spec.template.metadata.annotations; the book says only "your Deployment spec" (p. 214), and on the Deployment's own metadata it does not roll the Pods. The rest of the chapter needs correcting:| book says | page | correct, and on EKS |
|---|---|---|
| a mounted ConfigMap file "will be updated automatically" | 213 | true for whole-volume mounts, after a short delay; never for subPath mounts or environment variables |
| Secrets "are always stored in base64 format" | 216 | base64 is how the API represents bytes in JSON and YAML; it is not how etcd stores them |
| encryption at rest: look for --experimental-encryption-provider-config | 217 | the flag was renamed long ago, and on EKS there is nothing to look for: the EKS API model states that EKS "encrypts all Kubernetes API data with envelope encryption by default for clusters running Kubernetes version 1.28 or higher"; a customer KMS key is optional |
| Vault, Keywhiz, AWS Secrets Manager; "don't start with Vault" | 220 | the reasoning still holds. On AWS the dedicated tool is Secrets Manager, mounted with the Secrets Store CSI driver's AWS provider or synced by External Secrets, with the Pod's role from EKS Pod Identity |
| Sops with PGP; a KMS backend | 222–224 | Sops is now a CNCF project under getsops; age keys replace PGP for most teams; the KMS backend is the AWS-native choice |
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article