CKAD
CKAD
CKAD
1 / 74
By sebgoa
By Sebastien Goasguen, author of the Docker Cookbook and co-author of
Kubernetes cookbook.
2 / 74
3 / 74
Pre-requisities
minikube , https://github.com/kubernetes/minikube
or Docker for Desktop (Mac/Windows)
kubectl , https://kubernetes.io/docs/user-guide/prereqs/
git
Manifests here:
https://github.com/sebgoa/oreilly-kubernetes
4 / 74
Minikube
Minikube is open source and available on GitHub.
You will need an "Hypervisor" on your local machine, e.g VirtualBox, KVM,
Fusion
$ minikube start
5 / 74
Kubernetes Training
Goal: Review of API objects and practice to get ready for CKAD
Agenda
Morning:
Afternoon:
Practice
Practice
6 / 74
Borg Heritage
Borg was a Google secret for a long time.
Orchestration system to manage all Google applications at scale
Finally described publicly in 2015
Paper explains ideas behind Kubernetes
7 / 74
What is it really ?
A resource manager with lots of HA features
A scheduler to place containers in a cluster
Deployed as services on VMs or Bare-metal machines
8 / 74
Minikube
Minikube is open source and available on GitHub.
9 / 74
Part I: API Review
Pods, ReplicaSets, Deployments
Secrets, ConfigMaps
kubectl create and kubectl apply
10 / 74
Core Objects
See "Introduction to Kubernetes course"
11 / 74
Check API Resources with kubectl
Check it with kubectl:
12 / 74
Namespaces
Every request is namespaced e.g GET
https://192.168.99.100:8443/api/v1/namespaces/default/pods
13 / 74
Labels
You will have noticed that every resource can contain labels in its metadata.
By default creating a deployment with kubectl run adds a label to the pods.
apiVersion: v1
kind: Pod
metadata:
...
labels:
pod-template-hash: "3378155678"
run: ghost
You can then query by label and display labels in new columns:
14 / 74
Become Friends with Pods
15 / 74
Kubectl Pod commands
kubectl logs ...
kubectl describe ...
kubectl explain ...
kubectl exec ...
kubectl label ...
kubectl annotate ...
and tricks
16 / 74
Powerful REST based API
YAML or JSON definitions for objects
17 / 74
Exercise
Use curl to list Pods
Use curl to create a Pod
Use curl to delete a Pod
18 / 74
ResourceQuota Object
Create a oreilly ns from a file:
apiVersion: v1
kind: Namespace
metadata:
name: oreilly
$ cat rq.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
pods: "1"
...
$ kubectl create -f rq.yaml --namespace=oreilly
Then test !
19 / 74
ReplicaSet Object
Same as all Objects. Contains apiVersion, kind, metadata
But also a spec which sets the number of replicas, and the selector. An RC
insures that the matching number of pods is running at all time. The template
section is a Pod definition.
apiVersion: extensions/v1beta
kind: ReplicaSet
metadata:
name: redis
namespace: default
spec:
replicas: 2
selector:
app: redis
template:
metadata:
name: redis
labels:
app: redis
spec:
containers:
- image: redis:3.2
20 / 74
Deployments
21 / 74
Scaling and Rolling update of Deployments
Just like RC, Deployments can be scaled.
What if you want to update all your Pods to a specific image version. latest is
not a version number...
22 / 74
Accessing Services
Now that we have a good handle on creating resources, managing and
inspecting them with kubectl. The elephant in the room is how do you access
your applications ?
apiVersion: v1
kind: Service
...
spec:
clusterIP: 10.0.0.112
ports:
- nodePort: 31230
...
$ minikube ip
192.168.99.100
24 / 74
Service Types
Services can be of three types:
ClusterIP
NodePort
LoadBalancer
ClusterIP service type is the default and only provides access internally
(except if manually creating an external endpoint).
NodePort type is great for debugging, but you need to open your firewall on
that port (NodePort range defined in Cluster configuration). Not
recommended for public access.
25 / 74
Exercise
Run kubectl proxy
Open your browser and find the correct URL to access your service
26 / 74
DNS
A DNS service is provided as a Kubernetes add-on in clusters. On GKE and
minikube this DNS service is provided by default. A service gets registered in
DNS and DNS lookup will further direct traffic to one of the matching Pods via
the ClusterIP of the service.
Name: nginx
Address 1: 10.0.0.112
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 19h
nginx 10.0.0.112 nodes 80/TCP 36m
$ kubectl exec -ti busybox -- wget http://nginx
Connecting to nginx (10.0.0.112:80)
index.html 100% |*******************************| 612 0:00:00 ETA
27 / 74
Exercise: WordPress
Create a deployment to run a MySQL Pod.
28 / 74
BREAK
29 / 74
Part II: Other Objects and a bit more focus on Pods
DaemonSets
StatefulSets
CronJobs
Jobs
Ingress
Persistent Volume Claims
...
30 / 74
e.g CronJob
A Pod that is run on a schedule
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
31 / 74
Volumes
Define array of volumes in the Pod spec. Define your volume types.
...
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
32 / 74
Using Secrets
To avoid passing secrets directly in a Pod definition, Kubernetes has an API
object called secrets. You can create, get, delete secrets. They can be used in
Pod templates.
33 / 74
Con gMap
To store a configuration file made of key value pairs, or simply to store a
generic file you can use a so-called config map and mount it inside a Pod
...
spec:
containers:
- image: busybox
...
volumeMounts:
- mountPath: /velocity
name: test
name: busybox
volumes:
- name: test
configMap:
name: velocity
34 / 74
For persistency use PV and PVC
kubectl get pv
kubectl get pvc
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
35 / 74
Init-containers
Maybe you want to do some prep work before starting a container. Prep a file
system, run some provisioning script...They run to completion and then the
app starts.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep
36 / 74
Use Volumes with Init-containers
Example the git initializer
apiVersion: v1
kind: Pod
metadata:
name: git-repo-demo
spec:
initContainers:
- name: git-clone
image: alpine/git # Any image with git will do
args:
- clone
- --single-branch
- --
- https://github.com/kubernetes/kubernetes # Your repo
- /repo
volumeMounts:
- name: git-repo
mountPath: /repo
containers:
- name: busybox
image: busybox
args: ['sleep', '100000'] # Do nothing
volumeMounts:
- name: git-repo
mountPath: /repo
volumes:
- name: git-repo
emptyDir: {}
37 / 74
Requests and Limits
Great example to follow in the docs
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
38 / 74
Default Limit Range in a Namespace
You can create default per namespace which will be automatically added in
each Pod manifest.
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: 512Mi
defaultRequest:
memory: 256Mi
type: Container
39 / 74
Probes
Liveness probe to know when to restart a container
Readiness probe to know when to send traffice to it
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
40 / 74
Relax isolation
Share the process namespace betwen all containers in a Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true
containers:
- name: nginx
image: nginx
- name: shell
image: busybox
...
41 / 74
Security Context
Set uid, gid, selinux, fs permissions, capabilities at the Pod or container level.
...
spec:
securityContext:
runAsNonRoot: true
containers:
- name: nginx
image: nginx
42 / 74
ServiceAccount
Pods can talk to the Kubernetes API server using a service account
It used to be that this service account had full privileged access to the API
server ...:( Now you need to grant it privileges to do anything, see RBAC roles
and rolebinding.
A namespace has a default service account. Pods in a namespace will use this
service account. Otherwise create a new service account.
kubectl get ns
kubectl get sa
kubectl create ns kude
kubectl get sa -n kude
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: kude
43 / 74
Network Policies
You need a Networking add-on that has a network policy controller.
44 / 74
Deny All Network Policy
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-deny-all
spec:
podSelector:
matchLabels:
app: web
ingres: []
45 / 74
Imperative/ Declarative
See a blog about it
46 / 74
LUNCH BREAK
47 / 74
The Exam
Logistics
What to expect
Bit of advice
From https://training.linuxfoundation.org/certification/certified-kubernetes-
application-developer-ckad/
This exam curriculum includes these general domains and their weights on
the exam:
48 / 74
Curriculum
49 / 74
Curriculum
50 / 74
What to expect
Intense
Some questions are easy some take more time
Know your vi
Look up the documentation and paste
51 / 74
kubectl Cheat sheet
kubectl config use-context my-cluster-name
kubectl get pods -o wide
kubectl get services --sort-by=.metadata.name
kubectl get pods -o json | jq '.items[] ...
kubectl edit
kubectl run -i --tty busybox --image=busybox -- sh
kubectl port-forward my-pod 5000:6000
kubectl top
kubectl exec
kubectl cp
kubectl scale
kubectl run .... --dry-run -o json
kubectl get ... -- export
52 / 74
Practice - Pods
Create a Pod with name newyork and container image redis
53 / 74
Practice - Pods
Create a Pod with name newyork and container image redis
Create a Pod with name albany a container image busybox that sleeps and
define an environment variable VELOCITY whose value is rocks
54 / 74
Practice - Pods
Create a Pod with name newyork and container image redis
Create a Pod with name albany a container image busybox that sleeps and
define an environment variable VELOCITY whose value is rocks
Create a Pod with two containers, one name foo, the other one named bar .
The first one with the image nginx and the second one with the image redis.
The Pod should be called foobar and have the label foo=bar
55 / 74
Practice - Pods
Given the following manifest, set the container resource request for memory
to 128 Mega bytes.
apiVersion: v1
kind: Pod
metadata:
name: question10
spec:
containers:
- name: nginx
image: nginx
56 / 74
Practice - Pods
Create a deployment object called foo123 with 2 replicas that uses image
nginx.
57 / 74
Practice -- init-containers
A Python app is containerized in a Docker image mypytonapp, it needs some
modules defined in a requirements.txt file.
Configure an init container that installs the dependencies via a shared volume
in a Pod that runs the Python app
58 / 74
Practice - Deployments
Perform a rolling update of Deployment foo123 by changing the image of
container foo from nginx to runseb/2048
59 / 74
Pratice - Services
Given the manifest for a Pod:
apiVersion: v1
kind: Pod
metadata:
name: question10
spec:
containers:
- name: nginx
image: nginx
Expose it to the internet by creating a service. Fix any potential issues that
may arise.
60 / 74
Practice - Networking
List the network Policies and figure out why they are not working ?
tip Try configure minikube for testing network policies and run a few tests
from Ahmet's blog.
61 / 74
Practice - CronJob
Write a cronjob manifest that outputs the date every 5 minutes to stdout
62 / 74
Practice - Con guration
Given a file file.txt containing the sentence I will pass CKAD, mount this file
inside a Pod using a configMap and copy the file from the Pod back to the host.
63 / 74
Practice - Con guration
Given a file file.txt containing the sentence I will pass CKAD, mount this file
inside a Pod using a configMap and copy the file from the Pod back to the host.
64 / 74
Practice - Con guration
Given a file file.txt containing the sentence I will pass CKAD, mount this file
inside a Pod using a configMap and copy the file from the Pod back to the host.
65 / 74
Practice - Persistency
Create a PVC that requests 500 Megabytes and use this PVC to make the data of
a mysql Pod persistent.
66 / 74
Practice - Monitoring
Find the logs of the Pod called X
extra what would you use to aggregate the logs of all containers ?
67 / 74
Practice - Monitoring
Find the logs of the Pod called X
extra what would you use to aggregate the logs of all containers ?
Among all the Pods running in cluster Y, find the Pod that consumes the most
CPUs
68 / 74
Practice - Security
Write a Dockerfile for an image that can run in a Pod with a securityContext
that does not let run as root.
69 / 74
Practice - Probes
Come up with an example to showcase the behavior of Liveness and
readinessprobes
70 / 74
Practice - Service Account
Create a namespace
Set the kubectl config profile to access the cluster using this new service
account.
Create the RBAC roles to be able to create Pods in the created namespace
71 / 74
Practice - Service Account
Write a toy Python (or your preferred language) app that you containerize
(write a Dockerfile) that needs to call the k8s API server
Demonstrate that with the default service account the app calls fail and that
when you give the service account the proper privileges it runs properly
72 / 74
Bottom line
Make sure you know vi
Make sure you know your YAML syntax/linting
Make sure you know the structure of API objects
Make sure you know how to navigate the Kubernetes documentation
quickly
Make sure you know kubectl
73 / 74
Thank You
And good luck tomorrow
74 / 74