top of page

CKAD Module: Core Concepts episode 1

  • myriamfentanes
  • Mar 2, 2022
  • 5 min read

According with the exam curricula the for the first section the topics are:

  • Understand Kubernetes API primitives

  • Create and configure basic pods

Starting with the concepts

What is Kubernetes?

Kubernetes is an opensource orchestration engine for managing containerized workloads and services. The name Kubernetes comes from the greek word for helmsman and its original code name was project 7 currently is also known as k8s. The latest version is 1.26 ( the curriculum and material are based on that version). Kubernetes was initially created by Google and the first release was on June 7th 2014 .The first implementation was made in Java, but the code since has been written in Go.

Kubernetes is really a cluster, with a set of worker machines called nodes and a control plane. The nodes host the pods that contain the application workloads. You must always have at least one node. The control plane manages the nodes and the pods in a cluster through a set of services. Below you can see a diagram of a Kubernetes cluster. And you can find the overview of each service here


ree

What is a Kubernetes primitive?

The Kubernetes environment is defined by a collection of objects, this objects are also called primitives. Each primitive represents some functionality of the system and are defined in a file called manifest using YAML or JSON. The most important object in Kubernetes is a pod and the first section makes sure you know how to create, configure, manage and delete a pod.


Below you can see a diagram of the Kubernetes primitives relevant to the exam and its relations to a pod.


ree

The basic structure of an object in a manifest can be described as follows:


ree

Interacting with Kubernetes objects

For the exam your interaction tool with K8s will be kubectl. Kubectl is a tool provided by Kubernetes to interact with the cluster control plane via the cluster API.


You can interact with Kubernates in 2 ways: Declarative and imperative.


Declarative

For a declarative approach you use the object's manifest to create, edit or delete pods. For example:

To create a pod named webapp using the image tomcat:9.0 and expose the service on port 8080. We use a manifest like this:



apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: webapp
  name: webapp
spec:
  containers:
  - image: tomcat:9.0
    name: webapp
    ports:
    - containerPort: 8080
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {} 

Then we run the command to create the pod:

mfentane@MacBook-Pro ~ % kubectl create -f webapp.yaml 
pod/webapp created

To delete the pod you just created:

mfentane@MacBook-Pro ~ % kubectl delete  -f webapp.yaml 
pod "webapp" deleted

To inspect the pod you just created:


mfentane@MacBook-Pro ~ % kubectl describe pod webapp
Name:         webapp
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Wed, 01 Mar 2023 10:38:27 +0100
Labels:       run=webapp
Annotations:  <none>
Status:       Running
IP:           172.17.0.3
IPs:
  IP:  172.17.0.3
Containers:
  webapp:
    Container ID:   docker://a75a1219176c5bc07a3772dbdfba25c82bcc913862f571f9a4a1e76b8ecc52eb
    Image:          tomcat:8.0
    Image ID:       docker-pullable://tomcat@sha256:8ecb10948deb32c34aeadf7bf95d12a93fbd3527911fa629c1a3e7823b89ce6f
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Wed, 01 Mar 2023 10:41:25 +0100
    Last State:     Terminated
      Reason:       Error
      Exit Code:    143
      Started:      Wed, 01 Mar 2023 10:38:28 +0100
      Finished:     Wed, 01 Mar 2023 10:41:09 +0100
    Ready:          True
    Restart Count:  1
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-xhm2k (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-xhm2k:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age                  From               Message
  ----    ------     ----                 ----               -------
  Normal  Scheduled  3m21s                default-scheduler  Successfully assigned default/webapp to minikube
  Normal  Pulled     3m20s                kubelet            Container image "tomcat:9.0" already present on machine
  Normal  Killing    39s                  kubelet            Container webapp definition changed, will be restarted
  Normal  Pulling    39s                  kubelet            Pulling image "tomcat:8.0"
  Normal  Pulled     24s                  kubelet            Successfully pulled image "tomcat:8.0" in 15.446248745s
  Normal  Created    23s (x2 over 3m20s)  kubelet            Created container webapp
  Normal  Started    23s (x2 over 3m20s)  kubelet            Started container webapp
~                                                                                        

The output contains the details of the pod specs but also the status of the application running inside of the pod.


To edit the pod using the declarative approach, you need to provide a manifest that has a complete resource definition for the pod, and there are restrictions on the parameters that you can change. Once you have a manifest, there are 2 options:

You can overwrite the live configuration of the object using the replace command.

mfentane@MacBook-Pro ~ % kubectl replace -f pod.yaml    

Or you can use the apply command, that works like create with the difference that if the object exists the create command will produce and error and apply will update the live object.

mfentane@MacBook-Pro ~ % kubectl apply -f pod.yaml


Imperative approach

The imperative approach does not need a manifest definition, you can pass as arguments in the kubectl command the desired configuration of your pod

To create the same pod as before :

mfentane@MacBook-Pro ~ % kubectl run webapp --image tomcat:9.0 --restart=Never --port=8080

To delete the pod:

mfentane@MacBook-Pro ~ % kubectl delete pod webapp

To edit the pod using your text editor:

mfentane@MacBook-Pro ~ % kubectl edit pod webapp

Kubectl run is key for creating pods, for the exam is important to memorize and practice the command and all of its flags and options.


Examples

1- Setting environment variables and labels for a pod called database using a postgres image with the variable POSTGRES_PASSWORD = mysecretpassword and the label env=prod.

Declarative

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    env: prod
  name: database
spec:
  containers:
  - env:
    - name: POSTGRES_PASSWORD
      value: mysecretpassword
    image: postgres
    name: database
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

Using the manifest, we run the command

mfentane@MacBook-Pro ~ % kubectl create -f database.yaml


Imperative

mfentane@MacBook-Pro ~ % kubectl run database --image=postgres --port=8080 --env="POSTGRES_PASSWORD=mysecretpassword" --labels="env=prod" 


Other useful commands


During the exam you will be asked to find and fix errors when running or deploying applications. Some useful commands to do so are:

To see the logs of the pod called database

mfentane@MacBook-Pro ~ % kubectl logs database
The files belonging to this database system will be owned by user "postgres".

With the output

This user must also own the server process.


The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".


Data page checksums are disabled.


fixing permissions on existing directory /var/lib/postgresql/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Etc/UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok


initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.


Success. You can now start the database server using:


    pg_ctl -D /var/lib/postgresql/data -l logfile start

...
waiting for server to start....2023-03-07 10:35:32.631 UTC [48] LOG:  starting PostgreSQL 15.2 (Debian 15.2-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2023-03-07 10:35:32.633 UTC [48] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2023-03-07 10:35:32.638 UTC [51] LOG:  database system was shut down at 2023-03-07 10:35:32 UTC
2023-03-07 10:35:32.642 UTC [48] LOG:  database system is ready to accept connections
 done
server started
2023-03-07 10:35:32.883 UTC [1] LOG:  database system is ready to accept connections

To interact with the pod database you can:

mfentane@MacBook-Pro ~ % kubectl exec -it database -- /bin/sh

Given the time allocated to each task it's important to have proficiency in using the commands.

It is recommended to study the kubectl cheatsheet and Kubernetes documentation, these resources will be available during the exam.








Recent Posts

See All

Comments


bottom of page