こんにちは。SRE部の桝谷@hnchn87です。
この記事は、 Chatworkのカレンダー | Advent Calendar 2023 - Qiita の 9日目です。
2023年12月6日に行われた「耐障害性向上・パフォーマンス改善・運用負荷軽減をどう実現する? 事業を支えるSREのノウハウを共有」の中で「2023年度版!Chatwork流Kubernetesの運用方法」というタイトルでお話しをさせていただきました。
https://enechange-meetup.connpass.com/event/301585/
当日は時間の関係上、詳しくお話しできなかったので、発表資料を見ていただきつつ、補足情報をこちらに記載していこうと思います。
発表資料は以下を参照ください。
balloon✖️ClusterAutoScaler
balloon Podのmanifestは以下のような感じです。(簡略版)
apiVersion: apps/v1
kind: Deployment
metadata:
name: balloon
namespace: default
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node.chatwork.io/role
operator: In
values:
- worker
- key: topology.kubernetes.io/zone
operator: In
values:
- ap-northeast-1a
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/instance
operator: In
values:
- balloon
topologyKey: kubernetes.io/hostname
containers:
- image: 'registry.k8s.io/pause:3.9'
imagePullPolicy: IfNotPresent
name: balloon-pause
resources:
limits:
cpu: 100m
memory: 512Mi
requests:
cpu: 100m
memory: 512Mi
priorityClassName: low
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoSchedule
key: node.chatwork.io/role
operator: Equal
value: worker
registry.k8s.io/pauseというイメージを使用して、待機しておくだけのballoon Podを起動しています。
上記のmanifestは適当な値にしていますが、実際は「Chatwork」AppのPodの2.5倍のCPUリソースを確保して起動しています。
priorityClassName: "low"と指定しているのですが、弊社では独自にpriorityのlawを以下のように定義しています。
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: law value: -5 globalDefault: false
このようにvalueを-5に設定したpriorityを指定することによってballoon Podの優先度がその他のPodよりも下がるため、「Chatwork」AppのPodを起動するための余剰がNodeにない場合は、このballoon Podがkillされるようになります。
これによって、CAでNodeをスケールアウトする時間を待つことなくHPAによってPodをスケールアウトすることができ、サービスが不安定になることなくサービスの起動・停止ができるようにしています。
何でKarpenterを使わないのか
弊社では2022年に一度Karpenter(ver.0.5.0)を検証しました。
当時の大きな目的は以下の通りです。
- KubernetesにはCAという機能があるが、ノードがスケールアウトするまでに少し時間がかかってしまい、その期間サービスが不安定になってしまう
- AWSは提供するCAツールであるKarpenterがGAされたので良さそうなら導入したい
Karpenterの特徴は資料にも記載をしていますが、
- ASGを使用せずにEC2のAPIを直接実行することで起動する
- K8s Schedulerを使わずに起動したEC2にKarpernterがPodを配置する
これによって、CAのオーバーヘッドを少しでも減らして、Nodeの起動の時間だけに削減するという点です。
その代わりにEKSの設定をeksctl経由で行っている場合、launch templateに記載されているK8sの設定を全てKarpenterの設定に記載する必要があり、CAとは共存できないようになっています。
ということで、実際に検証をしてみました。
手順としては、
- インストール. 公式のGetting Startedを参照しつつ、helmで導入しました。
- provisionerの準備
Nodeの設定をprovisionerという名前のCustom Resourceで定義する必要があります。
複数定義することが可能で、AZを意識した構成になっている場合は以下のようにAZ毎に定義する必要があります。(簡略版)
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: karpenter-1a
spec:
ttlSecondsAfterEmpty: 30
labels:
node.karpenter.io/role: "worker"
node.karpenter.io/network: "private"
node.karpenter.io/purchaseType: "spot"
aws.amazon.com/purchaseType: "spot" # Requirements that constrain the parameters of provisioned nodes.
# These requirements are combined with pod.spec.affinity.nodeAffinity rules.
# Operators { In, NotIn } are supported to enable including or excluding values
requirements:
- key: "node.kubernetes.io/instance-type"
operator: In
values:
- t2.micro
- key: "topology.kubernetes.io/zone"
operator: In
values: ["ap-northeast-1a"]
- key: karpenter.sh/capacity-type
operator: In
values:
- spot
- key: kubernetes.io/arch
operator: In
values:
- amd64
# These fields vary per cloud provider, see your cloud provider specific documentation
provider:
instanceProfile: sandbox-eks-nodegroup-worker
kind: AWS
launchTemplate: eksctl-nodegroup-spot-worker-1a-private
subnetSelector:
kubernetes.io/cluster/eks-karpenter: 'shared'
securityGroupSelector:
Name: sg-000000000000
実際に使用してみると起動時間は30s程度短縮されました。
しかし、
- 当時eksctlを使用してEKSの構築を行っていたため、
launch templateとprovisionerのダブルメンテが必要になってしまい管理が大変になる *1 - Pod Affinityに対応していなかったので、
reauiredなPod Affinityを付与しているアプリケーションがデプロイできない - Node起動が30s短縮されたといえども数分はかかってしまい、アグレッシブにNodeの増減が発生する「Chatwork」のサービスとしては1分程度まで短縮されて欲しかった
という点から、Karpenterを使用はせず前述したballoon✖️ClusterAutoScalerの仕組みで運用しています。
まとめ
発表の中で詳しくお話しできなかった点についてご紹介しました。
その他の部分については以下に記載する参考記事をぜひご覧になってみてください!
参考
creators-note.chatwork.com 新入社員は見た!ChatworkにおけるEKSの運用と取り組み creators-note.chatwork.com KubernetesとTerraformのセキュリティ/ガバナンス向上委員会 with OPA
*1:もちろんeksctlでも予めlaunch templateの指定はできますが、eksctlで作成できるものはeksctlで作成する、という方針で、launch templateの作成自体をeksctlで作成していたため