Contenu connexe
Similaire à Karpenterで君だけの最強のオートスケーリングを実装しよう (20)
Karpenterで君だけの最強のオートスケーリングを実装しよう
- 2. © 2021 3-shake Inc. 2
自己紹介
- 株式会社スリーシェイク Sreake事業部
- 業務: SREとしてインフラ扱ったり、コード読み書きしたり
- Kubernetes周辺は個人的趣味もあり興味持って触っています
- 雪がどっぷり降る地域に住んでいます
- 趣味: 料理、お酒
永瀬滉平
- 3. © 2021 3-shake Inc. 3
今回のテーマは
自動化ツール
クラスター”オート”スケーラー
k8sのノード管理を”自動化”するKarpenterと
いうツールについてのお話しです
- 4. © 2021 3-shake Inc. 4
Karpenter is
オープンソースのクラスターオートスケーラーです。
目的はCluster Autoscalerと同様で、k8sのノードが足りなくなったら足して、不
要になったら削除するというのを実現します。
【特徴】
- 柔軟なリソース選択
- スケジュールできないpod全体でどれだけリソースが必要なのかを計算した上で、
最適なインスタンスタイプをその都度選択してくれます
- ASGのようなノードグループを使わず、Karpenterによってノードの選定・起動・削除が行われます
参照:https://karpenter.sh/
- 6. © 2021 3-shake Inc. 6
Karpenter is
$ k get all -n karpenter
NAME READY STATUS RESTARTS AGE
pod/karpenter-7c4bd8bdd7-7mcvt 2/2 Running 0 2d21h
pod/karpenter-7c4bd8bdd7-b585k 2/2 Running 0 2d11h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/karpenter ClusterIP 172.20.30.137 <none> 8080/TCP,443/TCP 13d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/karpenter 2/2 2 2 13d
NAME DESIRED CURRENT READY AGE
replicaset.apps/karpenter-7c4bd8bdd7 2 2 2 13d
$ k get crd | grep karpenter
awsnodetemplates.karpenter.k8s.aws 2022-07-21T07:39:07Z
provisioners.karpenter.sh 2022-07-21T07:39:07Z
$ k get mutatingwebhookconfigurations.admissionregistration.k8s.io | grep karpenter
defaulting.webhook.provisioners.karpenter.sh 1 13d
$ k get validatingwebhookconfigurations.admissionregistration.k8s.io | grep karpenter
validation.webhook.config.karpenter.sh 1 13d
validation.webhook.provisioners.karpenter.sh 1 13d
karpenterのPodには2つのコンテナが含まれている
- webhook: カスタムリソースの変更を検知・検証
- controller: ノード追加・削除などの処理を実施
CRD
- awsnodetemplates: ノードを追加する際に使用する
テンプレートを設定する際に使用
- provisioners: ノードの管理にあたって設定する際に
使用
- 7. © 2021 3-shake Inc. 7
Karpenter is
karpenterのミソとなるCustom Resourceである、Provisioner
ノード管理に関する設定を行うリソースです。
例えば以下のような設定ができます
- ノードに付与するラベル、taints
- インスタンスタイプの指定
- ノードのTTL指定
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: app1
spec:
labels:
workload: "app1"
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: [ "spot" ]
- key: "node.kubernetes.io/instance-type"
operator: NotIn
values: [ "m6g.16xlarge", "m6gd.16xlarge", "r6g.16xlarge", "r6gd.16xlarge" ]
limits:
resources:
cpu: 50
memory: 500Gi
provider:
subnetSelector:
karpenter.sh/discovery: "cluster-name"
securityGroupSelector:
karpenter.sh/discovery: "cluster-name"
tags:
karpenter.sh/discovery: "cluster-name"
ttlSecondsAfterEmpty: 30
- 8. © 2021 3-shake Inc. 8
今回のトピックは
Karpenterを実運用していくにあたって、
「ここは押さえておこう」というポイントをお話しします
【目次】
1. nodeSelector, taints/tolerationsを使ってノードグループを分ける
1. KarpenterのアプリPodを分散配置する
1. 不必要・必要以上なインスタンスタイプを除外する
- 9. © 2021 3-shake Inc. 9
題材のマニフェスト
githubにあげていますので、適宜参照していただければと思います。
(よろしければ手元でもぜひ試してみてください)
リポジトリ: https://github.com/k-ngs/karpenter-test
- 10. © 2021 3-shake Inc. 10
- アプリの性質や可用性などによってPodを配置するノードを適切
に選択するため、Provisionerでlabelやtaintを付与します
- CAの場合だとノードグループを分けて対応していたものを
Provisioner(Kubernetesリソース)で実現します
※立ち上げようとするpodが複数のProvisionerに当てはまること
がないように設計します
その1 nodeSelector, taints/tolerationsを使ってノードグループを分ける
- 11. © 2021 3-shake Inc. 11
その1 nodeSelector, taints/tolerationsを使ってノードグループを分ける
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: app1
spec:
labels:
workload: "app1"
…
…
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1
spec:
…
spec:
nodeSelector:
workload: "app1"
…
…
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: app2
spec:
taints:
- key: workload
value: "app2"
operator: "Exists"
effect: NoSchedule
…
…
apiVersion: apps/v1
kind: Deployment
metadata:
name: app2
spec:
…
spec:
tolerations:
- key: "workload"
value: "app2"
effect: "NoSchedule"
…
nodeSelectorの例
taints/tolerationsの例
- 12. © 2021 3-shake Inc. 12
その1 nodeSelector, taintを使ってノードグループを分ける
Q.nodeSelectorやTolerationsなどの条件に合うProvisionerがない場合は?
A.ノード自体が追加されません
KarpenterがPod配置の関わる条件を読み取って、Provisionerとの照らし合
わせを行っています
↓ちなみにこんなログが出力されます。
ERROR controller.provisioning Could not schedule pod, incompatible with provisioner "default",
incompatible requirements, key workload, [application] not in [default]
{"commit": "062a029", "pod": "karpenter-test/karpenter-test-5d98488ddc-7nfgm"}
- 13. © 2021 3-shake Inc. 13
その2 KarpenterのアプリPodを分散配置する
- レプリカ数を増やし、AZなどを元に分散配置してある程度の可用性を確保する
- https://github.com/k-ngs/karpenter-test/blob/main/manifests/values.yaml#L16
- 公式のhelm chartでは↑のように、replicasという変数で設定できる
- デフォルトだとtopologySpreadConstraintsがtopology.kubernetes.io/zoneに設定されている
(AZでの分散配置)
Q.KarpenterのPodが配置されているノードが落ちた場合はどうなるの?
A.Podが落ちていることになるので、ノードの追加・削除が行われなくなります
- 14. © 2021 3-shake Inc. 14
その3 不必要・必要以上なインスタンスタイプを除外する
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: app-1
spec:
labels:
workload: "app-1"
requirements:
- key: "node.kubernetes.io/instance-type"
operator: NotIn
values: [ "m6g.16xlarge", "m6gd.16xlarge", "r6g.16xlarge", "r6gd.16xlarge" ]
…
Gravitonプロセッサ搭載の大きな
インスタンスを禁止する例
参照:https://aws.github.io/aws-eks-best-practices/karpenter/#exclude-instance-types-that-do-not-fit-your-workload
- Karpenterを使うメリットを最大限生かすため、ブラックリスト方式でインスタンスタイプをチョイス
するのが望ましいと考えます
- スポットインスタンスで運用する場合は可用性の観点から重要度が増します(望ましいインスタ
ンスタイプ確保ができない場合に代替となるインスタンスタイプがなくなるため)
- 15. © 2021 3-shake Inc. 15
まとめ
1. nodeSelector, taints/tolerationsを使ってノードグループを分ける
1. KarpenterのアプリPodを分散配置する
1. 不必要・必要以上なインスタンスタイプを除外する
インスタンスタイプをその都度柔軟に選択できるというのは、とても画期的でありクラウド
でKubernetesを使うという点で大きな意味があることだと思います。
ぜひこれを機にKarpenterを検証・導入して、
君だけの最強のクラスターオートスケーラーを実現しよう!
Notes de l'éditeur
- 今回のテーマが自動化ツールとのことでしたので、kubernetesのノード管理を自動化するKarpenterというツールについてお話しします。
- 目的は本家のCAと同様でkubernetesのノードが足りなくなったら足して、不要になったら削除します。
- PendingしているpodのなかでスケジュールできないpodをKarpenterが検知して、最適なノードをノードを
- 今回は題材となるマニフェストや設定例があります。
githubにあげていますので、適宜確認していただければと思います。
- nodeSelectorを用いて設定する例
- Karpenterの最も大きな特徴は必要なリソースに応じてダイナミックにノードを選択してくれることです。
ただし、Kubernetes上で動かすワークロードに適さないインスタンスをプロビジョニングされる可能性もありますので選択できるインスタンスタイプの幅をある程度制限してあげるようにしましょう。