VMware
vSphere
air-gapped
restriced
disconnected
OpenShiftTV
vSphere IPI & disconnected environment
Note
This is not a complete documentation or copy & past ready documentation!
At least speaker notes or my personal notes, highlight only some key points.
A complete documentation is available at docs.openshift.com or docs.redhat.com
Recording
VIDEO
Definition
disconnected : Cluster has no access to the internet DIRECTLY (firewall rules are in place). They may or maynot have a proxy.
restricted : Cluster has SOME access to the internet (firewall rules allow some but not all). Install may fail. They may or maynot have a proxy. Term used in the documentation!
airgapped . Cluster has NO access to the internet. Full Stop. Not even the router or switches or anything have access. Think of a military install.
Kudos to Christian Hernandez
vSphere 7
Domain: example.com
Network: 172.16.0.0/24
172.16.0.4
- jumphost-disconnected.example.com (proxy in the env., ntpd,
vcenter forwarder)
172.16.0.5
- quay.example.com (image registry, dns, dhcp, git-server,
httpd)
VIPS:
172.16.0.10
- api.infra.example.com
172.16.0.11
- *.apps.infra.example.com
172.16.0.12
- api.demo1.example.com
172.16.0.13
- *.apps.demo1.example.com
172.16.0.14
- api.demo1.example.com
172.16.0.15
- *.apps.demo1.example.com
Overview
OpenShift installation
Mirror release images
Mirror rhcos ova
Prepare install-config.yaml
Important: imageContentSources 🔴, additionalTrustBundle,
platform.vsphere.clusterOSImage (check openshift-install explain
)
Run installation
OpenShift post-installation steps
OperatorHub / OLM
Disable default catalog sources
Create operator index
Mirror operator images
Apply operator source & imageContentSourcePolicy
OpenShift Upgrade
Demo: Run a pipeline
Documentation & use-full resources
OpenShift Installation
Mirror relrease images
$ cat env.sh
export OCP_RELEASE = 4 .7.0
export LOCAL_REGISTRY = 'quay.example.com'
export LOCAL_REPOSITORY = 'infra/openshift4'
export PRODUCT_REPO = 'openshift-release-dev'
export LOCAL_SECRET_JSON = 'pullsecret.json'
export RELEASE_NAME = "ocp-release"
export ARCHITECTURE = x86_64
$ ./env.sh
$ oc adm release mirror -a ${ LOCAL_SECRET_JSON } \
--from= quay.io/${ PRODUCT_REPO } /${ RELEASE_NAME } :${ OCP_RELEASE } -${ ARCHITECTURE } \
--to= ${ LOCAL_REGISTRY } /${ LOCAL_REPOSITORY } \
--to-release-image= ${ LOCAL_REGISTRY } /${ LOCAL_REPOSITORY } :${ OCP_RELEASE } -${ ARCHITECTURE }
....
imageContentSources:
- mirrors:
- quay.example.com/infra/openshift4
source: quay.io/openshift-release-dev/ocp-release- mirrors:
- quay.example.com/infra/openshift4
source: quay.io/openshift-release-dev/ocp-v4.0-art-dev
Install OpenShift
Example install-config
apiVersion : v1
baseDomain : example.com
compute :
- architecture : amd64
hyperthreading : Enabled
name : worker
platform : {}
replicas : 3
controlPlane :
architecture : amd64
hyperthreading : Enabled
name : master
platform : {} replicas: 3metadata :
creationTimestamp : null
name : infra
networking :
clusterNetwork :
- cidr : 10.128.0.0/14
hostPrefix : 23
machineNetwork :
- cidr : 10.0.0.0/16
networkType : OpenShiftSDN
serviceNetwork :
- 172.30.0.0/16
platform :
vsphere :
apiVIP : 172.16.0.10
cluster : lab
datacenter : DC
defaultDatastore : datastore
ingressVIP : 172.16.0.11
network : Disconnected
password : xxx
username : xxx
vCenter : vcenter.example.com
folder : /DC/vm/rbohne/
clusterOSImage : http://quay.example.com:8080/rhcos-4.7.0-x86_64-vmware.x86_64.ova?sha256=13d92692b8eed717ff8d0d113a24add339a65ef1f12eceeb99dabcd922cc86d1
publish : External
imageContentSources :
- mirrors :
- quay.example.com/infra/openshift4
source : quay.io/openshift-release-dev/ocp-release
- mirrors :
- quay.example.com/infra/openshift4
source : quay.io/openshift-release-dev/ocp-v4.0-art-dev
pullSecret : '{"auths":{"quay.example.com":{"auth":"YWRtaW46cmVkaGF0MDI="}}}'
sshKey : "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCu9AV3k/ktphogW+Y28fZ0R+ncTxtXalVmpGjvZCuARZJQcgA72pNnXSvrTadJo5D48LgXOz5BwZnoml0toPkLVKBa4fU6kvQsQHDzvElpKbBH8/tmYRV72wt2kJjAS//Ycu9qz2scK+YAdjyle+WUh0qyEzgKKkLjwUmdZOYfJ0eZP+Jl5ljeXk3olCcAQc7JaBr3umREr5o/3+wnHsYPlOGZoSvGRTuEy81tQTL+Nl12LrN1ZxZQZ8jzIExIGRvk8/F2oufFfCigXkEiMf+8l2WXDVR/MGLVhEyle2tJAczBwaskh1nJFKfK6H88lm0fyVev9++GYClSvIxjBWmD88s09cei6C4gRSKANtANmtoOUNhVGcFXaJSPHnrOo7bKnU7XNAcmEZZtUuB05Oc1lJSNoBB9wDj65hzvWnyvQ/zgXeSmUjHObArZ054qPtscIV5QGQUdgVsRCgPWS9SlmYMje9O8AJe+Kqye3ykyMeRDZEUNvO+9Pg+ZGbgH7eM= root@jumphost-disconnected.localdomain"
additionalTrustBundle : |
-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIUVwbzbrQNDW3tU2xdZDVsF5VzTlEwDQYJKoZIhvcNAQEL
BQAwgagxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
....
qGE5LlcUuR0SCO8yVcILcaiXhxGzqYlOZK26u4APntWyn4eUGuLpiReimgE4NvZr
ZYDgBfQ2I9ulhe0dAScUJz0c8iErjpJJ9kT0Ebar/UuPGQvyOnvM
-----END CERTIFICATE-----
Run openshift-install create cluster
Post installation
https://docs.openshift.com/container-platform/4.7/openshift_images/image-configuration.html
oc create configmap additional-trusted-ca \
--from-file= quay.example.com= /etc/pki/ca-trust/source/anchors/quay.ca.crt \
-n openshift-config
oc apply -f - <<EOF
apiVersion: config.openshift.io/v1
kind: Image
metadata:
name: cluster
spec:
allowedRegistriesForImport:
- domainName: quay.example.com
insecure: false
# If not added update will fail
# oc logs -n openshift-cluster-version -l k8s-app=cluster-version-operator
# I0413 08:12:21.986805 1 reflector.go:530] github.com/openshift/client-go/config/informers/externalversions/factory.go:101: Watch close - *v1.Proxy total 0 items received
#E0413 08:12:22.072266 1 task.go:112] error running apply for imagestream "openshift/cli" (378 of 668): ImageStream.image.openshift.io "cli" is invalid: spec.tags[latest].from.name: Forbidden: registry "quay.io" not allowed by whitelist: "image-registry.openshift-image-registry.svc:5000", "quay.example.com:443"
#I0413 08:12:24.705418 1 leaderelection.go:273] successfully renewed lease openshift-cluster-version/version
- domainName: quay.io
insecure: false
additionalTrustedCA:
name: additional-trusted-ca
registrySources:
containerRuntimeSearchRegistries:
- quay.example.com
allowedRegistries:
- quay.example.com
- registry.redhat.io
- quay.io
- registry.access.redhat.com
- image-registry.openshift-image-registry.svc:5000
EOF
Disable catalog sources
https://docs.openshift.com/container-platform/4.7/operators/admin/olm-restricted-networks.html#olm-restricted-networks-operatorhub_olm-restricted-networks
oc patch OperatorHub cluster --type json -p '[{"op": "add", "path": "/spec/disableAllDefaultSources", "value": true}]'
Create PVC
oc create -f - <<EOF
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: image-registry-pvc
namespace: openshift-image-registry
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: thin
EOF
Patch registry operator crd
oc patch configs.imageregistry.operator.openshift.io/cluster \
--type= 'json' \
--patch= '[
{"op": "replace", "path": "/spec/managementState", "value": "Managed"},
{"op": "replace", "path": "/spec/rolloutStrategy", "value": "Recreate"},
{"op": "replace", "path": "/spec/replicas", "value": 1},
{"op": "replace", "path": "/spec/storage", "value": {"pvc":{"claim": "image-registry-pvc" }}}
]'
chronybase64=$(cat << EOF | base64 -w 0
server 172.16.0.4 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
EOF
)
oc apply -f - << EOF
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 50-worker-chrony
spec:
config:
ignition:
version: 2.2.0
storage:
files:
- contents:
source: data:text/plain;charset=utf-8;base64,${chronybase64}
filesystem: root
mode: 0644
path: /etc/chrony.conf
EOF
oc apply -f - << EOF
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: master
name: 50-master-chrony
spec:
config:
ignition:
version: 2.2.0
storage:
files:
- contents:
source: data:text/plain;charset=utf-8;base64,${chronybase64}
filesystem: root
mode: 0644
path: /etc/chrony.conf
EOF
Operator installation
source env.sh
export REG_CREDS=${XDG_RUNTIME_DIR}/containers/auth.json
# Login into all registries...
podman run -p50051:50051 \
-it registry.redhat.io/redhat/redhat-operator-index:v4.7
opm index prune \
-f registry.redhat.io/redhat/redhat-operator-index:v4.7 \
-p advanced-cluster-management \
-t quay.example.com/infra/redhat-operator-index:v4.7
grpcurl -plaintext localhost:50051 api.Registry/ListPackages > packages.out
grep -E '(advanc|pipeline)' packages.out
opm index prune \
-f registry.redhat.io/redhat/redhat-operator-index:v4.7 \
-p advanced-cluster-management,openshift-pipelines-operator-rh,web-terminal \
-t quay.example.com/infra/redhat-operator-index:v4.7
podman push quay.example.com/infra/redhat-operator-index:v4.7
$ oc adm catalog mirror \
-a ${REG_CREDS} \
--manifests-only \
--index-filter-by-os='.*' \
quay.example.com/infra/redhat-operator-index:v4.7 \
quay.example.com/infra
src image has index label for database path: /database/index.db
using database path mapping: /database/index.db:/tmp/353326806
wrote database to /tmp/353326806
using database at: /tmp/353326806/index.db
no digest mapping available for quay.example.com/infra/redhat-operator-index:v4.7, skip writing to ImageContentSourcePolicy
wrote mirroring manifests to manifests-redhat-operator-index-1618230619
cd manifests-redhat-operator-index-1618230619
oc image mirror \
--skip-multiple-scopes=true \
-a ${REG_CREDS} \
--filter-by-os='.*' \
-f mapping.txt
Cluster upgrade
https://docs.openshift.com/container-platform/4.7/updating/updating-restricted-network-cluster.html
Mirror
source env.sh
export OCP_RELEASE=4.7.2
oc adm release mirror -a ${LOCAL_SECRET_JSON} \
--from=quay.io/${PRODUCT_REPO}/${RELEASE_NAME}:${OCP_RELEASE}-${ARCHITECTURE} \
--to=${LOCAL_REGISTRY}/${LOCAL_REPOSITORY} \
--apply-release-image-signature
....
Update command
oc adm release info -a $REG_CREDS quay.example.com/infra/openshift4:4.7.2-x86_64 | grep 'Pull From'
Pull From: quay.example.com/infra/openshift4@sha256:83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584
oc adm upgrade --allow-explicit-upgrade --to-image quay.example.com/infra/openshift4@sha256:83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584
OpenShift Update Service
https://www.openshift.com/blog/openshift-update-service-update-manager-for-your-cluster
Demo: Run a pipeline
Creating Pipeline Tasks
oc create -f http://quay.example.com:3000/openshift/pipelines-tutorial/raw/pipelines-1.3/01_pipeline/01_apply_manifest_task.yaml
oc create -f http://quay.example.com:3000/openshift/pipelines-tutorial/raw/pipelines-1.3/01_pipeline/02_update_deployment_task.yaml
oc create -f http://quay.example.com:3000/openshift/pipelines-tutorial/raw/pipelines-1.3/01_pipeline/04_pipeline.yaml
Mirroring images to run pipelines in a restricted environment
Mirroring images to run pipelines in a restricted environment
oc image mirror -a $REG_CREDS registry.redhat.io/ubi8/python-38:latest quay.example.com/ubi8/python-38:latest
oc image mirror -a $REG_CREDS registry.redhat.io/ubi8/go-toolset:1.14.7 quay.example.com/ubi8/go-toolset
oc tag quay.example.com/ubi8/python-38:latest python:latest --scheduled -n openshift
oc tag quay.example.com/ubi8/go-toolset:1.14.7 golang:latest --scheduled -n openshift
oc tag quay.example.com/infra/openshift4:4.7.0-x86_64-cli cli:latest --scheduled -n openshift
Run pipeline
tkn pipeline start build-and-deploy \
-w name=shared-workspace,volumeClaimTemplateFile=http://quay.example.com:3000/openshift/pipelines-tutorial/raw/pipelines-1.3/01_pipeline/03_persistent_volume_claim.yaml \
-p deployment-name=vote-api \
-p git-url=http://quay.example.com:3000/openshift-pipelines/vote-api.git \
-p IMAGE=image-registry.openshift-image-registry.svc:5000/pipeline/vote-api
tkn pipeline start build-and-deploy \
-w name=shared-workspace,volumeClaimTemplateFile=http://quay.example.com:3000/openshift/pipelines-tutorial/raw/pipelines-1.3/01_pipeline/03_persistent_volume_claim.yaml \
-p deployment-name=vote-ui \
-p git-url=http://quay.example.com:3000/openshift-pipelines/vote-ui.git \
-p IMAGE=image-registry.openshift-image-registry.svc:5000/pipeline/vote-ui
Problem
[build-image : build] WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fdf07b05c10>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/flask/
[build-image : build] WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fdf07b05280>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/flask/
[build-image : build] WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fdf07b05520>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/flask/
[build-image : build] WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fdf07b050d0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/flask/
[build-image : build] WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7fdf07afaf40>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/flask/
[build-image : build] ERROR: Could not find a version that satisfies the requirement Flask (from -r requirements.txt (line 1)) (from versions: none)
[build-image : build] ERROR: No matching distribution found for Flask (from -r requirements.txt (line 1))
[build-image : build] subprocess exited with status 1
[build-image : build] subprocess exited with status 1
[build-image : build] error building at STEP "RUN pip install -r requirements.txt": exit status 1
[build-image : build] level=error msg="exit status 1"
Solution: You have to mirror....
Appendix - Setup supporting infrastructure
Setup quay
Deploy Red Hat Quay for proof-of-concept (non-production) purposes
Setup Git-server
mkdir /home/gogs
cat > /etc/systemd/system/gogs.service <<EOF
[Unit]
Description=gogs
After=network.target
[Service]
Type=simple
TimeoutStartSec=5m
ExecStartPre=-/usr/bin/podman rm gogs
ExecStart=/usr/bin/podman run --name gogs \
-p 2222:22 \
-p 3000:3000 \
-v /home/gogs:/data:Z \
docker.io/gogs/gogs:latest
ExecReload=-/usr/bin/podman stop gogs
ExecReload=-/usr/bin/podman rm gogs
ExecStop=-/usr/bin/podman stop gogs
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
EOF
DNS & dhcp
Skiped, straigt foroward dnsmasq:
[root@quay ~]# cat /etc/dnsmasq.d/openshift-4.conf
#strict-order
domain=example.com
#expand-hosts
# Dynamisches DHCP
dhcp-range=172.16.0.100,172.16.0.199,12h
address=/api.infra.example.com/172.16.0.10address=/apps.infra.example.com/172.16.0.11
address=/api.demo1.example.com/172.16.0.12
address=/apps.demo1.example.com/172.16.0.13
2021-05-05
2021-04-12
Contributors: