Welcome to Acing the Certified Kubernetes Administrator Exam. If you’ve purchased this book, chances are you’ve already researched the exam, know what it’s about, and perhaps even have it scheduled. If not, don’t worry; we’ll talk about what the exam is and how to get signed up as soon as possible. For those of you who want to get right down to it, go ahead and skip this section, as it will most likely be review for you. You can skip to section 2, where we get into the meat and potatoes of the exam curriculum.
For those who are still being introduced to the CKA exam, let’s go over what the exam is and what it entails. First, let me start by stating that I’m glad you’ve decided to come along with us on this journey to get certified in Kubernetes. Achieving the Certified Kubernetes Administrator (CKA) certification is quite an accomplishment and will help advance your career in a very big way. Also, you’ll be part of a large group of individuals who hold this certification, including over 32,000 people worldwide. You might be asking yourself if it’s worth it, and to that, I would say yes, and here’s why:
- Kubernetes and distributed systems are going to be around for a long time.
- Kubernetes skills are in high demand.
- Getting certified will help solidify your understanding and show that you are well rounded and versed in Kubernetes.
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

Now, let’s get into what the exam is all about. The CKA exam is a competency test like no other. Instead of multiple-choice or fill-in-the-blank questions, this exam is entirely executed from within a Linux terminal (Ubuntu XFCE) in a remote desktop environment provided by PSI Services (the exam provider). Yes, that’s right; they’ll give you a set of tasks to complete, and you’ll execute the solutions by typing the commands inside the terminal within the provided remote desktop environment. This is the entire exam experience, and you will have two hours to complete 15–20 tasks of this nature. Once complete, you are graded on the outcome of your tasks, no matter which path you took to achieve the outcome. This means that there may be more than one way to solve a given task. Throughout this book, you will learn different ways of obtaining the same results, giving you more tools in your tool belt, to achieve a passing grade on this exam, which is 66% or higher. You can also receive partial credit on any task, so that will help your success rate as well.
Throughout this book, we’ll address tips and tricks available for each topic within each chapter. This will tie in nicely with applying your lessons and give you the necessary skills to approach the exam with confidence. These exam tips, in combination with your determination and repeated practice, will lead to success in passing the CKA exam. I can’t emphasize enough how much muscle memory and putting in the practice will help your brain retain and access the appropriate Kubernetes commands when the time comes for the exam. Acing the CKA is truly an exercise, so if you’re determined to pass the exam, you shouldn’t take long breaks between study sessions, especially if you aren’t working with Kubernetes daily. Don’t let this deter you, though; we’re going to do this Kubernetes workout together!
The CKA exam is provided by the Linux Foundation, and Kubernetes is maintained by the Cloud Native Computing Foundation (CNCF). The exam costs US$375 as of the writing of this book, but check the updated pricing sheet for current prices and prices in other currencies by visiting the Linux Foundation website at https://training.linuxfoundation.org. This price may be a bit higher than similar certifications of its class, but they do allow one free retake, as well as one additional browser tab, opened to the following sites and their subdomains during the exam:
- https://helm.sh/docs/
- https://kubernetes.io/docs/
- https://github.com/kubernetes/
- https://kubernetes.io/blog/
To take the exam, you will need a computer running Windows 8.1, Windows 10, Windows 11, macOS 10.15, macOS 11, macOS 12, Ubuntu 18.04, or Ubuntu 20.04 that has the Chrome web browser installed (all browsers are supported, but PSI highly recommends Chrome). When you begin the exam, you’ll be instructed to download and install a new PSI-secured browser, which will automatically grant you access to the PSI proctoring platform, called PSI Bridge, which is the remote desktop environment. The remote desktop environment will include links to open the terminal as well as the provided Firefox browser (you must use Firefox) so you can browse to the authorized sites listed earlier. You will also need a webcam that has at least 640 × 480 pixel resolution, as they will require a 360 view of the room (external camera required for desktops) and will be monitoring you for the duration of the exam. Your computer screen must be 1368 x 769 pixel resolution or higher (dual monitors are not supported), you must have a functional microphone, and your internet bandwidth speed must be at least 300 Kbps to download and upload. The room where you take the exam must be quiet and well lit. Public spaces such as coffee shops or stores are not allowed. Your desk must be cleared of all papers and other electronics, and you must be seen clearly in the center frame of your webcam.
On exam day, you’ll sit down at your desk with your computer, make sure it’s plugged in, then go to the Linux Foundation portal to start your exam. Before you click the Begin Exam button, make sure that all browser tabs are closed and no other applications are running in the background (the proctor will check this as well). Once you click on the button to begin the exam, you’ll immediately be introduced to an exam proctor. This exam proctor will check your environment to make sure that your desk is cleared and there aren’t any papers or unauthorized electronics around. So, using your camera, you’ll pan around the room to get a full 360 view, and you’ll wait for their approval. They’ll also periodically check your hands and wrists. The proctor will first check your hands and wrists before you start the exam, then they’ll also stop you at frequent intervals in the middle of your exam and ask you to show both sides of your hands and wrists. Before they release the exam to you, they will also ask you for your government-issued ID, which you must hold up to the camera. Once the proctor is done verifying your identity and checking your workspace, they will release the exam, which means they will allow you to enter the exam and view the first question. You’ll notice that each question has a similar format, including the context you must use and the task(s) that you must execute via the command line to solve the problem. If you come to a question that you can’t answer, my advice is to skip it; you can flag it and come back to it at any time during the exam. It will be clear how to flag a question for review, as they show you in a brief automated walk-through at the beginning of the exam. For each task, you will also see the percentage of points that the task is worth. If you’re stumped on something, look at how much it’s worth. If it’s worth, let’s say, 5%, then go ahead and skip it.
EXAM TIP
The core competencies on which you will be tested are cluster architecture, installation and configuration; workloads and scheduling; Services and networking; storage; and troubleshooting. We’ll cover all these areas in this book. Within the cluster architecture competency, which will comprise 25% of the questions on the exam, you will be tested on role-based access control, using kubeadm to add features and update a Kubernetes cluster, and backing up and restoring the etcd datastore. In the workloads and scheduling competency, which will comprise 15% of the questions on the exam, expect to be tested on performing rolling updates and rollbacks, as well as scaling applications and using ConfigMaps and Secrets. In the Services and networking competency, which comprises 20% of the questions on the exam, you’ll be tested on creating and updating various Services in Kubernetes, using Ingress, DNS, and the container network interface in Kubernetes. In the storage competency, which comprises 10% of the questions on the exam, you’ll need to understand storage classes, persistent volumes, and volume modes in Kubernetes. Then, in the troubleshooting competency, which is 30% of the questions on the exam, you will be expected to know how to get the logs from a Kubernetes cluster, as well as monitor and repair core cluster components. Table 1.1 outlines these domains and their competencies.
Table 1.1 Exam competencies and their percentages of the exam (view table figure)
You will have six clusters available during the exam that you will be required to switch between depending on the question. Usually, each question will ask you to perform the task on a different cluster than the previous question. They will provide instructions for how to switch between clusters, so don’t worry too much about memorizing the cluster names and commands to switch between clusters.
The exam will also have the alias for kubectl set to k. An alias is a command you run that pertains to another command. For example, a common alias that exists for most Linux operating systems is l='ls -lah', which means when you type the command l, it’s the same thing as typing ls -lah. Similarly for the CKA exam, when you type the command k, it’s the same as the command kubectl. From the command line on your computer, you can type alias to list all the existing aliases on your computer. All six clusters will have only one control plane node, and two clusters will have only one worker node, with one out of those two missing a worker node. They will all have a container network interface (CNI) installed and are named k8s, hk8s, bk8s, wk8s, ek8s, and ik8s, as shown in figure 1.1.
So many people have registered for the CKA exam that it has become one of the most popular Linux Foundation certifications to date. This partially speaks to the demand for the certification but also to the credibility of the certification once received. The certificate is valid for three years, and the process to recertify is the same process that you went through the first time you took the exam.
I suggest scheduling your exam now, so you have an end goal and a deadline for completing it. This will keep you motivated to finish this book and will provide the necessary timeline to keep your knowledge top of mind and appropriately prepared to sit for the exam. If you are currently working with Kubernetes at your job, and you are typing kubectl commands daily, then schedule your exam for one month from today.
If you are just approaching the topic of Kubernetes, having never heard of it before, go ahead and schedule your exam for the furthest date the exam scheduler will allow (usually this is three months, but it may be less.) You can always reschedule, but the point is to give yourself two things: (1) a deadline so that you can take this exam seriously and achieve your intended result and (2) daily practice to incorporate into your prefrontal cortex (where memories are stored). This is exactly what you’ll need to stay fresh and ready for the exam.
discuss

