Skip to content

Conversation

Vincent056
Copy link

What type of PR is this?

What this PR does / why we need it:

This commit introduces a comprehensive guide for manually migrating the Security Profiles Operator (SPO) from namespace-scoped to cluster-scoped Custom Resource Definitions (CRDs).

Which issue(s) this PR fixes:

Does this PR have test?

Special notes for your reviewer:

Does this PR introduce a user-facing change?


This commit introduces a comprehensive guide for manually migrating the Security Profiles Operator (SPO) from namespace-scoped to cluster-scoped Custom Resource Definitions (CRDs).
@openshift-ci openshift-ci bot requested review from xiaojiey and yuumasato July 30, 2025 04:39
Copy link

openshift-ci bot commented Jul 30, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Vincent056

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 30, 2025
SELINUX_TYPES=$(oc get selinuxprofiles,rawselinuxprofiles -A -o json | jq -r '.items[].status.usage' | sort -u)

# Find pods using any of these SELinux types
> $BACKUP_DIR/workload-analysis/selinux-usage.txt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line need to be removed.

### Backup Profile Bindings
```bash
# Backup all profile bindings
for binding in $(oc get profilebindings -n openshift-security-profiles -o name); do
Copy link

@xiaojiey xiaojiey Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When backing up all profile bindings, we can not use -n openshift-security-profiles here. It is better to use --all-namespaces parameter.

# Backup all profile bindings
for binding in $(oc get profilebindings -n openshift-security-profiles -o name); do
name=$(echo $binding | cut -d'/' -f2)
oc get profilebinding $name -n openshift-security-profiles -o json | jq '.' > \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

### Backup Security Profiles
```bash
# Backup seccomp profiles
for profile in $(oc get seccompprofiles -n openshift-security-profiles -o name); do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why only backup the seccompprofiles in ns openshift-security-profiles here? It is better to use --all-namespaces parameter.

# Backup seccomp profiles
for profile in $(oc get seccompprofiles -n openshift-security-profiles -o name); do
name=$(echo $profile | cut -d'/' -f2)
oc get seccompprofile $name -n openshift-security-profiles -o json | jq '.' > \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

done

# Backup SELinux profiles
for profile in $(oc get selinuxprofiles -n openshift-security-profiles -o name); do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

# Backup SELinux profiles
for profile in $(oc get selinuxprofiles -n openshift-security-profiles -o name); do
name=$(echo $profile | cut -d'/' -f2)
oc get selinuxprofile $name -n openshift-security-profiles -o json | jq '.' > \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

done

# Backup raw SELinux profiles
for profile in $(oc get rawselinuxprofiles -n openshift-security-profiles -o name); do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

# Backup raw SELinux profiles
for profile in $(oc get rawselinuxprofiles -n openshift-security-profiles -o name); do
name=$(echo $profile | cut -d'/' -f2)
oc get rawselinuxprofile $name -n openshift-security-profiles -o json | jq '.' > \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

### Delete Profile Bindings First
```bash
# List and delete all profile bindings
oc get profilebindings -n openshift-security-profiles
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above. Profilebindings can be created in all namespaces

% oc get profilebindings -A
NAMESPACE     NAME                      AGE
selinuxtest   profile-binding-selinux   109m
test-spo      busybox-binding           22m
test-spo2     busybox-binding           62m
test-spo2     profile-binding-selinux   41m

```bash
# List and delete all profile bindings
oc get profilebindings -n openshift-security-profiles
oc delete profilebindings --all -n openshift-security-profiles
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above


**Actual command and output:**
```bash
oc delete profilebinding profile-binding-seccomp profile-binding-selinuxd -n openshift-security-profiles
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

### Delete Security Profiles
```bash
# Delete all security profiles
oc delete seccompprofiles,selinuxprofiles,rawselinuxprofiles --all -n openshift-security-profiles
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above, the seccompprofiles, selinuxprofiles and rawselinuxprofiles can be created in all namespaces.



