Production EKS Platform — From Zero to Production›Part 2 · Cheat sheet & self-check

Part 2 — Build the platform · wrap-up

Cheat sheet & self-check

Every command from this section on one page.

03 · AWS account & VPC for EKS

Inspect the network

aws ec2 describe-subnets --filters Name=vpc-id,Values=<vpc> --query 'Subnets[].[SubnetId,AvailabilityZone,CidrBlock,AvailableIpAddressCount]' --output tableSubnets, AZs and free IPs
aws ec2 describe-route-tables --filters Name=vpc-id,Values=<vpc>Routes (IGW for public, NAT for private)
aws ec2 describe-nat-gateways --filter Name=vpc-id,Values=<vpc>NAT gateways per AZ
aws ec2 describe-vpc-endpoints --filters Name=vpc-id,Values=<vpc>Private endpoints to AWS services
aws ec2 describe-subnets --filters Name=tag:kubernetes.io/role/internal-elb,Values=1Subnets marked for internal load balancers

04 · VPC CNI & IP planning

Inspect

kubectl -n kube-system get ds aws-node -o jsonpath='{.spec.template.spec.containers[0].env}' | jqVPC CNI settings (env vars)
kubectl get nodes -o custom-columns=NAME:.metadata.name,PODS:.status.allocatable.podsMax pods per node
aws ec2 describe-subnets --subnet-ids <id> --query 'Subnets[].AvailableIpAddressCount'Free IPs left in a subnet

Key settings

ENABLE_PREFIX_DELEGATION=trueAssign /28 prefixes to ENIs (more pods per node)
AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=truePods use subnets from ENIConfig (e.g. a secondary CIDR)
WARM_IP_TARGET / WARM_PREFIX_TARGETHow many spare IPs/prefixes each node keeps ready

05 · The EKS cluster: control plane, compute & add-ons

Cluster

eksctl create cluster -f cluster.yamlCreate a cluster from a config file (quick labs)
aws eks update-kubeconfig --name prod --region eu-west-1Write a kubeconfig entry for the cluster
aws eks describe-cluster --name prod --query 'cluster.resourcesVpcConfig'Endpoint access, subnets, security groups
aws eks update-cluster-config --name prod --resources-vpc-config endpointPublicAccess=false,endpointPrivateAccess=trueMake the API endpoint private

Compute

aws eks list-nodegroups --cluster-name prodManaged node groups
kubectl get nodes -L eks.amazonaws.com/nodegroup,node.kubernetes.io/instance-type,topology.kubernetes.io/zoneNodes with group, type and AZ
aws eks list-fargate-profiles --cluster-name prodFargate profiles

Add-ons

aws eks describe-addon-versions --addon-name vpc-cni --kubernetes-version 1.33Compatible add-on versions for a Kubernetes version
aws eks create-addon --cluster-name prod --addon-name eks-pod-identity-agentInstall a managed add-on
aws eks describe-addon --cluster-name prod --addon-name coredns --query 'addon.[addonVersion,status]'Installed version and health

06 · IAM & governance: access entries, Pod Identity, IRSA, policies

Cluster access (access entries)

aws eks describe-cluster --name prod --query cluster.accessConfigAuthentication mode
aws eks list-access-entries --cluster-name prodWho has access
aws eks create-access-entry --cluster-name prod --principal-arn <role-arn>Grant an IAM role access
aws eks associate-access-policy --cluster-name prod --principal-arn <role-arn> --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy --access-scope type=namespace,namespaces=shopView access to one namespace
aws eks list-associated-access-policies --cluster-name prod --principal-arn <role-arn>What a principal can do
kubectl auth can-i --list -n shopYour own effective Kubernetes permissions

Pod permissions

