Skip to main content

Bastion Setup & Deployment

Purpose: For operators, shows how to configure the bastion as local container registry and package repository.

Prerequisites​

  • Bastion host running Ubuntu 24.04 in Zone C (disconnected network)
  • Zarf CLI installed on the bastion
  • The zarf-package-opencenter-airgap-amd64-*.tar.zst artifact transferred from Zone A
  • SSH access from bastion to all target cluster nodes
  • Minimum 100 GB free disk on /opt/opencenter
  • Ports 35000 (registry) and 80 (nginx) open to target node subnet

Steps​

1. Verify the artifact​

Confirm the package checksum matches what was recorded in Zone A:

sha256sum -c package.sha256

If the checksum fails, do not proceed — the artifact may be corrupted or tampered with.

2. Deploy the Zarf package​

zarf package deploy zarf-package-opencenter-airgap-amd64-*.tar.zst --confirm

Zarf prompts for variables unless --confirm is passed. Key variables and their defaults:

VariableDefaultDescription
BASTION_IP(prompted)IP address of this bastion host
SSH_USERdeployerSSH user for node access
INSTALL_PATH/opt/opencenterRoot directory for all artifacts
REGISTRY_PORT35000Local OCI registry listen port
NGINX_PORT80Nginx file server listen port

The deploy runs five components in order: bootstrap-tools → terraform-providers (optional) → kubespray-core → k8s-images (optional) → deploy-cluster.

3. Confirm services are running​

After deploy completes, the deploy-cluster component runs setup-all.sh, which starts the registry and nginx. Verify:

# Registry health check
curl -s http://localhost:35000/v2/_catalog | head

# Nginx file server
curl -s http://localhost:80/ | head

# Check container status (registry runs via podman)
podman ps --filter name=local-registry

4. Validate target node connectivity​

From the bastion, confirm each target node can reach the bastion services:

for node in 192.168.1.11 192.168.1.12 192.168.1.13; do
ssh ${SSH_USER}@${node} "curl -sf http://${BASTION_IP}:35000/v2/_catalog > /dev/null && echo ${node}: registry OK || echo ${node}: registry FAIL"
ssh ${SSH_USER}@${node} "curl -sf http://${BASTION_IP}:80/ > /dev/null && echo ${node}: nginx OK || echo ${node}: nginx FAIL"
done

5. Configure target nodes to use bastion​

Target nodes need their container runtime and package manager pointed at the bastion. Kubespray handles this automatically when run from the bastion, but for manual verification:

# containerd registry mirror (set by Kubespray)
cat /etc/containerd/config.toml | grep -A3 'registry.mirrors'

# APT repository (set by setup-all.sh)
cat /etc/apt/sources.list.d/opencenter-local.list

Expected APT source line:

deb [trusted=yes] http://<BASTION_IP>:80/repos/ubuntu jammy main

Verification​

Run a quick pull test from any target node:

# Pull an image through the bastion registry
crictl pull ${BASTION_IP}:35000/registry:2.8.3

# Install a package from the bastion repo
apt-get update && apt-get install -y jq

Troubleshooting​

SymptomLikely causeFix
curl: (7) Failed to connect on port 35000Registry container not runningpodman start local-registry
curl: (7) Failed to connect on port 80Nginx not startedCheck setup-all.sh logs in /opt/opencenter/logs/
Target node can't resolve bastionDNS not configuredUse IP address directly or add /etc/hosts entry
manifest unknown when pulling imageImage not loaded into registryRe-run load-push-all-images.sh from /opt/opencenter/target-scripts/