EKS의 Auto Scaling 노드 및 포드

14041 단어

kubernetes를 자동 확장하려면 어떤 옵션이 있나요?


  • 클러스터 자동 크기 조정기 ---> 노드 크기 조정
  • HPA ---> 리소스의 CPU 사용률에 따라 배포/복제 세트를 확장하거나 축소합니다
  • .
  • VPA ---> 포드에 대한 CPU 및 메모리 예약을 자동으로 조정합니다
  • .

    Kubernetes Cluster Autoscaler란 무엇입니까?


  • 현재 요구 사항을 충족하도록 Kubernetes 클러스터의 크기(노드 확장 및 축소)를 조정합니다.
  • 주요 클라우드 플랫폼에서 지원됨
  • Cluster Autoscaler는 일반적으로 클러스터에서 배포로 실행됩니다.

  • Kubernetes Cluster Autoscaler는 어떻게 작동합니까?



    Cluster AutoScaler는 정기적으로 노드 및 포드의 상태를 확인하고 노드 사용량 또는 포드 스케줄링 상태에 따라 조치를 취합니다.
    Cluster Autoscaler가 클러스터에서 보류 중인 Pod를 찾으면 대기 중인 Pod가 예약되거나 클러스터가 최대 노드 제한을 초과할 때까지 노드를 추가합니다.
    노드 사용률이 낮으면 Cluster Autoscaler가 초과 노드를 제거하고 Pod를 다른 노드로 전송할 수 있습니다.
    따라서 이것은 기반 CPU 또는 메모리 사용률이 아닙니다.

    Kubernetes 클러스터에 Cluster Autoscaler를 배포하기 전에 갖추어야 할 사항은 무엇입니까?



  • 클러스터의 IAM OIDC 제공자.

    왜요?



    Cluster Autoscaler는 노드를 확장하거나 축소하려면 AWS 권한이 필요합니다. 이 권한은 서비스 계정의 IAM 역할을 통해 부여됩니다. 서비스 계정에 대한 IAM 역할을 지원하려면 클러스터에 OIDC URL이 있어야 합니다.(서비스 계정에 대한 IAM 역할 기능은 Amazon EKS 버전 1.14 이상 및 EKS 클러스터에서 사용할 수 있습니다.)
  • Cluster Autoscaler에는 다음 태그가 필요합니다.
    Auto Scaling 그룹은 자동 검색될 수 있도록 합니다.k8s.io/cluster-autoscaler/enabled=truek8s.io/cluster-autoscaler/<cluster-name>=owned

  • 데모



    Terraform 방식으로 클러스터 자동 확장을 사용하여 EKS 클러스터를 생성해 보겠습니다.

    1) Terraform을 사용하여 EKS 클러스터를 생성합니다.

    
    locals {
      name            = "eks-scalable-cluster"
      cluster_version = "1.20"
      region          = "ap-southeast-1"
    }
    
    ###############
    # EKS Module
    ###############
    
    module "eks" {
      source = "terraform-aws-modules/eks/aws"
    
      cluster_name    = local.name
      cluster_version = local.cluster_version
    
      vpc_id  = module.vpc.vpc_id
      subnets = module.vpc.private_subnets
    
      cluster_endpoint_private_access = true
      cluster_endpoint_public_access  = true
    
      enable_irsa = true
    
      worker_groups = [
        {
          name                 = "worker-group-1"
          instance_type        = "t3.medium"
          asg_desired_capacity = 1
          asg_max_size         = 4
          #Cluster autoscaler Auto-Discovery Setup
          #https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#auto-discovery-setup
          tags = [
            {
              "key"                 = "k8s.io/cluster-autoscaler/enabled"
              "propagate_at_launch" = "false"
              "value"               = "true"
            },
            {
              "key"                 = "k8s.io/cluster-autoscaler/${local.name}"
              "propagate_at_launch" = "false"
              "value"               = "owned"
            }
          ]
        }
      ]
      tags = {
        clustername = local.name
      }
    }
    
    
    data "aws_eks_cluster" "cluster" {
      name = module.eks.cluster_id
    }
    
    data "aws_eks_cluster_auth" "cluster" {
      name = module.eks.cluster_id
    }
    
    data "aws_availability_zones" "available" {
    }
    
    
    


    2) OpenID Connect Federated Users를 사용하여 신뢰할 수 있는 리소스가 맡을 수 있는 IAM 역할을 생성합니다(클러스터 자동 확장자는 이러한 권한을 사용하여 자동 확장, ec2와 같은 AWS 서비스에 액세스함).

    data "aws_caller_identity" "current" {}
    
    data "aws_region" "current" {}
    
    locals {
      k8s_service_account_namespace = "kube-system"
      k8s_service_account_name      = "cluster-autoscaler-aws"
    }
    
    
    module "iam_assumable_role_admin" {
      #Creates a single IAM role which can be assumed by trusted resources using OpenID Connect Federated Users.
      source  = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
      version = "~> 4.0"
    
      create_role                   = true
      role_name                     = "cluster-autoscaler"
      provider_url                  = replace(module.eks.cluster_oidc_issuer_url, "https://", "")
      role_policy_arns              = [aws_iam_policy.cluster_autoscaler.arn]
      oidc_fully_qualified_subjects = ["system:serviceaccount:${local.k8s_service_account_namespace}:${local.k8s_service_account_name}"]
    }
    
    resource "aws_iam_policy" "cluster_autoscaler" {
      name_prefix = "cluster-autoscaler"
      description = "EKS cluster-autoscaler policy for cluster ${module.eks.cluster_id}"
      policy      = data.aws_iam_policy_document.cluster_autoscaler.json
    }
    
    data "aws_iam_policy_document" "cluster_autoscaler" {
      statement {
        sid    = "clusterAutoscalerAll"
        effect = "Allow"
    
        actions = [
          "autoscaling:DescribeAutoScalingGroups",
          "autoscaling:DescribeAutoScalingInstances",
          "autoscaling:DescribeLaunchConfigurations",
          "autoscaling:DescribeTags",
          "ec2:DescribeLaunchTemplateVersions",
        ]
    
        resources = ["*"]
      }
    
      statement {
        sid    = "clusterAutoscalerOwn"
        effect = "Allow"
    
        actions = [
          "autoscaling:SetDesiredCapacity",
          "autoscaling:TerminateInstanceInAutoScalingGroup",
          "autoscaling:UpdateAutoScalingGroup",
        ]
    
        resources = ["*"]
    
        condition {
          test     = "StringEquals"
          variable = "autoscaling:ResourceTag/k8s.io/cluster-autoscaler/${module.eks.cluster_id}"
          values   = ["owned"]
        }
    
        condition {
          test     = "StringEquals"
          variable = "autoscaling:ResourceTag/k8s.io/cluster-autoscaler/enabled"
          values   = ["true"]
        }
      }
    }
    


    3) helm 차트를 사용하여 클러스터 자동 확장기 설치

    resource "helm_release" "cluster-autoscaler" {
      depends_on = [
        module.eks
      ]
    
      name             = "cluster-autoscaler"
      namespace        = local.k8s_service_account_namespace
      repository       = "https://kubernetes.github.io/autoscaler"
      chart            = "cluster-autoscaler"
      version          = "9.10.7"
      create_namespace = false
    
      set {
        name  = "awsRegion"
        value = data.aws_region.current.name
      }
      set {
        name  = "rbac.serviceAccount.name"
        value = local.k8s_service_account_name
      }
      set {
        name  = "rbac.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn"
        value = module.iam_assumable_role_admin.iam_role_arn
        type  = "string"
      }
      set {
        name  = "autoDiscovery.clusterName"
        value = local.name
      }
      set {
        name  = "autoDiscovery.enabled"
        value = "true"
      }
      set {
        name  = "rbac.create"
        value = "true"
      }
    }
    


    Note:-
    Make sure your public and private subnets properly tagged which enables automatic subnet discovery so Kubernetes Cloud Controller Manager (cloud-controller-manager) and AWS Load Balancer Controller (aws-load-balancer-controller) can identify which subnets going to use for provisioning a ELB when creating Loadbalancer type Service. If you creating the VPC and Subnets from scratch you may use vpc.tf . Otherwise you can tag you subnets accordingly.



      public_subnet_tags = {
        "kubernetes.io/cluster/${local.name}" = "shared"
        "kubernetes.io/role/elb"              = "1"
      }
    
      private_subnet_tags = {
        "kubernetes.io/cluster/${local.name}" = "shared"
        "kubernetes.io/role/internal-elb"     = "1"
      }
    


    https://github.com/chathra222/tf-eks-autoscaling에서 내 코드를 찾을 수 있습니다.

    terraform을 사용하여 모든 리소스 배포

    terraform init
    terraform apply
    


    적용되면 AWS 관리 콘솔에서도 확인할 수 있습니다.



    어떤 Kubernetes 리소스가 프로비저닝되었는지 알아보겠습니다.




    kubectl get deploy -n kube-system
    NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
    cluster-autoscaler-aws-cluster-autoscaler   1/1     1            1           8h
    coredns                                     2/2     2            2           8h
    


    보시다시피 cluster-autoscaler-aws-cluster-autoscaler 네임스페이스에 kube-system라는 배포가 있습니다.

    kubectl get deploy -n kube-system cluster-autoscaler-aws-cluster-autoscaler -o yaml|grep -i serviceAccountName
          serviceAccountName: cluster-autoscaler-aws
    


    서비스 계정을 조사해 보겠습니다cluster-autoscaler-aws.

    kubectl describe sa cluster-autoscaler-aws
    Name:                cluster-autoscaler-aws
    Namespace:           kube-system
    Labels:              app.kubernetes.io/instance=cluster-autoscaler
                         app.kubernetes.io/managed-by=Helm
                         app.kubernetes.io/name=aws-cluster-autoscaler
                         helm.sh/chart=cluster-autoscaler-9.10.7
    Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::272435851616:role/cluster-autoscaler
                         meta.helm.sh/release-name: cluster-autoscaler
                         meta.helm.sh/release-namespace: kube-system
    Image pull secrets:  <none>
    Mountable secrets:   cluster-autoscaler-aws-token-x7ds6
    Tokens:              cluster-autoscaler-aws-token-x7ds6
    Events:              <none>
    


    이 서비스 계정이 역할eks.amazonaws.com/role-arn: arn:aws:iam::272435851616:role/cluster-autoscaler을 맡을 수 있다는 주석arn:aws:iam::272435851616:role/cluster-autoscaler을 볼 수 있습니다.

    Let's discover cluster-autoscaler 배포

    kubectl get deploy -o yaml cluster-autoscaler-aws-cluster-autoscaler
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
        deployment.kubernetes.io/revision: "1"
        meta.helm.sh/release-name: cluster-autoscaler
        meta.helm.sh/release-namespace: kube-system
      creationTimestamp: "2021-11-07T01:10:29Z"
      generation: 1
      labels:
        app.kubernetes.io/instance: cluster-autoscaler
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/name: aws-cluster-autoscaler
        helm.sh/chart: cluster-autoscaler-9.10.7
      name: cluster-autoscaler-aws-cluster-autoscaler
      namespace: kube-system
      resourceVersion: "1292"
      uid: 9f0f7f3f-adfd-422f-a007-7c1aa20deb4e
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app.kubernetes.io/instance: cluster-autoscaler
          app.kubernetes.io/name: aws-cluster-autoscaler
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          creationTimestamp: null
          labels:
            app.kubernetes.io/instance: cluster-autoscaler
            app.kubernetes.io/name: aws-cluster-autoscaler
        spec:
          containers:
          - command:
            - ./cluster-autoscaler
            - --cloud-provider=aws
            - --namespace=kube-system
            - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/eks-scalable-cluster
            - --logtostderr=true
            - --stderrthreshold=info
            - --v=4
            env:
            - name: AWS_REGION
              value: ap-southeast-1
            image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.21.0
            imagePullPolicy: IfNotPresent
            livenessProbe:
              failureThreshold: 3
              httpGet:
                path: /health-check
                port: 8085
                scheme: HTTP
              periodSeconds: 10
              successThreshold: 1
              timeoutSeconds: 1
            name: aws-cluster-autoscaler
            ports:
            - containerPort: 8085
              protocol: TCP
            resources: {}
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          serviceAccount: cluster-autoscaler-aws
          serviceAccountName: cluster-autoscaler-aws
          terminationGracePeriodSeconds: 30
    status:
      availableReplicas: 1
      conditions:
      - lastTransitionTime: "2021-11-07T01:11:42Z"
        lastUpdateTime: "2021-11-07T01:11:42Z"
        message: Deployment has minimum availability.
        reason: MinimumReplicasAvailable
        status: "True"
        type: Available
      - lastTransitionTime: "2021-11-07T01:10:29Z"
        lastUpdateTime: "2021-11-07T01:11:42Z"
        message: ReplicaSet "cluster-autoscaler-aws-cluster-autoscaler-74977bcc47" has
          successfully progressed.
        reason: NewReplicaSetAvailable
        status: "True"
        type: Progressing
      observedGeneration: 1
      readyReplicas: 1
      replicas: 1
      updatedReplicas: 1
    
    

    cluster-autoscaler 에 대한 다양한 매개변수가 있습니다. 필요에 따라 사용자 정의하려면 https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-are-the-parameters-to-ca을 참조하십시오.

    이 링크는 클러스터 오토스케일러에 대해 더 자세히 알고 싶다면 정말 좋습니다.
    https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md

    이러한 자동 크기 조정 옵션을 현명하게 사용하여 더 많은 비용을 절약할 수 있습니다. :-)

    좋은 웹페이지 즐겨찾기