Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.

Commit c861c41

Browse files
dkoshkinjimmidyson
andauthored
feat: add Cluster Autoscaler Addon with HelmAddon (nutanix-cloud-native#427)
Co-authored-by: Jimmi Dyson <[email protected]>
1 parent 8e26969 commit c861c41

25 files changed

+305
-60
lines changed

api/v1alpha1/addon_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ func (ClusterAutoscaler) VariableSchema() clusterv1.VariableSchema {
125125
Type: "string",
126126
Enum: variables.MustMarshalValuesToEnumJSON(
127127
AddonStrategyClusterResourceSet,
128+
AddonStrategyHelmAddon,
128129
),
129130
},
130131
},

charts/capi-runtime-extensions/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ A Helm chart for capi-runtime-extensions
3232
| deployment.replicas | int | `1` | |
3333
| env | object | `{}` | |
3434
| hooks.clusterAutoscaler.crsStrategy.defaultInstallationConfigMap.name | string | `"cluster-autoscaler"` | |
35+
| hooks.clusterAutoscaler.helmAddonStrategy.defaultValueTemplateConfigMap.create | bool | `true` | |
36+
| hooks.clusterAutoscaler.helmAddonStrategy.defaultValueTemplateConfigMap.name | string | `"default-cluster-autoscaler-helm-values-template"` | |
3537
| hooks.cni.calico.crsStrategy.defaultInstallationConfigMaps.AWSCluster.configMap.content | string | `""` | |
3638
| hooks.cni.calico.crsStrategy.defaultInstallationConfigMaps.AWSCluster.configMap.name | string | `"calico-cni-crs-installation-awscluster"` | |
3739
| hooks.cni.calico.crsStrategy.defaultInstallationConfigMaps.AWSCluster.create | bool | `true` | |

charts/capi-runtime-extensions/templates/cluster-autoscaler/manifests/cluster-autoscaler-configmap.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,5 @@ data:
221221
kind: ConfigMap
222222
metadata:
223223
creationTimestamp: null
224-
name: cluster-autoscaler
224+
name: '{{ .Values.hooks.clusterAutoscaler.crsStrategy.defaultInstallationConfigMap.name
225+
}}'
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright 2024 D2iQ, Inc. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
{{- if .Values.hooks.clusterAutoscaler.helmAddonStrategy.defaultValueTemplateConfigMap.create }}
5+
apiVersion: v1
6+
kind: ConfigMap
7+
metadata:
8+
name: '{{ .Values.hooks.clusterAutoscaler.helmAddonStrategy.defaultValueTemplateConfigMap.name }}'
9+
data:
10+
values.yaml: |-
11+
---
12+
fullnameOverride: "cluster-autoscaler-{{ `{{ .Cluster.metadata.name }}` }}"
13+
14+
cloudProvider: clusterapi
15+
16+
# Always trigger a scale-out if replicas are less than the min.
17+
extraArgs:
18+
enforce-node-group-min-size: true
19+
20+
# Enable it to run in a 1 Node cluster.
21+
tolerations:
22+
- effect: NoSchedule
23+
key: node-role.kubernetes.io/control-plane
24+
25+
# Limit a single cluster-autoscaler Deployment to a single Cluster.
26+
autoDiscovery:
27+
clusterName: "{{ `{{ .Cluster.metadata.name }}` }}"
28+
# The controller failed with an RBAC error trying to watch CAPI objects at the cluster scope without this.
29+
labels:
30+
- namespace: "{{ `{{ .Cluster.metadata.namespace }}` }}"
31+
32+
clusterAPIConfigMapsNamespace: "{{ `{{ .Cluster.metadata.namespace }}` }}"
33+
# For workload clusters it is not possible to use the in-cluster client.
34+
# To simplify the configuration, use the admin kubeconfig generated by CAPI for all clusters.
35+
clusterAPIMode: kubeconfig-incluster
36+
clusterAPIWorkloadKubeconfigPath: /cluster/kubeconfig
37+
extraVolumeSecrets:
38+
kubeconfig:
39+
name: "{{ `{{ .Cluster.metadata.name }}` }}-kubeconfig"
40+
mountPath: /cluster
41+
readOnly: true
42+
items:
43+
- key: value
44+
path: kubeconfig
45+
rbac:
46+
# Create a Role instead of a ClusterRoles to update cluster-api objects
47+
clusterScoped: false
48+
{{- end -}}

