Deploy an application that requires additional operating system privileges to run.
Deploy an application that requires access to the Kubernetes APIs to perform cluster maintenance tasks.
Outcomes
Deploy a cluster maintenance application that must be executed regularly.
Grant application access to Kubernetes APIs.
Run an application with a security context constraint (SCC).
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
[student@workstation ~]$ lab start appsec-review
In this exercise, you deploy two applications:
A legacy payroll application that must run as the fixed 0 UID to open the TCP 80 port.
A project cleaner deletes projects with the appsec-review-cleaner label and that are longer than 10 seconds.
This short expiration time is deliberate for the lab purposes.
You must deploy the project cleaner application to delete obsolete projects every minute.
The lab start command copies the required files for the exercise to the lab directory:
A deployment manifest with the payroll application.
A pod manifest that contains a project cleaner application. You can use this pod to test the project cleaner application and copy the pod specification into the cron job to complete the exercise.
A manifest with the project-cleaner cluster role that grants the application access to find and delete namespaces.
A cron job template file that you can edit to create cron jobs.
A script that generates projects to verify that the project cleaner application works.
Instructions
Log in to your OpenShift cluster as the developer user with the developer password and create the appsec-review project.
Log in as the developer user.
[student@workstation ~]$ oc login -u developer -p developer \
https://api.ocp4.example.com:6443
Login successful.
...output omitted...Create the appsec-review project.
[student@workstation ~]$ oc new-project appsec-review
Now using project "appsec-review" on server ...
...output omitted...Change to the ~/DO280/labs/appsec-review directory and deploy the payroll application in the payroll-app.yaml file.
Verify that the application cannot run.
Change to the ~/DO280/labs/appsec-review directory to access the lab files.
[student@workstation ~]$ cd ~/DO280/labs/appsec-reviewRun the oc apply command to create the payroll deployment.
[student@workstation appsec-review]$ oc apply -f payroll-app.yaml
deployment.apps/payroll-api createdVerify that the application fails to run by reading the deployment logs.
[student@workstation appsec-review]$oc logs deployment/payroll-api[2023-03-13 08:13:30 +0000] [1] [INFO] Starting gunicorn 20.1.0 [2023-03-13 08:13:30 +0000] [1] [ERROR] Retrying in 1 second. [2023-03-13 08:13:31 +0000] [1] [ERROR] Retrying in 1 second. [2023-03-13 08:13:32 +0000] [1] [ERROR] Retrying in 1 second. [2023-03-13 08:13:33 +0000] [1] [ERROR] Retrying in 1 second. [2023-03-13 08:13:34 +0000] [1] [ERROR] Retrying in 1 second. [2023-03-13 08:13:35 +0000] [1] [ERROR]Can't connect to ('', 80)
The container in the pod runs as root to listen on port 80.
As the admin user, look for an SCC that allows the workload in the payroll-app.yaml deployment to run.
Log in as the admin user with the redhatocp password.
[student@workstation appsec-review]$ oc login -u admin -p redhatocp \
https://api.ocp4.example.com:6443
Login successful.
...output omitted...Run the oc adm policy scc-subject-review command to get an SCC that allows the application to run.
[student@workstation appsec-review]$oc adm policy scc-subject-review \ -f payroll-app.yamlRESOURCE ALLOWED BY Deployment/payroll-apianyuid
Create the payroll-sa service account and assign to it the SCC that the application requires.
Then, assign the payroll-sa service account to the payroll-api deployment.
Run the oc create command to create the payroll-sa service account.
[student@workstation appsec-review]$ oc create sa payroll-sa
serviceaccount/payroll-sa createdAssign the anyuid SCC to the payroll-sa service account.
[student@workstation appsec-review]$ oc adm policy \
add-scc-to-user anyuid -z payroll-sa
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "payroll-sa"Use the oc set serviceaccount command to add the payroll-sa service account to the payroll-api deployment.
[student@workstation appsec-review]$ oc set serviceaccount deployment \
payroll-api payroll-sa
deployment.apps/payroll-api serviceaccount updatedVerify that the payroll API is accessible by running the curl command from the payroll-api deployment.
Use the http://localhost/payments/status URL to verify that the API is working.
Use the oc exec command with the payroll-api deployment to run the curl command.
Provide the -sS option to hide progress output and show errors.
[student@workstation appsec-review]$ oc exec deployment/payroll-api \
-- curl -sS http://localhost/payments/status
[{"id":240,"status":"Paid","userId":1003},{"id":241,"status":"Pending","userId":1003}]Create the project-cleaner-sa service account and assign it to the project-cleaner.yaml pod manifest to configure the application permissions.
Create the project-cleaner-sa service account.
[student@workstation appsec-review]$ oc create sa project-cleaner-sa
serviceaccount/project-cleaner-sa createdEdit the project-cleaner.yaml pod manifest file to use the project-cleaner-sa service account.
apiVersion: v1
kind: Pod
metadata:
name: project-cleaner
namespace: appsec-review
spec:
restartPolicy: Never
serviceAccountName: project-cleaner-sa
containers:
- name: project-cleaner
...output omitted...Create the project-cleaner role in the cluster-role.yaml file and assign it to the project-cleaner-sa service account.
Create the project-cleaner cluster role by applying the cluster-role.yaml manifest file.
[student@workstation appsec-review]$ oc apply -f cluster-role.yaml
clusterrole.rbac.authorization.k8s.io/project-cleaner createdUse the oc adm policy add-clusterrole-to-user command to add the project-cleaner role to the project-cleaner-sa service account.
[student@workstation appsec-review]$ oc adm policy add-cluster-role-to-user \
project-cleaner -z project-cleaner-sa
clusterrole.rbac.authorization.k8s.io/project-cleaner added: "project-cleaner-sa"Edit the cron-job.yaml file to create the appsec-review-cleaner cron job by using the project-cleaner.yaml pod manifest as the job template.
Create the cron job and configure it to run every minute.
You can use the solution file in the ~/DO280/solutions/appsec-review/cron-job.yaml path.
Edit the cron-job.yaml file to replace the CHANGE_ME string with the "*/1 * * * *" schedule to execute the job every minute.
apiVersion: batch/v1
kind: CronJob
metadata:
name: appsec-review-cleaner
namespace: appsec-review
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Forbid
jobTemplate:
...output omitted...Replace the CHANGE_ME label in the jobTemplate definition with the spec definition from the project-cleaner.yaml pod manifest.
Although the long image name might show across two lines, you must add it as one line.
apiVersion: batch/v1
kind: CronJob
metadata:
name: appsec-review-cleaner
namespace: appsec-review
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
serviceAccountName: project-cleaner-sa
containers:
- name: project-cleaner
image: registry.ocp4.example.com:8443/redhattraining/do280-project-cleaner:v1.1
imagePullPolicy: Always
env:
- name: "PROJECT_TAG"
value: "appsec-review-cleaner"
- name: "EXPIRATION_SECONDS"
value: "10"Create the cron job.
[student@workstation appsec-review]$ oc apply -f cron-job.yaml
cronjob.batch/appsec-review-cleaner createdOptionally, verify that the project cleaner executed correctly.
Use the generate-projects.sh script from the lab directory to generate projects for deletion.
Wait for the next job execution and print the logs from that job's pod.
Run the generate-projects.sh script to create test projects that the project cleaner will delete the next time that it runs.
[student@workstation appsec-review]$ ./generate-projects.sh
obsolete-appsec-review-1 created at 15:29:14
obsolete-appsec-review-2 created at 15:29:15
obsolete-appsec-review-3 created at 15:29:16
namespace/obsolete-appsec-review-1 labeled
namespace/obsolete-appsec-review-2 labeled
namespace/obsolete-appsec-review-3 labeled
Last appsec-review-cleaner label applied at 15:29:20
...output omitted...List the pods in the appsec-review project until you see a pod with the Completed status that is later than the last label that the script applied.
[student@workstation appsec-review]$oc get podsNAME READY STATUS RESTARTS AGE appsec-review-cleaner-27909204-g49gr 0/1 Completed 0 2m37s appsec-review-cleaner-27909205-q2f2t 0/1 Completed 0 97sappsec-review-cleaner-27909206-xcswb0/1Completed037s
Print the logs from the last completed job, to verify that it deleted the obsolete projects.
[student@workstation appsec-review]$ oc logs pod/appsec-review-cleaner-27909206-xcswb
...output omitted...
Namespace 'obsolete-appsec-review-1' deleted
Namespace 'obsolete-appsec-review-2' deleted
Namespace 'obsolete-appsec-review-3' deletedChange to the home directory to prepare for the next exercise.
[student@workstation appsec-review]$ cd