Skip to content

Commit

Permalink
Merge pull request 'Changes for the Cluster API Cluster Autoscaler in…
Browse files Browse the repository at this point in the history
…tegration done in KubeAid' (#15) from capi-cluster-autoscaler into main

Reviewed-on: https://gitea.obmondo.com/EnableIT/kubeaid-bootstrap-script/pulls/15
  • Loading branch information
Klavs Klavsen committed Nov 11, 2024
2 parents 820ae9f + fe80b49 commit d6927be
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 27 deletions.
3 changes: 3 additions & 0 deletions cmd/bootstrap_cluster/bootstrap_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ func BootstrapCluster(ctx *cli.Context) error {
"clusterctl move --kubeconfig %s --namespace %s --to-kubeconfig %s",
constants.OutputPathManagementClusterKubeconfig, capiClusterNamespace, constants.OutputPathProvisionedClusterKubeconfig,
))

// Sync cluster-autoscaler ArgoCD App.
utils.ExecuteCommandOrDie("argocd app sync argo-cd/cluster-autoscaler")
}

slog.Info("Cluster provisioned successfully 🎉🎉 !", slog.String("kubeconfig", constants.OutputPathProvisionedClusterKubeconfig))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ global:
{{- end }}
kubernetes:
version: {{ .K8sVersion }}
clusterAPI:
version: v1.8.1
capa:
version: v2.6.1
autoScaler: true
kubeaid:
repo: {{ .KubeaidForkURL }}
kubeaidConfig:
Expand All @@ -36,5 +31,5 @@ aws:
instanceType: {{ .ControlPlaneInstanceType }}
ami:
id: {{ .ControlPlaneAMI }}
machinePools:
{{ .MachinePools | toYaml | indent 2 }}
nodeGroups:
{{ .NodeGroups | toYaml | indent 2 }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cluster-autoscaler:
cloudProvider: clusterapi

# Cluster API mode : incluster-incluster / incluster-kubeconfig / kubeconfig-incluster / kubeconfig-kubeconfig / single-kubeconfig.
# Syntax: workloadClusterMode-ManagementClusterMode
#
# For 'kubeconfig-kubeconfig', 'incluster-kubeconfig' and 'single-kubeconfig' you always must
# mount the external kubeconfig using either 'extraVolumeSecrets' or 'extraMounts' and
# 'extraVolumes'.
#
# If you dont set 'clusterAPIKubeconfigSecret'and thus use an in-cluster config or want to use a
# non CAPI generated kubeconfig you must do so for the workload kubeconfig as well
#
# REFER : https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/clusterapi/README.md#connecting-cluster-autoscaler-to-cluster-api-management-and-workload-clusters
clusterAPIMode: incluster-incluster

autoDiscovery:
clusterName: {{ .ClusterName }}
namespace: {{ .CAPIClusterNamespace }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cluster-autoscaler
namespace: argo-cd

spec:
destination:
namespace: cluster-autoscaler
server: https://kubernetes.default.svc
sources:
- repoURL: {{ .KubeaidForkURL }}
path: argocd-helm-charts/cluster-autoscaler
targetRevision: HEAD
helm:
valueFiles:
- $values/k8s/{{ .ClusterName }}/argocd-apps/cluster-autoscaler.values.yaml
- repoURL: {{ .KubeaidConfigForkURL }}
targetRevision: HEAD
ref: values
project: default
syncPolicy:
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
4 changes: 2 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ type (
ControlPlaneAMI string `yaml:"controlPlaneAMI" validate:"required"`
ControlPlaneReplicas int `yaml:"controlPlaneReplicas" validate:"required"`

MachinePools []AWSMachinePool `yaml:"machinePools"`
NodeGroups []NodeGroups `yaml:"nodeGroups"`
}

AWSMachinePool struct {
NodeGroups struct {
Name string `yaml:"name" validate:"required"`
Replicas int `yaml:"replicas" validate:"required"`
InstanceType string `yaml:"instanceType" validate:"required"`
Expand Down
4 changes: 3 additions & 1 deletion config/templates/aws.sample.config.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ cloud:
controlPlaneAMI: {{ .AMI }}
controlPlaneReplicas: 1

machinePools:
nodeGroups:
- name: primary
ami:
id: {{ .AMI }}
Expand All @@ -42,6 +42,8 @@ cloud:
# REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine
# labels: []

# taints []

monitoring:
kubePrometheusVersion: v0.14.0
grafanaURL: ""
Expand Down
34 changes: 17 additions & 17 deletions config/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
)

var (
// A user defined MachinePool label key should belong to one of these domains.
// A user defined NodeGroup label key should belong to one of these domains.
// REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
ValidMachinePoolLabelDomains = []string{
ValidNodeGroupLabelDomains = []string{
"node.cluster.x-k8s.io/",
"node-role.kubernetes.io/",
"node-restriction.kubernetes.io/",
Expand All @@ -23,7 +23,7 @@ var (

// Validates the parsed config.
// Panics on failure.
// TODO : Extract the MachinePool labels and taints validation task from 'cloud specifics' section.
// TODO : Extract the NodeGroup labels and taints validation task from 'cloud specifics' section.
func validateConfig(config *Config) {
// Validate based on struct tags.
validate := validator.New(validator.WithRequiredStructEnabled())
Expand All @@ -35,38 +35,38 @@ func validateConfig(config *Config) {
switch {
case config.Cloud.AWS != nil:

for _, machinePool := range config.Cloud.AWS.MachinePools {
// Validate MachinePools labels.
for _, nodeGroup := range config.Cloud.AWS.NodeGroups {
// Validate NodeGroups labels.
//
// (1) according to Kubernetes specifications.
if err := labels.Validate(machinePool.Labels); err != nil {
log.Fatalf("MachinePool labels validation failed : %v", err)
if err := labels.Validate(nodeGroup.Labels); err != nil {
log.Fatalf("NodeGroup labels validation failed : %v", err)
}
//
// (2) according to ClusterAPI specifications.
for key := range machinePool.Labels {
for key := range nodeGroup.Labels {
// Check if the label belongs to a domain considered valid by ClusterAPI.
isValidMachinePoolLabelDomain := false
for _, machinePoolLabelDomains := range ValidMachinePoolLabelDomains {
if strings.HasPrefix(key, machinePoolLabelDomains) {
isValidMachinePoolLabelDomain = true
isValidNodeGroupLabelDomain := false
for _, nodeGroupLabelDomains := range ValidNodeGroupLabelDomains {
if strings.HasPrefix(key, nodeGroupLabelDomains) {
isValidNodeGroupLabelDomain = true
break
}
}
if !isValidMachinePoolLabelDomain {
slog.Error("MachinePool label key should belong to one of these domains", slog.Any("domains", ValidMachinePoolLabelDomains))
if !isValidNodeGroupLabelDomain {
slog.Error("NodeGroup label key should belong to one of these domains", slog.Any("domains", ValidNodeGroupLabelDomains))
os.Exit(1)
}
}

taintsAsKVPairs := map[string]string{}
for _, taint := range machinePool.Taints {
for _, taint := range nodeGroup.Taints {
taintsAsKVPairs[taint.Key] = fmt.Sprintf("%s:%s", taint.Value, taint.Effect)
}
//
// Validate MachinePool taints.
// Validate NodeGroup taints.
if err := labels.ValidateTaints(taintsAsKVPairs); err != nil {
log.Fatalf("MachinePool taint validation failed : %v", err)
log.Fatalf("NodeGroup taint validation failed : %v", err)
}
}

Expand Down
4 changes: 4 additions & 0 deletions constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ var (
"argocd-apps/templates/cluster-api.app.yaml.tmpl",
"argocd-apps/cluster-api.values.yaml.tmpl",

// Cluster Autoscaler.
"argocd-apps/templates/cluster-autoscaler.app.yaml.tmpl",
"argocd-apps/cluster-autoscaler.values.yaml.tmpl",

// Traefik.
"argocd-apps/templates/traefik.app.yaml.tmpl",
"argocd-apps/traefik.values.yaml.tmpl",
Expand Down

0 comments on commit d6927be

Please sign in to comment.