Cka Kubernetes Application Developer Crash Course
Cka Kubernetes Application Developer Crash Course
bmuschko
bmuschko
AUTOMATED
ASCENT
bmuschko.com
automatedascent.com
Companion study guide with
practice questions
https://www.cncf.io/certification/cka/
Exam Domains & Weights
The Curriculum
Candidate Skills
Underlying Concepts
Exam Environment
Online and proctored exam
https://kubernetes.io/docs
Getting Help on a Command
Render subcommands and options with --help
...
Available Commands:
...
configmap Create a configmap from a local file, directory or literal
value
deployment Create a deployment with the specified name.
...
Options:
...
Zeroing in on Command Details
Drill into object details with the explain command
DESCRIPTION:
... Most relevant information
FIELDS:
...
Time Management
# of problems in 2 hours, use your time wisely!
✓
? ✘
? ✋
? ✘
? ✓
?
✓
? ✓
? ? ? ?
⏰ ? ? ? ? ?
? ? ? ?
Using an Alias for kubectl
Your first action at the beginning of the exam
$ alias k=kubectl
$ k version
...
Setting a Context & Namespace
Questions will ask you to run a command on a specific
cluster - Make sure to execute it!
$ kubectl get ns
Usage of ns instead
of namespaces
��
The key to cracking the exam
Q&A
10 mins
BREAK
5 mins
Cluster Architecture,
Installation & Configuration
RBAC, Kubeadm, HA, etcd Backup and Restore
RBAC High-Level Overview
Three key elements for understanding concept
API Operations
Subject Resources (Verbs)
(Cluster) User
Role
get list
(Cluster)
Pod Group
RoleBinding
Service
Account
Defining a Role
Connects API resources and verbs
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
API Resources
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"] Operations
Defining a RoleBinding
Grants the permissions defined in a role to subject
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: User One or many subjects
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role Reference to role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
ClusterRole + ClusterRoleBinding
Same as Role and RoleBinding but on cluster-level
● ClusterRole
○ Can grant same permissions as Role.
○ Can grant access to nodes, non-resource endpoints and
resources across all namespaces.
● ClusterRoleBinding
○ Can grant same access as RoleBinding.
○ Bind a ClusterRole to all the namespaces in the cluster.
Aggregated ClusterRoles
Combine multiple ClusterRoles into one
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata: Matching on labels
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: []
EXERCISE
Regulating Access
to API Resources
with RBAC
What is Kubeadm?
Tool for creating and managing Kubernetes clusters
Creating a Cluster
with Kubeadm
Single-Master Cluster Setup
Losing the master node causes issues
● A ReplicaSet cannot recreate failing Pod as the worker node can’t talk
back to scheduler on master node.
master worker
master
node 1 etcd node 1
worker node 1
etcd node 1 load
balancer
load
master worker
balancer etcd
node 2 node 2
master worker
node 2 node 2
etcd
Upgrading a
Cluster Version with
Kubeadm
Backing up & Restoring etcd
Get etcdctl utility if it's not already present
Backing Up and
Restoring etcd
Q&A
5 mins
BREAK
5 mins
Workloads & Scheduling
Deployments, ConfigMaps & Secrets, Health
Probes, Pod Resource Limits, Node Affinity, Taints &
Tolerations
Understanding Deployments
Scaling and replication features for a set of Pods
Deployment
ReplicaSet ReplicaSet
v1 v1 v1 v2 v2 v2
Time
Rollout Revision Log
# Check initial deployment revisions
$ kubectl rollout history deployments my-deploy
deployment.extensions/my-deploy
REVISION CHANGE-CAUSE
1 <none>
v2 v2 v2 v1 v1 v1
Time
Rolling Back to a Revision
# Roll back to previous revision
$ kubectl rollout undo deployments my-deploy
deployment.extensions/my-deploy
Deployment Deployment
v1 v1 v1 v1 v1 v1
Pods Pods
Providing a Specific # of Replicas
# Check current deployment replicas
$ kubectl get deployments my-deploy
NAME READY UP-TO-DATE AVAILABLE AGE
my-deploy 2 2 2 9h
Time
Create Horizontal Pod Autoscaler
# Maintain average CPU utilization across all Pods of 70%
$ kubectl autoscale deployments my-deploy --cpu-percent=70 ↵
--min=1 --max=10
horizontalpodautoscaler.autoscaling/my-deploy autoscaled
Performing Rolling
Updates and Scaling
a Deployment
Centralized Configuration Data
Injects runtime configuration through object references
ConfigMap
key/value
Pod
Secret
key/value
(base 64)
Creating ConfigMaps (imperative)
Fast, easy and flexible, can point to different sources
# Literal values
$ kubectl create configmap db-config --from-literal=db=staging
# File or directory
$ kubectl create configmap db-config --from-file=config.txt
Creating ConfigMaps (declarative)
Definition of a ConfigMap is fairly short and on point
apiVersion: v1
data:
db: staging
username: jdoe
kind: ConfigMap
metadata:
name: db-config
Mounting a ConfigMap
Two options for consuming data
# Literal values
$ kubectl create secret generic db-creds ↵
--from-literal=pwd=s3cre!
Creating and
Mounting a
ConfigMap
Container Health
“How does Kubernetes know if a container is up and running?”
Pod
Pod
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: web-app
image: eshop:4.6.3
readinessProbe:
Successful if HTTP status code is
httpGet:
path: / between 200 and 399
port: 8080
initialDelaySeconds: 5
periodSeconds: 2
Understanding Liveness Probes
“Does the application still function without errors?”
Pod
container
✓ Kubelet Do you work? Yes
Pod
container
✘ Kubelet Do you work? No
Restart
Defining a Liveness Probe
An event log can be queried with a custom command
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: web-app
image: eshop:4.6.3
livenessProbe:
exec:
It makes sense to delay the initial
command: check as the application to fully
- cat start up first
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
Understanding Startup Probes
“Legacy application may need longer to start. Hold off on probing.”
Pod
Pod
apiVersion: v1
kind: Pod
metadata:
name: startup-pod
spec:
containers:
- image: httpd:2.4.46
name: http-server
startupProbe:
Tries to open a TCP socket
tcpSocket:
port: 80 connection to a port
initialDelaySeconds: 3
periodSeconds: 15
EXERCISE
Configuring Health
Probes for a Pod
Defining Resource Boundaries
Defines # of Pods, CPU and memory usage per Namespace
Namespace
“Please create a Pod in this Namespace!”
Sorry, we already reached the upper limit.
Pod Pod
Max 4 Pods ✘ Scheduler
Pod Pod
Creating a Resource Quota
Definition on the Namespace-level
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers: Requires at least 0.5 CPU resources
- image: nginx and 200m of memory
name: mypod
resources:
requests:
cpu: "0.5"
memory: "200m"
EXERCISE
Defining a Pod’s
Resource
Requirements
Node Affinity & Taints/Tolerations
Concepts with different purposes, but can go hand in hand
Pod 1
Node 1 size: small
nodeSelector:
size:
medium
Pod 2
nodeSelector:
Node 3 size: large
size: large
Node Selection Constraint
Add labels to nodes
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers: Can’t have multiple keys with the
- image: nginx same value as the underlying data
name: nginx
restartPolicy: Never
structure is a map
nodeSelector:
size: medium
Node Affinity
Similar to nodeSelector but more flexible and powerful
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
Node 2 size: medium
- key: size
or operator: In
values:
- medium
- large
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- image: nginx
name: nginx
restartPolicy: Never
affinity:
nodeAffinity: Available operators:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
In, NotIn, Exists,
- matchExpressions: DoesNotExist, Gt, Lt
- key: size
operator: In
values:
- medium
Node Affinity Types
Currently two types, potentially more in the future
Type Description
Rules that must be met for a Pod to
requiredDuringSchedulingIgnoredDuringExecution
be scheduled onto a node.
Rules that specify preferences that
preferredDuringSchedulingIgnoredDuringExecution the scheduler will try to enforce but
will not guarantee.
Scheduling a Pod
on Specific Nodes
Taints and Tolerations
A Pod that doesn’t have specific toleration is repelled
Pod 1
Node 1 tolerations:
✓ - key: "special"
operator: "Equal"
✓ value: "true"
✓
effect: "NoSchedule"
Node 2 special: true
✓
✘ Pod 2
Node 3
✓
Setting a Node Taint
Add taint to nodes
Effect Description
Unless a Pod has matching toleration, it won’t be be
NoSchedule
scheduled on the node.
Try not to place a Pod that does not tolerate the taint on
PreferNoSchedule
the node, but it is not required.
Evict Pod from node if already running on it. No future
NoExecute
scheduling on the node.
Setting a Pod’s Toleration
Requires a lot of configuration in various shapes and forms
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- image: nginx
name: nginx
restartPolicy: Never
Available operators:
tolerations: Equal, Exists
- key: "special"
operator: "Equal"
value: "true"
effect: "NoSchedule"
EXERCISE
Configuring a Node
to Only Accept
Specific Pods
Q&A
5 mins
BREAK
5 mins
Services & Networking
Inter-Pod Communication, Service Types, Ingress,
CoreDNS, CNI plugins
Understanding Services
Enables network access for a set of Pods
Incoming Traffic
Service
Incoming Traffic
spec.selector:
Label Selectors! Service tier: frontend
✘ ✘ ✓
metadata.labels: metadata.labels:
tier: backend Pod Pod Pod tier: frontend
Creating a Service (imperative)
“Create a Service with explicit type”
Incoming Traffic
3000 port
Service
80 targetPort
80 80 80 containerPort
spec.type: xyz
ClusterIP Service Type
Only reachable from within the cluster or API service via proxy
exposes Service
Two distinct concepts that
complement each other
Pod Pod Pod
manages Deployment
EXERCISE
Routing traffic to
Pods from Inside
and Outside of a
Cluster
Understanding Ingress
Manages external access to the services in a cluster via HTTP(S)
Pod
Pod
Cluster
Defining an Ingress
Traffic routing is controlled by rules defined on Ingress resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
Ingress Rules
Traffic routing is controlled by rules defined on Ingress resource
● Optional host. If not host is defined, then all inbound HTTP traffic is
handled.
Rule Request
/foo ✓
Exact /foo
/bar ✘
/foo, /foo/ ✓
Prefix /foo
/bar ✘
Listing an Ingress
$ kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in
v1.14+, unavailable in v1.22+; use networking.k8s.io/v1
Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
minimal-ingress <none> * 80 17s
EXERCISE
Hostname IP Address
Service Pod 10.0.0.87
web 10.96.174.197
Pod 10.0.0.88
default namespace
Resolving a Service by DNS
Resolve by hostname within the same namespace
example web
$ curl http://web
Pod Service Hello World
default namespace
Resolving a Service by DNS
Resolve by namespace, type, root domain from another
namespace
Root Domain
Resolving a Pod by DNS
DNS records are not created by default, resolve by IP address
10.0.0.84 10.0.0.86
$ curl 10.0.0.85
Pod Pod
Hello World
$ curl 10.0.0.86
other Hello World
Pod namespace
10.0.0.85
default
namespace
Object Representation CoreDNS
Recommended Kubernetes DNS server implementation
10-0-0-86.other.pod.
10-0-0-84 cluster.local
$ curl 10-0-0-85
Hello World
Pod Pod
$ curl
10-0-0-86.other.pod.cluster
Pod other .local
namespace Hello World
10-0-0-85
default
namespace
Understanding CNI
Kubernetes uses CNI for Pod networking
Specification Plugins
& Libraries
Implement Specification
Choosing a CNI Plugin
Direct installation instructions only available for Weave Net
List of plugins:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
https://kubernetes.io/docs/setup/production-environment/tools/kubead
m/high-availability/#steps-for-the-first-control-plane-node
Q&A
5 mins
BREAK
5 mins
Storage
Volumes, Volume Configuration Options,
PersistentVolumes with Static & Dynamic Binding
Understanding Volumes
Persist data that outlives a Pod restart
Pod Pod
Volume
tmp filesystem
vs.
Pod
Persistent
Volume
Container Persistent
Volume
/var/logs Claim
Creating a PersistentVolume
Pod
apiVersion: v1 PVC PV
kind: PersistentVolume
metadata:
name: pv
spec:
capacity: Defines a specific storage capacity
storage: 512m
accessModes: Read and/or write access
- ReadWriteOnce How many nodes can access volume?
hostPath:
path: /data/config
Access Mode & Reclaim Policy
Configuration options for PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv
Physical Persistent
spec: Storage Volume
capacity:
storage: 512m
accessModes:
- ReadWriteOnce pv
/data/config
storageClassName: shared
hostPath:
path: /data/config
Dynamic Provisioning
Creates PersistentVolume object automatically via storage class
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
apiVersion: storage.k8s.io/v1 name: pvc
kind: StorageClass spec:
metadata: accessModes:
name: standard - ReadWriteMany
provisioner: kubernetes.io/aws-ebs resources:
requests:
storage: 256m
storageClassName: standard
EXERCISE
Creating a
Persistent Volume
with Static or
Dynamic Binding
Troubleshooting
Cluster/Node Logging, Monitoring Applications,
Identifying and Fixing Application, Cluster, and
Networking Issues
Monitoring Cluster Components
What metrics are of interest?
... vs.
Heapster
✘Retired
Metrics
Server
Metrics Server
Cluster-wide metrics aggregator
Metrics Server
Cluster
kubelet kubelet kubelet
1 2 Pods 3 4 5 6 7 8
$ kubectl apply -f
https://github.com/kubernetes-sigs/metrics-server/
releases/latest/download/components.yaml
Using the Metrics Server
The kubectl top command can query nodes and Pods
5 mins
BREAK
5 mins
Official Troubleshooting Docs
Detailed advice and help during exam
● Troubleshooting applications
● Troubleshooting cluster
Troubleshooting Services
Check Service type and call endpoint
$ curl http://nginx:30184
curl: (6) Could not resolve host: nginx ✘Connectivity issue
Troubleshooting Services
Ensure correct label selection
✘Connectivity issues
Troubleshooting an
Issue for an
Application
Troubleshooting Control Plane
Check the status of the cluster nodes first - are they running?
✓ No error messages
EXERCISE
Troubleshooting an
Issue with the
Control Plane
Troubleshooting Worker Nodes
Check the status of the worker nodes - are they ready?
$ top $ df -h
Processes: 568 total, 2 running, 566 sleeping, 2382 threads Filesystem Size Used Avail Capacity iused
15:30:40 ifree %iused Mounted on
Load Avg: 1.96, 1.80, 1.68 CPU usage: 2.49% user, 1.83% sys, /dev/disk1s1s1 1.8Ti 14Gi 1.6Ti 1% 567557
95.66% idle 19538461203 0% /
SharedLibs: 706M resident, 108M data, 196M linkedit. devfs 187Ki 187Ki 0Bi 100% 648
MemRegions: 192925 total, 6808M resident, 312M private, 5106M 0 100% /dev
shared. PhysMem: 33G used (4319M wired), 31G unused. /dev/disk1s5 1.8Ti 20Ki 1.6Ti 1% 0
VM: 3461G vsize, 2315M framework vsize, 0(0) swapins, 0(0) 19539028760 0% /System/Volumes/VM
swapouts. /dev/disk1s3 1.8Ti 282Mi 1.6Ti 1% 799
Networks: packets: 6818487/8719M in, 2169040/361M out. Disks: 19539027961 0% /System/Volumes/Preboot
1305228/17G read, 1354811/32G written. /dev/disk1s6 1.8Ti 520Ki 1.6Ti 1% 16
19539028744 0% /System/Volumes/Update
/dev/disk1s2 1.8Ti 172Gi 1.6Ti 10% 1071918
19537956842 0% /System/Volumes/Data
map auto_home 0Bi 0Bi 0Bi 100% 0
✓ Kubelet active
Troubleshooting Worker Nodes
View and inspect systemd logs
$ journalctl -u kubelet.service
Jan 22 15:51:25 kube-worker-1 systemd[1]: Started kubelet: The Kubernetes Node Agent.
Jan 22 15:51:25 kube-worker-1 systemd[1]: kubelet.service: Current command vanished from the
unit file, execution of the command list won't be resumed.
Jan 22 15:51:25 kube-worker-1 systemd[1]: Stopping kubelet: The Kubernetes Node Agent...
Jan 22 15:51:25 kube-worker-1 systemd[1]: Stopped kubelet: The Kubernetes Node Agent.
Jan 22 15:51:25 kube-worker-1 systemd[1]: Started kubelet: The Kubernetes Node Agent.
Jan 22 15:51:25 kube-worker-1 kubelet[4330]: F0122 15:51:25.656116 4330 server.go:198] failed
to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config
file "/var/lib/kubelet/config
...
Troubleshooting an
Issue with a Worker
Node
Q&A
5 mins
Summary & Wrap Up
Last words of advice...
Gaining confidence
● Run through practice exams as often as you can