Skip to content

Commit 8309018

Browse files
authored
[improvement] Select subnet for cluster (#677)
* Added NetworkSpec option for subnet name * Added logic to select specific subnet by name * Updated templates to have configurable IP CIDRs * Doc updates for new fields and environment variables
1 parent 1b0fae8 commit 8309018

File tree

13 files changed

+120
-6
lines changed

13 files changed

+120
-6
lines changed

api/v1alpha2/linodecluster_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ type NetworkSpec struct {
174174
// additionalPorts contains list of ports to be configured with NodeBalancer.
175175
// +optional
176176
AdditionalPorts []LinodeNBPortConfig `json:"additionalPorts,omitempty"`
177+
// subnetName is the name/label of the VPC subnet to be used by the cluster
178+
// +optional
179+
SubnetName string `json:"subnetName,omitempty"`
177180

178181
// UseVlan provisions a cluster that uses VLANs instead of VPCs. IPAM is managed internally.
179182
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"

config/crd/bases/infrastructure.cluster.x-k8s.io_linodeclusters.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ spec:
170170
nodeBalancerID:
171171
description: NodeBalancerID is the id of NodeBalancer.
172172
type: integer
173+
subnetName:
174+
description: subnetName is the name/label of the VPC subnet to
175+
be used by the cluster
176+
type: string
173177
useVlan:
174178
description: UseVlan provisions a cluster that uses VLANs instead
175179
of VPCs. IPAM is managed internally.

config/crd/bases/infrastructure.cluster.x-k8s.io_linodeclustertemplates.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ spec:
164164
nodeBalancerID:
165165
description: NodeBalancerID is the id of NodeBalancer.
166166
type: integer
167+
subnetName:
168+
description: subnetName is the name/label of the VPC subnet
169+
to be used by the cluster
170+
type: string
167171
useVlan:
168172
description: UseVlan provisions a cluster that uses VLANs
169173
instead of VPCs. IPAM is managed internally.

docs/src/reference/out.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,7 @@ _Appears in:_
11201120
| `nodeBalancerFirewallID` _integer_ | NodeBalancerFirewallID is the id of NodeBalancer Firewall. | | |
11211121
| `apiserverNodeBalancerConfigID` _integer_ | apiserverNodeBalancerConfigID is the config ID of api server NodeBalancer config. | | |
11221122
| `additionalPorts` _[LinodeNBPortConfig](#linodenbportconfig) array_ | additionalPorts contains list of ports to be configured with NodeBalancer. | | |
1123+
| `subnetName` _string_ | subnetName is the name/label of the VPC subnet to be used by the cluster | | |
11231124
| `useVlan` _boolean_ | UseVlan provisions a cluster that uses VLANs instead of VPCs. IPAM is managed internally. | | |
11241125

11251126

docs/src/topics/vpc.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ spec:
6161
6262
Reference to LinodeVPC object is added to LinodeCluster object which then uses the specified VPC to provision resources.
6363
64+
### Additional Configuration
65+
By default, the VPC will use the subnet with the `default` label for deploying clusters. To modify this behavior, set the `SUBNET_NAME` environment variable to match the label of the subnet to be used. Make sure the subnet is set up in the LinodeVPC manifest.
66+
67+
Additionally, the `VPC_NETWORK_CIDR` and `K8S_CLUSTER_CIDR` environment variables can be used to change which CIDR blocks are used by the VPC and its clusters. `VPC_NETWORK_CIDR` designates the range used by the VPC, while `K8S_CLUSTER_CIDR` designates the range used by clusters for nodes. The `K8S_CLUSTER_CIDR` should be within the `VPC_NETWORK_CIDR`.
68+
6469
## Troubleshooting
6570
### If pod-to-pod connectivity is failing
6671
If a pod can't ping pod ips on different node, check and make sure pod CIDRs are added to ip_ranges of VPC interface.

internal/controller/linodemachine_controller_helpers.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,24 @@ func getVPCInterfaceConfig(ctx context.Context, machineScope *scope.MachineScope
431431
return nil, errors.New("failed to find subnet")
432432
}
433433

434-
subnetID := linodeVPC.Spec.Subnets[0].SubnetID
434+
var subnetID int
435+
436+
subnetName := machineScope.LinodeCluster.Spec.Network.SubnetName // name of subnet to use
437+
438+
if subnetName != "" {
439+
for _, subnet := range linodeVPC.Spec.Subnets {
440+
if subnet.Label == subnetName {
441+
subnetID = subnet.SubnetID
442+
}
443+
}
444+
445+
if subnetID == 0 {
446+
logger.Info("Failed to fetch subnet ID for specified subnet name")
447+
}
448+
} else {
449+
subnetID = linodeVPC.Spec.Subnets[0].SubnetID // get first subnet if nothing specified
450+
}
451+
435452
if subnetID == 0 {
436453
return nil, errors.New("failed to find subnet as subnet id set is 0")
437454
}

internal/controller/linodemachine_controller_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,6 +1985,7 @@ var _ = Describe("machine in VPC", Label("machine", "VPC"), Ordered, func() {
19851985
DNSRootDomain: "lkedevs.net",
19861986
DNSUniqueIdentifier: "abc123",
19871987
DNSTTLSec: 30,
1988+
SubnetName: "test",
19881989
},
19891990
VPCRef: &corev1.ObjectReference{
19901991
Namespace: "default",
@@ -2219,6 +2220,83 @@ var _ = Describe("machine in VPC", Label("machine", "VPC"), Ordered, func() {
22192220
Primary: true,
22202221
}}))
22212222
})
2223+
It("creates an instance with vpc with a specific subnet", func(ctx SpecContext) {
2224+
linodeMachine := infrav1alpha2.LinodeMachine{
2225+
ObjectMeta: metav1.ObjectMeta{
2226+
Name: "mock",
2227+
Namespace: defaultNamespace,
2228+
UID: "12345",
2229+
},
2230+
Spec: infrav1alpha2.LinodeMachineSpec{
2231+
ProviderID: ptr.To("linode://0"),
2232+
Type: "g6-nanode-1",
2233+
Interfaces: []infrav1alpha2.InstanceConfigInterfaceCreateOptions{
2234+
{
2235+
Primary: true,
2236+
},
2237+
},
2238+
},
2239+
Status: infrav1alpha2.LinodeMachineStatus{
2240+
CloudinitMetadataSupport: true,
2241+
},
2242+
}
2243+
mockLinodeClient := mock.NewMockLinodeClient(mockCtrl)
2244+
mockLinodeClient.EXPECT().
2245+
ListVPCs(ctx, gomock.Any()).
2246+
Return([]linodego.VPC{}, nil)
2247+
mockLinodeClient.EXPECT().
2248+
CreateVPC(ctx, gomock.Any()).
2249+
Return(&linodego.VPC{ID: 1, Subnets: []linodego.VPCSubnet{{
2250+
ID: 1,
2251+
Label: "primary",
2252+
IPv4: "192.16.0.0/24",
2253+
},
2254+
{
2255+
ID: 27,
2256+
Label: "test",
2257+
IPv4: "10.0.0.0/24",
2258+
},
2259+
}}, nil)
2260+
helper, err := patch.NewHelper(&linodeVPC, k8sClient)
2261+
Expect(err).NotTo(HaveOccurred())
2262+
2263+
_, err = lvpcReconciler.reconcile(ctx, logger, &scope.VPCScope{
2264+
PatchHelper: helper,
2265+
Client: k8sClient,
2266+
LinodeClient: mockLinodeClient,
2267+
LinodeVPC: &linodeVPC,
2268+
})
2269+
2270+
Expect(err).NotTo(HaveOccurred())
2271+
2272+
mScope := scope.MachineScope{
2273+
Client: k8sClient,
2274+
LinodeClient: mockLinodeClient,
2275+
Cluster: &cluster,
2276+
Machine: &machine,
2277+
LinodeCluster: &linodeCluster,
2278+
LinodeMachine: &linodeMachine,
2279+
}
2280+
2281+
patchHelper, err := patch.NewHelper(mScope.LinodeMachine, k8sClient)
2282+
Expect(err).NotTo(HaveOccurred())
2283+
mScope.PatchHelper = patchHelper
2284+
2285+
createOpts, err := newCreateConfig(ctx, &mScope, gzipCompressionFlag, logger)
2286+
Expect(err).NotTo(HaveOccurred())
2287+
Expect(createOpts).NotTo(BeNil())
2288+
Expect(createOpts.Interfaces).To(Equal([]linodego.InstanceConfigInterfaceCreateOptions{
2289+
{
2290+
Purpose: linodego.InterfacePurposeVPC,
2291+
Primary: true,
2292+
SubnetID: ptr.To(27),
2293+
IPv4: &linodego.VPCIPv4{NAT1To1: ptr.To("any")},
2294+
},
2295+
{
2296+
Primary: true,
2297+
},
2298+
}))
2299+
})
22222300
})
22232301

