7. Deployment View
The Pandur cluster is bootstrapped in two clearly separated steps — infrastructure, then GitOps — documented in full in pandur-cluster-bootstrap/README.md and automated (with manual token/secret input) in pandur-cluster-bootstrap/create-pandur.sh.
1. Infrastructure Level 1
- Motivation
-
Infrastructure (network, load balancer, nodes) and Kubernetes add-ons are deliberately kept in separate tools and separate failure domains ([CT-002 Kubernetes via Cluster API ], [CT-004 GitOps single source of truth ]): CAPH only ever manages Hetzner resources and the cluster’s machines, OpenTofu only ever manages the NAT gateway and the default route, and everything above "a running kubelet" is GitOps.
- Quality and/or Performance Features
-
-
Nodes have neither public IPv4 nor IPv6 ([CT-003 No public node IPs ]); the only public entry point is the Control-Plane Load Balancer (Kubernetes API) and, after Traefik is installed, the ingress Load Balancer.
-
MachineHealthCheck+HCloudRemediationTemplate(part of Phase 2) automatically replace unhealthy control-plane or worker machines, supporting [RE01 24/7 Availability] . -
The two-phase split means a broken OpenTofu run can be retried/destroyed without touching CAPH-owned resources, and vice versa.
-
- Mapping of Building Blocks to Infrastructure
-
Steps 5, 7 and 8 above install the Level 1 building blocks:
networking(Cilium, Traefik),argocd, and — once Argo CD exists —security,storage,operators,cnpg-systemandobservabilityare all reconciled onto the samepandurcluster shown here.
2. Infrastructure Level 2
2.1. Phase 1: CAPH base infrastructure
kubectl apply -f clusterctl/pandur-01-infrastructure.yaml against the temporary kind-management cluster creates and CAPH continues to own:
-
Cluster/pandurandHetznerCluster/pandur -
the private network
10.0.0.0/16with cloud subnet10.0.0.0/24 -
the Hetzner network gateway
10.0.0.1 -
the control-plane load balancer
-
placement groups
No Kubernetes nodes exist yet at the end of this phase.
2.2. OpenTofu: NAT gateway and default route
Once the network exists (its ID is read back via hcloud network describe pandur), pandur-cluster-bootstrap/opentofu creates and owns:
-
the NAT server and its stable public IPv4 (
nat_public_ipv4) -
the NAT firewall
-
the NAT’s attachment to the private network (private IP
10.0.0.254by default;10.0.0.1is reserved for the CAPH gateway and must not be reused) -
the Hetzner network route
0.0.0.0/0 → 10.0.0.254
This step is a hard prerequisite for Phase 2: control-plane and worker nodes have no public IP and rely on this route for all outbound traffic (package installs, container image pulls, kubeadm).
2.3. Phase 2: CAPH control plane and workers
kubectl apply -f clusterctl/pandur-02-cluster.yaml — only after the NAT route is confirmed working — creates:
-
KubeadmControlPlane(multiple replicas) -
MachineDeploymentfor workers -
KubeadmConfigTemplate -
HCloudMachineTemplatefor both control-plane and worker machines, withpublicNetwork.enableIPv4/enableIPv6: false -
MachineHealthCheckandHCloudRemediationTemplate
Each machine’s cloud-init sets the OS default route via the private gateway 10.0.0.1 and configures DNS before kubeadm runs, since the node has no other way to reach the internet at that point.
2.4. Workload kubeconfig and Kubernetes add-ons
Once KubeadmControlPlane reports INITIALIZED=true, a workload kubeconfig is extracted with clusterctl get kubeconfig pandur --namespace clusters. Nodes are NotReady until CNI and the cloud controller manager exist, so create-pandur.sh installs, directly via helm upgrade --install (i.e. not yet via Argo CD, which does not exist yet):
-
the Hetzner Cloud Controller Manager (HCCM), after patching the
kube-system/hcloudsecret with the network ID -
Cilium (CNI)
-
the kubelet CSR approver (needed to approve kubelet serving certificates during the upcoming pivot)
-
Traefik (ingress controller)
2.5. Cluster pivot
clusterctl move transfers the Cluster API custom resources (Cluster, HetznerCluster, KubeadmControlPlane, MachineDeployment, …) from the temporary kind-management cluster to the pandur cluster itself (after clusterctl init runs against pandur too), so that Pandur becomes self-managing. The kind-management cluster is then deleted.
2.6. Argo CD installation
Finally, Argo CD is installed via helm upgrade --install using pandur/argocd/config/argocd.yml. From this point on, every further change — including Argo CD’s own configuration, via argocd-resources — is reconciled through GitOps ([CT-004 GitOps single source of truth ]) as described in 4. Solution Strategy and GitOps Reconciliation.
- Ownership summary
-
Owner Resources CAPH
Network, Subnet, Control-Plane Load Balancer, Placement Groups, Control-Plane and Worker machines
OpenTofu
NAT public IPv4, NAT server, NAT firewall, NAT network attachment,
0.0.0.0/0network routeWorkload / GitOps (Argo CD, once installed)
HCCM, Cilium, Traefik, security, storage, operators, cnpg-system, observability
HCCM and the kubelet CSR approver are both installed once via helm upgrade --installduring bootstrap, before Argo CD exists, and are both immediately adopted into GitOps afterwards as Argo CDApplication`s (`pandur/argocd/apps/hccm.ymlandpandur/security/apps/kubelet-csr-approver.yml); [TR-002 HCCM is not GitOps-managed] is resolved.