diff --git a/cmd/bootstrap_cluster/bootstrap_cluster.go b/cmd/bootstrap_cluster/bootstrap_cluster.go index 779d254..3b09508 100644 --- a/cmd/bootstrap_cluster/bootstrap_cluster.go +++ b/cmd/bootstrap_cluster/bootstrap_cluster.go @@ -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)) diff --git a/cmd/bootstrap_cluster/templates/argocd-apps/capi-cluster.values.yaml.tmpl b/cmd/bootstrap_cluster/templates/argocd-apps/capi-cluster.values.yaml.tmpl index c06f549..c4d5f95 100644 --- a/cmd/bootstrap_cluster/templates/argocd-apps/capi-cluster.values.yaml.tmpl +++ b/cmd/bootstrap_cluster/templates/argocd-apps/capi-cluster.values.yaml.tmpl @@ -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: @@ -36,5 +31,5 @@ aws: instanceType: {{ .ControlPlaneInstanceType }} ami: id: {{ .ControlPlaneAMI }} - machinePools: -{{ .MachinePools | toYaml | indent 2 }} + nodeGroups: +{{ .NodeGroups | toYaml | indent 2 }} diff --git a/cmd/bootstrap_cluster/templates/argocd-apps/cluster-autoscaler.values.yaml.tmpl b/cmd/bootstrap_cluster/templates/argocd-apps/cluster-autoscaler.values.yaml.tmpl new file mode 100644 index 0000000..5b44f34 --- /dev/null +++ b/cmd/bootstrap_cluster/templates/argocd-apps/cluster-autoscaler.values.yaml.tmpl @@ -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 }} diff --git a/cmd/bootstrap_cluster/templates/argocd-apps/templates/cluster-autoscaler.yaml.tmpl b/cmd/bootstrap_cluster/templates/argocd-apps/templates/cluster-autoscaler.yaml.tmpl new file mode 100644 index 0000000..44a0558 --- /dev/null +++ b/cmd/bootstrap_cluster/templates/argocd-apps/templates/cluster-autoscaler.yaml.tmpl @@ -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 diff --git a/config/config.go b/config/config.go index 03cb3a2..4acd588 100644 --- a/config/config.go +++ b/config/config.go @@ -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"` diff --git a/config/templates/aws.sample.config.yaml.tmpl b/config/templates/aws.sample.config.yaml.tmpl index bb7337a..2d9392b 100644 --- a/config/templates/aws.sample.config.yaml.tmpl +++ b/config/templates/aws.sample.config.yaml.tmpl @@ -22,7 +22,7 @@ cloud: controlPlaneAMI: {{ .AMI }} controlPlaneReplicas: 1 - machinePools: + nodeGroups: - name: primary ami: id: {{ .AMI }} @@ -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: "" diff --git a/config/validate.go b/config/validate.go index 8e146fc..0451dde 100644 --- a/config/validate.go +++ b/config/validate.go @@ -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/", @@ -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()) @@ -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) } } diff --git a/constants/constants.go b/constants/constants.go index d92e7c4..6a7f7d8 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -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",