~ cka prep


Table of Contents

1. Exam Details

It is essential that you become one with `kubectl`, `kubeadm`, and `etcdctl`

When killing objects you may want to not wait for it to be shut down gracefully, you can use `--force` to kill the object.

2. Cluster Architecture, Installation and Configuration

Typical tasks you would expect a k8s admin to know, understanding the architectural components, setting up a cluster from scratch, and maintaining a cluster going forward

Role-Based Access Control (RBAC)

To control who can access what on the cluster we need to establish certain policies

RBAC defines policies for users, groups and processes, by letting them (or disallowing them) to manage certain API resources.

RBAC has 3 building blocks:

Creating a Subject

Users and groups are not stored in `etcd` (the k8s db), they are meant for processes running outside of the cluster. On the other hand, service accounts are k8s objects and are used by processes running inside of the cluster.

User accounts and groups

As stated before there is no k8s object for user, instead the job of creating the credential and distributing to the users is done externally by the admin.

There are different ways k8s can authenticate a user:

You wont have to create a user in the exam, but here are the steps for creating one using the OpenSSL method.

  1. Go to k8s control plane node and create a temporary dir that will have the keys.

    mkdir cert && cd cert
  2. Create a private key using openssl (username.key)

    openssl genrsa -out johndoe.key 2048
  3. Create a cerficiate sign request (a .csr file) with the key from the previous step

    openssl req -new -key johndoe.key -out johndoe.csr -subj "/CN=johndoe/O=cka-study-guide"
  4. Sign the .csr with the k8s CA (it usually is under /etc/kubernetes/pki)

    openssl x509 -req -in johndoe.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out johndoe.crt -days 364
  5. Add it to your kubeconfig file

    kubectl config set-credentials johndoe --client-certificate=johndoe.crt --client-key=johndoe.key

ServiceAccount

The users we created in the last paragraphs are meant to be used by humans, if a pod or a svc needs to authenticate against the k8s cluster we need to create a service account.

A k8s cluster already comes with a `sa` called default. Any pod that does not explicitly assign a service account uses the default service account

It is super simple to create one with the imperative approach

$ k create sa build-bot

When creating a service account a secret holding the API token will be created too. The Secret and token names use the Service Account name as a prefix.

To assing a service account to a pod you can do it imperatively by:

$ k run build-observer --image=alpine --restart=Never --serviceaccount=build-bot

Or add it to the manifest under `spec.serviceAccountName`.

vvv One more important thing. vvv

If you want to make a call to k8s api from within a pod using your serviceaccount. You will need to create a token, and then do the requests using the internal dns.

Roles and RoleBindings

We have these two primitives:

There are some default roles:

Creating Roles and RoleBindings

Imperative mode for roles.

k create role read-only --verb=list,get,watch --resource=pods,deployments,services

There is also `--resource-name` as a flag, where you can specify names of pods.

Imperative mode for rolebindings.

$ k create rolebinding read-only-binding --role=read-only --user=johndoe

If then you do a `get` you wont see the subject, you need to render the details to see that.

You can of course use `describe` and so on to check each of the primitives once created, but there is also this little neat command: $ k auth can-i this will give specific info on user permissions

$ kubectl auth can-i --list --as johndoe

$ kubectl auth can-i list pods --as johndoe

Yes

Cluster Role

Roles and RoleBinding are namespace specific. If we want to define the same but for the whole cluster we need to use ClusterRole and ClusterRoleBinding. The configuration elements are the same.

Aggregating RBAC Rules

Finally, we can aggregate different roles with label selection. Say you have one role that lets you list pods, and other that lets you delete pods.

You can aggregate them with an `aggregationRule`

Here is an example from Benjamin Muschko's Oreilly's Certified Kubernetes Administrator (CKA) Study Guide.

YAML manifest for listing pods

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: list-pods
  namespace: rbac-example
  labels:
    rbac-pod-list: "true"
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - list

YAML manifest for deleting svc's

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: delete-services
  namespace: rbac-example
  labels:
    rbac-service-delete: "true"
rules:
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - delete

YAML manifest aggregating them.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pods-services-aggregation-rules
  namespace: rbac-example
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac-pod-list: "true"
  - matchLabels:
      rbac-service-delete: "true"
rules: []

Creating and Managing a K8s Cluset

Common tasks an admin is expected to perform are:

For bootstrapping oprations we use `kubeadm`. You will need to provision the underlying infra before, using ansible or terraform.

For the exam you can expect `kubeadm` to be installed already.

To start a cluster basically on your master machine, you need on have a container runtime up and running, such as `containerd`. Then you follow some steps:

Highly Available Cluster

If we have a cluster, with just one node as a control plane, it can become risky. If the control plane node dies, we are not going to be able to talk with k8s API; neither the workers.

There is this concept of High-availability (HA) clusters, these help with scalability and redundancy. Due to the complexity of setting them up, it is not likely you are going to have to perform the steps during the exam. But this talks about the idea of having multiple control planes nodes. There are different architectures, here I will briefly explain some.

Stacked etcd topology

This involves creating two or more control plane nodes where etcd is located inside the node. These will talk to the workers via a load balancer.

External etcd topology