charts/capi-runtime-extensions/values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ hooks:
4747
crsStrategy:
4848
defaultInstallationConfigMap:
4949
name: cluster-autoscaler
50+
helmAddonStrategy:
51+
defaultValueTemplateConfigMap:
52+
create: true
53+
name: default-cluster-autoscaler-helm-values-template
5054

5155
deployDefaultClusterClasses: true
5256

examples/capi-quick-start/aws-cluster-calico-helm-addon.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ spec:
2121
- name: clusterConfig
2222
value:
2323
addons:
24+
clusterAutoscaler:
25+
strategy: HelmAddon
2426
cni:
2527
provider: Calico
2628
strategy: HelmAddon
@@ -51,5 +53,8 @@ spec:
5153
workers:
5254
machineDeployments:
5355
- class: default-worker
56+
metadata:
57+
annotations:
58+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "${WORKER_MACHINE_COUNT}"
59+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "${WORKER_MACHINE_COUNT}"
5460
name: md-0
55-
replicas: ${WORKER_MACHINE_COUNT}

examples/capi-quick-start/aws-cluster-cilium-helm-addon.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ spec:
2121
- name: clusterConfig
2222
value:
2323
addons:
24+
clusterAutoscaler:
25+
strategy: HelmAddon
2426
cni:
2527
provider: Cilium
2628
strategy: HelmAddon
@@ -51,5 +53,8 @@ spec:
5153
workers:
5254
machineDeployments:
5355
- class: default-worker
56+
metadata:
57+
annotations:
58+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "${WORKER_MACHINE_COUNT}"
59+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "${WORKER_MACHINE_COUNT}"
5460
name: md-0
55-
replicas: ${WORKER_MACHINE_COUNT}

examples/capi-quick-start/docker-cluster-calico-helm-addon.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ spec:
2222
- name: clusterConfig
2323
value:
2424
addons:
25+
clusterAutoscaler:
26+
strategy: HelmAddon
2527
cni:
2628
provider: Calico
2729
strategy: HelmAddon
@@ -32,5 +34,8 @@ spec:
3234
workers:
3335
machineDeployments:
3436
- class: default-worker
37+
metadata:
38+
annotations:
39+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "${WORKER_MACHINE_COUNT}"
40+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "${WORKER_MACHINE_COUNT}"
3541
name: md-0
36-
replicas: ${WORKER_MACHINE_COUNT}

examples/capi-quick-start/docker-cluster-cilium-helm-addon.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ spec:
2222
- name: clusterConfig
2323
value:
2424
addons:
25+
clusterAutoscaler:
26+
strategy: HelmAddon
2527
cni:
2628
provider: Cilium
2729
strategy: HelmAddon
@@ -32,5 +34,8 @@ spec:
3234
workers:
3335
machineDeployments:
3436
- class: default-worker
37+
metadata:
38+
annotations:
39+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "${WORKER_MACHINE_COUNT}"
40+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "${WORKER_MACHINE_COUNT}"
3541
name: md-0
36-
replicas: ${WORKER_MACHINE_COUNT}

