
2025.02.18
「売上をスケールする」AIの使い道とは アルペンが挑む、kintone×生成AIの接客データ活用法
リンクをコピー
記事をブックマーク
Open Policy Agentについて軽く説明したいと思います。Open Policy AgentはOSSの汎用ポリシーエンジンです。Regoというポリシー記述言語によってポリシーを定義して入力データを検証します。よくあるユースケースとしては、Deploymentに特定のLabelがあることを強制したり、DeploymentやJobなどのDockerイメージのTagにlatestが使われていないことを強制したりするユースケースが挙げられます。
それらのポリシーというのはコードで管理されていて、Policy as Codeという画面でも管理されています。ポリシーを基にKubernetes Manifestなどの入力データを検証することになります。メリットとしては、そのポリシーをコードにして明文化できたりとか、ポリシーをコードとして運用してそのあと開発していける。誰が見ても理解できるかたちであって、誰もが検証できるようなメリットがあります。
このようなポリシーエンジンを自分たちメルカリのCI/CDの中にどのように取り入れて行けばよいかを考えました。簡単に説明するとこのようなCI/CDになっていて、Open Policy Agentのプロダクトの中でもConftestというプロダクトとGatekeeperというプロダクトを導入しました。ConftestはCIに対して、GatekeeperはKubernetesに実際にデプロイしています。その理由はあとから説明します。
まずConftestとは入力データをRegoで書いたポリシーで、検証するためのCLIツールになっています。もともとCI上で使われることを想定されています。Apply前にマニフェストを実際に検証してみることによって、そのマニフェストがルールに違反しているかしていないかなどのフィードバックを得られます。
フィードバックのレベルも3つに分けられていて、違反していなかったらSuccess、違反していたらViolation、そして警告メッセージとしてWarningを出せます。Conftestは、もともとはOPAのRegoを用いたサードパーティツールでしかなかったんですけど、最近になってOPAコミュニティの傘下に入って正式にCLIツールとして地位を築きつつあるプロダクトです。
CIの中でどのように使えるか見てみます。先ほど紹介したKubernetesリポジトリのCIに対して、Conftestで検証するようなJobを追加して検証します。例えばServiceCがルールに違反しているYAMLをプッシュしていると、CIの中でConftestが落ちて結果的にマージできない。そのフィードバックがデベロッパーに返るような仕組みになっています。
Success、Violationだけでなくて例えばWarningも出せて、今回YAMLをパスするもののベストプラクティスはこのような感じです。「こんな感じで実装をしてください」などの警告を出せて、徐々に組織全体のポリシーをかけていくということもできます。そしてCLIツールなので、実際にプッシュをしなくてもデベロッパーのローカル開発環境で検証してみてフィードバックを得られることもメリットの1つです。
次にGatekeeperの説明をします。GatekeeperはOPAをKubernetesのAdmission Controllerとして使えるようにしたものです。現在はバージョン3です。Gatekeeperの主要な機能としてkubectlのApplyされた入力と既にクラスタ上にデプロイされている既存のリソースを同時に参照しながらの検証ができるSync機能だったりとか、定期的な既存リソースの検証ができるAudit機能などがあります。
GatekeeperのポリシーはConstraintTemplateとConstraintの2つのCRDによって定義します。
ConstraintTemplateというのはConstraintを生成するための雛形になるもので、こちらは実際にRegoを用いてポリシーを記述します。そしてConstraintというのはConstraintTemplateから作られるCRDのことで、実際にどのポリシーをどのリソース、例えばDeployment、Ingressに適用するかや細かいパラメータを指定することになります。
ConstraintTemplateの実際の例はこちらです。こちらのConstraintTemplateはLabelをバリデーションするものです。targets以下で見られるようにここでポリシーを記述することになります。
次にConstraintです。ConstraintはConstraintTemplateを指定して、またそのポリシーを書けるためのリソースを指定して作ります。ここで実際にポリシーを書けます。
Gatekeeperというのはアドミッションコントローラーなので、例えば今回SpinnakerでApplyされるリソースだけではなくて、直接kubectlをクライアントがApplyされるものもあればCircle CIにApplyされるものも検証できます。また、ApplyだけではなくてCRDとか抽象化したリソースの中でもそのポリシーに違反するApplyがないかというのを検証できて、Kubernetesクラスタの最後の砦のような役割をします。
ConftestとGatekeeperを導入したあとのCI/CDはこのような構造です。結果的にこのような2つのプロダクトを導入するようになったんですけどそれには理由があって、例えばGatekeeperだけになるとメリットとしてはどのようなKubernetesリソースのApplyに対してもポリシーを書けるのですが、実際にApplyをしてみないと結果がわからないというデメリットがあります。
とくにマイクロサービスのデプロイはCI/CDを通してリポジトリにプッシュしてレビューもらって、それをCIで回してSpinnakerでデプロイするという流れがある中で、実際にデプロイしないとわからないというのはかなりフィードバックが遅くて開発体験が低いものです。
そのために今回Conftestという、デベロッパーのローカル開発環境でも検証できる、あとはCIの中でも検証できる比較的フィードバックの早いプロダクトも同時に導入しています。このようなものを組み合わせることによって開発体験を損なうことなく組織にポリシーを適用できています。
ConftestとGatekeeperの機能を比較して表にしてみました。先ほども紹介した通りどちらもポリシーを基に検証を行うツールなんですけど、立ち位置が異なるために排他的なものではありません。
とくに注目していただきたいのが、そのバリデーションのフィードバックの速さです。ConftestはローカルやCIで行うためフィードバックは早いです。Gatekeeperは実際にApplyしてからでないとわからないので、CI/CDを敷いているところだとかなり遅いフィードバックになってしまいます。そのために検証の役割というのも違っていて、ConftestはメルカリではApply前に素早くフィードバックを得るために行うような検証に使われています。
またここでWarningなどの警告を用いてベストプラクティスをデベロッパーに提案しています。GatekeeperはKubernetesクラスタの最後の砦として、実際にこのポリシーだけは守りたいみたいな、確実に課したいポリシーに対してGatekeeperでポリシーをかけてブロックしているような流れです。
全体のCI/CDのフローを整理すると、このような感じになっています。マイクロサービスをリポジトリにプッシュしてCIが走って、そこでConftestのバリデーションが走ります。そこを通ってもSpinnakerがデプロイしたときにGatekeeperのバリデーションがあります。
このようなかたちで組織的なルールをポリシーとして定義してConftestでCIでのチェック、Gatekeeperでの実際にApplyしてからのチェックを行うことによって、マイクロサービスのすべてに対してポリシーを課せます。
ポリシー自体もCI/CDを行っています。それを少し紹介したいと思います。Conftestにはユニットテストをする仕組みがあるので、ポリシー自体もテストできます。また先ほども紹介した通り、ConftestはRegoというポリシーファイルを用意して、GatekeeperはCRDを用意しなければならないので互換性がありません。
そこで実際にポリシーを開発するときに、ポリシーをプッシュするとそのポリシーをCRDに変換してGatekeeperのCRDとしてデプロイしています。このような仕組みを用意しているので、ルールがConftestのルールとGatekeeperルールで統一されているのがメリットです。どちらかのポリシーを通って、どちらのポリシーに通らないというケースはなくなります。
なのでOPAを導入することによって、各マイクロサービスのCI/CDの開発サイクルの中でポリシーを課しています。
次の問題点として、Spinnaker PipelineというのはデベロッパーがGUIで設定するので、設定ミスをしやすかったりデプロイ手法もサービスによって質が異なることが挙げられます。
その解決策として、デベロッパーはパイプラインを簡単な設定で作れる仕組みだったりとか、パイプラインを作成するとあとから変更できないイミュータブルな仕組み作り。そしてプラットフォームチームが各マイクロサービスのデプロイ手法を管理して、デプロイ手法の標準化だったりベストプラクティスを提供し続けられる仕組み作りが必要でした。そこでSpinnaker Managed Pipelineを導入することになりました。
ここでSpinnaker Managed Pipelineについて説明したいと思います。Spinnaker Pipelineは最初に説明したように、デベロッパーが作って設定して、それ基にGKEクラスタにマイクロサービスをデプロイしていました。
Spinnaker Managed PipelineというのはManaged Pipeline Template、MPTと言われる雛形になるようなものに各デベロッパーが設定情報を渡してできるパイプラインのことです。これらはすべてコードで定義されています。
Spinnaker Managed Pipelineの主な機能として、Sync機能、Immutable機能、Configuration機能があります。Sync機能はMPTを更新するとそのMPTから生成されたすべてのパイプラインも同時に変更できるという機能です。想定されるユースケースとしては、プラットフォームチームが各マイクロサービスのデプロイ手法を一括で変えたいなどのケースです。
次にImmutable機能は、Managed Pipelineを直接変更できない機能です。これによって意図しない変更を防げます。
Configuration機能とは、必要な部分だけMPTの一部を変数化して、Managed Pipelineの生成時に設定できるような機能です。この変数はイミュータブルではなくて、いつでも変更できます。
Managed Pipelineを使えばMTPを管理するだけで横断的に全マイクロサービスのパイプラインを管理できます。
図にして説明してみます。Sync機能は各マイクロサービスがPipeline ConfigurationsとMPTを基にManaged Pipelineを生成します。例えばプラットフォームチームがデプロイ先を変更したい、クラスタを作り変えたいといったときに、プラットフォームチームはMPTを変更するだけで、各マイクロサービスのパイプラインを変更できます。
それによってデベロッパーは何もしなくてもデプロイ先のクラスタを変更することが可能です。また、デプロイ先に限らずプラットフォームチームがカナリアデプロイとかデプロイのベストプラクティスを提供したいとなったときに、MPTさえ変えられればManaged Pipeline自体もそのベストプラクティスを実装することになって、各マイクロサービスのパイプラインがより質の高いものになります。
次にImmutable機能です。Managed Pipelineはあとから変更できません。なのでこのようなパイプラインを1回作ったあとにパイプラインを改変したいとか、デベロッパーが誤って設定し直してしまうことを防げます。
Configuration機能はマイクロサービスに依存する設定値だけパイプライン生成時に設定できるような機能です。この設定値だけはあとからデベロッパーが変更できます。しかし基本的なパイプライン自体はイミュータブルになっていて、あとから変更できません。
このSpinnaker Managed Pipelineのメリットを整理します。
Sync機能についてはプラットフォームチームがMPTを管理するだけで、全マイクロサービスのデプロイを管理できます。
Immutable機能についてはパイプラインをあとからデベロッパーに変更されて何か破壊的なことが起きてしまうことを防げます。
Configuration機能は必要な部分だけをデベロッパーに設定してもらう機能です。このような機能を使うことによって、マイクロサービスに必要な最低限の機能だけをデベロッパーに公開して、あとから変更されることもなく、マイクロサービス全体のデプロイの標準化と管理ができます。
このようなパイプライン自体もコードを管理していて、プラットフォームチームはMPTを保守・開発することによって全マイクロサービスのパイプラインを管理できます。なのでそのテンプレートだけの面倒を見ればいいわけです。
全体のデプロイ手法を管理するだけではなくて、クラスタマイグレーションだったり全マイクロサービスのパイプラインの変更を要するときも1つのMPTを変更するだけで済みます。この際にデベロッパーは何もする必要がないため、リスクを回避できます。
Spinnaker Managed Pipelineを導入することによって、プラットフォームチームが各マイクロサービスのデプロイを統括的に管理して質を向上できるようになりました。
最後にこれらのまとめをして終わりたいと思います。
まず前提としてマイクロサービスアーキテクチャの継続的デリバリーにおいてサービス全体の、全マイクロサービスの質を担保してすべてを安全にデプロイしていくことは一般的に難しいです。そのような中で安全な継続的デリバリーを行うためにも、ぞれぞれのマイクロサービスの開発の中でルール・ポリシーを課したりとか、デプロイをする仕組みをプラットフォームチームが提供するべきです。
今回のメルカリの例では、Open Policy AgentとSpinnakerのManaged Pipelineの機能を使うことによって、すべてのマイクロサービスのKubernetes Manifestへポリシーを課したりとデプロイを管理できて、より安全な継続的デリバリーを実現できました。
以上で終わりたいと思います。ありがとうございました。
関連タグ:
2025.02.13
“最近の新人は報連相をしない”という、管理職の他責思考 部下に対する「NG指示」から見る、認識のズレを防ぐコツ
2025.02.13
AIを使いこなせない人が直面する本当の課題 元マッキンゼー・赤羽雄二氏が“英語の情報”を追い続ける理由
2025.02.06
すかいらーく創業者が、社長を辞めて75歳で再起業したわけ “あえて長居させるコーヒー店”の経営に込めるこだわり
2025.02.12
マネージャーは「プレイング3割」が適切 チームの業績を上げるためのマネジメントと業務の比率
2025.02.14
報連相ができない部下に対するコミュニケーションの取り方 「部下が悪い」で終わらせない、管理職のスキル向上のポイント
2025.02.13
上司からは丸投げ、部下からはハラスメント扱い、業務は増加…プレイングマネジャーを苦しめる「6つの圧力」とは
2025.02.12
何度言っても変わらない人への指示のポイント 相手が主体的に動き出す“お願い”の仕方
2025.02.13
「みんなで決めたから」を言い訳にして仲良しクラブで終わる組織 インパクトも多様性も両立させるソース原理
2025.02.10
32歳で「すかいらーく」を創業、75歳で「高倉町珈琲」で再起業 「失敗したからすかいらーくができた」横川竟氏流の経営哲学
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
着想から2か月でローンチ!爆速で新規事業を立ち上げる方法
2025.01.21 - 2025.01.21
新人の報連相スキルはマネージメントで引きあげろ!~管理職の「他責思考」を排除~
2025.01.29 - 2025.01.29
【手放すTALK LIVE#45】人と組織のポテンシャルが継承されるソース原理 ~人と組織のポテンシャルが花開く「ソース原理」とは~
2024.12.09 - 2024.12.09
『これで採用はうまくいく』著者が語る、今こそ採用担当に届けたい「口説く」力のすべて
2024.11.29 - 2024.11.29
第20回エクゼクティブメンターイベント「今、「ひと」と組織が共創する〜働き方の未来へ」
2024.12.07 - 2024.12.07