22242302
var _ = Describe("machine in vlan", Label("machine", "vlan"), Ordered, func() {

templates/addons/ccm-linode/ccm-linode.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ spec:
1717
valuesTemplate: |
1818
routeController:
1919
vpcNames: {{ .InfraCluster.spec.vpcRef.name }}
20-
clusterCIDR: 10.0.0.0/8
20+
clusterCIDR: ${VPC_NETWORK_CIDR:=10.0.0.0/8}
2121
configureCloudRoutes: true
2222
secretRef:
2323
name: "linode-token-region"

templates/addons/cilium/cilium.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ spec:
1919
enabled: true
2020
routingMode: native
2121
kubeProxyReplacement: true
22-
ipv4NativeRoutingCIDR: 10.0.0.0/8
22+
ipv4NativeRoutingCIDR: ${VPC_NETWORK_CIDR:=10.0.0.0/8}
2323
tunnelProtocol: ""
2424
enableIPv4Masquerade: true
2525
policyAuditMode: ${FW_AUDIT_ONLY:=true}

templates/flavors/clusterclass-kubeadm/cluster-template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ spec:
1010
clusterNetwork:
1111
pods:
1212
cidrBlocks:
13-
- 10.192.0.0/10
13+
- ${K8S_CLUSTER_CIDR:=10.192.0.0/10}
1414
topology:
1515
class: kubeadm
1616
version: ${KUBERNETES_VERSION}

0 commit comments

Comments
 (0)