Galactic VPC
Summary
Section titled “Summary”This guide provides background on the architecture, design decisions, and installation of the components that make up Galactic VPC.
What it is
Section titled “What it is”Galactic VPC is a Kubernetes-native overlay that enables the creation of Virtual Private Cloud (VPC) networks between containers. It allows termination of directly attached interfaces as well as routed network prefixes across a given VPC. This is achieved using an SRv6 (Segment Routing IPv6)-enabled underlay network through which the necessary encapsulated packets are routed.
Components
Section titled “Components”galactic-operator
Section titled “galactic-operator”Our galactic-operator is responsible for two major tasks.
It translates our CRDs into the necessary native or downstream manifests to provide the required functionality.
Primarily, this means creating Multus NetworkAttachmentDefinition
manifests that configure the
relevant CNI plugins.
Additionally, the operator assigns unique identifiers for VPC
and VPCAttachment
objects. These
identifiers are important, as they are used to encode all the relevant endpoint information for the SRv6
targets.
DeepWiki: https://deepwiki.com/datum-cloud/galactic-operator
galactic-cni
Section titled “galactic-cni”galactic-cni is our Kubernetes CNI plugin. It is responsible for creating the necessary low-level Linux kernel resources that tie the container into the relevant SRv6 endpoint. The CNI plugin also assigns a unique local VRF on each host where termination is performed.
DeepWiki: https://deepwiki.com/datum-cloud/galactic-cni
galactic-agent
Section titled “galactic-agent”galactic-agent runs on each Kubernetes node that hosts containers
with terminated endpoints. It does not need to run on control-plane
-only nodes if they do not
host such workloads. It is usually deployed as a DaemonSet
to ensure this.
The primary purpose of the galactic-agent
is to receive and configure routing instructions from the
central routing control plane (aka galactic-router
). It connects to an MQTT broker,
through which the necessary messages are passed using Protobuf-encoded messages.
In addition, the galactic-agent
listens on a host-local Unix socket for gRPC messages
from containers created by the galactic-cni
plugin. These messages register and deregister network
segments and terminations with the central control plane.
DeepWiki: https://deepwiki.com/datum-cloud/galactic-agent
galactic-router
Section titled “galactic-router”galactic-router is abstracted behind an MQTT-based
pub-sub queue, where it can receive register and deregister events for workloads. Based on
these events, the galactic-router
builds knowledge of the VPCs and their attached workloads.
From this, it creates the necessary routing instructions for each Kubernetes node and dispatches them accordingly.
It is written in Python to allow for higher-level interaction with the Galactic infrastructure. We believe Python is a better match for this component, as its ecosystem for data processing tasks is very rich. That said, there is no fundamental requirement for it to be written in Python. Any language could connect to the MQTT broker and perform the necessary computations. It is also possible to remove the MQTT abstraction entirely and listen for manifest changes inside the cluster to issue the relevant routing instructions. This side of the system is intentionally kept flexible, as we expect to innovate around how routing is performed.
DeepWiki: https://deepwiki.com/datum-cloud/galactic-router
Galactic Custom Resource Definitions are specified
in the galactic-operator
repository. The repository also contains samples
for all the resources the operator works with.
Example
Section titled “Example”In the following example, we showcase a VPC scenario where we connect workloads across three Datum Points of Presence.
Each of the three workloads directly connects to the VPC within the subnets defined for the VPC using both IPv4 and IPv6.
In addition, the workloads in SJC (San Jose) and AMS (Amsterdam) route their own prefixes across this VPC to each other. This is a scenario often encountered in more complex network setups and is often not supported by other overlay technologies.
For those prefixes to work, the container must set up the relevant interface and addresses inside itself. This is similar to what might be done by something like WireGuard.
If you just want to test the basic function, you can simply set them up manually:
# SJCip link add name test0 type dummyip link set dev test0 upip addr add 192.168.1.1/24 dev test0ip addr add 2001:1::1/64 dev test0
# AMSip link add name test0 type dummyip link set dev test0 upip addr add 192.168.2.1/24 dev test0ip addr add 2001:2::1/64 dev test0
---apiVersion: galactic.datumapis.com/v1alphakind: VPCmetadata: name: my-test-vpcspec: networks: - 10.1.1.0/24 - 2001:10:1:1::/64
---apiVersion: galactic.datumapis.com/v1alphakind: VPCAttachmentmetadata: name: my-test-vpc-sjcspec: vpc: apiVersion: galactic.datumapis.com/v1alpha kind: VPC name: my-test-vpc namespace: default interface: name: galactic0 addresses: - 10.1.1.1/24 - 2001:10:1:1::1/64 routes: - destination: 192.168.1.0/24 via: 10.1.1.1 - destination: 2001:1::/64 via: 2001:10:1:1::1 - destination: 192.168.2.0/24 via: 10.1.1.3 - destination: 2001:2::/64 via: 2001:10:1:1::3
---apiVersion: v1kind: Podmetadata: name: my-test-pod-sjc annotations: k8s.v1alpha.galactic.datumapis.com/vpc-attachment: my-test-vpc-sjcspec: containers: - name: test-container command: ["/bin/ash", "-c", "trap : TERM INT; sleep infinity & wait"] image: alpine securityContext: capabilities: add: - NET_ADMIN nodeSelector: topology.kubernetes.io/region: sjc
---apiVersion: galactic.datumapis.com/v1alphakind: VPCAttachmentmetadata: name: my-test-vpc-iadspec: vpc: apiVersion: galactic.datumapis.com/v1alpha kind: VPC name: my-test-vpc namespace: default interface: name: galactic0 addresses: - 10.1.1.2/24 - 2001:10:1:1::2/64
---apiVersion: v1kind: Podmetadata: name: my-test-pod-iad annotations: k8s.v1alpha.galactic.datumapis.com/vpc-attachment: my-test-vpc-iadspec: containers: - name: test-container command: ["/bin/ash", "-c", "trap : TERM INT; sleep infinity & wait"] image: alpine securityContext: capabilities: add: - NET_ADMIN nodeSelector: topology.kubernetes.io/region: iad
---apiVersion: galactic.datumapis.com/v1alphakind: VPCAttachmentmetadata: name: my-test-vpc-amsspec: vpc: apiVersion: galactic.datumapis.com/v1alpha kind: VPC name: my-test-vpc namespace: default interface: name: galactic0 addresses: - 10.1.1.3/24 - 2001:10:1:1::3/64 routes: - destination: 192.168.2.0/24 via: 10.1.1.3 - destination: 2001:2::/64 via: 2001:10:1:1::3 - destination: 192.168.1.0/24 via: 10.1.1.1 - destination: 2001:1::/64 via: 2001:10:1:1::1
---apiVersion: v1kind: Podmetadata: name: my-test-pod-ams annotations: k8s.v1alpha.galactic.datumapis.com/vpc-attachment: my-test-vpc-amsspec: containers: - name: test-container command: ["/bin/ash", "-c", "trap : TERM INT; sleep infinity & wait"] image: alpine securityContext: capabilities: add: - NET_ADMIN nodeSelector: topology.kubernetes.io/region: ams