Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【CI/CD 2023】Karpenter を活用した GitLab CI/CD ジョブ実...

【CI/CD 2023】Karpenter を活用した GitLab CI/CD ジョブ実行基盤の自動スケール

CI/CD Conference 2023 by CloudNative Days で発表した「Karpenter を活用した GitLab CI/CD ジョブ実行基盤の自動スケール」のスライドです。

Toshiki Shimomura

March 20, 2023
Tweet

More Decks by Toshiki Shimomura

Other Decks in Technology

Transcript

  1. 01 About 3-shake 02 GitLab CI/CD の概要 03 プロジェクトにおける CI/CD

    の課題 04 Karpenter の導入によるオートスケール化 05 導入結果 06 まとめ 目次 3
  2.    xOps Plattform DesignOps IaaS DevOps / SRE RevOps (Revenue

    Ops) HR(Engineer Hiring) HROps Data Engineering DataOps Security DevSecOps SecOps 事業者が抱える セキュリティリスクを無くす 本格的な脆弱性診断を 無料で手軽に セキュリファイ Security 良いエンジニアに良い案件を フリーランスエンジニアに 「今よりいい条件」を リランス HR(Engineer Hiring) あらゆるサービスを連携する ハブになる クラウド型ETL/データパイプ ラインサービスの決定版 レコナー Data Engineering 日本のSREをリード SRE総合支援からセキュリティ 対策を全方位支援 スリーク SRE スリーシェイク = xOps領域のプラットフォーマーへ 6 About 3-shake
  3.  ・SRE の考え方に従って、AWS や Google Cloud を利用しているお客様サービスの   技術戦略、設計、構築、運用までをワンストップで支援するサービス  ・マイクロサービス、Kubernetes などクラウドネイティブな技術領域に強み  ・ベンダー的な役割ではなく「お客様のチームメンバー」という立ち位置で最新技術の提案から

      運用支援までをトータルご支援  ・SRE チーム組成・SRE 文化の定着化・SRE 技術者の採用/育成コンサルティング等も対応 運用支援 アセスメント (パフォーマンス/セキュリティ) 構築/実装 支援 システム設計 Sreake SRE(スリーシェイクによる SRE 総合支援サービス) 技術戦略・コンサルティング 7
  4. • GitLab に付属する CI/CD 機能 • リポジトリに .gitlab-ci.yml を置いて 処理を書くと,手軽に

    CI/CD を 実現できる。 • GitLab Runner が CI/CD ジョブの 実行を担う。 GitLab CI/CD の簡単な説明 9 GitLab リポジトリ .gitlab-ci.yml GitLab Runner ジョブ stages: - build - test build-code-job: stage: build script: - echo "Check the ruby version, then build some Ruby project files:" - ruby -v - rake test-code-job: stage: test script: - echo "If the files are built successfully, test some files with one command:" - rake test .gitlab-ci.yml の例 https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html
  5. GitLab 本体とは別のマシンに Runner をインストールできる GitLab Runner の仕組み 10 GitLab CI/CD

    機能で作られた ジョブを Runner に 渡す Runner ジョブを受け取り Executor で実行 動かせる OS: • Linux • Windows • macOS Executor ジョブの実行環境 • Docker • Docker Machine • Kubernetes • VirtualBox • SSH • Shell など Runner 登録 ジョブ割り当て ジョブ実行
  6. Runner (agent) は Kubernetes クラスタ上で Deployment として動き, ジョブごとに Pod を作って実行

    GitLab Runner の Kubernetes Executor 11 https://docs.gitlab.com/runner/executors/kubernetes.html
  7. • 構成 ◦ GitLab Community Edition を Amazon EKS クラスタ上で運用

    ◦ GitLab Runner も同じクラスタ上で運用 ◦ 当初は固定のノード数で運用,都度手動でノードを増減 • リポジトリ数:~500個 • 利用テナント(チーム)数:21 • 利用者数:~1000名 プロジェクトの概要 13
  8. • AWS が開発した OSS の Kubernetes ノードオートスケーラー • Cluster Autoscaler

    より高速・柔軟なオートスケールを狙う • クラウドプロバイダ非依存だが,現状 Amazon EKS のみに対応 • Helm でインストールできる Karpenter の特徴 18 https://karpenter.sh/
  9. Cluster Autoscaler • Auto Scaling グループ (ASG)との紐付けが必要 • ノードの増減は ASG

    の サイズを制御することで実現 Cluster Autoscaler との違い 22 Karpenter • ASG の用意は不要 (起動テンプレートは必要) • ノードの増減は Amazon EC2 API から直接インスタンスを 起動・停止することで実現 Cluster Autoscaler よりもスケールが速い・柔軟
  10. • ECS on Fargate:イメージはタスク定義のもの固定なので, ジョブ定義のイメージは使えない。 • EKS on Fargate:1 Node

    1 Pod のため,全ジョブにノード起動の 待機時間が発生する。 • EKS on EC2:バルーニング(後述)すれば上記の課題を解決 できる。 その他の実行基盤の選択肢について検討 24
  11. Cluster Autoscaler • インスタンスタイプが固定 ☞ワークロードに応じて変える なら ASG が複数必要 Cluster Autoscaler

    との違い(続き) 25 Karpenter • ワークロードに応じて インスタンスタイプを 自動選定 基盤運用の立場からすると どの規模のジョブを利用するか想定できないため 要求リソースに合わせてノードのスペックを決めたい
  12. カスタムリソースの役割と関係 28 Unschedulable Provisioner (AWS)NodeTemplate ノードの制約や振る舞いを指定 • taints • labels

    • requirements ノードのテンプレートを定義 ①スケジュール待ちの Pod を Provisioner に割り当てる • tolerations • nodeSelector • nodeAffinity ②テンプレートを使って 条件に合致するノードを 立ち上げる ③ Pod をスケジュール
  13. 設定できる項目例: • labels, annotations, taints • requirements: インスタンスタイプ,AZ など •

    limits:リソース合計の上限 • ttlSecondsUntilExpired: ノードの失効時間 • ttlSecondsAfterEmpty: スケールイン判定 Provisioner でノードの制約を定義する 29 apiVersion: karpenter.sh/v1alpha5 kind: Provisioner metadata: name: gitlab-runner spec: providerRef: name: gitlab-runner labels: workload: gitlab-runner requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot"] - key: kubernetes.io/arch operator: In values: ["amd64"] - key: karpenter.k8s.aws/instance-family operator: In values: ["c6i", "m6i", "t3", "m5"] - key: karpenter.k8s.aws/instance-size operator: In values: ["large", "xlarge", "2xlarge"] limits: resources: cpu: 1000 ttlSecondsUntilExpired: 86400 # 1 Day ttlSecondsAfterEmpty: 600
  14. クラウド依存 AWS の場合は AWSNodeTemplate で, 起動テンプレート相当のものを 作れる • どんなノードを •

    どこのサブネットで • どんな設定で 起動するかを定義 NodeTemplate でノードの雛形を作る 30 apiVersion: karpenter.k8s.aws/v1alpha1 kind: AWSNodeTemplate metadata: name: gitlab-runner spec: subnetSelector: Name: "*-private" securityGroupSelector: karpenter.sh/discovery: my-cluster amiFamily: AL2 blockDeviceMappings: - deviceName: /dev/xvda ebs: volumeSize: 100Gi volumeType: gp3
  15. 今回はシンプルにラベル(Pod 側は nodeSelector)で指定する セレクタ設定|Karpenter によるセレクタの設定 31 apiVersion: karpenter.sh/v1alpha5 kind: Provisioner

    metadata: name: gitlab-runner spec: labels: workload: gitlab-runner workload = gitlab-runner のラベルが付いたノードに スケジュールされる Pod がスケール判定対象になる
  16. GitLab Runner では全ジョブの Pod に nodeSelector を付与するよう 設定 ☞ nodeSelector

    に対応したラベルの付いたノードで Pod が起動 セレクタ設定|セレクタに合わせた GitLab Runner の設定 32 [runners.kubernetes] [runners.kubernetes.node_selector] workload = gitlab-runner GitLab Runner の config.toml(抜粋)
  17. スケジュール待ちの Pod に優先度を付与できる。 Kubernetes の PriorityClass の機能 34 優先度の高いものから順に起動 優先度の低いものを退避させて

    高いものを起動(「横取り」) Pending 優先度100 優先度0 優先度-10 優先度100 優先度-10 優先度0 優先度-10 優先度100 優先度0
  18. バルーニング|ノードのバルーニングの設定 35 apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: gitlab-runner-balloon value:

    -10 preemptionPolicy: Never globalDefault: false apiVersion: apps/v1 kind: Deployment metadata: name: gitlab-runner-balloon spec: replicas: 10 template: spec: priorityClassName: gitlab-runner-balloon containers: - name: sleep-forever image: ubuntu command: ["sleep"] args: ["infinity"] nodeSelector: workload: gitlab-runner # 説明に必要な箇所のみ抜粋 低優先度クラスを指定 1. PriorityClass で優先度を 定義 2. バルーンの Pod spec で 1. の PriorityClass を指定
  19. GitLab Runner の設定で,ジョブの CPU・メモリリソースの上限を設定 • Request ◦ CPU:0.5 ◦ メモリ:2

    GiB • Limit ◦ CPU:2 ◦ メモリ:8 GiB 対処1-2:ジョブサイズの上限を設定する 43
  20. • バルーン Pod に topologySpreadCondition 設定を追加 • 2ゾーンまでは分散できた。 • 3ゾーン以上にはなかなかならなかった。

    対処2(暫定):topologySpreadCondition で2ゾーンに分散する 45 topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: balloon
  21. • GitLab Runner のジョブ実行基盤を,Karpenter を用いて ノードレベルでオートスケールする事例を紹介した。 • Karpenter を用いると,ワークロードの要求リソースに基づいて 最適なノードを短時間で起動・停止できる。

    • GitLab CI/CD のようなジョブ実行基盤に限らず, ワークロードが動的に変化する要件は, Karpenter によるオートスケールと相性が良い。 まとめ 51