This involves creating two or more control plane nodes where etcd is located outside the node. These will talk to the workers via a load balancer. Do note that for these you need a extra node per control plane. Since we will have an etcd node per control node.

The main difference is that etcd is outside the control nodes, so if a control node fails, etcd will still be there.

Upgrade k8s version

Only upgrade from a minor version to a next higher one. 1.18 -> 1.19 , or from a patch version to a higher one. 1.18.0 -> 1.18.3. Abstain from jumping up multiple minor versions, to avoid unexpected side effects.

Upgrade Control Planes

If you are managing a high available cluster, you need to upgrade one control plane node at a time.

  1. ssh to the control plane

  2. get current version, you can do `k get nodes`

  3. upgrade kubeadm to the version you want with your package manager.

    sudo apt-get install -y kubeadm=1.19.0-00
            
  4. Check which versions are available to upgrade to

    $ sudo kubeadm upgrade plan
    ...
    [upgrade] Fetching available versions to upgrade to
    [upgrade/versions] Cluster version: v1.18.20
    [upgrade/versions] kubeadm version: v1.19.0
    I0708 17:32:53.037895   17430 version.go:252] remote version is much newer: \
    v1.21.2; falling back to: stable-1.19
    [upgrade/versions] Latest stable version: v1.19.12
    [upgrade/versions] Latest version in the v1.18 series: v1.18.20
    ...
    You can now apply the upgrade by executing the following command:
    
    	kubeadm upgrade apply v1.19.12
    
    Note: Before you can perform this upgrade, you have to update kubeadm to v1.19.12.
    ...
            
  5. upgrade it `sudo kubeadm upgrade apply v1.19.0`

  6. we need to drain the node.

    if the concept of drain is new to you, you are not alone, it basically means, that the given node will be marked unschedulable to prevent new pods from arriving.

    kubectl drain kube-control-plane --ignore-daemonsets
            
  7. Upgrade kubelet and kubectl to the same version. Again, using your package manager.

  8. Restart and reaload `kubelet` process using systemclt

  9. Mark node as schedulable again

    `k uncordon kube-control-plane`

  10. If you do `k get nodes` again now you should see that node with the new version.

Upgrade Worker nodes

  1. ssh to the node

  2. upgrade kubeadm using your package manager

  3. upgrade the node using kubeadm

    sudo kubeadm upgrade node
            
  4. we need to drain (make it unscheduable) the node.

    kubectl drain worker-node --ignore-daemonsets
            
  5. Upgrade kubelet and kubectl to the same version.

  6. Restart and reaload `kubelet` process using systemclt

  7. Mark node as schedulable again

    `k uncordon worker-node`

  8. If you do `k get nodes` again now you should see that node with the new version.

Backing up and Restoring etcd

`etcd` is where k8s stores both the declared and observed states of the cluster. It uses a distributed key-value store.

It is important to have a backup, in case of some issue. The backup process should happen periodically and in short time frames.

We will use the etcdctl tool to do this.:

Backup Process

  1. ssh into the control pane

  2. check you have a higher than 3.4 etcdctl version installed

  3. Get and describe the pod etcd is running

    `k get pods -n kube-system`

    `k describe pod etcd-smth l-n kube-system`

  4. Look for the value under --listen-client-urls. We are going to need to the path for the server.crt, .key, and the ca.crt.

    $ sudo ETCDCTL_API=3 etcdctl
      --cacert= --cert= --key= \
      snapshot save 
            

    It would look something like this:

    sudo ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
      --cert=/etc/kubernetes/pki/etcd/server.crt \
      --key=/etc/kubernetes/pki/etcd/server.key \
      snapshot save /opt/etcd-backup.db
            
  5. Store the backup in a safe place

Restore Process

  1. ssh into the system

  2. run the `snapshot restore` command

    sudo ETCDCTL_API=3 etcdctl --data-dir=/var/lib/from-backup snapshot restore \
      /opt/etcd-backup.db
            
  3. Now we need to change the etcd manifest, to point to our backup

    It is mounted as a volume, with the `etcd-data` name.

    These manifests are declared under /etc/kubernetes/manifests. The pod will be re-created (automatically?) pointing to the backup directory

Essentials for Exam

3. Troubleshooting

Cluster Logging

Since we will have a node logs, pods logs, container logs it makes sense to think about how we will handle these streams. In a cluster, logs should have a separate storage and lifecycle independent of nodes, pods or containers. This process is called cluster-level logging.

One other thing worth mentioning, log rotation, the kubelet daemon is responsible for rotating container logs and managing the logging directory structure. It tells the container runtime where to write container logs.

You can configure `containerLogMaxSize` (max size of file) and `containerLogMaxFiles` (how many log files can be created)

So for Cluster-Level logging we have these options:

Troubleshooting Pods

Creating a Pod is pretty simple, as long as the yaml is right k8s will try to create it. Nevertheless we need to verify the correct behaviour. The first thing is to verify the high-level runtime information of the Pod.

Check the resources, the deployment, the pods, check the status column. Check the number of restarts.

If the number of restarts is greater than 0, then you might want to check the logic of the liveness probe. Identify why the restart was necessary.

Here are some of the common status errors that one might come across.

So a quick list on what to do:

Troubleshooting Services


~ Table of Contents

↑ go to the top