Skip to main content

Question 41 | CKS Challenge 1 - Complete Security Setup

Take me to the lab!

Please note that the competition status for CKS Challenges is ended. Please do not submit a solution. It will not be scored.

There are 6 images listed in the diagram. Using Aquasec Trivy (which is already installed on the controlplane node), identify the image that has the least number of critical vulnerabilities and use it to deploy the alpha-xyz deployment.

Secure this deployment by enforcing the AppArmor profile called custom-nginx.

Expose this deployment with a ClusterIP type service and make sure that only incoming connections from the pod called middleware is accepted and everything else is rejected.

Click on each icon (in the lab) to see more details. Once done, click the Check button to test your work.

Do the tasks in this order:

namespace

All the action is taking place in the alpha namespace

kubectl config set-context --current --namespace alpha

alpha-pv

  • A persistentVolume called alpha-pv has already been created. Do not modify it. Inspect the parameters used to create it.
kubectl describe pv alpha-pv

Note StorageClass, Access Modes, Capacity, VolumeMode

alpha-pvc

  • alpha-pvc should be bound to alpha-pv. Delete and Re-create it if necessary.
kubectl get pvc alpha-pvc

Status is pending, i.e it wont bind.

Delete the PVC and recreate it with values for storage class, access modes and capacity matching those of the PV

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: alpha-pvc
namespace: alpha
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: local-storage
volumeMode: Filesystem

images

  • Permitted images are: nginx:alpine, bitnami/nginx, nginx:1.13, nginx:1.17, nginx:1.16and nginx:1.14. Use trivy to find the image with the least number of CRITICAL vulnerabilities.

Inspect all images

docker image ls

Note there are additional images other than those stated

Loop over the images we want (by filtering out those we don't), and trivy them getting the information we need

for i in $(docker image ls --format '{{.Repository}}:{{.Tag}}' | grep nginx | grep -v none)
do
echo -n "$i "
trivy i -s CRITICAL $i | grep Total | awk '{print $2}'
done

nginx:alpine 0 bitnami/nginx:latest 3 nginx:latest 27 nginx:1.17 43 nginx:1.16 43 nginx:1.14 64 nginx:1.13 85

We can see that nginx:alpine has the least (zero) criticals, which is kind of as expected! We will use this image when we come to deploy the pod later.

custom-nginx

  • Move the AppArmor profile /root/usr.sbin.nginx to /etc/apparmor.d/usr.sbin.nginx on the controlplane node
  • Load the AppArmor profile called custom-nginx and ensure it is enforced.
mv /root/usr.sbin.nginx /etc/apparmor.d/usr.sbin.nginx

apparmor_parser /etc/apparmor.d/usr.sbin.nginx

alpha-xyz

  • Create a deployment called alpha-xyz that uses the image with the least 'CRITICAL' vulnerabilities? (Use the sample YAML file located at /root/alpha-xyz.yaml to create the deployment. Please make sure to use the same names and labels specified in this sample YAML file!)
  • Deployment has exactly 1 ready replica
  • data-volume is mounted at /usr/share/nginx/html on the pod
  • alpha-xyz deployment uses the custom-nginx apparmor profile (applied to container called nginx). Note that this task is revealed by clicking the arrow between custom-nginx and alpha-xyz

Edit the given file /root/alpha-xyz.yaml and fill in the necessary properties. We need to use the PVC from step 3, the image determined in step 4 and the apparmor profile from step 5

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: alpha-xyz
name: alpha-xyz
namespace: alpha
spec:
replicas: 1
selector:
matchLabels:
app: alpha-xyz
strategy: {}
template:
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/nginx: localhost/custom-nginx
labels:
app: alpha-xyz
spec:
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: alpha-pvc
containers:
- image: nginx:alpine
name: nginx
volumeMounts:
- name: data-volume
mountPath: /usr/share/nginx/html
kubectl apply -f /root/alpha-xyz.yaml

alpha-svc

  • Expose the alpha-xyz as a ClusterIP type service called alpha-svc
  • alpha-svc should be exposed on port: 80 and targetPort: 80
kubectl expose deployment alpha-xyz --type ClusterIP --name alpha-svc --port 80 --target-port 80

restrict-inbound

  • Create a NetworkPolicy called restrict-inbound in the alpha namespace
  • Policy Type = Ingress
  • Inbound access only allowed from the pod called middleware with label app=middleware
  • Inbound access only allowed to TCP port 80 on pods matching the policy
  • Policy should be only applied on pods with label app=alpha-xyz. This task is revealed by clicking the arrow between restrict-inbound and alpha-xyz
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-inbound
namespace: alpha
spec:
podSelector:
matchLabels:
app: alpha-xyz
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: middleware
ports:
- port: 80

Apply this policy

Once all the above tasks are completed, click the Check button.