############################################################ # Cluster Autoscaler para Hetzner Cloud + Talos # Escala workers automaticamente de 1 a 5 nodes ############################################################ --- apiVersion: v1 kind: Namespace metadata: name: cluster-autoscaler # Secret is created via install-autoscaler.sh (kubectl create secret) # to properly handle base64 encoding of cloud-init --- apiVersion: v1 kind: ServiceAccount metadata: name: cluster-autoscaler namespace: cluster-autoscaler --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-autoscaler rules: - apiGroups: [""] resources: ["events", "endpoints"] verbs: ["create", "patch"] - apiGroups: [""] resources: ["pods/eviction"] verbs: ["create"] - apiGroups: [""] resources: ["pods/status"] verbs: ["update"] - apiGroups: [""] resources: ["endpoints"] resourceNames: ["cluster-autoscaler"] verbs: ["get", "update"] - apiGroups: [""] resources: ["nodes"] verbs: ["watch", "list", "get", "update"] - apiGroups: [""] resources: ["namespaces", "pods", "services", "replicationcontrollers", "persistentvolumeclaims", "persistentvolumes"] verbs: ["watch", "list", "get"] - apiGroups: ["batch"] resources: ["jobs", "cronjobs"] verbs: ["watch", "list", "get"] - apiGroups: ["batch", "extensions"] resources: ["jobs"] verbs: ["get", "list", "patch", "watch"] - apiGroups: ["extensions"] resources: ["replicasets", "daemonsets"] verbs: ["watch", "list", "get"] - apiGroups: ["policy"] resources: ["poddisruptionbudgets"] verbs: ["watch", "list"] - apiGroups: ["apps"] resources: ["statefulsets", "replicasets", "daemonsets"] verbs: ["watch", "list", "get"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses", "csinodes", "csidrivers", "csistoragecapacities"] verbs: ["watch", "list", "get"] - apiGroups: ["coordination.k8s.io"] resources: ["leases"] verbs: ["create"] - apiGroups: ["coordination.k8s.io"] resources: ["leases"] resourceNames: ["cluster-autoscaler"] verbs: ["get", "update"] - apiGroups: [""] resources: ["configmaps"] verbs: ["create", "get", "update", "delete", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: cluster-autoscaler roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-autoscaler subjects: - kind: ServiceAccount name: cluster-autoscaler namespace: cluster-autoscaler --- apiVersion: apps/v1 kind: Deployment metadata: name: cluster-autoscaler namespace: cluster-autoscaler labels: app: cluster-autoscaler spec: replicas: 1 selector: matchLabels: app: cluster-autoscaler template: metadata: labels: app: cluster-autoscaler spec: serviceAccountName: cluster-autoscaler # Use host network to access external APIs (Hetzner) hostNetwork: true dnsPolicy: ClusterFirstWithHostNet # Workaround: Talos DNS proxy doesn't forward to upstream correctly hostAliases: - ip: "213.239.246.73" hostnames: - "api.hetzner.cloud" containers: - name: cluster-autoscaler image: registry.k8s.io/autoscaling/cluster-autoscaler:v1.31.0 command: - ./cluster-autoscaler - --cloud-provider=hetzner - --nodes=0:5:CAX11:nbg1:worker-pool - --nodes=0:0:CAX11:nbg1:draining-node-pool - --scale-down-enabled=true - --scale-down-delay-after-add=5m - --scale-down-unneeded-time=3m - --scale-down-utilization-threshold=0.5 - --skip-nodes-with-local-storage=false - --skip-nodes-with-system-pods=false - --balance-similar-node-groups=true - --v=4 env: - name: HCLOUD_TOKEN valueFrom: secretKeyRef: name: hcloud-autoscaler key: token - name: HCLOUD_CLOUD_INIT valueFrom: secretKeyRef: name: hcloud-autoscaler key: cloud-init - name: HCLOUD_IMAGE value: "${TALOS_IMAGE_ID}" - name: HCLOUD_NETWORK value: "${NETWORK_NAME}" - name: HCLOUD_FIREWALL value: "${FIREWALL_NAME}" - name: HCLOUD_SSH_KEY value: "${SSH_KEY_NAME}" resources: requests: cpu: 100m memory: 300Mi limits: cpu: 500m memory: 500Mi