autoscale aws node groups (#62)

This commit is contained in:
David Dollar 2019-12-31 09:36:50 -05:00 committed by GitHub
parent f51ebd5c0b
commit 964ade629a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 304 additions and 1 deletions

View File

@ -0,0 +1,298 @@
data "aws_iam_policy_document" "assume_autoscaler" {
statement {
actions = ["sts:AssumeRoleWithWebIdentity"]
effect = "Allow"
condition {
test = "StringEquals"
variable = local.oidc_sub
values = ["system:serviceaccount:kube-system:cluster-autoscaler"]
}
principals {
identifiers = [aws_iam_openid_connect_provider.cluster.arn]
type = "Federated"
}
}
}
resource "aws_iam_role" "autoscaler" {
name = "${var.name}-autoscaler"
assume_role_policy = data.aws_iam_policy_document.assume_autoscaler.json
path = "/convox/"
tags = local.tags
}
data "aws_iam_policy_document" "autoscale" {
statement {
actions = [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeTags",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"ec2:DescribeLaunchTemplateVersions",
]
effect = "Allow"
resources = ["*"]
}
}
resource "aws_iam_role_policy" "autoscaler_autoscale" {
name = "autoscale"
role = aws_iam_role.autoscaler.name
policy = data.aws_iam_policy_document.autoscale.json
}
locals {
autoscaler_labels = {
"k8s-addon" : "cluster-autoscaler.addons.k8s.io",
"k8s-app" : "cluster-autoscaler",
}
}
resource "kubernetes_service_account" "autoscaler" {
metadata {
name = "cluster-autoscaler"
namespace = "kube-system"
labels = local.autoscaler_labels
annotations = {
"eks.amazonaws.com/role-arn" : aws_iam_role.autoscaler.arn,
}
}
}
resource "kubernetes_cluster_role" "autoscaler" {
metadata {
name = "cluster-autoscaler"
labels = local.autoscaler_labels
}
rule {
api_groups = [""]
resources = ["events", "endpoints"]
verbs = ["create", "patch"]
}
rule {
api_groups = [""]
resources = ["pods/eviction"]
verbs = ["create"]
}
rule {
api_groups = [""]
resources = ["pods/status"]
verbs = ["update"]
}
rule {
api_groups = [""]
resources = ["endpoints"]
resource_names = ["cluster-autoscaler"]
verbs = ["get", "update"]
}
rule {
api_groups = [""]
resources = ["nodes"]
verbs = ["watch", "list", "get", "update"]
}
rule {
api_groups = [""]
resources = ["pods", "services", "replicationcontrollers", "persistentvolumeclaims", "persistentvolumes"]
verbs = ["watch", "list", "get"]
}
rule {
api_groups = ["extensions"]
resources = ["replicasets", "daemonsets"]
verbs = ["watch", "list", "get"]
}
rule {
api_groups = ["policy"]
resources = ["poddisruptionbudgets"]
verbs = ["watch", "list"]
}
rule {
api_groups = ["apps"]
resources = ["statefulsets", "replicasets", "daemonsets"]
verbs = ["watch", "list", "get"]
}
rule {
api_groups = ["storage.k8s.io"]
resources = ["storageclasses", "csinodes"]
verbs = ["watch", "list", "get"]
}
rule {
api_groups = ["batch", "extensions"]
resources = ["jobs"]
verbs = ["get", "list", "watch", "patch"]
}
rule {
api_groups = ["coordination.k8s.io"]
resources = ["leases"]
verbs = ["create"]
}
rule {
api_groups = ["coordination.k8s.io"]
resources = ["leases"]
resource_names = ["cluster-autoscaler"]
verbs = ["get", "update"]
}
}
resource "kubernetes_cluster_role_binding" "autoscaler" {
metadata {
name = "cluster-autoscaler"
labels = local.autoscaler_labels
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "cluster-autoscaler"
}
subject {
kind = "ServiceAccount"
name = "cluster-autoscaler"
namespace = "kube-system"
}
}
resource "kubernetes_role" "autoscaler" {
metadata {
name = "cluster-autoscaler"
namespace = "kube-system"
labels = local.autoscaler_labels
}
rule {
api_groups = [""]
resources = ["configmaps"]
verbs = ["create", "list", "watch"]
}
rule {
api_groups = [""]
resources = ["configmaps"]
resource_names = ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
verbs = ["delete", "get", "update", "watch"]
}
}
resource "kubernetes_role_binding" "autoscaler" {
metadata {
name = "cluster-autoscaler"
namespace = "kube-system"
labels = local.autoscaler_labels
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "Role"
name = "cluster-autoscaler"
}
subject {
kind = "ServiceAccount"
name = "cluster-autoscaler"
namespace = "kube-system"
}
}
resource "kubernetes_deployment" "autoscaler" {
depends_on = [aws_iam_role_policy.autoscaler_autoscale]
metadata {
name = "cluster-autoscaler"
namespace = "kube-system"
labels = {
"app" : "cluster-autoscaler"
}
}
spec {
replicas = 1
selector {
match_labels = {
"app" : "cluster-autoscaler"
}
}
template {
metadata {
labels = {
"app" : "cluster-autoscaler"
}
annotations = {
"cluster-autoscaler.kubernetes.io/safe-to-evict" : "false",
"prometheus.io/scrape" : "true",
"prometheus.io/port" : "8085"
}
}
spec {
automount_service_account_token = true
service_account_name = "cluster-autoscaler"
container {
image = "k8s.gcr.io/cluster-autoscaler:v1.14.7"
image_pull_policy = "Always"
name = "cluster-autoscaler"
command = [
"./cluster-autoscaler",
"--v=4",
"--stderrthreshold=info",
"--cloud-provider=aws",
"--skip-nodes-with-local-storage=false",
"--expander=least-waste",
"--node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/${aws_eks_cluster.cluster.name}",
"--balance-similar-node-groups",
"--skip-nodes-with-system-pods=false",
]
resources {
limits {
cpu = "100m"
memory = "300Mi"
}
requests {
cpu = "100m"
memory = "300Mi"
}
}
volume_mount {
name = "ssl-certs"
mount_path = "/etc/ssl/certs/ca-certificates.crt"
read_only = "true"
}
}
volume {
name = "ssl-certs"
host_path {
path = "/etc/ssl/certs/ca-bundle.crt"
}
}
}
}
}
}

View File

@ -14,6 +14,10 @@ provider "null" {
version = "~> 2.1"
}
locals {
oidc_sub = "${replace(aws_iam_openid_connect_provider.cluster.url, "https://", "")}:sub"
}
resource "null_resource" "delay_cluster" {
provisioner "local-exec" {
command = "sleep 15"
@ -75,6 +79,7 @@ resource "aws_eks_node_group" "cluster" {
lifecycle {
create_before_destroy = true
ignore_changes = [scaling_config[0].desired_size]
}
}

View File

@ -20,5 +20,5 @@ output "oidc_arn" {
output "oidc_sub" {
depends_on = [aws_eks_node_group.cluster]
value = "${replace(aws_iam_openid_connect_provider.cluster.url, "https://", "")}:sub"
value = local.oidc_sub
}