Skip to content

Commit de5099d

Browse files
authored
Add VRF device to support egress gateways (#62)
* Add VRF device support * cluster-template-cilium-load-balancer: metallb based loadbalancer nodes * LoadBalancerNodes: Documentation * load-balancer-nodes: taint and toleration for metallb * cluster-template-cilium-load-balancer: force ipvs/strictARP for metallb
1 parent 8bc8ff9 commit de5099d

16 files changed

+1774
-25
lines changed

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,18 @@ CALICO_VERSION ?= v3.26.3
227227
crs-calico: ## Generates crs manifests for Calico.
228228
curl -o templates/crs/cni/calico.yaml https://raw.githubusercontent.com/projectcalico/calico/$(CALICO_VERSION)/manifests/calico.yaml
229229

230+
METALLB_VERSION ?= 0.14.3
231+
FRR_K8S_DIR = metallb/charts/metallb/charts/frr-k8s/templates
232+
METALLB_TOLERATIONS = [{"key": "node-role.kubernetes.io/load-balancer", "operator": "Exists", "effect": "NoSchedule"}]
233+
.PHONY: crs-metallb
234+
crs-metallb: ## Generates crs manifests for MetalLB.
235+
$(HELM) repo add metallb https://metallb.github.io/metallb
236+
$(HELM) template metallb metallb/metallb --version $(METALLB_VERSION) --set frrk8s.enabled=true,speaker.frr.enabled=false --set-json 'controller.tolerations=$(METALLB_TOLERATIONS)' --set-json 'speaker.tolerations=$(METALLB_TOLERATIONS)' --set-json 'frr-k8s.frrk8s.tolerations=$(METALLB_TOLERATIONS)' --namespace=metallb-system > templates/crs/metallb.yaml
237+
238+
@# fixup namespacing in frr-k8s to work with clusterresourcesets
239+
@sed -e '7bp;48bp;69bp;1682bp;1854bp;1887bp;2253bp;bn' -e ':p i\ namespace: "metallb-system"' -e ':n' -i templates/crs/metallb.yaml
240+
241+
230242
##@ Release
231243
## --------------------------------------
232244
## Release

api/v1alpha1/proxmoxmachine_types.go

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,110 @@ type NetworkSpec struct {
203203
// +listType=map
204204
// +listMapKey=name
205205
AdditionalDevices []AdditionalNetworkDevice `json:"additionalDevices,omitempty"`
206+
207+
// VirtualNetworkDevices defines virtual network devices (e.g. bridges, vlans ...).
208+
VirtualNetworkDevices `json:",inline"`
209+
}
210+
211+
// InterfaceConfig contains all configurables a network interface can have.
212+
type InterfaceConfig struct {
213+
// IPv4PoolRef is a reference to an IPAM Pool resource, which exposes IPv4 addresses.
214+
// The network device will use an available IP address from the referenced pool.
215+
// This can be combined with `IPv6PoolRef` in order to enable dual stack.
216+
// +optional
217+
// +kubebuilder:validation:XValidation:rule="self.apiGroup == 'ipam.cluster.x-k8s.io'",message="ipv4PoolRef allows only IPAM apiGroup ipam.cluster.x-k8s.io"
218+
// +kubebuilder:validation:XValidation:rule="self.kind == 'InClusterIPPool' || self.kind == 'GlobalInClusterIPPool'",message="ipv4PoolRef allows either InClusterIPPool or GlobalInClusterIPPool"
219+
IPv4PoolRef *corev1.TypedLocalObjectReference `json:"ipv4PoolRef,omitempty"`
220+
221+
// IPv6PoolRef is a reference to an IPAM pool resource, which exposes IPv6 addresses.
222+
// The network device will use an available IP address from the referenced pool.
223+
// this can be combined with `IPv4PoolRef` in order to enable dual stack.
224+
// +optional
225+
// +kubebuilder:validation:XValidation:rule="self.apiGroup == 'ipam.cluster.x-k8s.io'",message="ipv6PoolRef allows only IPAM apiGroup ipam.cluster.x-k8s.io"
226+
// +kubebuilder:validation:XValidation:rule="self.kind == 'InClusterIPPool' || self.kind == 'GlobalInClusterIPPool'",message="ipv6PoolRef allows either InClusterIPPool or GlobalInClusterIPPool"
227+
IPv6PoolRef *corev1.TypedLocalObjectReference `json:"ipv6PoolRef,omitempty"`
228+
229+
// DNSServers contains information about nameservers to be used for this interface.
230+
// If this field is not set, it will use the default dns servers from the ProxmoxCluster.
231+
// +optional
232+
// +kubebuilder:validation:MinItems=1
233+
DNSServers []string `json:"dnsServers,omitempty"`
234+
}
235+
236+
// RouteSpec describes an IPv4/IPv6 Route.
237+
type RouteSpec struct {
238+
// To is the subnet to be routed.
239+
// +optional
240+
To string `json:"to,omitempty"`
241+
// Via is the gateway to the subnet.
242+
// +optional
243+
Via string `json:"via,omitempty"`
244+
// Metric is the priority of the route in the routing table.
245+
// +optional
246+
Metric uint32 `json:"metric,omitempty"`
247+
// Table is the routing table used for this route.
248+
// +optional
249+
Table uint32 `json:"table,omitempty"`
250+
}
251+
252+
// RoutingPolicySpec is a linux FIB rule.
253+
type RoutingPolicySpec struct {
254+
// To is the subnet of the target.
255+
// +optional
256+
To string `json:"to,omitempty"`
257+
258+
// From is the subnet of the source.
259+
// +optional
260+
From string `json:"from,omitempty"`
261+
262+
// Table is the routing table id.
263+
// +optional
264+
Table uint32 `json:"table,omitempty"`
265+
266+
// Priority is the position in the ip rule fib table.
267+
// +kubebuilder:validation:Maximum=4294967295
268+
// +kubebuilder:validation:XValidation:message="Cowardly refusing to insert fib rule matching kernel rules",rule="(self > 0 && self < 32765) || (self > 32766)"
269+
// +optional
270+
Priority uint32 `json:"priority,omitempty"`
271+
}
272+
273+
// VRFDevice defines Virtual Routing Flow devices.
274+
type VRFDevice struct {
275+
// Interfaces is the list of proxmox network devices managed by this virtual device.
276+
Interfaces []string `json:"interfaces,omitempty"`
277+
278+
// Name is the virtual network device name.
279+
// must be unique within the virtual machine.
280+
// +kubebuilder:validation:MinLength=3
281+
Name string `json:"name"`
282+
283+
// Table is the ID of the routing table used for the l3mdev vrf device.
284+
// +kubebuilder:validation:Maximum=4294967295
285+
// +kubebuilder:validation:XValidation:message="Cowardly refusing to insert l3mdev rules into kernel tables",rule="(self > 0 && self < 254) || (self > 255)"
286+
Table uint32 `json:"table"`
287+
288+
// InterfaceConfig contains all configurables a network interface can have.
289+
// +optional
290+
InterfaceConfig `json:",inline"`
291+
292+
// Routes are the routes associated with the l3mdev policy.
293+
// +optional
294+
// +kubebuilder:validation:MinItems=1
295+
Routes []RouteSpec `json:"routes,omitempty"`
296+
297+
// RoutingPolicy is the l3mdev policy inserted into FiB.
298+
// +optional
299+
// +kubebuilder:validation:MinItems=1
300+
RoutingPolicy []RoutingPolicySpec `json:"routingPolicy,omitempty"`
301+
}
302+
303+
// VirtualNetworkDevices defines linux software networking devices.
304+
type VirtualNetworkDevices struct {
305+
// Definition of a Vrf Device.
306+
// +optional
307+
// +listType=map
308+
// +listMapKey=name
309+
VRFs []VRFDevice `json:"vrfs,omitempty"`
206310
}
207311

208312
// NetworkDevice defines the required details of a virtual machine network device.
@@ -262,7 +366,7 @@ type AdditionalNetworkDevice struct {
262366

263367
// ProxmoxMachineStatus defines the observed state of ProxmoxMachine.
264368
type ProxmoxMachineStatus struct {
265-
// Ready indicates the Docker infrastructure has been provisioned and is ready
369+
// Ready indicates the Docker infrastructure has been provisioned and is ready.
266370
// +optional
267371
Ready bool `json:"ready"`
268372

@@ -282,13 +386,13 @@ type ProxmoxMachineStatus struct {
282386
// +optional
283387
IPAddresses map[string]IPAddress `json:"ipAddresses,omitempty"`
284388

285-
// Network returns the network status for each of the machine's configured
389+
// Network returns the network status for each of the machine's configured.
286390
// network interfaces.
287391
// +optional
288392
Network []NetworkStatus `json:"network,omitempty"`
289393

290394
// ProxmoxNode is the name of the proxmox node, which was chosen for this
291-
// machine to be deployed on
395+
// machine to be deployed on.
292396
// +optional
293397
ProxmoxNode *string `json:"proxmoxNode,omitempty"`
294398

@@ -298,7 +402,7 @@ type ProxmoxMachineStatus struct {
298402
// +optional
299403
TaskRef *string `json:"taskRef,omitempty"`
300404

301-
// RetryAfter tracks the time we can retry queueing a task
405+
// RetryAfter tracks the time we can retry queueing a task.
302406
// +optional
303407
RetryAfter metav1.Time `json:"retryAfter,omitempty"`
304408

api/v1alpha1/proxmoxmachine_types_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,5 +224,36 @@ var _ = Describe("ProxmoxMachine Test", func() {
224224

225225
Expect(k8sClient.Create(context.Background(), dm)).Should(MatchError(ContainSubstring("should be less than or equal to 65520")))
226226
})
227+
228+
It("Should only allow VRFS with a non kernel routing table ", func() {
229+
dm := defaultMachine()
230+
dm.Spec.Network = &NetworkSpec{
231+
VirtualNetworkDevices: VirtualNetworkDevices{
232+
VRFs: []VRFDevice{{
233+
Name: "vrf-blue",
234+
Table: 254,
235+
}},
236+
},
237+
}
238+
239+
Expect(k8sClient.Create(context.Background(), dm)).Should(MatchError(ContainSubstring("Cowardly refusing to insert l3mdev rules into kernel tables")))
240+
})
241+
242+
It("Should only allow non kernel FIB rule priority", func() {
243+
dm := defaultMachine()
244+
dm.Spec.Network = &NetworkSpec{
245+
VirtualNetworkDevices: VirtualNetworkDevices{
246+
VRFs: []VRFDevice{{
247+
Name: "vrf-blue",
248+
Table: 100,
249+
RoutingPolicy: []RoutingPolicySpec{{
250+
Priority: 32766,
251+
}},
252+
}},
253+
},
254+
}
255+
256+
Expect(k8sClient.Create(context.Background(), dm)).Should(MatchError(ContainSubstring("Cowardly refusing to insert fib rule matching kernel rules")))
257+
})
227258
})
228259
})

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 114 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)