Additional Updates
Some of the scenario questions here are based on Kodekloud's CKAD course labs.
CKAD and CKA can have similar scenario questions. It is recommended to go through the CKA practice tests.
Shortcuts
First run the two commands below for shortcuts.
export do="--dry-run=client -o yaml"
export now="--force --grace-period=0"
Questions
-
How many container images are in the host?
Answer
$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEredis latest eca1379fe8b5 8 months ago 117MBmysql latest 8189e588b0e8 8 months ago 564MBnginx latest 6efc10a0510f 8 months ago 142MBpostgres latest ceccf204404e 8 months ago 379MBnginx alpine 8e75cbc5b25c 9 months ago 41MBalpine latest 9ed4aefc74f6 9 months ago 7.04MBubuntu latest 08d22c0ceb15 10 months ago 77.8MBkodekloud/simple-webapp-mysql latest 129dd9f67367 5 years ago 96.6MBkodekloud/simple-webapp latest c6e3cd9aae36 5 years ago 84.8MB -
Build a docker image using the Dockerfile and name it webapp-color. No tag to be specified.
$ ls -ltotal 4drwxr-xr-x 4 root root 4096 Jan 6 04:18 webapp-color$ ls -l webapp-color/total 16-rw-r--r-- 1 root root 113 Jan 6 04:18 Dockerfile-rw-r--r-- 1 root root 2259 Jan 6 04:18 app.py-rw-r--r-- 1 root root 5 Jan 6 04:18 requirements.txtdrwxr-xr-x 2 root root 4096 Jan 6 04:18 templatesAnswer
$ docker build -t webapp-color webapp-color/Sending build context to Docker daemon 125.4kBStep 1/6 : FROM python:3.6---> 54260638d07cStep 2/6 : RUN pip install flask---> Using cache---> 94c3f6b51c29Step 3/6 : COPY . /opt/---> Using cache---> cd1ff9e242bbStep 4/6 : EXPOSE 8080---> Using cache---> 95dbaf915fbeStep 5/6 : WORKDIR /opt---> Using cache---> fb1706a0b0fcStep 6/6 : ENTRYPOINT ["python", "app.py"]---> Using cache---> ea2b85406064Successfully built ea2b85406064Successfully tagged webapp-color:latest$$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEwebapp-color latest ea2b85406064 About a minute ago 913MBredis latest eca1379fe8b5 8 months ago 117MBmysql latest 8189e588b0e8 8 months ago 564MB -
Run an instance of the image webapp-color and publish port 8080 on the container to 8282 on the host.
$ docker images | grep webappwebapp-color latest ea2b85406064 2 minutes ago 913MBAnswer
Use docker run, and then for exposing the port:
docker run -p <host-port>:<container:port>$ docker run -p 8282:8080 webapp-colorThis is a sample web application that displays a colored background.A color can be specified in two ways.1. As a command line argument with --color as the argument. Accepts one of red,green,blue,blue2,pink,darkblue2. As an Environment variable APP_COLOR. Accepts one of red,green,blue,blue2,pink,darkblue3. If none of the above then a random color is picked from the above list.Note: Command line argument precedes over environment variable.No command line argument or environment variable. Picking a Random Color =green* Serving Flask app 'app' (lazy loading)* Environment: productionWARNING: This is a development server. Do not use it in a production deployment.Use a production WSGI server instead.* Debug mode: off* Running on all addresses.WARNING: This is a development server. Do not use it in a production deployment.* Running on http://172.12.0.2:8080/ (Press CTRL+C to quit) -
What is the base Operating System used by the python:3.6 image?
$ docker images | grep pythonpython 3.6 54260638d07c 2 years ago 902MBAnswer
$ docker run python:3.6 cat /etc/*release*PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"NAME="Debian GNU/Linux"VERSION_ID="11"VERSION="11 (bullseye)"VERSION_CODENAME=bullseyeID=debianHOME_URL="https://www.debian.org/"SUPPORT_URL="https://www.debian.org/support"BUG_REPORT_URL="https://bugs.debian.org/" -
Build a new smaller docker image by modifying the same Dockerfile and name it webapp-color and tag it lite.
Find a smaller base image for python:3.6. Make sure the final image is less than 150MB.
Hint: Use python:3.6-alpine
$ cd webapp-color/$ ls -ltotal 16-rw-r--r-- 1 root root 113 Jan 6 04:18 Dockerfile-rw-r--r-- 1 root root 2259 Jan 6 04:18 app.py-rw-r--r-- 1 root root 5 Jan 6 04:18 requirements.txtdrwxr-xr-x 2 root root 4096 Jan 6 04:18 templates$$ cat DockerfileFROM python:3.6RUN pip install flaskCOPY . /opt/EXPOSE 8080WORKDIR /optENTRYPOINT ["python", "app.py"]Answer
Edit the Dockerfile.
FROM python:3.6-alpineRUN pip install flaskCOPY . /opt/EXPOSE 8080WORKDIR /optENTRYPOINT ["python", "app.py"]Build the image.
$ docker build -t webapp-color:lite .Sending build context to Docker daemon 125.4kBStep 1/6 : FROM python:3.6-alpine3.6-alpine: Pulling from library/python59bf1c3509f3: Pull complete8786870f2876: Pull completeacb0e804800e: Pull complete52bedcb3e853: Pull completeb064415ed3d7: Pull complete$ docker images | grep litewebapp-color lite a56a7c8ff6ff 15 seconds ago 51.9MB -
Run an instance of the new image webapp-color:lite and publish port 8080 on the container to 8383 on the host.
$ docker images | grep litewebapp-color lite a56a7c8ff6ff About a minute ago 51.9MBAnswer
docker run -p 8383:8080 webapp-color:lite -
I would like to use the dev-user to access test-cluster-1. Set the current context to the right one so I can do that.
controlplane ~ ➜ k config get-contexts --kubeconfig my-kube-configCURRENT NAME CLUSTER AUTHINFO NAMESPACEaws-user@kubernetes-on-aws kubernetes-on-aws aws-userresearch test-cluster-1 dev-user* test-user@development development test-usertest-user@production production test-userAnswer
controlplane ~ ➜ k config use-context research --kubeconfig my-kube-configSwitched to context "research".controlplane ~ ➜ k config get-contexts --kubeconfig my-kube-configCURRENT NAME CLUSTER AUTHINFO NAMESPACEaws-user@kubernetes-on-aws kubernetes-on-aws aws-user* research test-cluster-1 dev-usertest-user@development development test-usertest-user@production production test-user -
Inspect the environment and identify the authorization modes configured on the cluster.
Answer
controlplane ~ ✦ ➜ k get po -n kube-systemNAME READY STATUS RESTARTS AGEcoredns-5d78c9869d-5vk8b 1/1 Running 0 8m31scoredns-5d78c9869d-snn5g 1/1 Running 0 8m31setcd-controlplane 1/1 Running 0 8m38skube-apiserver-controlplane 1/1 Running 0 8m46skube-controller-manager-controlplane 1/1 Running 0 8m42skube-proxy-65s6j 1/1 Running 0 8m31skube-scheduler-controlplane 1/1 Running 0 8m43scontrolplane ~ ✦ ✖ k describe -n kube-system po kube-apiserver-controlplane | grep -i auth--authorization-mode=Node,RBAC--enable-bootstrap-token-auth=true -
What are the resources the kube-proxy role in the kube-system namespace is given access to?
Answer
controlplane ~ ✦ ➜ k get roles -A | grep kube-proxykube-system kube-proxy 2024-01-06T04:39:22Zcontrolplane ~ ✦ ➜ k describe role -n kube-system kube-proxyName: kube-proxyLabels: <none>Annotations: <none>PolicyRule:Resources Non-Resource URLs Resource Names Verbs--------- ----------------- -------------- -----configmaps [] [kube-proxy] [get] -
Which account is the kube-proxy role assigned to?
Answer
controlplane ~ ✦ ➜ k get rolebinding -A | grep kube-proxykube-system kube-proxy Role/kube-proxy 12mcontrolplane ~ ✦ ➜ k describe rolebinding -n kube-system kube-proxyName: kube-proxyLabels: <none>Annotations: <none>Role:Kind: RoleName: kube-proxySubjects:Kind Name Namespace---- ---- ---------Group system:bootstrappers:kubeadm:default-node-token -
Create the necessary roles and role bindings required for the dev-user to create, list and delete pods in the default namespace. Use the given spec:
-
Role: developer
-
Role Resources: pods
-
Role Actions: list
-
Role Actions: create
-
Role Actions: delete
-
RoleBinding: dev-user-binding
-
RoleBinding: Bound to dev-user
Answer
controlplane ~ ✦ ➜ k create role developer --verb "list,create,delete" --resource "pods" $doapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata:creationTimestamp: nullname: developerrules:- apiGroups:- ""resources:- podsverbs:- list- create- deletecontrolplane ~ ✦ ➜ k create role developer --verb "list,create,delete" --resource "pods"role.rbac.authorization.k8s.io/developer createdcontrolplane ~ ✦ ➜ k create rolebinding dev-user-binding --role developer --user dev-user $doapiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:creationTimestamp: nullname: dev-user-bindingroleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: developersubjects:- apiGroup: rbac.authorization.k8s.iokind: Username: dev-usercontrolplane ~ ✦ ➜ k create rolebinding dev-user-binding --role developer --user dev-userrolebinding.rbac.authorization.k8s.io/dev-user-binding created -
-
Which admission controller is enabled by default?
Answer
controlplane ~ ➜ k describe -n kube-system po kube-apiserver-controlplane | grep -i admission--enable-admission-plugins=NodeRestriction -
NamespaceExists admission controller enabled which rejects requests to namespaces that do not exist. So, to create a namespace that does not exist automatically, we could enable the NamespaceAutoProvision admission controller
Enable the NamespaceAutoProvision admission controller.
Answer
controlplane ~ ➜ ls -l /etc/kubernetes/manifests/total 16-rw------- 1 root root 2399 Jan 6 00:08 etcd.yaml-rw------- 1 root root 3877 Jan 6 00:08 kube-apiserver.yaml-rw------- 1 root root 3393 Jan 6 00:08 kube-controller-manager.yaml-rw------- 1 root root 1463 Jan 6 00:08 kube-scheduler.yamlcontrolplane ~ ➜ cd /etc/kubernetes/manifests/Modify the kube-apiserver YAML file.
apiVersion: v1kind: Podmetadata:annotations:kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.7.174.8:6443creationTimestamp: nulllabels:component: kube-apiservertier: control-planename: kube-apiservernamespace: kube-systemspec:containers:- command:- kube-apiserver- --advertise-address=192.7.174.8- --allow-privileged=true- --authorization-mode=Node,RBAC- --client-ca-file=/etc/kubernetes/pki/ca.crt- --enable-admission-plugins=NodeRestriction,NamespaceAutoProvisionOnce you update kube-apiserver yaml file, please wait for a few minutes for the kube-apiserver to restart completely.
controlplane /etc/kubernetes/manifests ➜ k get po -n kube-systemNAME READY STATUS RESTARTS AGEcoredns-5d78c9869d-bqnjq 1/1 Running 0 14mcoredns-5d78c9869d-wxjg5 1/1 Running 0 14metcd-controlplane 1/1 Running 0 14mkube-apiserver-controlplane 0/1 Pending 0 8skube-controller-manager-controlplane 1/1 Running 1 (33s ago) 14mkube-proxy-jld6s 1/1 Running 0 14mkube-scheduler-controlplane 1/1 Running 1 (32s ago) 14mVerify:
controlplane /etc/kubernetes/manifests ➜ k get nsNAME STATUS AGEdefault Active 15mkube-flannel Active 15mkube-node-lease Active 15mkube-public Active 15mkube-system Active 15mcontrolplane /etc/kubernetes/manifests ➜ k run nginx --image nginx -n testingpod/nginx createdcontrolplane /etc/kubernetes/manifests ➜ k get nsNAME STATUS AGEdefault Active 15mkube-flannel Active 15mkube-node-lease Active 15mkube-public Active 15mkube-system Active 15mtesting Active 3s -
Disable DefaultStorageClass admission controller This admission controller observes creation of PersistentVolumeClaim objects that do not request any specific storage class and automatically adds a default storage class to them. This way, users that do not request any special storage class do not need to care about them at all and they will get the default one.
Answer
apiVersion: v1kind: Podmetadata:annotations:kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.7.174.8:6443creationTimestamp: nulllabels:component: kube-apiservertier: control-planename: kube-apiservernamespace: kube-systemspec:containers:- command:- kube-apiserver- --advertise-address=192.7.174.8- --allow-privileged=true- --authorization-mode=Node,RBAC- --client-ca-file=/etc/kubernetes/pki/ca.crt- --enable-admission-plugins=NodeRestriction,NamespaceAutoProvision- --disable-admission-plugins=DefaultStorageClass -
Create TLS secret webhook-server-tls for secure webhook communication in webhook-demo namespace.
-
Certificate : /root/keys/webhook-server-tls.crt
-
Key : /root/keys/webhook-server-tls.key
Answer
controlplane ~ ➜ k create secret tls webhook-server-tls --namespace webhook-demo --cert /root/keys/webhook-server-tls.crt --key /root/keys/webhook-server-tls.keysecret/webhook-server-tls createdcontrolplane ~ ➜ k get secrets -n webhook-demoNAME TYPE DATA AGEwebhook-server-tls kubernetes.io/tls 2 8s -
-
Enable the v1alpha1 version for rbac.authorization.k8s.io API group on the controlplane node.
-
Create a custom resource called datacenter and the apiVersion should be traffic.controller/v1.
Set the dataField length to 2 and access permission should be true
Answer
## datacenter.ymlkind: GlobalapiVersion: traffic.controller/v1metadata:name: datacenterspec:dataField: 2access: truecontrolplane ~ ➜ k apply -f datacenter.ymlglobal.traffic.controller/datacenter createdcontrolplane ~ ➜ k get globalNAME AGEdatacenter 64s -
A deployment has been created in the default namespace. What is the deployment strategy used for this deployment?
controlplane ~ ➜ k get deployments.appsNAME READY UP-TO-DATE AVAILABLE AGEfrontend 5/5 5 5 95sAnswer
controlplane ~ ➜ k describe deployments.apps frontend | grep -i strategyStrategyType: RollingUpdateRollingUpdateStrategy: 25% max unavailable, 25% max surge -
What is the selector used by the frontend-service service?
controlplane ~ ➜ k get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEfrontend-service NodePort 10.104.213.172 <none> 8080:30080/TCP 2m26skubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7m27sAnswer
controlplane ~ ➜ k describe svc frontend-service | grep -i selectorSelector: app=frontend -
A new deployment called frontend-v2 has been created in the default namespace using the image kodekloud/webapp-color:v2. This deployment will be used to test a newer version of the same app.
Configure the deployment in such a way that the service called frontend-service routes less than 20% of traffic to the new deployment.
Do not increase the replicas of the frontend deployment.
controlplane ~ ➜ k get deployments.appsNAME READY UP-TO-DATE AVAILABLE AGEfrontend 5/5 5 5 4m23sfrontend-v2 2/2 2 2 21sAnswer
The frontend deployment currently has 7 replicas The frontend-v2 deployment currently has 2 replicas In total, there are 7 replicas or 7 pods.
The frontend-service distributes the traffice to all 7 pods equally, which means:
-
per 1 pod = 14.28% of the traffic
-
frontend deployment: 5 pods = 71.4% of the traffic
-
frontend-v2 deployment: 2 pods = 28.56% of the traffic
If we want to reduce the percent of traffic being directed to frontend-v2 deployment, scale down the replica to 2, which means:
-
per 1 pod = 16.66% of the traffic
-
frontend deployment: 5 pods = 83.3% of the traffic
-
frontend-v2 deployment: 2 pods = 16.66% of the traffic
Scale down the frontend-v2 to 1 replica.
controlplane ~ ➜ k scale deployment frontend-v2 --replicas 1deployment.apps/frontend-v2 scaledcontrolplane ~ ➜ k get deployments.appsNAME READY UP-TO-DATE AVAILABLE AGEfrontend 5/5 5 5 5m47sfrontend-v2 1/1 1 1 105s -
-
Search for a wordpress helm chart package from the Artifact Hub.
Answer
controlplane ~ ➜ helm search --helpUsage:helm search [command]Available Commands:hub search for charts in the Artifact Hub or your own hub instancerepo search repositories for a keyword in chartscontrolplane ~ ➜ helm search hub --helpUsage:helm search hub [KEYWORD] [flags]helm search hub wordpress -
Add a bitnami helm chart repository in the controlplane node.
-
name - bitnami
-
chart repo name - https://charts.bitnami.com/bitnami
Answer
controlplane ~ ➜ helm repo add --helpadd a chart repositoryUsage:helm repo add [NAME] [URL] [flags]controlplane ~ ➜ helm repo add bitnami https://charts.bitnami.com/bitnami"bitnami" has been added to your repositoriescontrolplane ~ ➜ helm listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONcontrolplane ~ ➜ helm repo listNAME URLbitnami https://charts.bitnami.com/bitnami -
-
What command is used to search for the joomla package from the added repository?
Answer
controlplane ~ ➜ helm repo listNAME URLbitnami https://charts.bitnami.com/bitnamicontrolplane ~ ➜ helm search --helpSearch provides the ability to search for Helm charts in the various placesthey can be stored including the Artifact Hub and repositories you have added.Use search subcommands to search different locations for charts.Usage:helm search [command]Available Commands:hub search for charts in the Artifact Hub or your own hub instancerepo search repositories for a keyword in chartscontrolplane ~ ➜ helm search repo joomlaNAME CHART VERSION APP VERSION DESCRIPTIONbitnami/joomla 18.0.0 5.0.1 Joomla! is an award winning open source CMS pla... -
Install drupal helm chart from the bitnami repository.
-
Release name should be bravo.
-
Chart name should be bitnami/drupal.
Answer
controlplane ~ ➜ helm install --helpUsage:helm install [NAME] [CHART] [flags]controlplane ~ ➜ helm install bitnami/drupal bravoError: INSTALLATION FAILED: non-absolute URLs should be in form of repo_name/path_to_chart, got: bravocontrolplane ~ ➜ helm install bravo bitnami/drupalNAME: bravoLAST DEPLOYED: Sat Jan 6 02:43:29 2024NAMESPACE: defaultSTATUS: deployedREVISION: 1TEST SUITE: NoneNOTES:CHART NAME: drupalCHART VERSION: 17.0.0APP VERSION: 10.2.0** Please be patient while the chart is being deployed ** -
-
Uninstall the drupal helm package which was installed in the previous question.
Answer
controlplane ~ ➜ helm uninstall bravorelease "bravo" uninstalled -
Download the bitnami apache package under the /root directory. Note: Do not install the package. Just download it.
controlplane ~ ➜ helm repo listNAME URLbitnami https://charts.bitnami.com/bitnamipuppet https://puppetlabs.github.io/puppetserver-helm-charthashicorp https://helm.releases.hashicorp.comAnswer
controlplane ~ ➜ helm search repo apacheNAME CHART VERSION APP VERSION DESCRIPTIONbitnami/apache 10.2.4 2.4.58 Apache HTTP Server is an open-source HTTP serve...bitnami/airflow 16.1.10 2.8.0 Apache Airflow is a tool to express and execute...bitnami/apisix 2.2.8 3.7.0 Apache APISIX is high-performance, real-time AP...bitnami/cassandra 10.6.8 4.1.3 Apache Cassandra is an open source distributed ...bitnami/dataplatform-bp2 12.0.5 1.0.1 DEPRECATED This Helm chart can be used for the ...bitnami/flink 0.5.3 1.18.0 Apache Flink is a framework and distributed pro...bitnami/geode 1.1.8 1.15.1 DEPRECATED Apache Geode is a data management pl...bitnami/kafka 26.6.2 3.6.1 Apache Kafka is a distributed streaming platfor...bitnami/mxnet 3.5.2 1.9.1 DEPRECATED Apache MXNet (Incubating) is a flexi...bitnami/schema-registry 16.2.6 7.5.3 Confluent Schema Registry provides a RESTful in...bitnami/solr 8.3.4 9.4.0 Apache Solr is an extremely powerful, open sour...bitnami/spark 8.1.7 3.5.0 Apache Spark is a high-performance engine for l...bitnami/tomcat 10.11.10 10.1.17 Apache Tomcat is an open-source web server desi...bitnami/zookeeper 12.4.1 3.9.1 Apache ZooKeeper provides a reliable, centraliz...controlplane ~ ➜ helm pull --helpRetrieve a package from a package repository, and download it locally.Usage:helm pull [chart URL | repo/chartname] [...] [flags]controlplane ~ ➜ helm pull bitnami/apachecontrolplane ~ ➜ ls -ltotal 36-rw-r--r-- 1 root root 35248 Jan 6 02:48 apache-10.2.4.tgzcontrolplane ~ ➜ tar -xf apache-10.2.4.tgzcontrolplane ~ ➜ ls -ltotal 40drwxr-xr-x 5 root root 4096 Jan 6 02:49 apache-rw-r--r-- 1 root root 35248 Jan 6 02:48 apache-10.2.4.tgz