### Delete Namespace
```bash
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before delete the namespace, you also need to run below command:
oc delete mutatingwebhookconfigurations spo-mutating-webhook-configuration


To uninstall the Security Profiles Operator (SPO) Operator, follow these steps:

### Uninstall via OperatorHub (Recommended)
Copy link

@xiaojiey xiaojiey Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the experience, this step Uninstall via OperatorHub is not necessary.

### Delete Profile Bindings First
```bash
# List and delete all profile bindings
oc get profilebindings -n openshift-security-profiles
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more issue: before delete any profilebinding, the activeWorkloads should be deleted first. Otherwise, the profilebinding deleting will fail.

…etion commands

This update modifies the backup and deletion sections of the Security Profiles Operator (SPO) migration guide to support operations across all namespaces. It includes commands to back up profile bindings, seccomp profiles, SELinux profiles, and raw SELinux profiles from all namespaces, as well as updated deletion instructions for these resources.
Profile bindings backed up:
profilebindings-openshift-security-profiles-profile-binding-seccomp.json
profilebindings-openshift-security-profiles-profile-binding-selinuxd.json
```

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to backup profilerecording?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a good point, but I wonder if profile recording is something customer would run at all time, would it be okay if we tell customer they need to check if they have any profile recording in progress, they need to manage those accordingly if so and point them to:

**IMPORTANT**: If you have any profile recording in progress, you should also remove them, as well as associated active workloads with the profile recordings.
[Manage Profile Recording](https://docs.redhat.com/en/documentation/openshift_container_platform/4.12/html/security_and_compliance/security-profiles-operator#spo-recording-profiles_spo-seccomp)

Next, update all workloads to remove references to SPO profiles. You must either recreate pods without these profiles, or update deployments, statefulset, and other workloads to remove the profile references from their pod templates.


### Delete Security Profiles

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before deleting the security profiles, we need to delete the active workload for the security profiles first.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added:

Next, update all workloads to remove references to SPO profiles. You must either recreate pods without these profiles, or update deployments, statefulset, and other workloads to remove the profile references from their pod templates.

I think it is hard to make recommendations here since it is up to customer to decide how to manage their active workload.

oc get seccompprofiles,selinuxprofiles,rawselinuxprofiles -A
```

## Step 5: Uninstall SPO Operator
Copy link

@xiaojiey xiaojiey Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before the uninstall, deleting the active workloads for the profilerecording and deleting the profilerecording is also a mandatory step(better before the deleting security profiles step.)

echo "Restoring: $(basename "$file")"
oc apply -f "$file"
fi
done

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Vincent056 I failed to restore the security profiles. Could you please take a look? Thanks.

echo "Restored profiles:"
oc get seccompprofiles,selinuxprofiles,rawselinuxprofiles
Restoring: rawselinuxprofiles-errorlogger.json
Error from server (NotFound): error when creating "spo-manual-backup-20250826-070749/profiles-to-restore/rawselinuxprofiles-errorlogger.json": the server could not find the requested resource (post rawselinuxprofiles.security-profiles-operator.x-k8s.io)
Restoring: seccompprofiles-log-enricher-trace.json
Error from server (NotFound): error when creating "spo-manual-backup-20250826-070749/profiles-to-restore/seccompprofiles-log-enricher-trace.json": the server could not find the requested resource (post seccompprofiles.security-profiles-operator.x-k8s.io)
Restoring: seccompprofiles-sleep-sh-pod.json
Error from server (NotFound): error when creating "spo-manual-backup-20250826-070749/profiles-to-restore/seccompprofiles-sleep-sh-pod.json": the server could not find the requested resource (post seccompprofiles.security-profiles-operator.x-k8s.io)
Restoring: selinuxprofiles-errorlogger.json
Error from server (NotFound): error when creating "spo-manual-backup-20250826-070749/profiles-to-restore/selinuxprofiles-errorlogger.json": the server could not find the requested resource (post selinuxprofiles.security-profiles-operator.x-k8s.io)

Copy link

@xiaojiey xiaojiey Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Vincent056 I am a little confused. I only removed label for rawselinuxprofile. But all profiles restore/creating succeeded on a fresh installed cluster. I think the operator was not installed correctly last time. Maybe something wrong with the previous uninstallation? Let me try again and give you feedback later.

