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

Helm / ArgoCD で実現する Kubernetes における宣言的リソースデリバリーの実践

77a4428a7b54e23e74ff81849563c458?s=47 Suzuki Shota
September 03, 2021

Helm / ArgoCD で実現する Kubernetes における宣言的リソースデリバリーの実践

77a4428a7b54e23e74ff81849563c458?s=128

Suzuki Shota

September 03, 2021
Tweet

Transcript

  1. Helm/ArgoCD で実現する Kubernetes における 宣言的リソースデリバリーの実践 鈴木 祥太

  2. 自己紹介 鈴木 祥太 (@sshota0809) • 株式会社ユーザベース SRE チーム所属 ◦ B2B

    向け SaaS Product を横串で担当 • 最近 Kubernetes の Gateway API に興味を持っています
  3. 弊社で運用している CI/CD パイプラインが抱えていた課題を Helm / ArgoCD を使った GitOps で解決したお話 今日の話題

  4. アジェンダ CI/CD パイプライン の課題 GitOps の採用 GitOps の導入戦略

  5. アジェンダ CI/CD パイプライン の課題 GitOps の採用 GitOps の導入戦略

  6. パイプラインの全体像 • Jenkins をメインで利用 • e2e~開発環境 / 本番環境へのデプロイでパイプラインを分割 • 各マイクロサービスは各

    Kubernetes 環境にデプロイされる ◦ e2e & 開発用クラスタ ◦ 本番用クラスタ e2e~開発環境用パイプライン 本番環境用パイプライン DockerImage 作成 e2e 用ネームスペースに リソースデプロイ & e2e 実行 開発用ネームスペースに リソースデプロイ 本番用ネームスペースに リソースデプロイ Istio による B/G 切り替え
  7. 「Kubernetes へのリソースデプロイ」部分をブレイクダウン e2e~開発環境用パイプライン 本番環境用パイプライン DockerImage 作成 e2e 用ネームスペースに リソースデプロイ &

    e2e 実行 開発用ネームスペースに リソースデプロイ 本番用ネームスペースに リソースデプロイ Istio による B/G 切り替え
  8. Kubernetes へのリソースデプロイ YYY ネームスペースにリソースデプロイ テンプレートファイルから マニフェスト生成 マニフェストを Kubernetes へデプロイ

  9. Kubernetes へのリソースデプロイ シンプルだがそれぞれのステップで課題が存在 YYY ネームスペースにリソースデプロイ テンプレートファイルから マニフェスト生成 マニフェストを Kubernetes へデプロイ

  10. Kubernetes へのリソースデプロイ YYY ネームスペースにリソースデプロイ テンプレートファイルから マニフェスト生成 マニフェストを Kubernetes へデプロイ

  11. 課題1 テンプレートファイルからマニフェスト生成 templateファイル (Deployment/etc...) 変数ファイル (e2e/開発/本番) envsubst • envsubst を利用したテンプレート機構

    ◦ 変数ファイル内で環境変数を export(変数ファイルの実体はシェルスクリプト) ◦ export した環境変数を envsubst でテンプレートファイルに埋め込み • envsubst とは? ◦ 指定したファイルに環境変数を export してくれる ◦ やれることが良くも悪くもシンプル ▪ 当然テンプレートファイル内で if / for 構文などは利用不可 + = マニフェストファイル
  12. 課題1 テンプレートファイルからマニフェスト生成 • envsubst を使ったテンプレート機構だと困る例 ◦ あるマニフェスト内で開発環境でのみ 「IP_ADDR」 という環境変数をセットしたい ◦

    本番環境では環境変数自体不要だが if 文などが使えないため なにかしらの適当な文字列を代入する必要がある apiVersion: apps/v1 kind: Deployment ... spec: ... image: hoge/fuga:v1 env: - name: IP_ADDR value: ${DEV_DAKE_TEIGI_SITAI} #!/usr/bin/env bash export DEV_DAKE_TEIGI_SITAI=10.10.10.10 👌 dev-env.sh #!/usr/bin/env bash export DEV_DAKE_TEIGI_SITAI=tekito-IP 😒 prd-env.sh
  13. 課題1 テンプレートファイルからマニフェスト生成 テンプレートエンジンの柔軟性が低い

  14. Kubernetes へのリソースデプロイ YYY ネームスペースにリソースデプロイ テンプレートファイルから マニフェスト生成 マニフェストを Kubernetes へデプロイ

  15. 課題2 マニフェストを Kubernetes へデプロイ • デプロイが非常に手続き的 ◦ パイプライン内で実行するシェルスクリプトで kubectl コマンドを直接実行

    ▪ kubernetes のコンテキスト情報はパイプライン内にベタ書き ▪ Jenkins の Worker ノードでコンテキスト情報を管理する必要あり ▪ 「どのリソースがどのクラスタにデプロイされているか」という情報を 宣言的に管理できていない • 実際にクラスタかパイプラインを見て確認する必要がある def DEV_K8S_CONTEXT = 'hoge@dev-gke01' def NAMESPACE = 'hoge’ ... sh "./create-resources.sh -c ${DEV_K8S_CONTEXT} -n ${NAMESPACE}" ... 😒 pipeline.groovy
  16. 課題2 マニフェストを Kubernetes へデプロイ kubectl コマンドを実行するという 非常に手続き的なデリバリーになってしまっている

  17. リッチなテンプレートエンジンを使いつつ 宣言的なリソースデリバリーを実現したい テンプレートエンジンの 柔軟性の低さ 手続き的なデリバリー

  18. Helm / ArgoCD を使い GitOps 化することで 宣言的なデリバリーを実現

  19. アジェンダ CI/CD パイプライン の課題 GitOps の採用 GitOps の導入戦略

  20.   Helm • Kubernetes のパッケージマネージャ ◦ Chart と呼ばれる Go Template

    を利用したマニフェストのかたまり ◦ リポジトリで公開されているChartの検索やダウンロード、インストール ◦ Chartのパッケージ化やリポジトリへのアップロード • Go Template によるリッチなテンプレートエンジン ◦ if/for 文、関数などが利用可能 ◦ 変数のリストを yaml 形式で記述可能なため可読性が高い
  21. テンプレートエンジンの 柔軟性の低さ Go Template による リッチなテンプレート

  22.   ArgoCD / GitOps • ArgoCD ◦ GitOps の思想に基づいた CD

    ツール ◦ Helm / Kustomize とのインテグレーションが可能 • GitOps ◦ 宣言的なデリバリー手法(Weaveworks が提唱) ◦ Git のリポジトリで管理されているマニフェスト(状態)を Kubernetes クラスタに同期 ▪ single source of truth の実現 • どんなリソースクラスタで動いているか Git 上で管理されている
  23. CD CI GitOps パイプライン アプリのソースコー ドリポジトリ Docker レジストリ マニフェスト ファイル

    マニフェスト リポジトリ イメージ Build 最新のマニフェストを 専用リポジトリに反映 監視 + 差分検知 差分を反映 • 設計/方針次第ではあるが CI / CD を分離することが可能 • マニフェストリポジトリに定義されているもの = 実際にクラスタで稼働しているもの
  24. 手続き的なデリバリー 宣言的なデリバリー

  25. ここからは ArgoCD の使い方や特徴について 詳しく説明していきます

  26.  ArgoCD アーキテクチャ API Server Repository Service Application Controller 差分検知 &

    デプロイ multiple k8s cluster 取得 & cache マニフェスト リポジトリ CLI (argocd command) GUI CI/CD Tools
  27. credential  ArgoCD を構成する主なリソース project application account rbac repository Cluster •

    project ◦ 複数の application をまとめた単位 • application ◦ どの git repository をどの Kubernetes クラスタに同期するか設定 • account / rbac ◦ project や application などに対する権限
  28.  ArgoCD Application Resouce の例 apiVersion: argoproj.io/v1alpha1 kind: Application metadata: namespace:

    argocd labels: app: hoge-api spec: project: hoge source: repoURL: git@github.com:sshota0809/hoge-api.git targetRevision: master path: dir1/dir2 destination: server: https://kubernetes.example.com namespace: hoge-api syncPolicy: automated: - prune: true syncOptions: - Validate=true - PruneLast=true • source ◦ 同期元のリポジトリ情報 • destination ◦ 同期先のクラスタ情報 • syncPolicy ◦ 同期の動きを制御する様々なオプション
  29.  ArgoCD の特徴 • ArgoCD 自身のあらゆる設定を Kubernetes のリソースとして宣言的に管理 • 差分同期の柔軟な制御 ◦

    Phase / Wave / Healthcheck など • GUI / CLI / API あらゆるインターフェースで操作可能
  30.  ArgoCD リソースの宣言的管理 • 各種 CRD ◦ Application / Project …

    • ConfigMap や Secret ◦ argocd-rbac-cm / argocd-cm / argocd-secret / cluster / repository ... data: accounts.tech: apikey,login repositories: | - url: https://github.com/sshota0809/hoge.git repository.credentials: | - url: git@github.com:sshota0809 sshPrivateKeySecret: name: git-ssh-key key: sshPrivateKey ... argocd-cm data: policy.csv: | p, tech, clusters, get, *, allow p, tech, projects, get, *, allow p, tech, repositories, get, *, allow p, tech, accounts, get, *, allow p, tech, applications, get, */*, allow p, tech, applications, sync, hoge/*, allow ... argocd-rbac-cm data: accounts.tech.password: xxx accounts.tech.passwordMtime: xxx accounts.tech.tokens: xxx ... argocd-secret
  31.  ArgoCD 差分同期の柔軟な制御 • Sync Phases ◦ 同期されるマニフェストに Annotation を記述することで制御可能 ▪

    argocd.argoproj.io/hook: <Phase> • 「PreSync で Init 処理を流す Job リソースを作成」など • Sync Waves ◦ Phase 内でリソースの同期される順番を制御可能(Default: wave 0) ▪ argocd.argoproj.io/sync-wave: <Wave Num> PreSync Sync PostSync SyncFail ConfigMap Deployment reading ConfigMap Wave -1 Wave 0
  32.  ArgoCD 差分同期の柔軟な制御 • HealthCheck ◦ 各リソースに対する HealthCheck が成功してはじめて「同期が成功した」とみなす ▪ 標準リソースに対する

    HealthCheck は Build-In されている • https://github.com/argoproj/argo-cd/tree/master/resource_customizations ▪ Lua でカスタムヘルスチェックを実装することも可能
  33.  ArgoCD GUI / CLI / API での操作 • GUI ◦

    使いやすくリッチな GUI が提供されている ▪ ArgoCD にあまり詳しくない人たちもスイスイ使える(と思われる) • CLI ◦ argocd コマンドが提供 ▪ 各種リソースの作成 / Sync / Sync が成功したか確認(wait)など多彩なコマンド • API ◦ GUI / CLI ともに内部的に API にアクセスをしているだけ ◦ API を利用すれば様々な操作が可能
  34.  ArgoCD GUI / CLI / API での操作 • GUI ◦

    各種リソースの Read / Create / Sync などが可能
  35.  ArgoCD GUI / CLI / API での操作 • CLI ◦

    各種リソースの Read / Create / Sync などが可能 ◦ https://argoproj.github.io/argo-cd/user-guide/commands/argocd/ ▪ argocd account - Manage account settings ▪ argocd app - Manage applications ▪ argocd cluster - Manage cluster credentials ▪ argocd login - Log in to Argo CD ▪ argocd proj - Manage projects ▪ argocd repo - Manage repository connection parameters ...
  36. アジェンダ CI/CD パイプライン の課題 GitOps の採用 GitOps の導入戦略

  37. GitOps における原理 / 原則 / プラクティス • ググるとたくさんの情報が提唱されている ◦ 5

    GitOps Best Practices ▪ https://blog.argoproj.io/5-gitops-best-practices-d95cb0cbe9ff ◦ GitOps in Kubernetes ▪ https://platform9.com/blog/gitops-for-kubernetes/ • ThoughtWorks 社が公開されている TECHNOLOGY RADER では GitOps は HOLD (Proceed with caution)に指定されていたりもする ▪ GitOps | Technology Radar | Thoughtworks • 色々と情報を集めつつ自分たちの環境にあった形で設計を実施
  38. 特に考慮した 3 つのポイント 同期の 実行戦略 ブランチ 戦略 Helm との インテグレー

    ション
  39. 特に考慮した 3 つのポイント 同期の 実行戦略 ブランチ 戦略 Helm との インテグレー

    ション
  40. 同期の実行戦略 • 自動同期 ◦ デフォルトでは 180s 毎に差分確認 + 同期を実行(設定変更可能) ▪

    パラメータで調整可能だが Application 数と同期スパンに応じて負荷がかかる ◦ Gitリポジトリの webhook の設定で同期処理の発火も可能 • 手動実行 ◦ GUI を利用した同期 ◦ CLI を利用した同期
  41. 同期の実行戦略 • パイプライン上で argocd コマンドによる手動同期をすることを選択 ◦ 「e2e デプロイ + HealthCheck

    の正常性確認~e2e 実行~開発環境へのデプロイ + HealthCheck の正常性確認」を 1 本のパイプラインで実行したかった ▪ argocd app sync • 同期オペレーション ▪ argocd app wait • HealthCheck の正常性確認 (--timeout <sec> を指定することで timeoutした場合は異常の終了値返却) e2e~開発環境用パイプライン DockerImage 作成 e2e 用ネームスペースにリソースデプロイ & e2e 実行 開発用ネームスペースに リソースデプロイ
  42. 同期の実行戦略 • パイプライン上でコマンドによる CD を実行しているため CI / CD を切り離せていない ◦

    しかし webhook などの自動同期によって CI / CD を分離すると かえってそれらの連携が必要となり一連の流れが複雑化すると考えた ▪ 数珠つなぎに次々発火していくイメージ ◦ 運用を続けて自分の環境におけるベストを引き続き模索していく e2e DockerImage 作成 e2e 用マニフェスト生成 + Git に push e2e環境へ差分デプロイ e2e e2e~開発環境 e2e実行 開発用マニフェスト生成 + Git に push 開発環境へ差分デプロイ 開発環境
  43. 特に考慮した 3 つのポイント 同期の 実行戦略 ブランチ 戦略 Helm との インテグレー

    ション
  44. ブランチ戦略 • 開発や本番といった環境毎にブランチを分けて運用するケースが多い • 一方でチームではトランクベース開発を基本としている文化がある 開発ブランチ マニフェスト リポジトリ 本番ブランチ 開発クラスタ

    本番クラスタ
  45. ブランチ戦略 • 開発方針に則って GitOps でも branch の複雑性を排除するため main ブランチのみの運用とした ◦

    環境毎にディレクトリを切ってそこをそれぞれ監視 ◦ これに関しても運用を続けてベストな環境を引き続き模索していく ▪ ディレクトリ構造がもたらす複雑性 マニフェスト リポジトリ 開発クラスタ 本番クラスタ dev/hoge-api/ prd/hoge-api/
  46. 特に考慮した 3 つのポイント 同期の 実行戦略 ブランチ 戦略 Helm との インテグレー

    ション
  47. Helm とのインテグレーション • Helm Chart を参照することでマニフェストを ArgoCD 内で生成可能 →あえて利用せずパイプライン上で helm

    template コマンドで  マニフェスト生成し Push ▪ Git に定義されているリソースがクラスタにデプロイされている 生のマニフェストになる方が直感的だと考えた ▪ Helm Chart はあくまで value とテンプレートが分離された状態なので 生のマニフェストと比べると可読性に劣る場合が多いと考えた apiVersion: argoproj.io/v1alpha1 kind: Application ... source: repoURL: https://github.com/helm/charts.git chart: stable/envoy helm: parameters: - name: "replicaCount" value: "1" releaseName: hoge valueFiles: - hoge.yaml ...
  48. 最終的なパイプラインの構造 e2e~開発環境用パイプライン 本番環境用パイプライン DockerImage 作成 helm コマンドでマニフェスト作成 + Git push

    argocd sync / wait コマンドで同期 e2e実行 本番をHelm / argocd でデプロイ 開発をHelm / argocd でデプロイ
  49. その他 Tips • 通知 ◦ ArgoCD Notifications を利用し Slack 通知を実装

    ▪ https://argocd-notifications.readthedocs.io/en/stable/ ▪ ユーザ定義のステータスに応じて通知や webhook 実行が可能 • Application リソースの管理 ◦ 開発者が自由に Application リソースを定義可能な運用 ◦ プロダクト毎のマニフェスト用リポジトリ内で特定ディレクトリ以下は自動同期する設定 ▪ 開発者がそのディレクトリ配下に Application リソースを作成 ◦ ArgoCD 自身のリソースも ArgoCD によって同期できる プロダクト A マニフェスト repo プロダクト B マニフェスト repo argocd/appliation/ argocd/appliation/ Kind: Application 自動同期 自動同期
  50. まとめ CI/CD パイプライン の課題 GitOps の採用 GitOps の導入戦略 テンプレートエン ジンの柔軟性

    / 手続き的な デリバリー Helm / ArgoCD を利用 自チームの文化 なども踏まえつつ 戦略を組み立て