hack/addons/update-cluster-autoscaler.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ cp "${KUSTOMIZE_BASE_DIR}"/*.yaml "${ASSETS_DIR}"
2525

2626
kustomize build --enable-helm "${ASSETS_DIR}" >"${ASSETS_DIR}/${FILE_NAME}"
2727

28-
kubectl create configmap cluster-autoscaler --dry-run=client --output yaml \
28+
kubectl create configmap "{{ .Values.hooks.clusterAutoscaler.crsStrategy.defaultInstallationConfigMap.name }}" --dry-run=client --output yaml \
2929
--from-file "${ASSETS_DIR}/${FILE_NAME}" \
3030
>"${ASSETS_DIR}/cluster-autoscaler-configmap.yaml"
3131

hack/examples/bases/aws/calico/crs/kustomization.yaml.tmpl

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,6 @@ patches:
3232
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
3333
value:
3434
strategy: ClusterResourceSet
35-
- op: "remove"
36-
path: "/spec/topology/workers/machineDeployments/0/replicas"
37-
- op: "add"
38-
path: "/spec/topology/workers/machineDeployments/0/metadata"
39-
value:
40-
annotations:
41-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "$${WORKER_MACHINE_COUNT}"
42-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "$${WORKER_MACHINE_COUNT}"
43-
4435

4536
# Delete all ClusterClass related resources to prevent duplicate resources because we use the same resources definition
4637
# above- we only actually want the Cluster resource to mutate here.

hack/examples/bases/aws/calico/helm-addon/kustomization.yaml.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ patches:
2828
path: "/spec/topology/variables/0/value/addons/nfd"
2929
value:
3030
strategy: HelmAddon
31+
- op: "add"
32+
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
33+
value:
34+
strategy: HelmAddon

hack/examples/bases/aws/cilium/crs/kustomization.yaml.tmpl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,6 @@ patches:
3232
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
3333
value:
3434
strategy: ClusterResourceSet
35-
- op: "remove"
36-
path: "/spec/topology/workers/machineDeployments/0/replicas"
37-
- op: "add"
38-
path: "/spec/topology/workers/machineDeployments/0/metadata"
39-
value:
40-
annotations:
41-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "$${WORKER_MACHINE_COUNT}"
42-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "$${WORKER_MACHINE_COUNT}"
4335

4436

4537
# Delete all ClusterClass related resources to prevent duplicate resources because we use the same resources definition

hack/examples/bases/aws/cilium/helm-addon/kustomization.yaml.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ patches:
2828
path: "/spec/topology/variables/0/value/addons/nfd"
2929
value:
3030
strategy: HelmAddon
31+
- op: "add"
32+
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
33+
value:
34+
strategy: HelmAddon
3135

3236
# Delete all ClusterClass related resources to prevent duplicate resources because we use the same resources definition
3337
# above- we only actually want the Cluster resource to mutate here.

hack/examples/bases/docker/calico/crs/kustomization.yaml.tmpl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,3 @@ patches:
3232
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
3333
value:
3434
strategy: ClusterResourceSet
35-
- op: "remove"
36-
path: "/spec/topology/workers/machineDeployments/0/replicas"
37-
- op: "add"
38-
path: "/spec/topology/workers/machineDeployments/0/metadata"
39-
value:
40-
annotations:
41-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "$${WORKER_MACHINE_COUNT}"
42-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "$${WORKER_MACHINE_COUNT}"

hack/examples/bases/docker/calico/helm-addon/kustomization.yaml.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ patches:
2828
path: "/spec/topology/variables/0/value/addons/nfd"
2929
value:
3030
strategy: HelmAddon
31+
- op: "add"
32+
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
33+
value:
34+
strategy: HelmAddon

hack/examples/bases/docker/cilium/crs/kustomization.yaml.tmpl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,3 @@ patches:
3232
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
3333
value:
3434
strategy: ClusterResourceSet
35-
- op: "remove"
36-
path: "/spec/topology/workers/machineDeployments/0/replicas"
37-
- op: "add"
38-
path: "/spec/topology/workers/machineDeployments/0/metadata"
39-
value:
40-
annotations:
41-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "$${WORKER_MACHINE_COUNT}"
42-
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "$${WORKER_MACHINE_COUNT}"

hack/examples/bases/docker/cilium/helm-addon/kustomization.yaml.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ patches:
2828
path: "/spec/topology/variables/0/value/addons/nfd"
2929
value:
3030
strategy: HelmAddon
31+
- op: "add"
32+
path: "/spec/topology/variables/0/value/addons/clusterAutoscaler"
33+
value:
34+
strategy: HelmAddon

hack/examples/kustomization.yaml.tmpl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,11 @@ patches:
3232
- op: "add"
3333
path: "/spec/clusterNetwork/serviceDomain"
3434
value: "cluster.local"
35+
- op: "remove"
36+
path: "/spec/topology/workers/machineDeployments/0/replicas"
37+
- op: "add"
38+
path: "/spec/topology/workers/machineDeployments/0/metadata"
39+
value:
40+
annotations:
41+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size: "$${WORKER_MACHINE_COUNT}"
42+
cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size: "$${WORKER_MACHINE_COUNT}"

pkg/handlers/generic/lifecycle/clusterautoscaler/handler.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,28 @@ import (
1818
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/handlers/lifecycle"
1919
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/variables"
2020
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/generic/clusterconfig"
21+
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/options"
2122
)
2223

2324
type addonStrategy interface {
24-
apply(context.Context, *runtimehooksv1.AfterControlPlaneInitializedRequest, logr.Logger) error
25+
apply(
26+
context.Context,
27+
*runtimehooksv1.AfterControlPlaneInitializedRequest,
28+
string,
29+
logr.Logger,
30+
) error
2531
}
2632

2733
type Config struct {
28-
crsConfig crsConfig
34+
*options.GlobalOptions
35+
36+
crsConfig crsConfig
37+
helmAddonConfig helmAddonConfig
2938
}
3039

3140
func (c *Config) AddFlags(prefix string, flags *pflag.FlagSet) {
3241
c.crsConfig.AddFlags(prefix+".crs", flags)
42+
c.helmAddonConfig.AddFlags(prefix+".helm-addon", flags)
3343
}
3444

3545
type DefaultClusterAutoscaler struct {
@@ -106,6 +116,11 @@ func (n *DefaultClusterAutoscaler) AfterControlPlaneInitialized(
106116
config: n.config.crsConfig,
107117
client: n.client,
108118
}
119+
case v1alpha1.AddonStrategyHelmAddon:
120+
strategy = helmAddonStrategy{
121+
config: n.config.helmAddonConfig,
122+
client: n.client,
123+
}
109124
default:
110125
resp.SetStatus(runtimehooksv1.ResponseStatusFailure)
111126
resp.SetMessage(
@@ -114,7 +129,7 @@ func (n *DefaultClusterAutoscaler) AfterControlPlaneInitialized(
114129
return
115130
}
116131

117-
if err := strategy.apply(ctx, req, log); err != nil {
132+
if err = strategy.apply(ctx, req, n.config.DefaultsNamespace(), log); err != nil {
118133
resp.SetStatus(runtimehooksv1.ResponseStatusFailure)
119134
resp.SetMessage(err.Error())
120135
return

pkg/handlers/generic/lifecycle/clusterautoscaler/strategy_crs.go

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
1616
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
1717

18-
capiutils "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/utils"
1918
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/k8s/client"
2019
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/generic/lifecycle/utils"
2120
)
@@ -51,6 +50,7 @@ type crsStrategy struct {
5150
func (s crsStrategy) apply(
5251
ctx context.Context,
5352
req *runtimehooksv1.AfterControlPlaneInitializedRequest,
53+
defaultsNamespace string,
5454
log logr.Logger,
5555
) error {
5656
defaultCM := &corev1.ConfigMap{
@@ -59,7 +59,7 @@ func (s crsStrategy) apply(
5959
Kind: "ConfigMap",
6060
},
6161
ObjectMeta: metav1.ObjectMeta{
62-
Namespace: s.config.defaultsNamespace,
62+
Namespace: defaultsNamespace,
6363
Name: s.config.defaultClusterAutoscalerConfigMap,
6464
},
6565
}
@@ -97,22 +97,12 @@ func (s crsStrategy) apply(
9797
)
9898
}
9999

100-
existingManagementCluster, err := capiutils.ManagementCluster(ctx, s.client)
101-
if err != nil {
102-
return fmt.Errorf(
103-
"failed to get management Cluster: %w",
104-
err,
105-
)
106-
}
107100
// The cluster-autoscaler is different from other addons.
108101
// It requires all resources to be created in the management cluster,
109102
// which means creating the ClusterResourceSet always targeting the management cluster.
110-
// In most cases, target the management cluster.
111-
// But if existingManagementCluster is nil, i.e. when s.client points to a bootstrap cluster,
112-
// target the cluster and assume that will become the management cluster.
113-
targetCluster := existingManagementCluster
114-
if targetCluster == nil {
115-
targetCluster = cluster
103+
targetCluster, err := findTargetCluster(ctx, s.client, cluster)
104+
if err != nil {
105+
return err
116106
}
117107

118108
// In the case when existingManagementCluster is nil, i.e. when s.client points to a bootstrap cluster,

0 commit comments

Comments
 (0)