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

内製DevOps基盤を大きく作り直してみた

Hiroki Okui
September 29, 2022
3k

 内製DevOps基盤を大きく作り直してみた

Hiroki Okui

September 29, 2022
Tweet

More Decks by Hiroki Okui

Transcript

  1. © NTT Communications Corporation All Rights Reserved. 自己紹介 NTTコミュニケーションズ Software

    Engineer 奥井 寛樹 略歴 • 伝送システムのSDNコントローラ開発 • シリコンバレー駐在、 ONOS開発 • DevOpsプラットフォーム開発 • IoTデータ収集基盤のモダナイゼーション @HirokiOkui hrk091 2
  2. © NTT Communications Corporation All Rights Reserved. 3 今日お話すること NTTCom内製のDevOps基盤:

    Qmonus Value Stream • DevOpsのFeedback loopを高速に回すための内製プラットフォーム • Flexible InterConnect、Super OCN Flexible Connect など多数のプロダクトの裏側で活躍 2022年4月に、NTTグループ向けに提供開始 • 2020年〜2021年にかけて社内基盤として実績を積み、プロダクトアウト 2021年度に、旧基盤の課題解決のために大きく刷新 • どういう課題をどのように解決したのか、裏側をご紹介
  3. © NTT Communications Corporation All Rights Reserved. 4 宣伝 Qmonus

    Value Stream開発の取り組みや技術について • “オンプレデリバリから Cloud Native CI/CDへの道のり”, NTT Engineers' Festa #4 • “クラウドを最大限活用する Infrastructure as Codeを考えよう”, Cloud Native Days Tokyo 2021 • "社内DevOps基盤、Tekton、Cuelang", Fukabori.fm, episode 50 • "Deliver Your Cloud Native Application with Design Pattern as Code", KubeCon Europe 2020 技術ブログ書いてます • 連載: DevOpsプラットフォームの取り組み
  4. © NTT Communications Corporation All Rights Reserved. Qmonus Value Streamとは

    6 アプリ提供までのバリューストリームを最大化するDevOpsプラットフォーム • ビジネスに価値を生む開発工程に注力するために、早いフィードバックループを実現 • 基盤に詳しくなくてもプロのように Cloud Nativeアプリケーションをデリバリできる
  5. © NTT Communications Corporation All Rights Reserved. 再利用可能な優れたプラクティスを組み合わせて、簡単にアプリをデプロイ • Cloud

    Native Adapterを選択するだけで、クラウドネイティブアーキテクチャを構成 • 任意のクラウド環境に、アプリケーション開発者だけでリリースできる 特徴1: 独自のInfrastructure as Code Pattern: { name: "wasabi" resources: { kubernetes: { ingress: ... service: ... } gcp: uptimecheck: ... } } Pattern: { name: "gcp/redis" resources: { kubernetes: { ingress: ... service: ... } gcp: uptimecheck: ... } } Pattern: { name: "k8s/nginx-ingress" resources: { kubernetes: { ingress: ... service: ... } gcp: uptimecheck: ... } } Cloud Application Qmonus Value Stream Cloud Native Adapter (ベストプラクティスをパッケージ化したIaCモジュール) ビルド テスト リリース 7
  6. © NTT Communications Corporation All Rights Reserved. Tekton = Kubernetes上でCI/CDの機能を実現するフレームワーク

    • 宣言的記述・スケーリングなどの Kubernetesのメリットを活用できる • 処理単位(Step)がコンテナのため任意の処理が組み込みやすく、かつ再利用しやすい Step、Task、Pipelineの3つで構成 • Step: Containerに対応 • Task: Podに対応(複数Stepで構成) • Pipeline: Taskのワークフロー(複数 Taskを順に実行) Qmonus Value Streamでは、もう一層独自に追加 • “Taskのワークフロー” をモジュール化して再利用するため • AssemblyLineと呼称*1 88 特徴2: ワークフロー基盤としてTektonを活用 Build Pipeline Task Task Task AssemblyLine Pipeline Task Task Pipeline Task Task Stage Stage *1: 旧基盤ではAssemblyLineではなくWorkflowと呼称していたが、本資料ではAssemblyLineで統一
  7. © NTT Communications Corporation All Rights Reserved. クラウドIaC・Kubernetes・CI/CDパイプラインを統一言語で表現 • 用途ごとに異なるツールを使うのではなく、宣言記述と構成テストを全て

    CUEだけで実現 • マルチクラウドをまたいでモジュール化・正規化して、見通しよく記述し、再利用できる • インフラの構成と、インフラにデリバリするワークフローをまとめてパッケージ化 9 特徴3: IaC・CI/CDの記述言語をCUEで統一 Infrastructure Configuration Build Scan Release CI/CD Pipeline Container Security Cloud Native Adapter Uptime Check Cloud Native Adapter Check GKE API Cloud Native Adapter Adapterを組み合わせ、 アーキテクチャと CI/CDパイプラインの 両方を拡張
  8. © NTT Communications Corporation All Rights Reserved. 11 旧基盤のアーキテクチャ概要(抜粋) Frontend

    API Server api-server Pipeline Controller Pipeline(Run) Task(Run) Task Step Step Step Infrastructure Adapter Infrastructure Manifest AssemblyLine Engine polling - AssemblyLineのワークフロー制御 - Tekton PipelineのCRUDによるPipeline制御 (k8sの外から制御)
  9. © NTT Communications Corporation All Rights Reserved. 課題1: Pipeline/Taskの汎化・再利用ができない 12

    Tekton Pipeline・Taskのレイヤごとの責務分けが構造上できなかった • 関連する処理をTaskにまとめる必要がある設計になっており、 Taskの汎化ができなかった (Taskの責務が大きすぎる) • RetryなどがPipeline単位でのみ可能なため、柔軟な制御を可能にすると PipelineとTaskが1-1に (Pipelineの責務が小さすぎる) AssemblyLine Pipeline Task Task Pipeline Task Task Stage Stage 期待値 実際 AssemblyLine Pipeline Task Pipeline Task Stage Stage AssemblyLine Pipeline Task Stage Pipeline Task Stage Pipeline Task Stage Pipeline Task Stage 依存のある複数コンテナで構成 される処理 -> Task分割できず、 Taskが肥大化 Retryを細かな粒度で行いたい -> PipelineとTaskが1-1に
  10. © NTT Communications Corporation All Rights Reserved. 課題1: Pipeline/Taskの汎化・再利用ができない 13

    Tekton Pipeline・Taskのレイヤごとの責務分けが構造上できなかった • 関連する処理をTaskにまとめる必要がある設計になっており、 Taskの汎化ができなかった (Taskの責務が大きすぎる) • RetryなどがPipeline単位でのみ可能なため、柔軟な制御を可能にすると PipelineとTaskが1-1に (Pipelineの責務が小さすぎる) AssemblyLine Pipeline Task Task Pipeline Task Task Stage Stage 期待値 実際 AssemblyLine Pipeline Task Pipeline Task Stage Stage AssemblyLine Pipeline Task Stage Pipeline Task Stage Pipeline Task Stage Pipeline Task Stage 依存のある複数コンテナで構成 される処理 -> Task分割できず、 Taskが肥大化 - 責務が肥大化して汎 化できない - PipelineとTaskが1-1となるケースが多く、 Pipeline のワークフローの責務がほぼない。 冗長なレイヤーになっている Retryを細かな粒度で行いたい -> PipelineとTaskが1-1に
  11. © NTT Communications Corporation All Rights Reserved. 14 課題2: パラメータの管理が複雑すぎる

    パラメータのマッピング・注入層が多すぎる • データマッパーが多段にある状態で、透明性が低い。 Taskで使われる値の追跡が大変 • 複製 => 値の修正漏れが発生。 汎化 => 過度に汎化すると予期せぬ変更の波及が発生 一度に扱うパラメータの数が多すぎる • 複数の環境、複数のアプリ、 BuildからReleaseに至るまでのたくさんの処理 • workflowからパラメータを参照する方式 => スケールしない AssemblyLine Pipeline Task マッピング 注入 マッピング 注入 注入 Config アプリ共通 アプリ共通 アプリ共通 アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 - 複雑・数が膨大でス ケールしない - データマッパーが多段で、透明性が低い - AssemblyLine・Pipeline・Taskの定義を全て確認しないと最終 的に使われる値がわからない
  12. © NTT Communications Corporation All Rights Reserved. 課題3: Userがセルフマネジメントできない 15

    マニフェストの記述量が多く、複雑 • Tekton Pipeline/Task、AssemblyLine定義、パラメータ定義を全て記述し整合させないと動かない • 全リソースが密結合しており、変更の影響が波及する & テストや自動生成などの支援がない API・UIが不十分のため、運用サポートが必須 • 半数の設定にUIがなく、APIが空いてないものもある(運用で対処していた) • 社内案件のSRE・インフラ基盤チームも兼任しており、デマケーションが不明瞭で低優先だった マニフェストの数が多い ... Pipeline Task AssemblyLine Config UIから設定できない or 問い合わせ必須なものも
  13. © NTT Communications Corporation All Rights Reserved. 17 3つの課題にどう対処したか 3.

    Userがセルフマネジメントできない 1. PIpeline/Taskの汎化・再利用ができない 2. パラメータの管理が複雑すぎる
  14. © NTT Communications Corporation All Rights Reserved. 18 3つの課題にどう対処したか 3.

    Userがセルフマネジメントできない 1. PIpeline/Taskの汎化・再利用ができない 2. パラメータの管理が複雑すぎる 1.独自のk8sカスタムオペレータの導入 2.Tekton Pipeline/Taskの自動生成 3.パラメータ管理のアーキテクチャ変更 4. 高速に開発できるアーキテクチャ 技術スタックの選定
  15. © NTT Communications Corporation All Rights Reserved. k8s外からPolling => k8s内のオペレータ間連携に方式を変更

    • Tekton Pipelineリソースと高度に連携し、 Task単位でのRetryやパラメータ注入機能などを具備 *1 TaskへのPipeline責務の流出・Taskの肥大化を防ぎ、汎化を可能に 19 対処1: 独自のk8sカスタムオペレータの導入 *1: https://engineers.ntt.com/entry/2022/09/26/084040 AssemblyLine Engine Pipeline Controller api-server AssemblyLine Controller Pipeline Controller api-server polling Reconciliation Loop AssemblyLine Pipeline Task Task Pipeline Task Task Stage Stage AssemblyLine: 複数アプリケーション・複数環境を扱う複雑なワークフローを構成する Pipeline: 再利用しやすい単位でワークフローをまとめる( Build、Deploy、Releaseなど) Task: 再利用しやすい単位で処理をまとめ汎化する( git checkout、image-build、pushなど)
  16. © NTT Communications Corporation All Rights Reserved. 20 対処2: Tekton

    Pipeline/Taskの自動生成 CUEを使って、Tekton Pipeline/TaskをCloud Native Adapterから自動生成 • TektonのPipeline/Taskはk8sマニフェストなので、 CUEでコンフィグとして扱える • Cloud Native Adapterを指定するだけで、Tektonマニフェストが自動生成(ユーザは記述不要)
  17. © NTT Communications Corporation All Rights Reserved. 21 対処2: Tekton

    Pipeline/Taskの自動生成 生成されたPipelineは、AssemblyLineのビルディングブロックとして使用できる • 結合検証・総合検証・商用と複数環境あってプロモートするケースでも、同じ Pipelineが流用可 • 生成されたPipelineを組み合わせるだけで、複雑な CI/CDパイプラインが構成できる
  18. © NTT Communications Corporation All Rights Reserved. 22 対処3: パラメータ管理のアーキテクチャ変更

    パラメータの保守性・透明性を高めるための3つの工夫*1(k8sオペレータで実装) AssemblyLine Pipeline Task マッピング 注入 マッピング 注入 注入 Config アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 Before *1: https://engineers.ntt.com/entry/2022/09/06/082901
  19. © NTT Communications Corporation All Rights Reserved. 23 対処3: パラメータ管理のアーキテクチャ変更

    パラメータの保守性・透明性を高めるための3つの工夫*1(k8sオペレータで実装) AssemblyLine Pipeline Task マッピング 注入 マッピング 注入 注入 Config アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 Before After AssemblyLine Pipeline Task マッピング 注入 Cloud Native Adapter 生成 AppA x Staging Build pipeline AppA x Prod Release pipeline Config AppA x Staging AppA x Prod アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 AppB x Staging パラメータセット *1: https://engineers.ntt.com/entry/2022/09/06/082901
  20. © NTT Communications Corporation All Rights Reserved. 24 対処3: パラメータ管理のアーキテクチャ変更

    パラメータの保守性・透明性を高めるための3つの工夫*1(k8sオペレータで実装) • パラメータのマッピング・注入層を 1箇所にする AssemblyLine Pipeline Task マッピング 注入 マッピング 注入 注入 Config アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 Before After AssemblyLine Pipeline Task マッピング 注入 Cloud Native Adapter 生成 AppA x Staging Build pipeline AppA x Prod Release pipeline Config AppA x Staging AppA x Prod アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 AppB x Staging - Pipeline/Taskが自動生成され、 マッピングが一意に決定する - マッピングが一層に限定され、透明性が向上 - 利用者は、ここだけ気にすれば良い パラメータセット *1: https://engineers.ntt.com/entry/2022/09/06/082901
  21. © NTT Communications Corporation All Rights Reserved. 25 対処3: パラメータ管理のアーキテクチャ変更

    パラメータの保守性・透明性を高めるための3つの工夫*1(k8sオペレータで実装) • パラメータのマッピング・注入層を 1箇所にする • 扱うスコープを小さくし、あらかじめパラメータセットを用意して注入する AssemblyLine Pipeline Task マッピング 注入 マッピング 注入 注入 Config アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 Before After AssemblyLine Pipeline Task マッピング 注入 Cloud Native Adapter 生成 AppA x Staging Build pipeline AppA x Prod Release pipeline Config AppA x Staging AppA x Prod アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 AppB x Staging - 1つのPipelineで扱うスコープを、 “1アプリ x 1環境” に限定する - AssemblyLineでPipelineのDAGを 組む際に、スコープも指定 パラメータセット - “1アプリ x 1環境” ごとに パラメータセットが用意されている - パラメータセットを、 Pipelineのインター フェースに注入して駆動する - パラメータセットは、 Qmonus Value Streamの 設定値からよしなに生成 *1: https://engineers.ntt.com/entry/2022/09/06/082901
  22. © NTT Communications Corporation All Rights Reserved. 26 対処3: パラメータ管理のアーキテクチャ変更

    パラメータの保守性・透明性を高めるための3つの工夫*1(k8sオペレータで実装) • パラメータのマッピング・注入層を 1箇所にする • 扱うスコープを小さくし、あらかじめパラメータセットを用意して注入する • Implicit Bindingを導入し、自明なマッピングは記述不要にする AssemblyLine Pipeline Task マッピング 注入 マッピング 注入 注入 Config アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 Before After AssemblyLine Pipeline Task マッピング 注入 Cloud Native Adapter 生成 AppA x Staging Build pipeline AppA x Prod Release pipeline Config AppA x Staging AppA x Prod アプリ共通 アプリ共通 環境共通 アプリ共通 アプリ共通 環境個別 アプリ共通 アプリ共通 アプリ共通 AppB x Staging パラメータセット - キーが一致する場合は自動注入( Implicit Binding) - インピーダンスミスマッチがある場合のみ、明示的にマッ ピングを書いてあげれば良い *1: https://engineers.ntt.com/entry/2022/09/06/082901
  23. © NTT Communications Corporation All Rights Reserved. 27 対処4: 高速開発可能な技術選定

    機能がたくさん必要 => 開発速度を重視した技術・アーキテクチャを採用 • UI/API:Vue/Nuxt/TypeScript、FastAPI • DB:Firestore • UI/API/k8s Operatorも全部含めて、モノレポ • サービスベースアーキテクチャ & モジュラーモノリス k8s CRDで生成した型を全体に流通し、型指向開発を効率的に Frontend API api-server AssemblyLine Controlelr openapi-generator api client Pydantic Type CRD JSON Schema Go Struct datamodel-codegen make generate OpenAPI *1: https://www.oreilly.co.jp/books/9784873119823/
  24. © NTT Communications Corporation All Rights Reserved. 29 課題と学び 1

    “CueとTektonで大統一言語 & DevOps基盤” はロマンがある • 単一のSaaSで完結して、パッケージを選ぶだけで IaC・CI/CDが簡単に構成できると嬉しい、 というニーズは間違いなくある(リリースエンジニアリングに投資できないチームなど) • ツールが乱立し群雄割拠な現在、これができたらかっこいいよね 道は険しい • Tektonは、CD特化のツールではない( CDも可能だが、専用ツールに比べると力不足) • マニフェスト・パラメータの効率的な記述・管理については、作り直したことで大きく改善 • デリバリしたリソース・バージョンの可視化、ステートの管理機能、などはこれから k8sカスタムオペレータでがちなものを作るのは大変 • ちょっとした自動化ツールなら良いが、ワークフローツールは難しい • 宣言状態から次の状態を導出 => マニフェスト全体が入力なので、関心の分離が難しい • テストが難しい & 時間がかかる
  25. © NTT Communications Corporation All Rights Reserved. 30 課題と学び 2

    ソフトウェア開発の原則は、IaCでもCI/CDでもパラメータ管理でも有効 • 責務を分ける、レイヤを揃える ◦ 責務が正しくわかれておらず染み出していると、複雑化するほど歪み、いずれ崩壊する ◦ フレームワークが原因でレイヤの統一ができないなら、使い方を変えるか、技術選定を見直すべきかも • インターフェースは場所を絞って効果的に使う ◦ デカップリングと依存性逆転は有用だが、やりすぎは毒 • 全てはトレードオフ。要件に応じた適切なバランスを選択する
  26. © NTT Communications Corporation All Rights Reserved. 31 課題と学び 3

    使う言語は精査したほうが良い • チームがスケールすると、言語によって担当者が分断されてしまい、スクラムがやりにくい ◦ UI/API(TypeScript/Python)チームと、Operator/CLI(Go)チームに分かれ気味 FastAPIで中規模以上の開発はいまいちかも • 今回、PydanticとProtocolなどを用いて、型安全に実装した ◦ duck typingは一切なし。anyにもほぼ逃げない • IDEサポートやCIで静的型検査など快適だが、もはや golangでの開発と開発体験が同じ ◦ コードの保守性は高いが、元来のPythonの良さが失われている気がする • Performanceが猛烈に悪い ◦ ランタイム型検査をoffにすると改善するが、入力バリデーションが効かなくなるので出来ない
  27. © NTT Communications Corporation All Rights Reserved. 32 まとめ Qmonus

    Value Stream旧基盤の課題を、2022年度リリース版で解消 • 独自のk8sカスタムオペレータの導入 • ソフトウェア開発原則に従った構成へのリアーキテクチャ • まだ道半ば 結局の所、ソフトウェア開発原則の習熟と、技術選定が一番大事 ご興味があれば、一度使ってみてください!
  28. © NTT Communications Corporation All Rights Reserved. 33 We are

    hiring プロダクト志向で、DevOpsプラットフォーム = Qmonus Value Streamを一緒に開発し てくれるメンバーを募集しています!