In the following post, we are going to talk about creating an offline container base registry.

Prerequisites

  • Linux Operating System ( in the further steps example of this post, we are going to use Fedora Linux 36 (Workstation Edition) ).
  • The host should have internet connectivity

Offiline registry

Step 1. Installing podman

 sudo dnf -y install podman

For other type of Linux Operating System check the Podman docs for the right command.

Step 2. Creating the application directory of the offline registry

 mkdir -p /apps/registry/{auth,certs,data}

Step 3. Installing the htpasswd

 sudo dnf -y install httpd-tools

Step 4. Creating the username:password of the offline registry

 htpasswd -bBc /apps/registry/auth/htpasswd <username> <password>

Note, that the username and password should be replaced with the values you are going to use for your environment.

Step 5. Creating the offline self-signed certificate.

 host_fqdn=$( hostname --long )
cert_c="<Country Name>"   # Country Name (C, 2 letter code)
cert_s="<State>"          # Certificate State (S)
cert_l="<Locality>"       # Certificate Locality (L)
cert_o="<Organization>"   # Certificate Organization (O)
cert_ou="<Org Unit>"      # Certificate Organizational Unit (OU)
cert_cn="${host_fqdn}"    # Certificate Common Name (CN)

openssl req \
    -newkey rsa:4096 \
    -nodes \
    -sha256 \
    -keyout /apps/registry/certs/domain.key \
    -x509 \
    -days 365 \
    -out /apps/registry/certs/domain.crt \
    -addext "subjectAltName = DNS:${host_fqdn}" \
    -subj "/C=${cert_c}/ST=${cert_s}/L=${cert_l}/O=${cert_o}/OU=${cert_ou}/CN=${cert_cn}"
 sudo cp /apps/registry/certs/domain.crt /etc/pki/ca-trust/source/anchors/
 sudo update-ca-trust

In order to validate the trust certificats use the following command

 sudo trust list | grep -i "registry"

Step 6. Creating the registry container

 podman run -d --name ocpdiscon-registry -p 5000:5000 \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM=Registry \
-e REGISTRY_HTTP_SECRET=ALongRandomSecretForRegistry \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true \
-e REGISTRY_STORAGE_DELETE_ENABLED=true \
-v /apps/registry/data:/var/lib/registry:z \
-v /apps/registry/auth:/auth:z \
-v /apps/registry/certs:/certs:z docker.io/library/registry:2.8.1

Step 7. Make sure that the firewall is having the port 5000 open

 sudo firewall-cmd --add-port=5000/tcp --zone=internal --permanent
 sudo firewall-cmd --add-port=5000/tcp --zone=public --permanent
 sudo firewall-cmd --reload

Step 8. Manage the ocpdiscon-registry container with systemd

 mkdir -p ${HOME}/.config/systemd/user/
 cd ${HOME}/.config/systemd/user/
 podman generate systemd --new --files --name ocpdiscon-registry
 systemctl --user daemon-reload
 systemctl --user start container-ocpdiscon-registry.service
 systemctl --user enable container-ocpdiscon-registry.service
 systemctl --user is-active container-ocpdiscon-registry.service
 cd ${HOME}

Step 9. Download the openshift-cli-client

Go to the Download Openshift CLI for linux to download the oc-cli-client for linux.

 tar xvf ${HOME}/Downloads/oc-4.10.21-linux.tar.gz
 cp ${HOME}/Downloads/oc-4.10.21-linux/oc /usr/local/bin/oc
 cp ${HOME}/Downloads/oc-4.10.21-linux/kubectl /usr/local/bin/kubectl

Step 10. Download the pull-secret

Go to the Download Openshift pull-secret to download the pull-secret file. Once you obtain the file check the following command to

Step 11. Modifying pull-secret file for offline-registry use

 cat ${HOME}/Downloads/pull-secret | jq . > /apps/registry/pull-secret.json

The following /apps/registry/pull-secret.json content would follow the following template:

{
  "auths": {
    "cloud.openshift.com": {
      "auth": "b3BlbnNo...",
      "email": "you@example.com"
    },
    "quay.io": {
      "auth": "b3BlbnNo...",
      "email": "you@example.com"
    },
    "registry.connect.redhat.com": {
      "auth": "NTE3Njg5Nj...",
      "email": "you@example.com"
    },
    "registry.redhat.io": {
      "auth": "NTE3Njg5Nj...",
      "email": "you@example.com"
    }
  }
}

Now we should add the section that describes the credentials to the offline registry:

"auths": {
    "<mirror_registry>": {
      "auth": "<credentials>",
      "email": "you@example.com"
  },

Replace the with the output from the following command `echo -n username:password | base64 -w0`.

In the end the pull-secret.json should follow the following template:

{
  "auths": {
    "cloud.openshift.com": {
      "auth": "b3BlbnNo...",
      "email": "you@example.com"
    },
    "quay.io": {
      "auth": "b3BlbnNo...",
      "email": "you@example.com"
    },
    "registry.connect.redhat.com": {
      "auth": "NTE3Njg5Nj...",
      "email": "you@example.com"
    },
    "registry.redhat.io": {
      "auth": "NTE3Njg5Nj...",
      "email": "you@example.com"
    },
    "<mirror_registry>": {
      "auth": "<credentials>",
      "email": "you@example.com"
    }
  }
}

Step 12. Login to the offline registry

 podman login --authfile pull-secret.json -u <username> -p <password> INBACRNRDL0100.offline.oxtechnix.lan:5000
 Login Succeeded!

Step 13. Mirroring OCP container base images to the offline registry

 export LOCAL_REG_PORT="5000"
 export OCP_VERSION="4.8.45"
 export LOCAL_REG=$(hostname -f):$LOCAL_REG_PORT
 export LOCAL_REPO=ocp-release
 export UPSTREAM_REPO=$(curl -s https://mirror.openshift.com/pub/openshift-v4/clients/ocp/$OCP_VERSION/release.txt | grep 'Pull From: quay.io' | awk -F ' ' '{print $3}')
 export PULLSECRET_FILE=/apps/registry/pull-secret.json
 oc adm release mirror -a ${PULLSECRET_FILE} --from=$UPSTREAM_REPO --to-release-image=$LOCAL_REG/$LOCAL_REPO:${VERSION} --to=$LOCAL_REG/$LOCAL_REPO --apply-release-image-signature

Step 14. ICSP.yaml and install-config.yaml

Once the container base image mirroring will be finished, you will be promt with the following message:

To use the new mirrored repository to install, add the following section to the install-config.yaml:

imageContentSources:
- mirrors:
  - INBACRNRDL0100.offline.oxtechnix.lan:5000/ocp-release
  source: quay.io/openshift-release-dev/ocp-release
- mirrors:
  - INBACRNRDL0100.offline.oxtechnix.lan:5000/ocp-release
  source: quay.io/openshift-release-dev/ocp-v4.0-art-dev


To use the new mirrored repository for upgrades, use the following to create an ImageContentSourcePolicy:

apiVersion: operator.openshift.io/v1alpha1
kind: ImageContentSourcePolicy
metadata:
  name: example
spec:
  repositoryDigestMirrors:
  - mirrors:
    - INBACRNRDL0100.offline.oxtechnix.lan:5000/ocp-release
    source: quay.io/openshift-release-dev/ocp-release
  - mirrors:
    - INBACRNRDL0100.offline.oxtechnix.lan:5000/ocp-release
    source: quay.io/openshift-release-dev/ocp-v4.0-art-dev

Save this information for later use. For more information you can check Openshift Documentation.

Step 15. Validating the mirroring

 curl --user <username>:<password> https://INBACRNRDL0100.offline.oxtechnix.lan:5000/v2/_catalog
{"repositories":["ocp-release"]}