aws eks create-pod-identity-association --cluster-name prod --namespace shop --service-account orders --role-arn <role-arn>Give a ServiceAccount an IAM role (Pod Identity)
aws eks list-pod-identity-associations --cluster-name prodAll Pod Identity associations
aws eks describe-cluster --name prod --query cluster.identity.oidc.issuerOIDC issuer (for IRSA)
kubectl annotate sa orders -n shop eks.amazonaws.com/role-arn=<role-arn>IRSA: link a ServiceAccount to a role
kubectl run awscli -n shop --rm -it --image=amazon/aws-cli --overrides='{"spec":{"serviceAccountName":"orders"}}' -- sts get-caller-identityWhich role does a pod really get?

Guard-rails

kubectl get resourcequota,limitrange -n shopQuotas and default limits in a namespace
kubectl label ns shop pod-security.kubernetes.io/enforce=restrictedEnforce the restricted Pod Security Standard
aws service-quotas get-service-quota --service-code ec2 --quota-code L-1216C47ARunning On-Demand standard instance vCPU quota

07 · Ingress: ALB, NLB and the Load Balancer Controller

Controller

helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=prodInstall (after creating its IAM role; eks = https://aws.github.io/eks-charts)
kubectl -n kube-system logs deploy/aws-load-balancer-controllerWhy an LB wasn't created
kubectl get ingress,svc -A -o wideLB DNS names on Ingresses and Services

Subnet tags (required for discovery)

kubernetes.io/role/elb = 1Public subnets for internet-facing LBs
kubernetes.io/role/internal-elb = 1Private subnets for internal LBs

08 · ECR & application deployment

ECR

aws ecr create-repository --repository-name shop/api --image-tag-mutability IMMUTABLE --image-scanning-configuration scanOnPush=trueRepository with immutable tags and scan on push
aws ecr get-login-password | docker login --username AWS --password-stdin <acct>.dkr.ecr.<region>.amazonaws.comLog Docker in to ECR (12-hour token)
docker push <acct>.dkr.ecr.<region>.amazonaws.com/shop/api:1.4.0Push an image
aws ecr describe-image-scan-findings --repository-name shop/api --image-id imageTag=1.4.0Vulnerability findings
aws ecr put-lifecycle-policy --repository-name shop/api --lifecycle-policy-text file://lifecycle.jsonExpire old images automatically

Roll out

kubectl set image deploy/api api=<acct>.dkr.ecr.<region>.amazonaws.com/shop/api:1.4.1 -n shopStart a rolling update
kubectl rollout status deploy/api -n shopWatch it complete
kubectl rollout undo deploy/api -n shopRoll back to the previous ReplicaSet
kubectl get pods -n shop -o wide -L topology.kubernetes.io/zoneAre replicas spread across AZs?

09 · Storage: EBS, EFS and S3

Drivers

aws eks create-addon --cluster-name prod --addon-name aws-ebs-csi-driverEBS CSI driver (give it a role via Pod Identity)
aws eks create-addon --cluster-name prod --addon-name aws-efs-csi-driverEFS CSI driver
kubectl get csidriversebs.csi.aws.com, efs.csi.aws.com, …

Tiers

gp3 (WaitForFirstConsumer)Hot: databases, general RWO volumes
io2Hot and demanding: consistent high IOPS
EFS (access points)Shared RWX files across AZs
S3 (+ Mountpoint CSI)Cold, large, read-heavy data; backups

10 · Autoscaling: HPA & Karpenter

Inspect

kubectl get nodepools,ec2nodeclassesKarpenter configuration
kubectl get nodeclaims -o wideNodes Karpenter launched (type, zone, capacity type)
kubectl -n kube-system logs deploy/karpenter -fWhy it launched or removed a node (namespace depends on install)
kubectl get nodes -L karpenter.sh/capacity-type,node.kubernetes.io/instance-type,topology.kubernetes.io/zoneCapacity type, instance type and zone per node

Protect a workload

karpenter.sh/do-not-disrupt: "true"Pod annotation: don't voluntarily disrupt this pod's node
PodDisruptionBudgetKarpenter respects PDBs when draining