EKS의 Auto Scaling 노드 및 포드
kubernetes를 자동 확장하려면 어떤 옵션이 있나요?
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 클러스터에서 사용할 수 있습니다.)
Auto Scaling 그룹은 자동 검색될 수 있도록 합니다.
k8s.io/cluster-autoscaler/enabled=true
k8s.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
이러한 자동 크기 조정 옵션을 현명하게 사용하여 더 많은 비용을 절약할 수 있습니다. :-)
Reference
이 문제에 관하여(EKS의 Auto Scaling 노드 및 포드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/chathra222/auto-scaling-nodes-and-pods-in-eks-alk
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
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" {
}
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"]
}
}
}
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"
}
terraform init
terraform apply
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
kubectl get deploy -n kube-system cluster-autoscaler-aws-cluster-autoscaler -o yaml|grep -i serviceAccountName
serviceAccountName: 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>
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
Reference
이 문제에 관하여(EKS의 Auto Scaling 노드 및 포드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/chathra222/auto-scaling-nodes-and-pods-in-eks-alk텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)