Services and Networking
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
-
What is the targetPort configured on the kubernetes service?
controlplane ~ ➜ k get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.43.0.1 <none> 443/TCP 6m50sAnswer
controlplane ~ ➜ k describe svc kubernetesName: kubernetesNamespace: defaultLabels: component=apiserverprovider=kubernetesAnnotations: <none>Selector: <none>Type: ClusterIPIP Family Policy: SingleStackIP Families: IPv4IP: 10.43.0.1IPs: 10.43.0.1Port: https 443/TCPTargetPort: 6443/TCPEndpoints: 192.36.199.3:6443Session Affinity: NoneEvents: <none> -
Create a new service to access the web application using the service-definition-1.yaml file.
- Name: webapp-service
- Type: NodePort
- targetPort: 8080
- port: 8080
- nodePort: 30080
- selector: name: simple-webapp
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEsimple-webapp-deployment-7b4d799f4d-z2knh 1/1 Running 0 45ssimple-webapp-deployment-7b4d799f4d-dn9lb 1/1 Running 0 45ssimple-webapp-deployment-7b4d799f4d-w7rgr 1/1 Running 0 45ssimple-webapp-deployment-7b4d799f4d-74bj4 1/1 Running 0 45scontrolplane ~ ➜ k get deployments.appsNAME READY UP-TO-DATE AVAILABLE AGEsimple-webapp-deployment 4/4 4 4 49sAnswer
controlplane ~ ➜ k expose deployment simple-webapp-deployment --name webapp-service --type NodePort --port 8080 --target-port 8080 $doapiVersion: v1kind: Servicemetadata:creationTimestamp: nullname: webapp-servicespec:ports:- port: 8080protocol: TCPtargetPort: 8080selector:name: simple-webapptype: NodePortstatus:loadBalancer: {}controlplane ~ ➜ k expose deployment simple-webapp-deployment --name webapp-service --type NodePort --port 8080 --target-port 8080 $do > webapp-service.yml## webapp-service.ymlapiVersion: v1kind: Servicemetadata:creationTimestamp: nullname: webapp-servicespec:ports:- port: 8080protocol: TCPtargetPort: 8080nodePort: 30080selector:name: simple-webapptype: NodePortstatus:loadBalancer: {}ontrolplane ~ ➜ k apply -f webapp-service.ymlservice/webapp-service createdcontrolplane ~ ➜ k get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.43.0.1 <none> 443/TCP 13mwebapp-service NodePort 10.43.68.185 <none> 8080:30080/TCP 3s -
What type of traffic is this Network Policy configured to handle?
controlplane ~ ➜ k get netpolNAME POD-SELECTOR AGEpayroll-policy name=payroll 21sAnswer
controlplane ~ ➜ k get netpol payroll-policy -o yaml | grep -i policyTypes{"apiVersion":"networking.k8s.io/v1","kind":"NetworkPolicy","metadata":{"annotations":{},"name":"payroll-policy","namespace":"default"},"spec":{"ingress":[{"from":[{"podSelector":{"matchLabels":{"name":"internal"}}}],"ports":[{"port":8080,"protocol":"TCP"}]}],"podSelector":{"matchLabels":{"name":"payroll"}},"policyTypes":["Ingress"]}} -
Create a network policy to allow traffic from the Internal application only to the payroll-service and db-service. Use the spec given below. You might want to enable ingress traffic to the pod to test your rules in the UI.
-
Policy Name: internal-policy
-
Policy Type: Egress
-
Egress Allow: payroll
-
Payroll Port: 8080
-
Egress Allow: mysql
-
MySQL Port: 3306
Answer
## internal-policy.yamlapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: internal-policynamespace: defaultspec:podSelector:matchLabels:name: internalpolicyTypes:- Egress- Ingressingress:- {}egress:- to:- podSelector:matchLabels:name: mysqlports:- protocol: TCPport: 3306- to:- podSelector:matchLabels:name: payrollports:- protocol: TCPport: 8080- ports:- port: 53protocol: UDP- port: 53protocol: TCPNote: We have also allowed Egress traffic to TCP and UDP port. This has been added to ensure that the internal DNS resolution works from the internal pod.
controlplane ~ ➜ k apply -f internal-policy.yamlnetworkpolicy.networking.k8s.io/internal-policy createdcontrolplane ~ ➜ k get networkpolicies.networking.k8s.ioNAME POD-SELECTOR AGEinternal-policy name=internal 3spayroll-policy name=payroll 17m -
-
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 Host configured on the Ingress Resource?
controlplane ~ ➜ k get ing -ANAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGEapp-space ingress-wear-watch <none> * 10.99.14.178 80 4m20sAnswer
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 ~ ➜ export do="--dry-run=client -o yaml"controlplane ~ ➜ export now="--force --grace-period=0"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 --namespace ingress-nginxserviceaccount/ingress-nginx createdcontrolplane ~ ➜ k create sa ingress-nginx-admission --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