$ for file in $BACKUP_DIR/profiles-to-restore/*.json; do
  if [ -f "$file" ]; then
    echo "Restoring: $(basename "$file")"
    oc apply -f "$file"
  fi
done
Restoring: rawselinuxprofiles-errorlogger.json
rawselinuxprofile.security-profiles-operator.x-k8s.io/errorlogger unchanged
Restoring: seccompprofiles-log-enricher-trace.json
seccompprofile.security-profiles-operator.x-k8s.io/log-enricher-trace created
Restoring: seccompprofiles-sleep-sh-pod.json
seccompprofile.security-profiles-operator.x-k8s.io/sleep-sh-pod unchanged
Restoring: selinuxprofiles-errorlogger.json
selinuxprofile.security-profiles-operator.x-k8s.io/errorlogger created
Restoring: selinuxprofiles-nginx-secure.json
selinuxprofile.security-profiles-operator.x-k8s.io/nginx-secure created
Restoring: selinuxprofiles-spo-recording-hello-openshift-5n58t.json
selinuxprofile.security-profiles-operator.x-k8s.io/spo-recording-hello-openshift-5n58t created
Restoring: selinuxprofiles-spo-recording-hello-openshift-c9tf8.json
selinuxprofile.security-profiles-operator.x-k8s.io/spo-recording-hello-openshift-c9tf8 created
Restoring: selinuxprofiles-spo-recording-hello-openshift-ms6qg.json
selinuxprofile.security-profiles-operator.x-k8s.io/spo-recording-hello-openshift-ms6qg created
Restoring: selinuxprofiles-spo-recording-hello-openshift2-5n58t.json
selinuxprofile.security-profiles-operator.x-k8s.io/spo-recording-hello-openshift2-5n58t created
Restoring: selinuxprofiles-spo-recording-hello-openshift2-c9tf8.json
selinuxprofile.security-profiles-operator.x-k8s.io/spo-recording-hello-openshift2-c9tf8 created
Restoring: selinuxprofiles-spo-recording-hello-openshift2-ms6qg.json
selinuxprofile.security-profiles-operator.x-k8s.io/spo-recording-hello-openshift2-ms6qg created

…ordings and metadata cleanup

This commit adds a note regarding the removal of active workloads and ongoing profile recordings during the migration process. Additionally, it enhances the cleanup script by including the deletion of metadata fields such as annotations, labels, managed fields, and owner references from backup profiles.
Copy link

openshift-ci bot commented Sep 1, 2025

@Vincent056: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-operator 99b298d link true /test e2e-operator
ci/prow/e2e-flaky 99b298d link false /test e2e-flaky

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

echo " Original namespace: $namespace"

# Prepare the profile (remove namespace and clean metadata)
jq 'del(.metadata.namespace) |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to add the "|" pipe operator at the end of each jq command:

    jq 'del(.metadata.namespace) | 
        del(.metadata.resourceVersion) | 
        del(.metadata.uid) | 
        del(.metadata.creationTimestamp) | 
        del(.metadata.generation) | 
        del(.metadata.annotations) |
        del(.metadata.labels) |
        del(.metadata.managedFields) |
        del(.metadata.ownerReferences) |
        del(.status) | 
        del(.metadata.finalizers)' "$file" > "$BACKUP_DIR/profiles-to-restore/${profile_type}-${name}.json"

image: nginx:1.19.1
securityContext:
seLinuxOptions:
type: errorlogger-selinuxd-test.process
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be type: errorlogger-selinuxd-test_.process

- name: nginx
securityContext:
seLinuxOptions:
type: errorlogger-selinuxd-test.process # No namespace in type
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be type: errorlogger-selinuxd-test_.process here

seccompprofile.security-profiles-operator.x-k8s.io/profile-block-all Installed 30s

NAME USAGE STATE
selinuxprofile.security-profiles-operator.x-k8s.io/errorlogger-selinuxd-test errorlogger-selinuxd-test.process Installed
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be errorlogger-selinuxd-test_.process

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants