Skip to content

Latest commit

 

History

History
executable file
·
1566 lines (1192 loc) · 52.7 KB

010-Practice-Test-CKA-Networking.md

File metadata and controls

executable file
·
1566 lines (1192 loc) · 52.7 KB

Practice Test: CKA

Some of the scenario questions here are based on Kodekloud's CKA course labs.

Networking

Note

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

  1. What is the Internal IP address of the controlplane node in this cluster?

    controlplane ~ ➜  k get no
    NAME           STATUS   ROLES           AGE   VERSION
    controlplane   Ready    control-plane   15m   v1.27.0
    node01         Ready    <none>          14m   v1.27.0
    Answer
    controlplane ~ ➜  k describe no controlplane  | grep -i ip
                        flannel.alpha.coreos.com/public-ip: 192.2.53.9
      InternalIP:  192.2.53.9 

  2. What is the network interface configured for cluster connectivity on the controlplane node?

    controlplane ~ ➜  k get no
    NAME           STATUS   ROLES           AGE   VERSION
    controlplane   Ready    control-plane   15m   v1.27.0
    node01         Ready    <none>          14m   v1.27.0
    Answer
    controlplane ~ ➜  k get no -o wide
    NAME           STATUS   ROLES           AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
    controlplane   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.6
    node01         Ready    <none>          19m   v1.27.0   192.2.120.12   <none>        Ubuntu 20.04.5 LTS   5.4.0-1106-gcp   containerd://1.6.6
    
    controlplane ~ ➜  ip addr | grep -B2 192.2
    13036: eth0@if13037: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default 
        link/ether 02:42:c0:02:78:09 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.2.120.9/24 brd 192.2.120.255 scope global eth0

  3. What is the MAC address assigned to node01?

    controlplane ~ ➜  k get no
    NAME           STATUS   ROLES           AGE   VERSION
    controlplane   Ready    control-plane   15m   v1.27.0
    node01         Ready    <none>          14m   v1.27.0
    Answer

    Need to ssh to node01.

    controlplane ~ ➜  ssh node01
    
    root@node01 ~ ➜  ip addr | grep -B2 192.2
    13945: eth0@if13946: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default 
        link/ether 02:42:c0:02:78:0c brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.2.120.12/24 brd 192.2.120.255 scope global eth0 

  4. 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 cni
    3: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    4: vethcb46d51e@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue master cni0 state UP mode DEFAULT group default 
        link/ether 46:15:1c:5b:93:f2 brd ff:ff:ff:ff:ff:ff link-netns cni-3f59b276-21d3-2b70-df1a-514e9f7eb6cb
    5: veth35f1d3bb@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue master cni0 state UP mode DEFAULT group default 
        link/ether 96:21:56:39:34:10 brd ff:ff:ff:ff:ff:ff link-netns cni-d15387ac-89be-7f41-ecb3-79879ae016f1

  5. If you were to ping google from the controlplane node, which route does it take?

    controlplane ~ ➜  k get no
    NAME           STATUS   ROLES           AGE   VERSION
    controlplane   Ready    control-plane   15m   v1.27.0
    node01         Ready    <none>          14m   v1.27.0
    Answer
    controlplane ~ ➜  ip route
    default via 172.25.0.1 dev eth1 

  6. What is the port the kube-scheduler is listening on in the controlplane node?

    Answer
    controlplane ~ ➜  netstat -tulpn | grep -i sched
    tcp        0      0 127.0.0.1:10259         0.0.0.0:*               LISTEN      3706/kube-scheduler  

  7. 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 etc
    tcp        0      0 192.2.120.9:2379        0.0.0.0:*               LISTEN      3723/etcd           
    tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      3723/etcd           
    tcp        0      0 192.2.120.9:2380        0.0.0.0:*               LISTEN      3723/etcd           
    tcp        0      0 127.0.0.1:2381          0.0.0.0:*               LISTEN      3723/etcd   
    
    controlplane ~ ➜  netstat -anp | grep etc | grep 2379 | wc -l
    63
    
    controlplane ~ ➜  netstat -anp | grep etc | grep 2380 | wc -l
    1
    
    controlplane ~ ➜  netstat -anp | grep etc | grep 2381 | wc -l
    1

  8. 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 container
    root        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 

  9. What is the path configured with all binaries of CNI supported plugins?

    Answer
    controlplane ~ ➜  ls -la /opt/cni
    total 20
    drwxr-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 bin
    
    controlplane ~ ➜  ls -la /opt/cni/bin/
    total 71424
    drwxrwxr-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 

  10. What is the CNI plugin configured to be used on this kubernetes cluster?

    Answer
    controlplane ~ ➜  ls -la /etc/cni/
    total 20
    drwx------ 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.d
    
    controlplane ~ ➜  ls -la /etc/cni/net.d/
    total 16
    drwx------ 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
    

  11. What binary executable file will be run by kubelet after a container and its associated namespace are created?

  12. 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 4
    drwx------ 1 root root 4096 Dec 30 20:02 net.d
    
    controlplane ~ ➜  ls -l /etc/cni/net.d/
    total 4
    -rw-r--r-- 1 root root 292 Dec 30 20:02 10-flannel.conflist 

    The 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
          }
        }
      ]
    } 

  13. 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 po
    NAME   READY   STATUS              RESTARTS   AGE
    app    1/1     ContainerCreating   0          3m7s 

    Install weavenet via the weave manifest.

    controlplane ~ ➜  ls -la /root/weave/
    total 20
    drwxr-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.yaml
    
    controlplane ~ ➜  k apply -f /root/weave/
    serviceaccount/weave-net created
    clusterrole.rbac.authorization.k8s.io/weave-net created
    clusterrolebinding.rbac.authorization.k8s.io/weave-net created
    role.rbac.authorization.k8s.io/weave-net created
    rolebinding.rbac.authorization.k8s.io/weave-net created
    daemonset.apps/weave-net created
    

    The app should now be able to run.

    controlplane ~ ➜  k get po
    NAME   READY   STATUS    RESTARTS   AGE
    app    1/1     Running   0          3m7s 

  14. What is the Networking Solution used by this cluster?

    Answer
    controlplane ~ ➜  ls -la /etc/cni/net.d/
    total 16
    drwx------ 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.conflist
    
    controlplane ~ ➜  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
            }
        ]
    } 

  15. How many weave agents/peers are deployed in this cluster?

    Answer
    controlplane ~ ➜  k get po -n kube-system 
    NAME                                   READY   STATUS    RESTARTS      AGE
    coredns-5d78c9869d-g5r7l               1/1     Running   0             24m
    coredns-5d78c9869d-kbzrl               1/1     Running   0             24m
    etcd-controlplane                      1/1     Running   0             24m
    kube-apiserver-controlplane            1/1     Running   0             24m
    kube-controller-manager-controlplane   1/1     Running   0             24m
    kube-proxy-6rzbz                       1/1     Running   0             24m
    kube-proxy-bqhf2                       1/1     Running   0             24m
    kube-scheduler-controlplane            1/1     Running   0             24m
    weave-net-mq78f                        2/2     Running   1 (23m ago)   24m
    weave-net-pxrzs                        2/2     Running   1 (23m ago)   24m 
    
    controlplane ~ ➜  k get po -n kube-system  -o wide ñ grep weave
    weave-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>

  16. Identify the name of the bridge network/interface created by weave on each node.

    Answer
    controlplane ~ ➜  ip addr | grep weave
    4: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default qlen 1000
        inet 10.244.192.0/16 brd 10.244.255.255 scope global weave
    7: vethwe-bridge@vethwe-datapath: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue master weave state UP group default 
    10: vethwepl4a7ab64@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue master weave state UP group default 
    12: vethwepl6d8c184@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue master weave state UP group default 
    

  17. 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 route
    default via 172.25.0.1 dev eth1 
    10.244.0.0/16 dev weave proto kernel scope link src 10.244.0.1 
    172.25.0.0/24 dev eth1 proto kernel scope link src 172.25.0.35 
    192.5.179.0/24 dev eth0 proto kernel scope link src 192.5.179.12  

  18. 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-system
    NAME                                   READY   STATUS    RESTARTS      AGE
    coredns-5d78c9869d-9qdz4               1/1     Running   0             28m
    coredns-5d78c9869d-qzd27               1/1     Running   0             28m
    etcd-controlplane                      1/1     Running   0             28m
    kube-apiserver-controlplane            1/1     Running   0             28m
    kube-controller-manager-controlplane   1/1     Running   0             28m
    kube-proxy-gq9zh                       1/1     Running   0             28m
    kube-proxy-p6fhm                       1/1     Running   0             28m
    kube-scheduler-controlplane            1/1     Running   0             28m
    weave-net-5djnr                        2/2     Running   0             28m
    weave-net-wcmwp                        2/2     Running   1 (28m ago)   28m
    
    controlplane ~ ➜  k logs -n kube-system weave-net-5djnr | grep -i ip
    Defaulted 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] 

  19. 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 -A
    NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
    default       kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  31m
    kube-system   kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   31m

    We 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.yaml
    
    controlplane ~ ➜  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  

  20. What type of proxy is the kube-proxy configured to use?

    Answer
    controlplane ~ ➜  k get po -n kube-system | grep kube-proxy
    kube-proxy-gq9zh                       1/1     Running   0             35m
    kube-proxy-p6fhm                       1/1     Running   0             36m
    
    controlplane ~ ➜  k logs -n kube-system kube-proxy-gq9zh | grep -i proxy
    I1231 03:24:13.560888       1 server_others.go:551] "Using iptables proxy"

  21. 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-pro
    kube-proxy-gq9zh                       1/1     Running   0             40m
    kube-proxy-p6fhm                       1/1     Running   0             40m
    
    controlplane ~ ➜  k describe  pod -n kube-system kube-proxy-gq9zh  | grep -i control
    Labels:               controller-revision-hash=7b6c5596fc
    Controlled By:  DaemonSet/kube-proxy 

  22. Identify the DNS solution implemented in this cluster.

    Answer
    controlplane ~ ✖ k get po -A | grep dns
    kube-system    coredns-5d78c9869d-9gj8f               1/1     Running   0          5m23s
    kube-system    coredns-5d78c9869d-gp7z4               1/1     Running   0          5m23s 

  23. What is the IP of the CoreDNS server that should be configured on PODs to resolve services?

    Answer
    controlplane ~ ➜  k get svc -n kube-system 
    NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
    kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   7m2s 

  24. Where is the configuration file located for configuring the CoreDNS service?

    Answer
    controlplane ~ ➜  k get po -n kube-system | grep dns
    coredns-5d78c9869d-9gj8f               1/1     Running   0          10m
    coredns-5d78c9869d-gp7z4               1/1     Running   0          10m
    
    controlplane ~ ➜  k describe -n kube-system pod coredns-5d78c9869d-gp7z4 | grep -i file
          /etc/coredns/Corefile 

  25. How is the Corefile passed into the CoreDNS POD?

    Answer
    controlplane ~ ➜  k get po -n kube-system | grep dns
    coredns-5d78c9869d-9gj8f               1/1     Running   0          11m
    coredns-5d78c9869d-gp7z4               1/1     Running   0          11m
    
    controlplane ~ ➜  k describe -n kube-system pod coredns-5d78c9869d-gp7z4 | grep -i control
    Node:                 controlplane/192.6.107.3
    Controlled By:  ReplicaSet/coredns-5d78c9869d
                                node-role.kubernetes.io/control-plane:NoSchedule
      Normal   Scheduled               11m   default-scheduler  Successfully assigned kube-system/coredns-5d78c9869d-gp7z4 to controlplane
    
    controlplane ~ ➜  k get rs -n kube-system 
    NAME                 DESIRED   CURRENT   READY   AGE
    coredns-5d78c9869d   2         2         2       11m

    When 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 -B5
                  topologyKey: kubernetes.io/hostname
                weight: 100
          containers:
          - args:
            - -conf
            - /etc/coredns/Corefile
    --
            key: node-role.kubernetes.io/control-plane
          volumes:
          - configMap:
              defaultMode: 420
              items:
              - key: Corefile
                path: Corefile 

  26. 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-system
    NAME                                                   DATA   AGE
    coredns                                                1      15m
    extension-apiserver-authentication                     6      16m
    kube-apiserver-legacy-service-account-token-tracking   1      16m
    kube-proxy                                             2      15m
    kube-root-ca.crt                                       1      15m
    kubeadm-config                                         1      15m
    kubelet-config                                         1      15m
    
    controlplane ~ ➜  k describe -n kube-system cm coredns
    Name:         coredns
    Namespace:    kube-system
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    Corefile:
    ----
    .:53 {
        errors
        health {
          lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
          ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
          max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
    
    
    BinaryData
    ====
    
    Events:  <none> 

  27. What name can be used to access the hr web server from the test Application?

    controlplane ~ ➜  k get po -A
    NAMESPACE      NAME                                   READY   STATUS    RESTARTS   AGE
    default        hr                                     1/1     Running   0          13m
    default        simple-webapp-1                        1/1     Running   0          13m
    default        simple-webapp-122                      1/1     Running   0          13m
    default        test                                   1/1     Running   0          13m
    kube-flannel   kube-flannel-ds-m267z                  1/1     Running   0          18m
    kube-system    coredns-5d78c9869d-9gj8f               1/1     Running   0          18m
    kube-system    coredns-5d78c9869d-gp7z4               1/1     Running   0          18m
    kube-system    etcd-controlplane                      1/1     Running   0          18m
    kube-system    kube-apiserver-controlplane            1/1     Running   0          18m
    kube-system    kube-controller-manager-controlplane   1/1     Running   0          18m
    kube-system    kube-proxy-hj5vp                       1/1     Running   0          18m
    kube-system    kube-scheduler-controlplane            1/1     Running   0          18m
    payroll        web                                    1/1     Running   0          13m
    
    controlplane ~ ➜  k get svc -A
    NAMESPACE     NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
    default       kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP                  18m
    default       test-service   NodePort    10.96.250.160   <none>        80:30080/TCP             13m
    default       web-service    ClusterIP   10.108.205.43   <none>        80/TCP                   13m
    kube-system   kube-dns       ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   18m
    payroll       web-service    ClusterIP   10.96.157.205   <none>        80/TCP                   13m 
    Answer

    Remove the -A flag so that it only shows the resources in the default namespace where the hr pod is.

    controlplane ~ ➜  k get po
    NAME                READY   STATUS    RESTARTS   AGE
    hr                  1/1     Running   0          16m
    simple-webapp-1     1/1     Running   0          15m
    simple-webapp-122   1/1     Running   0          15m
    test                1/1     Running   0          16m
    
    controlplane ~ ➜  k get svc
    NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        21m
    test-service   NodePort    10.96.250.160   <none>        80:30080/TCP   16m
    web-service    ClusterIP   10.108.205.43   <none>        80/TCP         16m 

    Run a curl from within the hr pod.

    controlplane ~ ✖ k exec -it hr -- curl web-service:80
    This is the HR server!

  28. 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 po
    NAME                READY   STATUS    RESTARTS   AGE
    hr                  1/1     Running   0          19m
    simple-webapp-1     1/1     Running   0          19m
    simple-webapp-122   1/1     Running   0          19m
    test                1/1     Running   0          19m
    
    controlplane ~ ➜  k get svc
    NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        24m
    test-service   NodePort    10.96.250.160   <none>        80:30080/TCP   19m
    web-service    ClusterIP   10.108.205.43   <none>        80/TCP         19m
      
    Answer
    controlplane ~ ➜  k exec -it test -- curl web-service:80
    This is the HR server!
    
    controlplane ~ ➜  k exec -it test -- curl web-service.default:80
    This is the HR server!
    
    controlplane ~ ➜  k exec -it test -- curl web-service.default.pod:80
    curl: (6) Could not resolve host: web-service.default.pod
    command terminated with exit code 6
    
    controlplane ~ ➜  k exec -it test -- curl web-service.default.svc:80
    This is the HR server! 

    The answer is web-service.default.pod.


  29. 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 payroll
    NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
    web-service   ClusterIP   10.96.157.205   <none>        80/TCP    26m
    
    controlplane ~ ➜  k get po
    NAME                READY   STATUS    RESTARTS   AGE
    hr                  1/1     Running   0          26m
    simple-webapp-1     1/1     Running   0          26m
    simple-webapp-122   1/1     Running   0          26m
    test                1/1     Running   0          26m
    Answer
    controlplane ~ ➜  k exec -it test -- curl web-service.payroll:80
    This is the PayRoll server!
    
    controlplane ~ ➜  k exec -it test -- curl web-service:80
    This is the HR server!
    
    controlplane ~ ➜  k exec -it test -- curl web:80
    curl: (6) Could not resolve host: web
    command terminated with exit code 6
    
    controlplane ~ ✖ k exec -it test -- curl web-service.default:80
    This is the HR server!

    The answers are:

    • web-service.payroll
    • web-service
    • web-service.default

  30. 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 -A
    NAMESPACE      NAME                                   READY   STATUS    RESTARTS   AGE
    default        hr                                     1/1     Running   0          30m
    default        simple-webapp-1                        1/1     Running   0          30m
    default        simple-webapp-122                      1/1     Running   0          30m
    default        test                                   1/1     Running   0          30m
    default        webapp-54b76556d-89b25                 1/1     Running   0          30s
    kube-flannel   kube-flannel-ds-m267z                  1/1     Running   0          35m
    kube-system    coredns-5d78c9869d-9gj8f               1/1     Running   0          35m
    kube-system    coredns-5d78c9869d-gp7z4               1/1     Running   0          35m
    kube-system    etcd-controlplane                      1/1     Running   0          35m
    kube-system    kube-apiserver-controlplane            1/1     Running   0          35m
    kube-system    kube-controller-manager-controlplane   1/1     Running   0          35m
    kube-system    kube-proxy-hj5vp                       1/1     Running   0          35m
    kube-system    kube-scheduler-controlplane            1/1     Running   0          35m
    payroll        mysql                                  1/1     Running   0          30s
    payroll        web                                    1/1     Running   0          30m 
    Answer

    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 deploy
    NAME     READY   UP-TO-DATE   AVAILABLE   AGE
    webapp   1/1     1            1           7m54s
    
    controlplane ~ ➜  k edit deploy webapp

    Append the namespace after the hostname.

        spec:
          containers:
          - env:
            - name: DB_Host
              value: mysql.payroll
            - name: DB_User
              value: root
            - name: DB_Password
              value: paswrd
            image: mmumshad/simple-webapp-mysql
            imagePullPolicy: Always
            name: simple-webapp-mysql
            ports:

  31. From the hr pod nslookup the mysql service and redirect the output to a file /root/CKA/nslookup.out

    controlplane ~ ➜  k get po
    NAME                      READY   STATUS    RESTARTS   AGE
    hr                        1/1     Running   0          43m
    simple-webapp-1           1/1     Running   0          43m
    simple-webapp-122         1/1     Running   0          43m
    test                      1/1     Running   0          43m
    webapp-6fdb68c84f-wvgd2   1/1     Running   0          2m37s
    
    controlplane ~ ➜  k get svc -n payroll
    NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    mysql         ClusterIP   10.96.128.66    <none>        3306/TCP   13m
    web-service   ClusterIP   10.96.157.205   <none>        80/TCP     43m
    Answer
    controlplane ~ ➜  k exec -it hr -- nslookup mysql.payroll
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   mysql.payroll.svc.cluster.local
    Address: 10.96.128.66
    
    
    controlplane ~ ➜  k exec -it hr -- nslookup mysql.payroll > /root/CKA/nslookup.out
    
    controlplane ~ ➜  ls -la /root/CKA/nslookup.out 
    -rw-r--r-- 1 root root 111 Dec 30 23:53 /root/CKA/nslookup.out
    
    controlplane ~ ➜  cat /root/CKA/nslookup.out 
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   mysql.payroll.svc.cluster.local
    Address: 10.96.128.66

  32. Which namespace is the Ingress Controller deployed in?

    Answer
    controlplane ~ ➜  k get all -A | grep -i ingress
    ingress-nginx   pod/ingress-nginx-admission-create-ddtp2        0/1     Completed   0          84s
    ingress-nginx   pod/ingress-nginx-admission-patch-nn4hl         0/1     Completed   0          84s
    ingress-nginx   pod/ingress-nginx-controller-5d48d5445f-zwmd9   1/1     Running     0          85s
    ingress-nginx   service/ingress-nginx-controller             NodePort    10.103.62.71    <none>        80:30080/TCP,443:32103/TCP   85s
    ingress-nginx   service/ingress-nginx-controller-admission   ClusterIP   10.96.188.183   <none>        443/TCP                      85s
    ingress-nginx   deployment.apps/ingress-nginx-controller   1/1     1            1           85s
    ingress-nginx   replicaset.apps/ingress-nginx-controller-5d48d5445f   1         1         1       85s
    ingress-nginx   job.batch/ingress-nginx-admission-create   1/1           10s        85s
    ingress-nginx   job.batch/ingress-nginx-admission-patch    1/1           9s         84s 

  33. What is the name of the ingress resource deployed?

    Answer
    controlplane ~ ➜  k api-resources | grep -i ingress
    ingressclasses                                 networking.k8s.io/v1                   false        IngressClass
    ingresses                         ing          networking.k8s.io/v1                   true         Ingress
    
    controlplane ~ ➜  k get ing -A
    NAMESPACE   NAME                 CLASS    HOSTS   ADDRESS        PORTS   AGE
    app-space   ingress-wear-watch   <none>   *       10.103.62.71   80      4m12s 

  34. What is the Host configured on the Ingress Resource?

    Answer

    All Hosts (*)

    controlplane ~ ➜  k api-resources | grep -i ingress
    ingressclasses                                 networking.k8s.io/v1                   false        IngressClass
    ingresses                         ing          networking.k8s.io/v1                   true         Ingress
    
    controlplane ~ ➜  k get ing -A
    NAMESPACE   NAME                 CLASS    HOSTS   ADDRESS        PORTS   AGE
    app-space   ingress-wear-watch   <none>   *       10.103.62.71   80      4m12s
    
    controlplane ~ ➜  k describe -n app-space ingress ingress-wear-watch 
    Name:             ingress-wear-watch
    Labels:           <none>
    Namespace:        app-space
    Address:          10.103.62.71
    Ingress 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: false
    Events:
      Type    Reason  Age                    From                      Message
      ----    ------  ----                   ----                      -------
      Normal  Sync    4m29s (x2 over 4m30s)  nginx-ingress-controller  Scheduled for sync 

  35. 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 -A
    NAMESPACE   NAME                 CLASS    HOSTS   ADDRESS        PORTS   AGE
    app-space   ingress-wear-watch   <none>   *       10.103.62.71   80      7m48s 
    Answer
    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/v1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
      creationTimestamp: "2023-12-31T04:54:24Z"
      generation: 1
      name: ingress-wear-watch
      namespace: app-space
      resourceVersion: "910"
      uid: 2e334919-c62f-4513-8400-e47ebf0eabf4
    spec:
      rules:
      - http:
          paths:
          - backend:
              service:
                name: wear-service
                port:
                  number: 8080
            path: /wear
            pathType: Prefix
          - backend:
              service:
                name: video-service
                port:
                  number: 8080
            path: /stream
            pathType: Prefix
    status:
      loadBalancer:
        ingress:
        - ip: 10.103.62.71 

  36. 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-space
    NAME              READY   UP-TO-DATE   AVAILABLE   AGE
    default-backend   1/1     1            1           10m
    webapp-food       1/1     1            1           13s
    webapp-video      1/1     1            1           10m
    webapp-wear       1/1     1            1           10m 
    
    controlplane ~ ➜  k get svc -n app-space 
    NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    default-backend-service   ClusterIP   10.99.131.124   <none>        80/TCP     14m
    food-service              ClusterIP   10.109.123.30   <none>        8080/TCP   4m5s
    video-service             ClusterIP   10.98.228.143   <none>        8080/TCP   14m
    wear-service              ClusterIP   10.109.75.46    <none>        8080/TCP   14m
    
    controlplane ~ ➜  k get ing -A
    NAMESPACE   NAME                 CLASS    HOSTS   ADDRESS        PORTS   AGE
    app-space   ingress-wear-watch   <none>   *       10.103.62.71   80      11m    
    Answer
    controlplane ~ ➜  k edit -n app-space ingress ingress-wear-watch  
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
      creationTimestamp: "2023-12-31T04:54:24Z"
      generation: 3
      name: ingress-wear-watch
      namespace: app-space
      resourceVersion: "2107"
      uid: 2e334919-c62f-4513-8400-e47ebf0eabf4
    spec:
      rules:
      - http:
          paths:
          - backend:
              service:
                name: wear-service
                port:
                  number: 8080
            path: /wear
            pathType: Prefix
          - backend:
              service:
                name: video-service
                port:
                  number: 8080
            path: /stream
            pathType: Prefix
          - backend:
              service:
                name: food-service
                port:
                  number: 8080
            path: /eat
            pathType: Prefix 

  37. 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 -A
    NAMESPACE        NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
    app-space        default-backend            1/1     1            1           16m
    app-space        webapp-food                1/1     1            1           7m2s
    app-space        webapp-video               1/1     1            1           16m
    app-space        webapp-wear                1/1     1            1           16m
    critical-space   webapp-pay                 1/1     1            1           102s
    ingress-nginx    ingress-nginx-controller   1/1     1            1           16m
    kube-system      coredns                    2/2     2            2           20m 
    
    controlplane ~ ➜  k get svc -n critical-space 
    NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    pay-service   ClusterIP   10.106.32.226   <none>        8282/TCP   2m13s
    
    controlplane ~ ➜  k get ing -A
    NAMESPACE   NAME                 CLASS    HOSTS   ADDRESS        PORTS   AGE
    app-space   ingress-wear-watch   <none>   *       10.103.62.71   80      17m    
    Answer

    Do not modify the existing ingress resource. Simply create a new one.

    ## ingress-pay.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: minimal-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx-example
      rules:
      - http:
          paths:
          - path: /testpath
            pathType: Prefix
            backend:
              service:
                name: test
                port:
                  number: 80             
    controlplane ~ ➜  k apply -f ingress-pay.yaml 
    ingress.networking.k8s.io/pay-ingress created
    
    controlplane ~ ➜  k get ing -A
    NAMESPACE        NAME                 CLASS    HOSTS   ADDRESS        PORTS   AGE
    app-space        ingress-wear-watch   <none>   *       10.103.62.71   80      25m
    critical-space   pay-ingress          <none>   *                      80      7s  

  38. 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-nginx
    namespace/ingress-nginx created
    
    controlplane ~ ➜  k get ns
    NAME              STATUS   AGE
    app-space         Active   67s
    default           Active   8m20s
    ingress-nginx     Active   2s
    kube-flannel      Active   8m14s
    kube-node-lease   Active   8m20s
    kube-public       Active   8m20s
    kube-system       Active   8m20s
    

    Create the ConfigMap.

    controlplane ~ ➜  k create configmap ingress-nginx-controller --namespace ingress-nginx $do
    apiVersion: v1
    kind: ConfigMap
    metadata:
      creationTimestamp: null
      name: ingress-nginx-controller
      namespace: ingress-nginx 
    
    controlplane ~ ➜  k create configmap ingress-nginx-controller --namespace ingress-nginx $do > cm-ingress-nginx-controller.yml
    
    controlplane ~ ➜  k create configmap ingress-nginx-controller --namespace ingress-nginx
    configmap/ingress-nginx-controller created
    
    controlplane ~ ➜  k get cm -n ingress-nginx 
    NAME                       DATA   AGE
    ingress-nginx-controller   0      53s
    kube-root-ca.crt           1      3m18s

    Next, create the service accounts.

    controlplane ~ ➜  k create sa ingress-nginx-admission --namespace ingress-nginx $do
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: null
      name: ingress-nginx-admission
      namespace: ingress-nginx
    
    controlplane ~ ➜  k create sa ingress-nginx-admission --namespace ingress-nginx $do > sa-ingress-nginx-admission.yml
    
    controlplane ~ ➜  k create sa ingress-nginx-admission --namespace ingress-nginx
    serviceaccount/ingress-nginx-admission created
    
    controlplane ~ ➜  k create sa ingress-nginx --namespace ingress-nginx
    serviceaccount/ingress-nginx-admission created
    
    controlplane ~ ➜  k get sa -n ingress-nginx 
    NAME                      SECRETS   AGE
    default                   0         8m53s
    ingress-nginx             0         67s
    ingress-nginx-admission   0         14s

    Fix the ingress-controller.yaml and apply afterwards.

    ## ingress-controller.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
        app.kubernetes.io/version: 1.1.2
        helm.sh/chart: ingress-nginx-4.0.18
      name: ingress-nginx-controller
      namespace: ingress-nginx
    spec:
      minReadySeconds: 0
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app.kubernetes.io/component: controller
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/name: ingress-nginx
      template:
        metadata:
          labels:
            app.kubernetes.io/component: controller
            app.kubernetes.io/instance: ingress-nginx
            app.kubernetes.io/name: ingress-nginx
        spec:
          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/key
            env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: LD_PRELOAD
              value: /usr/local/lib/libmimalloc.so
            image: registry.k8s.io/ingress-nginx/controller:v1.1.2@sha256:28b11ce69e57843de44e3db6413e98d09de0f6688e33d4bd384002a44f78405c
            imagePullPolicy: IfNotPresent
            lifecycle:
              preStop:
                exec:
                  command:
                  - /wait-shutdown
            livenessProbe:
              failureThreshold: 5
              httpGet:
                path: /healthz
                port: 10254
                scheme: HTTP
              initialDelaySeconds: 10
              periodSeconds: 10
              successThreshold: 1
              timeoutSeconds: 1
            name: controller
            ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - containerPort: 443
              name: https
              protocol: TCP
            - containerPort: 8443
              name: webhook
              protocol: TCP
            readinessProbe:
              failureThreshold: 3
              httpGet:
                path: /healthz
                port: 10254
                scheme: HTTP
              initialDelaySeconds: 10
              periodSeconds: 10
              successThreshold: 1
              timeoutSeconds: 1
            resources:
              requests:
                cpu: 100m
                memory: 90Mi
            securityContext:
              allowPrivilegeEscalation: true
              capabilities:
                add:
                - NET_BIND_SERVICE
                drop:
                - ALL
              runAsUser: 101
            volumeMounts:
            - mountPath: /usr/local/certificates/
              name: webhook-cert
              readOnly: true
          dnsPolicy: ClusterFirst
          nodeSelector:
            kubernetes.io/os: linux
          serviceAccountName: ingress-nginx
          terminationGracePeriodSeconds: 300
          volumes:
          - name: webhook-cert
            secret:
              secretName: ingress-nginx-admission
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
        app.kubernetes.io/version: 1.1.2
        helm.sh/chart: ingress-nginx-4.0.18
      name: ingress-nginx-controller
      namespace: ingress-nginx
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
        nodePort: 30080
      selector:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
      type: NodePort 
    controlplane ~ ➜  k get -n ingress-nginx po
    NAME                                       READY   STATUS      RESTARTS   AGE
    ingress-nginx-admission-create-wtzf6       0/1     Completed   0          7m32s
    ingress-nginx-controller-cc9f46d74-fmc65   0/1     Running     0          13s
    
    controlplane ~ ➜  k get -n ingress-nginx svc
    NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
    ingress-nginx-controller             NodePort    10.104.168.175   <none>        80:30080/TCP   18s
    ingress-nginx-controller-admission   ClusterIP   10.105.49.126    <none>        443/TCP        7m37s 

    Next, create the ingress resource. But first, get the services in the app-space namespace.

    controlplane ~ ➜  k get svc -n app-space
    NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    default-http-backend   ClusterIP   10.104.25.24    <none>        80/TCP     29m
    video-service          ClusterIP   10.97.188.119   <none>        8080/TCP   29m
    wear-service           ClusterIP   10.98.183.145   <none>        8080/TCP   29m 
    ## ingress-resource.yaml 
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: app-ingress
      namespace: app-space
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx-example
      rules:
      - http:
          paths:
          - path: /wear
            pathType: Prefix
            backend:
              service:
                name: wear-service
                port:
                  number: 8080
          - path: /watch
            pathType: Prefix
            backend:
              service:
                name: video-service
                port:
                  number: 8080
    controlplane ~ ➜  k apply -f ingress-resource.yaml 
    ingress.networking.k8s.io/app-ingress created
    
    controlplane ~ ➜  k get ing -n app-space
    NAME          CLASS           HOSTS   ADDRESS   PORTS   AGE
    app-ingress   nginx-example   *                 80      12s 

Back to the top