Automate periodic cluster node cleaning for a development environment.
Outcomes
Manually delete unused images from the nodes.
Automate the image pruning by using a cron job.
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
[student@workstation ~]$ lab start appsec-prune
Instructions
Log in to the OpenShift cluster and switch to the appsec-prune project.
Log in to the cluster as the admin user.
[student@workstation ~]$ oc login -u admin -p redhatocp \
https://api.ocp4.example.com:6443
Login successful.
...output omitted...Create the appsec-prune project.
[student@workstation ~]$ oc new-project appsec-prune
Now using project "appsec-prune" on server "https://api.ocp4.example.com:6443".
...output omitted...Change to the ~/DO280/labs/appsec-prune directory.
[student@workstation ~]$ cd ~/DO280/labs/appsec-prune
[student@workstation appsec-prune]$Clean up the unused container images in the node.
List the deployments and pods in the prune-apps namespace.
Each deployment has a pod that uses a different image.
[student@workstation appsec-prune]$oc get deployments -n prune-apps -o wideNAME ...IMAGES... nginx-ubi7 ...registry.ocp4.example.com:8443/ubi7/nginx-118:latest... nginx-ubi8 ...registry.ocp4.example.com:8443/ubi8/nginx-118:latest... nginx-ubi9 ...registry.ocp4.example.com:8443/ubi9/nginx-120:latest... [student@workstation appsec-prune]$oc get pods -n prune-appsNAME READY STATUS RESTARTS AGE pod/nginx-ubi7-594f548665-qvfq6 1/1 Running 0 5m pod/nginx-ubi8-855f6959b-jvs6h 1/1 Running 0 5m pod/nginx-ubi9-dd4c566d7-7vrrv 1/1 Running 0 5m
List the container images in the node.
The node has three httpd images and three nginx images.
[student@workstation appsec-prune]$oc debug node/master01 -- \ chroot /host crictl images | egrep '^IMAGE|httpd|nginx'...output omitted... Starting pod/master01-debug ... To use host binaries, run `chroot /host`IMAGETAGIMAGE ID ... registry.ocp4.example.com:8443/rhscl/httpd-24-rhel7latestc19a96fc0b019 ... registry.ocp4.example.com:8443/ubi8/httpd-24lateste54df115d5f0c ... registry.ocp4.example.com:8443/ubi9/httpd-24latest4afe283d911ab ... registry.ocp4.example.com:8443/ubi7/nginx-118latest3adc6d109b363 ... registry.ocp4.example.com:8443/ubi8/nginx-118latest90f91167f6d1d ... registry.ocp4.example.com:8443/ubi9/nginx-120latest0227435f34784 ... Removing debug pod ... ...output omitted...
Remove the unused images in the node.
Only the httpd container images are deleted, because no other container uses them.
[student@workstation appsec-prune]$oc debug node/master01 -- \ chroot /host crictl rmi --prune...output omitted... Starting pod/master01-debug ... To use host binaries, run `chroot /host`E121300:43:40.788951 166213 remote_image.go:266] "RemoveImage from image service failed" err="rpc error: code = Unknown desc = Image used by 5027ebb4...: image is in use by a container" image="c464e04f..."Deleted: registry.ocp4.example.com:8443/
rhscl/httpd-24-rhel7:latestDeleted: registry.ocp4.example.com:8443/ubi8/httpd-24:latestDeleted: registry.ocp4.example.com:8443/ubi9/httpd-24:latestRemoving debug pod ... ...output omitted...
Delete the deployments in the prune-apps namespace to remove the pods that use the nginx images.
[student@workstation appsec-prune]$oc delete deployment nginx-ubi{7,8,9} \ -n prune-appsdeployment.apps "nginx-ubi7"deleteddeployment.apps "nginx-ubi8"deleteddeployment.apps "nginx-ubi9"deleted
The cron job removes the unused container images in a later step.
Create a cron job to automate the image pruning process.
Edit the ~/DO280/labs/appsec-prune/configmap-prune.yaml file to match the following specification:
apiVersion: v1 kind: ConfigMap metadata: name:maintenancelabels: ge: appsec-prune app: crictl data: maintenance.sh: |#!/bin/bash -euNODES=$(oc get nodes -o=name)for NODE in ${NODES} do echo ${NODE} oc debug ${NODE} -- \ chroot /host \/bin/bash -euxc 'crictl images ; crictl rmi --prune'done
The ~/DO280/solutions/appsec-prune/configmap-prune.yaml file contains the correct configuration and can be used for comparison.
Create the configuration map:
[student@workstation appsec-prune]$ oc apply -f configmap-prune.yaml
configmap/maintenance createdEdit the ~/DO280/labs/appsec-prune/cronjob-prune.yaml file to match the following specification:
apiVersion: batch/v1 kind: CronJob metadata: name:image-prunerlabels: ge: appsec-prune app: crictl spec: schedule:'*/4 * * * *'jobTemplate: spec: template: spec: dnsPolicy: ClusterFirst restartPolicy: Never containers: - name: crictl image:registry.ocp4.example.com:8443/openshift/origin-cli:4.14resources: {} command: -
/opt/maintenance.shvolumeMounts: - name: scripts mountPath: /opt volumes: - name: scripts configMap: name: maintenance defaultMode: 0555
The |
The ~/DO280/solutions/appsec-prune/cronjob-prune.yaml file contains the correct configuration and can be used for comparison.
Apply the changes to the image pruner resource.
[student@workstation appsec-prune]$ oc apply -f cronjob-prune.yaml
cronjob.batch/image-pruner createdA warning indicates that the pod would violate several policies. The pod fails when the cron job is executed, because it lacks permissions to execute the maintenance task. A fix for this issue is implemented in a later step.
Wait until the cron job is scheduled, and get the name of the associated job.
The job completion status is 0/1, and the pod has an error status.
Press Ctrl+C to exit the watch command.
[student@workstation appsec-prune]$watch oc get cronjobs,jobs,podsEvery 2.0s: oc get cronjobs,jobs,pods workstation: Mon Feb 13 13:00:47 2024 NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/image-pruner */4 * * * * False 1 53s 6m NAMECOMPLETIONSDURATION AGE job.batch/image-pruner-278838000/130s 30s NAME READYSTATUSRESTARTS AGEpod/image-pruner-27950092-g76lb0/1Error0 15s
Get the logs of the pod. A permission error is displayed.
[student@workstation appsec-prune]$oc logs pod/image-pruner-27950092-g76lbError from server (Forbidden): nodes is forbidden: User "system:serviceaccount:appsec-prune:default" cannot list resource "nodes" in API group "" at the cluster scope
Delete the failed cron job. This action deletes the failed job and pod resources.
[student@workstation appsec-prune]$ oc delete cronjob/image-pruner
cronjob.batch "image-pruner" deletedSet the appropriate permissions to run the image pruner cron job.
Add the privileged SCC to the default service account of the namespace.
[student@workstation ~]$ oc adm policy add-scc-to-user -z default privileged
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged added: "default"Add the cluster-admin role to the default service account of the namespace.
[student@workstation ~]$ oc adm policy add-cluster-role-to-user \
cluster-admin -z default
clusterrole.rbac.authorization.k8s.io/cluster-admin added: "default"Create the cron job resource again.
[student@workstation appsec-prune]$ oc apply -f cronjob-prune.yaml
cronjob.batch/image-pruner createdWait until the new job and the pod are created.
Press Ctrl+C to exit the watch command when the job and the pod are marked as completed.
[student@workstation appsec-prune]$watch oc get cronjobs,jobs,podsEvery 2.0s: oc get cronjobs,jobs,pods workstation: Mon Feb 13 11:58:44 2024 NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/image-pruner */4 * * * * False 0 30s 2m NAMECOMPLETIONSDURATION AGE job.batch/image-pruner-278836601/19s 30s NAME READYSTATUSRESTARTS AGEpod/image-pruner-27883660-2ghvv0/1Completed0 30s
Get the logs of the pod that executed the maintenance task.
[student@workstation appsec-prune]$oc logs pod/image-pruner-...output omitted... +27883660-2ghvv| tailcrictl rmi --pruneE010618:08:31.686489 374926 remote_image.go:266] "RemoveImage from image service failed" err="rpc error: code = Unknown desc = Image used by 0c9ab998...: image is in use by a container" image="c464e04f..."Deleted: registry.ocp4.example.com:8443/ubi7/
nginx-118:latestDeleted: registry.ocp4.example.com:8443/ubi8/nginx-118:latestDeleted: registry.ocp4.example.com:8443/ubi9/nginx-120:latestRemoving debug pod ... ...output omitted...
Clean up resources.
Change to the student user home directory.
[student@workstation appsec-prune]$ cd
[student@workstation ~]$Ensure that you are working on the appsec-prune project.
[student@workstation ~]$oc projectUsing project"appsec-prune"on server "https://api.ocp4.example.com:6443".
Remove the cron job resource and the configuration map.
[student@workstation ~]$ oc delete cronjob/image-pruner configmap/maintenance
cronjob.batch "image-pruner" deleted
configmap "maintenance" deletedRemove the security constraint from the service account.
[student@workstation ~]$ oc adm policy remove-scc-from-user \
-z default privileged
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged removed: "default"Remove the role from the service account.
[student@workstation ~]$ oc adm policy remove-cluster-role-from-user \
cluster-admin -z default
clusterrole.rbac.authorization.k8s.io/cluster-admin removed: "default"Delete the appsec-prune project.
[student@workstation ~]$ oc delete project appsec-prune prune-apps
project.project.openshift.io "appsec-prune" deleted
project.project.openshift.io "prune-apps" deleted