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-toolsterraform-providers (optional) → kubespray-corek8s-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/