Importing Kubeturbo container images to a private repository (OperatorHub)

You can import the Kubeturbo container images to your private repository if you do not want to pull them from IBM Container Registry (icr.io).

  • kubeturbo

    This is the primary container image and is pulled from icr.io/cpopen/turbonomic/kubeturbo:8.18.0.

  • cpufreqgetter

    This container image (also known as BusyBox) runs a job on every node to collect CPU speed. It is pulled from icr.io/cpopen/turbonomic/cpufreqgetter:latest.

    For more information about the parameters associated with this job, see this topic.

  • (Operator method only) kubeturbo-operator

    This container image is pulled from icr.io/cpopen/kubeturbo-operator:8.18.0.

By default, the operator deploys a Kubeturbo image that matches the deployed operator version, and pulls directly from IBM Container Registry. While it is important that the Kubeturbo version matches your Turbonomic version, you might be using a different version or a private repository.

Note:

This documentation assumes that the private repository images are reachable and can be pulled without the need for an image pull secret.

Importing a multi-architecture container image to a private repository

IBM Container Registry provides multi-architecture container images. Your private repository needs to support loading these images. For example, multi-architecture container images are supported in Artifactory version 7.2+, but not in Artifactory version 6. Optionally, pull only the architecture version that you need. Specify the --platform parameter with docker pull and use docker inspect to confirm the architecture.

The following example script shows how you can import the kubeturbo image to your private repository. Replace <private_repository_prefix> with the prefix for your private repository.

PRIVATE_REPO="<private_repository_prefix>"
SRC_IMAGE="icr.io/cpopen/turbonomic/kubeturbo:8.18.0"

# Import a single image to private repo
BASE_REPO="icr.io/cpopen"
DST_IMAGE=$(echo "${SRC_IMAGE}" | sed 's|'"${BASE_REPO}"/'|'"${PRIVATE_REPO}"'/|g')

# Pull image for a specific platform
docker pull --platform linux/arm64 "${SRC_IMAGE}"

# Check if correct architecture has been pulled (optional)
docker inspect "${SRC_IMAGE}" | grep architecture
                "architecture": "aarch64",

# Tag the image and push it to the private repo 
docker tag "${SRC_IMAGE}" "${DST_IMAGE}"
docker push "${DST_IMAGE}"

You can use this script for the other container images. Be sure to update the SRC_IMAGE parameter with the default image paths and names as described in the first section of this topic.

Importing multiple images to a private repository

The following example script explains the logic for importing images to your private repository.

#!/bin/sh

# Create a temporary file
TEMP_FILE=$(mktemp /tmp/process_images.XXXXXX) || {
    echo "Error: Failed to create temporary file"
    exit 1
}

# Define private registry prefix and target images (EDIT below section)
private_registry_base="<private_repository_prefix>"
cat << EOF > "${TEMP_FILE}"
icr.io/cpopen/turbonomic/kubeturbo:8.18.0
icr.io/cpopen/turbonomic/cpufreqgetter:latest
icr.io/cpopen/kubeturbo-operator:8.18.0
EOF

ICR_IMAGE_BASE="icr.io/cpopen"
for image in $(cat "${TEMP_FILE}"); do
    # Standarlize input image
    image=$(echo "${image}" | sed 's|.*'"${ICR_IMAGE_BASE}"'/||g')

    SOURCE_IMAGE="${ICR_IMAGE_BASE}/${image}"
    TARGET_IMAGE="${private_registry_base}/${image}"

    echo "Mirroing: ${SOURCE_IMAGE} -> ${TARGET_IMAGE}"    
    if docker manifest inspect "${SOURCE_IMAGE}" | jq '.manifests[].platform' >/dev/null; then
        # Create and use a buildx builder
        docker buildx rm multiarch
        docker buildx create --name multiarch --driver docker-container --use

        # Mirror multiarch image to private repo
        docker buildx imagetools create --tag "${TARGET_IMAGE}" "${SOURCE_IMAGE}"
    else
        # Mirror single buiild image to private repo
        docker pull "${SOURCE_IMAGE}"
        docker tag  "${SOURCE_IMAGE}" "${TARGET_IMAGE}"
        docker push "${TARGET_IMAGE}"

        # Clean up local images
        docker image rm $SOURCE_IMAGE $TARGET_IMAGE 2>/dev/null
    fi
done

# Clean up the temporary file
rm -f "${TEMP_FILE}" || {
    echo "Warning: Failed to delete temporary file ${TEMP_FILE}"
}

echo "Processing complete, temporary file deleted"

To import multiple images to a private repository based on the preceding script, perform the following steps:

  1. In the preceding script, replace <private_repository_prefix> with your private repository prefix.

  2. If you use the secure client to automatically sync the Kubeturbo version with the Turbonomic version and enable central logging, add the following secure client image paths before EOF.

    • icr.io/cpopen/turbonomic/kube-state-metrics:v2.14.0

    • icr.io/cpopen/turbonomic/rsyslog-courier:8.18.0

    • icr.io/cpopen/turbonomic/skupper-config-sync:8.18.0

    • icr.io/cpopen/turbonomic/skupper-router:8.18.0

    • icr.io/cpopen/turbonomic/skupper-service-controller:8.18.0

    • icr.io/cpopen/turbonomic/skupper-site-controller:8.18.0

    • icr.io/cpopen/turbonomic/tsc-site-resources:8.18.0

  3. Pull the Kubeturbo operator and specify the operator's path and digest ID in the ClusterServerVersion resource.

    For information on how to work with operators or OLMs in a disconnected or restricted network (also referred to as an air-gapped environment) and how to stage certified operators, see the Red Hat OpenShift documentation. The Kubeturbo certified operator bundle is available in this GitHub repository. Be sure to work with the bundle version that matches the Kubeturbo product version that you need.

  4. Define the parameters in the operator instance or custom resource you have configured (default is kubeturbo-release), as shown in the following example (see a sample YAML here):

    spec:
      image:
        repository: <private_repository_prefix>/turbonomic/kubeturbo
        tag: 8.18.0
        cpufreqgetterRepository: <private_repository_prefix>/turbonomic/cpufreqgetter:latest

    Replace <private_repository_prefix> (two instances) with your private repository prefix.

After you apply your configuration, an instance or custom resource called kubeturbo-release is created, with a Kubeturbo deployed at either the same version as the operator, or a user-specified version.