Lab 02: Step-by-Step Guide
Complete walkthrough of the air-gapped deployment process.
Phase 1: Preparation (With Internet)
Step 1: Prerequisites Check
# Check tools are installed
docker --version
kind --version
helm version
kubectl version --client
# Check disk space (need ~10GB)
df -h .
# Check Docker is running
docker psStep 2: Navigate to Preparation Directory
cd labs/02-airgapped-deployment/preparationStep 3: Mirror Container Images
This pulls all required images and saves them as tar files.
./mirror-images.shWhat happens:
- Script reads
modules/kubernetes/argo-workflows-airgap/images.txt - For each image:
- Pulls from Docker Hub/Quay.io
- Saves as tar file in
images/directory
- Shows progress for each image
Expected output:
🖼️ Mirroring container images for air-gapped deployment
[1] Processing: quay.io/argoproj/workflow-controller:v3.5.5
📥 Pulling image...
💾 Saving to: images/quay_io_argoproj_workflow-controller_v3.5.5.tar
✅ Saved successfully
...
✅ Image mirroring complete!Time: 10-25 minutes (depends on internet speed)
Verify:
ls -lh images/
# Should see multiple .tar filesStep 4: Package Helm Charts
This downloads and packages Helm charts for offline use.
./package-helm.shWhat happens:
- Adds Argo Helm repository
- Downloads latest Argo Workflows chart
- Packages as .tgz file in
charts/directory
Expected output:
📦 Packaging Helm charts for offline installation
📥 Adding Helm repositories...
📦 Packaging Argo Workflows chart...
Version: 0.43.1
✅ Chart packaged successfullyTime: 1-2 minutes
Verify:
ls -lh charts/
# Should see argo-workflows-*.tgzStep 5: Create Deployment Bundle
This packages everything into a complete bundle.
./create-bundle.shWhat happens:
- Creates bundle directory with timestamp
- Copies all images to bundle
- Copies all charts to bundle
- Copies deployment scripts
- Creates checksums for verification
- Creates bundle README
Expected output:
📦 Creating deployment bundle for air-gapped environment
📁 Creating bundle structure...
📋 Copying images...
✅ Copied 5 image files
📋 Copying Helm charts...
✅ Copied 1 chart files
...
✅ Bundle created successfully!
Bundle location: preparation/airgap-deployment-bundle-20260105-143022
Total size: 2.5GTime: 1-2 minutes
Verify:
ls -lh airgap-deployment-bundle-*/
# Should see: images/, charts/, scripts/, manifests/, checksums.txt, README.mdStep 6: Verify Bundle Integrity
cd airgap-deployment-bundle-*
sha256sum -c checksums.txt
# All files should show "OK"Step 7: Transfer Bundle (For Real Air-Gap)
USB Drive:
# Copy bundle to USB
cp -r airgap-deployment-bundle-* /Volumes/USB-DRIVE/
# On air-gapped machine, copy from USB
cp -r /Volumes/USB-DRIVE/airgap-deployment-bundle-* ~/Network Transfer (if available):
# From preparation machine
scp -r airgap-deployment-bundle-* user@airgap-machine:/path/to/destination/
# Verify on air-gapped machine
sha256sum -c checksums.txtFor Lab (Local Simulation):
- Skip transfer step
- Bundle is already on your machine
Phase 2: Deployment (Air-Gapped)
Step 1: Setup Air-Gap Simulation (Local Testing)
For local testing, create a Kind cluster that simulates air-gap.
cd ../local-simulation
./setup-airgap-sim.shWhat happens:
- Creates Kind cluster named
airgap-simulation - Applies network policies to block external access
- Creates
argoandregistrynamespaces - Configures cluster for air-gap simulation
Expected output:
🚀 Setting up Kind cluster for air-gap simulation
📦 Creating Kind cluster...
✅ Cluster created successfully
🔒 Applying network policies...
✅ Network policies applied
✅ Air-gap simulation setup complete!Time: 5-10 minutes
Verify:
kubectl get nodes
kubectl get networkpolicies --all-namespacesFor Real Air-Gapped Environment:
- Skip this step
- Use your existing air-gapped Kubernetes cluster
- Ensure network policies block external egress
Step 2: Configure kubectl Context
# For Kind cluster
export KUBECONFIG=$(kind get kubeconfig-path --name airgap-simulation)
kubectl config use-context kind-airgap-simulation
# Verify
kubectl get nodesStep 3: Deploy Local Registry
Deploy a Docker registry inside your cluster.
cd ../deployment
./deploy-registry.shWhat happens:
- Creates
registrynamespace - Deploys Docker registry deployment
- Creates registry service
- Waits for registry to be ready
Expected output:
📦 Deploying local container registry
📋 Applying registry manifests...
⏳ Waiting for registry to be ready...
✅ Registry deployed successfully!
Registry endpoint: 10.96.0.1:5000
Registry service: local-registry.registry.svc.cluster.local:5000Time: 2-3 minutes
Verify:
kubectl get pods -n registry
kubectl get svc -n registryStep 4: Load Images into Registry
Load images from bundle into the local registry.
Important for Kind: You may need to port-forward the registry first:
# In a separate terminal, port-forward registry
kubectl port-forward svc/local-registry 5000:5000 -n registry &Then set registry to localhost:
export REGISTRY=localhost:5000
./load-images.shWhat happens:
- Reads image tar files from bundle
- Loads each image into Docker
- Tags images with registry address
- Pushes images to local registry
Expected output:
📥 Loading container images into local registry
[1] Processing: quay_io_argoproj_workflow-controller_v3.5.5.tar
📥 Loading image...
🏷️ Tagging as: localhost:5000/quay.io/argoproj/workflow-controller:v3.5.5
📤 Pushing to registry...
✅ Successfully pushed
...
✅ Image loading complete!Time: 10-20 minutes (depends on image sizes)
Verify:
# Check registry has images
kubectl exec -n registry deployment/local-registry -- ls /var/lib/registry/docker/registry/v2/repositories/Step 5: Deploy Argo Workflows
Install Argo Workflows using local charts and images.
./deploy-argo.shWhat happens:
- Creates
argonamespace - Finds packaged Helm chart
- Updates values file with registry address
- Installs Argo Workflows from local chart
- Uses images from local registry
- Waits for deployment to be ready
Expected output:
⚙️ Deploying Argo Workflows from local images
📦 Found chart: argo-workflows-0.43.1.tgz
📝 Creating namespace...
📋 Installing Argo Workflows...
✅ Argo Workflows installed successfully
⏳ Waiting for Argo Workflows to be ready...
✅ Argo Workflows deployment complete!Time: 5-10 minutes
Verify:
kubectl get pods -n argo
kubectl get svc -n argoStep 6: Validate Deployment
Verify everything is working correctly.
./validate.shWhat it checks:
- Namespaces exist
- Registry is running
- Argo Workflows components are ready
- Pods are using local registry images
- External access is blocked
Expected output:
🔍 Validating air-gapped deployment
📦 Checking namespaces...
✅ Namespace 'argo' exists
✅ Namespace 'registry' exists
...
✅ Validation complete!Step 7: Verify Air-Gap
Confirm that external access is blocked.
# This should FAIL (proving we're air-gapped)
kubectl run test --image=busybox --rm -it --restart=Never -- wget -O- https://www.google.com
# Expected: Connection refused or timeoutOr use the verification script:
../scripts/verify-airgap.shStep 8: Test Argo Workflows
Submit a test workflow to verify everything works.
# Submit test workflow
kubectl apply -f ../../reference-app/workflows/hello-world.yaml
# Check workflow status
kubectl get workflows -n argo
# View workflow details
kubectl describe workflow hello-world -n argo
# View logs
kubectl logs -n argo -l app=workflow-controllerExpected:
- Workflow should be created
- Workflow should execute successfully
- No image pull errors
- Workflow completes
Step 9: Access Argo UI (Optional)
Since we're air-gapped, use port-forward to access the UI:
kubectl port-forward svc/argo-workflows-server 2746:2746 -n argoThen open: http://localhost:2746
Troubleshooting Steps
If something fails:
Check pod status:
bashkubectl get pods --all-namespaces kubectl describe pod <pod-name> -n <namespace>Check logs:
bashkubectl logs <pod-name> -n <namespace>Check events:
bashkubectl get events --all-namespaces --sort-by='.lastTimestamp'Verify registry:
bashkubectl get svc -n registry kubectl logs -n registry deployment/local-registryCheck network policies:
bashkubectl get networkpolicies --all-namespaces
See Troubleshooting Guide for detailed solutions.
Success Criteria
You've successfully completed the lab when:
- ✅ All images are loaded into local registry
- ✅ Argo Workflows is deployed and running
- ✅ All pods are using local registry images
- ✅ External internet access is blocked
- ✅ Test workflow executes successfully
- ✅ No image pull errors in pod logs
Next Steps
After completing this lab:
- Review the patterns learned
- Experiment with different workflows
- Read about update strategies
- Understand how to apply this to real engagements
- Proceed to Lab 03: Private Network Deployment