30 Image preparation for air-gap environments #
This section describes how to prepare the image for air-gap environments showing only the differences from the previous sections. The following changes to the previous section (Image preparation for connected environments (Chapter 29, Image preparation for connected environments)) are required to prepare the image for air-gap environments:
The
mgmt-cluster.yamlfile must be modified to include theembeddedArtifactRegistrysection with theimagesfield set to all container images to be included into the EIB output image.The
custom/scripts/99-register.shscript must be removed when use an air-gap environment.
To include the SUSE Private Registry in the management cluster for future downstream deployments, the following changes are also required:
The
mgmt-cluster.yamlfile must be modified to include the helm chart section as well as the embedded artifacts with the new images to include them in the EIB output image.The
kubernetes/valuesandkubernetes/manifestsfolders must include additional manifest files to properly configure the SUSE Private Registry in the management cluster.
You will need certain credentials, which can be retrieved by following the official SUSE Private Registry documentation.
30.1 Modifications in the definition file #
The mgmt-cluster.yaml file must be modified to include the embeddedArtifactRegistry section.
In this section the images field must contain the list of all container images to be included in the output image.
The following example mgmt-cluster.yaml file includes both the embeddedArtifactRegistry section and the SUSE Private Registry feature.
Make sure to the listed images contain the component versions you need.
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
outputImageName: eib-mgmt-cluster-image.iso
operatingSystem:
isoConfiguration:
installDevice: /dev/sda
users:
- username: root
encryptedPassword: $ROOT_PASSWORD
packages:
packageList:
- jq
sccRegistrationCode: $SCC_REGISTRATION_CODE
kubernetes:
version: v1.35.3+rke2r3
helm:
charts:
- name: private-registry-helm
createNamespace: true
installationNamespace: kube-system
repositoryName: privateregistry
targetNamespace: suse-private-registry
valuesFile: privateregistry.yaml
version: 1.1.1
- name: cert-manager
repositoryName: jetstack
version: 1.20.1
targetNamespace: cert-manager
valuesFile: certmanager.yaml
createNamespace: true
installationNamespace: kube-system
- name: longhorn
version: 1.11.1
repositoryName: rancher-application-collection
targetNamespace: longhorn-system
createNamespace: true
installationNamespace: kube-system
valuesFile: longhorn.yaml
- name: metallb
version: 306.0.2+up0.15.3
targetNamespace: metallb-system
createNamespace: true
repositoryName: suse-edge-charts
installationNamespace: kube-system
- name: metal3
version: 306.0.26+up0.15.0
repositoryName: suse-edge-charts
targetNamespace: metal3-system
createNamespace: true
installationNamespace: kube-system
valuesFile: metal3.yaml
- name: rancher-turtles-providers
version: 306.0.6+up0.26.1
repositoryName: suse-edge-charts
targetNamespace: cattle-turtles-system
createNamespace: true
installationNamespace: kube-system
- name: neuvector-crd
version: 109.0.1+up2.8.13
repositoryName: rancher-charts
targetNamespace: neuvector
createNamespace: true
installationNamespace: kube-system
valuesFile: neuvector.yaml
- name: neuvector
version: 109.0.1+up2.8.13
repositoryName: rancher-charts
targetNamespace: neuvector
createNamespace: true
installationNamespace: kube-system
valuesFile: neuvector.yaml
- name: rancher
version: 2.14.1
repositoryName: rancher-prime
targetNamespace: cattle-system
createNamespace: true
installationNamespace: kube-system
valuesFile: rancher.yaml
repositories:
- name: jetstack
url: https://charts.jetstack.io
- name: rancher-charts
url: https://charts.rancher.io/
- name: suse-edge-charts
url: oci://registry.suse.com/edge/charts
- name: rancher-prime
url: https://charts.rancher.com/server-charts/prime
- name: rancher-application-collection
url: oci://dp.apps.rancher.io/charts
authentication:
username: $\{APPS.RANCHER.IO_USERNAME\}
password: $\{APPS.RANCHER.IO_ACCESS_TOKEN\}
- name: privateregistry
authentication:
username: ${PRIVATE_REGISTRY_USERNAME}
password: ${PRIVATE_REGISTRY_PASSWORD}
plainHTTP: false
skipTLSVerify: false
url: oci://registry.suse.com/private-registry
network:
apiHost: $API_HOST
apiVIP: $API_VIP
nodes:
- hostname: mgmt-cluster-node1
initializer: true
type: server
# - hostname: mgmt-cluster-node2
# type: server
# - hostname: mgmt-cluster-node3
# type: server
embeddedArtifactRegistry:
registries:
- uri: dp.apps.rancher.io
authentication:
username: $\{APPS.RANCHER.IO_USERNAME\}
password: $\{APPS.RANCHER.IO_ACCESS_TOKEN\}
- uri: registry.suse.com
authentication:
username: ${PRIVATE_REGISTRY_USERNAME}
password: ${PRIVATE_REGISTRY_PASSWORD}
images:
- name: registry.suse.com/private-registry/harbor-core:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-jobservice:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-portal:1.1.1-1.20
- name: registry.suse.com/private-registry/harbor-registry:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-registryctl:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-trivy-adapter:1.1.1-1.24
- name: registry.rancher.com/rancher/hardened-cluster-autoscaler:v1.10.3-build20260206
- name: registry.rancher.com/rancher/hardened-cni-plugins:v1.9.0-build20260309
- name: registry.rancher.com/rancher/hardened-coredns:v1.14.2-build20260310
- name: registry.rancher.com/rancher/hardened-k8s-metrics-server:v0.8.1-build20260206
- name: registry.rancher.com/rancher/hardened-multus-cni:v4.2.4-build20260310
- name: registry.rancher.com/rancher/hardened-traefik:v3.6.10-build20260309
- name: registry.rancher.com/rancher/klipper-helm:v0.9.14-build20260309
- name: registry.rancher.com/rancher/mirrored-cilium-cilium:v1.19.1
- name: registry.rancher.com/rancher/mirrored-cilium-operator-generic:v1.19.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-attacher:4.11.0-11.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-provisioner:5.3.0-11.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-resizer:2.1.0-4.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-snapshotter:8.5.0-11.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-livenessprobe:2.18.0-11.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-node-driver-registrar:2.16.0-11.1
- name: dp.apps.rancher.io/containers/longhorn-backing-image-manager:1.11.1-1.2
- name: dp.apps.rancher.io/containers/longhorn-engine:1.11.1-1.1
- name: dp.apps.rancher.io/containers/longhorn-instance-manager:1.11.1-1.1
- name: dp.apps.rancher.io/containers/longhorn-manager:1.11.1-1.2
- name: dp.apps.rancher.io/containers/longhorn-share-manager:1.11.1-1.1
- name: dp.apps.rancher.io/containers/longhorn-ui:1.11.1-1.2
- name: dp.apps.rancher.io/containers/rancher-support-bundle-kit:0.0.81-7.3
- name: registry.rancher.com/rancher/mirrored-sig-storage-snapshot-controller:v8.2.0
- name: registry.rancher.com/rancher/neuvector-compliance-config:1.0.12
- name: registry.rancher.com/rancher/neuvector-controller:5.5.1
- name: registry.rancher.com/rancher/neuvector-enforcer:5.5.1
- name: registry.rancher.com/rancher/nginx-ingress-controller:v1.14.5-hardened1
- name: registry.rancher.com/rancher/cluster-api-addon-provider-fleet:v0.14.1
- name: registry.rancher.com/rancher/fleet-agent:v0.15.1
- name: registry.rancher.com/rancher/fleet:v0.15.1
- name: registry.rancher.com/rancher/rancher-webhook:v0.10.4
- name: registry.rancher.com/rancher/turtles:v0.26.1
- name: registry.rancher.com/rancher/rancher:v2.14.1
- name: registry.rancher.com/rancher/shell:v0.1.24
- name: registry.rancher.com/rancher/system-upgrade-controller:v0.19.1
- name: registry.rancher.com/rancher/cluster-api-controller:v1.12.2
- name: registry.suse.com/rancher/cluster-api-provider-metal3:v1.12.3
- name: registry.rancher.com/rancher/cluster-api-provider-rke2-bootstrap:v0.24.3
- name: registry.rancher.com/rancher/cluster-api-provider-rke2-controlplane:v0.24.3
- name: registry.rancher.com/rancher/ip-address-manager:v1.12.3
- name: registry.rancher.com/rancher/kubectl:v1.35.2
- name: registry.rancher.com/rancher/mirrored-cluster-api-controller:v1.12.2
- name: registry.rancher.com/rancher/scc-operator:v0.4.0
- name: registry.rancher.com/rancher/kubectl:v1.33.1
- name: registry.suse.com/edge/3.6/ironic-python-agent:3.0.830.2 Modifications in the custom folder #
The
custom/scripts/99-register.shscript must be removed when using an air-gap environment. As you can see in the directory structure, the99-register.shscript is not included in thecustom/scriptsfolder.
30.3 Modifications in the kubernetes folder #
You need to modify the
${MGMT_CLUSTER_REGISTRY_IP}with a reserved static IP for the SUSE Private Registry in the following file:kubernetes/manifests/metallb-registry.yamlapiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: private-registry namespace: metallb-system spec: ipAddressPools: - private-registry-pool --- apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: private-registry-pool namespace: metallb-system spec: addresses: - ${MGMT_CLUSTER_REGISTRY_IP}/32 serviceAllocation: namespaces: - suse-private-registrykubernetes/helm/values/privateregistry.yamlcore: secretName: suse-registry-tls expose: tls: certSource: secret enabled: true secret: secretName: suse-registry-tls type: loadBalancer externalURL: https://${MGMT_CLUSTER_REGISTRY_IP} persistence: persistentVolumeClaim: registry: size: 20Gi
The
kubernetes/manifests/suse-private-registry-creds.yamlmust be created with the following content:
apiVersion: v1
kind: Secret
metadata:
name: suse-registry
namespace: suse-private-registry
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ${DOCKER_CONFIG_JSON_BASE64}
---
apiVersion: v1
kind: Secret
metadata:
name: suse-registry-tls
namespace: suse-private-registry
type: kubernetes.io/tls
data:
tls.crt: ${TLS_CRT_BASE64}
tls.key: ${TLS_KEY_BASE64}You need to modify the ${DOCKER_CONFIG_JSON_BASE64}, ${TLS_CRT_BASE64} and ${TLS_KEY_BASE64}. To correctly configure the docker config json (base64), you can do the following:
# ${DOCKER_CONFIG_JSON_BASE64} CONTENT
echo -n '{"auths":{"<MGMT_CLUSTER_REGISTRY_IP>":{"username":"<USERNAME>","password":"<PASSWORD>","auth":"<AUTH>"}}}' | base64 -w 0where the IP is the same as the previously configured ${MGMT_CLUSTER_REGISTRY_IP}, and the <USERNAME>, and <PASSWORD> values can be retrieved from the SUSE Private Registry official documentation; the <AUTH> value set in the auth field is the base64 encoding of the <USERNAME>:<PASSWORD> concatenation.
To set the content of the tls.crt and tls.key fields in the suse-registry-tls Secret manifest above, you can generate your own TLS self-signed certificate and related private key by running the following commands:
# Generate a self-signed certificate and key
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes
# Convert them to base64 for the suse-private-registry-creds.yaml file
cat cert.pem | base64 -w 0
cat key.pem | base64 -w 0