Throughout this book, I’ll be inserting exercises and exam-like scenarios for you to practice kubectl commands and prepare you for the exam. To make practice as easy as possible, I’ve included instructions for creating your local cluster. In appendix A, I’ll walk you through the steps to create a Kubernetes cluster using kind. Kind Kubernetes (https://kind.sigs.k8s.io/) is a free, lightweight, and easy-to-use tool for creating a cluster right on your existing laptop or desktop computer. The only requirement is Docker, and with one command, you’ll have a cluster up and running in seconds. This eliminates the barrier to entry for practicing for the CKA. I advise you to utilize this method, as you can waste a lot of time trying to build a cluster manually; and because the exam will have clusters already prepared for you, I believe this is the best way to study and follow along with this book. There are other methods to create a local cluster that you are welcome to use, such as minikube or MicroK8s. The idea is similar, but those tools might not align directly with the scenarios in this book. For example, in chapter 5, we’ll prepare a cluster with a missing node. The steps to stage the environment are unique to kind, so reproducing the environment in minikube will be different.
Within each chapter of this book, there will be a scenario that resembles the real exam, which we’ll work through together, followed by additional practice exercises that you can complete on your own. In appendix D, you can review hints for solving these practice exercises. You can use these to both test your knowledge of the book’s content and to gauge your readiness for the CKA exam.
Before we begin, I’d like to clarify some points and let you know what this book is and what it isn’t. This book is not an introduction to Kubernetes, so I expect that you have a background in containers and an understanding of what problem Kubernetes solves, as these will not be covered in this book. The CKA exam is not introductory; therefore, it will require quite a bit of experience with using and navigating the Linux operating system. People who understand cgroups and namespaces, which provide containers in Linux, will have an easier time following this book and subsequently passing the exam. Also, most who sit for this exam are already working with the technology in their job today, by either being introduced to it via a new project or by already using cluster administration as a primary function within their role. I’m not saying that people who are not working with Kubernetes won’t pass the exam, but getting direct exposure to real-world scenarios, using your knowledge in a daily, hands-on fashion is more likely to lead to success.
The role of a Kubernetes administrator is twofold. A Kubernetes administrator knows the inner workings of Kubernetes and how to translate that into value for the end users. Here’s what a job posting for a Kubernetes administrator might look like: “The responsibility of a Kubernetes administrator is to ensure that the company’s services meet the needs of the customers within the desired levels of reliability, performance, and availability by developing continuous improvements, tools, and automation. You must know how to install, configure, deploy, update, and patch each of the components of the Kubernetes infrastructure to ensure that services and underlying systems are properly monitored and have adequate observability. This includes identifying and monitoring proper KPIs (key performance indicators) to ensure service health, minimizing MTTA (mean time to acknowledge) and MTTR (mean time to repair).”
Let’s not sugarcoat it; the difficulty level of the exam remains high, hence the need for this book. But you will start to realize the complexities of Kubernetes after reading this book—not only how to envision the complexities and how they relate to what you already know about engineering and technology, but also how to dig through the complexities to troubleshoot and determine the root cause for the actions within a Kubernetes cluster.
settings

That brings me to the next point—the Kubernetes cluster. What is it? The Kubernetes cluster is called a cluster because it is a RESTful API of machines working together, in conjunction, as in figure 1.2. Just like a server farm, the machines are interconnected and housed within the same facility or network. But the key difference in Kubernetes is that the connected servers not only distribute load appropriately but also easily exchange data to eliminate a single point of failure. If one of the nodes fails, it doesn’t bring down the entire cluster. Throughout this book, we’ll call servers nodes. Node is a term that’s specific to clusters, which tend to indicate that the server is a part of a larger system. We’ll talk more about the anatomy of a cluster in chapter 2.
Figure 1.2 Servers (called nodes) working together in a cluster. When one fails, it takes itself out of the cluster to be repaired.

NOTE
Kubernetes is nothing more than a piece of software that you interact with via a REST API. A RESTful API is a well-defined, highly scalable, loosely coupled application architecture that favors communication over a network—and, more importantly, the act of transferring the state of a resource over a network. I can’t stress enough how important it is to remember that Kubernetes is behind an API (a RESTful one, which is a collection of resources that can be manipulated through that API). Resources is the keyword here. Resources are how we address objects in Kubernetes. Sometimes in the Kubernetes community, we use the words resources and objects interchangeably, but there is a fundamental difference. Objects can have more than one resource address; for example, Deployments can have multiple URIs (uniform resource identifiers) based on the API version or based on the Deployment name, as you can see in figure 1.3. Deployments in Kubernetes are objects that offer more automated control over Pods and ReplicaSets that comprise your application running on Kubernetes. ReplicaSets are another type of object in Kubernetes that provides a control loop running a specified number of Pods (i.e., Pod replicas). You can list all available API resources with the command kubectl api-resources from any Kubernetes cluster.
Figure 1.3 Kubernetes addresses objects by their resource URI, where multiple URIs can point to a single object.

We commonly interact with the Kubernetes API, and the objects within, by using a command-line tool called kubectl. We will solely be using kubectl throughout this book, as this is the command-line tool used on the exam to interface with the Kubernetes API. Having the kubectl command-line tool, in addition to a certificate, is needed to create, read, update, and delete Kubernetes resources. Depicted in figure 1.4 is a certificate that provides us with the role-based access that we need to perform certain operations in the Kubernetes cluster.
Figure 1.4 kubectl is the tool used to access Kubernetes objects, given a valid certificate inside the kubeconfig.

As previously mentioned, the architecture of a cluster is comprised of nodes, and on those nodes are running Pods. A Pod is the smallest deployable unit in Kubernetes and contains one or more containers. In an abstraction of the API, resources like Deployments are created that are comprised of ReplicaSets, which in turn are running one or more Pods across multiple nodes. In Kubernetes, there are two types of nodes—the control plane node and the worker node. The control plane node runs the API server, DNS, the controller manager, the scheduler, kube-proxy, and etcd datastore. All these parts and their relationships are shown in figure 1.5.
Communication to the control plane happens through the API, on the control plane node. The worker nodes, by way of the kubelet, get instructions from the control plane to fulfill their duty to not only run the containers themselves but to report on the health, providing a constant status to the control plane. The workers carry the brunt of the load, which makes their role very important for running applications in Kubernetes.
Resources like ReplicaSets (rs) and Deployments (deploy) are essential to developing stateless application workloads running on Kubernetes. Without them, we wouldn’t be able to automatically scale Pods, which provides load balancing, making our applications more readily available when running on Kubernetes. We call the process of deploying these applications to Kubernetes scheduling. The term scheduling comes from the scheduler, which is a component of the control plane. We’ll talk more about the control plane components later in this chapter. Historically, if you had to create an application that runs on hardware, it had to be maintained and updated from time to time. This can cause outages and/or limitations to what that hardware can do (it gets old). Kubernetes (the application) abstracts this hardware away and creates a common interface (an API) between it and everything else (hardware alike). This allows you to switch out hardware on the fly, as well as incorporate hardware from different vendors and mix and match.
My favorite way of driving home this point is to look at an example to get a solid understanding of resources inside of an API. Let’s look at an API that’s been rendered through the browser at https://swapi.dev. If you go to SWAPI (Star Wars API), you’ll see how to request different facts about Star Wars movies. You make this request via a GET request to the API. Because the API is built on top of the HTTP protocol, we can perform HTTP methods to take action on the API Endpoints. Those actions can be create, read, update, or delete, usually designated by an acronym: CRUD. In this case, though, the purpose of the SWAPI is to make a request to the API and “GET” back some data. So, in the request field, type people/1/, and down below you should see the results, shown in figure 1.6.
The result is "Luke Skywalker", but the result doesn’t really matter; the point is that you just received data (in JSON format) from the API. The data that you received is the resource URI we’ve been talking about. The object located at that URI was "Luke Skywalker", and that object contains data such as height, hair color, eye color, etc. Relating this to Kubernetes, the people object in SWAPI is much like the Deployment object in Kubernetes. And you can similarly access the Kubernetes API. The Kubernetes Dashboard even offers the API rendered through a browser, just like SWAPI. Figure 1.7 shows some Kubernetes resource URIs.
Figure 1.7 Objects in Kubernetes accessed according to their resource URI. Nodes, for example, are located in /apis/apps/v1/nodes.

There are different API calls (called HTTP methods) that perform certain actions against the API (given you have already authenticated to the API). They are GET, POST, PATCH, PUT, and DELETE. A GET HTTP method is exactly what we’ve been doing with the SWAPI, which is to retrieve or view information about the resources in our API. A POST HTTP method is used to create a new resource in the API. A PATCH HTTP method is used to update existing resources, and a PUT HTTP method is used to replace existing resources in the API. Finally, a DELETE HTTP method is used to delete a resource from the API.
To have the end user interact with your application running on Kubernetes, we create an object called a Service. These Services provide a load-balancing feature to the Pods they serve. They also provide a single IP address and DNS name, which we’ll review in later chapters. Speaking of DNS, there’s a component in Kubernetes called CoreDNS that provides names for IP translations. This means that resources in Kubernetes can talk to each other using common names as opposed to IP addresses. The three types of Services are ClusterIP, NodePort, and LoadBalancer.
An Ingress resource is another Kubernetes object that provides path-based routing to a Service in Kubernetes. For example, you would create an Ingress resource to offer a layer-7 (application layer) route to a Service based on a URL path.
While managing ephemeral objects such as Pods in Kubernetes, you can’t rely on storage to be tied to a single Pod. Storage is the data that an application uses to store and organize files in a filesystem such as NTFS, XFS, or ext4. A filesystem is the act of the organization of storage that takes place in an operating system such as Linux. In Kubernetes, there’s a concept of persistent volumes that aren’t tied to an individual Pod but instead to an NFS, EFS, or iSCSI volume. Having the storage decoupled from the ephemeral applications creates that persistence of data.
In addition, from a developer’s perspective, you no longer have to manage the underlying storage. To Kubernetes, it seems like just one large storage layer. The developer can utilize an object called a persistent volume claim to reserve a persistent volume, so it cannot be used for other applications running in Kubernetes. This still requires the persistent volume to exist, so in the case that it doesn’t, the developer may access storage dynamically using an object called storage class. Storage class pertains to the different classes that volumes come in—for example, slow versus fast.
Volumes can also be used by multiple Pods at the same time as well as reused, specifying certain access modes and certain reclaim policies, respectively. The access modes allow the read and write capability of a volume to one or many Pods. The reclaim policy will allow or deny access from other Pods in a Kubernetes cluster.
Kubernetes clusters aren’t perfect; they can become quite complex the more resources and objects are created in them. Troubleshooting when problems arise is essential to limit the downtime of running applications and also to detect problems to optimize and have Kubernetes performing at its best. Being able to decipher logs from a running container, analyze failures, and propose a solution to that failure is key to becoming a great Kubernetes administrator. Logs are time-based behavioral data sent via text to a directory on the filesystem to give you verbose information about a problem that’s occurring. All the redundancy in the world will not fix a cluster that has been poorly constructed and not well maintained.
Applications running on Kubernetes also have an added maintenance responsibility. They contain logs from stdout and stderr that are important for detecting when communication problems arise or application failure is imminent.
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

The controller manager is a control loop, responsible for matching the current state to the desired state. For example, the controller manager will automatically scale a Deployment if the Pods do not match the desired number of replicas. The controller manager also creates the default accounts and API access tokens for new namespaces. That’s why you’ll see when we create a Kubernetes cluster in the next chapter that there’s a default namespace, Service Account, and secret already created for you to start deploying your resources (applications) into. This makes it easy to start running containerized applications on Kubernetes right away. When referring to a namespace, think of it as a dedicated virtual environment for your Kubernetes resources. The default namespace will be isolated within the scope of that namespace and can have its own grouping of Kubernetes resources.
The API server is exactly what it sounds like: it’s the component that exposes the Kubernetes API (the RESTful API that we talked about earlier). It’s the entry point for the cluster, so all communication to the cluster passes through it to access the cluster components. Think of it like a gate that will open only if opened with the right key using authentication, as in figure 1.8. We’ll talk more about authentication in chapter 3.
The scheduler is the component that selects the nodes on which the Pods run. You will probably hear the word scheduling a lot throughout this book, so from here on when I say “scheduling,” it just means that the Pods are being placed (scheduled) on the nodes for running them. If multiple nodes already have Pods running on them, then the scheduler is going to place the Pods on a different node, taking into consideration the available resources and other rules/specifications that have been placed on that node.
There are certain Services (called daemons) that run on the control plane and are critical for the Kubernetes cluster to operate. They are so critical, in fact, that in a production scenario, they are replicated for high availability. Replicating the control plane components is beyond the scope of this book and the exam because the Kubernetes clusters on the exam are not going to have more than one control plane node. In general, replicating the control plane works by performing two functions. First, replication ensures that the control plane components have only one instance-receiving request at a time. This is achieved by electing a leader. The leader will act as the primary control plane and relay its status to the other followers. Second, because the control plane relies on etcd for storing all the Kubernetes configuration data (the state of resources and how they are running in Kubernetes), you’ll create multiple redundant copies of etcd. If you want to learn more about replicating the control plane for high availability in Kubernetes, you can read more here: http://mng.bz/5wz7.
The etcd datastore is one of those critical control plane components we addressed earlier. Etcd stores all the Kubernetes configuration data (the state of Kubernetes). Etcd is a consistent, distributed key-value store designed to hold small amounts of data that can fit entirely in memory. This is important because data can be retrieved more quickly than other traditional databases (see figure 1.9). The most important thing to remember about the etcd datastore is that losing it (etcd failure) is catastrophic, as it contains all the configuration information for resources running inside a Kubernetes cluster, so making sure it’s backed up is extremely important. You may come across questions on the exam about backing up etcd, so we’ll cover how to do this in the next chapter.
discuss

Now that we’ve talked about the control plane components in great detail, let’s review the components that reside on a worker node, as shown in figure 1.10. The components that run on a worker node are different from the components on the control plane because the worker nodes play a different role in the Kubernetes landscape. You will most certainly have more than one node inside of a Kubernetes cluster, and each one of the following components is installed on each node:
Figure 1.10 The role of the worker node is to run the application workloads. It also contains kubelet, kube-proxy, and the container runtime (e.g., containerd).

The kubelet service that runs on each worker node makes sure that containers are running in a Pod. However, although it’s not aware of containers that aren’t managed by the scheduler, kubelet can detect when a container (within a Pod) is failing and take corrective action to ensure that the container restarts in the way that is specified in the YAML manifest, the set of instructions for configuring a Pod in YAML (YAML isn’t markup language) format. It’s like a set of declarative instructions (with the end state in mind) for the kubelet to follow to maintain high availability for the application running on Kubernetes. If the kubelet can’t make the container run, it will report the status of the Pod and container to the Kubernetes API server, and you can see it in the Pod events by performing the command kubectl describe po nginx (nginx is the name of the Pod). A similar output is shown here:
$ kubectl describe po nginx Name: nginx Namespace: default Priority: 0 Node: host01/172.17.0.33 Start Time: Tue, 01 Feb 2022 16:49:36 +0000 Labels: run=nginx Annotations: <none> Status: Running IP: 192.168.0.4 IPs: IP: 192.168.0.4 Containers: nginx: Container ID: containerd:/ /4de3efffd3a6f1ec49c968d7fde95e8eae4ae0c25574e8055cca33a197499879 Image: nginx Image ID: docker.io/library/nginx@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 Port: <none> Host Port: <none> State: Running Started: Tue, 01 Feb 2022 16:49:44 +0000 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-5ffvj (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-5ffvj: 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 17s default-scheduler Successfully assigned default/nginx to host01 Normal Pulling 16s kubelet Pulling image "nginx" Normal Pulled 9s kubelet Successfully pulled image "nginx" in 6.993614669s Normal Created 9s kubelet Created container nginx Normal Started 9s kubelet Started container nginx
When you look at the events after describing the Pod, you see that there are different states of a container (shown as the status), including waiting, running, and terminated. You will also see the state of the container by running the command kubectl get po.
The kube-proxy Service running on each worker node is the communication mechanism of a Kubernetes Service. A Service is another resource type in Kubernetes and is responsible for allocating traffic to the various Pods within that Service. We’ll review Services in depth in chapter 6. These are basic network rules for the node to follow if traffic needs to get to the Pods in Kubernetes. There’s a fascinating video that describes this in greater detail called “Life of a Packet.” I highly encourage you to watch it here: https://youtu.be/0Omvgd7Hg1I.
Finally, running on each node in the Kubernetes cluster is the container runtime. This is a necessary component for Kubernetes to work, as it is the engine that runs the containers themselves. Interestingly, though, it is an external dependency, meaning that it’s one of the only components necessary to a Kubernetes cluster that Kubernetes doesn’t apply or install itself. This means that you have choices when it comes to container engines that you have to install. Kubernetes supports any container runtime time that follows the CRI requirements (http://mng.bz/6D0R). The common options are either Docker (https://docs.docker.com/engine/), containerd (https://containerd.io/docs/), or CRI-O (https://cri-o.io/#what-is-cri-o). Chances are you’ve heard of Docker, but did you know that Docker uses containerd as the container runtime under the hood while using a feature called dockershim to get to containerd? Docker is also not CRI compliant (http://mng.bz/o1nD). So, containerd, implied by the last sentence, is the stripped-down (so it’s lightweight and portable) container runtime that is also CRI compliant. CRI-O is another lightweight container runtime that supports the open container initiative (OCI). So, it’s a community-driven, open source project that supports multiple image formats, including Docker images.
settings

Take our tour and find out more about liveBook's features:
- Search - full text search of all our books
- Discussions - ask questions and interact with other readers in the discussion forum.
- Highlight, annotate, or bookmark.
We’ll talk more about RBAC and identity management in Kubernetes in chapter 3, but for now, let’s just talk about the public key infrastructure that comprises the client-to-server relationship in Kubernetes. As we have seen, to manipulate objects in Kubernetes, we need two things. The first is the command-line tool kubectl. The second is a client certificate, as you can see in figure 1.11.
Public key infrastructure (PKI) is a very common client–server communication pattern, and it is the usual way our computers securely communicate with websites via web servers. At a high level, PKI enables secure communication over the web by ensuring that the website you’re visiting is the website that you intended to visit (via cryptographic signature). This ensures that you’re visiting the right website (not an imposter’s website), but also ensures that nobody is snooping or intercepting the traffic back and forth. If you think about accessing your bank over the web, this PKI infrastructure is critical to ensuring that bank accounts are safe, that the people accessing them are indeed the owners of the accounts, and that the bank you are accessing is indeed the correct bank.
The fundamental pieces of the PKI include three elements, which are shown in figure 1.12. First and foremost is the certificate authority (CA). The CA is the source of truth and signs the server certificate (in the case of one used with the API), and subsequently, the client can determine if the server is valid. On the web, for example, the common certificate authorities are DigiCert, Symantec, and Thawte and are already trusted by the browser (the client) as a way for your browser to quickly verify a website’s identity (e.g., whether google.com is actually Google). The second and third pieces of the PKI puzzle are the server and client, both relying on the CA—the client trying to verify the identity of the server, and the server trying to authenticate and prove to the CA that they are who they say they are. Just like the PKI for the web, the same PKI model is applied to Kubernetes.
Figure 1.12 The control plane node serves as the certificate authority (CA), which signs the certificate and provides authentication to client and server communication.

Taking the same three pieces of the PKI puzzle and applying them to Kubernetes, Kubernetes is its own CA and will be the source of truth for the other components within a Kubernetes cluster. The clients in Kubernetes (the ones checking whether the servers are who they say they are) are the kubelet, the scheduler, the controller manager, and the etcd datastore. The same Kubernetes component can be a client and a server at the same time. The servers in Kubernetes (the ones trying to prove their identity to the CA) are the kubelet, the Kubernetes API, and the etcd datastore (see figure 1.13).
Figure 1.13 The Kubernetes API has multiple responsibilities in the PKI infrastructure of both client and server. The CA is generating certificates, and servers are proving their identity (http://mng.bz/mV68).

Luckily, you don’t have to worry about creating a CA, client, or server certificate. Kubeadm will do all of this for you. Kubeadm is another command-line tool like kubectl, but its purpose is for creating the necessary components that make up our Kubernetes cluster (including the CA and other certificates); sometimes we call this bootstrapping the cluster. We’ll talk more about kubeadm and the location of all of these certificates in chapter 3.
highlight, annotate, and bookmark
You can automatically highlight by performing the text selection while keeping the alt/ key pressed.

With all this talk about Services and components to both the control plane and the worker nodes, I thought it pertinent to mention Linux system services. Linux system services are a grouping of files on the Linux operating system that provides a software program that constantly runs in the background. If you remember, I referred to certain services that run on the control plane as daemons. Daemons have been used in the Linux world for ages, not to be confused with a DaemonSet in Kubernetes, which makes sure the daemon is running on each node as a Pod in the Kubernetes cluster at all times, as shown in figure 1.14. If you are more familiar with Windows computers, this same concept is called a service.
Figure 1.14 DaemonSets ensure that a single Pod is running on each node in the cluster. kube-proxy and CNI both run as DaemonSets.

For that matter, the control plane components that we spoke about earlier are a good example of that. You can have a DaemonSet running on each node that provides the kube-proxy component, for example. See for yourself by running the command kubectl get ds -A.
$ kubectl get ds -A NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-system kube-flannel-ds 1 1 1 1 1 <none> 18m kube-system kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 19m
There is one service, however, that you don’t want Kubernetes to manage (as a DaemonSet), and that is kubelet. kubelet is one of the only services in the context of Kubernetes that will be located on the Linux system itself (as a Linux system service). You must know this for the exam. Why? Because the Linux service may be down, presenting a scenario on the exam for you to repair it. Knowledge about where this service is and how to repair it will come in handy. To see a list of all services on your Linux system, type the command sudo systemctl list-unit-files --type service --all | grep kubelet -a6.
$ sudo systemctl list-unit-files --type service --all | grep kubelet -a6 ip6tables.service enabled enabled iptables.service enabled enabled irqbalance.service enabled enabled keyboard-setup.service enabled enabled kmod-static-nodes.service static enabled kmod.service static enabled kubelet.service enabled enabled logrotate.service static enabled lvm2-lvmpolld.service static enabled lvm2-monitor.service enabled enabled lvm2-pvscan@.service static enabled lvm2.service masked enabled man-db.service static enabled
You will see a list of services that will show the unit file (the service name) and the state of the service (enabled/disabled/masked/static). In this list, you will see kubelet.service as one of these. Once you’ve identified that the kubelet service is running on your system, you can do one of three things. If it has stopped, you can start it by typing systemctl start kubelet. If you notice that the service does not start when the node is rebooted, then you can enable it with the command systemctl enable kubelet so that it automatically starts up when the node starts up (or restarts). Finally, if you simply want to check the status of the service to see if it’s active or inactive, you can run the command systemctl status kubelet.
Within the list of services, you may have noticed the systemd.journald service. If you didn’t, go ahead and run the following command to show it: sudo systemctl list-unit-files --type service --all | grep journald.service.
$ systemctl list-unit-files --type service --all | grep journald.service systemd-journald.service static enabled
Journald (another Linux system service) is used to collect logs about the kubelet service on each node. Journalctl is a command-line utility for viewing logs on a Linux system collected by systemd, which is the primary daemon in Linux that controls all processes. This logging mechanism can prove very useful during the exam. You may find yourself digging through the logs to find out why the kubelet service is failing, for example. Use the commands sudo journalctl -u kubelet and sudo journalctl -u containerd as a reference.
You can check the /var/log/pods directory for Pod logs; however, you can also retrieve these in the exact same fashion with the kubectl logs command (e.g., kubectl logs kube-controller-manager-server1 -n kube-system). More on troubleshooting and collecting these logs in chapter 8. For now, just know that these Linux system services are important for collecting valuable information about Kubernetes and that some services exist on the Linux system (the node) and some Services exist within the confines of Kubernetes (in a Pod).
discuss

Now that you have a good idea of the composition of a Kubernetes cluster and its underlying Services, I would be remiss not to mention the primary purpose of Kubernetes, which is to run applications. Yes, once you have the foundation (which we’ve talked about thus far in this chapter) of your control plane components, worker node components, and Linux system services, and the cluster is functioning as a loosely coupled unit (remember the API model?), it’s time to run your applications. After all, this is the primary function and the reason why we’re using Kubernetes in the first place. As far as running these applications on Kubernetes, you can run a Java application on Kubernetes, just the same as a .NET application.
Figure 1.15 In a true microservices architecture, each microservice is decoupled from other services; therefore, it can be built in the language that suits the service best.

Kubernetes doesn’t care at all about the language or about how the application runs, as depicted in figure 1.15. It will run your containers the same way in every instance and does so by keeping that same foundational benefit to containers, which inherently run the same way on every machine because the application binaries and libraries are packaged up along with the container.
So, if Kubernetes doesn’t care about the language or the framework of the application, how are applications deployed on Kubernetes? This brings us to a very important word in DevOps and cloud native—declarative. You will find that building applications on Kubernetes in a declarative way is far better than imperative. Why? Imperative is nothing more than running a series of commands in a specific sequence. This makes it hard to track these commands and detect if a command failed during the execution of those imperative commands in sequential order. Declarative is more descriptive and succinct and has the following major benefits:
- Describing your configuration via YAML file, which can be checked into version control
- Building with the end state in mind, without considering order or specific commands to run
- Having the efficiency and speed to get up and running through parallel actions
YAML is a human-readable language, also rendered for machines, so creating this configuration file is fairly simple. Most resources follow the same pattern and structure for YAML and how it’s made. Here’s an example of a file named my-pod-manifest.yaml:
apiVersion: v1 kind: Pod metadata: labels: run: nginx name: nginx spec: containers: - image: nginx name: nginx
These YAML files (called manifests) can be referred to years later, which is a good form of documenting how the application was built. Checking it into version control will allow you to track changes and work in teams to develop and enhance the configuration over time. You have the freedom to build applications running on Kubernetes with the end in mind. This is called goal seeking. You don’t have to be concerned about the path to reach that end state; you simply submit the YAML file to the Kubernetes API, and the API chooses the best path to complete your build.
Interestingly enough, submitting your file to the API is the same as performing a POST request to the API. Because everything running in your cluster is visible to the API, actions can be processed in parallel and will reach your end state faster. Here’s an example of running an imperative command (using kubectl) to create a Pod via the YAML file declaratively:
$ kubectl create -f my-pod-manifest.yaml pod/nginx created
There are three different ways you can submit this file to the Kubernetes API using kubectl—by using the command kubectl create -f my-pod-manifest.yaml, the command kubectl apply -f my-pod-manifest.yaml, or the command kubectl replace -f manifest.yaml. The create command expects that no resource has been created yet, and if otherwise, it will throw an error. The apply command, on the other hand, can be used to either create or update an existing resource. The replace command will delete the resource if it’s there and create an entirely new one as if you deleted the resource manually and then created a new one. Using the replace command on a Deployment, for example, will trigger a new rollout, where the Pods within that Deployment will be gracefully terminated and new Pod replicas will be spun up. We’ll talk about Deployments in more detail in chapter 4 and rollouts in chapter 5.
Idempotent is another important word to remember. The benefit of working with the Kubernetes API is that the state of the resources within will remain unchanged, no matter how many times the same call is made to the API. This creates consistency in your environment, and you know what to expect as your infrastructure and applications get increasingly complex over time.
Now that we’ve talked about Kubernetes to exhaustion and discussed the complexities and complications that we may or may not run into, let’s dive into the next chapter and get more hands-on with our approach to learning Kubernetes. After all, you’ll have your hands on the keyboard for the exam, so why not dive into practicing and simulating the exam experience? Roll up your sleeves!
settings

- Perform the command to list all API resources in your Kubernetes cluster. Save the output to a file named resources.csv.
- List the services on your Linux operating system that are associated with Kubernetes. Save the output to a file named services.csv.
- List the status of the kubelet service running on the Kubernetes node, output the result to a file named kubelet-status.txt, and save the file in the /tmp directory.
- Use the declarative syntax to create a Pod from a YAML file in Kubernetes. Save the YAML file as chap1-pod.yaml. Use the kubectl create command to create the Pod.
- Using the kubectl CLI tool, list all the Services created in your Kubernetes cluster across all namespaces. Save the output of the command to a file named all-k8s-services.txt.
In this chapter, you’ve met Kubernetes. You now know what Kubernetes looks like inside and out and what it’s commonly used for. You should also know the following:
- Kubernetes is an application that runs other applications and is built much like other RESTful web apps. The API is the central hub for authentication, authorization, and communication in the Kubernetes cluster.
- A cluster has many different components, including two main parts: a control plane, which is handled by the control plane nodes, and the worker nodes, which are responsible for running the workloads (i.e., the containerized applications running on top of Kubernetes).
- Linux system services are important in Kubernetes because they are responsible for keeping Kubernetes running on the host itself.
- You can access the cluster in two ways, programmatically or using a tool called kubectl, which both require a certificate to authenticate. This certificate is common in a PKI (public key infrastructure) system that checks in with the CA (certificate authority) to ensure that the certificate is valid and that communication can happen between components in the Kubernetes cluster.
- Kubernetes was built with microservices in mind, meaning that large microservice applications can run more efficiently in Kubernetes, being that each service is decoupled from the overall application.
- Running Services on Kubernetes is more efficient via a declarative approach. This way, we can describe what we want the end state to be, as opposed to running a set of imperative commands to achieve the same result.