Closed6
karpenterをEKSで動かす
terraform
# karpenter
module "karpenter" {
source = "terraform-aws-modules/eks/aws//modules/karpenter"
cluster_name = aws_eks_cluster.main.name
enable_irsa = true
irsa_namespace_service_accounts = [ "kube-system:karpenter" ]
irsa_oidc_provider_arn = aws_iam_openid_connect_provider.main.arn
# iam policy name
iam_policy_name = "KarpenterController"
iam_policy_use_name_prefix = false
# controller iam role name
iam_role_name = "KarpenterController"
iam_role_use_name_prefix = false
# node iam role name
node_iam_role_name = "KarpenterNode"
node_iam_role_use_name_prefix = false
tags = {
ManagedBy = "karpenter"
}
}
helmfile
helmfile.yaml
repositories:
- name: karpenter
url: public.ecr.aws/karpenter
oci: true
releases:
- name: karpenter
namespace: kube-system
chart: karpenter/karpenter
version: 0.37.5
values:
- ./values.yaml
oci: true
がないと
ERROR:
exit status 1
EXIT STATUS
1
STDERR:
Error: could not find protocol handler for:
COMBINED OUTPUT:
Error: could not find protocol handler for:
エラーを吐く
values.yaml
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxxxxxxxx:role/KarpenterController
settings:
clusterName: <cluster name>
replicas: 1
メモ
- 検証で1ノードのみ立ち上げているため
replicas: 1
とする。デフォルトの2podだとaffinityでひっかかる
nodepool
調達するインスタンスのスペックや、karpenterの挙動を管理するカスタムリソース
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: kubernetes.io/os
operator: In
values: ["linux"]
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
- key: "karpenter.k8s.aws/instance-cpu"
operator: In
values: ["2", "4"]
- key: "karpenter.k8s.aws/instance-hypervisor"
operator: In
values: ["nitro"]
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ["2"]
nodeClassRef:
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
name: default
limits:
cpu: "16"
memory: 32Gi
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: 720h
-
spec.templates.spec.requirements
で調達したいインスタンスを指定- コスト下げるためspotを利用
-
nodeClassRef
でnodeclass(後述)を指定 -
limits
でkarpenterによるスケール上限を指定。↑の場合cpuの合計が16,memの合計が32GiBを超えると新たなノードを調達しない - disruptionでノードの中断処理を設定
karpenterの設定については以下がわかりやすい
nodeclass
karpenterが調達したノードをどこに配置するか、どのセキュリティグループを使うか、などを定義するカスタムリソース
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
role: "KarpenterNode"
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "test-cluster"
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: "test-cluster"
tags:
Name: karpenter-node
-
karpenter.sh/discovery: "test-cluster"
のタグがついたサブネット/SGを利用する - 起動したノードのNameタグは
karpenter-node
となる
動作確認
getting startedのこれをパクる
$ k apply -f deployment.yaml -n default
$ kubectl scale deployment inflate --replicas 5
ノードが増えればOK
karpenterが用意したノードにはkarpenter.sh/registered
キーのラベルが作成されるため、それでgetします。
$ kubectl get nodes -o custom-columns=NAME:.metadata.name,REGISTERED:.metadata.labels.karpenter\\.sh/registered
NAME REGISTERED
ip-10-0-1-123.ap-northeast-1.compute.internal <none>
ip-10-0-2-152.ap-northeast-1.compute.internal true
ip-10-0-2-72.ap-northeast-1.compute.internal true
無事用意出来ています。
ノードの中断も確認します
$ kubectl scale deployment inflate --replicas 0
$ kubectl get nodes -o custom-columns=NAME:.metadata.name,REGISTERED:.metadata.labels.karpenter\\.sh/registered
NAME REGISTERED
ip-10-0-1-123.ap-northeast-1.compute.internal <none>
片付いています
このスクラップは1ヶ月前にクローズされました