Skip to content

Commit e912d43

Browse files
committed
Updated and tested instructions
1 parent 877ea08 commit e912d43

File tree

4 files changed

+110
-16
lines changed

4 files changed

+110
-16
lines changed

README.md

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,97 @@
11
# Use oc-mirror v2 for an OpenShift Integrated Registry
22

3-
4-
3+
![GitHub release (latest by date)](https://img.shields.io/github/v/release/kevchu3/oc-mirror-v2-integrated-registry?color=blue&style=plastic)
54
![GitHub](https://img.shields.io/github/license/kevchu3/oc-mirror-v2-integrated-registry?color=blue&style=plastic)
65

76
## Background
87

9-
The following procedures are designed for an airgapped OpenShift cluster to mirror images to the OpenShift integrated registry, to reduce setup time and eliminate network connectivity to an external registry. Mirroring uses the oc-mirror OpenShift CLI (oc) plugin, which mirrors all required OpenShift Container Platform content and other images to your mirror registry. We'll use the oc-mirror v2 plugin ([refer to the docs](https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/disconnected_environments/mirroring-in-disconnected-environments#about-installing-oc-mirror-v2) to mirror to the cluster's OpenShift integrated registry, typically available at `image-registry.openshift-image-registry.svc.cluster.local:5000`.
8+
The following procedures are designed for an airgapped Red Hat OpenShift cluster to mirror images to the OpenShift integrated registry, to reduce setup time and eliminate network connectivity to an external registry. Mirroring uses the oc-mirror OpenShift CLI (oc) plugin, which mirrors all required OpenShift Container Platform content and other images to your mirror registry. We'll use the oc-mirror v2 plugin ([refer to the docs](https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/disconnected_environments/mirroring-in-disconnected-environments#about-installing-oc-mirror-v2)) to mirror to the cluster's OpenShift integrated registry, typically available at `image-registry.openshift-image-registry.svc.cluster.local:5000`.
9+
10+
# Design
11+
12+
This design pattern assumes the cluster is not fully airgapped and there is limited connectivity to the internet. In a fully airgapped scenario, since the integrated registry is responsible for providing infrastructure images, the unavailability of the registry during an upgrade is a risk as a potential point of cyclical failure. In addition, in a fully airgapped scenario, additional images for the operator catalog will need to be mirrored, and `CatalogSource` configured for an offline registry.
13+
14+
An `ImageDigestMirrorSet` (IDMS) for the cluster will be configured to redirect images to the internal registry. Since applying IDMS requires a node cordon and drain, we've opted to handcraft an IDMS manifest that will be consistent over time even if operators add images to their upstream repositories. There is no guarantee that these upstream repositories (i.e. `registry.redhat.io/container-native-virtualization`) will not change paths over time, but it is infrequent at best.
15+
16+
Prior to mirroring images, the OpenShift integrated registry should be configured for persistent storage with ReadWriteMany access mode and two or more replicas to support high availability.
17+
18+
## Setup
19+
20+
The oc-mirror v2 binary will mirror images based on an `ImageSetConfiguration` to target repositories. An example [imagesetconfiguration.yaml](manifests/imagesetconfiguration.yaml) has been provided and should be customized based on your mirroring needs. I've opted to wrap my `ImageSetConfiguration` inside a `ConfigMap` to be mounted to my mirroring job pod. To determine the operator packages to specify in the `ImageSetConfiguration`, you can download the `oc-mirror` binary and run the following command (replace the tag with your OpenShift version):
21+
```
22+
./oc-mirror list operators --catalog registry.redhat.io/redhat/redhat-operator-index:v4.18
23+
```
24+
25+
You can view the [Container Platform Update Graph](https://access.redhat.com/labs/ocpupgradegraph/update_path) and your cluster's OperatorHub to determine specific cluster and operator package target versions to download and update. As a good practice, you should also include the source (current) cluster and operator package versions, so that if pods must be drained prior to upgrading, they will pull from the internal registry.
26+
27+
The OpenShift integrated registry stores images in persistent storage (if configured) in the openshift-image-registry namespace, with references from imagestreams in other namespaces. It follows a `<registry>/<repository>/<image>[:tag] or [@sha256:digest]` format with a restriction of two levels of nesting and thus oc-mirror must use `--max-nested-paths=2`. The registry also assumes the repository already exists as an OpenShift namespace prior to pushing images to it. Thus, the namespaces will need to be created before mirroring. You can also use the [Red Hat Ecosystem Catalog](https://catalog.redhat.com/software/containers/explore) to determine the source registry and repository paths that will need to be mirrored, replacing the repository path with the OpenShift namespaces that will need to be created.
28+
29+
Based on the example [imagesetconfiguration.yaml](manifests/imagesetconfiguration.yaml), we will create the following namespaces and configure RBAC to allow [System users](https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/authentication_and_authorization/understanding-authentication#rbac-users_understanding-authentication) to pull images.
30+
31+
```
32+
# openshift namespace already exists
33+
oc create ns openshift4 # maps to registry.redhat.io/openshift4 for local-storage-operator and kubernetes-nmstate-operator
34+
oc create ns redhat # maps to registry.redhat.io/redhat for redhat-operator-index but we won't fetch it airgapped
35+
oc create ns container-native-virtualization # maps to registry.redhat.io/container-native-virtualization for kubevirt-hyperconverged
36+
oc create ns migration-toolkit-virtualization # maps to registry.redhat.io/migration-toolkit-virtualization for kubevirt-hyperconverged
37+
38+
oc adm policy add-role-to-group system:image-puller system:unauthenticated -n openshift
39+
oc adm policy add-role-to-group system:image-puller system:unauthenticated -n openshift4
40+
oc adm policy add-role-to-group system:image-puller system:unauthenticated -n redhat
41+
oc adm policy add-role-to-group system:image-puller system:unauthenticated -n container-native-virtualization
42+
oc adm policy add-role-to-group system:image-puller system:unauthenticated -n migration-toolkit-virtualization
43+
```
1044

11-
## Instructions
45+
## Mirroring
1246

13-
Create new projects `oc-mirror` for the mirror job and `oc-mirror-images` for the mirrored imagestreams. Apply the manifests in this repository:
47+
Create the `oc-mirror` namespace, job, and related manifests:
1448
```
15-
oc new-project oc-mirror # mirror job
16-
oc new-project oc-mirror-images # mirrored imagestreams
49+
oc create ns oc-mirror
1750
oc apply -f manifests
1851
```
1952

53+
In the event that your job pod fails, you can create a debug pod and rerun the oc-mirror commands from within the pod (the pod displays the inline commands but does not automatically execute them when running a debug pod). Image layer blobs that have already been pushed to the registry will not need to be repushed, so the mirroring process should largely pick up where it left off.
54+
55+
```
56+
$ oc get pods
57+
NAME READY STATUS RESTARTS AGE
58+
run-oc-mirror-6x6hl 1/1 Running 0 33s
59+
$ oc debug pod/run-oc-mirror-6x6hl
60+
Starting pod/run-oc-mirror-6x6hl-debug-5ccp2, command was: /bin/bash -c # Download oc-mirror
61+
cd /tmp
62+
curl https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/latest/oc-mirror.tar.gz -o oc-mirror.tar.gz
63+
tar -xzvf oc-mirror.tar.gz
64+
chmod +x oc-mirror
65+
# Login to registry
66+
oc registry login --registry ${REGISTRY} --to=/.docker/destination-registry.json
67+
68+
# Downloads the Pull secret
69+
oc get secret pull-secret -n openshift-config -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d > /tmp/pull-secret.json
70+
71+
# Combine pull secret and registry auth
72+
jq -s 'reduce .[] as $item ({}; .auths += $item.auths)' "/tmp/pull-secret.json" "/.docker/destination-registry.json" > /.docker/config.json
73+
74+
# Run oc-mirror
75+
./oc-mirror --v2 --config=/tmp/imagesetconfiguration.yaml docker://${REGISTRY} --dest-tls-verify=${DEST_TLS_VERIFY} --max-nested-paths=2 --retry-times 10 --workspace=file:///opt/oc-mirror --cache-dir=/opt/oc-mirror --log-level debug
76+
77+
Pod IP: 10.130.1.85
78+
If you don't see a command prompt, try pressing enter.
79+
```
80+
81+
## Applying ImageDigestMirrorSet
82+
83+
After the content has been mirrored, the ImageDigestMirrorSet can be applied. An example [imagedigestmirrorset.yaml](idms/imagedigestmirrorset.yaml) has been provided and should be customized. Applying and updating this manifest will cordon and drain nodes, and I've customized the manifest to be resilient across OpenShift upgrades to reduce the cordon and drain activities.
84+
85+
```
86+
oc apply -f idms/imagedigestmirrorset.yaml
87+
```
88+
89+
## Upgrading
90+
91+
Finally, upgrade OpenShift. Since we specified specific versions in the [imagesetconfiguration.yaml](manifests/imagesetconfiguration.yaml), remember to use the same versions.
92+
93+
To verify the images are being properly pulled through the OpenShift integrated registry, you can search the registry pod logs for corresponding image pulls.
94+
2095
## Credits
2196

2297
Credit to Josh Swanson (Red Hat) for providing the base scripts from which this work was built on.

idms/imagedigestmirrorset.yaml

Whitespace-only changes.

manifests/imagesetconfiguration.yaml

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,34 @@ data:
1313
- "amd64"
1414
graph: false
1515
channels:
16+
- name: stable-4.17
17+
type: ocp
18+
minVersion: 4.17.25
19+
maxVersion: 4.17.25
1620
- name: stable-4.18
1721
type: ocp
1822
minVersion: 4.18.9
1923
maxVersion: 4.18.9
2024
operators:
21-
- catalog: registry.redhat.io/redhat/redhat-operator-index:v4.18
22-
packages:
23-
- name: kubevirt-hyperconverged
24-
- name: local-storage-operator
25-
- name: nmstate-operator
25+
- catalog: registry.redhat.io/redhat/redhat-operator-index:v4.18
26+
packages:
27+
- name: kubevirt-hyperconverged
28+
minVersion: 4.18.2
29+
maxVersion: 4.18.2
30+
- name: local-storage-operator
31+
minVersion: 4.18.0-202504151633
32+
maxVersion: 4.18.0-202504151633
33+
- name: kubernetes-nmstate-operator
34+
minVersion: 4.18.0-202504160308
35+
maxVersion: 4.18.0-202504160308
36+
- catalog: registry.redhat.io/redhat/redhat-operator-index:v4.18
37+
packages:
38+
- name: kubevirt-hyperconverged
39+
minVersion: 4.18.2
40+
maxVersion: 4.18.2
41+
- name: local-storage-operator
42+
minVersion: 4.18.0-202504151633
43+
maxVersion: 4.18.0-202504151633
44+
- name: kubernetes-nmstate-operator
45+
minVersion: 4.18.0-202504160308
46+
maxVersion: 4.18.0-202504160308

manifests/oc-mirror-v2-job.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ spec:
2323
env:
2424
- name: REGISTRY
2525
value: image-registry.openshift-image-registry.svc.cluster.local:5000
26-
- name: IMAGESTREAMS_NAMESPACE
27-
value: oc-mirror-images
2826
- name: DEST_TLS_VERIFY
2927
value: 'false'
3028
command:
@@ -46,7 +44,7 @@ spec:
4644
jq -s 'reduce .[] as $item ({}; .auths += $item.auths)' "/tmp/pull-secret.json" "/.docker/destination-registry.json" > /.docker/config.json
4745
4846
# Run oc-mirror
49-
./oc-mirror --v2 --config=/tmp/imagesetconfiguration.yaml docker://${REGISTRY}/${IMAGESTREAMS_NAMESPACE} --dest-tls-verify=${DEST_TLS_VERIFY} --max-nested-paths=2 --retry-times 10 --workspace=file:///opt/oc-mirror --cache-dir=file:///opt/oc-mirror --log-level debug
47+
./oc-mirror --v2 --config=/tmp/imagesetconfiguration.yaml docker://${REGISTRY} --dest-tls-verify=${DEST_TLS_VERIFY} --max-nested-paths=2 --retry-times 10 --workspace=file:///opt/oc-mirror --cache-dir=/opt/oc-mirror --log-level debug
5048
volumeMounts:
5149
- name: run-oc-mirror-configs
5250
mountPath: /tmp/imagesetconfiguration.yaml
@@ -74,4 +72,4 @@ spec:
7472
sizeLimit: 100Mi
7573
- name: docker-dir
7674
emptyDir:
77-
sizeLimit: 100Mi
75+
sizeLimit: 100Mi

0 commit comments

Comments
 (0)