Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for configuring the BGP control plane #118

Merged
merged 6 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .cruft.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"template": "https://github.com/projectsyn/commodore-component-template.git",
"commit": "ea12efff947bce80cf31a3f1ed4412eab40e8b33",
"commit": "26ee71e475cca036551c68a6c6b2285fe86139a0",
"checkout": "main",
"context": {
"cookiecutter": {
"name": "Cilium",
"slug": "cilium",
"parameter_key": "cilium",
"test_cases": "defaults helm-opensource olm-opensource egress-gateway",
"test_cases": "defaults helm-opensource olm-opensource egress-gateway bgp-control-plane",
"add_lib": "n",
"add_pp": "n",
"add_golden": "y",
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
- helm-opensource
- olm-opensource
- egress-gateway
- bgp-control-plane
defaults:
run:
working-directory: ${{ env.COMPONENT_NAME }}
Expand All @@ -54,6 +55,7 @@ jobs:
- helm-opensource
- olm-opensource
- egress-gateway
- bgp-control-plane
defaults:
run:
working-directory: ${{ env.COMPONENT_NAME }}
Expand Down
2 changes: 1 addition & 1 deletion Makefile.vars.mk
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ KUBENT_IMAGE ?= ghcr.io/doitintl/kube-no-trouble:latest
KUBENT_DOCKER ?= $(DOCKER_CMD) $(DOCKER_ARGS) $(root_volume) --entrypoint=/app/kubent $(KUBENT_IMAGE)

instance ?= defaults
test_instances = tests/defaults.yml tests/helm-opensource.yml tests/olm-opensource.yml tests/egress-gateway.yml
test_instances = tests/defaults.yml tests/helm-opensource.yml tests/olm-opensource.yml tests/egress-gateway.yml tests/bgp-control-plane.yml
2 changes: 2 additions & 0 deletions class/cilium.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ parameters:
- input_paths:
- ${_base_directory}/component/aggregated-clusterroles.jsonnet
- ${_base_directory}/component/egress-gateway-policies.jsonnet
- ${_base_directory}/component/bgp-control-plane.jsonnet
input_type: jsonnet
output_path: ${_instance}/

Expand All @@ -49,6 +50,7 @@ parameters:
- input_paths:
- ${_base_directory}/component/aggregated-clusterroles.jsonnet
- ${_base_directory}/component/egress-gateway-policies.jsonnet
- ${_base_directory}/component/bgp-control-plane.jsonnet
input_type: jsonnet
output_path: ${_instance}/
- input_paths:
Expand Down
6 changes: 6 additions & 0 deletions class/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ parameters:

cilium_helm_values:
bgpControlPlane:
enabled: ${cilium:bgp:enabled}
secretNamespace:
# Ensure that Cilium's BGP control plane is configured to look for
# peering secrets in the same namespace where Cilium is installed.
Expand Down Expand Up @@ -97,6 +98,11 @@ parameters:
generate_shadow_ranges_configmap: false
egress_ip_ranges: {}

bgp:
enabled: false
peerings: {}
loadbalancer_ip_pools: {}

olm:
source:
opensource: https://github.com/isovalent/olm-for-cilium/archive/main.tar.gz
Expand Down
83 changes: 83 additions & 0 deletions component/bgp-control-plane.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
local com = import 'lib/commodore.libjsonnet';
local kap = import 'lib/kapitan.libjsonnet';
local kube = import 'lib/kube.libjsonnet';

local util = import 'util.libsonnet';

local inv = kap.inventory();
local params = inv.parameters.cilium;

local version = util.parse_version(
if params.install_method == 'helm' then
local chart = if params.release == 'opensource'
then
'cilium'
else
'cilium-enterprise';
params.charts[chart].version
else
params.olm.full_version
);

local CiliumLoadBalancerIPPool(name) =
kube._Object('cilium.io/v2alpha1', 'CiliumLoadBalancerIPPool', name) {
metadata+: {
annotations+: {
'argocd.argoproj.io/sync-options': 'SkipDryRunOnMissingResource=true',
},
},
};

local CiliumBGPPeeringPolicy(name) =
kube._Object('cilium.io/v2alpha1', 'CiliumBGPPeeringPolicy', name) {
metadata+: {
annotations+: {
'argocd.argoproj.io/sync-options': 'SkipDryRunOnMissingResource=true',
},
},
};

local render_peering(name, peering) =
local render_vrouter(config) = config {
neighbors: std.objectValues(std.mapWithKey(
function(peerAddr, n) n {
peerAddress: peerAddr,
},
super.neighbors
)),
};
{
spec: {
nodeSelector: std.get(peering, 'nodeSelector', {}),
virtualRouters: std.map(
render_vrouter,
std.objectValues(peering.virtualRouters)
),
} + com.makeMergeable(std.get(peering, 'spec', {})),
};

local peerings = com.generateResources(
std.mapWithKey(render_peering, params.bgp.peerings),
CiliumBGPPeeringPolicy
);

local render_ip_pool(name, pool) =
{
spec: {
[if version.minor <= 14 then 'cidrs' else 'blocks']:
std.objectValues(pool.blocks),
serviceSelector: std.get(pool, 'serviceSelector', {}),
} + com.makeMergeable(std.get(pool, 'spec', {})),
};

local lb_ip_pools = com.generateResources(
std.mapWithKey(render_ip_pool, params.bgp.loadbalancer_ip_pools),
CiliumLoadBalancerIPPool,
);

{
[if params.bgp.enabled && std.length(peerings) > 0 then
'40_bgp_peerings']: peerings,
[if params.bgp.enabled && std.length(lb_ip_pools) > 0 then
'40_loadbalancer_ip_pools']: lb_ip_pools,
}
20 changes: 2 additions & 18 deletions component/olm.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local inv = kap.inventory();
local params = inv.parameters.cilium;

local helm = import 'render-helm-values.jsonnet';
local util = import 'util.libsonnet';

local olmDir =
local prefix = '%s/olm/cilium/cilium-olm/' % inv.parameters._base_directory;
Expand Down Expand Up @@ -212,24 +213,6 @@ local patchManifests = function(file, has_csv)
else
file;

local olm_version =
local ver = params.olm.full_version;
local verparts = std.split(ver, '.');
local parseOrError(val, typ) =
local parsed = std.parseJson(val);
if std.isNumber(parsed) then
parsed
else
error
'Failed to parse %s version "%s" as number' % [
typ,
val,
];
{
major: parseOrError(verparts[0], 'major'),
minor: parseOrError(verparts[1], 'minor'),
};

local kubeSystemSecretRO = [
kube.Role(metadata_name_map[params.release].OlmRole) {
metadata+: {
Expand Down Expand Up @@ -262,6 +245,7 @@ local kubeSystemSecretRO = [
},
];

local olm_version = util.parse_version(params.olm.full_version);

std.foldl(
function(files, file) files { [std.strReplace(file.filename, '.yaml', '')]: file.contents },
Expand Down
20 changes: 20 additions & 0 deletions component/util.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
local parse_version(ver) =
local verparts = std.split(ver, '.');
local parseOrError(val, typ) =
local parsed = std.parseJson(val);
if std.isNumber(parsed) then
parsed
else
error
'Failed to parse %s version "%s" as number' % [
typ,
val,
];
{
major: parseOrError(verparts[0], 'major'),
minor: parseOrError(verparts[1], 'minor'),
};

{
parse_version: parse_version,
}
65 changes: 65 additions & 0 deletions docs/modules/ROOT/pages/references/parameters.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,71 @@ spec:
<2> The DaemonSet mounts the `eip-shadow-ranges` ConfigMap as a volume.
<3> The DaemonSet is scheduled using the same node selector that's used for the `IsovalentEgressGatewayPolicy` resources

== `bgp`

This section allows users to configure the https://docs.cilium.io/en/stable/network/bgp-control-plane/[Cilium BGP control plane].

=== `bgp.enabled`

[horizontal]
type:: bool
default:: `false`

Whether to enable the BGP control plane feature in Cilium.

=== `bgp.peerings`

[horizontal]
type:: object
default:: `{}`

This parameter allows users to configure `CiliumBGPPeeringPolicy` resources.
This resource is used to configure peers for the BGP control plane.

The component expects the contents of this parameter to be key value pairs where the value is another object with field `virtualRouters` and optional fields `nodeSelector` and `spec`.
The component generates a `CiliumBGPPeeringPolicy` for each entry in the parameter.
The key of the entry is used as the name of the resulting resource.
The values of fields `virtualRouters` and `nodeSelector` are processed and used as the base values for fields `spec.virtualRouters` and `spec.nodeSelector` in the resulting resource.
The value of field `spec` is merged into `spec` of the resource.

Field `virtualRouters` in the parameter entry value is expected to be an object.
The key of each entry in this field is expected to be a peer address (in CIDR notation, such as `192.0.2.2/32`) and the value of each entry is expected to be a valid entry for `spec.virtualRouters`.
The key is written into field `peerAddress` of the value to construct the final entry for `spec.virtualRouters`.

See the https://docs.cilium.io/en/stable/network/bgp-control-plane/#ciliumbgppeeringpolicy-crd[upstream documentation] for the full set of supported fields.

[NOTE]
====
Make sure to check the upstream documentation for the version of Cilium that you're running.
The BGP control plane feature is relatively new and sometimes has significant changes between Cilium minor versions.
====

=== `bgp.loadbalancer_ip_pools`

[horizontal]
type:: object
default:: `{}`

This parameter allows users to configure `CiliumLoadBalancerIPPool` resources.
This resource is used to configure IP pools which Cilium can use to allocate IPs for services with `type=LoadBalancer`.

The component expects the contents of this parametr to be key value pairs where the value is another object with field `blocks`, and optional fields `serviceSelector` and `spec`.
The component generates a `CiliumLoadBalancerIPPool` for each entry in the parameter.
The key of the entry is used as the name of the resulting resource.
The values of fields `blocks` and `serviceSelector` are processed and used as the base values for fields `spec.blocks` (or `spec.cidrs` in Cilium <= 1.14) and `spec.serviceSelector`.
The value of field `spec` is merged into `spec` of the resource.

The component expects field `blocks` to be an object whose values are suitable entries for `spec.blocks` (or `spec.cidrs`) of the resulting resource.
The keys of the object are not used by the component and are only present to allow users to make IP pool configurations more reusable.

See the https://docs.cilium.io/en/stable/network/lb-ipam/[upstream documentation] for the full set of supported fields.

[NOTE]
====
Make sure to check the upstream documentation for the version of Cilium that you're running.
The LoadBalancer IP address management (LB IPAM) feature is under active development and sometimes has significant changes between Cilium minor versions.
====

== Example

[source,yaml]
Expand Down
44 changes: 44 additions & 0 deletions tests/bgp-control-plane.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
parameters:
cilium:
bgp:
enabled: true
peerings:
lb-services:
nodeSelector:
matchLabels:
node-role.kubernetes.io/infra: ''
virtualRouters:
lbs:
localASN: 64512
exportPodCIDR: false
neighbors:
'192.0.2.2/32':
peerASN: 64512
'192.0.2.3/32':
peerASN: 64512
serviceSelector:
matchLabels:
syn.tools/load-balancer-class: cilium
spec:
virtualRouters:
- localASN: 64513
neighbors:
- peerAddress: '192.0.2.100/32'
peerASN: 64513
loadbalancer_ip_pools:
lb-services:
blocks:
tn2:
cidr: 198.51.100.32/27
tn3:
start: 203.0.113.10
stop: 203.0.113.20
serviceSelector:
matchLabels:
syn.tools/load-balancer-class: cilium
lb-services-2:
blocks:
tn3:
cidr: 203.0.113.32/27
spec:
enabled: false
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
annotations: {}
labels:
name: cilium
name: cilium
Loading
Loading