Creating the Seed Image

Introduction to Seed Image Generation

In this section, we will create a seed image from the Seed single-node OpenShift cluster. This seed cluster has the same hardware and a similar cluster configuration to the OpenShift clusters we will create and upgrade later. More information on the allowed configuration of the seed SNO cluster can be found here.

We will use the Lifecycle Agent to generate a seed image from a managed cluster. The Operator checks for required system configurations, performs necessary system cleanup before generating the image, and launches the image generation process. The seed image generation includes the following tasks:

  • RHACM and Multicluster Engine for Kubernetes Operator are not installed on the seed cluster.

  • A shared container directory is configured on the seed cluster.

  • The minimum required version of the OADP Operator and the Lifecycle Agent are installed on the seed cluster.

  • Persistent volumes are not configured on the seed cluster.

  • The LocalVolume CR does not exist on the seed cluster if the Local Storage Operator is used.

  • The LVMCluster CR does not exist on the seed cluster if LVM Storage is used.

  • The DataProtectionApplication CR does not exist on the seed cluster if OADP is used.

  • An OCI container image is generated from the seed SNO cluster and uploaded to the container registry.

During the deployment of this lab, we ensured that the seed SNO cluster is ready for seed image generation.

Running Seed Image Generation

Connect to the seed SNO cluster and verify that the OpenShift ADP and Lifecycle Agent (LCA) operators are installed as required operators to create a seed image. Notice that the SR-IOV and LVM operators are also installed. In this case, they are included as part of the seed image because the SNO clusters using this seed image will require these operators to run their workloads.

If the following command throws an error saying: The connection to the server api.sno-seed.5g-deployment.lab:6443 was refused - did you specify the right host or port?, wait up to 10 minutes, as the cluster may be restarting its API.
oc --kubeconfig ~/seed-cluster-kubeconfig get csv -A
NAMESPACE                              NAME                                          DISPLAY                     VERSION               REPLACES   PHASE
openshift-adp                          oadp-operator.v1.5.0                          OADP Operator               1.5.0                            Succeeded
openshift-lifecycle-agent              lifecycle-agent.v4.19.0                       Lifecycle Agent             4.19.0                           Succeeded
openshift-logging                      cluster-logging.v6.3.0                        Red Hat OpenShift Logging   6.3.0                            Succeeded
openshift-operator-lifecycle-manager   packageserver                                 Package Server              0.0.1-snapshot                   Succeeded
openshift-ptp                          ptp-operator.v4.19.0-202507180107             PTP Operator                4.19.0-202507180107              Succeeded
openshift-sriov-network-operator       sriov-network-operator.v4.19.0-202507212206   SR-IOV Network Operator     4.19.0-202507212206              Succeeded
openshift-storage                      lvms-operator.v4.19.0                         LVM Storage                 4.19.0                           Succeeded

Verify that the OpenShift Container Platform version of the seed SNO cluster is v4.19.0:

oc --kubeconfig ~/seed-cluster-kubeconfig get clusterversion
NAME      VERSION       AVAILABLE   PROGRESSING   SINCE   STATUS
version   v4.19.0  True        False         13m     Cluster version is v4.19.0

Create the Secret object that contains the container registry credentials where you can push the seed image:

cat <<EOF | oc --kubeconfig ~/seed-cluster-kubeconfig apply -f -
---
apiVersion: v1
kind: Secret
metadata:
  name: seedgen
  namespace: openshift-lifecycle-agent
type: Opaque
stringData:
  seedAuth: '{"auths": {"infra.5g-deployment.lab:8443": {"auth": "YWRtaW46cjNkaDR0MSE="}}}'
EOF

Create the SeedGenerator CR. The Lifecycle Agent provides orchestration of Seed Image generation via the SeedGenerator CR.

A good practice is to tag the seed container image with the OpenShift version of the seed SNO cluster.
cat <<EOF | oc --kubeconfig ~/seed-cluster-kubeconfig apply -f -
---
apiVersion: lca.openshift.io/v1
kind: SeedGenerator
metadata:
  name: seedimage
spec:
  seedImage: infra.5g-deployment.lab:8443/ibi/lab5gran:v4.19.0
EOF

You can follow the progress by checking the logs of the lifecycle-agent-controller and the status of the SeedGenerator object:

oc --kubeconfig ~/seed-cluster-kubeconfig get seedgen -A
NAME        AGE   STATE               DETAILS
seedimage   47s   SeedGenInProgress   Cleaning cluster resources
oc --kubeconfig ~/seed-cluster-kubeconfig -n openshift-lifecycle-agent logs -f deployment/lifecycle-agent-controller-manager -c manager
2025-02-03T17:47:18Z	INFO	controllers.ImageBasedUpgrade.ibu-manager-client	Setting up retry middleware
2025-02-03T17:47:18Z	INFO	setup	Initial IBU created
2025-02-03T17:47:18Z	INFO	controllers.ImageBasedUpgrade.ibu-dynamic-client	Setting up retry middleware
2025-02-03T17:47:18Z	INFO	controllers.ImageBasedUpgrade.ibu-dynamic-client	Successfully created dynamic client
INFO[0000] Running systemctl is-active [var-lib-containers.mount]
INFO[0000] Executing /usr/bin/env with args [-- systemctl is-active var-lib-containers.mount]
INFO[0000] Running systemctl cat [var-lib-containers.mount]
INFO[0000] Executing /usr/bin/env with args [-- systemctl cat var-lib-containers.mount]
2025-02-03T17:47:18Z	INFO	controllers.ImageBasedUpgrade.ibu-clientset	Setting up retry middleware
2025-02-03T17:47:18Z	INFO	setup	starting manager
2025-02-03T17:47:18Z	INFO	controller-runtime.metrics	Starting metrics server
... REDACTED ...
2025-02-04T09:37:08Z	INFO	controllers.SeedGenerator	Generating seed image: infra.5g-deployment.lab:8443/ibi/lab5gran:v4.19.0
2025-02-04T09:37:08Z	INFO	controllers.SeedGenerator	Checking system health
INFO[57054] Executing /usr/bin/env with args [-- systemd-run --collect --wait --unit lca-generate-seed-image --setenv HTTP_PROXY --setenv HTTPS_PROXY --setenv NO_PROXY podman run --privileged --pid=host --name=lca_image_builder --replace --net=host --http-proxy=true -v /etc:/etc -v /var:/var -v /var/run:/var/run -v /run/systemd/journal/socket:/run/systemd/journal/socket -v /var/lib/lca/ibu-seedgen-orch/auth.json:/var/lib/lca/ibu-seedgen-orch/auth.json --entrypoint lca-cli registry.redhat.io/openshift4/lifecycle-agent-rhel9-operator@sha256:7c5bed953d0f2a774bc099c22d3c520f98cad0605723218624cc3737be4086ac create --authfile /var/lib/lca/ibu-seedgen-orch/auth.json --image infra.5g-deployment.lab:8443/ibi/lab5gran:v4.19.0 --recert-image registry.redhat.io/openshift4/recert-rhel9@sha256:f78fd5c29b78bf429596679d8104cd629bf2dca1265638824b39ed56cb3dbb13]
The cluster reboots and loses API capabilities while the Lifecycle Agent generates the seed image. Applying the SeedGenerator CR stops the kubelet and the CRI-O operations, then it starts the image generation. This process may take up to 10 minutes.
oc --kubeconfig ~/seed-cluster-kubeconfig get seedgen
Get "https://api.sno-seed.5g-deployment.lab:6443/apis/lca.openshift.io/v1/seedgenerators?limit=500": dial tcp 192.168.125.30:6443: connect: connection refused - error from a previous attempt: unexpected EOF

After the cluster recovers and is available, you can continue checking the status of the SeedGenerator CR by running the following command:

oc --kubeconfig ~/seed-cluster-kubeconfig get seedgen seedimage -o json | jq '.status'
{
  "conditions": [
    {
      "lastTransitionTime": "2025-02-04T09:43:55Z",
      "message": "Seed Generation completed",
      "observedGeneration": 1,
      "reason": "Completed",
      "status": "False",
      "type": "SeedGenInProgress"
    },
    {
      "lastTransitionTime": "2025-02-04T09:43:55Z",
      "message": "Seed Generation completed",
      "observedGeneration": 1,
      "reason": "Completed",
      "status": "True",
      "type": "SeedGenCompleted"
    }
  ],
  "observedGeneration": 1
}
oc --kubeconfig ~/seed-cluster-kubeconfig get seedgen
NAME        AGE   STATE              DETAILS
seedimage   12s   SeedGenCompleted   Seed Generation completed

Once the SeedGenerator CR shows the state as SeedGenCompleted, the image creation is complete. Verify that the cluster is available again. However, if you want to generate more seed images, you must provision a new seed cluster with the version from which you want to generate a seed image.

oc --kubeconfig ~/seed-cluster-kubeconfig get clusterversion,nodes
NAME                                         VERSION       AVAILABLE   PROGRESSING   SINCE   STATUS
clusterversion.config.openshift.io/version   v4.19.0  False       False         16h     Cluster version is v4.19.0

NAME                      STATUS   ROLES                         AGE   VERSION
node/openshift-master-0   Ready    control-plane,master,worker   16h   v1.32.5

At this point, the seed image is created and pushed to our container registry under infra.5g-deployment.lab:8443/ibi/lab5gran:v4.19.0. The seed image is ready to be used to provision new SNO clusters using the image-based installation method.