Mirroring images with a portable storage device
You can make the operators for IBM Cloud Pak for Integration available to a cluster that has no internet connectivity by using a portable storage device. First mirror the images to the portable storage device using a machine that has internet connectivity. Next connect the portable storage device to a machine that is connected to the restricted network environment and mirror the images to a registry within that environment for use by the Red Hat OpenShift cluster.
Overview
Prerequisites
Install an OpenShift 4.6 cluster(see Operating environment).
Prepare a Docker registry and make it available. For more information, see Prepare a Docker registry.
A Docker registry must be set up on an external host that is connected to the internet. For more information, see Prepare a Docker registry.
A portable storage device that has sufficient storage must be attached to the external host. For more information, see Prepare an external host.
cloudctlversion 3.6.1-2002 or later is required.
Prepare a Docker registry
A local Docker registry is used to store all images in your restricted environment. You must create such a registry and ensure that it meets the following requirements:
Supports Docker Manifest V2, Schema 2.
Is accessible from your OpenShift cluster nodes.
Has the username and password of a user who can write to the target registry from the internal host.
Has the username and password of a user who can read from the target registry that is on the OpenShift cluster nodes.
Allows path separators in the image name.
An example of a simple registry is included in Creating a mirror registry for installation in a restricted network in the OpenShift documentation.
Verify that you:
Have the credentials of a user who can write and create repositories. The internal host uses these credentials.
Have the credentials of a user who can read all repositories. The OpenShift cluster uses these credentials.
Prepare an external host
Prepare an external host that can be connected to the internet. Attach a portable storage device to the host. The storage device is later connected to the local Docker registry in the air-gapped environment.
The external host must be on a Linux x86_64 platform, or any operating system that the IBM Cloud Pak CLI and the OpenShift CLI supports.
The external host
localemust be set to English.
The portable device must have sufficient storage to hold all of the software that is to be transferred to the local Docker registry.
Complete these steps on your external host:
Install OpenSSL version 1.11.1 or higher.
Install Docker or Podman.
To install Docker (for example, on Red Hat® Enterprise Linux®), run these commands:
yum check-update yum install dockerTo install Podman, see Podman Installation Instructions.
Install
httpd-tools.
yum install httpd-toolsInstall the IBM Cloud Pak CLI. Install the latest version of the binary file for your platform. For more information, see cloud-pak-cli.
Download the binary file.
wget https://github.com/IBM/cloud-pak-cli/releases/latest/download/<binary-file-name>For example,
wget https://github.com/IBM/cloud-pak-cli/releases/latest/download/cloudctl-linux-amd64.tar.gz.Extract the binary file.
tar -xf <binary-file-name>Run the following commands to modify and move the file.
chmod 755 <file-name> mv <file-name> /usr/local/bin/cloudctlConfirm that
cloudctlis installed:
cloudctl --helpThe cloudctl usage is displayed.
Install the
ocOpenShift CLI tool. For more information, see Getting started with the CLI in the Red Hat OpenShift documentation.Install the
skopeoCLI version1.0.0or higher. For more information, see Installing skopeo from packages.Create a directory that serves as the offline store.
Following is an example directory, which is used in the subsequent steps.
mkdir $HOME/offlineNote: This offline store must be persistent to avoid transferring data more than once. The persistence also helps to run the mirroring process multiple times or on a schedule.
Create environment variables for the installer and image inventory
On your external host, create the following environment variables with the installer image name and the image inventory.
export CASE_NAME=ibm-cp-integration
export CASE_VERSION=2.1.0
export CASE_ARCHIVE=${CASE_NAME}-${CASE_VERSION}.tgz
export CASE_INVENTORY_SETUP=operator
export OFFLINEDIR=$HOME/offline
export OFFLINEDIR_ARCHIVE=offline.tgz
export CASE_REMOTE_PATH=https://github.com/IBM/cloud-pak/raw/master/repo/case/${CASE_ARCHIVE}
export CASE_LOCAL_PATH=$OFFLINEDIR/$CASE_ARCHIVE
export PORTABLE_DOCKER_REGISTRY_HOST=127.0.0.1
export PORTABLE_DOCKER_REGISTRY_PORT=443
export PORTABLE_DOCKER_REGISTRY=$PORTABLE_DOCKER_REGISTRY_HOST:$PORTABLE_DOCKER_REGISTRY_PORT
export PORTABLE_DOCKER_REGISTRY_USER=localuser
export PORTABLE_DOCKER_REGISTRY_PASSWORD=l0calPassword!
export PORTABLE_DOCKER_REGISTRY_PATH=$OFFLINEDIR/imageregistryDownload the installer and image inventory
Download the installer and image inventory to the external registry host.
cloudctl case save \
--case $CASE_REMOTE_PATH \
--outputdir $OFFLINEDIRMirror the images to the external host
Complete these steps to mirror the images from the internet to the external host:
Store authentication credentials for all source Docker registries.
See Applying your entitlement key for how to obtain your entitlement key.
After obtaining your entitlement key, run the following command to configure credentials for the IBM Entitled Registry:
cloudctl case launch \ --case $HOME/offline/${CASE_ARCHIVE} \ --inventory ${CASE_INVENTORY_SETUP} \ --action configure-creds-airgap \ --args "--registry cp.icr.io --user cp --pass <entitlement key> --inputDir $HOME/offline"The command stores and caches the registry credentials in a file on your file system in the
$HOME/.airgap/secretslocation.Store authentication credentials of the Docker registry that is running on the external host.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action configure-creds-airgap \ --args "--registry $PORTABLE_DOCKER_REGISTRY --user $PORTABLE_DOCKER_REGISTRY_USER --pass $PORTABLE_DOCKER_REGISTRY_PASSWORD"The command stores and caches the registry credentials in a file on your file system in the
$HOME/.airgap/secretslocation.Run a Docker registry service on localhost.
a. Initialize the Docker registry.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action init-registry \ --args "--registry $PORTABLE_DOCKER_REGISTRY_HOST --user $PORTABLE_DOCKER_REGISTRY_USER --pass $PORTABLE_DOCKER_REGISTRY_PASSWORD --dir $PORTABLE_DOCKER_REGISTRY_PATH"b. Start the Docker registry.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action start-registry \ --args "--registry $PORTABLE_DOCKER_REGISTRY_HOST --port $PORTABLE_DOCKER_REGISTRY_PORT --user $PORTABLE_DOCKER_REGISTRY_USER --pass $PORTABLE_DOCKER_REGISTRY_PASSWORD --dir $PORTABLE_DOCKER_REGISTRY_PATH"Mirror the images to the registry on the external host.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action mirror-images \ --args "--registry $PORTABLE_DOCKER_REGISTRY --inputDir $OFFLINEDIR"
(Optional) Save the Docker registry image
If your air-gapped network doesn’t have a Docker registry image, you can save the image on the portable device and copy it later to the host in your air-gapped environment.
docker save docker.io/library/registry:2.6 -o $PORTABLE_DOCKER_REGISTRY_PATH/registry-image.tarCopy the saved offline data to an external storage device
Connect the portable storage device, such as a USB drive or external HDD, to this external host.
Archive the offline data for transfer:
tar -cvzf $OFFLINEDIR_ARCHIVE -C $OFFLINEDIR .Copy the preceding TAR file to the portable storage.
This portable storage device should be physically transferred from the machine that has a public internet connection to the machine that has no internet connectivity.
Log in to the internal host that has access to the Openshift Container Platform cluster
The following steps need to be run from this internal host, which is in your air-gapped network, unless otherwise noted.
The internal host must be connected to both the portable storage device and the Openshift Container Platform cluster.
Log in to the Openshift Container Platform cluster as a cluster administrator
Following is an example command to log in to the Openshift Container Platform cluster:
oc login <cluster host:port> --username=<cluster admin user> --password=<cluster admin password>Create a Kubernetes namespace for the Cloud Pak
Create an environment variable with a namespace to install, then create the namespace. For example:
export NAMESPACE=cp4i
oc create namespace ${NAMESPACE}Prepare the internal host and extract images
args "--registry <registry> --user <registry userid> --pass {registry password} --inputDir ~/offline". The tilde doesn’t expand and your commands might fail.Create environment variables with the local Docker registry connection information.
export CASE_NAME=ibm-cp-integration
export CASE_VERSION=2.1.0
export CASE_ARCHIVE=${CASE_NAME}-${CASE_VERSION}.tgz
export CASE_INVENTORY_SETUP=operator
export OFFLINEDIR=$HOME/offline
export OFFLINEDIR_ARCHIVE=offline.tgz
export CASE_REMOTE_PATH=https://github.com/IBM/cloud-pak/raw/master/repo/case/${CASE_ARCHIVE}
export CASE_LOCAL_PATH=$OFFLINEDIR/$CASE_ARCHIVE
export PORTABLE_DOCKER_REGISTRY_HOST=127.0.0.1
export PORTABLE_DOCKER_REGISTRY_PORT=443
export PORTABLE_DOCKER_REGISTRY=$PORTABLE_DOCKER_REGISTRY_HOST:$PORTABLE_DOCKER_REGISTRY_PORT
export PORTABLE_DOCKER_REGISTRY_USER=localuser
export PORTABLE_DOCKER_REGISTRY_PASSWORD=l0calPassword!
export PORTABLE_DOCKER_REGISTRY_PATH=$OFFLINEDIR/imageregistry
export LOCAL_DOCKER_REGISTRY_HOST=<IP_or_FQDN_of_local_docker_registry>
export LOCAL_DOCKER_REGISTRY_PORT=443
export LOCAL_DOCKER_REGISTRY=$LOCAL_DOCKER_REGISTRY_HOST:$LOCAL_DOCKER_REGISTRY_PORT
export LOCAL_DOCKER_REGISTRY_USER=<username>
export LOCAL_DOCKER_REGISTRY_PASSWORD=<password>Extract the transferred offline data from the portable storage device.
mkdir -p $OFFLINEDIR tar -xvf $OFFLINEDIR_ARCHIVE -C $OFFLINEDIRSet up the registry.
Run the local, Docker registry as a container. The registry then points to the Docker file system directory that is transferred from the external host.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action start-registry \ --args "--registry $PORTABLE_DOCKER_REGISTRY_HOST --port $PORTABLE_DOCKER_REGISTRY_PORT --user $PORTABLE_DOCKER_REGISTRY_USER --pass $PORTABLE_DOCKER_REGISTRY_PASSWORD --dir $PORTABLE_DOCKER_REGISTRY_PATH"Set up registry credentials for mirroring.
Store credentials of the registry that is running on the internal host (created in previous step)
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action configure-creds-airgap \ --args "--registry $PORTABLE_DOCKER_REGISTRY --user $PORTABLE_DOCKER_REGISTRY_USER --pass $PORTABLE_DOCKER_REGISTRY_PASSWORD"Store credentials of the registry that will serve images to the cluster/workloads.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action configure-creds-airgap \ --args "--registry $LOCAL_DOCKER_REGISTRY --user $LOCAL_DOCKER_REGISTRY_USER --pass $LOCAL_DOCKER_REGISTRY_PASSWORD"
Mirror the images and configure the cluster
Mirror the images to the target registry that is on your Openshift cluster and configure the cluster.
Mirror the images from the internal host registry to the target registry on your cluster.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --inventory $CASE_INVENTORY_SETUP \ --action mirror-images \ --args "--fromRegistry $PORTABLE_DOCKER_REGISTRY --registry $LOCAL_DOCKER_REGISTRY --inputDir $OFFLINEDIR"Configure a global image pull secret and ImageContentSourcePolicy.
cloudctl case launch \ --case $CASE_LOCAL_PATH \ --namespace $NAMESPACE \ --inventory $CASE_INVENTORY_SETUP \ --action configure-cluster-airgap \ --args "--registry $LOCAL_DOCKER_REGISTRY --inputDir $OFFLINEDIR"Note: In Openshift Container Platform version 4.6, this step restarts all cluster nodes. The cluster resources might be unavailable until the time the new pull secret is applied.Verify that the ImageContentSourcePolicy resource is created.
oc get imageContentSourcePolicyOptional: If you use an insecure registry, you must add the local registry to the cluster insecureRegistries list.
oc patch image.config.openshift.io/cluster --type=merge -p '{"spec":{"registrySources":{"insecureRegistries":["'$LOCAL_DOCKER_REGISTRY']}}}'Verify your cluster node status.
oc get nodes
After the imageContentsourcePolicy and global image pull secret are applied, you might see the node status as Ready, Scheduling, or Disabled. Wait until all the nodes show a Ready status.
Create the CatalogSource
CP4I can be installed by adding the CatalogSource for the mirrored operators to your cluster and using OLM to install the operators.
Create a catalog source.
This command adds the
CatalogSourcefor the components to your cluster, so the cluster can access them from the private registry:cloudctl case launch \ --case $HOME/offline/${CASE_ARCHIVE} \ --inventory ${CASE_INVENTORY_SETUP} \ --action install-catalog \ --namespace ${NAMESPACE} \ --args "--registry ${LOCAL_DOCKER_REGISTRY} --inputDir $HOME/offline --recursive"Verify that the
CatalogSourcefor the Cloud Pak installer operator is created.oc get pods -n openshift-marketplace oc get catalogsource -n openshift-marketplace
Next steps
Once the CatalogSource is installed, the next step is to install the operators. See Installing operators.