CKA Exam Prep Flashcards
What is the command to create a POD?
kubectl run pod_name –image=image_name
What is the command to create a POD manifest file without creating the resources?
kubectl run pod_name –image=image_name –dry-run=client -o yaml
How to create a deployment?
kubectl create deployment deployment_name –image=image_name
e.g. kubectl create deployment my-nginx –image=nginx
This creates a Deployment named my-nginx that runs Pods using the nginx image. Kubernetes will automatically ensure that one instance of the nginx container is running unless scaled otherwise.
Kubernetes automatically assigns labels as well to the pod and uses those as selectors in deployment
Create deployment with 4 replicas
kubectl create deployment deployment_name –image=image_name –replicas=4
e.g.: kubectl create deployment nginx –image=nginx –replicas=4
How to scale a deployment
kubectl scale deployment deployment_name –replicas=6
e.g.: kubectl scale deployment nginx –replicas=4
How to create a namespace?
kubectl create namespace namespace_name
e.g. kubectl create namespace dev
How to create a POD in a specific namespace
kubectl run pod_name –image=image_name –namespace=namespace_name
e.g. kubectl run nginx –image=nginx –namespace=dev
How to edit a resource?
kubectl edit resource_type resource_name
e.g.
kubectl edit deployment deployment_name
kubectl edit pod pod_name
This edits the in-memory file and changes the resources but the main config file is untouched
How to apply a configuration file?
kubectl apply -f config_file.yaml
How to set a new image for an existing deployment?
kubectl set image deployment/deployment_name image_name=new_image_name
e.g. kubectl set image deployment/my-deployment nginx=nginx:1.21
This command directly modifies the configuration of the Deployment in the Kubernetes cluster. It creates a rolling update where Pods are gradually replaced with new Pods using the updated image.
How to describe a resource?
kubectl describe pod pod_name
How to view logs
kubectl logs pod_name
How to get resources? pods, services, deployments, namespaces, nodes
kubectl get pods
kubectl get services
kubectl get deploymnets
kubectl get nodes
kubectl get all
How to see resources for all namespaces?
kubectl get all –all-namespaces
How to get resources with wide output?
kubectl get pods -o wide
How to delete a deployment?
kubectl delete deployment deployment_name
How to create a resource file for deployment from Live configuration?
kubectl get deployment deployment_name -o yaml > deployment.yaml
How to dry run to generate a YAML file? Consider a deployment
kubectl create deployment deployment_name -image=image_name –dry-run=client -o yaml
How to update objects within a configuration file?
kubectl replace -f config_file.yaml
you can use kubectl apply -f config_file.yaml
How to apply resources in a directory instead of specific file?
kubectl apply -f /path/to/config-files
Does deployments automatically create all the resources including replica sets?
Yes
How to check the rollout status of a deployment?
kubectl rollout status deployment/deployment_name
How to check the rollout history of a deployment?
kubectl rollout history deployment/deployment_name
How to undo a rollout for a deployment?
kubectl rollout undo deployment/deployment_name
How to scale a replicaset?
kubectl scale -f replicaset-definitionfile.yaml –replicas=6
You can also update the replicaset directly
kubectl scale replicaset replicaset_name –replicas=6
How to connect to a resource in another namespace? Lets say its a mysql database and the namespace name is dev and the resource name is db-service?
mysql.connect(db-service.dev.svc.cluster.local)
How to get pods in a specific namespace?
kubectl get pods –namespace=namespace_name
How to switch contexts permanently for a namespace to dev?
kubectl config set context $(kubectl config current-context) –namespace=dev
How to create a service to route traffic to a deployment?
kubectl expose deployment deployment_name –port 80
- If you want the service to be accessible outside the cluster, you can specify –type=NodePort or –type=LoadBalancer.
- If the nginx deployment exposes containers on a port other than 80, you need to add –target-port=<container-port> to map the service's port to the container's port.</container-port>
What are the different types of ports?
port: ServicePort
targetPort: Container Port (where the traffic should be forwarded)
nodePort: where the service is exposed outside the cluster
The only mandatory field is port. If targetPort is not entered it gets the same port as port.
If the nodePort is not entered kubernetes automatically assigns a port between 30000-32627
What is the difference between replace & apply?
kubectl replace -f nginx.yaml
kubectl replace –force -f nginx.yaml
kubectl apply -f nginx.yaml
replace: the resource should exist. It will delete the resources & create them fresh with the supplied config file
apply: if the resource does not exist, it will create the resource. If the resource already exist, it will apply the changes.
If you are making changes that are not supported as an in-place update (e.g., changing certain immutable fields like spec.selector in a Deployment), you may need to delete and recreate the resource.
Use kubectl apply to create or update resources without deleting them first.
Delete resources only when you need to reset their state or make changes that are not supported in-place.
When to use kubectl edit command
For quick changes and you are sure that you are not going to reply on object configuration file in future. Because changes are not made in the config file.
How to Create a Service named redis-service of type ClusterIP to expose pod redis on port 6379. Just do a dry run
kubectl expose pod redis –port=6379 –name=redis-service –dry-run=client -o yaml
By default this command uses pod labels as selectors as you cannot pass selectors in imperative commands
How to create a pod with labels
kubectl run nginx –image=nginx –labels=”env=production,app=nginx”
How to Create a Service named redis-service of type ClusterIP to expose pod redis on port 6379. Just do a dry run
kubectl create service redis-service –port-80 –dry-run=client -o yaml
> service-fil.yaml
This will not use the pods labels as selectors, instead it will assume selectors as app=redis-service. 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:
Pod labels as selectors:
kubectl expose pod nginx –port=80 –type=NodePort –name=nginx –dry-run=client -o yaml > service-file.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.
Pod Labels are not used as selectors:
kubectl create service –type=nodeport –name=nginx –port=80 –node-port=30080 –dry-run=client -o yaml
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.
To specify nodePort:
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # The port the service will expose internally
targetPort: 8080 # The port on the container to forward traffic to
nodePort: 30007 # The specific NodePort to expose on each node
Summary of lab commands
controlplane ~ ➜ kubectl run nginx-pod –image=nginx:alpine
pod/nginx-pod created
controlplane ~ ➜ kubectl run redis –image=redis:alpine –labels=”tier=db”
pod/redis created
controlplane ~ ✖ kubectl expose pod redis –port=6379 –name=redis-service
service/redis-service exposed
controlplane ~ ➜ kubectl create deployment webapp –image=kodekloud/webapp-color –replicas=3
deployment.apps/webapp created
controlplane ~ ➜ kubectl run custom-nginx –image=nginx –port=80
pod/custom-nginx created
controlplane ~ ➜ kubectl delete pod custom-nginx
pod “custom-nginx” deleted
controlplane ~ ✖ kubectl run custom-nginx –image=nginx –port=8080
pod/custom-nginx created
controlplane ~ ➜ kubectl create namespace dev-ns
namespace/dev-ns created
controlplane ~ ➜ kubectl create deployment redis-deploy –namespace=dev-ns –image=redis –replicas=2
deployment.apps/redis-deploy created
controlplane ~ ➜ kubectl run httpd –image=httpd:alpine
pod/httpd created
controlplane ~ ➜ kubectl expose pod httpd –port=80
service/httpd exposed
How to create a POD declaratively?
apiVersion: v1
kind: Pod
metadata:
name: redis-pod
labels:
name: redis-pod
app: demo-voting-app
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
How to use help command say for e.g. kubectl expose
kubectl expose –help
How to create a deployment declaratively?
apiVersion: apps/v1
kind: Deployment
metadata:
name: voting-app-deploy
labels:
name: voting-app-deploy
app: demo-voting-app
spec:
template:
metadata:
name: voting-app-pod
labels:
name: voting-app-pod
app: demo-voting-app
spec:
containers:
- name: voting-app
image: kodekloud/examplevotingapp_vote:v1
ports:
- containerPort: 80
selector:
matchLabels:
name: voting-app-pod
app: demo-voting-app
replicas: 1
How to create a service declaratively?
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
name: result-app-service
app: demo-voting-app
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
nodePort: 30005
selector:
name: result-app-pod
app: demo-voting-app
What is the key used by scheduler to verify if a POD has been scheduled or not?
nodeName in the pod definition file. This can be used to bypass scheduler and place the pod on a specific node
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: node01
containers:
- image: nginx
name: nginx
How to manually schedule a POD to a node once it has been created?
Create a binding object and send a post request to the POD’s binding API
Binding object:
apiVersion: v1
kind: Binding
metadata:
name: my-pod
namespace: default
target:
apiVersion: v1
kind: Node
name: node-1
kubectl apply -f binding.yaml
What does replace command do?
It deletes the POD and recreates it
kubectl replace –force -f pod-def.yaml
Note: If using kubectl apply then you have to first delete the pod separately and then use apply
How to get pods that belongs to a specific labels
kubectl get pods –selector app=App1
k get pods –selector env=dev
k get pods –selector env=prod,bu=finance,tier=frontend
What are annotations used for?
To record other details for informative purpose
for e.g. name, version, build, contact details
What are taints and tolerations used for?
To restrict what pods are placed on what nodes
taint is applied on a node
toleration is applied on a pod
How to taint a node?
k taint nodes node_name key=value:taint-effect
e.g. kubectl taint nodes node-1 app=blue:NoSchedule
k taint nodes node01 spray=mortein:NoSchedule
What are the different types of effects in tainting
NoSchedule: No pod will be scheduled on the tainted node unless it has a matching toleration.
PreferNoSchedule: The scheduler will prefer not to schedule pods on the node, but will do so if no other nodes are suitable.
NoExecute: Any existing pods on the node will be evicted, and no new pods will be scheduled unless they tolerate the taint.
How to add toleration to a pod for this taint on a node?
e.g. kubectl taint nodes node-1 app=blue:NoSchedule
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
tolerations:
- key: “app”
operator: “Equal”
value: “blue”
effect: “NoSchedule”
What is the main purpose of taints & tolerations?
It restricts nodes from accepting certain pods. It does not guarantee that a pod will always be placed on a specific node. If there are other nodes without any taint. The pod may well be placed in those nodes. This functionality is achieved by node affinity.
Where do you see matchLabels in selector?
Only in deployment & replicaset yaml files
How to check the taint on the master node?
kubectl describe node kubemaster | grep Taint
How to ensure a POD is placed in a specific Node?
Using Node Selectors in POD config file or NodeAffinity
spec:
nodeSelector:
size: Large # node label
How to label a node?
kubectl label nodes node_name <label_key>=<label_value</label_key>
e.g. kubectl label nodes node1 size=Large
What is the limitation of nodeSelector?
Does not work for complex expressions with nodeSelector
for e.g. Place pod in Large or Medium, Do Not place PODS in Small nodes
The solution is nodeAffinity
What is the purpose of NodeAffinity?
To ensure PODS are hosted on specific nodes
How to add nodeAffinity to a pod definition file?
spec
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: size
operator: In
values:
- Large
- Medium
Operator can be NotIn
What is the operator used to check if a label exists on a node
operator: Exists
What are the nodeAffinity types?
requiredDuringSchedulingIgnoredDuringExecution:
What it does: Ensures that a pod can only be scheduled on a node that meets the specified condition (label match).
Ignored During Execution: Once the pod is running, it won’t be evicted if the condition changes.
preferredDuringSchedulingIgnoredDuringExecution:
What it does: Tries to schedule the pod on a node that matches the condition but doesn’t strictly require it.
Ignored During Execution: Once the pod is running, it won’t be evicted if the condition changes.
requiredDuringSchedulingRequiredDuringExecution:
What it does: Ensures that a pod can only run on a node that meets the specified condition both during scheduling and while it is running.
Required During Execution: If the node’s labels change and the condition is no longer met, the pod will be evicted.
Why should I use Taint, Tolerations & NodeAffinity together
With Taint & Tolerations: you cannot limit the PODS from being placed in other nodes which does not have any taint. They can happily be placed. Here: PODS can be PLACED on STRANGER nodes
With NodeAffinity: There are labels set for nodes and you give the PODS those labels in the spec section. There is no guarantee that other PODS which does not have those labels set are not placed in these nodes right. They can be happily placed. Here: STRANGER PODS can be PLACED on YOUR nodes
What resources does a node have?
CPU & Memory
e.g. 1 CPU and 1Gi Memory - known as resource request for a container
Who decides which node the POD goes to?
kube-scheduler
How to add resource request within a POD definition file?
within the containers:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
resources:
requests:
memory: “4Gi”
cpu: 2
What does 1 CPU really mean?
1 AWS vCPU
1 GCP Core
1 Azure Core
What is the difference between 1G and 1Gi in memory?
1G is 1000MB
1Gi is 1024MB
By default does container has any limit on the resources it can consume on a node?
No. This could lead to suffocation
How to control the no. of resources a container consumes on a node?
By setting limits at each container
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
resources:
requests:
memory: “4Gi”
cpu: 2
limits:
memory: “2Gi”
cpu: 2
What is the difference between requests & limits
requests: This is the amount of resources the container is guaranteed to have
limit: This is the maximum amount of resources the container can use
What happens if the container exceeds limits for CPU & Memory?
In case of CPU throttling happens
In case of Memory it can use more memory than its limit. But if it does constantly, the POD will be terminated with an OOM (Out of Memory) message. Once memory is assigned to a POD, only way to retrieve it is by killing the POD
What happens if you have limits set but no requests?
In this case kubernetes sets the requests same as limits
What happens if you have requests set but no limits?
Each pod is guaranteed the requested amount of resources. But if POD 1 is needs more resources, it can get those since there are no limits. This is the most ideal set up!
Since we have REQUESTS set, POD 2 is always guaranteed the minimum resources
What is the issue with setting both limits & requests?
If POD 1 needs more resources and POD 2 is under-utilized then POD 1 cannot use those left over resources since we limited.
How to ensure every POD created has some default set for the limits & requests?
Can be done using LimitRange. Only affects newer PODS. The below config is done at namespace level
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-resource-constraint
spec:
limits:
- default: #default limit
cpu: 500m
defaultRequest: #default request
cpu: 500m
max: #max limit, the container cannot set more than this
cpu: “1”
min: #min request, the container must request at least this
cpu: 100m
type: Container
Is there any way to restrict no. of resources consumed by ALL the PODS within a kubernetes cluster?
Can be done using ResourceQuota at namespace level
apiVersion: v1
kind: ResourceQuota
metadata:
name: my-resource-quota
spec:
hard:
requests.cpu: 4
requests.memory: 4Gi
limits.cpu: 10
limits.memory: 10Gi
So if you are asked to edit a property of a POD part of a deployment you may do that simply by running which command?
kubectl edit deployment deployment_name
With Deployments you can easily edit any field/property of the POD template. Since the pod template is a child of the deployment specification, with every change the deployment will automatically delete and create a new pod with the new changes.
Can you edit the environment variables, service accounts, resource limits of a running pod
No. But if you have to do that you can do it by using
kubectl edit pod pod_name
you will get forbidden message. But a copy of your changes are saved in a temporary location
You can then delete the POD and create the new POD using the temporary file
2nd Option is to.. extract the POD def file to a yaml, make changes, delete the POD and use kubectl create -f pod_def.yaml
What is the purpose of Deamon Sets?
Ensures one copy of the POD runs on each node of the cluster
Use Cases:
- Monitoring Solution
- Logs Viewer
- Kube-proxy
How to create Deamon Sets using configuration file?
Similar to replicaset
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: monitoring-daemon
spec:
selector:
matchLabels:
app: monitoring-agent #this label pod will be placed in all nodes
template:
metadata:
labels:
apps: monitoring-agent
spec:
containers:
- name: monitoring-agent
image: monitoring-agent
How to view the Daemon sets
k get deamonsets
Can you create daemonset imperatively?
As a workaround you can.
You cannot give namespaces or images names.. Instead do a dryrun and specify namespace separately. Again dryrun should be performed with deployment config file and you make the edits as necessary
What does kubelet do?
It is like a captain of the node. Relies on kube-apiserver to instruct what pods to load on its node.
The decision is made by the kube-scheduler and the decision is stored in ETCD datastore
Can kubelet operate as an independent node without the master node which has all the controlplane? How to provide the pod definition file to kubelet without the kube-apiserver?
kubelet can be configured to read the pod def files from a directory in the server designated to store info about pods
/etc/kubernetes/manifests
kubelet.service file
the option for the folder is –pod-manifest-path
OR
you can provide a path to another config file
–config=kubeconfig.yaml and define the directory as staticPodPath:
These pods are called static pods. Only PODS can be created this way. Not other resources like deployments, replicasets, etc.
These PODS are viewed using docker ps
Why would you use static pods?
To deploy kubernetes controlplane components
Install kubelet
create the def files for all the controlplane components
place them in the –pod-manifest-path
kubelet will take care of deploying the components
This way you dont have to worry about downloading binaries, configuring services or crashing services etc.. as kubelet will recreate crashing services automatically. This is how a kubeadm sets up a kubernetes cluster.
kubectl get pods –namespace=kube-system .. you will see all pods only since the control plane components are set up as pods
static pods have nodename appended at the end
kube-scheduler has no affect on what resources?
static pods and daemon sets
How to check the kubelet.service file
Option 1:
systemctl status kubelet
Check the kubelet.service file
Check the file to see the path directly or a config file.yaml
cat the config file and look for staticPodPath
Option 2:
ls /var/lib/kubelet/config.yaml
How to give sleep 1000 in a pod def file?
command: [“sleep”, “1000”]
How to run commands within a pod of a running container?
kubectl exec -it mypod – /bin/sh
This would open an interactive shell (/bin/sh) inside the mypod container.
kubectl exec mypod – echo “Hello from inside the container”
Explain LimitRange config file in detail
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-memory-constraint
spec:
limits:
- default:
cpu: 500m
defaultRequest:
cpu: 200m
max:
cpu: “1”
min:
cpu: 100m
type: Container
- default:
memory: “2Gi”
defaultRequest:
memory: “1Gi”
max:
memory: “4Gi”
min:
memory: “512Mi”
type: Container
In this example:
limits: is a list that contains two items.
Inside this item:
default: sets the default CPU limit.
defaultRequest: sets the default CPU request.
max: sets the maximum CPU limit.
min: sets the minimum CPU request.
type: Container indicates that these constraints apply to containers.
How to deploy a custom kube-scheduler
First they must have different names (default-scheduler, kubernetes-scheduler-1)
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchdulerConfiguration
profiles:
- schedulerName: kubernetes-scheduler-1
leaderElection: #if multiple schedulers in the cluster
leaderElect: true
resourceNamespace: kube-system
resourceName: lock-object-my-schedule
When you run the kube-scheduler binary, you point it to the new custom config file
Ideally this is NOT how you deploy a scheduler. With kubeadm all controlplane components are deployed as a POD within a cluster
apiVersion: v1
kind: Pod
metadata:
name: custom-scheduler-name
namespace: kube-system
spec:
containers:
- image: k8s.gcr.io/kube-scheduler-amd64:v1.11.3
name: kube-scheduler
command:
- kube-scheduler # First element in the list: the main command
- –address=127.0.0.1 # Second element in the list: the first argument
- –kubeconfig=/etc/kubernetes/scheduler.conf # Third element
- –config=/etc/kubernetes/my-scheduler-config.yaml # Fourth element
Key Points:
command: is a field that specifies the command to run inside the container.
It is a list of values, where each dash (-) represents an item in that list.
The first item (kube-scheduler) is the main command that runs inside the container.
The subsequent items (–address=127.0.0.1, –kubeconfig=/etc/kubernetes/scheduler.conf, and –config=/etc/kubernetes/my-scheduler-config.yaml) are the arguments passed to the kube-scheduler command.
How to ensure that the POD is using the custom scheduler instead of the default one?
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx:
name: nginx
schedulerName: my-custom-scheduler
How to know which scheduler picked up in scheduling a POD
k get events -o wide and you can check the source
How to view the logs of a scheduler
k logs scheduler_name –namespace=namespace_name
How to create configmap
k create configmap –name configmap_name –from-file=/root/my-scheduler-config.yaml –namepsace=kube-system
How to set priority for a POD for scheduling?
Using priorityClassName
apiVersion: v1
kind: Pod
metadata:
name: pod_name
spec:
priorityClassName: high-priority
containers:
- name: container_name
image: image_nme
resources:
requests:
cpu: 2
memory: “4Gi”
How to define a priority class
apiVersion: scheduling.k8s.io.v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
What is the workflow for scheduling?
Scheduling Queue
Filtering
Scoring
Binding
Within kubelet what is the subcomponent responsible for retrieving container metrics from PODS?
cAdvisor or Container Advisor
What are some of the monitoring solutions to capture cluster metrics
prometheus, metrics server, elastic stack, datadog, dynatrace
e.g. This is the command to install metrics server on a cluster: k apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Once metrics server is deployed what commands can be used to monitor the metrics for nodes & pods?
k top pod - these display the resource usage of pods running in a cluster
k top node
Memory: Mebibytes
CPU: millicores
In kubernetes how to see the logs?
k logs -f config_file.yaml container_name
You need to specify container name if multiple containers are out there
k logs pod_name (if the pod only has one container)
k logs pod_name -c container_name –namespace=namespace (if pod has multiple container and you want to view the logs for a specific container & namespace)
What are the different deployment strategies?
Recreate
RollingUpdate (Default)
What are the 2 ways to change the deployment configuration details
- Change the deployment config file for e.g. image and then k apply -f deploy_config.yaml
- k set-image deployment deployment_name –nginx=nginx:1.2
Note: the 2nd option does not change the config file