From 3ac958a094ddea8d7c2f0b3c239319a94f55b84c Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Fri, 1 Mar 2024 19:37:49 +0000 Subject: [PATCH 01/10] add vpc support for capl clusters --- .../linodemachine_controller_helpers.go | 8 +++++++ templates/addons/cilium/cilium.yaml | 9 +++++++ templates/flavors/base/kustomization.yaml | 1 + templates/flavors/base/linodeCluster.yaml | 4 ++++ templates/flavors/base/linodeVPC.yaml | 10 ++++++++ templates/flavors/rke2/rke2ControlPlane.yaml | 24 +++++++++++++++++++ 6 files changed, 56 insertions(+) create mode 100644 templates/flavors/base/linodeVPC.yaml diff --git a/controller/linodemachine_controller_helpers.go b/controller/linodemachine_controller_helpers.go index 96d9fe41d..61a6d7fb2 100644 --- a/controller/linodemachine_controller_helpers.go +++ b/controller/linodemachine_controller_helpers.go @@ -88,6 +88,14 @@ func (r *LinodeMachineReconciler) newCreateConfig(ctx context.Context, machineSc createConfig.RootPass = uuid.NewString() } + // add public interface to linode (eth0) + iface := &linodego.InstanceConfigInterfaceCreateOptions{ + Purpose: linodego.InterfacePurposePublic, + Primary: true, + } + createConfig.Interfaces = append(createConfig.Interfaces, *iface) + + // if vpc, attach additional interface to linode (eth1) if machineScope.LinodeCluster.Spec.VPCRef != nil { iface, err := r.getVPCInterfaceConfig(ctx, machineScope, createConfig.Interfaces, logger) if err != nil { diff --git a/templates/addons/cilium/cilium.yaml b/templates/addons/cilium/cilium.yaml index 4fd2280bf..7940b8da0 100644 --- a/templates/addons/cilium/cilium.yaml +++ b/templates/addons/cilium/cilium.yaml @@ -18,8 +18,17 @@ spec: valuesTemplate: | bgpControlPlane: enabled: true + routingMode: native + kubeProxyReplacement: true + ipv4NativeRoutingCIDR: 10.0.0.0/8 + tunnelProtocol: "" + enableIPv4Masquerade: true ipam: mode: kubernetes + ipv4: + enabled: true + ipv6: + enabled: false k8s: requireIPv4PodCIDR: true hubble: diff --git a/templates/flavors/base/kustomization.yaml b/templates/flavors/base/kustomization.yaml index 7f70ef2b5..257e0bd01 100644 --- a/templates/flavors/base/kustomization.yaml +++ b/templates/flavors/base/kustomization.yaml @@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - cluster.yaml + - linodeVPC.yaml - linodeCluster.yaml - linodeMachineTemplate.yaml - machineDeployment.yaml diff --git a/templates/flavors/base/linodeCluster.yaml b/templates/flavors/base/linodeCluster.yaml index 3f5956877..d4cb85701 100644 --- a/templates/flavors/base/linodeCluster.yaml +++ b/templates/flavors/base/linodeCluster.yaml @@ -7,3 +7,7 @@ spec: region: ${LINODE_REGION} credentialsRef: name: ${CLUSTER_NAME}-credentials + vpcRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 + kind: LinodeVPC + name: vpc-${CLUSTER_NAME} diff --git a/templates/flavors/base/linodeVPC.yaml b/templates/flavors/base/linodeVPC.yaml new file mode 100644 index 000000000..515e5a176 --- /dev/null +++ b/templates/flavors/base/linodeVPC.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 +kind: LinodeVPC +metadata: + name: vpc-${CLUSTER_NAME} +spec: + region: ${LINODE_REGION} + subnets: + - ipv4: 10.0.0.0/8 + label: default \ No newline at end of file diff --git a/templates/flavors/rke2/rke2ControlPlane.yaml b/templates/flavors/rke2/rke2ControlPlane.yaml index 6aa6261ef..726fc4579 100644 --- a/templates/flavors/rke2/rke2ControlPlane.yaml +++ b/templates/flavors/rke2/rke2ControlPlane.yaml @@ -21,6 +21,30 @@ spec: name: linode-${CLUSTER_NAME}-crs-0 owner: root:root path: /var/lib/rancher/rke2/server/manifests/linode-token-region.yaml + - path: /var/lib/rancher/rke2/server/manifests/rke2-cilium-config.yaml + owner: root:root + permissions: "0640" + content: | + apiVersion: helm.cattle.io/v1 + kind: HelmChartConfig + metadata: + name: rke2-cilium + namespace: kube-system + spec: + valuesContent: |- + routingMode: native + kubeProxyReplacement: true + ipv4NativeRoutingCIDR: 10.0.0.0/8 + tunnelProtocol: "" + enableIPv4Masquerade: true + ipam: + mode: kubernetes + ipv4: + enabled: true + ipv6: + enabled: false + k8s: + requireIPv4PodCIDR: true registrationMethod: internal-only-ips serverConfig: cni: cilium From e751529811f5b00763ec5970a417199c2f0b4097 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 11 Mar 2024 15:09:07 +0000 Subject: [PATCH 02/10] disable kube-proxy, address review comments --- controller/linodemachine_controller.go | 12 +++- .../linodemachine_controller_helpers.go | 57 ++++++++++++++++--- templates/addons/cilium/cilium.yaml | 10 ++++ .../addons/provider-linode/linode-ccm.yaml | 5 ++ templates/flavors/base/linodeCluster.yaml | 2 +- .../flavors/base/linodeMachineTemplate.yaml | 4 +- templates/flavors/base/linodeVPC.yaml | 4 +- .../flavors/default/kubeadmControlPlane.yaml | 2 + templates/flavors/k3s/k3sConfigTemplate.yaml | 2 +- templates/flavors/k3s/k3sControlPlane.yaml | 32 ++++++++++- templates/flavors/rke2/kustomization.yaml | 12 ++++ .../flavors/rke2/rke2ConfigTemplate.yaml | 6 +- templates/flavors/rke2/rke2ControlPlane.yaml | 29 +--------- 13 files changed, 133 insertions(+), 44 deletions(-) diff --git a/controller/linodemachine_controller.go b/controller/linodemachine_controller.go index 149828b3d..2f5cd978f 100644 --- a/controller/linodemachine_controller.go +++ b/controller/linodemachine_controller.go @@ -83,6 +83,11 @@ var requeueInstanceStatuses = map[linodego.InstanceStatus]bool{ linodego.InstanceResizing: true, } +type nodeIP struct { + ip string + ipType clusterv1.MachineAddressType +} + // LinodeMachineReconciler reconciles a LinodeMachine object type LinodeMachineReconciler struct { client.Client @@ -359,7 +364,12 @@ func (r *LinodeMachineReconciler) reconcileCreate( } machineScope.LinodeMachine.Spec.ProviderID = util.Pointer(fmt.Sprintf("linode://%d", linodeInstance.ID)) - machineScope.LinodeMachine.Status.Addresses = buildInstanceAddrs(linodeInstance) + + addrs, err := r.buildInstanceAddrs(ctx, logger, machineScope, linodeInstance.ID) + if err != nil { + return linodeInstance, err + } + machineScope.LinodeMachine.Status.Addresses = addrs // Set the instance state to signal preflight process is done machineScope.LinodeMachine.Status.InstanceState = util.Pointer(linodego.InstanceOffline) diff --git a/controller/linodemachine_controller_helpers.go b/controller/linodemachine_controller_helpers.go index 61a6d7fb2..81aa12eae 100644 --- a/controller/linodemachine_controller_helpers.go +++ b/controller/linodemachine_controller_helpers.go @@ -109,20 +109,59 @@ func (r *LinodeMachineReconciler) newCreateConfig(ctx context.Context, machineSc return createConfig, nil } -func buildInstanceAddrs(linodeInstance *linodego.Instance) []clusterv1.MachineAddress { +func (r *LinodeMachineReconciler) buildInstanceAddrs(ctx context.Context, logger logr.Logger, machineScope *scope.MachineScope, instanceID int) ([]clusterv1.MachineAddress, error) { addrs := []clusterv1.MachineAddress{} - for _, addr := range linodeInstance.IPv4 { - addrType := clusterv1.MachineExternalIP - if addr.IsPrivate() { - addrType = clusterv1.MachineInternalIP - } + ips, err := r.getInstanceIPv4Addresses(ctx, logger, machineScope, instanceID) + if err != nil { + logger.Error(err, "Failed to get instance ip addresses") + return nil, err + } + + // add all instance ips to machine's status + for _, ip := range ips { addrs = append(addrs, clusterv1.MachineAddress{ - Type: addrType, - Address: addr.String(), + Type: ip.ipType, + Address: ip.ip, }) } - return addrs + return addrs, nil +} + +func (r *LinodeMachineReconciler) getInstanceIPv4Addresses(ctx context.Context, logger logr.Logger, machineScope *scope.MachineScope, instanceID int) ([]nodeIP, error) { + addresses, err := machineScope.LinodeClient.GetInstanceIPAddresses(ctx, instanceID) + if err != nil { + return nil, err + } + + // get the default instance config + configs, err := machineScope.LinodeClient.ListInstanceConfigs(ctx, instanceID, &linodego.ListOptions{}) + if err != nil || len(configs) == 0 { + logger.Error(err, "Failed to list instance configs") + return nil, err + } + + ips := []nodeIP{} + // check if a node has public ip and store it + if len(addresses.IPv4.Public) != 0 { + ips = append(ips, nodeIP{ip: addresses.IPv4.Public[0].Address, ipType: clusterv1.MachineExternalIP}) + } + + // Iterate over interfaces in config and find VPC specific ips + for _, iface := range configs[0].Interfaces { + if iface.VPCID != nil && iface.IPv4.VPC != "" { + ips = append(ips, nodeIP{ip: iface.IPv4.VPC, ipType: clusterv1.MachineInternalIP}) + } + } + + // if a node has private ip, store it as well + // NOTE: We specifically store VPC ips first so that they are used first during + // bootstrap when we set `registrationMethod: internal-only-ips` + if len(addresses.IPv4.Private) != 0 { + ips = append(ips, nodeIP{ip: addresses.IPv4.Private[0].Address, ipType: clusterv1.MachineInternalIP}) + } + + return ips, nil } func (r *LinodeMachineReconciler) getOwnerMachine(ctx context.Context, linodeMachine infrav1alpha1.LinodeMachine, log logr.Logger) (*clusterv1.Machine, error) { diff --git a/templates/addons/cilium/cilium.yaml b/templates/addons/cilium/cilium.yaml index 7940b8da0..509089ffd 100644 --- a/templates/addons/cilium/cilium.yaml +++ b/templates/addons/cilium/cilium.yaml @@ -23,6 +23,12 @@ spec: ipv4NativeRoutingCIDR: 10.0.0.0/8 tunnelProtocol: "" enableIPv4Masquerade: true + egressMasqueradeInterfaces: eth0 + k8sServiceHost: {{ .InfraCluster.spec.controlPlaneEndpoint.host }} + k8sServicePort: {{ .InfraCluster.spec.controlPlaneEndpoint.port }} + extraArgs: + - --direct-routing-device=eth1 + - --nodeport-addresses=0.0.0.0/0 ipam: mode: kubernetes ipv4: @@ -36,3 +42,7 @@ spec: enabled: true ui: enabled: true +# ipMasqAgent: +# enabled: true +# bpf: +# masquerade: true diff --git a/templates/addons/provider-linode/linode-ccm.yaml b/templates/addons/provider-linode/linode-ccm.yaml index dd2839fa4..5e4715390 100644 --- a/templates/addons/provider-linode/linode-ccm.yaml +++ b/templates/addons/provider-linode/linode-ccm.yaml @@ -15,6 +15,11 @@ spec: wait: true timeout: 5m valuesTemplate: | + routeController: + vpcName: ${VPC_NAME:=${CLUSTER_NAME}} + linodeNodePrivateSubnet: 10.0.0.0/8 + configureCloudRoutes: true + routeReconciliationPeriod: 1m secretRef: name: "linode-token-region" image: diff --git a/templates/flavors/base/linodeCluster.yaml b/templates/flavors/base/linodeCluster.yaml index d4cb85701..565a89ff3 100644 --- a/templates/flavors/base/linodeCluster.yaml +++ b/templates/flavors/base/linodeCluster.yaml @@ -10,4 +10,4 @@ spec: vpcRef: apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 kind: LinodeVPC - name: vpc-${CLUSTER_NAME} + name: ${VPC_NAME:=${CLUSTER_NAME}} diff --git a/templates/flavors/base/linodeMachineTemplate.yaml b/templates/flavors/base/linodeMachineTemplate.yaml index b2ee8f19d..81731faca 100644 --- a/templates/flavors/base/linodeMachineTemplate.yaml +++ b/templates/flavors/base/linodeMachineTemplate.yaml @@ -11,7 +11,7 @@ spec: region: ${LINODE_REGION} authorizedKeys: # uncomment to include your ssh key in linode provisioning - # - ${LINODE_SSH_PUBKEY:=""} + - ${LINODE_SSH_PUBKEY:=""} --- apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 kind: LinodeMachineTemplate @@ -25,4 +25,4 @@ spec: region: ${LINODE_REGION} authorizedKeys: # uncomment to include your ssh key in linode provisioning - # - ${LINODE_SSH_PUBKEY:=""} + - ${LINODE_SSH_PUBKEY:=""} diff --git a/templates/flavors/base/linodeVPC.yaml b/templates/flavors/base/linodeVPC.yaml index 515e5a176..4ed39878c 100644 --- a/templates/flavors/base/linodeVPC.yaml +++ b/templates/flavors/base/linodeVPC.yaml @@ -2,9 +2,9 @@ apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 kind: LinodeVPC metadata: - name: vpc-${CLUSTER_NAME} + name: ${VPC_NAME:=${CLUSTER_NAME}} spec: region: ${LINODE_REGION} subnets: - ipv4: 10.0.0.0/8 - label: default \ No newline at end of file + label: default diff --git a/templates/flavors/default/kubeadmControlPlane.yaml b/templates/flavors/default/kubeadmControlPlane.yaml index 62db33029..72089e5e2 100644 --- a/templates/flavors/default/kubeadmControlPlane.yaml +++ b/templates/flavors/default/kubeadmControlPlane.yaml @@ -51,6 +51,8 @@ spec: extraArgs: cloud-provider: external initConfiguration: + skipPhases: + - addon/kube-proxy nodeRegistration: kubeletExtraArgs: cloud-provider: external diff --git a/templates/flavors/k3s/k3sConfigTemplate.yaml b/templates/flavors/k3s/k3sConfigTemplate.yaml index a3e8570c2..bbafe3fed 100644 --- a/templates/flavors/k3s/k3sConfigTemplate.yaml +++ b/templates/flavors/k3s/k3sConfigTemplate.yaml @@ -11,7 +11,7 @@ spec: preK3sCommands: - | mkdir -p /etc/rancher/k3s/config.yaml.d/ - echo "node-ip: $(hostname -I | grep -oE 192\.168\.[0-9]+\.[0-9]+)" >> /etc/rancher/k3s/config.yaml.d/capi-config.yaml + echo "node-ip: $(ip a s eth1 |grep 'inet ' |cut -d' ' -f6|cut -d/ -f1)" >> /etc/rancher/k3s/config.yaml.d/capi-config.yaml - sed -i '/swap/d' /etc/fstab - swapoff -a - hostnamectl set-hostname '{{ ds.meta_data.label }}' && hostname -F /etc/hostname diff --git a/templates/flavors/k3s/k3sControlPlane.yaml b/templates/flavors/k3s/k3sControlPlane.yaml index 3600642bc..d83059183 100644 --- a/templates/flavors/k3s/k3sControlPlane.yaml +++ b/templates/flavors/k3s/k3sControlPlane.yaml @@ -33,6 +33,36 @@ spec: name: linode-${CLUSTER_NAME}-crs-0 owner: root:root path: /var/lib/rancher/k3s/server/manifests/linode-token-region.yaml + - path: /var/lib/rancher/k3s/server/manifests/k3s-cilium-config.yaml + owner: root:root + permissions: "0640" + content: | + apiVersion: helm.cattle.io/v1 + kind: HelmChartConfig + metadata: + name: cilium + namespace: kube-system + spec: + valuesContent: |- + routingMode: native + kubeProxyReplacement: true + ipv4NativeRoutingCIDR: 10.0.0.0/8 + tunnelProtocol: "" + enableIPv4Masquerade: true + egressMasqueradeInterfaces: eth0 + k8sServiceHost: 10.0.0.2 + k8sServicePort: 6443 + extraArgs: + - --direct-routing-device=eth1 + - --nodeport-addresses=0.0.0.0/0 + ipam: + mode: kubernetes + ipv4: + enabled: true + ipv6: + enabled: false + k8s: + requireIPv4PodCIDR: true serverConfig: disableComponents: - servicelb @@ -41,7 +71,7 @@ spec: nodeName: '{{ ds.meta_data.label }}' preK3sCommands: - | - echo "node-ip: $(hostname -I | grep -oE 192\.168\.[0-9]+\.[0-9]+)" >> /etc/rancher/k3s/config.yaml.d/capi-config.yaml + echo "node-ip: $(ip a s eth1 |grep 'inet ' |cut -d' ' -f6|cut -d/ -f1)" >> /etc/rancher/k3s/config.yaml.d/capi-config.yaml - sed -i '/swap/d' /etc/fstab - swapoff -a - hostnamectl set-hostname '{{ ds.meta_data.label }}' && hostname -F /etc/hostname diff --git a/templates/flavors/rke2/kustomization.yaml b/templates/flavors/rke2/kustomization.yaml index fdfed62da..2cc4242da 100644 --- a/templates/flavors/rke2/kustomization.yaml +++ b/templates/flavors/rke2/kustomization.yaml @@ -5,6 +5,7 @@ resources: - rke2ControlPlane.yaml - rke2ConfigTemplate.yaml - secret.yaml + - ../../addons/cilium patches: - target: group: cluster.x-k8s.io @@ -14,6 +15,17 @@ patches: - op: replace path: /spec/controlPlaneRef/kind value: RKE2ControlPlane + - target: + group: cluster.x-k8s.io + version: v1beta1 + kind: Cluster + patch: |- + apiVersion: cluster.x-k8s.io/v1beta1 + kind: Cluster + metadata: + name: ${CLUSTER_NAME} + labels: + cni: cilium - target: group: cluster.x-k8s.io version: v1beta1 diff --git a/templates/flavors/rke2/rke2ConfigTemplate.yaml b/templates/flavors/rke2/rke2ConfigTemplate.yaml index 3c459fd90..b532b5adb 100644 --- a/templates/flavors/rke2/rke2ConfigTemplate.yaml +++ b/templates/flavors/rke2/rke2ConfigTemplate.yaml @@ -12,10 +12,14 @@ spec: cisProfile: ${CIS_PROFILE:-"cis-1.23"} protectKernelDefaults: true # TODO: use MDS to get public and private IP instead because hostname ordering can't always be assumed + kubelet: + extraArgs: + - "provider-id=linode://{{ ds.meta_data.id }}" + # TODO: use MDS to get private IP instead preRKE2Commands: - | mkdir -p /etc/rancher/rke2/config.yaml.d/ - echo "node-ip: $(hostname -I | grep -oE 192\.168\.[0-9]+\.[0-9]+)" >> /etc/rancher/rke2/config.yaml.d/capi-config.yaml + echo "node-ip: $(ip a s eth1 |grep 'inet ' |cut -d' ' -f6|cut -d/ -f1)" >> /etc/rancher/rke2/config.yaml.d/capi-config.yaml - sed -i '/swap/d' /etc/fstab - swapoff -a - hostnamectl set-hostname '{{ ds.meta_data.label }}' && hostname -F /etc/hostname diff --git a/templates/flavors/rke2/rke2ControlPlane.yaml b/templates/flavors/rke2/rke2ControlPlane.yaml index 726fc4579..d474f0912 100644 --- a/templates/flavors/rke2/rke2ControlPlane.yaml +++ b/templates/flavors/rke2/rke2ControlPlane.yaml @@ -21,39 +21,16 @@ spec: name: linode-${CLUSTER_NAME}-crs-0 owner: root:root path: /var/lib/rancher/rke2/server/manifests/linode-token-region.yaml - - path: /var/lib/rancher/rke2/server/manifests/rke2-cilium-config.yaml - owner: root:root - permissions: "0640" - content: | - apiVersion: helm.cattle.io/v1 - kind: HelmChartConfig - metadata: - name: rke2-cilium - namespace: kube-system - spec: - valuesContent: |- - routingMode: native - kubeProxyReplacement: true - ipv4NativeRoutingCIDR: 10.0.0.0/8 - tunnelProtocol: "" - enableIPv4Masquerade: true - ipam: - mode: kubernetes - ipv4: - enabled: true - ipv6: - enabled: false - k8s: - requireIPv4PodCIDR: true registrationMethod: internal-only-ips serverConfig: - cni: cilium + cni: none cloudProviderName: external disableComponents: pluginComponents: - "rke2-ingress-nginx" kubernetesComponents: - "cloudController" + - "kubeProxy" agentConfig: version: ${KUBERNETES_VERSION} nodeName: '{{ ds.meta_data.label }}' @@ -62,7 +39,7 @@ spec: preRKE2Commands: - | mkdir -p /etc/rancher/rke2/config.yaml.d/ - echo "node-ip: $(hostname -I | grep -oE 192\.168\.[0-9]+\.[0-9]+)" >> /etc/rancher/rke2/config.yaml.d/capi-config.yaml + echo "node-ip: $(ip a s eth1 |grep 'inet ' |cut -d' ' -f6|cut -d/ -f1)" >> /etc/rancher/rke2/config.yaml.d/capi-config.yaml - sed -i '/swap/d' /etc/fstab - swapoff -a - hostnamectl set-hostname '{{ ds.meta_data.label }}' && hostname -F /etc/hostname From 8a669513d8afad350abf2ea5bd9301cbb6aaf22c Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Thu, 14 Mar 2024 21:09:55 +0000 Subject: [PATCH 03/10] use updated version of linode-ccm --- templates/addons/provider-linode/linode-ccm.yaml | 5 ++--- templates/flavors/base/linodeMachineTemplate.yaml | 4 ++-- templates/flavors/k3s/secret.yaml | 6 +++++- templates/flavors/rke2/secret.yaml | 6 +++++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/templates/addons/provider-linode/linode-ccm.yaml b/templates/addons/provider-linode/linode-ccm.yaml index 5e4715390..8849f0b53 100644 --- a/templates/addons/provider-linode/linode-ccm.yaml +++ b/templates/addons/provider-linode/linode-ccm.yaml @@ -9,7 +9,7 @@ spec: repoURL: https://linode.github.io/linode-cloud-controller-manager/ chartName: ccm-linode namespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.3.24} + version: ${LINODE_CCM_VERSION:=v0.4.1} options: waitForJobs: true wait: true @@ -17,9 +17,8 @@ spec: valuesTemplate: | routeController: vpcName: ${VPC_NAME:=${CLUSTER_NAME}} - linodeNodePrivateSubnet: 10.0.0.0/8 + clusterCIDR: 10.0.0.0/8 configureCloudRoutes: true - routeReconciliationPeriod: 1m secretRef: name: "linode-token-region" image: diff --git a/templates/flavors/base/linodeMachineTemplate.yaml b/templates/flavors/base/linodeMachineTemplate.yaml index 81731faca..b2ee8f19d 100644 --- a/templates/flavors/base/linodeMachineTemplate.yaml +++ b/templates/flavors/base/linodeMachineTemplate.yaml @@ -11,7 +11,7 @@ spec: region: ${LINODE_REGION} authorizedKeys: # uncomment to include your ssh key in linode provisioning - - ${LINODE_SSH_PUBKEY:=""} + # - ${LINODE_SSH_PUBKEY:=""} --- apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 kind: LinodeMachineTemplate @@ -25,4 +25,4 @@ spec: region: ${LINODE_REGION} authorizedKeys: # uncomment to include your ssh key in linode provisioning - - ${LINODE_SSH_PUBKEY:=""} + # - ${LINODE_SSH_PUBKEY:=""} diff --git a/templates/flavors/k3s/secret.yaml b/templates/flavors/k3s/secret.yaml index d6f8f02b4..47ff1bd25 100644 --- a/templates/flavors/k3s/secret.yaml +++ b/templates/flavors/k3s/secret.yaml @@ -39,11 +39,15 @@ stringData: name: ccm-linode spec: targetNamespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.3.24} + version: ${LINODE_CCM_VERSION:=v0.4.1} chart: ccm-linode repo: https://linode.github.io/linode-cloud-controller-manager/ bootstrap: true valuesContent: |- + routeController: + vpcName: ${VPC_NAME:=${CLUSTER_NAME}} + clusterCIDR: 10.0.0.0/8 + configureCloudRoutes: true secretRef: name: "linode-token-region" nodeSelector: diff --git a/templates/flavors/rke2/secret.yaml b/templates/flavors/rke2/secret.yaml index d50cde02c..fc40a421f 100644 --- a/templates/flavors/rke2/secret.yaml +++ b/templates/flavors/rke2/secret.yaml @@ -21,11 +21,15 @@ stringData: name: ccm-linode spec: targetNamespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.3.24} + version: ${LINODE_CCM_VERSION:=v0.4.1} chart: ccm-linode repo: https://linode.github.io/linode-cloud-controller-manager/ bootstrap: true valuesContent: |- + routeController: + vpcName: ${VPC_NAME:=${CLUSTER_NAME}} + clusterCIDR: 10.0.0.0/8 + configureCloudRoutes: true secretRef: name: "linode-token-region" nodeSelector: From b716b20b25889bc701d52940c6e1be9cfbec5184 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Tue, 19 Mar 2024 21:25:55 +0000 Subject: [PATCH 04/10] address review comments --- controller/linodemachine_controller.go | 7 +--- .../linodemachine_controller_helpers.go | 38 +++++-------------- 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/controller/linodemachine_controller.go b/controller/linodemachine_controller.go index 2f5cd978f..d4b6e82eb 100644 --- a/controller/linodemachine_controller.go +++ b/controller/linodemachine_controller.go @@ -83,11 +83,6 @@ var requeueInstanceStatuses = map[linodego.InstanceStatus]bool{ linodego.InstanceResizing: true, } -type nodeIP struct { - ip string - ipType clusterv1.MachineAddressType -} - // LinodeMachineReconciler reconciles a LinodeMachine object type LinodeMachineReconciler struct { client.Client @@ -365,7 +360,7 @@ func (r *LinodeMachineReconciler) reconcileCreate( machineScope.LinodeMachine.Spec.ProviderID = util.Pointer(fmt.Sprintf("linode://%d", linodeInstance.ID)) - addrs, err := r.buildInstanceAddrs(ctx, logger, machineScope, linodeInstance.ID) + addrs, err := r.buildInstanceAddrs(ctx, machineScope, linodeInstance.ID) if err != nil { return linodeInstance, err } diff --git a/controller/linodemachine_controller_helpers.go b/controller/linodemachine_controller_helpers.go index 81aa12eae..8c3a052cf 100644 --- a/controller/linodemachine_controller_helpers.go +++ b/controller/linodemachine_controller_helpers.go @@ -89,11 +89,11 @@ func (r *LinodeMachineReconciler) newCreateConfig(ctx context.Context, machineSc } // add public interface to linode (eth0) - iface := &linodego.InstanceConfigInterfaceCreateOptions{ + iface := linodego.InstanceConfigInterfaceCreateOptions{ Purpose: linodego.InterfacePurposePublic, Primary: true, } - createConfig.Interfaces = append(createConfig.Interfaces, *iface) + createConfig.Interfaces = append(createConfig.Interfaces, iface) // if vpc, attach additional interface to linode (eth1) if machineScope.LinodeCluster.Spec.VPCRef != nil { @@ -109,48 +109,28 @@ func (r *LinodeMachineReconciler) newCreateConfig(ctx context.Context, machineSc return createConfig, nil } -func (r *LinodeMachineReconciler) buildInstanceAddrs(ctx context.Context, logger logr.Logger, machineScope *scope.MachineScope, instanceID int) ([]clusterv1.MachineAddress, error) { - addrs := []clusterv1.MachineAddress{} - ips, err := r.getInstanceIPv4Addresses(ctx, logger, machineScope, instanceID) - if err != nil { - logger.Error(err, "Failed to get instance ip addresses") - return nil, err - } - - // add all instance ips to machine's status - for _, ip := range ips { - addrs = append(addrs, clusterv1.MachineAddress{ - Type: ip.ipType, - Address: ip.ip, - }) - } - - return addrs, nil -} - -func (r *LinodeMachineReconciler) getInstanceIPv4Addresses(ctx context.Context, logger logr.Logger, machineScope *scope.MachineScope, instanceID int) ([]nodeIP, error) { +func (r *LinodeMachineReconciler) buildInstanceAddrs(ctx context.Context, machineScope *scope.MachineScope, instanceID int) ([]clusterv1.MachineAddress, error) { addresses, err := machineScope.LinodeClient.GetInstanceIPAddresses(ctx, instanceID) if err != nil { - return nil, err + return nil, fmt.Errorf("get instance ips: %w", err) } // get the default instance config configs, err := machineScope.LinodeClient.ListInstanceConfigs(ctx, instanceID, &linodego.ListOptions{}) if err != nil || len(configs) == 0 { - logger.Error(err, "Failed to list instance configs") - return nil, err + return nil, fmt.Errorf("list instance configs: %w", err) } - ips := []nodeIP{} + ips := []clusterv1.MachineAddress{} // check if a node has public ip and store it if len(addresses.IPv4.Public) != 0 { - ips = append(ips, nodeIP{ip: addresses.IPv4.Public[0].Address, ipType: clusterv1.MachineExternalIP}) + ips = append(ips, clusterv1.MachineAddress{Address: addresses.IPv4.Public[0].Address, Type: clusterv1.MachineExternalIP}) } // Iterate over interfaces in config and find VPC specific ips for _, iface := range configs[0].Interfaces { if iface.VPCID != nil && iface.IPv4.VPC != "" { - ips = append(ips, nodeIP{ip: iface.IPv4.VPC, ipType: clusterv1.MachineInternalIP}) + ips = append(ips, clusterv1.MachineAddress{Address: iface.IPv4.VPC, Type: clusterv1.MachineInternalIP}) } } @@ -158,7 +138,7 @@ func (r *LinodeMachineReconciler) getInstanceIPv4Addresses(ctx context.Context, // NOTE: We specifically store VPC ips first so that they are used first during // bootstrap when we set `registrationMethod: internal-only-ips` if len(addresses.IPv4.Private) != 0 { - ips = append(ips, nodeIP{ip: addresses.IPv4.Private[0].Address, ipType: clusterv1.MachineInternalIP}) + ips = append(ips, clusterv1.MachineAddress{Address: addresses.IPv4.Private[0].Address, Type: clusterv1.MachineInternalIP}) } return ips, nil From b1204eef62abc36214730fd6d7ba66c5dd9a6d53 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Thu, 21 Mar 2024 00:45:41 +0000 Subject: [PATCH 05/10] don't use /etc/hosts for node-ip --- templates/common-init-files/secret.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/common-init-files/secret.yaml b/templates/common-init-files/secret.yaml index 1cfba34ff..8afd927e4 100644 --- a/templates/common-init-files/secret.yaml +++ b/templates/common-init-files/secret.yaml @@ -38,4 +38,5 @@ stringData: modprobe overlay modprobe br_netfilter sysctl --system - + IPADDR=$(ip a s eth1 |grep 'inet ' |cut -d' ' -f6|cut -d/ -f1) + sed -i "s/kubeletExtraArgs:/kubeletExtraArgs:\n node-ip: $IPADDR/g" /run/kubeadm/kubeadm.yaml From 436f206ccf3af89d3dcddc6963b7009df91414d7 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Thu, 21 Mar 2024 14:09:11 +0000 Subject: [PATCH 06/10] add additional interface using machinetemplate --- controller/linodemachine_controller_helpers.go | 7 ------- templates/flavors/base/linodeMachineTemplate.yaml | 6 ++++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/controller/linodemachine_controller_helpers.go b/controller/linodemachine_controller_helpers.go index 8c3a052cf..2e0a715a3 100644 --- a/controller/linodemachine_controller_helpers.go +++ b/controller/linodemachine_controller_helpers.go @@ -88,13 +88,6 @@ func (r *LinodeMachineReconciler) newCreateConfig(ctx context.Context, machineSc createConfig.RootPass = uuid.NewString() } - // add public interface to linode (eth0) - iface := linodego.InstanceConfigInterfaceCreateOptions{ - Purpose: linodego.InterfacePurposePublic, - Primary: true, - } - createConfig.Interfaces = append(createConfig.Interfaces, iface) - // if vpc, attach additional interface to linode (eth1) if machineScope.LinodeCluster.Spec.VPCRef != nil { iface, err := r.getVPCInterfaceConfig(ctx, machineScope, createConfig.Interfaces, logger) diff --git a/templates/flavors/base/linodeMachineTemplate.yaml b/templates/flavors/base/linodeMachineTemplate.yaml index b2ee8f19d..dd4c74610 100644 --- a/templates/flavors/base/linodeMachineTemplate.yaml +++ b/templates/flavors/base/linodeMachineTemplate.yaml @@ -9,6 +9,9 @@ spec: image: ${LINODE_OS:="linode/ubuntu22.04"} type: ${LINODE_CONTROL_PLANE_MACHINE_TYPE} region: ${LINODE_REGION} + interfaces: + - purpose: public + primary: true authorizedKeys: # uncomment to include your ssh key in linode provisioning # - ${LINODE_SSH_PUBKEY:=""} @@ -23,6 +26,9 @@ spec: image: ${LINODE_OS:="linode/ubuntu22.04"} type: ${LINODE_MACHINE_TYPE} region: ${LINODE_REGION} + interfaces: + - purpose: public + primary: true authorizedKeys: # uncomment to include your ssh key in linode provisioning # - ${LINODE_SSH_PUBKEY:=""} From bb491606ccc8f7228480d1bc14f7a16f1d3d11c6 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 15 Apr 2024 19:15:58 +0000 Subject: [PATCH 07/10] rebase fix and address comments --- controller/linodemachine_controller.go | 20 +++++--- controller/linodemachine_controller_test.go | 54 +++++++++++++++++++-- templates/flavors/base/linodeVPC.yaml | 2 + 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/controller/linodemachine_controller.go b/controller/linodemachine_controller.go index d4b6e82eb..ad9ce3043 100644 --- a/controller/linodemachine_controller.go +++ b/controller/linodemachine_controller.go @@ -355,17 +355,25 @@ func (r *LinodeMachineReconciler) reconcileCreate( return ctrl.Result{RequeueAfter: reconciler.DefaultMachineControllerWaitForRunningDelay}, nil } + addrs, err := r.buildInstanceAddrs(ctx, machineScope, linodeInstance.ID) + if err != nil { + logger.Error(err, "Failed to get instance ip addresses") + + if reconciler.RecordDecayingCondition(machineScope.LinodeMachine, + ConditionPreflightReady, string(cerrs.CreateMachineError), err.Error(), + reconciler.DefaultMachineControllerPreflightTimeout(r.ReconcileTimeout)) { + return ctrl.Result{}, err + } + + return ctrl.Result{RequeueAfter: reconciler.DefaultMachineControllerWaitForRunningDelay}, nil + } + machineScope.LinodeMachine.Status.Addresses = addrs + conditions.MarkTrue(machineScope.LinodeMachine, ConditionPreflightReady) } machineScope.LinodeMachine.Spec.ProviderID = util.Pointer(fmt.Sprintf("linode://%d", linodeInstance.ID)) - addrs, err := r.buildInstanceAddrs(ctx, machineScope, linodeInstance.ID) - if err != nil { - return linodeInstance, err - } - machineScope.LinodeMachine.Status.Addresses = addrs - // Set the instance state to signal preflight process is done machineScope.LinodeMachine.Status.InstanceState = util.Pointer(linodego.InstanceOffline) diff --git a/controller/linodemachine_controller_test.go b/controller/linodemachine_controller_test.go index d561c0738..3c6e8a54a 100644 --- a/controller/linodemachine_controller_test.go +++ b/controller/linodemachine_controller_test.go @@ -148,10 +148,26 @@ var _ = Describe("create", Label("machine", "create"), func() { IPv4: []*net.IP{ptr.To(net.IPv4(192, 168, 0, 2))}, Status: linodego.InstanceOffline, }, nil) - mockLinodeClient.EXPECT(). + bootInst := mockLinodeClient.EXPECT(). BootInstance(ctx, 123, 0). After(createInst). Return(nil) + getAddrs := mockLinodeClient.EXPECT(). + GetInstanceIPAddresses(ctx, 123). + After(bootInst). + Return(&linodego.InstanceIPAddressResponse{ + IPv4: &linodego.InstanceIPv4Response{ + Private: []*linodego.InstanceIP{{Address: "192.168.0.2"}}, + }, + }, nil) + mockLinodeClient.EXPECT(). + ListInstanceConfigs(ctx, 123, gomock.Any()). + After(getAddrs). + Return([]linodego.InstanceConfig{{ + Devices: &linodego.InstanceConfigDeviceMap{ + SDA: &linodego.InstanceConfigDevice{DiskID: 100}, + }, + }}, nil) mScope := scope.MachineScope{ Client: k8sClient, @@ -308,7 +324,7 @@ var _ = Describe("create", Label("machine", "create"), func() { Private: []*linodego.InstanceIP{{Address: "192.168.0.2"}}, }, }, nil) - mockLinodeClient.EXPECT(). + createNB := mockLinodeClient.EXPECT(). CreateNodeBalancerNode(ctx, 1, 2, linodego.NodeBalancerNodeCreateOptions{ Label: "mock", Address: "192.168.0.2:6443", @@ -316,6 +332,22 @@ var _ = Describe("create", Label("machine", "create"), func() { }). After(getAddrs). Return(nil, nil) + getAddrs = mockLinodeClient.EXPECT(). + GetInstanceIPAddresses(ctx, 123). + After(createNB). + Return(&linodego.InstanceIPAddressResponse{ + IPv4: &linodego.InstanceIPv4Response{ + Private: []*linodego.InstanceIP{{Address: "192.168.0.2"}}, + }, + }, nil) + mockLinodeClient.EXPECT(). + ListInstanceConfigs(ctx, 123, gomock.Any()). + After(getAddrs). + Return([]linodego.InstanceConfig{{ + Devices: &linodego.InstanceConfigDeviceMap{ + SDA: &linodego.InstanceConfigDevice{DiskID: 100}, + }, + }}, nil) mScope := scope.MachineScope{ Client: k8sClient, @@ -463,7 +495,7 @@ var _ = Describe("create", Label("machine", "create"), func() { Private: []*linodego.InstanceIP{{Address: "192.168.0.2"}}, }, }, nil) - mockLinodeClient.EXPECT(). + createNB := mockLinodeClient.EXPECT(). CreateNodeBalancerNode(ctx, 1, 2, linodego.NodeBalancerNodeCreateOptions{ Label: "mock", Address: "192.168.0.2:6443", @@ -471,6 +503,22 @@ var _ = Describe("create", Label("machine", "create"), func() { }). After(getAddrs). Return(nil, nil) + getAddrs = mockLinodeClient.EXPECT(). + GetInstanceIPAddresses(ctx, 123). + After(createNB). + Return(&linodego.InstanceIPAddressResponse{ + IPv4: &linodego.InstanceIPv4Response{ + Private: []*linodego.InstanceIP{{Address: "192.168.0.2"}}, + }, + }, nil) + mockLinodeClient.EXPECT(). + ListInstanceConfigs(ctx, 123, gomock.Any()). + After(getAddrs). + Return([]linodego.InstanceConfig{{ + Devices: &linodego.InstanceConfigDeviceMap{ + SDA: &linodego.InstanceConfigDevice{DiskID: 100}, + }, + }}, nil) _, err = reconciler.reconcileCreate(ctx, logger, &mScope) Expect(err).NotTo(HaveOccurred()) diff --git a/templates/flavors/base/linodeVPC.yaml b/templates/flavors/base/linodeVPC.yaml index 4ed39878c..7a311127e 100644 --- a/templates/flavors/base/linodeVPC.yaml +++ b/templates/flavors/base/linodeVPC.yaml @@ -3,6 +3,8 @@ apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 kind: LinodeVPC metadata: name: ${VPC_NAME:=${CLUSTER_NAME}} + labels: + cluster.x-k8s.io/cluster-name: ${CLUSTER_NAME} spec: region: ${LINODE_REGION} subnets: From aab43d73773fd99a9b8eb624d41ed8cf1e66fe93 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Wed, 17 Apr 2024 06:26:02 +0000 Subject: [PATCH 08/10] reduce cognitive complexity, update tests and use ccm v0.4.3 for updated helm chart --- controller/linodemachine_controller.go | 25 ++++++++++++++----- controller/linodemachine_controller_test.go | 24 +++++++++++++++--- .../addons/provider-linode/linode-ccm.yaml | 2 +- templates/flavors/k3s/secret.yaml | 2 +- templates/flavors/rke2/secret.yaml | 2 +- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/controller/linodemachine_controller.go b/controller/linodemachine_controller.go index ad9ce3043..1c88ae073 100644 --- a/controller/linodemachine_controller.go +++ b/controller/linodemachine_controller.go @@ -61,6 +61,7 @@ const ( ConditionPreflightAdditionalDisksCreated clusterv1.ConditionType = "PreflightAdditionalDisksCreated" ConditionPreflightConfigured clusterv1.ConditionType = "PreflightConfigured" ConditionPreflightBootTriggered clusterv1.ConditionType = "PreflightBootTriggered" + ConditionPreflightNBConfigured clusterv1.ConditionType = "PreflightNBConfigured" ConditionPreflightReady clusterv1.ConditionType = "PreflightReady" ) @@ -248,7 +249,6 @@ func (r *LinodeMachineReconciler) reconcile( return } -//nolint:cyclop // keep top-level preflight condition checks in the same function for readability func (r *LinodeMachineReconciler) reconcileCreate( ctx context.Context, logger logr.Logger, @@ -312,8 +312,17 @@ func (r *LinodeMachineReconciler) reconcileCreate( return ctrl.Result{}, err } + return r.reconcileInstanceCreate(ctx, logger, machineScope, linodeInstance) +} + +func (r *LinodeMachineReconciler) reconcileInstanceCreate( + ctx context.Context, + logger logr.Logger, + machineScope *scope.MachineScope, + linodeInstance *linodego.Instance, +) (ctrl.Result, error) { if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightConfigured) { - if err = r.configureDisks(ctx, logger, machineScope, linodeInstance.ID); err != nil { + if err := r.configureDisks(ctx, logger, machineScope, linodeInstance.ID); err != nil { if reconciler.RecordDecayingCondition(machineScope.LinodeMachine, ConditionPreflightConfigured, string(cerrs.CreateMachineError), err.Error(), reconciler.DefaultMachineControllerPreflightTimeout(r.ReconcileTimeout)) { @@ -327,7 +336,7 @@ func (r *LinodeMachineReconciler) reconcileCreate( } if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightBootTriggered) { - if err = machineScope.LinodeClient.BootInstance(ctx, linodeInstance.ID, 0); err != nil { + if err := machineScope.LinodeClient.BootInstance(ctx, linodeInstance.ID, 0); err != nil { logger.Error(err, "Failed to boot instance") if reconciler.RecordDecayingCondition(machineScope.LinodeMachine, @@ -342,12 +351,12 @@ func (r *LinodeMachineReconciler) reconcileCreate( conditions.MarkTrue(machineScope.LinodeMachine, ConditionPreflightBootTriggered) } - if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightReady) { - if err = services.AddNodeToNB(ctx, logger, machineScope); err != nil { + if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightNBConfigured) { + if err := services.AddNodeToNB(ctx, logger, machineScope); err != nil { logger.Error(err, "Failed to add instance to Node Balancer backend") if reconciler.RecordDecayingCondition(machineScope.LinodeMachine, - ConditionPreflightReady, string(cerrs.CreateMachineError), err.Error(), + ConditionPreflightNBConfigured, string(cerrs.CreateMachineError), err.Error(), reconciler.DefaultMachineControllerPreflightTimeout(r.ReconcileTimeout)) { return ctrl.Result{}, err } @@ -355,6 +364,10 @@ func (r *LinodeMachineReconciler) reconcileCreate( return ctrl.Result{RequeueAfter: reconciler.DefaultMachineControllerWaitForRunningDelay}, nil } + conditions.MarkTrue(machineScope.LinodeMachine, ConditionPreflightNBConfigured) + } + + if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightReady) { addrs, err := r.buildInstanceAddrs(ctx, machineScope, linodeInstance.ID) if err != nil { logger.Error(err, "Failed to get instance ip addresses") diff --git a/controller/linodemachine_controller_test.go b/controller/linodemachine_controller_test.go index 3c6e8a54a..1b6dd62e8 100644 --- a/controller/linodemachine_controller_test.go +++ b/controller/linodemachine_controller_test.go @@ -493,6 +493,7 @@ var _ = Describe("create", Label("machine", "create"), func() { Return(&linodego.InstanceIPAddressResponse{ IPv4: &linodego.InstanceIPv4Response{ Private: []*linodego.InstanceIP{{Address: "192.168.0.2"}}, + Public: []*linodego.InstanceIP{{Address: "172.0.0.2"}}, }, }, nil) createNB := mockLinodeClient.EXPECT(). @@ -509,6 +510,7 @@ var _ = Describe("create", Label("machine", "create"), func() { Return(&linodego.InstanceIPAddressResponse{ IPv4: &linodego.InstanceIPv4Response{ Private: []*linodego.InstanceIP{{Address: "192.168.0.2"}}, + Public: []*linodego.InstanceIP{{Address: "172.0.0.2"}}, }, }, nil) mockLinodeClient.EXPECT(). @@ -518,6 +520,10 @@ var _ = Describe("create", Label("machine", "create"), func() { Devices: &linodego.InstanceConfigDeviceMap{ SDA: &linodego.InstanceConfigDevice{DiskID: 100}, }, + Interfaces: []linodego.InstanceConfigInterface{{ + VPCID: ptr.To(1), + IPv4: &linodego.VPCIPv4{VPC: "10.0.0.2"}, + }}, }}, nil) _, err = reconciler.reconcileCreate(ctx, logger, &mScope) @@ -531,10 +537,20 @@ var _ = Describe("create", Label("machine", "create"), func() { Expect(*linodeMachine.Status.InstanceState).To(Equal(linodego.InstanceOffline)) Expect(*linodeMachine.Spec.InstanceID).To(Equal(123)) Expect(*linodeMachine.Spec.ProviderID).To(Equal("linode://123")) - Expect(linodeMachine.Status.Addresses).To(Equal([]clusterv1.MachineAddress{{ - Type: clusterv1.MachineInternalIP, - Address: "192.168.0.2", - }})) + Expect(linodeMachine.Status.Addresses).To(Equal([]clusterv1.MachineAddress{ + { + Type: clusterv1.MachineExternalIP, + Address: "172.0.0.2", + }, + { + Type: clusterv1.MachineInternalIP, + Address: "10.0.0.2", + }, + { + Type: clusterv1.MachineInternalIP, + Address: "192.168.0.2", + }, + })) Expect(testLogs.String()).To(ContainSubstring("creating machine")) Expect(testLogs.String()).To(ContainSubstring("Linode instance already exists")) diff --git a/templates/addons/provider-linode/linode-ccm.yaml b/templates/addons/provider-linode/linode-ccm.yaml index 8849f0b53..eeb2bde32 100644 --- a/templates/addons/provider-linode/linode-ccm.yaml +++ b/templates/addons/provider-linode/linode-ccm.yaml @@ -9,7 +9,7 @@ spec: repoURL: https://linode.github.io/linode-cloud-controller-manager/ chartName: ccm-linode namespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.4.1} + version: ${LINODE_CCM_VERSION:=v0.4.3} options: waitForJobs: true wait: true diff --git a/templates/flavors/k3s/secret.yaml b/templates/flavors/k3s/secret.yaml index 47ff1bd25..9e024ff82 100644 --- a/templates/flavors/k3s/secret.yaml +++ b/templates/flavors/k3s/secret.yaml @@ -39,7 +39,7 @@ stringData: name: ccm-linode spec: targetNamespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.4.1} + version: ${LINODE_CCM_VERSION:=v0.4.3} chart: ccm-linode repo: https://linode.github.io/linode-cloud-controller-manager/ bootstrap: true diff --git a/templates/flavors/rke2/secret.yaml b/templates/flavors/rke2/secret.yaml index fc40a421f..bc1caf540 100644 --- a/templates/flavors/rke2/secret.yaml +++ b/templates/flavors/rke2/secret.yaml @@ -21,7 +21,7 @@ stringData: name: ccm-linode spec: targetNamespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.4.1} + version: ${LINODE_CCM_VERSION:=v0.4.3} chart: ccm-linode repo: https://linode.github.io/linode-cloud-controller-manager/ bootstrap: true From 46b199b6b1f6e977c538423894d96c36fca79d35 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Wed, 24 Apr 2024 17:18:27 +0000 Subject: [PATCH 09/10] update linode-ccm to v0.4.4 --- templates/addons/provider-linode/linode-ccm.yaml | 2 +- templates/flavors/k3s/secret.yaml | 2 +- templates/flavors/rke2/secret.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/addons/provider-linode/linode-ccm.yaml b/templates/addons/provider-linode/linode-ccm.yaml index eeb2bde32..64e57c9de 100644 --- a/templates/addons/provider-linode/linode-ccm.yaml +++ b/templates/addons/provider-linode/linode-ccm.yaml @@ -9,7 +9,7 @@ spec: repoURL: https://linode.github.io/linode-cloud-controller-manager/ chartName: ccm-linode namespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.4.3} + version: ${LINODE_CCM_VERSION:=v0.4.4} options: waitForJobs: true wait: true diff --git a/templates/flavors/k3s/secret.yaml b/templates/flavors/k3s/secret.yaml index 9e024ff82..abc074827 100644 --- a/templates/flavors/k3s/secret.yaml +++ b/templates/flavors/k3s/secret.yaml @@ -39,7 +39,7 @@ stringData: name: ccm-linode spec: targetNamespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.4.3} + version: ${LINODE_CCM_VERSION:=v0.4.4} chart: ccm-linode repo: https://linode.github.io/linode-cloud-controller-manager/ bootstrap: true diff --git a/templates/flavors/rke2/secret.yaml b/templates/flavors/rke2/secret.yaml index bc1caf540..4641b5a13 100644 --- a/templates/flavors/rke2/secret.yaml +++ b/templates/flavors/rke2/secret.yaml @@ -21,7 +21,7 @@ stringData: name: ccm-linode spec: targetNamespace: kube-system - version: ${LINODE_CCM_VERSION:=v0.4.3} + version: ${LINODE_CCM_VERSION:=v0.4.4} chart: ccm-linode repo: https://linode.github.io/linode-cloud-controller-manager/ bootstrap: true From fa6fc01a55e8dc7b460b94a0c5382f978e66ac04 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Wed, 24 Apr 2024 21:13:12 +0000 Subject: [PATCH 10/10] address review comments, add vpc note --- controller/linodemachine_controller.go | 8 ++++---- docs/src/developers/development.md | 5 ++++- docs/src/topics/getting-started.md | 3 +++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/controller/linodemachine_controller.go b/controller/linodemachine_controller.go index 1c88ae073..6454cadcc 100644 --- a/controller/linodemachine_controller.go +++ b/controller/linodemachine_controller.go @@ -61,7 +61,7 @@ const ( ConditionPreflightAdditionalDisksCreated clusterv1.ConditionType = "PreflightAdditionalDisksCreated" ConditionPreflightConfigured clusterv1.ConditionType = "PreflightConfigured" ConditionPreflightBootTriggered clusterv1.ConditionType = "PreflightBootTriggered" - ConditionPreflightNBConfigured clusterv1.ConditionType = "PreflightNBConfigured" + ConditionPreflightNetworking clusterv1.ConditionType = "PreflightNetworking" ConditionPreflightReady clusterv1.ConditionType = "PreflightReady" ) @@ -351,12 +351,12 @@ func (r *LinodeMachineReconciler) reconcileInstanceCreate( conditions.MarkTrue(machineScope.LinodeMachine, ConditionPreflightBootTriggered) } - if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightNBConfigured) { + if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightNetworking) { if err := services.AddNodeToNB(ctx, logger, machineScope); err != nil { logger.Error(err, "Failed to add instance to Node Balancer backend") if reconciler.RecordDecayingCondition(machineScope.LinodeMachine, - ConditionPreflightNBConfigured, string(cerrs.CreateMachineError), err.Error(), + ConditionPreflightNetworking, string(cerrs.CreateMachineError), err.Error(), reconciler.DefaultMachineControllerPreflightTimeout(r.ReconcileTimeout)) { return ctrl.Result{}, err } @@ -364,7 +364,7 @@ func (r *LinodeMachineReconciler) reconcileInstanceCreate( return ctrl.Result{RequeueAfter: reconciler.DefaultMachineControllerWaitForRunningDelay}, nil } - conditions.MarkTrue(machineScope.LinodeMachine, ConditionPreflightNBConfigured) + conditions.MarkTrue(machineScope.LinodeMachine, ConditionPreflightNetworking) } if !reconciler.ConditionTrue(machineScope.LinodeMachine, ConditionPreflightReady) { diff --git a/docs/src/developers/development.md b/docs/src/developers/development.md index 861451d74..a483623d5 100644 --- a/docs/src/developers/development.md +++ b/docs/src/developers/development.md @@ -213,7 +213,7 @@ clusterctl generate cluster $CLUSTER_NAME \ | kubectl apply -f - ``` -This will provision the cluster with the CNI defaulted to [cilium](../topics/addons.md#cilium) +This will provision the cluster within VPC with the CNI defaulted to [cilium](../topics/addons.md#cilium) and the [linode-ccm](../topics/addons.md#ccm) installed. ##### Using ClusterClass (alpha) @@ -245,6 +245,9 @@ To delete the cluster, simply run: ```sh kubectl delete cluster $CLUSTER_NAME ``` +```admonish warning +VPCs are not deleted when a cluster is deleted using kubectl. One can run `kubectl delete linodevpc ` to cleanup VPC once cluster is deleted. +``` ```admonish question title="" For any issues, please refer to the [troubleshooting guide](../topics/troubleshooting.md). diff --git a/docs/src/topics/getting-started.md b/docs/src/topics/getting-started.md index d2bb4e8ec..658edfd84 100644 --- a/docs/src/topics/getting-started.md +++ b/docs/src/topics/getting-started.md @@ -32,6 +32,9 @@ export LINODE_MACHINE_TYPE=g6-standard-2 For Regions and Images that do not yet support Akamai's cloud-init datasource CAPL will automatically use a stackscript shim to provision the node. If you are using a custom image ensure the [cloud_init](https://www.linode.com/docs/api/images/#image-create) flag is set correctly on it ``` +```admonish warning +By default, clusters are provisioned within VPC. For Regions which do not have [VPC support](https://www.linode.com/docs/products/networking/vpc/#availability) yet, use the VPCLess[TODO] flavor to have clusters provisioned. +``` ## Register linode as an infrastructure provider 1. Add `linode` as an infrastructure provider in `~/.cluster-api/clusterctl.yaml`