CKA
Cluster Architecture
Master: manage, plan, schedule, monitor nodes
ETCD CLUSTER
Nodes
PODs
Configs
Secrets
Accounts
Roles
Bindings
Others
#Run ETCD service on port 2379
./etcd
./etcdctl put key1 value1
./etcdctl get key1ETCDCTL version 2 commands:
ETCDCTL version 3 commands:
To set the right version of API set the environment variable ETCDCTL_API command:
specify path to certificate files so that ETCDCTL can authenticate to the ETCD API Server:
specify the ETCDCTL API version and path to certificate files:
kube-scheduler
Controller-Manager
watch status
Remediate situation
Node-Controller
Node Monitor Period = 5s
Node monitor grace period = 40s
Pod Eviction timeout = 5m
Worker Nodes: host application as containers
Replication-Controller
kube-apiserver
the primary management component in kubernetes
Authenticate user
Validate request
Retrieve data
Update ETCD
Scheduler
Kubelet
kubelet
Kube-proxy
Kube-proxy
View kube-proxy - kubeadm
Super-powers are granted randomly so please submit an issue if you're not happy with yours.
YAML in Kubernetes
lab
Deployments
Certification Tip
Using the kubectl run command can help in generating a YAML template. And sometimes, you can even get away with just the kubectl run command without having to create a YAML file at all. For example, if you were asked to create a pod or deployment with specific name and image you can simply run the kubectl run command.
Use the below set of commands and try the previous practice tests again, but this time try to use the below commands instead of YAML files. Try to use these as much as you can going forward in all exercises
Reference (Bookmark this page for exam. It will be very handy):
https://kubernetes.io/docs/reference/kubectl/conventions/
Create an NGINX Pod
kubectl run nginx --image=nginx
Generate POD Manifest YAML file (-o yaml). Don't create it(--dry-run)
kubectl run nginx --image=nginx --dry-run=client -o yaml
Create a deployment
kubectl create deployment --image=nginx nginx
Generate Deployment YAML file (-o yaml). Don't create it(--dry-run)
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml
Generate Deployment YAML file (-o yaml). Don't create it(--dry-run) with 4 Replicas (--replicas=4)
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml > nginx-deployment.yaml
Save it to a file, make necessary changes to the file (for example, adding more replicas) and then create the deployment.
kubectl create -f nginx-deployment.yaml
OR
In k8s version 1.19+, we can specify the --replicas option to create a deployment with 4 replicas.
kubectl create deployment --image=nginx nginx --replicas=4 --dry-run=client -o yaml > nginx-deployment.yaml
Services
Imperative vs Declarative
Imperative: Taxi
Declarative: Uber
Infrastructure as Code
Imperative: 1. Provision a vm by the name 'web-server'
2. Install NGINX software on it
Declarative: VM Name: web-server
Package: nginx
Port: 8080
Path: /var/www/nginx
Code: GIT Repo - X
Kubernetes
Imperative:
Create Objects
k run --image=nginx nginx
k create deployment --image=nginx nginx
k expose deployment nginx --port 80
Update Objects
k edit deployment nginx
k cale deployment nginx --replicas=5
k set image deployment nginx nginx=ninx:1.18
k create -f nginx.yaml
k replace -f nginx.yaml
k delete -f nginx.yaml
Imperative Object Configuration Files
Create Objects
Kubernetes Memory
pod-definition
Update Objects
Declarative:
Create Objects
k apply -f nginx.yaml
k apply -f /path/to/config-files
Update Objects
k apply -f nginx.yaml
Exam Tips
Create Objects
k apply -f nginx.yaml
k run --image=nginx nginx
k create deployment --image=nginx nginx
k expose deployment nginx --port 80
Update objects
k apply -f nginx.yaml
k edit deployment nginx
k scale deployment nginx --replicas=5
k set image deployment nginx nginx=nginx:1.18
Certification Tips - Imperative Commands with Kubectl
While you would be working mostly the declarative way - using definition files, imperative commands can help in getting one time tasks done quickly, as well as generate a definition template easily. This would help save considerable amount of time during your exams.
Before we begin, familiarize with the two options that can come in handy while working with the below commands:
--dry-run: By default as soon as the command is run, the resource will be created. If you simply want to test your command , use the --dry-run=client option. This will not create the resource, instead, tell you whether the resource can be created and if your command is right.
-o yaml: This will output the resource definition in YAML format on screen.
Use the above two in combination to generate a resource definition file quickly, that you can then modify and create resources as required, instead of creating the files from scratch.
POD
Create an NGINX Pod
kubectl run nginx --image=nginx
Generate POD Manifest YAML file (-o yaml). Don't create it(--dry-run)
kubectl run nginx --image=nginx --dry-run=client -o yaml
Deployment
Create a deployment
kubectl create deployment --image=nginx nginx
Generate Deployment YAML file (-o yaml). Don't create it(--dry-run)
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml
Generate Deployment with 4 Replicas
kubectl create deployment nginx --image=nginx --replicas=4
You can also scale a deployment using the kubectl scale command.
kubectl scale deployment nginx --replicas=4
Another way to do this is to save the YAML definition to a file and modify
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > nginx-deployment.yaml
You can then update the YAML file with the replicas or any other field before creating the deployment.
Service
Create a Service named redis-service of type ClusterIP to expose pod redis on port 6379
kubectl expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml
(This will automatically use the pod's labels as selectors)
Or
kubectl create service clusterip redis --tcp=6379:6379 --dry-run=client -o yaml (This will not use the pods labels as selectors, instead it will assume selectors as app=redis. You cannot pass in selectors as an option. So it does not work very well if your pod has a different label set. So generate the file and modify the selectors before creating the service)
Create a Service named nginx of type NodePort to expose pod nginx's port 80 on port 30080 on the nodes:
kubectl expose pod nginx --type=NodePort --port=80 --name=nginx-service --dry-run=client -o yaml
(This will automatically use the pod's labels as selectors, but you cannot specify the node port. You have to generate a definition file and then add the node port in manually before creating the service with the pod.)
Or
kubectl create service nodeport nginx --tcp=80:80 --node-port=30080 --dry-run=client -o yaml
(This will not use the pods labels as selectors)
Both the above commands have their own challenges. While one of it cannot accept a selector the other cannot accept a node port. I would recommend going with the kubectl expose command. If you need to specify a node port, generate a definition file using the same command and manually input the nodeport before creating the service.
Reference:
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
Scheduling
How scheduling works

No Scheduler!
Manual scheduling (lab)
Labels and Selectors
Labels
Select
k get pods --selector app=App1
ReplicaSet
Same method use in Service
Annotations
Taints and Tolerations
Taints-Node
k taint nodes node-name key=value:taint-effect
taint-effect: NoSchedule | PreferNoSchedule| NoExcute
k taint nodes node1 app=blue:NoSchedule
Tolerations-PODs
k taint nodes node1 app=blue:NoSchedule
Taint-NoExecute
taint and toleration does not tell the pod to go to a particular node. Instead it tells the node to only accept parts with certain toleration.
If you requirment is to restrict a pod to certain nodes it is achieved through another concept called node affinity.
k describe node kubemaster|grep -i taint
Remove the taint: k taint nodes controlplane node-role.kubernetes.io/master:NoSchedule-
node/controlplane untainted
k run bee --image=nginx --restart=Never --dry-run -o yaml > bee.ayml
k explain pod --recursive|less
k explain pod --recursive | grep -A5 tolerations
k get pods -o wide
Node Selectors
pod-definition.yml
Label Nodes
k label nodes <node-name> <label-key>=<label-value>
k label nodes node-1 size=Large
Node Selector-Limitations
Large OR Medium
NOT Small
Node Affinity
ensure that pods are hosted on particular Nodes
pod-definition.yml
Node Affinity Types
available:
requiredDuringSchedulingIgnoredDuringExecution
perferredDuringSchedulingIgnoreDuringExecution
Type 1
Required
Ignored
Type 2
Preferred
Ignored
Type 3
Required
Required
planned:
requiredDuringSchedulingRequiredDuringExecution
Lab command:
k get nodes node01 --show-labels
Create a new deployment named 'blue' with the NGINX image and 6 replicas:
k create deployment blue --image=nginx
k scale deployment blue --replicas=6
Set Node Affinity to the deployment to place the PODs on node01 only:
k get deployments.apps blue -o yaml > blue.yaml
vi blue.yaml
add affinity part from https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/
k delete deployments.apps blue
k apply -f blue.yaml
Create a new deployment named 'red' with the NGINX image and 3 replicas, and ensure it gets placed on the master node only.
Use the label -node-role.kubernetes.io/master- set on the master node.
k create deployment red --image=nginx --dry-run -o yaml > red.yaml
change the replicas to 3 add affinity
k apply -f red.yaml
k get pods -o wide|grep red
Node affinity vs taints and tolerations
Resource Requirements and Limits
pod-definition.yaml
CPU 1
1 AWS vCPU
1 GCP Core
1 Azure Core
1 Hyperthread
MEM 256 Mi
1 G (Gigabyte) = 1,000,000,000 bytes
1 M (Megabyte) = 1,000,000 bytes
1 K (Kilobyte) = 1,000 bytes
1 Gi (Gibibyte) = 1,073,741,824 bytes
1 Mi (Mebibyte) = 1,048,576 bytes
1 Ki (Kibibyte) = 1,024 bytes
Disk
Resource limits
by default limits each container 1 vCPU 512Mi memory, k8s throttles the cpu so that it does not go beyound the specified limit, a container can use more memory resources than its limit.
If a pod tries to consume more meory than its limit constantly, the pod will be terminated.
Note on default resource requirements and limits
In the previous lecture, I said - "When a pod is created the containers are assigned a default CPU request of .5 and memory of 256Mi". For the POD to pick up those defaults you must have first set those as default values for request and limit by creating a LimitRange in that namespace.
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/
References:
https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource
Last updated