有名テック企業の技術ブログを、ひとつのフィードで。
フィード
32件
こんにちは!Core SRE の 織田 英吾です。 キャディはクラウドネイティブ会議にブーススポンサーとして協賛させていただきました。 この記事では2日間にわたるイベント期間中のブースの様子や聴講したセッションの感想をレポートします。 ブース紹介 まずは、キャディのブースについて紹介します! ブースでは、 私たちが取り組む製造業にまつわる課題を知っていただくための「30秒図面捜索チャレンジ」を実施したり、おすすめの Claude Code Skills を共有するボードを用意しました。 以下が実際に寄っていただいた皆さんに記載いただいたボードの写真です。おすすめ Claude Code Skills や使っている機能などをたくさん教えていただきました。Skillsを自作されている方も多くいて、コードのレビューやドキュメント作成が特に多かった印象です。私が知らなかったものも多くあり、試してみようかと思いました。 私たちが提供している「製造業AIデータプラットフォームCADDi」のアプリケーションである「製造業データ活用クラウドCADDi Drawer」のデモも行いました。 デモを通して、製造業出身者や所属の方以外にも、製造業が抱える課題に共感していただくことができました。私自身、キャディが取り組んでいることの重要さを再認識することができた機会になりました。 名古屋での開催ということもあり、製造業出身や所属の方も多く、現場の声やペインポイントを聞くことができ、私が学ばせていただく機会にもなり、とてもいい経験をすることができました。 イベント期間中、キャディのブースに立ち寄ってくださった皆さん、本当にありがとうございました! 聴講したセッションの感想 次に、私や他のメンバーが聴講させていただいたセッションの感想を簡潔にまとめます。 「100マイクロサービスのTerraform/Kubernetes管理地獄から抜け出すためのAI活用術」 株式会社LegalOn Technologies の Ishigaki さんと Wada さんによる発表です。 本セッションでは、マイクロサービスの増加に伴って Kubernetes / Terraform 管理や設定変更、レビュー対応が大きな運用負荷になるという課題が紹介されました。その解決策として、定型的な変更作業は仕様化・ツール化し、AIエージェントを活用してサービス単位で並列に展開するアプローチが示されており、とても参考になりました。 特に印象的だったのは、AI にすべてを任せるのではなく、社内ルールやガイドラインを AI が参照しやすい形に整備し、人間が最終判断を担う設計にしていた点です。これにより、大量の PR 作成やレビュー支援、移行作業を効率化しながら、運用品質を保つ工夫がなされていました。 AI 活用の前提として、業務プロセスやナレッジを構造化しておくことの重要性を感じるセッションでした。(Core SRE 織田) 登壇資料: https://speakerdeck.com/markie1009/kubernetesguan-li-di-yu-karaba-kechu-sutamenoaihuo-yong-shu 「そのSLO99.9%、本当に必要ですか? 〜優先度付きSLOによる責任共有の設計思想〜」 株式会社TopotalのVTRyoさんによる発表を聴講しました。以前、SREKaigiでもVTRyoさんの発表を聞いたことがあり、とても参考になったので今回も楽しみにしていました。 本発表では、SREチームはDevチームのEnablingを突き詰めていくと、横断で複数のサービスを見ていくことが増えていくことで、運用しているサービスで何が起きているのか分からなくなる可能性が高くなりやすいと話されてました。実際に、VTRyoさんは自分たちはSREとしてサービスに価値を生み出していないのではないかと葛藤が生じたそうです。 そこで紹介されていたのが Product-Focused Reliability for SRE (PER)という考え方でした。自分は初めて聞いたのですが、SREチームが限られたリソースを有効活用するために、ビジネスやユーザーにとって最も重要なことに焦点を当て、優先順位をつけて活動することだそうです。 確かに、従来のSREはインフラやサービスそのものの安定稼働に責務を持つため、自然とDevはアプリケーション、SREはインフラという得意領域で境界が分かれてしまいやすいです。 PERの考え方は、SREの関心ごとをサービスからプロダクトの重要機能に移し、プロダクト中心にSLOを考えていくため、よりユーザーやビジネスの理解が重要になってきます。自分自身、SREが信頼性という指標を追っているのはユーザーの満足度とビジネスの成功度を上げるためだと思っているので、PERの考え方はとてもしっくりきました。 また、SREは日々のアラート対応に追われがちではありますが、それは本当にユーザーの離脱や解約につながっているのか?実は過剰な信頼性を追っているだけで、根本的な問題は機能不足なのではないか?、本セッションの問いとして投げかけられていた「そのSLO99.9%は本当に必要なのか」は定期的にSLOを見直す際に立ち返りたい問いだなと思いました。(Drawer SRE 松嶋) 登壇資料:https://speakerdeck.com/vtryo/is-that-99-dot-9-percent-slo-really-necessary-design-philosophy-of-shared-responsibility-through-prioritized-slos 登壇レポート キャディからCore SREチームリーダーの小林明斗が登壇しました。 セッション名:生成AI時代に信頼性をどう保ち続けるか - Policy as Codeの実践 概要:生成AIによりコードやIaCの変更量が増える中、人手のレビューやチェックリストだけでは信頼性リスクを見落としやすくなっています。本セッションで は、組織ポリシーのうち静的に評価できる項目をPolicy as CodeとしてCIや実環境に組み込み、人の認知に依存しすぎず信頼性を維持する設計を紹介し、ConftestやKyvernoの実装例を交え、誤検知対応、ポリシー強度、既存リソース是正など、形骸化しないガードレール運用の工夫を共有しました。 開発組織の変遷や SRE の歩みから入り Policy as Code の紹介、実装方法の共有がされていました。私はまだ入社3か月目なのもあり、キャディの私でも学べるセッションでした。 会場の席はほぼ埋まり、立ち見がでるほどの盛況ぶりで約100名の方が参加されていました! SNSでも「Policy as Code が気になっている」、「PRC のレビューが大変なのわかる」、「Policy 違反1,684件すべて修正完了はすごい」などたくさんの反響をいただきました。キャディから登壇者を出せてとても良かったです。 Policy 違反の Report に「Policy の詳細や OK/NG の例が記載された wiki」へのリンクを入れているらしい。これを見ることで Policy 違反が発生した時の開発者側での修正をやりやすくしてる感じっぽい。よさそう。#cloudnativekaigi #cloudnativekaigi_b— こたつ&&みかん (@kota2and3kan) 2026年5月15日 x.com 1684件すべて修正完了すごすぎる#cloudnativekaigi #cloudnativekaigi_b— yuki / ほにゃにゃ (@honyanyas) 2026年5月15日 x.com うおー、ポリシーに対するテストコード書けるのめっちゃいい。#cloudnativekaigi #cloudnativekaigi_b— たか (@_nogtk_) 2026年5月15日 x.com 登壇資料: speakerdeck.com 終わりに ブースへの来場・セッション聴講・懇親会と充実した2日間でした。クラウドネイティブな技術の進化は非常に速いですが、今回学んだ知見を業務に活かしていきたいと思います。 スピーカーの皆さん、参加者の皆さん、クラウドネイティブ会議の運営の皆さん、素晴らしいイベントをありがとうございました。今後もキャディは、技術的な挑戦や課題解決の知見を発信し、エンジニアコミュニティへの貢献を続けていきます。今後のイベントでもお会いできるのを楽しみにしています!
製造業データ活用クラウド CADDi Drawerで SREを担当している佐藤です。 組織編成でCADDi Drawer専任のSREになったことを機に、長らく後回しにしていたDatadog MonitorのTerraform構成の再設計に取り組みました。複数チームの監視設定が単一リソースに混在しOwnershipが不明確なため、各チームが自律的に改善に踏み出せない状態でした。 本記事ではこの課題をOwnership単位のモジュール設計で解消した経緯と学びについて紹介します。 監視設定が抱える課題 単一リソースに積み上がった監視設定 Ownershipの不在によるアラート改善の停滞 Ownershipを明確化したモジュール設計 監視ロジックとOwner情報の分離 Owner情報の一元管理 ふりかえり よかったこと 苦労したこと 移行の現状と今後 おわりに 監視設定が抱える課題 キャディでは監視基盤にDatadogを採用しており、Datadog Monitorはすべて監視用の単一リポジトリでTerraform管理しています。 歴史的経緯により、監視すべき内容については検討できていましたが、Terraformモジュールとしてどう実装するかは整理されていませんでした。 このためDatadog MonitorのTerraform実装には以下のような課題を抱えていました。 単一リソースに積み上がった監視設定 Terraformモジュールの設計が難しい問題です。適切な抽象化の粒度を見極め、再利用可能な形でモジュール化するには、対象サービスや組織の全体像が見えていることが前提になります。 組織・サービスが急成長していた時期には監視対象が次々と増え、その都度設計を見直す余裕はありませんでした。この結果、再利用可能な形でのモジュール化は採用せず、既存の設定を拡張する形で対応し続けていました。 具体的には、監視対象のサービスが増えるたびに新規のモジュールやモニターを構築することはせず、既存の単一のDatadog Monitorに対象サービスを追加し続けていました。 Terraformのdatadog_monitorリソースでは監視条件をquery属性の文字列として定義しますが、サービスが増えるたびにOR条件を追記し続けた結果、以下のような状態になっていました。 logs( "status:error (service:SERVICE_A OR (service:SERVICE_B -message:\"noisy message\") OR service:SERVICE_C OR service:SERVICE_D OR (service:SERVICE_E env:production))" ).index("*").rollup("count").last("5m") > 100 組織規模が小さく、サービス数が2-3個の場合やサービス固有の除外条件が含まれていない場合にはこれでも上手くいきました。 しかし、サービス数が増え、サービスごとの監視条件が混在するようになると、とたんにコードからどのサービスがどの条件を持つのか読み解くことが困難な状態になりました。 また、問題の兆候は認識していましたが、全サービスに影響する監視設定の一括整備に踏み切るきっかけがなく、他のタスクを優先していました。 Ownershipの不在によるアラート改善の停滞 この課題に向き合うきっかけになったのが2025年に実施した組織編成です。 それまで全社横断でインフラ運用を担っていたSREチームから、サービス・プロダクトごとにSREが配置される形になりました。 私はCADDi Drawer専任のSREとして新たな役割を担うことになりました。 CADDi Drawerの信頼性向上に絞った視点で改めて監視設定を見ると、Datadog Monitorの複雑化に関する問題が浮き彫りになりました。 複数サービスの設定が混在したクエリへの変更は、git diff や terraform planでも影響範囲が掴みにくい状態でした。 Ownerの異なるチームが同じリソースを共有しているため、「他チームに影響しないか」という懸念が変更の腰を重くし、細かな改善がどんどん後回しになっていました。 クエリ実装の複雑さ以上に懸念になっていたのがSlackのアラート通知先の混在でした。 Datadog MonitorのSlack通知チャンネルの動的切り替えはクエリ条件以上に複雑になるため、Datadog Monitorごとに単一のSlackチャンネルに通知していました。 その結果、複数チームのアラートが同じSlackチャンネルに通知され、関係のないアラートであっても内容を都度確認する割り込みコストが発生していました。 SREチームで議論した結果、これらの問題の根本は、どのチームがどのモニターに責任を持つかが不明確というOwnershipの欠如にあると判断しました。 複数チームのサービスが1つのdatadog_monitorリソースを共有しているため、変更が他チームに影響するかどうかを確認せずに修正できません。 自チームの判断だけで変更に踏み切れず、誰も主体的に手を入れられない状態になっていました。 Ownershipを明確化したモジュール設計 これらの課題を解決し、Datadog MonitorのOwnershipを明確化するため、監視項目のTerraformモジュールを設計して移行しました。 監視ロジックとOwner情報の分離 従来の構成では、通知先や担当チームといったOwner情報がモジュール内に直接書き込まれていました。Owner情報が埋め込まれた構造では、呼び出す側がチームごとの情報を渡す設計にはできません。 具体的には以下のような構成でした。 terraform/ ├── modules/ │ └── monitor/ │ └── shared_monitors/ # 全サービス・全チームの監視設定が混在 └── environments/ ├── <google_project>-development/ │ └── main.tf # shared_monitorsモジュールを呼び出す └── <google_project>-production/ └── main.tf # shared_monitorsモジュールを呼び出す terraform/environments/<environment>/main.tf が shared_monitors モジュールを呼び出す構成です。このモジュールに全サービス・全チームの監視設定が集中していたことが、前述の問題の原因でした。 そこでこのモジュールを解体し、監視ロジックの情報に限定したモジュールを作成した上で対象サービス・通知先・担当チームといったOwner情報は呼び出し元から変数として渡す設計にしました。 具体的には以下のような構成です。 terraform/ ├── main.tf # environments をモジュールとして呼び出す ├── teams.tf # チーム情報を一元定義 ├── modules/ │ └── common/ │ ├── cloudrun-service/ # Cloud Run監視モジュール │ ├── alloydb/ # AlloyDB監視モジュール │ └── ... └── environments/ └── <google_project>-production/ └── service-a/ ├── locals.tf # 通知先・Owner情報を定義 └── main.tf # 各監視モジュールをOwner情報と共に呼び出す 監視項目の種類( cloudrun-service など)ごとにモジュールを定義し、 terraform/environments/<environment>/<service>/ というサービス単位のディレクトリから呼び出す構成です。 モジュール自体は監視対象のプロダクトを知らず、呼び出すディレクトリごとにOwnershipが決まるため、「誰がどのアラートに責任を持つか」がディレクトリ構造として表れます。 各モジュールに対するOwner情報を変数として以下のように設定することで、サービスごと・モニターごとのOwnershipを明確化できました。 # environments/project-production/service-a/main.tf module "cloudrun_service_monitor" { source = "../../../modules/common/cloudrun-service" service_name = "service-a" env = "production" owner_teams = local.owner_teams mention_slack_alert_ch = local.mention_slack_alert_ch mention_oncall = local.mention_oncall } この設計により、変更の影響範囲が自チームのスコープに収まり、他チームを巻き込まずに監視設定を改善できるようになります。移行後はこの設計方針をドキュメントにまとめ、社内で共有しました。設計を標準として明文化することで、チーム間の設計認識を統一し、今後の監視設定追加・変更にも一貫したOwnership管理を維持できるようにしました。 Owner情報の一元管理 監視対象ごとにDatadog Monitorが分割されることで、移行後はモニターの総数が増えます。多数のモニターを管理するにはタグ情報が欠かせないため、各Datadog Monitorへのタグ付けを徹底しました。 タグ自体は従来から設計に組み込まれていましたが、今回の移行を機に全Datadog Monitorへの適用を強化しました。 タグ情報の適用を強化する上で、通知先Slackチャンネル、担当チーム名といったOwner情報を各サービスの設定に個別に書き込むと、組織変更のたびに全サービスのファイルを修正する必要があります。また、複数の場所に分散して書くとチーム名やSlackメンションの表記ゆれも起きやすくなります。 そこで、チーム情報を teams.tf に一元定義しました。Datadog Teamリソースもここで合わせて作成します。 # teams.tf locals { owner_teams = { team_alpha = { name = "Dept A > Group A > Team Alpha" mention = "<!subteam^XXXXX>" # @team-alpha tag = "team:team_alpha" } team_beta = { name = "Dept B > Group B > Team Beta" mention = "<!subteam^YYYYY>" # @team-beta tag = "team:team_beta" } } } resource "datadog_team" "teams" { for_each = local.owner_teams name = each.value.name handle = each.key } 組織変更が起きた場合も teams.tf の修正だけで全サービスに反映されます。 ふりかえり よかったこと サービスごとに通知先を変更できるようになったことがメリットとしては大きいです。 チームごとにSlackチャンネルを切り分け、CADDi Drawer 関連のアラートのみに集中できる環境を整えたことで、業務への割り込みを最小限に抑えることが可能になりました。 datadog_monitor がOwnerごとに分割されたことで、PRレビューの負荷も下がり、自チームの判断だけで変更をマージできるようになりました。 モジュール化に伴い監視条件を変数として宣言的に記述する構成になったことで、各サービスの監視条件を個別に把握できるようになった点も嬉しいポイントです。 苦労したこと 最も苦労したのはDatadog Monitor移行に伴うPRレビューです。Datadog Monitorリソースの分割には destroy / create が伴う上、クエリの整理も必要だったため、大量の terraform plan の差分が発生しました。これをすべて人手で確認しきることは難しく、想定以上にレビューに時間がかかってしまいました。 今回は利用できませんでしたが、AIを活用したリソース移行の半自動化や設定差分の検出など、効率化の仕組みを今後の大規模移行に活かしたいと考えています。 移行の現状と今後 作業リソースやスケジュールの都合上、通知頻度の高いコンポーネントの移行を優先して完了させました。旧モジュールへの新規追加を禁止することでこれ以上の複雑化を防ぎつつ、通知先のチャンネル分離も継続して進めています。一方、一部のDatadog Monitorはまだ解体する必要があるものが残っており、引き続き整備を進める予定です。 設計方針はドキュメントとして共有しているものの、まだ十分に浸透できているとは言えません。設計の定着にはドキュメントだけでなく、ポリシーチェックをCIに組み込むような仕組みも必要だと感じています。今後は組織横断チームと連携しながら検討を進めていきます。 おわりに 組織の自律性を高める上で、監視設定のOwnershipも合わせて整備することが重要だと実感しました。Ownershipが明確であれば、自チームの判断だけで監視設定を改善でき、変更のスピードも上がります。 今回は組織編成がきっかけとなり、長らく後回しにしていた構成の再設計に取り組むことができました。 普段から監視設定を気軽に修正できる状態を維持し、組織や役割が変化した際には監視のOwnershipが適切に機能しているかを継続的に見直していきます。
こんにちは、SRE Team の大野です。製造業データ活用クラウド CADDi Drawer の Product SRE として、サービスの信頼性の向上や、効率的な運用を目指す取り組みを行っています。 今回は Cloud Run ワークロードの OOM 対応に Datadog Continuous Profiler を導入した際の、ハマりどころや学びについてのお話をします。 TL;DR はじめに Cloud Run での Profiler 選定 導入時のハードル 公式 Wrapper が使えない Profiler 単体で動かすための環境変数 プロファイリング結果の分析 プロダクト理解から見えた掛け算の構造 複数の観点で判断する 改善提案のまとめ方 Claude Code を活用した横断的調査 おわりに TL;DR Cloud Run ワークロードの OOM 調査にて Datadog Continuous Profiler を利用、Cloud Run 特有の導入ハードルや環境変数の罠があった Compare 機能でスパイク時のメモリ増分を特定し、複数要因の掛け算で消費が増大する構造を解明 問題指摘で終わらず、レイヤーごとの改善提案を開発チームに共有して意思決定を支援 はじめに CADDi Drawer は、図面や仕様・不具合情報といった複数種別のデータから、関連性や類似性をもとに検索・集約する機能を持っています。 先日、その処理を担う Cloud Run ワークロードが頻繁に OOM を起こすようになり、ユーザー体験に影響が出る程度のパフォーマンス劣化を引き起こしていました。ユーザー影響を抑えるためにひとまずメモリ増強によって延命したものの、根本原因は掴めておらず、再発リスクの見通しも立っていない状況でした。 原因を突き止めるためにメモリプロファイリングの手法を検討した結果、Datadog Continuous Profiler を試験的に導入してメモリ消費構造を可視化することにしました。Profiler の結果と他の観点での分析を組み合わせて問題構造を紐解き、具体的な改善提案にまとめることができました。現在は改善が実施され、問題は解消しています。 Cloud Run での Profiler 選定 Cloud Run でメモリプロファイリングをやろうとすると、案外「これだ」と言える整った手法がないことに気づきます。取りうる手段をミニマムに整理しました。 🤔 Google Cloud Profiler: Google Cloud ネイティブだが、そもそも Cloud Run がサポート対象外 🤔 自前での heap dump: Node.js の場合はヒープスナップショット取得中にリクエスト処理が停止するため、本番環境での実施はリスクが高い 💡 Datadog Continuous Profiler: 全社的に Datadog を利用しており親和性が高い、2026 年 3 月時点ではプレビュー扱いで追加費用なく試せた、APM なしで Profiler 単体で動作する 消去法的ではありますが、スピード重視で Datadog Continuous Profiler の導入を決めました。 導入時のハードル いざ決まったものの、Cloud Run への導入は一筋縄ではいきませんでした。 公式 Wrapper が使えない Datadog は Cloud Run 向けに Terraform Wrapper モジュール を提供しており、これを使えば簡単に導入できるはずでした。しかし 2 つの壁にぶつかります。 1 つ目は Cloud Run API バージョンの問題です。 Wrapper モジュールは Cloud Run API v2 を前提としていますが、対象ワークロードは API v1 で管理されていました。Google Cloud の移行手引き を参考に v1 → v2 への Terraform import で解消しましたが、API バージョン間でパラメータ記法の変更(annotation からの移行など)があり、単純な import だけでは済みません。意図しない差分からリソースの再作成を引き起こすとサービス断に直結するため、plan 結果を慎重に確認しながら進める必要がありました。 2 つ目は CI/CD フローとの衝突です。 このワークロードでは、Terraform の管理外で GitHub Actions がイメージタグを書き換えることでデプロイしていました。このため Terraform 側では lifecycle { ignore_changes } で image の変更を無視する必要があります。しかし利用時点の Wrapper モジュールではその設定ができず、apply のたびに意図しないイメージの巻き戻しが発生してしまいます。 この時点で Wrapper モジュールの利用を断念し、serverless-init をサイドカーコンテナとして直接組み込む方式に切り替えました。この構成では、アプリケーションコンテナ側で dd-trace ライブラリがプロファイルデータを収集し、サイドカーの serverless-init が Datadog Agent として Datadog へ中継する形になります。 Profiler 単体で動かすための環境変数 弊社ではトレーシングに OpenTelemetry 経由で Google Cloud Trace を利用しているため、Datadog APM や Tracing は使わずに Profiler だけを有効化したいという状況でした。 しかし dd-trace にはトレーシング関連の環境変数が DD_TRACE_ENABLED, DD_TRACING_ENABLED, DD_APM_TRACING_ENABLED と似た名前で複数存在します。たとえば DD_TRACE_ENABLED=false は dd-trace ライブラリ全体を停止するため Profiler も止まってしまいます。 今回は組み合わせを検証する時間が限られていたため、なるべく Trace を送信せず APM も止める方向で安全側に倒すよう、下記で設定していました。 # アプリケーションコンテナ(dd-trace を init() する側) DD_PROFILING_ENABLED=true # Continuous Profiler を有効化 DD_APM_TRACING_ENABLED=false # Agent → Datadog APM への転送を無効化 DD_TRACE_SAMPLE_RATE=0 # トレースのサンプリングを 0% に # serverless-init サイドカー(Datadog Agent 側) DD_PROFILING_ENABLED=true # Profiler データの受け付けを有効化 DD_APM_TRACING_ENABLED=false # Agent → Datadog APM への転送を無効化 # DD_ENV, DD_SERVICE 等のユニバーサルサービスタグは両コンテナに必要(後述の公式ドキュメント参照) 詳細はライブラリやイメージのバージョンによって挙動が変わりうるため、公式ドキュメント(共通設定)および Node.js 固有の設定 を参照のうえ、実環境での検証を組み合わせて確認することをおすすめします。 プロファイリング結果の分析 Profiler が動き始めると、公式ドキュメント にもある通り、ある時点でのメモリ内訳確認や Insight によるボトルネック候補の自動提示など、いくつかの分析手法が使えるようになります。 今回特に効いたのが Compare 機能です。平常時とメモリスパイク発生時の Heap Live Size を並べることで、単一時点では区別がつきにくいスパイクの原因が明確になります。 冒頭で触れた通り、対象のワークロードは複数種別のデータから関連性や類似性をもとに検索・集約する処理を担っており、そのためのメモリ消費が中心になっています。 実際に比較すると、スパイク時にしか出現しない関数(Compare では「Only in B」と表示)が見つかりました。図ではマスクしていますが、特定条件下での検索クエリ構築やレスポンス保持の関数群にヒープ増分が集中していることが、画面から読み取れるようになっています。 Datadog Profiler 実画面イメージ この結果から、「常にメモリを多く使っている処理」ではなく「特定条件下でメモリを大量消費する処理」が原因であるという仮説が立ちました。 プロダクト理解から見えた掛け算の構造 Profiler の結果はあくまで「何がメモリを消費しているか」を示すだけで、「なぜそうなるのか」「どう対処すべきか」は別の分析が必要です。該当する機能がどのようなものでどう使われているのかを、仕様書や機能説明資料、直近の開発プロジェクトの動向から読み解きました。 CADDi Drawer は、顧客ごとに異なる課題を幅広く解決するデータプラットフォーム上でデータの探索・分析を担うプロダクトです。大半の利用シーンではメモリ消費も穏やかに収まりますが、特定の利用パターンでは画面表示のための検索エンジンへのクエリが、非常に複雑になることがあります。 まさに今回はこの事象を踏んでおり、リクエストあたりの処理量が複数の要因の掛け算で増大するケースに該当していました。個々の要因は単体では大きな問題にならないものの、これらが重なった際にメモリ消費が一気に跳ね上がります。 Profiler の Compare で特定の処理にヒープ増分が集中していたのも、この掛け算構造がスパイク時に顕在化した結果です。 複数の観点で判断する 掛け算構造が見えてくると、Profiler の結果だけで判断するのは危ういことに気づきます。チームメンバーからのフィードバックも踏まえ、以下の観点を加えました。 リクエストパターン: 同時かつ並列でリクエストが集中していないか 単発では問題にならないメモリ消費も、並列度が上がると一気にスパイクに繋がる リードタイム: 処理がどれくらい長引くか 長時間メモリを保持し続けることで、GC が追いつかずメモリ消費が積み上がるケースがある 発生頻度: 頻繁に起こるのか、稀なのか 稀であっても、データ量の増加やリクエストパターンの変化で「いつ爆発してもおかしくない」構造なのかを見極める必要がある 改善提案のまとめ方 問題構造が見えたら、開発チームが動きやすい形で提案をまとめる必要があります。今回は以下のように整理しました。 レイヤーごとに対策を分ける フロントエンド・バックエンド・API スキーマ・インフラなど 掛け算構造のすべての要因に単一の対策では対処できないため 今回の例では、API スキーマへの入力制約の追加や、検索エンジンへのクエリ構造の改善といった対策を提案 実現しやすさ順に並べる まず実態把握、次にすぐ効果が出る対策 構造的な改善は並行して検討 プロダクト判断が必要な境界を明示する 仕様の見直しを伴う対策は SRE だけでは判断できない どの対策が技術的に閉じるもので、どの対策が PdM や開発チームとの議論を要するのかを切り分けることで、関係者ごとに次のアクションが見えやすくなる 「ここが問題です」で終わるのと「こういう構造なので、この順で対処するのがよさそうです」まで持っていくのとでは、開発チームへの引き継ぎのスムーズさが変わります。 Claude Code を活用した横断的調査 今回の調査では Claude Code も活用しました。大規模かつ変化が激しいシステムでは、コードベース全体を頭に入れるのは現実的ではありません。複数リポジトリにまたがるコードフロー(ロジックの流れ、リクエストの経路、コンポーネント間の繋がり、インフラ設定)を横断的に追う場面で非常に重宝しました。 既に一般的になりつつありますが、工夫していた点をいくつか挙げます。 MCP 経由で調査対象を広げる GitHub のソースコードだけでなく、Datadog のログやメトリクスにも MCP Server 経由でアクセス コードの静的な構造とランタイムの挙動を突き合わせる調査を、コンテキストを切り替えずに一連の流れで実行できた subagent でコンテキストウィンドウを節約 フロントエンド・バックエンド・検索サービスのリポジトリ群を横断する必要があり、各コンポーネントの詳細調査を subagent に委譲 メインのコンテキストウィンドウには要約だけが残るので、Compacting Conversation の頻度を減らすことが出来た ドキュメントの下書きに使う 問題を構造的に説明しようとすると、ファクトを並べるだけでも文量が膨らむ 下書きを作らせたうえで、自分の理解と照らし合わせながら論点を絞り込んだ おわりに Cloud Run ワークロードに Continuous Profiler を導入し、OOM の根本原因を特定して改善提案に繋げた一連の流れを紹介しました。 振り返ると、重要だったのは以下の 3 点です。 ツールを入れて終わりにしない Profiler の出力はあくまで出発点であり、そこからプロダクトの仕様・使われ方・リクエストパターンを重ね合わせて、問題の構造を明らかにする 総合的に判断する プロファイリング結果だけでなく、頻度・リードタイム・並列度といった実利用での観点を加えて、対処の優先度を見極める 改善提案まで持っていく 問題を指摘するだけでなく、具体的な対策案と優先度の根拠を示して、開発チーム全体の意思決定を支援する 「ボトルネックを見つけて改善する」という行為は一見シンプルですが、そこに至るまでの選定・導入・分析・提案のそれぞれに SRE としての判断と工夫が求められます。同様の課題に取り組む方にとって、本記事が何かしらの参考になれば嬉しいです。 キャディの Product SRE は、インフラの運用に閉じることなく、プロダクトの仕様理解から改善提案まで踏み込める環境にあります。今回のようにプロファイリングで得た技術的なファクトを起点に、開発チームや PdM と協働しながらプロダクト全体の信頼性を高めていく働き方に興味がある方は、ぜひ キャディの Tech 採用ページ をご覧ください! また、キャディは 5 月 14 日(木)から 5 月 15 日(金)の 2 日間、名古屋で開催されるクラウドネイティブ会議にブーススポンサーとして協賛します! 当日は SRE や Platform Engineering に関わるメンバーを中心に 7 名が現地の会場を訪れる予定です。 参加される方は、ぜひ会場のブースにも遊びにお越しいただけると嬉しいです。 caddi.tech
こんにちは!CADDi Drawer SREの松嶋です。 キャディは、5月14日(木)から5月15日(金)の2日間、名古屋で開催されるクラウドネイティブ会議にブーススポンサーとして協賛します! 当日は弊社のSREやPlatform Engineeringに関わるメンバーを中心に7名が現地の会場を訪れる予定です。 会場でお会いできるのを楽しみにしていますので、ぜひ弊社のブースに足を運んでいただけると嬉しいです。 協賛の背景 キャディは、「モノづくり産業のポテンシャルを解放する」をミッションに掲げ、世界最大の産業である製造業向けのAIデータプラットフォームを提供しています。 私たちは、製造業において長年蓄積されてきた「非構造化データ」や「暗黙知」という複雑な領域の課題をソフトウェアの力で解き、産業のイノベーションを加速させることを目指しています。 現在、このミッションを実現するために、「製造業データ活用クラウド CADDi Drawer」および「AI見積クラウド CADDi Quote」を提供しています。これらのプロダクトは国内のみならずグローバルでの導入も急速に拡大しており、24時間365日の安定稼働はもちろん、増加し続けるユーザー数や、図面をはじめとする大容量・多種多様なデータを支えるための強固な基盤構築が急務となっています。 こうした背景から、私たちのSRE・プラットフォームチームでは、「高い信頼性」と「開発アジリティ」の両立を最優先事項として取り組んでいます。 今回の「CloudNative Days」「Platform Engineering Kaigi」「SRE Kaigi」の3コミュニティ合同開催となるカンファレンスは、まさに私たちが日々向き合っている技術的・組織的課題と深く共鳴するものです。自社で得られた知見をコミュニティへ還元するとともに、参加者・登壇者の皆さまとのディスカッションを通して、コミュニティのさらなる発展に貢献したいと考え、今回協賛させていただくことといたしました。 SREチームリーダーの小林が登壇します! 弊社からはCentral SREのチームリーダーである小林(@akitok_)がDay2の11:10より「生成AI時代に信頼性をどう保ち続けるか - Policy as Codeの実践」というタイトルで登壇します。 当日の発表資料は、後日公開予定です。 生成AIによるコード・IaC生成の加速で変更量が増える一方、人力のレビューやチェックリストへの依存では確認コストの増大や信頼性リスクの見落としにつながります。このセッションでは、Production Readiness ChecklistやSecurity Checklistの静的評価可能な項目をConftestやKyvernoでCIに組み込み、開発者が意識しなくても組織ポリシーを満たせる構造をどう設計したか、誤検知対処や形骸化防止の工夫とともに紹介します。 ブースでは製造業において最重要な「図面」にまつわるクイズ企画を実施します! 今回、モノづくりの地である名古屋で開催されることに合わせ、キャディのブースでは、製造業において最も重要かつ複雑な「図面データ」をテーマにしたクイズを用意しております。私たちのプロダクトを通して向き合っている製造現場の課題を、クイズを通してぜひ楽しみながら体験してください。 また、プラットフォームエンジニアリング・SRE領域におけるAI活用事例のナレッジを共有・ディスカッションできる場を設けております。 ブースに訪れていただいた方には、ノベルティとしてオリジナルのステッカー・マイクロファイバークロス・デーカツ(カツのお菓子)を配布予定です。 イベントで人気のデータ活用カツ また、5月15日(金)の12:00〜13:30頃には、セッション登壇者の小林がブースに常駐しておりますので、登壇内容について質問がある方、ディスカッションしたい方、ゆるく雑談したい方など、ぜひお気軽にブースにお越しください! さいごに キャディでは、今回初めての協賛となります。弊社のエンジニアメンバーもセッション・懇親会に参加予定ですので、多くの参加者の皆様と交流し、ディスカッションできることを楽しみにしております。 私自身、久しぶりにゆかりのある名古屋に訪れることができるので嬉しく思います。 また、魅力的なセッションがとても多く、どのセッションを聴講するか悩ましいですが、特に「サンプリングは「作る」のか「使う」のか?分散トレースのコストと運用を両立する実践的戦略」、「実践AI SRE — AIワークロードの自律的パフォーマンスエンジニアリング」のセッションが個人的に楽しみです。 では、現地でお会いできるのを楽しみにしております。よろしくお願いいたします! キャディのSRE/Platform Engineering関連の記事 caddi.tech caddi.tech caddi.tech
こんにちは、昨年キャディ株式会社に入社した佐野です。入社して初めての技術記事になります。 この記事では、これまでの開発経験を振り返りながら、それが推論システムの運用にどう活きたのかを整理してみようと思います。 対象読者 機械学習システムを運用したことがないSRE、バックエンドエンジニアの方々 これから機械学習システムを運用していくSRE、バックエンドエンジニアの方々 伝えたいこと 機械学習のモデル開発経験や機械学習システムの運用経験がなくても、機械学習システム(推論システム)の運用に貢献できます。SREの領域と被るものが大半であるため、今までの経験を活かせることが大半です。 入社前までの経験 直近5年くらいはバックエンド、SREを往復するようなキャリアでした。APIの設計・開発から始まり、DB設計、システム設計などを色々やっておりました。機械学習の経験はというと、プロジェクトで半年ほど画像認識で使用する画像をOpenCVでコネコネしていたことはあります。ただそれも7年以上前なので、記憶の彼方に消えてしまってます。 配属先のチーム キャディに入社後の私の配属先のチームは、Analysis Platformチームで、機械学習システム(推論システム)を開発・運用しています。具体的には、モデル開発以外(システム設計、API設計・開発、インフラ構築など)の業務を全て担っています。 役に立った経験 実際チームでシステムを運用、タスクを消化していく中で感じたことは、バックエンド、SREの経験をそのまま使えるということです。例えば、以下のような経験はそのまま活かすことができます。 システム設計 データリソースの選定 モニタリングやアラートの設計/運用 ネットワーク設計 など システム設計(非同期設計) システム設計については、推論システムだからといって特別なものはほぼなく、通常のシステム設計の考え方(非同期設計など)に似た部分が多いように感じています。その中でも特に非同期設計の経験は役に立ちます。なぜ役に立つかは後述します。 データリソースの選定 この経験も非常に有用だと考えています。推論APIの設計にも依存しますが、モデルによってはAPIのレスポンスが肥大しがちです。例えば物体検出のモデルでは、検出数によってレスポンスが大きくなることもあり得ます。この推論結果をどのデータリソースに格納するのが望ましいかは腕の見せ所であり、面白いポイントだと感じています。Cloud SQLのようなRDB、mongoDBのようなNoSQL、GCSのようなストレージサービスなど様々な選択肢がある中で、要件に応じた選定を行う必要があります。これを決めていくにあたり、これまでのデータリソースの運用経験が非常に活きると考えています。 モニタリングやアラートの設計/運用 推論システムといえど、運用という点ではこれまでのシステムとほぼ変わりません。SLOの定義や、アラート疲れを起こさないための運用設計など、まさにSREの知見が求められるシーンが多かったです。 また私が入ったタイミングで、既存の推論システムをGKEへ移行しており、システムをいかに安全に移行するか、モニタリングをどう再設計するかなどの知見も非常に有用でした。 zenn.dev 通常システムとの違い 今までの経験がいきるとはいえ、推論システムと通常システムには多少違いがあります。自分の中で感じた部分を少し書ければと思います。 非機能要件: 非同期処理にしたい モデルによって推論に時間がかかることはしばしばあります。例えば物体検出のモデルでは、検出数が多ければ多いほど推論に時間がかかるため、処理時間が数十秒になることも珍しくありません。そのため非機能要件を定めるに当たっては注意が必要になります。システムを運用する視点では、非同期処理によせることができれば、同期処理と比較し、シビアに処理時間を気にしなくて良くなります。 また、当たり前ですがGPUは通常のインスタンスと比較してコストが高くなります。そのためGPUを使用しないときは、インスタンスを停止してコストを抑える必要があります。具体的にはkubernetesの場合はKEDAのScaledObjectなどを使い、使用していない期間のインスタンスの停止などの工夫を行い、コストを抑える必要があります。 このようなこともあり、非同期処理の経験が非常に活かせると考えています。 技術選定: GPUを利用するための術を知りたい 推論システムを運用していく上で避けて通れないのは、GPUの運用です。私の知る限りGoogle Cloudでは、Compute EngineはもちろんのことマネージドサービスであるVertex AI、サーバーレスであるCloud RunでもGPUを扱えます。これらの選択肢の中で、何が要件としてマッチしているかは検討できるようになる必要があると感じています。 docs.cloud.google.com 余談ですが、Compute Engineのマシンタイプでは、A2 マシンシリーズやN1 マシンシリーズ(T4)、G2マシンシリーズ(L4)という名前が出てきます。最初これらのアルファベットを聞いて、何を言ってるのかさっぱりわからなかった記憶があります。 docs.cloud.google.com リソース管理: GPUを効率的に使いたい GKE上でGPUを効率的に使用するにはいくつか方法があります。マルチインスタンスやタイムシェアリングなどの方法があります。私はまだ実装経験はありませんが、これらをどのように使っていくかはまさに推論システムの特徴なのではと感じています。 docs.cloud.google.com ライブラリ管理: マイナーバージョンの更新であっても細心の注意を払いたい 機械学習で使用されるライブラリであるnumpyやtorchなどのバージョン更新には細心の注意が必要です。たとえマイナーバージョンの更新であってもnumpyは2.0系統であれば、推論結果に影響が出る可能性があるようです。私もPR作成時に意図せずバージョンが上がった時があり、機械学習エンジニアに指摘してもらうことがありました。 最後に まだまだ入門したばかりで、学ぶことも多々あると思いますが、SREやバックエンドでの経験は確実に活き、運用できていると感じます。皆さんもぜひチャレンジしてみてくださいね!
こんにちは、Infrastructure Teamの宮本(@m1yam0t0)と申します。 本記事では、キャディの権限昇格システムの取り組みを紹介します。 目次 目次 はじめに 内製システムから Google Cloud PAM への移行 PAM の利用資格の設定 PAM の運用で工夫していること Slack 通知機能の実装 Devin による利用資格設定の自動化 まとめ はじめに みなさんは、パブリッククラウドの権限はどのように管理されていますか? IAMでメンバーに必要な権限を付与していますでしょうか?TerraformでIaC管理されていますでしょうか? キャディでは、最小権限の原則に従って、開発者には閲覧系の必要最低限の権限のみを付与しています。*1 開発・運用で追加の権限が必要になった場合は、Just-In-Time(JIT) Accessの仕組みで一定期間だけ権限昇格できるようになっています。 開発者が権限を申請し、承認者が承認してはじめて権限が付与されます。 最小権限の原則を徹底することで、昨今利用が広がっているAIエージェントを活用した場合にも、本番環境の権限を持っていないため、誤って操作してしまうリスクを低減できます。 本記事ではこのJIT Access Systemを内製システムからGoogle Cloud Priviledged Access Manager(PAM)に移行したお話を紹介いたします。 内製システムから Google Cloud PAM への移行 キャディでは、2022年より内製のJIT Access Systemを運用しておりました。 しかし、この内製のJIT Access Systemについて、認可制御に課題があったため、IAM Condition を組み合わせて権限が付与できるように改修を検討していました。 そんな中、Google Cloud PAM のアップデートで、権限のスコープが設定可能になったことを知り、検証をしてみたところ、内製のシステムを改修しづつけるより、効率良く目的を達成できることがわかりました。 IAM release notes | Identity and Access Management (IAM) | Google Cloud Documentation 上記を踏まえて、以下の理由から、キャディのJIT Access SystemをGoogle Cloud PAMへ移行する価値があると判断し、移行を実施いたしました。 権限のスコープを細かく設定でき、取得する権限を必要最小限に抑えられる Cloud Loggingに監査ログが残るため、通知や監査に活用できる Google Cloudマネージドのサービスであるためメンテナンス不要 PAM の利用資格の設定 Google Cloud PAMでは、取得したい権限のセットを利用資格として定義し、必要な権限に対応する利用資格を選択して申請します。 Terraform Provider が公式で提供されているため、IaCで管理できます。 利用資格はユースケースごとに複数作成するため、 以下のようなTerraform moduleを定義し、変数を入力することで容易に設定できるようにします。 resource "google_privileged_access_manager_entitlement" "entitlement" { provider = google-beta entitlement_id = var.entitlement_id location = var.location parent = var.parent max_request_duration = var.max_request_duration eligible_users { principals = var.eligible_users } privileged_access { gcp_iam_access { resource_type = var.resource_type resource = var.resource dynamic "role_bindings" { for_each = toset(var.roles) content { role = role_bindings.value } } } } approval_workflow { manual_approvals { require_approver_justification = var.require_approver_justification steps { approvers { principals = var.approvers } approvals_needed = var.approvals_needed approver_email_recipients = var.approver_email_recipients } } } additional_notification_targets { admin_email_recipients = var.notification_emails } requester_justification_config { unstructured {} } } 実際に利用する箇所では以下のようにTerraform moduleを呼び出して定義しています。 申請・承認するユーザを設定できるため、チームによって申請可能な利用資格を設定できます。 module "pam_org_gcs_bucket_read_access" { source = "../../modules/pam" # 利用資格名 entitlement_id = "gcs-bucket-read-access" # Organization, Folder, Project 単位で指定可能 parent = "organizations/${local.organization_id}" location = "global" resource_type = "cloudresourcemanager.googleapis.com/Organization" resource = "//cloudresourcemanager.googleapis.com/organizations/${local.organization_id}" # 取得したい role を定義 roles = [ "roles/storage.bucketViewer", "roles/storage.objectViewer", ] # 申請可能なユーザ eligible_users = [ "group:users@caddi.com", ] # 承認可能なユーザ approvers = [ "group:approvers@caddi.com", ] # 最大の申請期間 max_request_duration = "14400s" # 必要な承認の数 approvals_needed = 1 } PAM の運用で工夫していること Slack 通知機能の実装 PAMの通知機能はメール通知のみでSlackへの通知には標準では対応していません。 しかし、既存のJIT Access SystemではSlack通知するようにしていたため、利用者体験が変わらないようにする必要がありました。 そこで、PAMの監査ログの内容をパースしてSlack通知するAPIを実装しました。 以下のような仕組みで動作しています。 Pub/Subを経由して、実装したSlack通知APIに送信 Cloud Loggingに保存されているPAMの監査ログをLog routerでPub/Subに転送 Pub/Subの Push Subscription を使ってCloud Runで動作しているSlack通知APIにHTTP POST 実際の構成図は以下です。 PAM通知機能の構成図 上記のSlack通知APIを利用して、既存システムの使用感はそのままに、SlackでPAMの申請・承認を通知できるようにしました。 PAMのSlack通知 Slack通知の内容についても、利便性を上げるために様々な改善をしています。 承認結果のメッセージを申請したメッセージのスレッドに紐づけて投稿 申請内容に不備がある場合は、申請内容の修正を促すように警告文を自動で投稿 申請のステータスによって、SlackのAttachmentの色を変更 Devin による利用資格設定の自動化 PAMの利用資格の中に取得したい権限が存在しない場合、利用資格を修正する必要があります。 PAMの移行当初は取得できる権限が不足しており、利用者から多く依頼を受けていました。 その度にTerraformの定義を修正しレビューするのは大変です。 そこで、Devinを使って、Terraformの修正からPRの作成を自動でしてもらうようにしました。 Devin Playbook で利用資格を修正するPR作成作業を定型化しています。 利用者がSlack Workflowで追加してほしい権限を入力するとDevinが呼び出され自動でPRを作成します。 あとは、チームメンバーがPRをレビュー