Networking
Some of the scenario questions here are based on Kodekloud's CKA course labs.
CKAD and CKA can have similar scenario questions. It is recommended to go through the CKAD 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
-
What is the Internal IP address of the controlplane node in this cluster?
controlplane ~ ➜ k get noNAME STATUS ROLES AGE VERSIONcontrolplane Ready control-plane 15m v1.27.0node01 Ready <none> 14m v1.27.0Answer
controlplane ~ ➜ k describe no controlplane | grep -i ipflannel.alpha.coreos.com/public-ip: 192.2.53.9InternalIP: 192.2.53.9 -
What is the network interface configured for cluster connectivity on the controlplane node?
controlplane ~ ➜ k get noNAME STATUS ROLES AGE VERSIONcontrolplane Ready control-plane 15m v1.27.0node01 Ready <none> 14m v1.27.0Answer
controlplane ~ ➜ k get no -o wideNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIMEcontrolplane Ready control-plane 20m v1.27.0 192.2.120.9 <none> Ubuntu 20.04.6 LTS 5.4.0-1106-gcp containerd://1.6.6node01 Ready <none> 19m v1.27.0 192.2.120.12 <none> Ubuntu 20.04.5 LTS 5.4.0-1106-gcp containerd://1.6.6controlplane ~ ➜ ip addr | grep -B2 192.213036: eth0@if13037: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group defaultlink/ether 02:42:c0:02:78:09 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 192.2.120.9/24 brd 192.2.120.255 scope global eth0 -
What is the MAC address assigned to node01?
controlplane ~ ➜ k get noNAME STATUS ROLES AGE VERSIONcontrolplane Ready control-plane 15m v1.27.0node01 Ready <none> 14m v1.27.0Answer
Need to ssh to node01.
controlplane ~ ➜ ssh node01root@node01 ~ ➜ ip addr | grep -B2 192.213945: eth0@if13946: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group defaultlink/ether 02:42:c0:02:78:0c brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 192.2.120.12/24 brd 192.2.120.255 scope global eth0 -
We use Containerd as our container runtime. What is the interface/bridge created by Containerd on the controlplane node?
Answer
controlplane ~ ✖ ip link show | grep -i cni3: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP mode DEFAULT group default qlen 10004: vethcb46d51e@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue master cni0 state UP mode DEFAULT group defaultlink/ether 46:15:1c:5b:93:f2 brd ff:ff:ff:ff:ff:ff link-netns cni-3f59b276-21d3-2b70-df1a-514e9f7eb6cb5: veth35f1d3bb@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue master cni0 state UP mode DEFAULT group defaultlink/ether 96:21:56:39:34:10 brd ff:ff:ff:ff:ff:ff link-netns cni-d15387ac-89be-7f41-ecb3-79879ae016f1 -
If you were to ping google from the controlplane node, which route does it take?
controlplane ~ ➜ k get noNAME STATUS ROLES AGE VERSIONcontrolplane Ready control-plane 15m v1.27.0node01 Ready <none> 14m v1.27.0Answer
controlplane ~ ➜ ip routedefault via 172.25.0.1 dev eth1 -
What is the port the kube-scheduler is listening on in the controlplane node?
Answer
controlplane ~ ➜ netstat -tulpn | grep -i schedtcp 0 0 127.0.0.1:10259 0.0.0.0:* LISTEN 3706/kube-scheduler -
Notice that ETCD is listening on two ports. Which of these have more client connections established?
Answer
2379 is the port of ETCD to which all control plane components connect to. 2380 is only for etcd peer-to-peer connectivity when you have multiple controlplane nodes.
controlplane ~ ➜ netstat -tulpn | grep -i etctcp 0 0 192.2.120.9:2379 0.0.0.0:* LISTEN 3723/etcdtcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 3723/etcdtcp 0 0 192.2.120.9:2380 0.0.0.0:* LISTEN 3723/etcdtcp 0 0 127.0.0.1:2381 0.0.0.0:* LISTEN 3723/etcdcontrolplane ~ ➜ netstat -anp | grep etc | grep 2379 | wc -l63controlplane ~ ➜ netstat -anp | grep etc | grep 2380 | wc -l1controlplane ~ ➜ netstat -anp | grep etc | grep 2381 | wc -l1 -
Inspect the kubelet service and identify the container runtime endpoint value is set for Kubernetes.
Answer
Answer is unix:///var/run/containerd/containerd.sock.
controlplane ~ ➜ ps -aux | grep kubelet | grep containerroot 4685 0.0 0.0 3702540 101388 ? Ssl 20:02 0:12 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock --pod-infracontainer-image=registry.k8s.io/pause:3.9 -
What is the path configured with all binaries of CNI supported plugins?
Answer
controlplane ~ ➜ ls -la /opt/cnitotal 20drwxr-xr-x 1 root root 4096 Nov 2 11:33 .drwxr-xr-x 1 root root 4096 Nov 2 11:38 ..drwxrwxr-x 1 root root 4096 Dec 30 20:02 bincontrolplane ~ ➜ ls -la /opt/cni/bin/total 71424drwxrwxr-x 1 root root 4096 Dec 30 20:02 .drwxr-xr-x 1 root root 4096 Nov 2 11:33 ..-rwxr-xr-x 1 root root 3859475 Jan 16 2023 bandwidth-rwxr-xr-x 1 root root 4299004 Jan 16 2023 bridge-rwxr-xr-x 1 root root 10167415 Jan 16 2023 dhcp-rwxr-xr-x 1 root root 3986082 Jan 16 2023 dummy-rwxr-xr-x 1 root root 4385098 Jan 16 2023 firewall-rwxr-xr-x 1 root root 2474798 Dec 30 20:02 flannel-rwxr-xr-x 1 root root 3870731 Jan 16 2023 host-device-rwxr-xr-x 1 root root 3287319 Jan 16 2023 host-local-rwxr-xr-x 1 root root 3999593 Jan 16 2023 ipvlan-rwxr-xr-x 1 root root 3353028 Jan 16 2023 loopback-rwxr-xr-x 1 root root 4029261 Jan 16 2023 macvlan-rwxr-xr-x 1 root root 3746163 Jan 16 2023 portmap-rwxr-xr-x 1 root root 4161070 Jan 16 2023 ptp-rwxr-xr-x 1 root root 3550152 Jan 16 2023 sbr-rwxr-xr-x 1 root root 2845685 Jan 16 2023 static-rwxr-xr-x 1 root root 3437180 Jan 16 2023 tuning-rwxr-xr-x 1 root root 3993252 Jan 16 2023 vlan-rwxr-xr-x 1 root root 3586502 Jan 16 2023 vrf -
What is the CNI plugin configured to be used on this kubernetes cluster?
Answer
controlplane ~ ➜ ls -la /etc/cni/total 20drwx------ 1 root root 4096 Nov 2 11:33 .drwxr-xr-x 1 root root 4096 Dec 30 20:02 ..drwx------ 1 root root 4096 Dec 30 20:02 net.dcontrolplane ~ ➜ ls -la /etc/cni/net.d/total 16drwx------ 1 root root 4096 Dec 30 20:02 .drwx------ 1 root root 4096 Nov 2 11:33 ..-rw-r--r-- 1 root root 292 Dec 30 20:02 10-flannel.conflist -
What binary executable file will be run by kubelet after a container and its associated namespace are created?
-
What binary executable file will be run by kubelet after a container and its associated namespace are created?
Answer
controlplane ~ ➜ ls -l /etc/cni/total 4drwx------ 1 root root 4096 Dec 30 20:02 net.dcontrolplane ~ ➜ ls -l /etc/cni/net.d/total 4-rw-r--r-- 1 root root 292 Dec 30 20:02 10-flannel.conflistThe answer is flannel.
controlplane ~ ✖ cat /etc/cni/net.d/10-flannel.conflist{"name": "cbr0","cniVersion": "0.3.1","plugins": [{"type": "flannel","delegate": {"hairpinMode": true,"isDefaultGateway": true}},{"type": "portmap","capabilities": {"portMappings": true}}]} -
Deploy weave-net networking solution to the cluster.
NOTE: - We already have provided a weave manifest file under the /root/weave directory.
Answer
The pod cannot start because networking is not yet configured.
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEapp 1/1 ContainerCreating 0 3m7sInstall weavenet via the weave manifest.
controlplane ~ ➜ ls -la /root/weave/total 20drwxr-xr-x 2 root root 4096 Dec 30 20:21 .drwx------ 1 root root 4096 Dec 30 20:20 ..-rw-r--r-- 1 root root 6259 Dec 30 20:21 weave-daemonset-k8s.yamlcontrolplane ~ ➜ k apply -f /root/weave/serviceaccount/weave-net createdclusterrole.rbac.authorization.k8s.io/weave-net createdclusterrolebinding.rbac.authorization.k8s.io/weave-net createdrole.rbac.authorization.k8s.io/weave-net createdrolebinding.rbac.authorization.k8s.io/weave-net createddaemonset.apps/weave-net createdThe app should now be able to run.
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEapp 1/1 Running 0 3m7s -
What is the Networking Solution used by this cluster?
Answer
controlplane ~ ➜ ls -la /etc/cni/net.d/total 16drwx------ 1 root root 4096 Dec 30 22:19 .drwx------ 1 root root 4096 Nov 2 11:33 ..-rw-r--r-- 1 root root 318 Dec 30 22:19 10-weave.conflistcontrolplane ~ ➜ cat /etc/cni/net.d/10-weave.conflist{"cniVersion": "0.3.0","name": "weave","plugins": [{"name": "weave","type": "weave-net","hairpinMode": true},{"type": "portmap","capabilities": {"portMappings": true},"snat": true}]} -
How many weave agents/peers are deployed in this cluster?
Answer
controlplane ~ ➜ k get po -n kube-systemNAME READY STATUS RESTARTS AGEcoredns-5d78c9869d-g5r7l 1/1 Running 0 24mcoredns-5d78c9869d-kbzrl 1/1 Running 0 24metcd-controlplane 1/1 Running 0 24mkube-apiserver-controlplane 1/1 Running 0 24mkube-controller-manager-controlplane 1/1 Running 0 24mkube-proxy-6rzbz 1/1 Running 0 24mkube-proxy-bqhf2 1/1 Running 0 24mkube-scheduler-controlplane 1/1 Running 0 24mweave-net-mq78f 2/2 Running 1 (23m ago) 24mweave-net-pxrzs 2/2 Running 1 (23m ago) 24mcontrolplane ~ ➜ k get po -n kube-system -o wide ñ grep weaveweave-net-mq78f 2/2 Running 1 (24m ago) 24m 192.5.179.12 node01 <none> <none>weave-net-pxrzs 2/2 Running 1 (24m ago) 24m 192.5.179.9 controlplane <none> <none> -
Identify the name of the bridge network/interface created by weave on each node.
Answer
controlplane ~ ➜ ip addr | grep weave4: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default qlen 1000inet 10.244.192.0/16 brd 10.244.255.255 scope global weave7: vethwe-bridge@vethwe-datapath: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue master weave state UP group default10: vethwepl4a7ab64@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue master weave state UP group default12: vethwepl6d8c184@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue master weave state UP group default -
What is the default gateway configured on the PODs scheduled on node01?
Answer
We are interested with the route for weave, which shows default gateway of 10.244.0.1.
root@node01 ~ ➜ ip routedefault via 172.25.0.1 dev eth110.244.0.0/16 dev weave proto kernel scope link src 10.244.0.1172.25.0.0/24 dev eth1 proto kernel scope link src 172.25.0.35192.5.179.0/24 dev eth0 proto kernel scope link src 192.5.179.12 -
What is the range of IP addresses configured for PODs on this cluster? The network is configured with weave.
Answer
Check the pod for weave and see the logs. It should show the ip allocation range.
controlplane ~ ➜ k get po -n kube-systemNAME READY STATUS RESTARTS AGEcoredns-5d78c9869d-9qdz4 1/1 Running 0 28mcoredns-5d78c9869d-qzd27 1/1 Running 0 28metcd-controlplane 1/1 Running 0 28mkube-apiserver-controlplane 1/1 Running 0 28mkube-controller-manager-controlplane 1/1 Running 0 28mkube-proxy-gq9zh 1/1 Running 0 28mkube-proxy-p6fhm 1/1 Running 0 28mkube-scheduler-controlplane 1/1 Running 0 28mweave-net-5djnr 2/2 Running 0 28mweave-net-wcmwp 2/2 Running 1 (28m ago) 28mcontrolplane ~ ➜ k logs -n kube-system weave-net-5djnr | grep -i ipDefaulted container "weave" out of: weave, weave-npc, weave-init (init)INFO: 2023/12/31 03:24:40.683471 Command line options: map[conn-limit:200 datapath:datapath db-prefix:/weavedb/weave-net docker-api: expect-npc:true http-addr:127.0.0.1:6784 ipalloc-init:consensus=1 ipalloc-range:10.244.0.0/16 metrics-addr:0.0.0.0:6782 name:62:53:38:78:b6:a0 nickname:node01 no-dns:true no-masq-local:true port:6783] -
What is the IP Range configured for the services within the cluster?
Answer
From here we can see the the servuces are configured in the 10.96.0.x range.
controlplane ~ ➜ k get svc -ANAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdefault kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 31mkube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 31mWe can also check the manifest for the kub-apiserver.
controlplane ~ ➜ ls -l /etc/kubernetes/manifests/kube-apiserver.yaml-rw------- 1 root root 3877 Dec 30 22:23 /etc/kubernetes/manifests/kube-apiserver.yamlcontrolplane ~ ➜ grep -i ip /etc/kubernetes/manifests/kube-apiserver.yaml- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname- --service-cluster-ip-range=10.96.0.0/12 -
What type of proxy is the kube-proxy configured to use?
Answer
controlplane ~ ➜ k get po -n kube-system | grep kube-proxykube-proxy-gq9zh 1/1 Running 0 35mkube-proxy-p6fhm 1/1 Running 0 36mcontrolplane ~ ➜ k logs -n kube-system kube-proxy-gq9zh | grep -i proxyI1231 03:24:13.560888 1 server_others.go:551] "Using iptables proxy" -
How does this Kubernetes cluster ensure that a kube-proxy pod runs on all nodes in the cluster?
Answer
kube-proxy is managed through a DaemonSet.
controlplane ~ ➜ k get po -n kube-system | grep kube-prokube-proxy-gq9zh 1/1 Running 0 40mkube-proxy-p6fhm 1/1 Running 0 40mcontrolplane ~ ➜ k describe pod -n kube-system kube-proxy-gq9zh | grep -i controlLabels: controller-revision-hash=7b6c5596fcControlled By: DaemonSet/kube-proxy -
Identify the DNS solution implemented in this cluster.
Answer
controlplane ~ ✖ k get po -A | grep dnskube-system coredns-5d78c9869d-9gj8f 1/1 Running 0 5m23skube-system coredns-5d78c9869d-gp7z4 1/1 Running 0 5m23s -
What is the IP of the CoreDNS server that should be configured on PODs to resolve services?
Answer
controlplane ~ ➜ k get svc -n kube-systemNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 7m2s -
Where is the configuration file located for configuring the CoreDNS service?
Answer
controlplane ~ ➜ k get po -n kube-system | grep dnscoredns-5d78c9869d-9gj8f 1/1 Running 0 10mcoredns-5d78c9869d-gp7z4 1/1 Running 0 10mcontrolplane ~ ➜ k describe -n kube-system pod coredns-5d78c9869d-gp7z4 | grep -i file/etc/coredns/Corefile -
How is the Corefile passed into the CoreDNS POD?
Answer
controlplane ~ ➜ k get po -n kube-system | grep dnscoredns-5d78c9869d-9gj8f 1/1 Running 0 11mcoredns-5d78c9869d-gp7z4 1/1 Running 0 11mcontrolplane ~ ➜ k describe -n kube-system pod coredns-5d78c9869d-gp7z4 | grep -i controlNode: controlplane/192.6.107.3Controlled By: ReplicaSet/coredns-5d78c9869dnode-role.kubernetes.io/control-plane:NoScheduleNormal Scheduled 11m default-scheduler Successfully assigned kube-system/coredns-5d78c9869d-gp7z4 to controlplanecontrolplane ~ ➜ k get rs -n kube-systemNAME DESIRED CURRENT READY AGEcoredns-5d78c9869d 2 2 2 11mWhen we try to check the YAML file for the ReplicaSet, we see that the file is passed as a ConfigMap object.
controlplane ~ ➜ k get rs -n kube-system coredns-5d78c9869d -o yaml | grep -i corefile -B5topologyKey: kubernetes.io/hostnameweight: 100containers:- args:- -conf- /etc/coredns/Corefile--key: node-role.kubernetes.io/control-planevolumes:- configMap:defaultMode: 420items:- key: Corefilepath: Corefile -
Since we know that the Corefile is passed as a ConfigMap object, determine the root domain/zone configured for this kubernetes cluster.
Answer
The root domain is cluster.local.
controlplane ~ ➜ k get cm -n kube-systemNAME DATA AGEcoredns 1 15mextension-apiserver-authentication 6 16mkube-apiserver-legacy-service-account-token-tracking 1 16mkube-proxy 2 15mkube-root-ca.crt 1 15mkubeadm-config 1 15mkubelet-config 1 15mcontrolplane ~ ➜ k describe -n kube-system cm corednsName: corednsNamespace: kube-systemLabels: <none>Annotations: <none>Data====Corefile:----.:53 {errorshealth {lameduck 5s}readykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30loopreloadloadbalance}BinaryData====Events: <none> -
What name can be used to access the hr web server from the test Application?
controlplane ~ ➜ k get po -ANAMESPACE NAME READY STATUS RESTARTS AGEdefault hr 1/1 Running 0 13mdefault simple-webapp-1 1/1 Running 0 13mdefault simple-webapp-122 1/1 Running 0 13mdefault test 1/1 Running 0 13mkube-flannel kube-flannel-ds-m267z 1/1 Running 0 18mkube-system coredns-5d78c9869d-9gj8f 1/1 Running 0 18mkube-system coredns-5d78c9869d-gp7z4 1/1 Running 0 18mkube-system etcd-controlplane 1/1 Running 0 18mkube-system kube-apiserver-controlplane 1/1 Running 0 18mkube-system kube-controller-manager-controlplane 1/1 Running 0 18mkube-system kube-proxy-hj5vp 1/1 Running 0 18mkube-system kube-scheduler-controlplane 1/1 Running 0 18mpayroll web 1/1 Running 0 13mcontrolplane ~ ➜ k get svc -ANAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdefault kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18mdefault test-service NodePort 10.96.250.160 <none> 80:30080/TCP 13mdefault web-service ClusterIP 10.108.205.43 <none> 80/TCP 13mkube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 18mpayroll web-service ClusterIP 10.96.157.205 <none> 80/TCP 13mAnswer
Remove the -A flag so that it only shows the resources in the default namespace where the hr pod is.
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEhr 1/1 Running 0 16msimple-webapp-1 1/1 Running 0 15msimple-webapp-122 1/1 Running 0 15mtest 1/1 Running 0 16mcontrolplane ~ ➜ k get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21mtest-service NodePort 10.96.250.160 <none> 80:30080/TCP 16mweb-service ClusterIP 10.108.205.43 <none> 80/TCP 16mRun a curl from within the hr pod.
controlplane ~ ✖ k exec -it hr -- curl web-service:80This is the HR server! -
Which of the names CANNOT be used to access the HR service from the test pod?
- web-service
- web-service.default
- web-service.default.pod
- web-service.default.svc
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEhr 1/1 Running 0 19msimple-webapp-1 1/1 Running 0 19msimple-webapp-122 1/1 Running 0 19mtest 1/1 Running 0 19mcontrolplane ~ ➜ k get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24mtest-service NodePort 10.96.250.160 <none> 80:30080/TCP 19mweb-service ClusterIP 10.108.205.43 <none> 80/TCP 19mAnswer
controlplane ~ ➜ k exec -it test -- curl web-service:80This is the HR server!controlplane ~ ➜ k exec -it test -- curl web-service.default:80This is the HR server!controlplane ~ ➜ k exec -it test -- curl web-service.default.pod:80curl: (6) Could not resolve host: web-service.default.podcommand terminated with exit code 6controlplane ~ ➜ k exec -it test -- curl web-service.default.svc:80This is the HR server!The answer is web-service.default.pod.
-
Which of the below name can be used to access the payroll service from the test application?
- web-service.payroll
- web-service
- web
- web-service.default
controlplane ~ ➜ k get svc -n payrollNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEweb-service ClusterIP 10.96.157.205 <none> 80/TCP 26mcontrolplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEhr 1/1 Running 0 26msimple-webapp-1 1/1 Running 0 26msimple-webapp-122 1/1 Running 0 26mtest 1/1 Running 0 26mAnswer
controlplane ~ ➜ k exec -it test -- curl web-service.payroll:80This is the PayRoll server!controlplane ~ ➜ k exec -it test -- curl web-service:80This is the HR server!controlplane ~ ➜ k exec -it test -- curl web:80curl: (6) Could not resolve host: webcommand terminated with exit code 6controlplane ~ ✖ k exec -it test -- curl web-service.default:80This is the HR server!The answers are:
- web-service.payroll
- web-service
- web-service.default
-
We just deployed a web server - webapp - that accesses a database mysql - server. However the web server is failing to connect to the database server. Troubleshoot and fix the issue.
controlplane ~ ➜ k get po -ANAMESPACE NAME READY STATUS RESTARTS AGEdefault hr 1/1 Running 0 30mdefault simple-webapp-1 1/1 Running 0 30mdefault simple-webapp-122 1/1 Running 0 30mdefault test 1/1 Running 0 30mdefault webapp-54b76556d-89b25 1/1 Running 0 30skube-flannel kube-flannel-ds-m267z 1/1 Running 0 35mkube-system coredns-5d78c9869d-9gj8f 1/1 Running 0 35mkube-system coredns-5d78c9869d-gp7z4 1/1 Running 0 35mkube-system etcd-controlplane 1/1 Running 0 35mkube-system kube-apiserver-controlplane 1/1 Running 0 35mkube-system kube-controller-manager-controlplane 1/1 Running 0 35mkube-system kube-proxy-hj5vp 1/1 Running 0 35mkube-system kube-scheduler-controlplane 1/1 Running 0 35mpayroll mysql 1/1 Running 0 30spayroll web 1/1 Running 0 30mAnswer
From the given above, we can see that the web-app and mysql are in different namespaces. There are two options here:
- Make sure both are in the same namespace
- Configure the webapp to point to the mysql at payroll namespace.
We will so the second option.
controlplane ~ ➜ k get deployNAME READY UP-TO-DATE AVAILABLE AGEwebapp 1/1 1 1 7m54scontrolplane ~ ➜ k edit deploy webappAppend the namespace after the hostname.
spec:containers:- env:- name: DB_Hostvalue: mysql.payroll- name: DB_Uservalue: root- name: DB_Passwordvalue: paswrdimage: mmumshad/simple-webapp-mysqlimagePullPolicy: Alwaysname: simple-webapp-mysqlports: -
From the hr pod nslookup the mysql service and redirect the output to a file /root/CKA/nslookup.out
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEhr 1/1 Running 0 43msimple-webapp-1 1/1 Running 0 43msimple-webapp-122 1/1 Running 0 43mtest 1/1 Running 0 43mwebapp-6fdb68c84f-wvgd2 1/1 Running 0 2m37scontrolplane ~ ➜ k get svc -n payrollNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEmysql ClusterIP 10.96.128.66 <none> 3306/TCP 13mweb-service ClusterIP 10.96.157.205 <none> 80/TCP 43mAnswer
controlplane ~ ➜ k exec -it hr -- nslookup mysql.payrollServer: 10.96.0.10Address: 10.96.0.10#53Name: mysql.payroll.svc.cluster.localAddress: 10.96.128.66controlplane ~ ➜ k exec -it hr -- nslookup mysql.payroll > /root/CKA/nslookup.outcontrolplane ~ ➜ ls -la /root/CKA/nslookup.out-rw-r--r-- 1 root root 111 Dec 30 23:53 /root/CKA/nslookup.outcontrolplane ~ ➜ cat /root/CKA/nslookup.outServer: 10.96.0.10Address: 10.96.0.10#53Name: mysql.payroll.svc.cluster.localAddress: 10.96.128.66 -
Which namespace is the Ingress Controller deployed in?
Answer
controlplane ~ ➜ k get all -A | grep -i ingressingress-nginx pod/ingress-nginx-admission-create-ddtp2 0/1 Completed 0 84singress-nginx pod/ingress-nginx-admission-patch-nn4hl 0/1 Completed 0 84singress-nginx pod/ingress-nginx-controller-5d48d5445f-zwmd9 1/1 Running 0 85singress-nginx service/ingress-nginx-controller NodePort 10.103.62.71 <none> 80:30080/TCP,443:32103/TCP 85singress-nginx service/ingress-nginx-controller-admission ClusterIP 10.96.188.183 <none> 443/TCP 85singress-nginx deployment.apps/ingress-nginx-controller 1/1 1 1 85singress-nginx replicaset.apps/ingress-nginx-controller-5d48d5445f 1 1 1 85singress-nginx job.batch/ingress-nginx-admission-create 1/1 10s 85singress-nginx job.batch/ingress-nginx-admission-patch 1/1 9s 84s -
What is the name of the ingress resource deployed?
Answer
controlplane ~ ➜ k api-resources | grep -i ingressingressclasses networking.k8s.io/v1 false IngressClassingresses ing networking.k8s.io/v1 true Ingresscontrolplane ~ ➜ k get ing -ANAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGEapp-space ingress-wear-watch <none> * 10.103.62.71 80 4m12s -
What is the Host configured on the Ingress Resource?
Answer
All Hosts (*)
controlplane ~ ➜ k api-resources | grep -i ingressingressclasses networking.k8s.io/v1 false IngressClassingresses ing networking.k8s.io/v1 true Ingresscontrolplane ~ ➜ k get ing -ANAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGEapp-space ingress-wear-watch <none> * 10.103.62.71 80 4m12scontrolplane ~ ➜ k describe -n app-space ingress ingress-wear-watchName: ingress-wear-watchLabels: <none>Namespace: app-spaceAddress: 10.103.62.71Ingress Class: <none>Default backend: <default>Rules:Host Path Backends---- ---- --------*/wear wear-service:8080 (10.244.0.4:8080)/watch video-service:8080 (10.244.0.5:8080)Annotations: nginx.ingress.kubernetes.io/rewrite-target: /nginx.ingress.kubernetes.io/ssl-redirect: falseEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal Sync 4m29s (x2 over 4m30s) nginx-ingress-controller Scheduled for sync -
You are requested to change the URLs at which the applications are made available. Make the change in the given Ingress Controller.
controlplane ~ ➜ k get ing -ANAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGEapp-space ingress-wear-watch <none> * 10.103.62.71 80 7m48sAnswer
controlplane ~ ➜ k edit -n app-space ingress ingress-wear-watch# Please edit the object below. Lines beginning with a '#' will be ignored,# and an empty file will abort the edit. If an error occurs while saving this file will be# reopened with the relevant failures.#apiVersion: networking.k8s.io/v1kind: Ingressmetadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /nginx.ingress.kubernetes.io/ssl-redirect: "false"creationTimestamp: "2023-12-31T04:54:24Z"generation: 1name: ingress-wear-watchnamespace: app-spaceresourceVersion: "910"uid: 2e334919-c62f-4513-8400-e47ebf0eabf4spec:rules:- http:paths:- backend:service:name: wear-serviceport:number: 8080path: /wearpathType: Prefix- backend:service:name: video-serviceport:number: 8080path: /streampathType: Prefixstatus:loadBalancer:ingress:- ip: 10.103.62.71 -
You are requested to add a new path to your ingress to make the food delivery application available to your customers.
Make the new application available at /eat.
controlplane ~ ➜ k get deploy -n app-spaceNAME READY UP-TO-DATE AVAILABLE AGEdefault-backend 1/1 1 1 10mwebapp-food 1/1 1 1 13swebapp-video 1/1 1 1 10mwebapp-wear 1/1 1 1 10mcontrolplane ~ ➜ k get svc -n app-spaceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdefault-backend-service ClusterIP 10.99.131.124 <none> 80/TCP 14mfood-service ClusterIP 10.109.123.30 <none> 8080/TCP 4m5svideo-service ClusterIP 10.98.228.143 <none> 8080/TCP 14mwear-service ClusterIP 10.109.75.46 <none> 8080/TCP 14mcontrolplane ~ ➜ k get ing -ANAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGEapp-space ingress-wear-watch <none> * 10.103.62.71 80 11mAnswer
controlplane ~ ➜ k edit -n app-space ingress ingress-wear-watchapiVersion: networking.k8s.io/v1kind: Ingressmetadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /nginx.ingress.kubernetes.io/ssl-redirect: "false"creationTimestamp: "2023-12-31T04:54:24Z"generation: 3name: ingress-wear-watchnamespace: app-spaceresourceVersion: "2107"uid: 2e334919-c62f-4513-8400-e47ebf0eabf4spec:rules:- http:paths:- backend:service:name: wear-serviceport:number: 8080path: /wearpathType: Prefix- backend:service:name: video-serviceport:number: 8080path: /streampathType: Prefix- backend:service:name: food-serviceport:number: 8080path: /eatpathType: Prefix -
You are requested to make the new application webapp-pay available at /pay.
Identify and implement the best approach to making this application available on the ingress controller and test to make sure its working. Look into annotations: rewrite-target as well.
controlplane ~ ➜ k get deploy -ANAMESPACE NAME READY UP-TO-DATE AVAILABLE AGEapp-space default-backend 1/1 1 1 16mapp-space webapp-food 1/1 1 1 7m2sapp-space webapp-video 1/1 1 1 16mapp-space webapp-wear 1/1 1 1 16mcritical-space webapp-pay 1/1 1 1 102singress-nginx ingress-nginx-controller 1/1 1 1 16mkube-system coredns 2/2 2 2 20mcontrolplane ~ ➜ k get svc -n critical-spaceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEpay-service ClusterIP 10.106.32.226 <none> 8282/TCP 2m13scontrolplane ~ ➜ k get ing -ANAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGEapp-space ingress-wear-watch <none> * 10.103.62.71 80 17mAnswer
Do not modify the existing ingress resource. Simply create a new one.
## ingress-pay.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: minimal-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target: /spec:ingressClassName: nginx-examplerules:- http:paths:- path: /testpathpathType: Prefixbackend:service:name: testport:number: 80controlplane ~ ➜ k apply -f ingress-pay.yamlingress.networking.k8s.io/pay-ingress createdcontrolplane ~ ➜ k get ing -ANAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGEapp-space ingress-wear-watch <none> * 10.103.62.71 80 25mcritical-space pay-ingress <none> * 80 7s -
Deploy an Ingress Controller.
- First, create a namespace called ingress-nginx.
- The NGINX Ingress Controller requires a ConfigMap object. Create a ConfigMap object with name ingress-nginx-controller in the ingress-nginx namespace.
- The NGINX Ingress Controller requires two ServiceAccounts. Create both ServiceAccount with name ingress-nginx and ingress-nginx-admission in the ingress-nginx namespace. Use the spec provided below.
- Name: ingress-nginx
- Name: ingress-nginx-admission
- The roles, clusterroles, rolebindings, and clusterrolebindings have been created
- Create the Ingress Controller using the /root/ingress-controller.yaml. There are several issues with it. Try to fix them.
- Finally, create the ingress resource to make the applications available at /wear and /watch on the Ingress service. Also, make use of rewrite-target annotation field.
- Path: /wear
- Path: /watch
Answer
controlplane ~ ➜ k create ns ingress-nginxnamespace/ingress-nginx createdcontrolplane ~ ➜ k get nsNAME STATUS AGEapp-space Active 67sdefault Active 8m20singress-nginx Active 2skube-flannel Active 8m14skube-node-lease Active 8m20skube-public Active 8m20skube-system Active 8m20sCreate the ConfigMap.
controlplane ~ ➜ k create configmap ingress-nginx-controller --namespace ingress-nginx $doapiVersion: v1kind: ConfigMapmetadata:creationTimestamp: nullname: ingress-nginx-controllernamespace: ingress-nginxcontrolplane ~ ➜ k create configmap ingress-nginx-controller --namespace ingress-nginx $do > cm-ingress-nginx-controller.ymlcontrolplane ~ ➜ k create configmap ingress-nginx-controller --namespace ingress-nginxconfigmap/ingress-nginx-controller createdcontrolplane ~ ➜ k get cm -n ingress-nginxNAME DATA AGEingress-nginx-controller 0 53skube-root-ca.crt 1 3m18sNext, create the service accounts.
controlplane ~ ➜ k create sa ingress-nginx-admission --namespace ingress-nginx $doapiVersion: v1kind: ServiceAccountmetadata:creationTimestamp: nullname: ingress-nginx-admissionnamespace: ingress-nginxcontrolplane ~ ➜ k create sa ingress-nginx-admission --namespace ingress-nginx $do > sa-ingress-nginx-admission.ymlcontrolplane ~ ➜ k create sa ingress-nginx-admission --namespace ingress-nginxserviceaccount/ingress-nginx-admission createdcontrolplane ~ ➜ k create sa ingress-nginx --namespace ingress-nginxserviceaccount/ingress-nginx-admission createdcontrolplane ~ ➜ k get sa -n ingress-nginxNAME SECRETS AGEdefault 0 8m53singress-nginx 0 67singress-nginx-admission 0 14sFix the ingress-controller.yaml and apply afterwards.
## ingress-controller.yamlapiVersion: apps/v1kind: Deploymentmetadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/managed-by: Helmapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.1.2helm.sh/chart: ingress-nginx-4.0.18name: ingress-nginx-controllernamespace: ingress-nginxspec:minReadySeconds: 0revisionHistoryLimit: 10selector:matchLabels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxspec:containers:- args:- /nginx-ingress-controller- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller- --election-id=ingress-controller-leader- --watch-ingress-without-class=true- --default-backend-service=app-space/default-http-backend- --controller-class=k8s.io/ingress-nginx- --ingress-class=nginx- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller- --validating-webhook=:8443- --validating-webhook-certificate=/usr/local/certificates/cert- --validating-webhook-key=/usr/local/certificates/keyenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: LD_PRELOADvalue: /usr/local/lib/libmimalloc.soimage: registry.k8s.io/ingress-nginx/controller:v1.1.2@sha256:28b11ce69e57843de44e3db6413e98d09de0f6688e33d4bd384002a44f78405cimagePullPolicy: IfNotPresentlifecycle:preStop:exec:command:- /wait-shutdownlivenessProbe:failureThreshold: 5httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1name: controllerports:- name: httpcontainerPort: 80protocol: TCP- containerPort: 443name: httpsprotocol: TCP- containerPort: 8443name: webhookprotocol: TCPreadinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1resources:requests:cpu: 100mmemory: 90MisecurityContext:allowPrivilegeEscalation: truecapabilities:add:- NET_BIND_SERVICEdrop:- ALLrunAsUser: 101volumeMounts:- mountPath: /usr/local/certificates/name: webhook-certreadOnly: truednsPolicy: ClusterFirstnodeSelector:kubernetes.io/os: linuxserviceAccountName: ingress-nginxterminationGracePeriodSeconds: 300volumes:- name: webhook-certsecret:secretName: ingress-nginx-admission---apiVersion: v1kind: Servicemetadata:creationTimestamp: nulllabels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/managed-by: Helmapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.1.2helm.sh/chart: ingress-nginx-4.0.18name: ingress-nginx-controllernamespace: ingress-nginxspec:ports:- port: 80protocol: TCPtargetPort: 80nodePort: 30080selector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: NodePortcontrolplane ~ ➜ k get -n ingress-nginx poNAME READY STATUS RESTARTS AGEingress-nginx-admission-create-wtzf6 0/1 Completed 0 7m32singress-nginx-controller-cc9f46d74-fmc65 0/1 Running 0 13scontrolplane ~ ➜ k get -n ingress-nginx svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx-controller NodePort 10.104.168.175 <none> 80:30080/TCP 18singress-nginx-controller-admission ClusterIP 10.105.49.126 <none> 443/TCP 7m37sNext, create the ingress resource. But first, get the services in the app-space namespace.
controlplane ~ ➜ k get svc -n app-spaceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdefault-http-backend ClusterIP 10.104.25.24 <none> 80/TCP 29mvideo-service ClusterIP 10.97.188.119 <none> 8080/TCP 29mwear-service ClusterIP 10.98.183.145 <none> 8080/TCP 29m## ingress-resource.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: app-ingressnamespace: app-spaceannotations:nginx.ingress.kubernetes.io/rewrite-target: /spec:ingressClassName: nginx-examplerules:- http:paths:- path: /wearpathType: Prefixbackend:service:name: wear-serviceport:number: 8080- path: /watchpathType: Prefixbackend:service:name: video-serviceport:number: 8080controlplane ~ ➜ k apply -f ingress-resource.yamlingress.networking.k8s.io/app-ingress createdcontrolplane ~ ➜ k get ing -n app-spaceNAME CLASS HOSTS ADDRESS PORTS AGEapp-ingress nginx-example * 80 12s