Security
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 secret type must we choose for docker registry?
Answer
root@controlplane ~ ➜ k create secret --help | grep dockerdocker-registry Create a secret for use with a Docker registry -
Update the image of the deployment to use a new image from myprivateregistry.com:5000
root@controlplane ~ ➜ k get deployments.appsNAME READY UP-TO-DATE AVAILABLE AGEweb 2/2 2 2 104sAnswer
We simply need to append at the beginning of the image.
k edit deployments.appsspec:containers:- image: myprivateregistry.com:5000/nginx:alpine -
Create a secret object with the credentials required to access the registry.
- Name: private-reg-cred
- Username: dock_user
- Password: dock_password
- Server: myprivateregistry.com:5000
- Email: dock_user@myprivateregistry.com
Secret Type: docker-registry
Answer
Based on: https://kubernetes.io/docs/concepts/configuration/secret/
kubectl create secret docker-registry private-reg-cred \--docker-email=dock_user@myprivateregistry.com \--docker-username=dock_user \--docker-password=dock_password \--docker-server=myprivateregistry.com:5000root@controlplane ~ ➜ kubectl create secret docker-registry private-reg-cred \> --docker-email=dock_user@myprivateregistry.com \> --docker-username=dock_user \> --docker-password=dock_password \> --docker-server=myprivateregistry.com:5000secret/private-reg-cred createdroot@controlplane ~ ➜ k get secretsNAME TYPE DATA AGEprivate-reg-cred kubernetes.io/dockerconfigjson 1 8sroot@controlplane ~ ➜ k describe secrets private-reg-credName: private-reg-credNamespace: defaultLabels: <none>Annotations: <none>Type: kubernetes.io/dockerconfigjsonData====.dockerconfigjson: 176 bytesWhen we try to generate the YAML file, we can see that the data is hidden.
root@controlplane ~ ➜ k get secrets private-reg-cred -o yamlapiVersion: v1data:.dockerconfigjson: eyJhdXRocyI6eyJteXByaXZhdGVyZWdpc3RyeS5jb206NTAwMCI6eyJ1c2VybmFtZSI6ImRvY2tfdXNlciIsInBhc3N3b3JkIjoiZG9ja19wYXNzd29yZCIsImVtYWlsIjoiZG9ja191c2VyQG15cHJpdmF0ZXJlZ2lzdHJ5LmNvbSIsImF1dGgiOiJaRzlqYTE5MWMyVnlPbVJ2WTJ0ZmNHRnpjM2R2Y21RPSJ9fX0=kind: Secretmetadata:creationTimestamp: "2023-12-30T17:26:54Z"name: private-reg-crednamespace: defaultresourceVersion: "2092"uid: 7bd9c254-9f9e-425a-b7f2-589c85f5df0atype: kubernetes.io/dockerconfigjson -
Configure the deployment to use credentials from the new secret to pull images from the private registry
root@controlplane ~ ➜ k get secretsNAME TYPE DATA AGEprivate-reg-cred kubernetes.io/dockerconfigjson 1 2m40sroot@controlplane ~ ➜ k get deployments.appsNAME READY UP-TO-DATE AVAILABLE AGEweb 2/2 1 2 13mAnswer
root@controlplane ~ ➜ k get deployments.apps web -o yaml > web.yamlroot@controlplane ~ ➜ k delete -f web.yamldeployment.apps "web" deletedroot@controlplane ~ ➜ k get deployments.appsNo resources found in default namespace.Modify the YAML file. Follow: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
spec:containers:- image: myprivateregistry.com:5000/nginx:alpineimagePullPolicy: IfNotPresentname: nginxresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FileimagePullSecrets:- name: private-reg-credroot@controlplane ~ ➜ k apply -f web.yamldeployment.apps/web createdroot@controlplane ~ ➜ k get deployments.appsNAME READY UP-TO-DATE AVAILABLE AGEweb 2/2 2 2 3s -
What is the user used to execute the sleep process within the ubuntu-sleeper pod?
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEubuntu-sleeper 1/1 Running 0 76sAnswer
Enter the pod and run whoami.
controlplane ~ ➜ k exec -it ubuntu-sleeper -- whoamiroot -
Edit the pod ubuntu-sleeper to run the sleep process with user ID 1010.
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEubuntu-sleeper 1/1 Running 0 76sAnswer
controlplane ~ ➜ k get po ubuntu-sleeper -o yaml > ubuntu-sleeper.yamlcontrolplane ~ ✦ ➜ k delete po ubuntu-sleeper $nowWarning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.pod "ubuntu-sleeper" force deletedcontrolplane ~ ✦ ✖ k get poNo resources found in default namespace.## ubuntu-sleeper.yamlapiVersion: v1kind: Podmetadata:creationTimestamp: "2023-12-30T17:40:14Z"name: ubuntu-sleepernamespace: defaultresourceVersion: "814"uid: f866a186-25d6-45f3-9fb8-f8e37cf91c38spec:securityContext:runAsUser: 1010containers:- command:- sleep- "4800"image: ubuntuimagePullPolicy: Alwaysname: ubuntucontrolplane ~ ➜ k apply -f ubuntu-sleeper.yamlpod/ubuntu-sleeper createdcontrolplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEubuntu-sleeper 1/1 Running 0 3scontrolplane ~ ➜ k exec -it ubuntu-sleeper -- whoamiwhoami: cannot find name for user ID 1010command terminated with exit code 1 -
Update pod ubuntu-sleeper to run as Root user and with the SYS_TIME capability.
controlplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEubuntu-sleeper 1/1 Running 0 2m48sAnswer
controlplane ~ ➜ k get po ubuntu-sleeper -o yaml > ubuntu-sleeper.yamlcontrolplane ~ ➜ k delete po ubuntu-sleeper $nowWarning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.pod "ubuntu-sleeper" force deletedcontrolplane ~ ➜ k get poNo resources found in default namespace.## ubuntu-sleeper.yaml---apiVersion: v1kind: Podmetadata:name: ubuntu-sleepernamespace: defaultspec:containers:- command:- sleep- "4800"image: ubuntuname: ubuntu-sleepersecurityContext:capabilities:add: ["SYS_TIME"]controlplane ~ ➜ k apply -f ubuntu-sleeper.yamlpod/ubuntu-sleeper createdcontrolplane ~ ➜ k get poNAME READY STATUS RESTARTS AGEubuntu-sleeper 1/1 Running 0 6scontrolplane ~ ➜ k exec -it ubuntu-sleeper -- whoamiroot -
How many network policies do you see in the environment?
Answer
controlplane ~ ➜ k api-resources | grep -i networkingressclasses networking.k8s.io/v1 false IngressClassingresses ing networking.k8s.io/v1 true Ingressnetworkpolicies netpol networking.k8s.io/v1 true NetworkPolicycontrolplane ~ ➜ k get netpolNAME POD-SELECTOR AGEpayroll-policy name=payroll 37s -
Which pod is the Network Policy applied on?
controlplane ~ ➜ k get netpolNAME POD-SELECTOR AGEpayroll-policy name=payroll 37sAnswer
controlplane ~ ➜ k describe networkpolicies.networking.k8s.io payroll-policyName: payroll-policyNamespace: defaultCreated on: 2023-12-30 13:01:40 -0500 ESTLabels: <none>Annotations: <none>Spec:PodSelector: name=payrollAllowing ingress traffic:To Port: 8080/TCPFrom:PodSelector: name=internalNot affecting egress trafficPolicy Types: 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 -