Red Hat - Open Innovation Labsのブログ - TECH PLAY

TECH PLAY

Red Hat  - Open Innovation Labs

Red Hat - Open Innovation Labs の技術ブログ

全900件

Red Hat のソリューションアーキテクトの瀬戸です。 Anthropicがアプリケーションの脆弱性を見つけ出すのが得意な Claude Mythos Preview を発表しました。それを使った脆弱性を見つけるプロジェクトはProject Glasswingとして組織され、すでに多くの企業で実験的に使われており、多数の脆弱性をみつけています。この記事では、Claude Mythos Previewがどのような影響を与えているかから、コンテナがどのように役に立つのかを説明します。 金融庁の要請が示す新時代のセキュリティ対策 Claude Mythos Previewの結果を受け、2026年5月22日に金融庁が国内の全金融機関に対して画期的な要請を行いました。 「フロンティアAIによる脅威変化を踏まえた金融機関等の短期的な対応」に係る要請 では次のようなことが対策として求められています。 AI対応を継続的な経営課題として優先的に取り扱うこと インターネット決済サービスを支えるシステムを優先的に対策すること 特定した資産の技術負債を解消し、セキュリティパッチをいつでも適用可能な状態にしておくこと システム監視のための人員を増強すること ITベンダーと協力してメンテナンス手順を見直すこと パッチ適用プロセスをリスクベースとし、システム停止も選択肢として認める パッチ適用以外の対策(WAFなど)も強化する 特筆すべきは、 システム停止も選択肢として認める という点です。これは、AIによる脆弱性検出の速度が、従来の対応スピードを圧倒的に上回ることを示唆しています。つまり、 セキュリティアップデートのスピードを上げなければ、システムを守ることができない時代 が到来したと考えられます。 金融系のシステム開発をやったことがある身としては本当に信じられませんでした。 従来の問題:アップデートを忌避する文化 これまで、本番環境へのリリースには多くのゲートウェイがありました。企画、開発、テスト、QA、承認...と、何段階もの承認プロセスを経る必要があり、単純なセキュリティパッチを適用するだけでも数週間から数ヶ月かかることも珍しくありませんでした。 その結果、現在はどうなっているでしょうか? セキュリティアップデートが後回しにされる 「本番環境では絶対に失敗できない」という過度なプレッシャー リリースサイクルの長期化による技術的負債の蓄積 脆弱性が発見されてから対応するまでの時間が長く、攻撃のリスクが高まる しかし、Mythos時代にはこのような悠長なプロセスは通用しません。AIが数時間で脆弱性を発見できる時代に、対応に数週間もかけていては、セキュリティは守れないのです。 コンテナがもたらす革命:バックアップ不要のアップデート ここで注目したいのが、 コンテナ技術 です。コンテナには、従来のシステムアップデートの常識を覆す特性があります。 コンテナイメージ:最高のバックアップ 従来のシステムでは、アップデート前に必ずバックアップを取得する必要がありました。しかし、コンテナでは コンテナイメージそのものが完全なバックアップ になります。 アップデート前 :現在動いているコンテナイメージ myapp:v1.2.3 がそのまま残る アップデート後 :新しいコンテナイメージ myapp:v1.2.4 をデプロイ 問題発生時 : myapp:v1.2.3 に戻すだけ(数秒で完了) バックアップの取得時間がゼロになり、ロールバックは数秒で完了します。これにより、 アップデートのリスクが劇的に低減 されるのです。 また、お気づきでしょうか?コンテナイメージではロールバックからの起動は確実に成功します。従来のバックアップでは、バックアップしたものが確実に動作するのかは不明でした。 当然、ほとんどの場合は動作します。ただ、動作するというテストはしてますか? コンテナイメージは初回起動がバックアップからの起動のテストを兼ねます。それに気が付いただけでも既存のバックアップを捨ててコンテナイメージに移りたいと考える人が出てくるでしょう。 新しい時代:失敗を恐れない文化への転換 コンテナを使えば、 本番環境で失敗しても即座に戻せる という安心感が生まれます。これは、組織の意識改革を促します。 「本番では絶対に失敗できない」→ 「失敗しても大丈夫、すぐ戻せる」 「アップデートは慎重に」→ 「どんどんアップデートして、問題があれば戻す」 「リリースは月1回」→ 「必要な時にいつでもリリース」 この意識の変化こそが、Mythos時代のセキュリティ対策の鍵となります。 AIとOODAループ:リリース速度の加速 F5の記事 AIとOODAループ: 運用の新たなビジョン が指摘するように、AI導入により、IT運用はOODAループベースのモデルへとシフトしています。OODAループ(Observe-Orient-Decide-Act)は、アジャイル開発の源流とも言われる、高速な意思決定と行動のフレームワークです。 AIがもたらすリリース速度の革命 AIを活用することで、次のプロセスが自動化・高速化されます。 Observe(観察) : AIがコードの変更点、脆弱性、パフォーマンスの問題を自動検出 Orient(情勢判断) : AIが過去のデータから最適なアプローチを提案 Decide(意思決定) : AIが回帰テストを自動実行し、リスクを評価 Act(行動) : 自動デプロイメントパイプラインで即座にリリース OODAループは高速反復サイクルを意味し、MTTRの短縮、障害の減少、よりスマートな自動化をもたらします。 つまり、従来は数週間かかっていたセキュリティアップデートが、AIの支援により 数時間から数日で完了 できるようになるのです。 コンテナ × AI:最強の組み合わせ しかし、ここで重要な問題があります。 AIは間違える可能性がある ということです。 自動生成されたテストが不十分かもしれない AIが見落とした副作用が本番で発生するかもしれない 自動デプロイメントのロジックにバグがあるかもしれない だからこそ、 コンテナとAIの組み合わせが最強 となります。 AIが間違えたとしてもコンテナであればすぐに戻すことができます。 AIの速度 + コンテナの安全性 要素 AIの貢献 コンテナの貢献 リリース速度 自動テスト、自動デプロイで高速化 イメージビルドで高速デプロイ可能 品質保証 回帰テストの自動生成と実行 同一環境の再現性で「動くはずだったのに」を防止 リスク管理 潜在的な問題の早期検出 即座のロールバックで被害を最小化 学習サイクル 失敗から学習して次回に活かす 失敗しても安全に試行錯誤できる環境 AIが高速に開発・テスト・デプロイを進め、もし問題が発生してもコンテナの特性により数秒でロールバック。そして、その失敗からAIが学習し、次のリリースに活かす──これこそが、Mythos時代の理想的なOODAループなのです。 今こそ、コンテナを始めよう! 金融庁の要請が示すように、セキュリティ対策のスピードアップは、もはや選択肢ではなく 必須 なものになっています。そして、その実現にはコンテナ技術を使う事が最適です。 コンテナを試そう! すでにコンテナを使ったことがある人はそのまま使い続けてください。そうない場合はぜひコンテナを使い始めてみましょう。 小さく始める :まずは開発環境からコンテナ化してみましょう 失敗を恐れない :ステージング環境で試して、問題があれば戻す経験を積みましょう チームで共有 :コンテナの利点をチーム全体で理解し、文化を変えていきましょう AIを活用する :Containerfile(Dockerfile)の生成、テストの自動化など、AIにサポートしてもらいましょう もちろんRed Hatもサポートすることができます! システム開発がより素早くなる時代へ! Mythos時代は大きな変革であり、大変な思いをしている方々もたくさんいると思います。 しかし同時に、これまで以上に素早く、安全に、システムを改善できる時代でもあります。 今までのシステム開発は多くの規制やしがらみにとらわれてなかなか創造的な事ができませんでした。 コンテナとAIを組み合わせることで、次のようなことができるようになります。 セキュリティの脅威に即座に対応できる ユーザーに価値を届けるスピードを上げられる 失敗を恐れず、革新的なアイデアを試せる エンジニアがより創造的な仕事に集中できる 「失敗しても戻せる」という安心感が、最高のイノベーションを生みだすと考えています。 いまこそコンテナを使い始めてみてください。
はじめに 巧妙化するランサムウェア攻撃と、完璧な防御を練る「罠」 実例をベースにした侵入の手口 コンテナ環境だからこその「即応性」:まずは防御層を一枚増やす 攻撃チェーンの分断:RHACSはどこまで効くのか? ブラストラディウス(被害半径)を構造的に縮める 誠実な限界:RHACS「単体」では届かない領域 「来週から回せる運用」へ:導入の軽さ おわりに:まずは「Alert」の観測から始めよう はじめに Kubernetes環境のセキュリティを考える際、多くの組織で共通して直面している大きな壁があります。それは、「完璧なセキュリティアーキテクチャを描こうとするあまり、最初の第一歩を踏み出すまでに膨大な時間を空費してしまっている」というジレンマです。 コンサルタントの金子です。本記事では、Red Hat Advanced Cluster Security for Kubernetes(以下、RHACS。旧StackRox)を取り上げます。実際の攻撃の現実を見据えたうえで、RHACSのどの機能がどこまで効き、どこからは届かないのか。コンテナ環境ならではの特性を活かし、「来週から防御層を一枚増やす」という現実的な割り切りがいかに重要かについて、お伝えしたいと思います。 巧妙化するランサムウェア攻撃と、完璧な防御を練る「罠」 昨今、クラウドネイティブ環境を狙う攻撃は自動化と巧妙化が加速しています。現在のランサムウェア攻撃は、単にデータを暗号化するだけの単純なものではありません。 攻撃者は、放置された脆弱性や設定ミスを突いて初期侵入を果たします。その後、インターネット上から攻撃用のバイナリやスクリプトをダウンロードして実行し、内部ネットワークを横展開(Lateral Movement)して重要なデータへとアクセスします。そして最終的に、データの暗号化や外部への持ち出し、さらにはデータ公開を盾に取った二重・三重の脅迫へと至る、多段階の攻撃チェーンを形成しています。 国内の実在組織においても、こうしたランサムウェアやそれに類するデータ侵害による深刻なインシデントが後を絶ちません。AIを活用した攻撃の自動化や、脆弱性が公開されてから実際に悪用されるまでのリードタイムの短縮など、攻撃側の進化は止まりません。 こうした脅威を前にして、私たちはつい「あらゆる攻撃パターンを網羅した完璧なセキュリティ要件」を定義しようとしてしまいます。複数の部署をまたいだ数カ月にわたる検討プロジェクトが立ち上がり、壮大な多層防御のアーキテクチャ図が描かれます。 しかし、その机上の議論を続けている間にも、現在稼働しているシステムは無防備な状態、あるいは最低限の防御のみで脅威に晒され続けています。完璧主義は、時に最大のセキュリティホールになり得るのです。 実例をベースにした侵入の手口 では、実際の攻撃事例を基に、攻撃者がどのような手順で侵入を試みるのかを確認してみましょう。 https://www.sysdig.com/blog/scarleteel-mitre-attack 上記のブログで紹介されている「ScarletEel」の事例は、2023年に公開されたJupyterLabコンテナの脆弱性を悪用したクリプトマイニング攻撃です。ランサムウェアとは最終目的が異なるものの、標準的な攻撃手段を網羅しており、その戦術と対策を理解するための好例です。 ① Initial Access(初期アクセス) 攻撃は、公開されていたJupyterLabノートブック・コンテナの脆弱性を悪用し、Kubernetesクラスター内に侵入することから始まります。これは、攻撃者が最も簡単に「足がかり」を作るステップです。 ② Execution & Credential Access(実行と認証情報窃取) 侵入後、攻撃者は直ちにコンテナ内の環境を探索します。特定の内部IPアドレス(169.254.169.254)に対して不正なリクエストを送りAWSの認証情報を取得したり、DDoSマルウェア(Pandora)やツール(Peirates)をダウンロードして実行します。 ③ Privilege Escalation & Lateral Movement(特権昇格と横展開) 攻撃者は、設定ミスや命名規則の不備を突いて管理者権限の獲得を試みます。さらに、AWS CLIやフレームワーク(Pacu)をインストールし、環境内で権限を悪用して影響範囲を広げていきます。 ④ C2, Exfiltration & Defense Evasion(C2、データ持ち出し、防御回避) 最終段階として、攻撃者は外部のC2サーバーと通信リンクを確立し、窃取したデータをBase64でエンコードして外部へ持ち出します。証拠を隠滅するためにログの削除工作を行い、活動を隠蔽しようとします。 これらの攻撃ステップを個別に眺めると、それぞれが独立した出来事のように見えるかもしれません。しかし、これらは『チェーン(連鎖)』として繋がっており、この鎖のどこか一箇所でも物理的・論理的に切断すれば、攻撃は完遂できません。 コンテナ環境だからこその「即応性」:まずは防御層を一枚増やす ここで立ち返りたいのが、コンテナとKubernetesが持つ「不変性(Immutable)」と「宣言的(Declarative)」な特性です。 従来型の仮想マシン(VM)環境であれば、各サーバーのOSやミドルウェアの構成が少しずつ異なる(Mutableである)ため、新しいセキュリティエージェントを一つ導入するだけでも、綿密な影響調査と長期間のテストが必要でした。 しかし、コンテナ環境は異なります。アプリケーションはイメージとして固定され、クラスタの構成はマニフェストによって宣言的に管理されています。この特性により、「まずは観測だけを行う(Alert)」という形で防御層を素早く差し込むことが格段に容易になっています。 数カ月かけて完璧なルールを作るのではなく、まずはデフォルトのポリシーでアラートを出し、「システム内で何が起きているか」を可視化する。そして、誤検知が少なく確実に防ぐべきものから順に「強制(Enforce)」へとフェーズを引き上げていく。もしアプリケーションの動作に支障が出れば、すぐにポリシーを調整したり、一時的にAlertに戻したりすることも容易です。 この「試行と適用のサイクルの軽さ」こそが、コンテナ環境の最大のセキュリティ上の利点です。「来週からとりあえず防御層を一枚追加して、様子を見る」というアプローチが現実的に可能なのです。 攻撃チェーンの分断:RHACSはどこまで効くのか? では、具体的にRHACSを導入することで、先述したランサムウェアのような多段階の攻撃チェーンに対して、どのような効果が期待できるのでしょうか。段階ごとに整理してみます。 ① Initial Access(初期アクセス)の予防 攻撃者はまず、パッチが当たっていない既知の脆弱性(CVE)を狙います。RHACSはCI/CDパイプラインやレジストリと連携し、イメージの脆弱性スキャンを行います。さらに、CVSSのスコアだけでなく「実際に悪用可能なコードが存在するか」「そのコンポーネントが実行環境でロードされているか」といった文脈を評価し、対応の優先順位をつけます。 そして、KubernetesのAdmission Controllerと連携することで、「修正可能な重要脆弱性を含むイメージのデプロイ」を強制的に拒否(Deploy: NG)することが可能です。これにより、本番環境へ「攻撃の穴」が持ち込まれるのをシステム的に水際で阻止します。 ② Execution & Credential Access(実行と認証情報窃取)への対応:未知の攻撃への備え 万が一侵入を許した場合、攻撃者は curl や wget を使って外部からマルウェアをダウンロードしたり、見慣れないスクリプトを実行しようとします。 ここでRHACSは、コンテナの「プロセスベースライン」を活用します。コンテナは単一の役割を持つように設計されているため、VMと比べて実行されるプロセスが限定的であり、予測が容易です。 RHACSはこの「普段の振る舞い」から逸脱したプロセス(例えば、Webサーバーのコンテナ内で突然シェルが起動したり、パッケージマネージャが実行されたりする挙動)を異常として検知します。 これはシグネチャに依存しないアプローチであるため、AIで生成された亜種や未知の攻撃ツールに対しても相対的に強いという利点があります。致命的な逸脱を検知した瞬間、即座にそのPodを削除(Kill & Restart)して進行を遮断するよう設定することも可能です。 ③ Privilege Escalation & Lateral Movement(特権昇格と横展開)の防止 攻撃者は足場を固めた後、クラスタ内の他のPodやデータベースへと横展開を図ります。ここで威力を発揮するのが、ネットワークベースラインの監視とNetwork Policyの自動生成機能です。 RHACSはクラスタ内の通信トラフィックを可視化し、不要な通信経路を特定します。 そして、アプリケーションの正常な動作に必要な通信だけを許可する「最小権限のNetwork Policy」を提案してくれます。これにより、攻撃者が別のネームスペースにあるバックエンドデータベースへアクセスしようとしても、ネットワークレベルで構造的に遮断されます。 ④ C2, Exfiltration & Defense Evasion(C2、データ持ち出し、防御回避)への対応   最終段階において、攻撃者は外部サーバーとの通信確立やログの改ざんを試みます。ここでRHACSは、「検知」と「遮断」の両面で最後の防波堤となります。 ネットワーク監視機能は、コンテナが通常行わない外部通信やC2サーバーとの怪しいやり取りを即座に検知し、管理者に警告します。また、攻撃者が自身の痕跡を消すために行うツール実行やログ操作といった挙動も、プロセスベースラインから逸脱するものとして可視化されます。 さらに重要なのは「ネットワークポリシー」による出口の封鎖です。RHACSによって「必要な通信以外はすべて拒否する」というホワイトリスト型の通信制限を適用しておけば、万が一攻撃者がコンテナ内に入り込んだとしても、外部へのデータ持ち出し経路そのものが存在しないため、攻撃者は目的を達成できずに立ち往生することになります。つまり、ここでの防御は「攻撃の入り口を絞る」こと以上に、「攻撃者の逃げ道を塞ぐ」ことにあります。 ブラストラディウス(被害半径)を構造的に縮める ここで、セキュリティにおける重要な概念である「ブラストラディウス(Blast Radius:被害半径)」について触れておきます。 システムへの侵入を100%防ぐことは、現代の複雑なIT環境においては事実上不可能です。そこで問われるのは、万が一どこか一点が突破されたときに、「何人の顧客に、どのデータに、いくらの損失と何日のシステム停止が及ぶのか」という被害の範囲です。 RHACSを用いたネットワークセグメンテーション(Network Policyの厳格化)や、過剰な権限の可視化と剥奪は、まさにこのブラストラディウスを物理的・論理的に極小化するための投資です。 一部のフロントエンドコンテナが侵害されたとしても、そこから顧客情報が格納されたデータベースへの経路が絶たれていれば、被害は局所的なものに留まり、ビジネス全体の停止という最悪の事態を免れることができます。経営層やCISOの皆様には、RHACSの導入を単なる「マルウェア対策」ではなく、「ビジネスリスクの範囲を限定するための構造的なアーキテクチャ投資」として捉えていただきたいと思います。 誠実な限界:RHACS「単体」では届かない領域 では、RHACSを導入すればセキュリティは万全かと言えば、そうではありません。ここからは、エンジニア・セキュリティ責任者の皆様に信頼していただくため、RHACSが届かない領域と、それに対してどう立ち向かうべきかについて、包み隠さずお話しします。 RHACSはコンテナセキュリティにおいて非常に強力なツールですが、決して万能の「銀の弾丸」ではありません。 例えば、メモリ上だけで悪意のあるコードを実行する「インメモリ実行」や、OSに標準で備わっている正規のツールを巧妙に悪用して攻撃を行う「Living-off-the-Land(環境寄生型)」攻撃の一部は、プロセスの起動自体は正規のものであるため、ベースラインの逸脱として現れにくく、RHACS単体では検知が難しい場合があります。 また、ランサムウェアの最終目的である「永続ボリューム(PV)に対する大量のファイル暗号化」そのものを監視し、ファイルI/Oレベルでブロックすることは、RHACSの主要な得意領域ではありません。 したがって、「RHACSさえあればあらゆる攻撃を完全に防げる」とは言えません。ホストOSやコンテナランタイムの挙動をより深く監視するEDR、ログを統合分析するSIEM、そして何より土台となる定期的なパッチ運用と組み合わせることで、初めて強固なセキュリティが実現します。RHACSは、コンテナ特有のライフサイクルに寄り添う「多層防御の極めて優秀な一枚目の層」として位置づけるのが正しい理解です。 「来週から回せる運用」へ:導入の軽さ とはいえ、「そんな基盤を導入・運用するリソースがない」と思われるかもしれません。 RHACSのアーキテクチャは、一元管理を行う管理コンソール(Central)と、監視対象の各クラスタに配置されるエージェント(Secured Cluster:SensorやCollector等)に分かれています。 現在では「RHACS Cloud Service」というマネージドサービスが提供されており、管理コンソール側のインフラを自前で構築・保守する必要はありません。監視対象となる皆様のKubernetesクラスタ側には、Operatorを通じてSecured Clusterコンポーネントをデプロイするだけで導入が完了します(※サポートされるプラットフォームやバージョン要件は頻繁にアップデートされます。必ず 最新のサポートマトリックス にて最新情報をご確認ください)。 これにより、導入プロジェクトにつきものの「サーバーの調達」や「管理用データベースの冗長化設計」といった重たい作業をスキップし、本当に「来週から」セキュリティの観測を始めることができるのです。 おわりに:まずは「Alert」の観測から始めよう 完璧な対策を数カ月かけて設計する間にも、攻撃は待ってくれません。ランサムウェアをはじめとする脅威が身近に迫る今、私たちが取るべきは、怯えて立ち止まることでも、実現不可能な完璧さを追求することでもありません。 コンテナの特性を活かし、まずは検証環境、あるいは一部の開発環境へOperator経由でRHACSをインストールしてみてください。最初は何も遮断(Enforce)する必要はありません。アラート(Alert)を眺めるだけで、「自分たちのクラスタ内で、想像以上に過剰な権限が与えられていること」や「見知らぬ通信が発生していること」に気づくはずです。 その気づきこそが、多層防御の実践への第一歩です。ブラストラディウスを縮め、システムとビジネスを守るための現実的な一歩を、今日から踏み出してみませんか。
Red Hat のソリューションアーキテクトの瀬戸です。 最近JBoss EAP XPについての質問をよく受けます。 JBoss EAP XPはJakarta EEに準拠したウェブサーバーであるJBoss EAPにMicroProfileに準拠した機能を追加するためのeXtension Packです。 MicroProfileには今後の標準的な監視のスタンダードとしてOpenTelemetryなども含まれており、k8s上での標準化として期待がされています。 JBoss EAP XPはJBoss EAPとは別のライフサイクルで開発が行われており、現在の最新版は6.0になっています。また、8.0と8.1で共通で使用できます。 こちらを起動可能なJAR(Bootable jar)で使ってみます。 アプリケーションサーバーは昔はOSにプリインストールして使う事が多かったですが、アプリケーションフレームワークとして手軽に使う事も増えたため、昨今では事前にインストールすることは減っています。 起動可能なJBoss EAPを使う JBoss EAPはEAPのプラグインとして動作しますので、基本的にはEAPの設定とほぼ一緒です。前提となる知識として次の記事を参照してください。 rheb.hatenablog.com 追加の設定 eap-maven-pluginをカスタマイズしていきます。 channelとして、org.jboss.eap.channels#eap-xp-6.0 を追加します。 <channel> <manifest> <groupId> org.jboss.eap.channels </groupId> <artifactId> eap-xp-6.0 </artifactId> <version> ${version.xp.channel} </version> </manifest> </channel> ※versionは参考文献を参照して適切なものを指定してください。versionを指定しない場合は最新版が使用されます。 feature-packとしてorg.jboss.eap.xp:wildfly-galleon-packを追加します。 <feature-pack> <location> org.jboss.eap.xp:wildfly-galleon-pack </location> </feature-pack> 修正の全量、詳細な差分については次のコミットログを参照してください。 github.com これだけでJBoss EAP XPを使用する事が出来ます。起動方法についてはJBoss EAPと同じです。 また、今回は触れませんでしたが、必要に応じて機能のトリミングも行うことができます。 さっとながしましたが、ぜひEAP XPについてもお試しいただけるとありがたいです。 参考: JBoss EAP 8 Maintenance Schedule - Red Hat Customer Portal eap-maven-pluginで指定するJBoss EAPのバージョン JBoss EAP XP 6 Maintenance Schedule - Red Hat Customer Portal eap-maven-pluginで指定するJBoss EAP XPのバージョン 第10章 起動可能な JAR | JBoss EAP XP 6.0 の使用 | Red Hat JBoss Enterprise Application Platform | 8.1 | Red Hat Documentation
Red Hatでソリューションアーキテクト(SA)として金融領域を担当している田川です。 2025年12月に入社した際、20代は自分だけだったのですが、最近は着々と若手が増えてきています。 入社前は、担当が日本のお客様のみであるため、業務がグローバルに関わることはないだろうと思っていましたが、実際には業務の端々で海外拠点との接点があります。 本記事では、質問をいただくことが多い「Red Hat社員って英語使うの?」という話題について、入社半年における英語が関わる業務経験をもとにいくつかご紹介します。 e-learning 入社3ヶ月まではe-learning形式で製品や営業活動のキャッチアップをしていきます。 このコンテンツはグローバルで共通であるため、海外での導入事例や最新の情報をキャッチアップできます。 New Hire Cultural Experience New Hire Cultural Experienceは、Red Hatに入社した新入社員に向けて、企業文化を伝え、同じ地域の同僚とコミュニケーションをするためのオリエンテーションです。 私は、3月にシンガポールで開催された回に参加しました。 いくつかのセッションがあり、Red Hatの理念の理解を深めたり、APACの様々なチームの新入社員とコミュニケーションを取ることができました。 Red Hat Summit Red Hat Summitは、世界中の技術者やパートナーが集結し、オープンソースの最新技術やビジョンを共有する年次最大のグローバル・カンファレンスです。 Red Hat Summit 2026 は5/11から5/14にアトランタで開催されました。 私は現地には行く機会はなかったのですが、現地で行われる担当顧客向けのサイドミーティングの準備に少し関わりました。 担当顧客の関心領域がAIの活用であったため、社内のRHELエンジニアリングチームや研究部署などにヒアリングし最新状況を確認するなど、貴重な機会がありました。 Executive Briefing Center (EBC) Executive Briefing Center とは、顧客のビジネス課題に合わせてカスタマイズされた戦略的対話を行うための専用のブリーフィング施設およびプログラムです。 Red Hat の経営陣や技術エキスパートと直接連携し、最新のオープンソース技術や製品デモを通じて、お客様のビジョンや長期的なテクノロジー戦略を具体化する場となっています。 3月に担当顧客向けのEBCが開催され、その場所や内容やプレゼンターの調整を、担当顧客とボストンのEBCチームの橋渡しをする形で行いました。 調整にあたりAPACやヨーロッパのチームとも連携する機会があり、時差をまたいだ調整スキルなどが身につきました。 7月には別の担当顧客に対してEBCを開催する機会があり、今回は事前の調整だけでなく、ボストンに渡航して参加する予定です。 Red Hat One Red Hat Oneは、レッドハットのグローバル営業組織と主要パートナーが参加する、戦略共有とスキルトレーニングを目的とした社内イベントです。 基調講演やセールスワークショップ、技術セッションを通じて、次年度の戦略や製品ロードマップに関する知見を深め、チーム間の連携を強化する場として活用されています。 今年は行けていませんが、毎年海外で開催されるため、現地で最新の情報をキャッチアップできます。 福利厚生 私はそれほど英語が得意ではないため、英語学習を継続しています。 金額の制限はありますが、自分の好きなプラットフォームを選んで英語学習ができるため、金銭的な負担なく継続できています。 また、Geminiなどのサービスが使えるため、英語のコンテンツの翻訳などの効率化ができています。 さいごに ここまでの内容はあくまで業務の一環(体感で言うと1/50くらい)です。 そのため、Red HatのSAは、必ずしも英語を話せなければ業務が進まないわけではありません。 現在は翻訳ツールなどのサポートも充実しているため、必要に応じて補いながら進めることが可能です。 一方で、より深く海外拠点と連携したい、あるいは最新の情報を一次ソースから取りに行きたいという個人の意欲があれば、入社半年であっても十分にその機会を掴める環境です。 自身のキャリアや得意不得意に合わせて、海外拠点との距離感を柔軟に選べる点は、Red Hatの面白さの一つだと感じています。
こんにちは。レッドハットコンサルティングチームの木嶋です。 これまでの連載では、「アプリケーションモダナイゼーション(以下、モダナイゼーション)」の進め方について解説してきました。 しかし実務では、技術的に妥当と判断される取り組みであっても、予算が承認されないケースは少なくありません。 なぜ、モダナイズは予算が通らないのでしょうか。 本記事では、予算承認側の視点を踏まえながら、モダナイズを意思決定に結びつけるための考え方を整理します。 はじめに 予算はどこに対して降りるのか 予算承認者は何をみているのか 専門領域が違うと、そのままでは伝わらない 予算承認者の世界の言葉に翻訳する IR情報から逆算する アセスメントで見るべき観点 損失として翻訳する まとめ はじめに 「予算申請したんですが通らなくて」「新しい機能が追加されておらず、ビジネスにメリットがないからダメと言われました」 こうした言葉は支援の現場でも頻繁に耳にします。 そのときにどう訴求したかをお伺いすると、次のようなキーワードが並んでいることが少なくありません。 基盤老朽化 技術負債 スパゲッティコード 開発リードタイム もちろん、こうした論点そのものが間違っているわけではありません。実際、モダナイゼーションを進めるうえで重要な観点です。 しかし、技術そのものが競争力に直結するという認識が、組織としての「あたりまえ」になっている場合を除き、これらの言葉だけで予算が承認されることは多くありません。 歴史のある大きな組織で実際にモダナイズ投資を獲得するには、技術課題をそのまま訴えるのではなく、意思決定につながる形へ翻訳する必要があります。 本記事では、予算承認者が「それは必要だ」と判断できるようにするための、意思決定の土台の設計について整理します。 予算はどこに対して降りるのか では予算承認者の視点に立ち、なぜ「それは必要だ」と言えないのかを紐解いていきましょう。 簡単にいってしまうと、「基盤が古くて」「技術負債」は、承認者の視点では問題ではないのです。 予算承認者は何をみているのか まずは、予算を承認する経営側の視点をみていきましょう。 ここでいう予算承認者とは、個別プロジェクトの予算を執行するプロジェクトオーナーやシステムオーナーではなく、複数の投資候補を比較し、予算配分を判断する立場の人を想定しています。 予算承認者が何を見て、何を気にし、どのように判断しているのかを文章だけで説明しても、少し分かりにくいかもしれません。 そこで、まずは共感マップの形で整理してみます。 予算承認者の頭の中は、おおむね次のようなものです。 共感マップ ご覧いただくとわかる通り、ここにはソフトウェア技術そのものの論点はほとんど出てきません。強いて言えば、Pains のところに「理解しきれないこと」とある通り、ソフトウェア技術に対して苦手意識すらあるかもしれません。 予算承認者にとって関心の中心にあるのは、技術の優劣ではなく、ゴール達成へのインパクトや、投資判断としての妥当性です。 ここでいうゴールとは、典型的にはコスト削減や売上向上といった事業成果を指します。 したがって、予算承認者にとってわかりやすい説明とは、その提案とゴール達成の間にどのような関係があり、どの程度の影響が見込まれるのかが、数値を伴って示されたものです。 専門領域が違うと、そのままでは伝わらない では、このような方々が「基盤が古くて」「技術負債がひどくて」といった説明を耳にしたとき、どう受け取るでしょうか。 おそらくゴール達成とどのような関係があるか、想像もできないはずです。 これは当然なことです。 たとえばわれわれエンジニアが、財務や経営の論点を耳にしても、それが自分たちの仕事やシステムにどう影響があるかすぐには掴めないことも多いのではないでしょうか。 それだけ専門領域が違うと話が伝わらないものなのです。 しかし、ここで重要なのは、相手が理解できないことを責めることではありません。 むしろ、われわれ自身もまた、「技術負債」や「基盤の老朽化」が、ゴール達成にどう影響するのかだけでなく、自分たちの仕事やシステムにどのような具体的損失を生んでいるのかさえ、十分に言語化しないまま使ってしまっているのかもしれません。 それでは、意思決定の言葉として機能しないのも無理はありません。 予算承認者の世界の言葉に翻訳する ここまでの内容を踏まえて共感マップを見返すと、われわれが持っている「技術負債」や「基盤の老朽化」といった懸念は、ゴールに対する「悪いニュース」に位置づけられるはずです。 しかし、「技術負債がありバグが生まれやすい」といった定性的な表現のままでは、意思決定に必要な情報としては十分ではありません。これを意思決定の言葉として機能させるには、定量的な形に変換する必要があります。 そして、予算承認の文脈において最も効果的な定量表現は、金額です。すなわち、 これを放置すると、具体的にいくら損をするのか これを実施すると、具体的にいくら得をするのか のいずれかで示すことが重要になります。 予算承認者は、他の多くの投資案件についても同様に定量的な説明を受けています。その中で、承認者自身が個別に金額を計算していては、意思決定は進みません。 だからこそ、他のプロジェクトと比較できる形、すなわち金額に換算して提示することが、最も直感的で効果的な伝え方になります。 われわれ自身も、何らかの技術的な意思決定を行う際には、比較表を使うことが少なくありません。あれは、複数の選択肢を同じ土俵に載せ、比較しやすい形に整えるための工夫です。 予算承認者も同じように、複数の投資候補を比較し、優先順位を判断するための情報を求めます。 内容そのものは異なっていても、どれかを選ばなければならない場面では、他の候補と並べて妥当性を確認できる状態が必要です。 その意味で、金額で表現することは、予算承認者にとって意思決定の前提条件だと言えます。 IR情報から逆算する ではここからは、どのように数字を揃えるかをご紹介します。 ここでは一例を、考え方とともに整理していきます。 多くのシステムは、今この瞬間だけを見れば、ぎりぎり何とか動いています。 現状維持を前提にする限り、当面は大きな問題が見えにくいことも少なくありません。 そこで有効なのが、「現状維持では成立しなくなるのはいつか」「どのような条件で限界を迎えるのか」を探すことです。 その手がかりは、会社がこれから何を達成しようとしているかを示した資料の中にあります。典型的には、IR情報や中期経営計画です。 こうした資料には、売上成長、顧客数拡大、新規事業、海外展開といったビジネス拡張計画が、一定の具体性を持って書かれています。 予算承認者のゴールとは、最終的にはこのビジネス拡張計画にあります。 したがって予算承認者にとってつい聞きたくなる情報は、IR情報に描かれた将来のビジネス拡張計画にとってのマイナス要素です。 なお、すべてのシステムがIR情報や中期経営計画に直接結びついて見えるわけではありません。特に、間接部門や社内業務を支えるシステムでは、「このシステムが売上成長にどう関係するのか」が一見わかりにくいこともあります。 その場合は、IR情報に書かれたゴールを、それを支える業務プロセスへ分解して考えるとよいでしょう。 たとえば Sales Ops の領域であれば、見積作成や承認、契約手続き、商談情報の更新といったプロセスが、案件の失注や営業活動の停滞に影響することがあります。 このように、間接部門であっても、分解していくとIR情報や中期経営計画に紐づく接点が見つかります。次のアセスメントで、現在の技術的状況から発生している制約を見つけられるよう、まずは現在のビジネス動向をIR情報から拾っておきましょう。 アセスメントで見るべき観点 では次に、システムのアセスメントを通じて、ゴール達成に対する制約を探していきましょう。 投資獲得の観点で知りたいのは、このシステムが未来に対してどのような「悪いニュース」を抱えているかです。 たとえば、次のような観点があります。 基盤が老朽化しており、セキュリティ対策が追いついていないことはないか 攻撃を受けた場合に脆弱であり、ランサムウェアなどの被害を受けるリスクが高くはないか DBのキャパシティやHTTPトラフィック処理能力が、将来の拡張を支えられるか NW帯域や夜間バッチの実行時間が、データボリューム増加後も耐えられるか 予定している新規ビジネスを、計画通りに立ち上げられるだけの開発スピードが出せるか このような観点については、本連載でもこれまで取り上げてきました。必要に応じて、あわせて参照していただければと思います。 また、システム運用実績データやコードの複雑さだけでなく、Ops の運用工数も含めて総合的に診断することをおすすめします。 というのも、システム運用実績データやコードの複雑さによって生じる問題を、現場の運用工数で何とか吸収しているケースは非常によくあるからです。 そのため、Ops にかかっている運用工数とそこに内在するリスクもあわせて見積もることで、実現可能性と必要コストをより現実に即して評価できるようになります。 損失として翻訳する ここまで整理できれば、あとは翻訳です。 たとえば、DBキャパシティに限界がある場合には、IR情報や中期経営計画に記載されたビジネス拡張の前提に対して、どこまで対応できるのかを確認します。 重要なのは、「技術的に限界がある」という事実をそのまま伝えるのではなく、ゴール達成に対する制約として表現することです。 たとえば、次のように説明できる状態を目指します。 「現在のシステムではDBアクセスに限界があり、特にピーク時間帯に問題があります。IR情報に記載されたユーザー数拡大計画を前提とすると、1年後に予定されているXX倍までで頭打ちとなり、それ以上のアクセスでは障害発生リスクが高まります。IR情報に描かれている3年後の姿と比較すると、XX円規模の機会損失につながる可能性があります。」 同様に、「時間がかかっている」といった問題も、翻訳が難しい代表的な例です。 このときに注意したいのが、リードタイムと作業工数を混同してしまうケースです。この2つは意味が異なるため、混在させると予算承認者にとっては論理的に理解しにくい説明になってしまいます。 そのため、問題として扱う際には、リードタイムか工数のいずれかに明確に分けて整理する必要があります。 リードタイムであれば、「IR情報に記載されているこのマイルストーンに間に合わない可能性がある」といった形で表現します。 一方、工数であれば、工数に時間単価を掛け合わせることで金額に変換し、「ROIが悪化し、利益向上に対してマイナスの影響が出る可能性がある」といった形で示すことができます。 重要なのは、「リードタイムが長い」「工数がかかる」という事象そのものが問題なのではない、という点です。 それらの事象によって、ゴール達成にどのような悪影響が生じるのかを言語化してはじめて、意思決定の材料として機能します。 まとめ 本記事では、モダナイズ投資を意思決定につなげるための考え方を整理しました。 技術負債や基盤の老朽化といった言葉は、現場では通じるものの、そのままでは予算承認者にとっての「問題」にはなりません。重要なのは、それらをゴール達成に対する制約として捉え直し、どのような影響があり、どの程度の損失につながるのかを、数値、最終的には金額として表現することです。 予算承認の場では、複数の投資候補が並び、比較され、優先順位が決まります。その中で意思決定を前に進めるためには、他の案件と同じ土俵で比較できる形に整える必要があります。 こうした翻訳作業は、正直に言えば、われわれエンジニアにとって必ずしも得意な領域ではないかもしれません。できれば避けたいと感じる方もいるでしょう。 しかし実は、この作業はプロジェクト開始後の技術的意思決定にも良い影響をもたらします。 支援の現場では、「A案とB案があるが、決め手がなくて困っている」「こちらの技術を使いたいが、同意が得られなくて困っている」といった場面をよく目にします。 そのようなとき、予算訴求の根拠として整理した説明が、意思決定のものさしとして機能することがあります。何を優先するのか、どのような制約を避けたいのかが共有されていれば、技術的な選択肢にも判断軸が生まれるからです。 モダナイズとは、単に技術を更新する活動ではありません。何を解くべき問題とし、どのような将来を目指すのかを明らかにし、それを意思決定の言葉に翻訳して投資として成立させ、さらにそれを実現可能な設計に落とし込んでいく活動です。 つまり、投資の必然性を設計することは、そのままモダナイズの軸を定めることでもあるのです。 本記事が、そのための一助となれば幸いです。
Red Hatのソリューションアーキテクトの輿水です。アジア太平洋地区でOpenShift Virtualizationを担当しています。今回はOpenShift Migration Advisorについて説明いたします。 OpenShift Migration Advisorとは VMware環境からOpenShift Virtualizationへの移行を考えている方も多いかと思いますが、現在稼働しているワークロードがどの程度移行できるか評価しようと考えたときに、何をどのように実施すればよいのか悩むこともあるかと思います。そんなお悩みを解決すべく、VMware環境からOpenShift Virtualizationへどの程度移行性があるのかを評価するためのツールとして OpenShift Migration Advisor が発表されました。 Hybrid Cloud Console (Red Hatのマネージドサービスインフラストラクチャ)から利用できます。 Red Hat Hybrid Cloud Console このツールは、今年の3月に Red Hatのブログ(英語)で紹介されました、 www.redhat.com 冒頭の紹介部分を翻訳すると、以下のような説明になっています。 OpenShift Migration Advisorは、本格的な移行を決定する前に、VMwareワークロードの移行準備状況(Readiness)を評価するために設計された、無償のセルフサービス型ツールです。お客様の vCenter 環境をスキャンすることで、自信を持って移行計画を策定するために必要な技術的詳細を網羅したレポートを自動生成します。OpenShift Migration Advisor を活用すれば、Red Hat OpenShift への移行を計画する際、VMワークロードの最適な移行パスを確実に見極めることができます。 ポイント 無償サービス ユーザの都合の良いタイミングで実施できるセルフサービス型 VMwareワークロードの移行準備状況を評価したレポートを生成 実施内容 VMware vCenter環境を分析 仮想マシンとその構成を特定 移行準備状況の評価を提供 インフラストラクチャ、ストレージ、ネットワークなどに関する詳細なレポートを生成 なんかそれなりにいろいろやってくれそうな雰囲気を醸し出しております。 利用方法 OpenShift Migration Advisorを利用するには以下の条件が必要です。 RedHatアカウントがあること OpenShift Migration Advisor へアクセスできること 評価するVMware環境にOMA Discovery Agentを導入すること( ※1 ) ※1 OMA Discovery Agentを導入できない場合は、RVtoolsというツールで環境のデータを収集し、そのデータを Hybrid Cloud Console にUploadすることでも評価することができます。 OMA Discovery Agent OMA Discovery Agentを導入する必要があるので、OMA Discovery Agentがどのようなもので、どのような事を実施するのか簡単に説明します。 概要 OMA Discovery AgentはOVA形式で提供され、OVAテンプレートを仮想アプライアンスとしてvCenterにデプロイします。vCenter環境から匿名化されたVMwareインベントリデータを収集し、結果を console.redhat.com に送信します。このエージェントはvCenter APIの読み取り専用オブザーバーであり仮想マシン、ホスト、データストア、ネットワーク、その他のvCenterオブジェクトを変更することはありません。 収集するデータ VMインベントリ :名前、UUID、OS、CPU/RAM/ディスク/NIC構成、電源状態 ホストインベントリ :ベンダー、モデル、CPUコア数/ソケット数、メモリ容量、オーバーコミット比率 データセンター、クラスタ、データストアのトポロジー ネットワークトポロジー :VLAN、ポートグループ、分散スイッチ 移行準備状況 :ゲストOSのサポート状況、ディスクタイプ、VMware Toolsの状態、スナップショットの有無、CBTの状態 収集時に、ワークロードデータ、ユーザーデータ、データベースの内容、ファイルシステムの内容、ゲストVM内の認証情報は収集されません。このエージェントはvCenterメタデータのみを読み取ります。 収集データの送信 エージェントは収集したインベントリデータをHTTPS経由で console.redhat.com に送信します。データは暗号化(TLS)されて送信されます。このサービス外にデータが送信されることはありません。 OVAの削除 移行評価が完了したら、OVAをシャットダウンし、vCenterから削除できます。エージェントが使用していたサービスアカウントは取り消すことができます。vCenter環境には永続的な変更は残りません。 上記説明の通り、稼働している環境に影響を与えることはしません。 導入と評価方法 OMA Discovery Agentの導入方法と評価の方法はこちらの動画で説明されています。(英語です) interact.redhat.com レポートのサンプル OpenShift Migration Advisor のページでレポートのサンプルを見ることができます。サンプルを簡単に説明します。 収集されたデータから、Detected 630 VMs in 2 vSphere clusters ということで、この環境には2クラスタが存在していることがわかります。2クラスタ分の各種情報をまとめて見ることもできますし、クラスタごとの各種情報も見ることができます。プルダウンメニューからクラスタdomain-c34を選択すると、クラスタdomain-c34おける現在のVMの数とその中でMigratableなVMとmigration readyではないVMが表示されます。migration readyではないVMとは Migration Toolkit for Virtualization でサポートされていないOSを指します。 次に、VMのメモリ/CPUとディスクのスペックの情報です。各VMがどれくらいのメモリ/CPUとディスクを使っているのかを表示します。 ホストの台数とモデル、VMが使用しているネットワーク/NICの数を表示します。 WarningおよびErrorの内容と数を表示します。Warningでは、例えば  Changed Block Tracking (CBT) has not been enabled for this device. This feature is a prerequisite for VM warm migration.  は、CBTがenableになっておらず、Migration Toolkit for Virtualizationのwarmマイグレーションの前提を満たしていない事を指摘しています。Errorでは、 RDM disks are not currently supported by Migration Toolkit for Virtualization. The VM cannot be migrated unless the RDM disks are removed. You can reattach them to the VM after migration.  RDMディスクはMigration Toolkit for Virtualizationではサポートしておらず、何らかの対処が必要になるVMが41存在していることを指摘しています。 現在の情報を分析を行った上で、推奨されるOpenShiftクラスタの構成案、移行にかかる時間の見積、移行の難易度の内訳を表示します。なお、これらのレポートはPDFまたはhtmlでエクスポートすることが可能です。 推奨されるOpenShiftクラスタの構成案 移行にかかる時間の見積 移行の難易度の内訳 このようにOpenShift Migration Advisorを利用すると、現在VMwareで稼働しているワークロードを分析し、OpenShift Virtualizationへの移行に関する評価を簡単に行うことができます。 移行に向けて ここでご注意いただきたい点があります。それはOpenShift Migration Advisorの分析結果でErrorがあったり移行見積時間が長かったりという理由で即、移行を諦めようとは思わないで欲しいことです。OpenShift Migration Advisorの次のステップとして、Red Hatでは Virtualization Migration Assessment というサービスをご用意しています。このサービスは移行に関する戦略的なソリューション・ロードマップを策定するものです。詳細な説明は割愛しますが、以下のような成果を提供します。 移行計画の構築 :具体的なフェーズ分けや実行手順を含むマスタープランの作成 Day 2 運用(運用フェーズ ):移行後の安定稼働を見据えた運用管理体制の定義 セキュリティとコンプライアンス :企業基準に準拠した安全な基盤設計 ファイナンシャル・ストラテジー :コスト最適化や投資対効果(ROI)を考慮した財務戦略 モダナイズへの道筋 :カスタマイズ可能な拡張モジュールを活用し、最新のIT環境へ進化するためのステップ OpenShift Migration Advisorを利用して移行の道筋を見極め、Virtualization Migration Assessmentで確実な成功へと導く、これがOpenShift Virtualizationへの移行のステップとなります。 まずはOpenShift Migration Advisorを使ってみてください。OpenShift Migration Advisor導入に関しての疑問点や質問があれば、弊社担当までご連絡ください。
1. はじめに:自己紹介 みなさん、初めまして! 2026 年 4 月に Red Hat へアカウント・ソリューションアーキテクト(ASA)として入社いたしました古川です。 先日 5 月 14 日・ 15 日に名古屋で開催された「クラウドネイティブ会議」へ参加してきました。私にとっては、Red Hat の一員としての初めての大型技術イベントへの参加でした。会場の熱気、そして諸先輩方がブースやセッションで放つプロフェッショナルなオーラに圧倒されつつも、非常に楽しむことができましたので、2 日間の模様をレポートいたします。 2. イベント概要:クラウドネイティブ会議とは 2026 年 5 月 14 日・ 15 日の 2 日間、名古屋の中日ホール&カンファレンスにて「クラウドネイティブ会議」が開催されました。 本イベントは、以下の 3 つのカンファレンスが合同で行われた、コミュニティの枠を超えた一大イベントです。 CloudNative Days SRE Kaigi Platform Engineering Kaigi 現地には約 800 名、オンラインで約 1200 名、計 2000 名近いエンジニアが参加しており、会場は熱気に包まれていました。1 日目はクラウドネイティブ技術、2 日目は SRE および Platform Engineering を主軸とした構成で、最新トレンドを一気に吸収できる貴重な機会となりました。 イベント詳細は公式サイト↓をご確認ください。 kaigi.cloudnativedays.jp 3. Red Hatter の活躍:登壇セッションの紹介 Red Hat からは 3 名のスペシャリストが登壇しました。エッジコンピューティングの最新動向や、Platform Engineering 実施時のリアルな声に対する考えなど、多角的な視点で知見を共有し盛況となりました。登録をすればアーカイブ視聴も可能ですので、ぜひご覧ください。 Yudai Ono さん 「分断されたOTとITを繋ぐ架け橋 - Kubernetesが切り拓く産業用組み込み製品の現在地」 専用ハードウェアが主役だったOT(制御・運用技術)の世界と、ITの世界をKubernetesを活用してどう融合させるかについて。エッジデバイスにおける「Immutable OS(bootc)」の活用や、コードで構成を定義し自律的に維持する「宣言的オペレーション」など、産業用組み込み製品の最前線について学ぶことができます。 分断されたOTとITを繋ぐ架け橋 - Kubernetesが切り拓く産業用組み込み製品の現在地 | クラウドネイティブ会議 Shintaro Kitamura さん 「開発者ポータルって必要?エンタープライズにおけるPlatform Engineering立ち上げの現実解」 エンタープライズ企業で Platform Engineering を立ち上げる際の「現実解」について。「きれいなポータル画面を作る前に、裏側のインフラを整えるべきでは?」といった声に答えつつ、開発者ポータルの必要性について学ぶことができます。 開発者ポータルって必要?エンタープライズにおけるPlatform Engineering立ち上げの現実解 | クラウドネイティブ会議 Sachiko Kijima さん 「Platform Engineering はなぜスケールしないのか ― スコープ設計と責任境界の話」 Platform Engineering が組織内でスケールしない理由を、スコープ設計や責任境界の観点から実体験をもとに解説。著名な「Kotter の変革プロセス」をベースにした失敗要因の分析も行っており、社内外から共感を呼びました。 Platform Engineeringはなぜスケールしないのか ― スコープ設計と責任境界の話 | クラウドネイティブ会議 4. 初心者にも優しいイベント設計が推せる 初心者の視点から見て、この会議は非常に「学びの門戸」が広いと感じました。イベント参加前は「詳しい人ばかりだと思うので参加するのに気が引ける」と思っていました。実際開催者も参加者も詳しい方も多かったのですが、初心者が参加しても受け入れる体制が用意されていました。 セッション 2日目のセッションの1/3が初心者向けに設計されており、SREやプラットフォームの入門を網羅的に学ぶことができました。 ユニークな企画 難解なクラウドネイティブ用語を1枚の画像で解説する「用語解説チャレンジ」。生成AIなどを使用して、誰が見ても用語の意味をつかめるように伝える企画もありました。 2日目には有志が作成したSRE とプラットフォームエンジニアリングの入門書の配布が行われました。 運営の方とも少し話す機会があったのですが、「初心者の人が来ても困らないように初心者向けコンテンツをしっかり盛り込むことにはこだわった。」というお話をされていました。コミュニティの温かさと知識を誰にでも共有し合う文化に触れ、非常に感銘を受けました。 もしも私のように参加に気が引けると思っている方がいましたら、コミュニティを信じて思い切って参加してみるのはいかがでしょうか。 5. クラウドネイティブ、SRE、Platform Engineeringの入門 イベントのご説明もできたところで、せっかくなので学びのアウトプットもしてみようと思います。 最近はシステム開発の現場で「クラウドネイティブ」や「SRE」、「Platform Engineering」という言葉を耳にする機会が増えたのではないでしょうか。その割に違いが分からない、あまり内容を知らないという方もいらっしゃるかと思います。私も本イベント参加前まで、それぞれの用語を正確に説明できない状態でした。イベントを通して勉強をしてきましたので、初心者の方向けに「そもそもそれぞれどういう意味?」をお伝えいたします。 5.1 クラウドネイティブとは Cloud Native Computing Foundation(CNCF)の定義によれば、クラウドネイティブとは「変化に強く無限に拡張できるシステムを、最小限の労力で運用するためのアプローチのこと」です。パブリッククラウドやハイブリッドクラウドといった近代的な環境で、スケーラブルなアプリケーションを構築・実行するための手法です。クラウドネイティブは、以下の 5 つのコア技術が核となります。 コンテナ サービスメッシュ マイクロサービス イミュータブルインフラストラクチャ 宣言型API これらの技術を組み合わせることで、回復性、管理性、可観測性を備えた疎結合なシステムを実現します。さらに堅牢な自動化を取り入れることで、エンジニアは最小限の労力で、影響の大きなシステム変更を頻繁かつ予測通りに行うことが可能になります。 5.2 SRE(Site Reliability Engineering)とは SRE とは、「ユーザーがサービスを快適に使えるように日々のシステム運用に対してソフトウェアエンジニアリングでアプローチすること」です。システムの信頼性を担保しつつ、開発のスピードを落とさないための実践的な手法と言えます。主な活動には以下が含まれます。 インシデントレスポンス 障害発生時の動きを手順化し実践する。 ポストモーテム 障害発生後、「個人を責めない」という文化のもとで振り返りを行い、再発防止策を策定する。 トイル削減 繰り返し発生する手作業(トイル)を自動化する。 監視: システムの健康状態を計測し、目標が守られているか常時確認する。 SRE では信頼性を客観的に測るため、SLI(サービスレベル指標)と SLO(サービスレベル目標値)を定めます。さらに重要なのが「エラーバジェット(許容できるエラーの数)」という概念です。これにより、「新機能をどんどんリリースしたい開発チーム」と「とにかく安定運用したい運用チーム」の対立を避け、スピードと安定性の最適なバランスをとることができます。 また、SRE を実践する上で、欠かすことのできない要素が「オブザーバビリティ(可観測性)」です。メトリクス、ログ、トレースといったシグナルから複雑なシステムの内部を紐解き、現状を正確に把握できなければ、信頼性の維持・向上は望めません。オブザーバビリティこそが、クラウドネイティブ時代のシステム運用を支える大黒柱なのです。 SRE の実践により、クラウドネイティブ技術がもたらした複雑性という課題に対してソフトウェアエンジニアリングの力で立ち向かい、システムの信頼性を守ることができるのです。 5.3 Platform Engineeringとは クラウドネイティブのエコシステムが拡大するにつれ、開発者が選定・管理すべきツールが増え、「開発者が考えることが多すぎる」という課題が生まれました。これを解決するアプローチが Platform Engineering です。 一言で言えば、「プラットフォームの構築や運営により、開発者の認知負荷(開発者にかかる情報処理の負荷)を下げるアプローチのこと」です。プラットフォームチームが、セルフサービスで利用できるAPI、ツール、ナレッジ、サポートなどを整備した社内基盤を提供します。 また、Platform Engineering の重要なキーワードがありますのでご紹介します。 ゴールデンパス ベストプラクティスや標準化されたプロセスを整備し、開発チームが迷わずに素早く安全に開発・運用できるようにしたルートのこと。これにより、セキュリティやコンプライアンスが自然と担保され、開発者は本来の「ビジネス価値の創出」に集中できるようになります。 2つのIDP Internal Developer Platform(内部開発者プラットフォーム) CI/CDや監視などの共通機能を統合した、裏側の技術基盤。 Internal Developer Portal(内部開発者ポータル) 開発者が機能を利用するための入口となるWeb画面(代表的なOSSとしてBackstageなどがあります) このように、ゴールデンパスや IDP を駆使することによって開発者がプラットフォームの詳細を意識せずに利用することを目指します。そうすることによって、開発者がより思考やビジネス価値創出に時間を投資することができるようになります。 また、これら 3 つの概念は、単独で存在するのではなく相互に深く関わり合っています。「クラウドネイティブ」な技術基盤の上に、「SRE」の思想で信頼性を担保し、それを「Platform Engineering」によって開発者が使いやすい形で提供する。この 3 本柱を理解することが、これからのシステム開発を成功に導く第一歩となるでしょう。 6. Red Hat は敷居が高い !? 今回のイベントでは、セッションだけでなくスポンサーブースも出展し、スタンプラリーなどを通じて多くのエンジニアの方々(特に20代〜30代の若手層)と直接お話しする機会がありました。 その中で、キャリアなどの話題になった際、多くの方から「Red Hat は敷居が高く感じて、そもそもチャレンジする気にならない」というリアルな声をいただきました。 実は、先日入社したばかりの私自身も、入社前は「 Red Hat = 雲の上のエキスパート集団」というイメージがあり、同じように感じていた時期がありました。しかし、イベント後に社内の先輩方にこのお話をすると、「えっ、自分たちは全くそんなこと思っていなかった!」と、いうような反応が返ってきました。 実際の Red Hat の社内は、様々なバックグラウンドの人材がいるのに加え、知見をシェアする文化があるので分からないことがあっても 1 人で困ってしまうケースは少ないです。 しかし、外から見るとまだまだ「敷居が高い・近寄りがたい」と思われてしまっている……。社内の人間が気付いていなかった「外からのイメージとのギャップ」が分かったことは、今回ブースでみなさまと直接会話できたからこその大きな収穫でした。 今後は私自身も、こうしたブログなどでの発信を通じて「等身大の Red Hat の姿」をお伝えし、もっと多くのみなさんと気軽に会話ができるような空気を作っていきたい所存です!
はじめに レッドハットのソリューションアーキテクトの森です。 本記事は、Red Hat Connectivity Link入門シリーズの第6回です。 今回は、RHCL 1.3.3 で Tech Preview として追加された新機能、 MCP Gateway について紹介します。 過去の記事はこちらから rheb.hatenablog.com MCP Gateway は、AI エージェント開発における新しいプロトコル Model Context Protocol (MCP) を RHCL の Gateway API エコシステムに統合する機能です。複数の MCP サーバーからツール(Tools)を集約し、AI クライアントに統一されたインターフェースを提供します。 本記事では、以下の内容をカバーします: MCP(Model Context Protocol) とは何か RHCLにおける MCP Gateway の役割とアーキテクチャ RHCLにおける MCP Gateway のサンプル を手動でデプロイする手順 サンプルの 動作確認 と期待される結果 MCP Gateway とは Model Context Protocol (MCP) について Model Context Protocol (MCP) は、AI エージェントがさまざまなデータソースやツールに接続するための オープンスタンダードプロトコル です。2024年11月に Anthropic 社によって公開され、AI アプリケーション開発における標準化を目指しています。 MCP の主な特徴: 統一されたインターフェース : AI エージェントが異なるデータソースやツールに一貫した方法でアクセスできる ツールの集約 : 複数の MCP サーバーから提供されるツール(Functions)を統合 セッション管理 : クライアントとサーバー間の状態を管理 JSON-RPC ベース : シンプルで実装しやすいプロトコル MCP の公式ドキュメント : modelcontextprotocol.io MCP Gateway の役割 MCP Gateway は、RHCL における MCP プロトコルのゲートウェイ実装です。以下の役割を果たします: MCP サーバーの集約(Tool Federation) 複数の MCP サーバーからツールを収集し、単一のエンドポイントとして公開 Gateway API との統合 Kubernetes Gateway API リソース(Gateway、HTTPRoute)を活用した柔軟なルーティング Kuadrant Policy の適用 AuthPolicy、RateLimitPolicy などの Policy を MCP エンドポイントに適用可能 Tool Prefix による Namespace 管理 複数の MCP サーバーから提供されるツール名の衝突を回避 MCP Gateway の利用シーン AI エージェント開発 : 複数のバックエンド API を統合し、AI エージェントに提供 ツールの標準化 : 異なるツールを MCP プロトコルで統一 アクセス制御 : AuthPolicy による認証・認可の実装 Rate Limiting : トークン消費の制御 RHCL における MCP Gateway のアーキテクチャ コンポーネント構成 RHCL の MCP Gateway は、以下のコンポーネントで構成されます: 1. MCP Gateway Operator MCP Gateway の管理を担当する Kubernetes Operator です。以下の CRD(Custom Resource Definition)を提供します: MCPGatewayExtension : Gateway を MCP プロトコルに拡張 MCPServerRegistration : Backend MCP サーバーを登録 MCPVirtualServer (オプション): 特定のツールのみを公開する仮想エンドポイント 2. MCP Gateway Broker MCP ブローカーは、クライアントからのリクエストを受け付け、以下の処理を行います: Session 管理 : JWT トークンによるセッション追跡 Tool Federation : 複数の MCP サーバーからツールを集約 Request Routing : ツール呼び出しを適切な backend MCP サーバーに転送 3. Backend MCP Servers 実際のツール(Functions)を提供する MCP サーバーです。例: データベースクエリツール API 呼び出しツール ファイル操作ツール カスタムビジネスロジック 4. Gateway API リソース MCP Gateway は、Kubernetes Gateway API リソースを活用します: Gateway : エントリーポイント(Listener 定義) HTTPRoute : ルーティングルール ReferenceGrant : Cross-namespace 参照の許可 5. Kuadrant Policy(オプション) MCP エンドポイントに適用可能なポリシー: DNSPolicy : DNS レコードの自動管理 TLSPolicy : TLS 証明書の自動取得 AuthPolicy : API Key / JWT 認証 TokenRateLimitPolicy : Tokenベースのレート制限 リクエストフロー MCP クライアントから Backend MCP サーバーまでのリクエストフローは以下の通りです: External Client → http://mcp.example.com/mcp (HTTP listener - MCP Gateway の標準構成) Gateway → MCP Broker MCP Broker → Hairpin Request → Gateway → HTTPRoute → Backend MCP Server Backend MCP Server → Tool 実行結果を返却 Hairpin Request : MCP Broker が Gateway 自身を経由して backend に接続する仕組み。Gateway API のルーティングや Policy を適用可能。 Custom Resource Definition (CRD) MCP Gateway で使用する主要な CRD を紹介します。 MCPGatewayExtension Gateway を MCP プロトコルに拡張する CRD です。 apiVersion : mcp.kuadrant.io/v1alpha1 kind : MCPGatewayExtension metadata : name : mcp-gateway-extension namespace : mcp-system spec : targetRef : group : gateway.networking.k8s.io kind : Gateway name : mcp-gateway # 対象のGateway名 namespace : ai-gateway # Gatewayを設置している Namespase sectionName : http-mcp # HTTP listener を指定 publicHost : mcp.example.com # 自分の環境のHostnameに置き換える privateHost : mcp-gateway-istio.ai-gateway.svc.cluster.local:80 httpRouteManagement : Enabled # HTTPRoute の自動管理を有効化 主要フィールド : フィールド 説明 targetRef 対象の Gateway リソース(Cross-namespace 参照可能) sectionName Gateway の Listener 名(MCP 内部通信用) publicHost 外部からアクセスする際のホスト名 privateHost Hairpin リクエスト用の内部ホスト名(Gateway Service) httpRouteManagement HTTPRoute の自動管理(Enabled / Disabled) MCPServerRegistration Backend MCP サーバーを登録する CRD です。 apiVersion : mcp.kuadrant.io/v1alpha1 kind : MCPServerRegistration metadata : name : test-server1 namespace : mcp-system spec : path : /mcp toolPrefix : test1_ targetRef : group : gateway.networking.k8s.io kind : HTTPRoute name : mcp-server1-route 主要フィールド : フィールド 説明 path MCP エンドポイントのパス(例: /mcp ) toolPrefix ツール名のプレフィックス(例: test1_ → test1_greet )。複数サーバーのツール名衝突を回避 targetRef Backend MCP サーバーへのルート(HTTPRoute を指定) MCP Gateway のサンプル環境/設定の手動デプロイ手順 ここでは、RHCL の MCP Gateway Upstream リポジトリ( Kuadrant/mcp-gateway )で提供されている test-server1 サンプルを手動でデプロイする手順を紹介します。 前提条件 OpenShift Container Platform 4.19 以上 OpenShift Service Mesh 3.2 以上 RHCL 1.3.3 がインストール済み( 第1回参照 ) oc CLI ツールが利用可能 サンプルアーキテクチャ 今回デプロイするサンプルは以下の構成です: Gateway : mcp-gateway (ai-gateway namespace) HTTP listener (port 80) - MCP Gateway の標準構成 MCP 内部用 listener ( *.mcp.local ) Backend MCP Server : mcp-test-server1 提供ツール: greet , time , slow , headers , add_tool イメージ: ghcr.io/kuadrant/mcp-gateway/test-server1:latest なお、このサンプル MCP Server は、動作確認用として以下の 5 つの MCP Tools を提供します。 greet : 指定した名前に対して挨拶メッセージを返します。 time : 現在時刻を返します。 slow : 指定した秒数だけ待機してからレスポンスを返します。 headers : MCP Gateway 経由で受け取った HTTP ヘッダー情報を確認できます。 add_tool : 新しいツールを動的に追加する挙動を確認できます。 以降の手順では、これらのツールが MCP Gateway によって検出され、 tools/list や tools/call 経由で利用できることを確認します。 デプロイ手順 ステップ1: MCP Gateway Operator のインストール OpenShift Web Console から、 Ecosystem -> Software Catalog を選択し、Filter に、 MCP Gateway と入れてください。 MCP Gatewat Operator (Tech Preview) を選択します。 インストール時の設定については、下記のようにします。(2026/05時点) Update channel : preview Version : 0.6.0 Istallation mode : All namespaces on the cluster (default) ステップ2: Namespace の作成 Gateway、HTTPRoute、MCP Server などを配置する Namespace を作成します。 oc create namespace ai-gateway oc create namespace mcp-system ステップ3: ReferenceGrant の作成 Cross-namespace 参照を許可します( mcp-system → ai-gateway (Gateway を配置する Namespace))。 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: mcp-gateway-cross-namespace namespace: ai-gateway # Gateway を配置する Namespace spec: from: - group: mcp.kuadrant.io kind: MCPGatewayExtension namespace: mcp-system # MCP Server を配置する Namespace to: - group: gateway.networking.k8s.io kind: Gateway EOF 重要 : ReferenceGrant は、参照される側の namespace(この場合 ai-gateway )に作成します。 ステップ4: Gateway の作成 MCP Server にアクセスするための Gatewayリソースを作成します。 (詳細は 第2回参照 ) oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: mcp-gateway namespace: ai-gateway # Gateway を配置する Namespace spec: gatewayClassName: istio listeners: - name: http-mcp hostname: 'mcp.example.com' # 自分の環境のHostnameに置き換える port: 80 protocol: HTTP allowedRoutes: namespaces: from: All - name: mcps port: 80 protocol: HTTP hostname: '*.mcp.local' allowedRoutes: namespaces: from: All EOF 注 : hostname は実際の環境に合わせて変更してください 確認 : oc get gateway -n ai-gateway 期待される出力の例: NAME CLASS ADDRESS PROGRAMMED AGE mcp-gateway istio a98f1593264b1474aafc6fff5736c2d9-661449485.us-... True 1m ステップ5: MCPGatewayExtension の作成 oc apply -f - <<EOF apiVersion: mcp.kuadrant.io/v1alpha1 kind: MCPGatewayExtension metadata: name: mcp-gateway-extension namespace: mcp-system spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: mcp-gateway namespace: ai-gateway sectionName: http-mcp # 内部 hairpin は HTTP を使用 publicHost: mcp.example.com # 自分の環境のHostnameに置き換える privateHost: mcp-gateway-istio.ai-gateway.svc.cluster.local:80 # Gatewayが生成するServiceのHostname httpRouteManagement: Enabled EOF 重要 : sectionName は http-mcp を指定します。MCP Gateway の内部 hairpin リクエストは HTTP を使用するためです。 確認 : oc get mcpgatewayextension -n mcp-system 期待される出力: NAME READY AGE mcp-gateway-extension True 30s ステップ6: DNS Provider Secretの作成 DNSPolicyを使用するための、DNSプロバイダーの認証情報を設定します。 (詳細は 第2回参照 ) # AWS認証情報Secretの作成(Gatewayネームスペース用) oc -n ai-gateway create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY # cert-managerネームスペース用 oc -n cert-manager create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY 以下の変数は、自分の環境でのIDとKEYに置き換えてください。 $KUADRANT_AWS_ACCESS_KEY_ID $KUADRANT_AWS_SECRET_ACCESS_KEY ステップ7: DNSPolicy の作成 Route53 に DNS レコードを自動作成します。 (詳細は 第2回参照 ) oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: DNSPolicy metadata: name: mcp-gateway-dns namespace: ai-gateway # Gateway のNamespace spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: mcp-gateway sectionName: http-mcp # HTTP listener に適用 providerRefs: - name: aws-credentials # 先ほど作成したDNS Provider Secret EOF providerRefs に、先ほど作成した DNS Provider Secret を設定してください。 注意 : DNS Record が作成され、DNS伝播するまでに少々時間がかかる場合があります。 ステップ8: Backend MCP Server のデプロイ oc apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: mcp-test-server1 namespace: mcp-system spec: replicas: 1 selector: matchLabels: app: mcp-test-server1 template: metadata: labels: app: mcp-test-server1 spec: containers: - name: mcp-test-server1 image: ghcr.io/kuadrant/mcp-gateway/test-server1:latest imagePullPolicy: Always command: ["/mcp-test-server"] args: ["--http", "0.0.0.0:9090"] ports: - containerPort: 9090 name: http env: - name: LOG_LEVEL value: "info" --- apiVersion: v1 kind: Service metadata: name: mcp-test-server1 namespace: mcp-system spec: selector: app: mcp-test-server1 ports: - name: http port: 9090 targetPort: 9090 protocol: TCP EOF 確認 : oc get pods -n mcp-system -l app=mcp-test-server1 期待される出力: NAME READY STATUS RESTARTS AGE mcp-test-server1-6f6f6bf5dd-jhlgr 1/1 Running 0 1m ステップ9: 内部用 HTTPRoute の作成 Backend MCP Server への内部ルートを作成します。 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: mcp-server1-route namespace: mcp-system labels: mcp-server: 'true' spec: parentRefs: - name: mcp-gateway namespace: ai-gateway hostnames: - 'server1.mcp.local' rules: - matches: - path: type: PathPrefix value: / filters: - type: RequestHeaderModifier requestHeaderModifier: set: - name: Accept value: "application/json, text/event-stream" backendRefs: - name: mcp-test-server1 port: 9090 EOF 重要 : filters で Accept: application/json, text/event-stream ヘッダーを設定します。MCP プロトコルでは両方の Content-Type が必要です。 application/json のみを設定すると、Backend MCP Server が "Accept must contain both 'application/json' and 'text/event-stream'" エラーを返し、tools/call が失敗します。 ステップ10: MCPServerRegistration の作成 Backend MCP Server を MCP Gateway に登録します。 oc apply -f - <<EOF apiVersion: mcp.kuadrant.io/v1alpha1 kind: MCPServerRegistration metadata: name: test-server1 namespace: mcp-system spec: path: /mcp toolPrefix: test1_ targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: mcp-server1-route EOF 確認 : oc get mcpserverregistration -n mcp-system 期待される出力: NAME PREFIX TARGET PATH READY TOOLS CREDENTIALS AGE test-server1 test1_ mcp-server1-route /mcp True 5 12h 確認ポイント : READY が True で、 TOOLS が 5 であることを確認してください。これは、5つのツール(greet, time, slow, headers, add_tool)が正常に検出されたことを示します。 ステップ11: DNS 解決の確認 ローカルマシンから DNS 解決を確認します。 nslookup mcp.example.com # 自分の環境のHostnameに置き換える 期待される出力: Server: 8.8.8.8 Address: 8.8.8.8#53 Non-authoritative answer: mcp.example.com canonical name = *****-*****.reagioin.elb.amazonaws.com. Name: *****-*****.reagioin.elb.amazonaws.com Address: 13.59.251.55 Name: *****-*****.reagioin.elb.amazonaws.com Address: 3.12.127.167 AWS ELB(Istio Gateway Service)の IP アドレスが返却されれば、DNS レコードが正しく作成されています。 サンプルの検証手順と期待値 ここでは、デプロイした MCP Gateway サンプルの動作確認を行います。ローカルマシンから HTTP 経由で MCP リクエストを送信します。 環境変数の設定 自分の環境のHostnameに置き換えて、 MCP_URL を設定してください。 MCP_URL="http://mcp.example.com/mcp" ① Initialize Request(セッション初期化) MCP セッションを初期化します。 curl -v ${MCP_URL} \ -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "jsonrpc": "2.0", "method": "initialize", "params": { "protocolVersion": "2025-11-25", "capabilities": {}, "clientInfo": { "name": "manual-test", "version": "1.0.0" } }, "id": 1 }' 期待される結果 : < HTTP/1.1 200 OK < content-type: application/json < mcp-session-id: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...(略) < date: Sun, 24 May 2026 14:21:40 GMT < content-length: 176 < x-envoy-upstream-service-time: 0 < server: istio-envoy < {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"Kuadrant MCP Gateway","version":"0.0.1"}}} 確認ポイント : HTTP ステータス: 200 OK mcp-session-id ヘッダーに JWT トークンが含まれている レスポンス JSON に protocolVersion と serverInfo が含まれている Session ID を環境変数に保存 : SESSION_ID="<上記レスポンスの mcp-session-id の値>" ② Tools List Request(利用可能なツールのリスト取得) curl -s ${MCP_URL} \ -X POST \ -H "Content-Type: application/json" \ -H "mcp-session-id: ${SESSION_ID}" \ -d '{ "jsonrpc": "2.0", "method": "tools/list", "id": 2 }' | jq . 期待される結果 ( jq でフォーマット済み): { " jsonrpc ": " 2.0 ", " id ": 2 , " result ": { " tools ": [ { " _meta ": {} , " annotations ": { " title ": " add " } , " description ": " dynamically add a new tool (triggers notifications/tools/list_changed) ", " inputSchema ": { " additionalProperties ": false , " properties ": { " description ": { " description ": " the description of the new tool ", " type ": " string " } , " name ": { " description ": " the name of the new tool to add ", " type ": " string " } } , " required ": [ " name ", " description " ] , " type ": " object " } , " name ": " test1_add_tool " } , { " _meta ": {} , " annotations ": {} , " description ": " say hi ", " inputSchema ": { " additionalProperties ": false , " properties ": { " name ": { " description ": " the name to say hi to ", " type ": " string " } } , " required ": [ " name " ] , " type ": " object " } , " name ": " test1_greet " } , { " _meta ": {} , " annotations ": {} , " description ": " get headers ", " inputSchema ": { " additionalProperties ": false , " properties ": {} , " required ": [] , " type ": " object " } , " name ": " test1_headers " } , { " _meta ": {} , " annotations ": {} , " description ": " delay N seconds ", " inputSchema ": { " additionalProperties ": false , " properties ": { " seconds ": { " description ": " number of seconds to wait ", " type ": " integer " } } , " required ": [ " seconds " ] , " type ": " object " } , " name ": " test1_slow " } , { " _meta ": {} , " annotations ": { " title ": " time " } , " description ": " get current time ", " inputSchema ": { " additionalProperties ": false , " properties ": {} , " required ": [] , " type ": " object " } , " name ": " test1_time " } ] } } 確認ポイント : tools 配列に 5 つのツールが含まれている 各ツール名に test1_ プレフィックスが付いている(MCPServerRegistration の toolPrefix 設定) inputSchema でツールの引数が定義されている ③ Tool Call Requests(ツールの実行) 各ツールを実行して、動作を確認します。 ③-1. test1_time - 現在時刻取得 curl -s ${MCP_URL} \ -X POST \ -H "Content-Type: application/json" \ -H "mcp-session-id: ${SESSION_ID}" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "test1_time", "arguments": {} }, "id": 10 }' 期待される結果 : event: message data: {"jsonrpc":"2.0","id":10,"result":{"content":[{"type":"text","text":"2026-05-25 00:16:49.122721849 +0000 UTC m=+439.191493349"}]}} 確認ポイント : Server-Sent Events 形式のレスポンス UTC タイムスタンプが返却される その他のツール( test1_greet 、 test1_headers 、 test1_slow 、 test1_add_tool )も同様に tools/call で実行できます。 検証完了条件 : ✅ 5 つのツール全てが正常に実行され、期待通りのレスポンスが返る ✅ Hairpin リクエスト(MCP Gateway → Backend MCP Server)が正常に動作 ✅ Server-Sent Events 形式のレスポンスが正しく返却される 終わりに 本記事では、RHCL 1.3.3 で Tech Preview として追加された MCP Gateway についてサンプルを用いて紹介しました。 今後、Red Hat Connectivity Linkは、AI Gatewayとしての機能をさらに充実していく予定となっておりますので、乞うご期待ください!
こんにちは、Ansible Automation Platform製品のテクニカルサポートの呉です。 この記事では、Ansible Automation Platform(AAP)と OPA (Open Policy Agent) を連携する方法を紹介します。 みなさまが、AAPで Policy as Code な運用を始めるための最初の一歩の手助けとなれば幸いです。 はじめに:そもそも、Policy as Codeとは? PaCは、組織のルールやセキュリティ要件をコード化し、自動化の実行時にリアルタイムで強制適用する仕組みです。 この仕組みを実現するために使われるのが OPA(Open Policy Agent)となります。 OPAは、チェックまたは適用したいポリシーを保存・管理するための外部サーバーです。 AAP と OPA を連携すると、AAPは自動化ジョブが実行される直前(ランタイム)に、対象のジョブが規定のポリシーに準拠しているかを自動で検証できるようになります。 規定するポリシーとしては、たとえば: 平日日勤帯以外でのジョブの実行を禁止する。 ジョブの実行日時やタイミングによって、ジョブを起動可能なユーザーを制限する。 ジョブに渡してはいけない変数を定義する。 インベントリの全ホストに対して一斉にジョブを適用することを禁止する(最大XX台までにする)。 などなど・・・これらのような内容がユースケースとして考えられるかと思います。 それぞれの開発・運用現場によって異なる細かいルールがあるかと思いますが、こうした数々のルールをあらかじめコードで定義しておくことで、 ジョブの実行前に手動でのポリシー確認が不要になるため、開発や生産性のスピードを落とすことなく一貫したガバナンスを適用できます。 詳細はこちらの記事などもぜひご参考ください。 www.redhat.com AAPとOPAを連携してみる それでは、実際にAAPとOPAを連携してみたいと思います。なお、今回はチュートリアルですので、OPAサーバーはコンテナでさくっと用意します。 今回実装例として使用する実装・適用するポリシーは、AAPのジョブテンプレートの extra_vars に ansible_user: root の設定を禁止するルールとします。 これにより、マネージドノードへSSHログインするユーザーを extra_vars で root ユーザーに上書きされるリスクを回避することができます。 作業ディレクトリを作成 まずは、AAPからアクセス可能なサーバーの任意の場所に policies ディレクトリを作成します。 このディレクトリ配下に、以下の内容で DenyRootUser.rego ファイル(このファイル名は任意の名前で構いません)を作成してください。 ./policies/DenyRootUser.rego package aap.demo import rego.v1 default root_user_deny = {"allowed": true, "violations": []} # ユーザーが extra_vars で root ユーザーを指定したら拒否 root_user_deny = {"allowed": false, "violations": [reason]} if { input.extra_vars.ansible_user == "root" reason := "セキュリティポリシーにより、extra_vars での root ユーザー指定は禁止されています。" } OPAのコンテナイメージをダウンロードします。 $ podman pull openpolicyagent/opa:latest OPAを起動します。  ※./policies ディレクトリおよび DenyRootUser.rego ファイルの部分は、実際のパスおよびファイル名に書き換えてください。 $ podman run -d --name opa-server --network host -v $(pwd)/policies:/policies:Z openpolicyagent/opa run --server --addr localhost:8181 /policies/DenyRootUser.rego  これで、OPAは起動しました。 AAP側で、OPAの設定を行います。  AAP ダッシュボードから、設定 > Automation Execution > Policy > 編集ボタンから、 OPA server hostname に OPAコンテナが起動中のサーバーのアドレスを設定し、 OPA server port にポート 8181 を設定し保存してください。  なお、今回はひとまずOPAを動かすことが目的なので、筆者はAAPと同じサーバー上でOPAコンテナを起動しました。そのため、 OPA server hostname には以下のようにlocalhostを設定しています。 AAP側のOPA設定画面  もし実際の本番環境で運用する場合、冗長性などの観点から、AAPとは別のサーバーでOPAを起動することもご検討ください。 AAPで任意のジョブテンプレートを開き、設定項目 Policy enforcement に aap/demo/root_user_deny を設定してください。また、今回はポリシー拒否の挙動を確認するため、テストとして設定項目 Extra variables には、 ansible_user: root をあえて設定して保存してください。  なお、 Policy enforcement に設定した aap/demo/root_user_deny  はOPAのクエリパスです。これは、ジョブテンプレートと連携したいOPAのポリシーを指定するのに使います。  今回の例では、以下の抜粋のように ./policies/DenyRootUser.rego ファイルの冒頭を package aap.demo と定義しており、またその中の root_user_deny ポリシーをジョブテンプレートに適用したいので、クエリが aap/demo/root_user_deny となりました。適用するポリシーによって、このクエリパスは変わりますのでご留意ください。 ``` package aap.demo ... # ユーザーが extra_vars で root ユーザーを指定したら拒否 root_user_deny = {"allowed": false, "violations": [reason]} if { ... ``` OPAの設定が完了したら、ジョブテンプレートを実行してみます。  以下の実行ログが出ましたら、OPAのセットアップは期待通りに成功しています。 ``` This job cannot be executed due to a policy violation or error. See the following details: {'Violations': {'Job template': ['セキュリティポリシーにより、extra_vars での root ' 'ユーザー指定は禁止されています。']}} ``` まとめ いかがでしたでしょうか。今回はコンテナを使って「最初の一歩」となるAAPとOPAの連携手順を紹介しました。 AAPとOPAを連携することで、これまで課題になりがちだった「運用ルールの形骸化」を防ぎ、ジョブの実行直前にシステム側で自動的にガードレールを敷くことが可能になります。 これにより、Ansibleによる自動化のスピードや柔軟性を損なうことなく、より安全で一貫したガバナンスを実現できるかと思います。 今回はシンプルな変数チェックを試しましたが、現場のルールに合わせてぜひ応用してみてください!
RHELのスペシャリストソリューションアーキテクトの田中司恩( @tnk4on )です。 nginx の rewrite モジュールにヒープバッファオーバーフローの脆弱性 CVE-2026-42945(通称「NGINX Rift」)が公開されました。Red Hat は本脆弱性の影響度(Impact)を Critical と評価しており(CVSS v3.1 Base Score: 8.1)、該当する全製品へのエラータを順次提供しています。脆弱性の詳細は CVE-2026-42945(Red Hat Customer Portal) 、技術的な分析は NGINX Rift(depthfirst.com) 、F5 のセキュリティーアドバイザリーは K000161019 を参照してください。 この記事では、コンテナーイメージとして nginx を利用している方に向けて、 Red Hat Hardened Images の hi/nginx を使うことで NGINX Rift にいかに早く対応できるかを紹介します。前提として、アプリケーションがすでにコンテナー化されている、またはこれからコンテナー化を目指している環境を想定しています。Red Hat Hardened Images については、以前の記事「 Red Hat Summit 2026で発表されたRHELの最新アップデート 」でも紹介しています。 rheb.hatenablog.com 脆弱性対応の課題: パッチ適用までの時間 RHEL ユーザーにとって、脆弱性が公開されてからパッチを適用するまでの手順は通常、複数のステップにまたがります。Red Hat がエラータを公開し、リポジトリーの同期を行い、テスト環境で検証し、本番環境に適用する。 以前の記事 では Red Hat Satellite を使ってこのプロセスを効率化する方法を紹介しましたが、手順そのものが不要になるわけではありません。 コンテナー環境でも同様の課題があります。Docker Hub の公式 nginx イメージや UBI ベースの nginx イメージを使っている場合、アップストリームプロジェクトで脆弱性が修正されても、それがコンテナーイメージに反映されるまでには時間がかかります。イメージの更新を待ち、Containerfile を修正し、アプリケーションイメージを再ビルドし、テストしてデプロイする。この間、脆弱性スキャナーはアラートを出し続けますが、修正版のイメージが届かない限り、ユーザーは対処のしようがありません。あるいは、各ディストリビューションから修正済みのパッケージ(RHEL であれば RPM パッケージ)のみが先にリリースされている場合、そのパッケージをコンテナー内で適用し、イメージを再ビルドするという手順を自ら行う必要があります。 NGINX Rift は、こうした課題が特に注目されるケースとなりました。 以前の記事 で取り上げた CVE-2026-31431(Copy Fail)に続き、AI を活用した脆弱性検出が現実のものとなる中で発見された新たな Critical 脆弱性です。nginx はリバースプロキシーやロードバランサーとして広く使われており、Web インフラの入口に位置するコンポーネントであるため、他の脆弱性と組み合わされた場合の影響範囲が大きく、迅速な対応が求められます。このような状況で、Red Hat Hardened Images の hi/nginx はどれだけ速く修正版を届けることができたのでしょうか。 Red Hat Hardened Images カタログ(images.redhat.com) hi/nginx の修正リリースはどれだけ速かったか Red Hat Hardened Images の hi/nginx は、NGINX Rift の公開から わずか1日以内 にエラータ RHSA-2026:17417 を発行し、修正版イメージをレジストリーに公開しました。 以下は CVE-2026-42945 に対する各製品のエラータ発行状況です(5/19 時点)。Red Hat Hardened Images が最も早く、5月14日に修正版をリリースしています。 CVE-2026-42945 に対するエラータ一覧 製品 修正リリース日 CVE 公開からの日数 hi/nginx(Red Hat Hardened Images) 5/14 T+1 RHEL 9.2 AUS / E4S / ELS 5/15 T+2 RHEL 9.6 EUS(nginx:1.24 / nginx:1.26 モジュール) 5/15 T+2 RHEL 9.0 E4S / 9.4 EUS / 9.6 EUS / 10.0 EUS 5/16 T+3 RHEL 10 標準ストリーム(nginx) Affected(5/19 時点で未修正) — RHEL 9 標準ストリーム(nginx:1.24 / nginx:1.26 モジュール) Affected(5/19 時点で未修正) — Red Hat Lightspeed proxy 1 Affected(5/19 時点で未修正) — エラータの詳細は各 RHSA advisory ページの Affected Products セクションで確認できます *1 。 hi/nginx は RHEL の EUS / AUS / E4S / ELS 各リポジトリーへのエラータ提供より 1〜2日先行 しており、RHEL 標準ストリーム(RHEL 9 / 10)には 5/19 時点でまだエラータが提供されていません。RHEL の各ストリームでは、パッケージのビルド・テスト・QE など複数のプロセスを経てエラータが発行されるため、提供までに時間がかかる場合があります。Red Hat Hardened Images はこのプロセスを自動化パイプラインで短縮しており、今回の NGINX Rift ではその差が顕著に現れました。 では、この速度はどのようにして実現されているのでしょうか。その鍵となるのが、アップストリームプロジェクトのコミットを自動検知し、RPM のビルドからコンテナーイメージの生成、レジストリーへの公開までを実行する自動化パイプラインです。Red Hat Hardened Images のパッケージには、Fedora dist-git をそのまま使う「clean」、Fedora に独自パッチを加える「modified」、Fedora に存在しないパッケージを独自に管理する「native」の3種類があり、参照するアップストリームが異なります。nginx は「clean」に分類されるため、Fedora メンテナのコミットがそのまま自動レーンに乗り、人手の介入なしで修正版がリリースされました *2 。この仕組みにより、ユーザーは修正版のイメージが届くのを長く待つ必要がなくなります。 hi/nginx を使うとパッチ適用はどう変わるか では、実際に hi/nginx を使っている場合、NGINX Rift への対応はどのように変わるのでしょうか。結論から言えば、 コンテナーイメージを更新するだけ で完了します。 従来のパッチ適用プロセスと比較してみましょう。 手順 従来の nginx イメージ hi/nginx 修正版の提供を待つ 数日〜数週間 1日以内 Containerfile の修正 バージョンタグの変更が必要 フローティングタグなら変更不要 アプリケーションイメージの再ビルド 必要 必要 修正版の検証 SBOM なし、署名なしの場合が多い SBOM・署名・来歴証明が標準付属 最も大きな違いは最初のステップです。修正版のイメージが届くまでの「待ち時間」が数日から1日以内に短縮されます。Red Hat Hardened Images のゼロ CVE 戦略により、脆弱性が公開されたらすぐに修正版のイメージが提供されるため、あとはイメージを pull してデプロイするだけです。 さらに、 hi/nginx では :1 や :1.30 のようなフローティングタグが提供されています。これらのタグはメジャーバージョンやマイナーバージョン内の最新リリースを常に追跡するため、Containerfile を変更せずにイメージを再ビルドするだけでセキュリティー修正を取得できます *3 。 hi/nginx の CVE Reporting ページ Docker Hub や UBI の nginx イメージからの移行 まだ hi/nginx を使っていない場合でも、移行は容易です。多くの場合、Containerfile の FROM 行を書き換えるだけで動作します。 # Docker Hub の公式 nginx イメージを使っている場合 FROM docker.io/nginx:latest # ↓ FROM registry.access.redhat.com/hi/nginx:1 メジャーバージョンタグ :1 を指定しておけば、nginx 1.x 系の最新セキュリティー修正が自動的に反映されます。Red Hat Developer の記事「 Exploring distroless containers with Project Hummingbird 」でも紹介されている通り、 registry.access.redhat.com/hi/ というレジストリーパスを指定するだけで、Docker Hub のイメージとほぼ同じ使い勝手でコンテナーを起動できます。 $ podman pull registry.access.redhat.com/hi/nginx:1 $ podman run -d -p 8080:8080 registry.access.redhat.com/hi/nginx:1 移行にあたって知っておくべき違いがいくつかあります。以下の図と表で確認してみましょう。 コンテナーイメージの移行による変更点の比較 項目 Docker Hub nginx hi/nginx リッスンポート 80 8080 (非 root 実行のため) 実行ユーザー root UID 65532 シェル あり(bash) なし (distroless) パッケージマネージャー あり(apt) なし SBOM なし 標準付属 (SPDX 形式) イメージ署名 なし cosign + SLSA L3 provenance ポート番号の変更(80 → 8080)は、Kubernetes のマニフェストや docker-compose.yml のポートマッピングを調整するだけで対応できます。シェルが含まれないため、コンテナー内部の調査には podman logs によるコンテナーログの確認や、一時的なデバッグコンテナーの使用が推奨されています。詳細は Red Hat Hardened Images の公式ドキュメント を参照してください。 なお、Containerfile でアプリケーション固有の設定をインストールしている場合や、ベースイメージに深い依存関係がある場合は、追加の調整が必要になることがあります。具体的な使い方や設定方法については、 images.redhat.com の各イメージの Overview ページに掲載されています。 hi/nginx の Overview ページ Red Hat Hardened Images は無償で利用可能です。登録やメールアドレスも不要で、 images.redhat.com からすぐにダウンロードできます。 まとめ この記事では、NGINX Rift(CVE-2026-42945)を題材に、Red Hat Hardened Images の hi/nginx を使うことでいかに早く脆弱性に対応できるかを紹介しました。 hi/nginx は CVE 公開から1日以内に修正版をリリースし、RHEL の各リポジトリーへのエラータ提供より1〜2日先行した hi/nginx を使っている場合、パッチ適用はイメージを更新するだけで完了する Docker Hub や UBI の nginx イメージからの移行は、多くの場合 FROM 行を書き換えるだけで導入できる 従来の RHEL パッチ運用では、Satellite のようなツールを使ってプロセスを効率化できますが、コンテナー化されたワークロードについては、Red Hat Hardened Images のゼロ CVE 戦略によってセキュリティー対応の速度を抜本的に引き上げることができます。すべてのワークロードを一度に移行する必要はありません。まずは nginx のような Web サーバーなど、セキュリティー上のインパクトが大きいコンポーネントから Red Hat Hardened Images への差し替えを検討してみてください。 リンク Red Hat Hardened Images カタログ Red Hat Hardened Images 製品ドキュメント Project Hummingbird 公式サイト CVE-2026-42945 — Red Hat Customer Portal RHSA-2026:17417 — Red Hat Hardened Images 用エラータ F5 K000161019 — NGINX Rift セキュリティーアドバイザリー NGINX Rift 解説(depthfirst.com) Red Hat Satellite で CVE-2026-31431(Copy Fail)のパッチを適用する — RHEB Exploring distroless containers with Project Hummingbird — Red Hat Developer Red Hat Summit 2026で発表されたRHELの最新アップデート — RHEB *1 : CVE ページの表は概要表示のため、1 errata あたり代表的な製品名が 1 行で表示されます。例えば RHSA-2026:17751 は CVE ページでは「RHEL 9.2 Update Services for SAP Solutions」と表示されますが、advisory ページには AUS / E4S / ELS の 3 系統・9 製品が列挙されています。 *2 : 実際のコミットログを追いたい方のために、主要なリンクを記載します。Fedora メンテナによる dist-git コミット: c423f5f5 (2026-05-13 22:06 UTC)、Hummingbird rpms への自動 MR: 3140aa9f (2026-05-14 00:14 UTC)、自動マージ: df7ed5b5 (00:51 UTC)、containers lockfile 更新: e2d1f8aa 。 *3 : Red Hat Hardened Images の 公式ガイド では、:latest タグはテスト用途向けとされています。本番環境ではメジャーバージョンタグ(:1)やマイナーバージョンタグ(:1.30)の使用が推奨されています。
RHELのスペシャリストソリューションアーキテクトの田中司恩( @tnk4on )です。 2026年5月11日〜14日に開催されたRed Hat Summit 2026にて、Red Hat Enterprise Linux (RHEL) に関連する多くの発表が行われました。この記事では、Day 2キーノート「 The AI-ready enterprise is here 」のRHELセクションの内容をまとめています。キーノートはYouTubeでオンデマンド視聴が可能ですので、ぜひ動画と合わせてご覧ください。 youtu.be RHELの最新アップデート Day 2キーノート:RHELセクションの冒頭 Red Hat Summit 2026のDay 2キーノートでは、Ashesh Badani(President and Chief Product Officer)が「世界をリードするエンタープライズLinuxプラットフォーム、RHELから始めましょう」と切り出し、RHELに関連する以下のトピックが取り上げられました。 ライフサイクルの拡張 — RHEL Long-Life Add-On NVIDIA連携の強化 — RHEL for NVIDIA ゼロCVEを目指すコンテナーイメージ — Red Hat Hardened Images AI開発向けOS — Fedora Hummingbird Linux 開発者向けローカル環境 — Red Hat Desktop AIエージェントの安全な実行 — OpenShell キーノートでは「すべてが、本当にすべてがLinux上で動いている」と語られ、ハードウェアエコシステム、数千のアプリケーション、複数のクラウド、UBIのようなパッケージングモデルなど、RHELへの要件が膨大であることが強調されました。 RHEL Long-Life Add-On We need to run RHEL forever." 「何十年もの間、Red Hatの10年サポートが業界標準でした。それを14年に延長しました。しかし、皆さんの中には私の目を見てこう言う方がいました。『あのバージョンのRHELを永遠に動かし続けたい』と。皮肉を込めてではなく」 キーノートではこの言葉から、エンタープライズにおけるRHELの長期運用ニーズが語られました。これに応える形で、 Red Hat Enterprise Linux Long-Life Add-On が発表されました。 Introducing Red Hat Enterprise Linux Long-Life Add-On RHEL Extended Life Cycle, Premium のライフサイクル(メジャーバージョン最大14年、特定マイナーリリース6年延長)が終了した後も、終了日が予め定められていない継続的なサポートを提供するアドオンです。年次更新で購入でき、Red Hat Product Securityが「Critical」と評価したセキュリティー脆弱性へのパッチと優先度の高いバグ修正、および24時間体制の技術サポートが提供されます。 「変更できないシステムには、終わらないサポートが必要だ」と語りました。 RHEL for NVIDIA 「Faster innovation. Faster updates.」— Red Hat × NVIDIA 「Faster innovation. Faster updates.」のメッセージとともに、Red HatとNVIDIAの連携強化が紹介されました。 キーノートでは「NVIDIAはムーアの法則を凌駕するような性能向上を伴う新GPUを年次サイクルで出荷している」と述べられ、このスピードに対応するために今年導入されたのが Red Hat Enterprise Linux for NVIDIA です。 RHEL for NVIDIA 26.01は4月に提供が開始されています。RHELの恒久的なフォークではなく、NVIDIAの最新ハードウェアサポートがRHELのメインラインに統合されるまでの一時的なブリッジとして機能する特別エディションです。NVIDIAのハードウェアサイクルに追従するより高速な更新を提供しつつ、コアのRHELシステムとの互換性を維持します。 「安定性重視のゆっくり動くシステムでも、イノベーション重視の速く動くシステムでも、RHELを動かしているからこそ選べる」— 安定性とイノベーションの両立をRHELが実現するというメッセージが語られました。 Red Hat Hardened Images 「Zero CVEs」 キーノートでは、セキュリティーに関して「変わらないものがひとつある。それはセキュリティーだ。RHELは設計段階からセキュリティーに注力しており、SELinuxのようなデフォルト設定によりデプロイの瞬間からセキュアだ」と述べられました。 そして「目指すのはゼロ。ゼロCVEだ」という言葉とともに、コンテナーイメージに含まれる多数のCVE(警告アイコン群)が「Zero CVEs」(すべてグリーン)に変わるビジュアルで、 Red Hat Hardened Images が紹介されました。 Introducing Red Hat Hardened Images Red Hat Hardened Imagesは、最新の言語やランタイム、データベース、Webサーバーなどのマイクロサイズでテスト済みの強化されたコンテナーイメージです。クラウドネイティブ環境はもちろん、コンテナーを活用するさまざまなワークロードの基盤として利用できます。 無償で利用可能(RHELサブスクリプションへの追加コスト不要) 登録やメールアドレスも不要で、 images.redhat.com からすぐにダウンロード可能 Red Hatサポートをプラットフォーム内で取得するオプションも今後追加予定 これらのイメージは、無人のエージェンティックソフトウェアファクトリーにより継続的にビルドされています。キーノートでは詳細は語られませんでしたが、このファクトリーは Konflux をベースとしています。ビルドの仕組みについては「 Reproducible builds with Project Hummingbird 」で解説されています。 詳細は以下のプレスリリースを参照してください。 www.redhat.com Fedora Hummingbird Linux Fedora Hummingbird Linux と Red Hat Hardened Images Red Hat Hardened Imagesと同じファクトリーから生まれた新しいビルダー向けLinuxディストリビューションとして、 Fedora Hummingbird Linux が紹介されました。AIエージェントと、それを構築するビルダーの双方を対象としたローリングリリースOSです。 Red Hat Hardened Imagesと同じ自動化されたインフラストラクチャー上に構築されているため、提供される言語、ランタイム、データベース、ツールは既知のCVEがない状態で配信されます。従来のRPMベースのディストリビューションとは異なり、bootcによるイメージベースのローリングリリースモデルを採用しており、6ヶ月ごとのリリースサイクルを待たずにアップストリームの最新コンポーネントにアクセスできます。登録やメールアドレスも不要で、AIエージェントが実験フェーズでOSを素早く立ち上げることも可能です。 Fedora Hummingbird Linuxの詳細については、以下のプレスリリースを参照してください。 www.redhat.com Red Hat Desktop Red Hat Desktop 「AIシステムを構築する開発者の辞書に『待つ』や『遅い』はない。開発者にとってはワクワクすることだが、エンタープライズの管理者や監査担当者にとっては恐ろしいことだ」 この課題に応える形で、 Red Hat Desktop の一般提供(GA)が発表されました。 Red Hat build of Podman Desktop として、コンテナー化されたアプリケーションのビルドを支援します。Red Hat Desktopのベースとなるアップストリームのオープンソースプロジェクト、Podman Desktopはすでに400万回以上ダウンロードされています。 Red Hat Hardened ImagesやRed Hat Trusted Librariesに直接接続し、エンタープライズのソフトウェアサプライチェーン標準に常に準拠するイメージやライブラリーを開発者が利用可能 「デスクトップで準拠、プロダクションでも準拠」— スピードを犠牲にせずにコンプライアンスを実現 AIエージェント開発向けに、エージェントを開発・本番環境から分離するローカルサンドボックスを追加 なお、Podman Desktopチームは、AIコーディングエージェントをコンテナーやmicroVMで隔離して実行するオープンソースプラットフォーム Kaiden も開発しています。 詳細は以下のブログ記事および 製品ページ を参照してください。 www.redhat.com キーノートではRed Hat build of Podman Desktopに初期バンドルされている拡張機能、Hummingbird CatalogのUIも披露されました。開発者はこのカタログからコンテナーイメージやパッケージをブラウズ・検索できます。 OpenShell Red Hat × NVIDIA と OpenShell RHEL紹介パートの最後には、Red Hat × NVIDIAのロゴとともに OpenShell が紹介されました。 キーノートでは「Red HatはNVIDIAと協業し、OpenShellのようなオープンソースプロジェクトを取り入れて、開発者のラップトップからプロダクションまでのサンドボックスを提供する」と述べられました。 OpenShell は、NVIDIAが創設した自律型AIエージェント向けのサンドボックスランタイムを提供するオープンソースプロジェクトです。Red HatはOpenShellプロジェクトへの主要なコントリビューターとして参加しています。 詳細は以下のブログ記事を参照してください。 www.redhat.com 日産自動車とRed Hatの協業 — ソフトウェア定義車両の未来 日産自動車のAI-defined vehicleビジョン キーノートの後半では、日産自動車のSDV Software Platform Development部門のGeneral Managerである杉本和馬氏が登壇し、Red Hatとの協業が発表されました。 杉本氏は、車両ソフトウェアを 安全性が重要な領域 と 高頻度更新領域 に分離し、高頻度更新領域にLinuxを採用したことを説明しました。車両のライフサイクル全体にわたるLinuxの安定性を確保するため、Red Hatとの協業を進めているとのことです。 日産自動車のScalable Open Software Platform上に、ハードウェアの抽象化と明確なインターフェース設計、モジュール性と独立したデプロイ可能性という2つのコンセプトを適用し、ハードウェアの世代交代がソフトウェアスタック全体に波及することを防ぐアーキテクチャーが紹介されました。 さらに杉本氏は「AI-defined vehicle(AI定義車両)」というビジョンを示し、AI DriveとAI Partnerをコアプロダクトとして、SDVプラットフォームがその実現の鍵となることを述べました。 詳細は以下のプレスリリースを参照してください。 www.redhat.com まとめ Red Hat Summit 2026 Day 2キーノートのRHELセクションでは、幅広いアップデートが発表されました。RHEL Long-Life Add-Onによるライフサイクルのさらなる拡張、RHEL for NVIDIAによるAIハードウェアへの迅速な対応、Red Hat Hardened ImagesとFedora Hummingbird Linuxによるゼロ CVEを目指すコンテナーイメージとOS環境の提供が紹介されました。さらに、Red Hat Desktop(Red Hat build of Podman Desktop)による開発者のデスクトップからプロダクションまでの一貫したコンプライアンス、OpenShellによるAIエージェントのサンドボックスについても発表がありました。キーノートの後半では日産自動車が登壇し、Red Hat In-Vehicle Operating Systemを活用したソフトウェア定義車両プラットフォームの協業も紹介されました。 最後に、キーノートのデモパートでは、普段利用しているLLMからRed Hatのサブスクリプションやプロダクトをより効率的に活用できるようにするRed Hat Skillsについても紹介がありました。Red Hat Skillsの導入方法や使い方については以下の記事で紹介していますので、ぜひ合わせてご覧ください。 rheb.hatenablog.com なお、各製品の詳細については担当のRed Hatの営業までお問い合わせください。 リンク Red Hat Summit 2026 Red Hat Summit 2026 Day 2キーノート(YouTube) Red Hat Summit 2026 セッションカタログ What's new at Red Hat Summit 2026 Red Hat Enterprise Linux Red Hat Enterprise Linux Long-Life Add-On(プレスリリース、英語) Red Hat Enterprise Linux Extended Life Cycle, Premium(プレスリリース、日本語) Red Hat Enterprise Linux for NVIDIA Red Hat Hardened Images Red Hat Desktop Red Hat AI Factory with NVIDIA Expands Support for a New Class of Autonomous Agents in the Enterprise Nissan and Red Hat Co-Engineer the Future of Software-Defined Vehicles Red Hat Enterprise Linux powers AI innovation
はじめに レッドハットのソリューションアーキテクトの森です。 本記事は、Red Hat Connectivity Link入門シリーズの第5回です。 第1回 でRed Hat Connectivity Linkをインストールした環境があれば、本記事の内容を実践できます。 過去の記事はこちらから rheb.hatenablog.com Connectivity LinkとAI Gateway Red Hat Connectivity Linkは、従来のAPI Gatewayの機能に加えて、 AI Gateway としての側面も持ちます。LLM(Large Language Model)APIの普及に伴い、AI特有の要件に対応したGateway機能が求められるようになりました。 Connectivity LinkのAI Gateway機能 Connectivity LinkがAI Gatewayとして提供する主な機能: LLMモデル別の利用状況/性能/トラフィック可視化 : どのモデルがどれだけ使われているかを可視化 トークンベースのレート制限 : 従来のリクエスト数ではなく、トークン消費量に基づく制限 認証/認可 : ユーザーやティアごとのアクセス制御 コスト制御 : トークン単価に基づくコスト追跡と予算管理 これらの機能により、Platform Engineersは複数のAIモデルへのアクセスを統一的に管理し、セキュアかつコスト効率的なLLM APIサービスを提供できます。 MCP Gateway(Tech Preview): Connectivity Link 1.3.3では、さらに MCP Gateway (Model Context Protocol Gateway)がTech Previewとして追加されました。 MCP Gatewayは、AIエージェントがツールやデータソースにアクセスするための標準プロトコルであるModel Context Protocolをサポートし、AIアプリケーションの統合をさらに強化します。 MCP Gatewayの詳細については、次の第6回で詳しく解説する予定です。 本記事の焦点 第5回となる今回は、AI Gateway機能の中でも特に重要な トークンベースのレート制限 について解説します。 従来のリクエスト数ベースのレート制限では、LLM APIのコスト管理や公平な利用制限が困難でした。 Kuadrant 1.3で提供される TokenRateLimitPolicy を使用することで、実際のトークン消費量に基づいた精密なレート制限が可能になります。 本記事では、最小構成でトークンベースのレート制限を体験できるよう、モックLLM APIサービスとシンプルなHTTP Gatewayを使用します。 本記事で扱う内容 なぜトークンベースのレート制限が必要か : リクエストベースの課題 モックLLM APIサービスのデプロイ : OpenAI互換のテストAPI Gateway作成 : シンプルなHTTP Gateway TokenRateLimitPolicyの基本 : トークン自動抽出と制限設定 動作確認 : Port-forward経由でのレート制限テスト 前提条件 本記事では、以下が完了していることを前提とします: Red Hat Connectivity Link 1.3がインストール済み ( 第1回 を参照) oc CLI がインストール済みで、クラスターにログイン済み なぜトークンベースのレート制限が必要か LLM APIの特性 LLM APIは、従来のREST APIと異なる特性を持ちます: 従来のREST API: リクエストの処理コストがほぼ一定 レスポンスサイズも比較的均一 リクエスト数ベースの制限で公平性を確保可能 LLM API: リクエストごとの処理コストが大きく異なる 入力トークン数(プロンプトの長さ)による変動 出力トークン数(生成されるテキストの長さ)による変動 リクエスト数だけでは公平性とコスト管理が困難 具体例: 不公平なリクエストベース制限 シナリオ : 1分あたり10リクエストの制限 ユーザーA: リクエスト1: 入力10,000トークン、出力4,000トークン → 14,000トークン リクエスト2: 入力10,000トークン、出力4,000トークン → 14,000トークン ... 合計10リクエスト = 140,000トークン(非常に高コスト) ユーザーB: リクエスト1: 入力50トークン、出力150トークン → 200トークン リクエスト2: 入力50トークン、出力150トークン → 200トークン ... 合計10リクエスト = 2,000トークン(低コスト) 同じリクエスト数でも、実際のコストは 70倍 の差があります。 TokenRateLimitPolicyの利点 特徴 リクエストベース トークンベース 公平性 リクエスト数のみで制限 実際の使用量で制限 コスト管理 困難(リクエストサイズ不定) 精密(トークン単位) 悪用防止 大きなリクエストで悪用可能 トークン制限で防止 ビジネスモデル 単純なティア分け トークン単価ベースの課金 ユーザー体験 小リクエストが不利 使用量に応じた公平な制限 LLM APIレスポンスの構造 LLM API(OpenAI互換API)は、以下のようなレスポンスを返します: { " id ": " chatcmpl-abc123 ", " object ": " chat.completion ", " created ": 1715580000 , " model ": " gpt-4 ", " choices ": [ { " index ": 0 , " message ": { " role ": " assistant ", " content ": " I'm doing well, thank you! " } , " finish_reason ": " stop " } ] , " usage ": { " prompt_tokens ": 12 , " completion_tokens ": 28 , " total_tokens ": 40 } } 重要 : usage フィールドに注目してください。これがRateLimitPolicyで使用するトークン数です。 モックLLM APIバックエンドの準備 本記事では、実際のGPUやモデルがない環境でもテストできるよう、OpenAI互換のモックLLM APIサービスを使用します。 注 : 実際の運用環境では、OpenShift AIのvLLMやその他のLLMサービングプラットフォームを使用してください。OpenShift AIの詳細は 公式ドキュメント を参照してください。 モックLLM APIサービスのデプロイ 実際のGPUやモデルがない環境でもテストできるよう、モックサービスを使用します: # MockLLM API用のnamespace作成 oc create namespace llm-api # MockLLM APIの作成 oc apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: mock-llm-api namespace: llm-api data: app.py: | from flask import Flask, request, jsonify import random import time app = Flask(__name__) @app.route('/v1/chat/completions', methods=['POST']) def chat_completions(): data = request.get_json(silent=True) or {} messages = data.get('messages', []) max_tokens = data.get('max_tokens', 100) # プロンプトトークン数を推定(簡易的に文字数/4) prompt_text = ' '.join([m.get('content', '') for m in messages]) prompt_tokens = len(prompt_text) // 4 # 出力トークン数(max_tokensの70-90%をランダムに使用) completion_tokens = int(max_tokens * random.uniform(0.7, 0.9)) response = { "id": f"chatcmpl-{random.randint(1000000, 9999999)}", "object": "chat.completion", "created": int(time.time()), "model": data.get('model', 'mock-llm'), "choices": [{ "index": 0, "message": { "role": "assistant", "content": "This is a mock response from the LLM API." }, "finish_reason": "stop" }], "usage": { "prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "total_tokens": prompt_tokens + completion_tokens } } return jsonify(response) if __name__ == '__main__': app.run(host='0.0.0.0', port=8080) --- apiVersion: apps/v1 kind: Deployment metadata: name: mock-llm-api namespace: llm-api spec: replicas: 1 selector: matchLabels: app: mock-llm-api template: metadata: labels: app: mock-llm-api spec: containers: - name: api image: python:3.11-slim command: - /bin/sh - -c - | pip install --target=/packages flask && \ PYTHONPATH=/packages python /app/app.py ports: - containerPort: 8080 volumeMounts: - name: app mountPath: /app - name: packages mountPath: /packages volumes: - name: app configMap: name: mock-llm-api - name: packages emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: mock-llm-api namespace: llm-api spec: selector: app: mock-llm-api ports: - port: 8080 targetPort: 8080 EOF 注 : 実際の環境では、OpenShift AIのvLLMやその他のLLMサービングプラットフォームを使用してください。 Gateway作成 モックLLM APIサービスを公開するためのシンプルなHTTP Gatewayを作成します。 # Gateway用のnamespace作成 oc create namespace llm-gateway # Gateway作成 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: llm-gateway namespace: llm-gateway spec: gatewayClassName: istio listeners: - name: http hostname: "*.llm-api.local" port: 80 protocol: HTTP allowedRoutes: namespaces: from: All EOF HTTPRouteでの公開 モックLLM APIをGateway経由で公開します: oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: llm-api namespace: llm-api labels: service: mock-llm-api deployment: mock-llm-api spec: parentRefs: - name: llm-gateway namespace: llm-gateway hostnames: - "api.llm-api.local" rules: - matches: - method: POST path: type: PathPrefix value: "/v1/chat/completions" backendRefs: - name: mock-llm-api port: 8080 EOF TokenRateLimitPolicyの実装 Kuadrant 1.3では、トークンベースのレート制限には専用の TokenRateLimitPolicy CRDを使用します。 トークン抽出の仕組み TokenRateLimitPolicyは、レスポンスボディからトークン数を自動的に抽出します。OpenAI API互換のレスポンスの usage.total_tokens フィールドからトークン数を取得します: { " usage ": { " prompt_tokens ": 12 , " completion_tokens ": 28 , " total_tokens ": 40 } } TokenRateLimitPolicy作成 oc apply -f - <<EOF apiVersion: kuadrant.io/v1alpha1 kind: TokenRateLimitPolicy metadata: name: llm-api-token-limit namespace: llm-api spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: llm-api limits: token-limit: rates: - limit: 1000 window: 1m counters: - expression: "1" EOF 設定の詳細解説 APIバージョン: kuadrant.io/v1alpha1 - TokenRateLimitPolicy専用のAPIバージョン limits.token-limit: rates.limit : 1分あたり1,000トークン(テスト用の小さい値) rates.window : 1m - 1分間のウィンドウ counters: expression : "1" - すべてのリクエストを同じカウンターでカウント 注: 本番環境では、AuthPolicyと統合して auth.identity.userid を使用します( 第3回記事 参照) トークン数の抽出: TokenRateLimitPolicyは、レスポンスボディの usage.total_tokens を自動的に抽出 手動で costs フィールドを設定する必要はありません 設定後の状態(Policy Topology View) 今回は、簡略化のため DNS Policy 、 TLS Policy による外部公開は行なっておりません。こちらの詳細については、 第2回記事 を参照ください。 動作確認 Port-forward経由でトークンベースのレート制限をテストします。 1. Port-forwardの開始 別のターミナルで以下を実行: oc port-forward -n llm-gateway service/llm-gateway-istio 8080:80 2. 正常リクエストのテスト curl -X POST http://localhost:8080/v1/chat/completions \ -H "Host: api.llm-api.local" \ -H "Content-Type: application/json" \ -d '{ "model": "mock-llm", "messages": [ {"role": "user", "content": "What is OpenShift?"} ], "max_tokens": 200 }' | jq . 期待されるレスポンス: { " choices ": [ { " finish_reason ": " stop ", " index ": 0 , " message ": { " content ": " This is a mock response from the LLM API. ", " role ": " assistant " } } ] , " created ": 1778639456 , " id ": " chatcmpl-3377409 ", " model ": " mock-llm ", " object ": " chat.completion ", " usage ": { " completion_tokens ": 142 , " prompt_tokens ": 4 , " total_tokens ": 146 } } 注 : モックAPIは max_tokens の70~90%をランダムに使用するため、 completion_tokens と total_tokens は実行ごとに変わります。この例では約146トークンが消費されました。 3. レート制限の確認 トークン制限(1分あたり1,000トークン)を超えるまでリクエストを繰り返します: # 連続してリクエストを送信(max_tokens=200で大きめのトークン消費) for i in {1..10}; do echo "=== Request $i ===" response=$(curl -s -X POST http://localhost:8080/v1/chat/completions \ -H "Host: api.llm-api.local" \ -H "Content-Type: application/json" \ -d '{ "model": "mock-llm", "messages": [{"role": "user", "content": "What is OpenShift?"}], "max_tokens": 200 }') echo "$response" | jq -r '.usage.total_tokens' 2>/dev/null || echo "$response" sleep 1 done 実行例: === Request 1 === 152 === Request 2 === 172 === Request 3 === 151 === Request 4 === 158 === Request 5 === 160 === Request 6 === 145 === Request 7 === 168 === Request 8 === Too Many Requests === Request 9 === Too Many Requests === Request 10 === Too Many Requests 累計トークン消費の例: 1~7回目: 152 + 172 + 151 + 158 + 160 + 145 + 168 = 1,106トークン 7回目のリクエストで累計1,106トークンとなり、1,000トークンの制限を超過 8回目以降: Too Many Requests が返される 注 : モックAPIはランダムなトークン数を返すため、実行ごとに各リクエストのトークン数は変わります 制限に達するまでのリクエスト回数も、6~8回程度で変動します トークン消費の確認 TokenRateLimitPolicyが正しくトークン数をカウントしているか確認します。 OpenShift Web Consoleでのメトリクス確認 Limitador(レート制限エンジン)は、トークン消費状況をPrometheusメトリクスとして公開します。OpenShift Web Consoleから確認できます。 手順: OpenShift Web Consoleにログイン 左メニューから Observe > Metrics を選択 クエリ入力欄に以下を入力: authorized_hits{limitador_namespace="llm-api/llm-api"} Run queries をクリック グラフの見方: グラフは、時系列で累計トークン消費量を表示します。リクエストを送信するごとに、 authorized_hits の値が増加していくことが確認できます。 メトリクスの意味: authorized_hits : 許可されたリクエストの累計トークン数 レート制限内で処理されたリクエストのトークン数の合計 この値が1分間で1,000トークンを超えると、次のリクエストは拒否されます まとめ 本記事では、TokenRateLimitPolicyを使用したLLM API向けのトークンベースレート制限の基本を解説しました。 本記事で学んだこと トークンベースレート制限の必要性 : リクエストベースとトークンベースの違い モックLLM APIのデプロイ : OpenAI互換API( usage.total_tokens を含む) Gateway作成 : シンプルなHTTP Gateway TokenRateLimitPolicy : トークン数の自動抽出とカウント レート制限の動作 : 累計トークン消費による制限発動 動作確認 : Port-forward経由でのテスト トークンベースレート制限の利点 項目 利点 公平性 実際の使用量に基づく制限 コスト管理 トークン単位でのコスト追跡 悪用防止 大きなリクエストでの制限回避を防止 柔軟性 ビジネスモデルに応じた制限設定
RHELのスペシャリストソリューションアーキテクトの田中司恩( @tnk4on )です。 Red Hat から「 Red Hat Agentic Skills 」が公開されました。これは、Claude Code や Cursor といった AI コーディングアシスタントに Red Hat 製品の運用スキルを追加する仕組みです。スキルをインストールすると、AI エージェントがスラッシュコマンド経由で Red Hat の API やデータソースにアクセスし、CVE の調査や診断データの収集などを実行できるようになります。この記事では、Agentic Skills の概要と、基本スキルを使った CVE 調査のデモを紹介します。 AI エージェントに「スキル」が必要な理由 Red Hat の Matt Hicks は、Red Hat の公式ブログ " AI's next inflection point: transforming agents into enterprise superusers " の中で、AI エージェントにおけるスキルの重要性を次のように述べています。 A model without specific skills is like a high-performance vehicle without a steering wheel. (特定のスキルを持たないモデルは、ハンドルのない高性能車のようなものだ) スキルとは「AI エージェントが特定のエコシステム内でタスクを実行するための専門知識」であり、モデルを単なるチャットボットからエンタープライズの「スーパーユーザー」へと変える鍵だと Matt Hicks は述べています。パッチの適用、ログのスキャン、コードのトラブルシューティングといった実務を自律的に行えるエージェントを実現するために、Red Hat は3つの柱を掲げています。 MCP サーバー — モデルが実際に「何かを実行する」ためにはツールが必要であり、Model Context Protocol を通じて Red Hat のナレッジベースや API に接続する スキルリポジトリー — Red Hat エコシステムの理解を起点に、モダナイゼーションの段階に応じたスキルを推奨するカタログ オープンな仕組み — オープンソースの原則に基づき、ユーザーが基盤とスキルの両方を制御・貢献できるエコシステム Agentic skill pack for Red Hat customers この3つの柱を具体的な形にしたのが Red Hat Agentic Skills です。このページは AI エージェント向けのインストーラーを兼ねており、ページに記載されたプロンプトを AI コーディングアシスタントに貼り付けるだけで、スキルが自動的にセットアップされます *1 。対応プラットフォームは Claude Code、Cursor、OpenShift Dev Spaces です。 ここからインストールされる「Agentic skill pack for Red Hat customers」には、以下の5つの基本スキルが含まれています。 スキル スラッシュコマンド 説明 CVE Explainer /red-hat-cve-explainer Red Hat の重大度評価システムを使用して CVE を検索し、影響を分かりやすく説明する Diagnostic Data Gathering /red-hat-diagnostics sosreport、OpenShift must-gather、Ansible 診断バンドルの収集手順をステップバイステップで案内する Product Lifecycle Advisor /red-hat-product-lifecycle Red Hat 製品・バージョンのライフサイクルステータスとサポートフェーズの詳細を確認する Support Severity Helper /red-hat-support-severity サポートケースの適切な重大度レベル(Sev 1〜4)を判定し、SLA の応答時間を説明する Security MCP Setup /red-hat-security-mcp-setup Red Hat Security MCP サーバーの初期設定を支援するワンタイムヘルパー これらのスキルは Red Hat の CVE Database、Security Advisories API、Product Lifecycle API、Customer Portal といったデータソースにアクセスします。MCP サーバーが設定されていない環境でも、公開されている Red Hat のドキュメントにフォールバックして動作します。 Red Hat Agentic Skills のエコシステム Red Hat Agentic Skills では、ペルソナや製品領域ごとにスキルをまとめた「スキルパック」という単位でスキルが提供されます。今回紹介した「for Red Hat customers」はその一つで、 Red Hat Ecosystem Catalog - AI には SRE 向け、OpenShift 向け、OpenShift Virtualization 向けのスキルパックに加え、個別スキルや MCP サーバーも掲載されています。 スキルのソースコードは GitHub リポジトリー RHEcosystemAppEng/agentic-collections で Apache-2.0 ライセンスのもと公開されています。このリポジトリーは Lola というユニバーサルパッケージマネージャーに対応しており、複数のスキルパックを Claude Code や Cursor などの AI コーディングアシスタントへ一括でインストールできます。 セットアップと実践 ここからは、実際に Agentic Skills をインストールし、CVE Explainer スキルを使って CVE-2026-31431(Copy Fail)を調査するデモを紹介します。 スキルのインストール Red Hat Agentic Skills のページに掲載されている手順に従い、AI コーディングアシスタントにスキルをインストールします。ここでは Claude Code を使用します。 Red Hat Agentic Skills のページに記載されているプロンプトをコピーし、Claude Code に貼り付ける Claude Code がプロンプトの指示に従い、ブートストラップスキルファイルをダウンロードしてプロジェクトのスキルディレクトリーに配置する /red-hat-get-started コマンドを実行すると、5つのスキルが GitHub リポジトリーから順番にダウンロードされる 全スキルのインストールが完了すると、ブートストラップインストーラーが自動で削除される Claude Code が `/red-hat-get-started` を認識し、5つのスキルのダウンロードを開始する様子 全5スキルのインストールが完了し、利用可能なコマンド一覧が表示される CVE Explainer で CVE-2026-31431 を調査する インストールが完了すると、 /red-hat-cve-explainer スラッシュコマンドが使えるようになります。Linux カーネルの暗号サブシステムに見つかった特権昇格の脆弱性 CVE-2026-31431(Copy Fail) を題材に、スキルの動作を見てみましょう。 /red-hat-cve-explainer を実行すると、CVE ID の入力を求められます。 CVE-2026-31431 を入力すると、スキルが Red Hat の Security Data API にアクセスして脆弱性情報を取得します。 /red-hat-cve-explainer を実行し、CVE-2026-31431 の調査を開始する様子。Red Hat Security MCP が未設定の場合は自動的に WebFetch にフォールバックする 調査結果には、Red Hat 独自の重大度評価(Important / CVSS v3: 7.8)、脆弱性の概要、影響を受ける製品ごとの状態(Fixed / Not affected)と対応するエラータ番号、パッケージバージョン、そして推奨される対応アクションが含まれます。 CVE-2026-31431 の調査結果。RHEL 10/9/8 および OpenShift 4.21 に修正済みエラータが提供されていることが分かる このように、ターミナル上の会話だけで脆弱性の概要把握からパッチ情報の確認までが完結します。以前の記事「 Red Hat Satellite で CVE-2026-31431(Copy Fail)のパッチを適用する 」で紹介したような実際のパッチ適用作業と組み合わせると、調査から修復までの一連の流れをエージェントと一緒に進められます。 今回は CVE Explainer をデモしましたが、他にも製品のライフサイクル確認( /red-hat-product-lifecycle )、診断データの収集手順案内( /red-hat-diagnostics )、サポートケースの重大度判定( /red-hat-support-severity )といったスキルが利用できます。スキルパックの詳細は Agentic skill pack for Red Hat customers を参照してください。 まとめ Red Hat Agentic Skills は、AI コーディングアシスタントに Red Hat 製品の専門知識を持たせるためのスキルパックです。CVE の調査、診断データの収集、製品ライフサイクルの確認など、日常の運用業務をエージェントと一緒に行えるようになります。 私は普段から Claude Code を使って RHEL 関連の業務を行っていますが、Red Hat 公式のスキルが追加されることで、エージェントがより正確な情報に基づいた提案をしてくれるようになると期待しています。実際に CVE Explainer で CVE-2026-31431 を調査してみると、Red Hat の公式データに基づいた正確な脆弱性情報がすぐに得られ、対応の初動が格段に速くなると感じました。 スキルの導入は簡単で、 Red Hat Agentic Skills のページから数ステップでセットアップできます。ぜひお手元の AI コーディングアシスタントで試してみてください。 リンク Red Hat Agentic Skills AI's next inflection point: transforming agents into enterprise superusers - Red Hat Blog Agentic skill pack for Red Hat customers - Red Hat Ecosystem Catalog Red Hat Ecosystem Catalog - AI RHEcosystemAppEng/agentic-collections - GitHub Lola - Universal Package Manager for AI Agent Skills lobsterTrap/lola - GitHub *1 : Lola パッケージマネージャーを使ったインストールにも対応しています。
はじめに レッドハットのソリューションアーキテクトの森です。 第3回記事 では、JWT(JSON Web Token)ベースの認証 と ロールベースアクセス制御(RBAC)について紹介しました。 第4回の本記事では、Red Hat Connectivity Link(Kuadrant)のObservability機能に焦点を当て、 メトリクス監視 の実装方法を解説します。 これまでの記事で構築してきたGateway API環境(Gateway、HTTPRoute、各種Policy)が実際にどのように動作しているのか、トラフィックの状況やポリシーの適用状態を可視化することで、プラットフォームの運用管理が大きく改善されます。 過去の記事はこちらから rheb.hatenablog.com 本記事で扱う内容 メトリクス収集の仕組み : OpenShift User Workload MonitoringとKuadrantの統合 3つのサンプルダッシュボード : Platform Engineer、App Developer、Business User向けの監視ビュー 実装手順 : OpenShift環境でのGrafanaベース監視スタックの構築 メトリクス収集の仕組み Red Hat Connectivity Link の observability は、 OpenShift User Workload Monitoring(Prometheus ベース監視基盤)と Kuadrant が提供するメトリクスを統合して実現されています。 Connectivity Link / Kuadrant / Envoy / Gateway API 関連コンポーネントは、 ServiceMonitor / PodMonitor を通じて Prometheus により収集されます。 収集したメトリクスは、必要に応じて Thanos Querier を介して集約され、 Grafana などの可視化ツールから PromQL クエリで参照できます。 アーキテクチャ概要 コンポーネントの役割 1. User Workload Monitoring (UWM) OpenShift 4.x に組み込まれている監視機能で、ユーザーアプリケーションのメトリクス収集を担当します。 主な特徴: Prometheusベースのメトリクス収集 ServiceMonitor/PodMonitor CRDによる動的な監視対象管理 Thanos統合による長期保存とクエリ統合 cluster-admin権限なしでの利用が可能 2. kube-state-metrics-kuadrant Kuadrantが提供するカスタムメトリクスエクスポーターで、Gateway APIリソースの状態情報を収集します。 収集するメトリクス: メトリクス名 説明 主要ラベル gatewayapi_httproute_labels HTTPRouteのラベル情報 name , exported_namespace , service , deployment gatewayapi_httproute_status_parent_info 親Gatewayとの関連情報 parent_name , parent_namespace , parent_kind gatewayapi_httproute_created HTTPRoute作成時刻 name , exported_namespace gatewayapi_gateway_info Gateway基本情報 name , exported_namespace gatewayapi_gateway_status Gateway状態(Ready/Programmed) name , condition_type , condition_status gatewayapi_gatewayclass_info GatewayClass情報 name , controller_name 重要な役割: このメトリクスは、Istioのトラフィックメトリクス( istio_requests_total 等)とGateway APIリソースを 紐付ける ために使用されます。 例えば、以下のようなクエリで特定のHTTPRouteのトラフィックを抽出できます: sum(rate(istio_requests_total{}[5m])) by (destination_service_name) * on(destination_service_name) group_left(name) ( label_replace( gatewayapi_httproute_labels{name="news-api"}, "destination_service_name", "$1", "service", "(.+)" ) ) 3. Istio メトリクス IstioのEnvoyプロキシが生成するトラフィックメトリクスです。 主要メトリクス: メトリクス名 タイプ 説明 istio_requests_total Counter リクエスト総数 istio_request_duration_milliseconds Histogram リクエストレイテンシ istio_request_bytes Histogram リクエストサイズ istio_response_bytes Histogram レスポンスサイズ デフォルトラベル: destination_service_name : 宛先サービス名 response_code : HTTPステータスコード request_protocol : プロトコル(http, grpc) source_workload : 送信元ワークロード reporter : メトリクスレポーター(source/destination) 拡張ラベル(Telemetry設定で追加): Kuadrantのダッシュボードでは、以下の追加ラベルが必要です: request_url_path : リクエストパス(例: /technology , /sports ) request_host : リクエストホスト(例: api.example.com ) destination_port : 宛先ポート(例: 443 ) これらはIstio Telemetry CRDで設定します(後述)。 4. Kuadrant コンポーネントメトリクス Kuadrantの各コンポーネントも独自のメトリクスを公開しています: Authorino(認証/認可): authorino_server_evaluator_* : 認証評価メトリクス authorino_server_authconfig_* : AuthConfig状態 Limitador(レート制限): limitador_counter_* : カウンター値 limitador_limit_* : リミット設定 DNS Operator: dns_provider_health_* : DNSプロバイダーヘルス これらのメトリクスはServiceMonitorによって自動的に収集されます。 メトリクスフロー 収集 : Prometheusが定期的(30秒間隔)にServiceMonitor/PodMonitorで定義されたエンドポイントからメトリクスをスクレイプ 保存 : User Workload Monitoring Prometheusに24時間保存 統合 : Thanos Querierが複数のPrometheusインスタンスからメトリクスを統合クエリ 可視化 : GrafanaがThanos Querierに対してPromQLクエリを発行し、ダッシュボードに表示 3つのサンプルダッシュボード Kuadrantプロジェクトは、異なる役割のユーザー向けに3つのGrafanaダッシュボードのサンプルを提供しています。 App Developer Dashboard 対象ユーザー : アプリケーション開発者、サービスオーナー 目的 : 自分のHTTPRoute(API)のトラフィック、パフォーマンス、エラー状況の監視 主要パネル 1. Request breakdown by code (rate) (左側) HTTPステータスコード別のリクエストレート(req/sec) 成功系(2xx)、リダイレクト(3xx)、クライアントエラー(4xx)、サーバーエラー(5xx)を色分け表示 画像では時系列でステータスコード別のトラフィック推移が確認できます。APIのトラフィックパターンと正常系/異常系の比率を把握できます。 2. Request latency percentiles (右側) p95レイテンシ(95パーセンタイル) p90レイテンシ p99レイテンシ 画像では複数のパーセンタイルが重ねて表示されており、レスポンス時間の分布を把握できます。ユーザー体験に直結するレスポンス時間を監視します。 ユースケース例 シナリオ : APIのレスポンスが遅いという報告を受けた App Developer Dashboardで確認: Request latency percentiles (右側): p95レイテンシの推移を確認(通常時と比較) Request breakdown by code (左側): ステータスコード分布から異常なエラー増加がないか確認 これにより、パフォーマンス問題の原因(トラフィック増、特定エンドポイントの問題、エラー率上昇等)を特定できます。 Business User Dashboard 対象ユーザー : プロダクトマネージャー、ビジネスアナリスト、エグゼクティブ 目的 : ビジネスメトリクスとトレンド分析 主要パネル 1. Traffic Summary (左上) 時間帯別のリクエスト数 サービス別のトラフィック分布 ビジネス活動のパターンを把握できます。画像では時系列でトラフィックの推移が表示されています。 2. Historical Request Comparison (右上) 直近期間(most recent)と前期間(previous)のリクエスト数比較(棒グラフ) トレンドの変化を視覚的に把握できます。画像では青い棒グラフで比較が表示されています。 3. Breakdown by Path (左下) パス別のリクエストレート(req/sec) パスごとの時系列グラフ APIの各エンドポイントの利用状況を比較できます。画像では複数のパス(色分け)の推移が確認できます。 4. Total Requests for Selected Range (右下) 選択期間のトータルリクエスト数(パス別) 前期間との比較 増減率(Increase/Decrease列) どのエンドポイントが成長/縮小しているかを一目で把握できます。 ユースケース例 シナリオ : 新機能リリース後の影響を評価したい Business User Dashboardで確認: Total Requests for Selected Range : リリース前後でトラフィックがどう変化したか(画像右下のテーブルで確認) Breakdown by Path : 新しいエンドポイントへのアクセスが増えているか(画像左下のグラフで確認) Historical Request Comparison : 前週/前月との比較(画像右上の棒グラフで確認) これにより、新機能の採用状況とサービス品質への影響を評価できます。 Platform Engineer Dashboard 対象ユーザー : プラットフォームエンジニア、SRE、クラスター管理者 目的 : Gateway APIインフラストラクチャ全体の健全性とポリシー適用状態の監視 主要パネル - Gatewaysセクション 上図では、Gatewaysセクションが表示されています: 1. Gateway Overview Total : Gateway総数 Healthy : 正常なGateway数 Unhealthy : 異常なGateway数 2. Gateways テーブル Gateway Class: 使用しているGatewayClass Name: Gateway名 Namespace: デプロイ先namespace Programmed: プログラミング状態 Accepted: 受理状態 3. Gateway Listeners Gateway: Gateway名 Gateway NS: Gatewayのnamespace Hostname: リスナーのホスト名 Listener: リスナー名 Port: ポート番号 Protocol: プロトコル 4. Gateway Policies Kind: Policyの種類(TLSPolicy, RateLimitPolicy, AuthPolicy, DNSPolicy) Name: Policy名 Namespace: デプロイ先namespace Target Kind: 適用対象のリソース種別(Gateway) Target Name: 適用対象のリソース名 このパネルで、クラスター内のGateway APIリソースの全体像とポリシー適用状態を一覧できます。 主要パネル - HTTPRoutesセクション 上図では、HTTPRoutesセクションが表示されています: 1. Total requests (graphs) HTTPRoute別のリクエスト数推移(時系列グラフ) 2. Total Gateways (requests) Gateway別のリクエスト数一覧 3. Request latency HTTPRoute別のレイテンシ推移 このセクションで、各HTTPRouteのトラフィック状況とパフォーマンスを監視できます。 主要パネル - Alertsセクション 上図では、Alertsセクションが表示されています: 1. Alert Summary Total Firing : 発火中のアラート数(画像では2) Total Pending : 保留中のアラート数(画像では0) 2. Currently Active テーブル 現在検出中の Alert AlertmanagerReceiversNotConfigured : Alertmanagerの通知先未設定(テスト環境では無視可能) Watchdog : 監視システムが正常動作している証明(常時発火が正常) 3. Active State Timeline 時系列でアラートの発火状態を表示: 赤色: Firing(発火中) オレンジ色: Pending(保留中) 緑色: Inactive(非アクティブ) 画像では複数のアラート(AlertmanagerReceiversNotConfigured, Watchdog, KubeContainerWaiting等)の状態推移が確認できます。 ユースケース例 シナリオ : 新しいHTTPRouteをデプロイ後、トラフィックが流れない Platform Engineer Dashboardで確認: Gateways テーブル : GatewayのProgrammedとAcceptedが True か確認(画像1枚目) Gateway Policies : 関連するAuthPolicyやRateLimitPolicyが表示されているか確認(画像1枚目) HTTPRoutes セクション : デプロイしたHTTPRouteがリクエストを受けているか確認(画像2枚目) Alerts : 関連するアラートが発火していないか確認(画像3枚目) これにより、問題の切り分けが迅速に行えます。 OpenShift環境への導入手順 ここからは、実際にOpenShift環境でGrafanaベースの監視スタックを構築する手順を解説します。 前提条件 以下が完了していることを前提とします: Red Hat Connectivity Link 1.3 がインストール済み( 第1回記事 参照) OpenShift CLI ( oc ) がインストール済みで、クラスターにログイン済み cluster-admin権限 または以下の権限: User Workload Monitoringの有効化( openshift-monitoring namespaceの編集) Operatorのインストール( openshift-operators namespaceへのSubscription作成) 各namespaceでのリソース作成権限 (推奨) 第2回記事 で作成した環境 - Gateway、HTTPRoute、News APIがデプロイ済み Step 1: Kuadrant Observability の有効化 Connectivity Link / Kuadrant のメトリクス収集を開始するには、Kuadrant CRで observability を有効化する必要があります。 1.1 有効化の設定 以下のように spec.observability.enable: true を追加します: apiVersion : kuadrant.io/v1beta1 kind : Kuadrant metadata : name : kuadrant namespace : kuadrant-system spec : observability : enable : true #追加 # ... その他の設定 1.2 有効化の確認 設定が反映されたことを確認します: oc get kuadrant kuadrant -n kuadrant-system -o jsonpath='{.spec.observability.enable}' # 出力: true ServiceMonitorが作成されているか確認します: oc get servicemonitor -n kuadrant-system 以下のようなServiceMonitorが表示されれば成功です: NAME AGE authorino-operator-monitor 22s dns-operator-monitor 22s kuadrant-authorino-monitor 22s kuadrant-operator-monitor 22s limitador-operator-monitor 22s 重要 : この設定を有効化することで、Kuadrantの各コンポーネント(Authorino、Limitador、DNS Operator等)のメトリクスが収集可能になります。 Step 2: HTTPRouteラベルの確認と設定 メトリクス収集を正しく機能させるために、HTTPRouteに適切なラベルが設定されている必要があります。 kube-state-metrics-kuadrant は、HTTPRouteのラベル情報をメトリクスに含めることで、ダッシュボードでDeploymentやServiceと紐付けた表示を可能にします。 HTTPRouteには、以下のラベルが設定されている必要があります: deployment : バックエンドのDeployment名 service : バックエンドのService名 これらのラベルは、 gatewayapi_httproute_labels メトリクスに含まれ、ダッシュボードのクエリで使用されます。 ラベルが不足している場合、HTTPRouteを更新します: apiVersion : gateway.networking.k8s.io/v1 kind : HTTPRoute metadata : ... labels : app : news-api deployment : news-api # ラベル追加 service : news-api # ラベル追加 ... spec : ... 注意 : - deployment ラベルの値は、実際のDeployment名と一致させてください - service ラベルの値は、実際のService名と一致させてください - 複数のHTTPRouteがある場合、それぞれに適切なラベルを設定してください Step 3: User Workload Monitoring の有効化 OpenShiftのUser Workload Monitoring機能を有効化されていない場合は、設定を変更します。 3.1 ConfigMapの作成 User Workload Monitoringを有効化するConfigMapを作成します: cat <<EOF | oc apply -f - apiVersion: v1 kind: ConfigMap metadata: name: cluster-monitoring-config namespace: openshift-monitoring data: config.yaml: | enableUserWorkload: true EOF 3.2 有効化の確認 User Workload Monitoring用のPodが起動するまで待ちます(通常30秒〜1分): oc get pods -n openshift-user-workload-monitoring 以下のようなPodが表示されれば成功です: NAME READY STATUS RESTARTS AGE prometheus-operator-xxx 2/2 Running 0 1m prometheus-user-workload-0 6/6 Running 0 1m prometheus-user-workload-1 6/6 Running 0 1m thanos-ruler-user-workload-0 3/3 Running 0 1m thanos-ruler-user-workload-1 3/3 Running 0 1m 重要 : この設定はクラスター全体に影響するため、他のユーザーワークロードもメトリクス収集の対象になります。 Step 4: kube-state-metrics-kuadrant のデプロイ Gateway APIリソースのメトリクスを収集するkube-state-metrics-kuadrantをデプロイします。 4.1 Kuadrant Observability設定の確認 Kuadrantが提供するサンプルのObservability設定を確認します: https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/v1.3.0/config/install/configure/observability/kustomization.yaml https://github.com/Kuadrant/gateway-api-state-metrics/tree/0.7.0/config/kuadrant https://github.com/Kuadrant/kuadrant-operator/tree/v1.3.0/config/observability/openshift https://github.com/Kuadrant/kuadrant-operator/tree/v1.3.0/config/observability/prometheus/monitors この設定には以下が含まれます: kube-state-metrics-kuadrantのDeployment ServiceMonitor(Prometheus用のスクレイプ設定) ConfigMap(カスタムリソースの定義) RBAC(ClusterRole, ServiceAccount等) Grafana Operator インストール 4.2 Observability設定の適用 Kustomizeを使用して設定を適用します: oc apply -k 'https://github.com/Kuadrant/kuadrant-operator/config/install/configure/observability?ref=v1.3.0' 実行すると、以下のリソースが作成されます: namespace/monitoring created serviceaccount/kube-state-metrics-kuadrant created clusterrole.rbac.authorization.k8s.io/kube-state-metrics-kuadrant created clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics-kuadrant created configmap/custom-resource-state created service/kube-state-metrics-kuadrant created deployment.apps/kube-state-metrics-kuadrant created servicemonitor.monitoring.coreos.com/kube-state-metrics-kuadrant created servicemonitor.monitoring.coreos.com/authorino-operator-metrics created servicemonitor.monitoring.coreos.com/dns-operator-metrics-monitor created servicemonitor.monitoring.coreos.com/kuadrant-operator-metrics created servicemonitor.monitoring.coreos.com/limitador-operator-metrics created subscription.operators.coreos.com/grafana-operator created 重要 : このKustomizeには以下も含まれています: Grafana Operator : コミュニティ版Grafana Operator v5が自動的にインストールされます ServiceMonitor : Kuadrant各コンポーネント(Authorino、Limitador、DNS Operator等)のメトリクス収集設定 注意 : gateway-system namespaceに関するエラーが表示されることがありますが、無視して問題ありません(Gateway API CRDの標準namespaceですが、実際には使用されません)。 Step 5: Istio Telemetry の設定 Istioメトリクスに追加ラベル( request_url_path 等)を設定します。 5.1 istio-system namespace の確認 namespace: istio-system が存在しない場合は作成します: oc create namespace istio-system 5.2 Telemetry リソースの作成 Istioの Telemetry リソースを作成します。 Istioメトリクスに request_url_path 、 request_host 、 destination_port ラベルを追加します: cat <<EOF | oc apply -f - apiVersion: telemetry.istio.io/v1 kind: Telemetry metadata: name: namespace-metrics namespace: istio-system spec: metrics: - overrides: - match: metric: REQUEST_COUNT tagOverrides: destination_port: value: string(destination.port) request_host: value: request.host request_url_path: value: request.url_path - match: metric: REQUEST_DURATION tagOverrides: destination_port: value: string(destination.port) request_host: value: request.host request_url_path: value: request.url_path providers: - name: prometheus EOF Step 6: Grafana Instance のデプロイ monitoring namespaceにGrafana Instanceを作成します。 6.1 ServiceAccount の作成 GrafanaがPrometheusにアクセスするためのServiceAccountを作成します: oc create serviceaccount grafana-serviceaccount -n monitoring 6.2 権限の付与 重要 : GrafanaがThanos Querierに接続するために、 cluster-monitoring-view ClusterRoleを付与する必要があります。 oc adm policy add-cluster-role-to-user cluster-monitoring-view \ system:serviceaccount:monitoring:grafana-serviceaccount この権限により、GrafanaはThanos Querierからメトリクスを取得できます。 権限付与を確認: oc get clusterrolebinding cluster-monitoring-view -o yaml | grep -A 3 "subjects:" 出力例: subjects : - kind : ServiceAccount name : grafana-serviceaccount namespace : monitoring 6.3 ServiceAccount Token Secret の作成 Kubernetes 1.24以降、ServiceAccountのTokenは自動生成されないため、明示的にSecretを作成します: cat <<EOF | oc apply -f - apiVersion: v1 kind: Secret metadata: name: grafana-serviceaccount-token namespace: monitoring annotations: kubernetes.io/service-account.name: grafana-serviceaccount type: kubernetes.io/service-account-token EOF 6.4 Grafana CR の作成 Grafana Instanceを定義します: cat <<EOF | oc apply -f - apiVersion: grafana.integreatly.org/v1beta1 kind: Grafana metadata: name: grafana namespace: monitoring labels: dashboards: grafana spec: config: security: admin_user: admin admin_password: grafana123 route: spec: port: targetPort: 3000 tls: insecureEdgeTerminationPolicy: Redirect termination: edge wildcardPolicy: None EOF 設定のポイント: admin_password: grafana123 : テスト環境用の簡易パスワード(本番環境では変更必須) route.spec : OpenShift RouteでHTTPS経由でアクセス可能に 6.5 Grafana起動の確認 Podが起動するまで待ちます(1〜2分): oc get pods -n monitoring -l app=grafana -w Running になればOKです。 Ctrl+C で監視を終了します。 Grafana CRの状態確認: oc get grafana grafana -n monitoring -o jsonpath='{.status.stage}' complete が表示されれば正常です。 6.6 Grafana URL の確認 作成されたRouteのURLを確認します: oc get route grafana-route -n monitoring -o jsonpath='{.spec.host}' 出力例: grafana-route-monitoring.apps.cluster-xxx.xxx.openshiftapps.com ブラウザで https://<上記のホスト名> にアクセスし、ログイン画面が表示されることを確認します。 ログイン情報: Username: admin Password: grafana123 Step 7: Prometheus Datasource の設定 GrafanaからThanos Querierに接続するためのDatasourceを設定します。 7.1 Bearer Token の取得 ServiceAccountのTokenを取得します: TOKEN=$(oc get secret grafana-serviceaccount-token -n monitoring -o jsonpath='{.data.token}' | base64 -d) echo "Token length: ${#TOKEN}" 7.2 Token Secret の作成 Grafana Operatorが参照できるようにSecretを作成します: cat <<EOF | oc apply -f - apiVersion: v1 kind: Secret metadata: name: prometheus-bearer-token namespace: monitoring stringData: token: "Bearer ${TOKEN}" type: Opaque EOF 7.3 Thanos Querier URL の取得 OpenShift MonitoringのThanos Querier URLを取得します: CLUSTER_DOMAIN=$(oc get route console -n openshift-console -o jsonpath='{.spec.host}' | sed 's/^console-openshift-console\.//') THANOS_URL="https://thanos-querier-openshift-monitoring.${CLUSTER_DOMAIN}" echo "Thanos Querier URL: ${THANOS_URL}" 出力例: Thanos Querier URL: https://thanos-querier-openshift-monitoring.apps.cluster-xxx.xxx.openshiftapps.com 7.4 GrafanaDatasource CR の作成 cat <<EOF | oc apply -f - apiVersion: grafana.integreatly.org/v1beta1 kind: GrafanaDatasource metadata: name: prometheus-datasource namespace: monitoring spec: instanceSelector: matchLabels: dashboards: grafana datasource: name: Prometheus type: prometheus access: proxy url: ${THANOS_URL} isDefault: true jsonData: httpHeaderName1: Authorization timeInterval: 30s tlsSkipVerify: true secureJsonData: httpHeaderValue1: \${token} valuesFrom: - targetPath: secureJsonData.httpHeaderValue1 valueFrom: secretKeyRef: name: prometheus-bearer-token key: token EOF 設定のポイント: url : Thanos QueryerのURL httpHeaderName1: Authorization : Bearer Token認証を使用 tlsSkipVerify: true : 自己署名証明書を許可 secureJsonData.httpHeaderValue1: \${token} : プレースホルダー(Grafana Operatorが valuesFrom で指定された値に置き換える) valuesFrom : Secret ( prometheus-bearer-token ) からBearerトークンを取得し、 \${token} プレースホルダーを置き換え 7.5 Datasource の確認 GrafanaDatasource CRの状態を確認します: oc get grafanadatasource prometheus-datasource -n monitoring 出力例: NAME NO MATCHING INSTANCES LAST RESYNC AGE prometheus-datasource 30s 30s LAST RESYNC に時間が表示されていれば、Grafana Operatorが同期処理を完了しています。 7.6 Grafana UIで接続テスト 重要 : 必ずGrafana UIから接続テストを実施してください。 ブラウザでGrafanaにログイン : Username: admin Password: grafana123 Datasource接続テスト : 左メニュー > Connections > Data sources Prometheus をクリック 下部までスクロールして Save & test ボタンをクリック 成功メッセージを確認 : ✓ Successfully queried the Prometheus API. 緑のチェックマークとこのメッセージが表示されれば成功です。 Step 8: Grafana Dashboard のインポート Kuadrantの3つのサンプルダッシュボードをインポートします。 8.1 Platform Engineer Dashboard cat <<EOF | oc apply -f - apiVersion: grafana.integreatly.org/v1beta1 kind: GrafanaDashboard metadata: name: platform-engineer-dashboard namespace: monitoring spec: instanceSelector: matchLabels: dashboards: grafana datasources: - inputName: "DS_GRAFANACLOUD-KUADRANTDEV-PROM" datasourceName: "Prometheus" url: "https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/refs/tags/v1.3.0/examples/dashboards/platform_engineer.json" EOF 8.2 App Developer Dashboard cat <<EOF | oc apply -f - apiVersion: grafana.integreatly.org/v1beta1 kind: GrafanaDashboard metadata: name: app-developer-dashboard namespace: monitoring spec: instanceSelector: matchLabels: dashboards: grafana datasources: - inputName: "DS_GRAFANACLOUD-KUADRANTDEV-PROM" datasourceName: "Prometheus" url: "https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/refs/tags/v1.3.0/examples/dashboards/app_developer.json" EOF 8.3 Business User Dashboard cat <<EOF | oc apply -f - apiVersion: grafana.integreatly.org/v1beta1 kind: GrafanaDashboard metadata: name: business-user-dashboard namespace: monitoring spec: instanceSelector: matchLabels: dashboards: grafana datasources: - inputName: "DS_GRAFANACLOUD-KUADRANTDEV-PROM" datasourceName: "Prometheus" url: "https://raw.githubusercontent.com/Kuadrant/kuadrant-operator/refs/tags/v1.3.0/examples/dashboards/business_user.json" EOF インポート方法のポイント: spec.url : GitHubのサンプルのJSONを直接参照 datasources : ダッシュボード内のDatasource名をマッピング Grafana Operatorが自動でJSONをダウンロードしてインポート 8.4 Dashboard の確認 Grafana Operatorがダッシュボードを同期するまで待ちます(30秒〜1分): CRの状態確認: oc get grafanadashboard -n monitoring 出力例: NAME NO MATCHING INSTANCES LAST RESYNC AGE app-developer-dashboard 45s 45s business-user-dashboard 44s 44s platform-engineer-dashboard 46s 46s Grafana UIで確認: 1. Grafanaにログイン 2. 左メニュー > Dashboards 3. 3つのダッシュボードが表示されていることを確認 Step 9: 動作確認 9.1 メトリクス収集の確認 Gateway APIメトリクスが収集されているか確認: # HTTPRouteメトリクスの確認 oc exec -n openshift-user-workload-monitoring prometheus-user-workload-0 -c prometheus -- \ promtool query instant http://localhost:9090 \ 'gatewayapi_httproute_labels{name="news-api"}' メトリクスが返ってくればOKです。 9.2 トラフィックの生成 ダッシュボードにデータを表示するため、テストリクエストを送信します: 以下は、 第2回記事 で使用したリソースをデプロイしている場合の例です。 # 環境変数設定 API_KEY=$(oc get secret api-keys -n kuadrant-system -o jsonpath='{.data.api_key}' | base64 -d) GATEWAY_HOST=$(oc get gateway external -n api-gateway -o jsonpath='{.spec.listeners[0].hostname}') # リクエスト送信(複数回) for i in {1..10}; do curl -sk -H "Authorization: APIKEY ${API_KEY}" https://${GATEWAY_HOST}/ curl -sk -H "Authorization: APIKEY ${API_KEY}" https://${GATEWAY_HOST}/technology curl -sk -H "Authorization: APIKEY ${API_KEY}" https://${GATEWAY_HOST}/sports sleep 1 done 9.3 App Developer Dashboard の確認 Grafanaにアクセス: https://<grafana-route-host> 左メニュー > Dashboards > App Developer Dashboard 上部の変数セレクターで: route_name : news-api を選択 api_namespace : news-api を選択 以下を確認: Request breakdown by code (左上): ステータスコード別のリクエストレートグラフ Request latency percentiles (右上): p95, p90, p99レイテンシのグラフ Request breakdown by code and path (左下): パス別・コード別の詳細グラフ Request latency by code and path (p95) (右下): パス別p95レイテンシ 9.4 Business User Dashboard の確認 Dashboards > Business User Dashboard 以下を確認: Total Requests for Selected Range (右下): パス別リクエスト数のテーブル / , /technology , /sports が表示される Breakdown by Path (左下): パス別のトラフィックグラフ Historical Request Comparison (右上): 期間比較の棒グラフ 9.5 Platform Engineer Dashboard の確認 Dashboards > Platform Engineer Dashboard 以下を確認: Gateways : Gateway数とステータス、Policyの適用状態 HTTPRoutes : HTTPRoute別のトラフィックとレイテンシ Alerts : 発火中のアラート一覧 注意 : メトリクスが表示されるまで1〜2分かかる場合があります。データが表示されない場合は、ブラウザをリフレッシュしてください。 まとめ 本記事では、Red Hat Connectivity LinkのObservability機能として、メトリクス監視の実装方法を解説しました。 構築した環境 OpenShift User Workload Monitoring : Prometheusベースのメトリクス収集基盤 kube-state-metrics-kuadrant : Gateway APIリソースのメトリクス収集 Istio Telemetry : トラフィックメトリクスへの追加ラベル設定 Grafana監視スタック : 3つの役割別ダッシュボード 3つのダッシュボードの使い分け ダッシュボード 対象ユーザー 主な用途 確認する内容 App Developer アプリケーション開発者 API監視 トラフィック、レイテンシ、エラー率 Business User PM、アナリスト ビジネスメトリクス リクエスト数トレンド、パス別分析 Platform Engineer SRE、クラスター管理者 インフラ全体監視 Gateway/Policy状態、コンポーネントヘルス、アラート 参考リンク Red Hat Connectivity Link Documentation Kuadrant Operator - Observability Examples OpenShift Monitoring Documentation Grafana Operator Documentation
RHELのスペシャリストソリューションアーキテクトの田中司恩( @tnk4on )です。 Linux カーネルの暗号サブシステムに特権昇格の脆弱性 CVE-2026-31431(Copy Fail)が見つかりました。Red Hat は該当しない RHEL 6、7 を除くすべての製品へのエラータを提供済みで、あとは各ホストに適用するフェーズです。脆弱性の詳細や対応の時系列は Red Hat Security Bulletin(RHSB-2026-02) 、リリース済みエラータの一覧は CVE-2026-31431 のページを参照してください。 この記事では、パッチ適用の方法の一つとして Red Hat Satellite を使ったアプローチを紹介します。Satellite を活用すると、影響を受けるホストの特定からパッチ適用までを Web UI や AI エージェント経由で効率的に実行できます。 エラータ(Errata)は、Red Hat が提供するセキュリティ修正、バグ修正、機能強化などの更新をパッケージとしてまとめたものです。一般的に「パッチ」と呼ばれるものに相当します。 -目次- Red Hat Satellite とコンテンツ管理 Satellite でのパッチ適用手順 デモ環境 Step 1: エラータの存在確認 Step 2: Content View の確認 Step 3: Content View のパブリッシュ Step 4: Dev 環境への Promote Step 5: エラータのインストール可能化を確認 Step 6: ホストへのパッチ適用 応用: MCP server for Satellite + Claude Code による自動化 (参考)Red Hat Lightspeed in Satellite による脆弱性の可視化 まとめ ウェビナーのご案内 リンク Red Hat Satellite とコンテンツ管理 Red Hat Satellite は RHEL のライフサイクル管理を行うためのツールです。パッチ管理においては、Red Hat Content Delivery Network(CDN)からリポジトリーを同期し、Content View を通じてホストにコンテンツを配信します。エラータがホストに届くまでの流れは以下の通りです。 CDN → リポジトリー同期 → Content View パブリッシュ → ライフサイクル環境へ Promote → ホストに配信 ここで重要なのは、 リポジトリーの同期と Content View のパブリッシュは別の操作である という点です。CDN からエラータが同期されても、Content View を再パブリッシュしないとホストからはそのエラータが見えません。この仕組みにより、テスト済みのコンテンツだけを段階的に配信でき、本番環境への意図しない変更を防ぐことができます。 Satellite でのパッチ適用手順 ここからは、実際に Satellite の Web UI を使って CVE-2026-31431 のパッチを RHEL ホストに適用する手順を紹介します。 デモ環境 項目 値 Satellite 6.18(satellite.home.lab) Content View RHEL10-Base(RHEL 10 用)、RHEL9-Base(RHEL 9 用) ライフサイクル環境 Library → Dev → Prod 管理対象ホスト RHEL 10.1 × 4台、RHEL 9.7 × 1台 対象エラータ RHSA-2026:13566(RHEL 10)、RHSA-2026:13565(RHEL 9) このデモでは RHEL10-Base の Content View を使い、RHEL 10 向けのエラータ(RHSA-2026:13566)を対象に操作を行います。 Step 1: エラータの存在確認 まず Satellite にエラータが同期されているか確認します。コンテンツ > コンテンツタイプ > エラータ で RHSA-2026:13566 を検索します。 エラータ一覧: 適用可能 4件、インストール可能 0件 エラータは存在していますが、注目すべきは「適用可能: 4 件、インストール可能: 0 件」という表示です。 指標 意味 適用可能(Applicable) ホストに該当パッケージがインストールされている(つまり脆弱性の影響を受ける) インストール可能(Installable) Content View に含まれていて、パッチ適用が可能 エラータは CDN から同期済みですが、Content View がまだ更新されていないため、ホストからはインストールできない状態です。 Step 2: Content View の確認 コンテンツ > ライフサイクル > Content Views で RHEL10-Base を開きます。 Content View RHEL10-Base: Version 1.0 が全環境に配置 Version 1.0 のみが存在し、Library・Dev・Prod すべての環境に v1.0 が配置されています。この v1.0 は CVE-2026-31431 の修正エラータが公開される前にパブリッシュされたものです。 Step 3: Content View のパブリッシュ 「Publish new version」をクリックして新しいバージョンをパブリッシュします。説明欄にはパブリッシュの理由を記載しておくと、あとから変更履歴を追跡しやすくなります。 パブリッシュウィザード: Version 2.0 の説明を入力 パブリッシュが完了すると Version 2.0 が作成されます。この時点では v2.0 は Library にのみ配置されており、Dev や Prod 環境にはまだ反映されていません。 パブリッシュ完了: Version 2.0 が Library に作成 Step 4: Dev 環境への Promote Version 2.0 の「Promote」をクリックし、ライフサイクルパスから Dev 環境を選択して Promote を実行します。 Promote ダイアログ: Dev 環境を選択 Promote が完了すると、v2.0 が Library と Dev に配置されます。 Promote 完了: v2.0 が Library と Dev に配置 Dev 環境のホストはこの v2.0 を参照するようになります *1 。 Step 5: エラータのインストール可能化を確認 再びエラータの画面で RHSA-2026:13566 を検索します。 エラータ一覧: インストール可能が 0件 → 4件 に変化 Content View の再パブリッシュと Promote により、 インストール可能が 0 件 → 4 件に変化 しました。これでホストからエラータをインストールできる状態になりました。 Step 6: ホストへのパッチ適用 ホスト > (対象ホスト) > コンテンツ > Errata タブを開くと、RHSA-2026:13566 が Installable として表示されています。エラータを展開すると、Synopsis や Description などの詳細情報を確認できます。 ホストの Errata タブ: エラータ詳細の表示 エラータを選択して「Apply」(Apply via remote execution)をクリックすると、即時にパッチ適用が開始されます。この場合、Satellite/Capsule からホストに SSH 接続してコマンドが実行されます *2 。プルダウンから「Apply via customized remote execution」を選択すると、スケジュール実行も可能です。ここでは「Apply」を選択して即時実行します。 Apply ボタン: 即時適用とカスタマイズ実行の選択 ジョブが開始されると通知が表示されます。 ジョブ開始の通知 ジョブの実行状況はタスクページで確認できます。対象ホストごとの進行状況やコマンドの実行ログがリアルタイムで表示されます。 ジョブ実行中: コマンドログの表示 ジョブが完了するとステータスが Succeeded になります。 ジョブ完了: ステータス Succeeded カーネルのエラータを適用した場合、新しいカーネルを有効にするためにホストの再起動が必要です。Satellite のリモート実行機能を使えば、Web UI から再起動のスケジュール実行も可能です。 以上で、Satellite を使ったパッチ適用は完了です。Web UI からの操作だけで、エラータの確認から適用までの一連のプロセスを行うことができました。 応用: MCP server for Satellite + Claude Code による自動化 Satellite 6.18 の新機能として「 MCP server for Satellite 」が提供されています(テクノロジープレビュー)。MCP(Model Context Protocol)に対応した AI エージェントから Satellite の API を直接操作できる機能です。 以下は Claude Code から MCP server for Satellite を利用して、CVE の確認から Content View の更新、エラータのスケジュール適用までを自然言語の1プロンプトで一気に実行した例です。 入力したプロンプト: CVE-2026-31431 の影響を受けるホストを確認して。 Content View が古い場合は再パブリッシュして Dev に promote して。 その後、client1 に該当エラータを今日の 0:00 にスケジュール適用して。 Claude Code の実行結果(前半): CVE 確認 → CV パブリッシュ → Promote Claude Code の実行結果(後半): エラータ状態確認 → スケジュール適用 この例では、CVE の確認 → Content View のパブリッシュ → Dev への Promote → エラータの状態確認 → ホストへのスケジュール適用を、Claude Code が MCP server for Satellite と Satellite CLI( hammer )を組み合わせて自動実行しています。本記事で紹介した Web UI の操作と同じ一連のプロセスを、ターミナルから自然言語で指示するだけで自動化できます。特に、複数のシステムにまたがってさまざまなバージョンの RHEL が混在する環境では、従来の管理手法で手間や時間がかかっていた作業を、AI エージェントによって迅速かつ正確に完了できます。 (参考)Red Hat Lightspeed in Satellite による脆弱性の可視化 Red Hat Lightspeed in Satellite は、Red Hat Lightspeed(旧 Red Hat Insights)の機能を Satellite 上でオンプレミスに提供するコンポーネントです。Advisor(アドバイザー)と Vulnerability(脆弱性)の 2 つのサービスを提供しており、なぜこれらが Satellite 本体とは別に提供されているかを理解するには、Satellite の設計思想を知る必要があります。 Satellite はコンテンツ管理ツールとして設計されており、管理単位はエラータ ID(例: RHSA-2026:13566)です。Satellite の役割は「正しいパッケージを正しいホストに正しいタイミングで届ける」ことであり、CVE 起点の脆弱性評価とは関心事が異なります。セキュリティチームが「CVE-2026-31431 の影響範囲は?」と考えるのに対し、運用チームは「どのエラータを適用すればよいか?」を起点に動きます。Satellite が CVE での横断検索を持たないのは、コンテンツ配信の信頼性(Content View のバージョニング、ライフサイクル管理)に注力してきた経緯があるためと考えられます。 Red Hat Lightspeed in Satellite は、この CVE 起点の脆弱性管理を専用のデータパイプラインでオンプレミスに提供するもので、Satellite のコンテンツ管理とは別レイヤーの関心事を統合します。有効にすると、 CVE を起点とした脆弱性管理 が可能になります。「CVE-2026-31431 は CVSS 7.8 で 4 ホストに影響」という情報が一画面で確認でき、エラータとの対応関係も自動でマッピングされます。 Vulnerability ページ: CVE-2026-31431 の検出と詳細表示 機能 Satellite 単体 + Lightspeed in Satellite エラータ一覧 ○ ○ ホスト別 Installable Errata ○ ○ CVE × ホストのマトリックス × ○(CVE ID で検索、影響ホスト数を表示) CVSS スコア表示 × ○(CVE ごとに CVSS base score を表示) Advisor Recommendations × ○(セキュリティ以外も含む改善提案) クラウド接続 不要 不要(全てオンプレミス) クラウド接続不要で、複数のコンテナーが全てオンプレミスで動作するため、非接続環境(Air-gapped 環境)にも対応しています *3 。 まとめ この記事では、Red Hat Satellite を使って CVE-2026-31431 のセキュリティパッチを RHEL ホストに適用する手順を紹介しました。ポイントは以下の通りです。 Satellite では Content View のパブリッシュによって、配信するエラータを明示的に制御できる Content View のパブリッシュと Promote により、ライフサイクル環境ごとに段階的な配信が可能 Web UI からの操作だけで、エラータの確認からパッチ適用まで一連のプロセスを完結できる MCP server for Satellite を活用すると、AI エージェントによる操作の自動化が可能 Red Hat Lightspeed in Satellite を活用すると、脆弱性の影響範囲をオンプレミスで可視化できる 今回の CVE-2026-31431 のケースが示すように、Claude Mythos のような最先端のモデルを使わなくても、すでに利用可能な AI モデルを使って誰でも脆弱性を発見できる時代になりつつあり、それがゼロデイ攻撃につながるリスクも高まっています。このような時代には、複雑なツールを使って時間をかけて対応するのでは間に合いません。ホストのインベントリ管理から脆弱性の特定、修正パッチの適用までを、迅速に実行できる仕組みが求められています。 Red Hat Satellite は Red Hat 純正の管理ツールであり、RHEL ホストのインベントリ管理から脆弱性の特定、パッチ適用までを一貫して行うことができます。この記事が、Satellite を活用したセキュリティ対応の参考になれば幸いです。 ウェビナーのご案内 Satellite と Ansible Automation Platform を組み合わせたパッチ適用の自動化や、Red Hat Lightspeed in Satellite について、より詳しい内容をウェビナーで紹介しました。現在はオンデマンドで配信しており、登録のみで動画と資料を参照できます。 www.redhat.com 「 RHELパッチ運用の自動化で脆弱性を封じ込める、次世代セキュリティ対応の実践ガイド ~Satellite / Ansible / Lightspeedの全貌~ 」 前半パート : 情報セキュリティの脅威動向(IPA 10大脅威 2026)、セキュリティパッチ適用の実態と課題、Satellite と Ansible Automation Platform を活用したパッチ運用の自動化デモ 後半パート : Red Hat Lightspeed in Satellite の紹介(Advisor / Vulnerability 機能)、Satellite を使ったデモ、Satellite 6.18 新機能「Satellite MCP Server」 リンク RHSB-2026-02 Cryptographic Subsystem Privilege Escalation - Linux Kernel CVE-2026-31431 Red Hat Satellite Red Hat Satellite 6.18 Release Notes MCP server for Satellite ウェビナー: RHELパッチ運用の自動化で脆弱性を封じ込める、次世代セキュリティ対応の実践ガイド *1 : Prod 環境への Promote は別途必要です。本番環境への配信前に Dev 環境でテストを行い、問題がないことを確認してから Promote するのが推奨です。 *2 : デフォルトのリモート実行方法は SSH です。ホスト側で SSH サービスが稼働している必要があります。 *3 : Satellite 6.18 において、Advisor 機能は GA、Vulnerability 機能はテクノロジープレビューです。
こんにちは、レッドハットコンサルティングチームの木嶋です。 GW明けにクラウドネイティブ会議が名古屋で行われます。 名古屋に1000人の参加者を呼び寄せようという熱いお祭りに貢献すべく、弊社もたくさんのメンバーで参加いたします。 もしお越しになる場合は、弊社の出展ブースやセッションにぜひお立ち寄りください。 クラウドネイティブ会議 イベント概要 日時: 2026/5/14 (木) - 5/15 (金) 場所: 中日ホール&カンファレンス 詳しくは直接イベントWebサイトをご参照ください。 kaigi.cloudnativedays.jp 参加形態 現地あるいはオンライン参加 ※ 事前登録が必要です。 見どころ1: セッション アジェンダをご覧いただくと目移りしてしまうほどたくさんのセッションが登録されています。 弊社では合計3名がセッション枠を頂戴しました! 5/14 (木) 12:50-13:20 分断されたOTとITを繋ぐ架け橋 - Kubernetesが切り拓く産業用組み込み製品の現在地 Yudai Ono CNCF IoT Edge WG発足以降、Kubernetesの活用範囲は、産業用組み込み製品にまで広がっています。産業用組み込み製品の未来の話、Kubernetesがなぜ求められるのか?そして、何よりエッジコンピューティングの面白さを、製造業の地 名古屋でぜひ体験していってください。 kaigi.cloudnativedays.jp 5/15 (金) 12:00-12:30 開発者ポータルって必要?エンタープライズにおけるPlatform Engineering立ち上げの現実解 Shintaro Kitamura 「開発者ポータルって、今すぐ必要?それとも将来でいい?」Platform Engineeringを始めると必ず出てくるこの問いに、“未来を見据えて必要な理由”と“今すぐ入れても価値が出る理由”の両面から切り込みます。 kaigi.cloudnativedays.jp 5/15 (金) 17:00-17:30 Platform Engineeringはなぜスケールしないのか ― スコープ設計と責任境界の話 Sachiko Kijima CNCFにプラットフォームエンジニアリングの成熟度はあるものの、実際には成熟度は思うようにあがりません。コンサルティングの現場から、ベストプラクティスをお届けします。 kaigi.cloudnativedays.jp 見どころ2: 出展ブース クラウドネイティブ会議のRed Hatブースでは、エンタープライズのDXやAI実装を加速させるプラットフォームエンジニアリングの現実解について紐解きます! クラウドネイティブやSRE、プラットフォームエンジニアリングに関連する製品紹介 コンサルタントによる伴走支援の事例紹介、個別相談 Red Hatコンサルティングでのお仕事紹介 現場エンジニアと直接語り合える機会としてぜひご活用ください。ノベルティをご用意してお待ちしております! 見どころ3: コミュニティTech Tilesステッカー レッドハット有志メンバーを中心に、OSSのアレコレをワイワイと議論しあうコミュニティである「OpenShift Lounge+」は、クラウドネイティブ会議を盛り上げる協賛団体として参加しています! 協賛コミュニティ一覧: kaigi.cloudnativedays.jp 既に クラウドネイティブ会議公式ブログでも紹介頂いてます が、今回の協賛を記念してTech Tiles形式ステッカーを作成しました! 名古屋会場にて配布しておりますので、是非この機会にGetしてみてください! OpenShift Lounge+ お越しをお待ちしております イベントではそのほか、懇親会、連携コミュニティイベント等、多数の企画が進行中です。ぜひチェックしてみてください。 kaigi.cloudnativedays.jp それでは、現地でお会いしましょう!
はじめに レッドハットのソリューションアーキテクトの森です。 第2回記事 では、API Key認証を実装しました。 第3回の本記事ではより高度な認証機能として JWT(JSON Web Token)ベースの認証 と ロールベースアクセス制御(RBAC) を実装します。 Red Hat build of Keycloak(RHBK)をOIDCプロバイダーとして使用し、Authorinoと統合することで、エンタープライズグレードの認証・認可基盤を構築します。 前回の記事はこちら rheb.hatenablog.com 本記事で扱う内容 シナリオ 内容 ユースケース シナリオ1 JWT検証の基本実装 トークンベースの認証 シナリオ2 ロールベースアクセス制御(RBAC) ユーザーロールによるアクセス制御 シナリオ3 RateLimitPolicyとの統合 ユーザーロール別のレート制限 前提条件 本記事における環境 項目 要件 OpenShift Container Platform 4.19以降 Red Hat Connectivity Link 1.3.2以降インストール済み(第1回記事参照) Red Hat build of Keycloak 26.4インストール済み(本記事内参照) News API デプロイ済み(第2回記事参照) Gateway, HTTPRoute, 各種Policy 作成済み(第2回記事参照) Keycloakセットアップ Red Hat build of Keycloak(RHBK)のインストールとRealm設定は、簡略化のため自動化スクリプトを使用して実施します。 セットアップ実行 # リポジトリのクローン git clone https://github.com/kamorisan/connectivity-link-blog.git cd connectivity-link-blog/03-advanced_authentication # 1. RHBKのインストール(5〜10分) ./install-rhbk.sh # 2. サンプルRealmのインポート(1〜2分) ./import-realm.sh # 3. 環境変数の読み込み source keycloak-env.sh セットアップされる内容 スクリプトにより以下が自動設定されます: 項目 内容 Realm news-api-realm Client news-api-client Roles admin , user , premium テストユーザー guest (user), john.doe (user+premium), admin.user (admin) トークン有効期限 5分 詳細なセットアップ手順 : GitHub - 03-advanced_authentication/README.md JWT(JSON Web Token)とは JWT(JSON Web Token)は、クライアントとサーバー間で安全に情報を転送するためのオープンスタンダード( RFC 7519 )です。 JWTの構造(3つの部分): eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.signature...... └───────────── Header ─────────────┘ └──────────────────── Payload ────────────────────┘ └─ Signature ─┘ 主な利点 : ステートレス、スケーラブル、クロスドメイン対応、自己完結型、標準ベース 図1: アクセストークンの例 シナリオ1: JWTトークン検証の基本実装 Keycloakから発行されたJWTトークンの署名検証と基本的なクレーム抽出を実装します。 OIDC Discovery KeycloakはOIDC(OpenID Connect)プロバイダーとして、自動的に設定情報とJWKS(JSON Web Key Set)を公開します: # OIDC Discovery エンドポイントを確認 curl -s ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/.well-known/openid-configuration | jq . # JWKS(公開鍵)エンドポイントを確認 curl -s ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/certs | jq . Authorinoの自動検証: Authorinoは issuerUrl から自動的にこれらの設定を取得し、以下を検証します: ✓ JWT署名 : JWKSから取得した公開鍵を使用 ✓ exp クレーム : トークンの有効期限(期限切れトークンを自動的に拒否) ✓ nbf クレーム : Not Before(まだ有効でないトークンを拒否) ✓ iss クレーム : Issuerが issuerUrl と一致することを確認 つまり、明示的なOPAポリシーを記述しなくても、基本的なセキュリティチェックは自動的に行われます。 基本的なJWT検証のAuthPolicy まず、第2回記事で作成したAPI Key認証のAuthPolicyがある場合は、それを削除します: # 第2回記事で作成したAPI Key認証のAuthPolicyを削除 oc delete authpolicy news-api-auth -n ${KUADRANT_DEVELOPER_NS} 2>/dev/null || true JWT検証のAuthPolicyを作成します: oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: news-api-jwt-basic namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: news-api rules: authentication: jwt-verification: jwt: issuerUrl: ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM} credentials: authorizationHeader: prefix: Bearer response: unauthenticated: headers: "content-type": value: application/json body: value: | { "error": "Unauthenticated", "message": "Valid JWT token is required. Use header: Authorization: Bearer <token>" } EOF 注 : Authorinoは、JWT検証時に自動的に署名検証、 exp (有効期限)、 nbf (Not Before)クレームをチェックします。 トークンの有効期限は、Keycloak Realmの設定で管理されます(デフォルト: 5分)。 AuthPolicyのステータス確認 AuthPolicyが正常に適用されるまで待機します: # AuthPolicyのステータスを確認 oc get authpolicy news-api-jwt-basic -n ${KUADRANT_DEVELOPER_NS} # 詳細なステータスを確認(EnforcedがTrueになることを確認) oc get authpolicy news-api-jwt-basic -n ${KUADRANT_DEVELOPER_NS} -o jsonpath='{.status.conditions[?(@.type=="Enforced")]}' | jq . 期待される出力: { " lastTransitionTime ": " 2026-04-28T04:51:48Z ", " message ": " AuthPolicy has been successfully enforced ", " reason ": " Enforced ", " status ": " True ", " type ": " Enforced " } status: "True" になっていれば、AuthPolicyが正常に適用されています。 設定の詳細解説 主要パラメータ: issuerUrl : Keycloak RealmのURL(OIDC設定とJWKSを自動取得) credentials.authorizationHeader.prefix : Bearer 注 : Authorinoは、 issuerUrl から自動的にJWKSを取得し、JWT署名、 exp / nbf / iss クレームを検証します。明示的なOPAポリシーは不要です。 動作確認 ステップ1: アクセストークンを取得 # Keycloakからguestユーザーのトークンを取得 export GUEST_TOKEN=$(curl -s -X POST \ "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "client_id=news-api-client" \ -d "client_secret=${CLIENT_SECRET}" \ -d "username=guest" \ -d "password=guest123" \ | jq -r '.access_token') # トークンが取得できたか確認 if [ -n "$GUEST_TOKEN" ] && [ "$GUEST_TOKEN" != "null" ]; then echo "✓ Access token obtained successfully" echo "Token: ${GUEST_TOKEN:0:50}..." else echo "✗ Failed to obtain token" fi ステップ2: トークンなしでアクセス(401エラーが返る) curl -k https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力: { " error ": " Unauthenticated ", " message ": " Valid JWT token is required. Use header: Authorization: Bearer <token> " } ステップ3: userロールを持つユーザーのトークンありでアクセス(成功) JWT検証のみの場合、有効なトークンを持つユーザー( guest :userロール保持)で認証が成功します: # guestユーザーでアクセス(成功) curl -k -H "Authorization: Bearer ${GUEST_TOKEN}" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力: [ { " id ":" 69ebc38b-e24f-4108-864b-34cae563a665 ", " title ":" First Article ", " body ": null , " date ":" 2026-04-23 09:24:08 +0000 ", " author ":" Unknown ", " user_id ": null } ] 第2回記事で投稿をしていない場合、もしくはNews APIのPodを再起動した場合は、出力は空になっています。 JWT検証のみの場合、 有効なトークンであればロールに関係なくアクセスが許可されます 。これは、ロールベースのアクセス制御(RBAC)を実装していないためです。 トークンの有効期限について : Keycloakのデフォルト設定では、アクセストークンの有効期限は 5分 です。 トークン発行後、5分以内はAPIアクセスが成功し、5分経過するとAuthorinoが自動的に 401 Unauthenticated エラーを返します。 有効期限は、Keycloak Realm設定の Realm settings > Tokens > Access Token Lifespan で変更できます。 401 Unauthenticated エラーが返る場合は、新しいトークンを再取得してください。 シナリオ2: ロールベースアクセス制御(RBAC) ユーザーのロールに基づいて、異なる操作へのアクセスを制御します: userロール : 記事参照(GET)のみ premiumロール : 記事参照(GET)+ 記事投稿(POST) adminロール : 記事参照(GET)+ 記事投稿(POST)+ 記事削除(DELETE) HTTPメソッド別のロール要件 HTTPメソッド(GET/POST/DELETE)ごとに異なるHTTPRouteを作成し、それぞれに異なるロール要件を設定します。 記事参照エンドポイント(GET) HTTPRouteの修正: 既存の news-api HTTPRouteをGET専用に更新します: oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: news-api namespace: ${KUADRANT_DEVELOPER_NS} labels: app: news-api spec: parentRefs: - name: ${KUADRANT_GATEWAY_NAME} namespace: api-gateway hostnames: - api.${KUADRANT_ZONE_ROOT_DOMAIN} rules: - matches: - path: type: PathPrefix value: / method: GET backendRefs: - name: news-api port: 80 EOF AuthPolicy: シナリオ1のAuthPolicyを削除して、RBAC付きAuthPolicyに置き換えます: # シナリオ1のAuthPolicyを削除 oc delete authpolicy news-api-jwt-basic -n ${KUADRANT_DEVELOPER_NS} # RBAC付きAuthPolicyを作成 oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: news-api-rbac namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: news-api rules: authentication: keycloak-oidc: jwt: issuerUrl: ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM} credentials: authorizationHeader: prefix: Bearer authorization: check-user-role: opa: rego: | allow { input.auth.identity.realm_access.roles[_] == "user" } allow { input.auth.identity.realm_access.roles[_] == "premium" } allow { input.auth.identity.realm_access.roles[_] == "admin" } response: unauthenticated: headers: "content-type": value: application/json body: value: | { "error": "Unauthenticated", "message": "Valid JWT token is required" } unauthorized: headers: "content-type": value: application/json body: value: | { "error": "Unauthorized", "message": "User does not have required role (user, premium, or admin)" } success: filters: identity: json: properties: userid: selector: auth.identity.sub username: selector: auth.identity.preferred_username roles: selector: auth.identity.realm_access.roles EOF 注 : このAuthPolicyは、user/premium/adminのいずれかのロールを持つユーザーにGETアクセスを許可します。 response.success.filters.identity でカスタムプロパティ( userid , username , roles )を定義しています。これらはシナリオ3のRateLimitPolicyで使用されます。 記事投稿エンドポイント(POST) HTTPRoute: premiumロールまたはadminロールを持つユーザーのみが記事を投稿できるように、POST専用HTTPRouteを作成します: oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: news-api-write namespace: ${KUADRANT_DEVELOPER_NS} labels: app: news-api spec: parentRefs: - name: ${KUADRANT_GATEWAY_NAME} namespace: api-gateway hostnames: - api.${KUADRANT_ZONE_ROOT_DOMAIN} rules: - matches: - path: type: PathPrefix value: / method: POST backendRefs: - name: news-api port: 80 EOF AuthPolicy: oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: news-api-write-only namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: news-api-write rules: authentication: keycloak-oidc: jwt: issuerUrl: ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM} credentials: authorizationHeader: prefix: Bearer authorization: premium-or-admin: opa: rego: | allow { input.auth.identity.realm_access.roles[_] == "premium" } allow { input.auth.identity.realm_access.roles[_] == "admin" } response: unauthorized: headers: "content-type": value: application/json body: value: | { "error": "Forbidden", "message": "Premium or Admin role required for POST operations" success: filters: identity: json: properties: userid: selector: auth.identity.sub username: selector: auth.identity.preferred_username roles: selector: auth.identity.realm_access.roles EOF 注 : このAuthPolicyは、premium/adminロールを持つユーザーにのみPOSTアクセスを許可します。 記事削除エンドポイント(DELETE) HTTPRoute: 管理者のみが記事を削除できるように、DELETE専用HTTPRouteを作成します: oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: news-api-admin namespace: ${KUADRANT_DEVELOPER_NS} labels: app: news-api spec: parentRefs: - name: ${KUADRANT_GATEWAY_NAME} namespace: api-gateway hostnames: - api.${KUADRANT_ZONE_ROOT_DOMAIN} rules: - matches: - path: type: PathPrefix value: / method: DELETE backendRefs: - name: news-api port: 80 EOF AuthPolicy: oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: news-api-admin-only namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: news-api-admin rules: authentication: keycloak-oidc: jwt: issuerUrl: ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM} credentials: authorizationHeader: prefix: Bearer authorization: admin-only: opa: rego: | allow { input.auth.identity.realm_access.roles[_] == "admin" } response: unauthorized: headers: "content-type": value: application/json body: value: | { "error": "Forbidden", "message": "Admin role required for DELETE operations" } success: filters: identity: json: properties: userid: selector: auth.identity.sub username: selector: auth.identity.preferred_username roles: selector: auth.identity.realm_access.roles EOF 注 : このAuthPolicyは、adminロールを持つユーザーにのみDELETEアクセスを許可します。 動作確認 HTTPメソッド別のロール制御を確認します。 注 : 以下のテストでは、各HTTPメソッドが異なるHTTPRouteにマッチします: GET → news-api HTTPRoute → news-api-rbac AuthPolicy (user/premium/admin) POST → news-api-write HTTPRoute → news-api-write-only AuthPolicy (premium/admin) DELETE → news-api-admin HTTPRoute → news-api-admin-only AuthPolicy (admin) テスト1: userロールで記事投稿を試行(失敗) # guestユーザー(userロールのみ)のトークンを取得 export GUEST_TOKEN=$(curl -s -X POST \ "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "client_id=news-api-client" \ -d "client_secret=${CLIENT_SECRET}" \ -d "username=guest" \ -d "password=guest123" \ | jq -r '.access_token') # guestユーザーで投稿を試行(失敗) curl -k -X POST -H "Authorization: Bearer ${GUEST_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"title": "Test Article", "body": "Unauthorized"}' \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力: { " error ": " Forbidden ", " message ": " Premium or Admin role required for POST operations " } テスト2: premiumロールで記事投稿(成功) # john.doeユーザー(user + premiumロール)のトークンを取得 export PREMIUM_TOKEN=$(curl -s -X POST \ "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "client_id=news-api-client" \ -d "client_secret=${CLIENT_SECRET}" \ -d "username=john.doe" \ -d "password=password123" \ | jq -r '.access_token') # john.doeユーザーで記事投稿(成功) ARTICLE_ID=$(curl -k -s -X POST -H "Authorization: Bearer ${PREMIUM_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"title": "Premium Article", "body": "This will be deleted by admin"}' \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology \ | jq -r '.id') echo "Created article ID: ${ARTICLE_ID}" # john.doeユーザーで記事参照(成功) curl -k -H "Authorization: Bearer ${PREMIUM_TOKEN}" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology テスト3: premiumロールで記事削除を試行(失敗) # john.doeユーザーで削除を試行(失敗) curl -k -X DELETE -H "Authorization: Bearer ${PREMIUM_TOKEN}" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology/${ARTICLE_ID} 期待される出力: { " error ": " Forbidden ", " message ": " Admin role required for DELETE operations " } テスト4: adminロールで記事削除(成功) # admin.userのトークンを取得 export ADMIN_TOKEN=$(curl -s -X POST \ "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "client_id=news-api-client" \ -d "client_secret=${CLIENT_SECRET}" \ -d "username=admin.user" \ -d "password=admin123" \ | jq -r '.access_token') # 管理者ユーザーで削除(成功) curl -k -X DELETE -H "Authorization: Bearer ${ADMIN_TOKEN}" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology/${ARTICLE_ID} 期待される出力例: { " id ":" e2bb1629-2431-47d5-a454-5a7caff41166 ", " title ":" Premium Article ", " body ":" This will be deleted by admin ", " date ":" 2026-04-28 02:38:30 +0000 ", " author ":" Unknown ", " user_id ": null } シナリオ3: RateLimitPolicyとの統合 シナリオ2で設定したHTTPRouteとAuthPolicyに加えて、ユーザーのロール(tier)に基づいた異なるレート制限を適用します: userロール : 10リクエスト/30秒 premiumロール : 15リクエスト/30秒 adminロール : 20リクエスト/30秒 ロール別RateLimitPolicyの設定 まず、第2回記事で作成したRateLimitPolicyがあれば、それを削除します: # 第2回記事で作成したRateLimitPolicyを削除 oc delete ratelimitpolicy news-api-ratelimit -n ${KUADRANT_DEVELOPER_NS} 2>/dev/null || true 次に、ロール別のRateLimitPolicyを作成します: oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: RateLimitPolicy metadata: name: news-api-tier-limits namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: news-api limits: "user-tier": rates: - limit: 10 window: 30s counters: - expression: auth.identity.userid when: - predicate: | auth.identity.roles.exists(r, r == 'user') - predicate: | !auth.identity.roles.exists(r, r == 'premium') - predicate: | !auth.identity.roles.exists(r, r == 'admin') "premium-tier": rates: - limit: 15 window: 30s counters: - expression: auth.identity.userid when: - predicate: | auth.identity.roles.exists(r, r == 'premium') - predicate: | !auth.identity.roles.exists(r, r == 'admin') "admin-tier": rates: - limit: 20 window: 30s counters: - expression: auth.identity.userid when: - predicate: | auth.identity.roles.exists(r, r == 'admin') EOF 重要な設定ポイント: counters.expression : auth.identity.userid - シナリオ2のAuthPolicyで定義したカスタムプロパティを使用 when条件 : 複数の predicate でAND条件を実現し、ロールの優先度を制御 user-tier: user ロールを持ち、かつ premium と admin を持たない premium-tier: premium ロールを持ち、かつ admin を持たない admin-tier: admin ロールを持つ これにより、複数ロールを持つユーザー(例: john.doeは user + premium )は、最も緩い制限(premium-tier: 15リクエスト/30秒)が適用されます レート制限の確認 userロールのレート制限確認(10リクエスト/30秒): # guestユーザー(userロールのみ)のトークンを取得 export GUEST_TOKEN=$(curl -s -X POST \ "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "client_id=news-api-client" \ -d "client_secret=${CLIENT_SECRET}" \ -d "username=guest" \ -d "password=guest123" \ | jq -r '.access_token') # 連続15回リクエスト(10回まで成功、11回目以降は429エラー) for i in {1..15}; do RESPONSE=$(curl -k -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer ${GUEST_TOKEN}" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology) echo "Request $i: HTTP $RESPONSE" sleep 0.1 done 期待される出力: Request 1: HTTP 200 ... Request 10: HTTP 200 Request 11: HTTP 429 Request 12: HTTP 429 ... premiumロールのレート制限確認(15リクエスト/30秒): # john.doeユーザー(premiumロール)のトークンを取得 export PREMIUM_TOKEN=$(curl -s -X POST \ "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "client_id=news-api-client" \ -d "client_secret=${CLIENT_SECRET}" \ -d "username=john.doe" \ -d "password=password123" \ | jq -r '.access_token') # 連続18回リクエスト(15回まで成功、16回目以降は429エラー) for i in {1..18}; do RESPONSE=$(curl -k -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer ${PREMIUM_TOKEN}" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology) echo "Request $i: HTTP $RESPONSE" sleep 0.1 done 期待される出力: Request 1: HTTP 200 ... Request 15: HTTP 200 Request 16: HTTP 429 Request 17: HTTP 429 ... adminロールのレート制限確認(20リクエスト/30秒): # admin.userのトークンを取得 export ADMIN_TOKEN=$(curl -s -X POST \ "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "client_id=news-api-client" \ -d "client_secret=${CLIENT_SECRET}" \ -d "username=admin.user" \ -d "password=admin123" \ | jq -r '.access_token') # 連続25回リクエスト(20回まで成功、21回目以降は429エラー) for i in {1..25}; do RESPONSE=$(curl -k -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer ${ADMIN_TOKEN}" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology) echo "Request $i: HTTP $RESPONSE" sleep 0.1 done 期待される出力: Request 1: HTTP 200 ... Request 20: HTTP 200 Request 21: HTTP 429 Request 22: HTTP 429 ... 注 : レート制限は30秒間隔でリセットされます。 429 Too Many Requests エラーが表示された後、30秒待機すれば再度リクエストが可能になります。 まとめ 本記事では、Red Hat Connectivity LinkでJWT認証とRBACを実装しました: 本記事で学んだこと JWT検証 : Keycloak(OIDC)を使用した署名検証と自動的なクレームチェック RBAC : ユーザーロールに基づくエンドポイント保護とOPAポリシー ロール別レート制限 : ユーザーティアに応じた差別化されたレート制限 次のステップ 次回以降の記事では、以下のようなトピックを扱う予定です: 観測性の設定 : メトリクス、ログ、トレーシングの統合 TokenRateLimitPolicy : LLM APIなどのトークンベースのレート制限
1. モダナイゼーション最大の壁は「コードの理解」 2. 2つのAIアプローチによる実機検証 検証①:AIエージェント型(Cursor) 検証②:AI拡張開発型(CNCF Konveyor AI) 3. まとめ:適材適所のAI活用を 参考 先日開催されたDevOpsDays Tokyo 2026 にて、 「塩漬けコードの移行を確実に加速する実践知〜CNCF Konveyorとナレッジ注入AIで実現するモダナイゼーション〜」 と題したセッションを実施してきました。 confengine.com 本記事では、レガシーシステムのモダナイゼーションにおける課題と、 「AIエージェント型(Cursor)」 および 「AI拡張開発型(CNCF Konveyor)」 の2つのアプローチを用いた実践的な比較検証のポイントを分かりやすくダイジェストでお届けします。 1. モダナイゼーション最大の壁は「コードの理解」 既存システムを新しい環境へ移行(マイグレーション)する際、組織は「システムの複雑さ」や「優先順位の競合」といった課題に直面します。中でも現場のエンジニアを最も悩ませるのが 技術的な複雑さ です。 開発時間の6〜7割は「コードの理解」に費やされる 通常の開発においてすら、コードを書く時間よりも理解する時間に圧倒的なコストがかかっています。 マイグレーションではコストが「二重」に 既存のコードの仕様を理解した上で、さらに「移行先の新しい環境・アーキテクチャ」も理解して正しく動くか検証する必要があるため、コーディングの速度向上だけでは根本的な解決になりません。 この高い障壁を乗り越えるため、現在約8割の企業がAIの活用を検討・実施しています。 2. 2つのAIアプローチによる実機検証 今回のセッションでは、サンプルアプリ(Java/JBossからQuarkusへの移行)を用いて、近年トレンドとなっている2つのAIアプローチで実際にマイグレーションを行い、それぞれのメリットと課題を比較しました。 検証①:AIエージェント型(Cursor) プロンプトによる指示だけで、AIが計画からソースコード修正、テスト、実行までを全自動で作り上げるアプローチです。 メリット 言語を細かく指定せずとも文脈を理解し、手軽にマイグレーションを完遂できる。 ビルドやアプリ起動までをAIに一任できるため、初動のスピードが速い。 課題(落とし穴) 意図しないリファクタリングの発生: 単なるランタイムの移行だけを頼んだはずが、AIの判断でメソッドの集約などが行われてしまい、コードレビュー(確認作業)の負荷が高まる。 潜在的なバグの混入: メモリリーク(JMSコンテキストの未回収など)や、テストコードが存在しないUI部分のバグは見落とされがち。 ナレッジが属人化(AI化)する: 修正のプロセスやコンテキストがAI側に閉じてしまうため、組織内に「横展開できる移行ノウハウ」が残らない。 検証②:AI拡張開発型( CNCF Konveyor AI ) 人間とAIが協調して作業を分担するアプローチです。今回はCNCFのサンドボックスプロジェクトであるオープンソースツール 「Konveyor(コンベイヤー)」 を使用しました。 Konveyorは、既存コードを静的解析し、修正すべき箇所を特定した上でLLM(AI)に修正案を提示させ、人間がレビューしていくツールです。 メリット ビジネスロジックを壊さない: 型の変換やフレームワークの「お作法」の修正に徹底し、意図しないリファクタリングを行わないため、デグレードのリスクを最小限に抑えられる。 ガードレールによる制御: 静的解析のルールに基づくため、的外れな修正が入りにくい。 ナレッジの資産化: 「どのようなルールで変換したか」を組織のカスタムルールとして追加・蓄積できるため、後続の移行プロジェクトでも使い回せる。 課題 依存関係の自動解決は発展途上: pom.xml の整合性やバージョン指定など、ビルド依存関係の完全な自動修正は難しく、人間の手による最終調整が必要。 LLMの性能に左右される: 性能の低いローカルLLMを使用すると、コンパイルエラーになるコードが出力されることもある。また、明文化されていないアーキテクチャ方針はAIには推測できない。 3. まとめ:適材適所のAI活用を 今回の検証結果から、どちらのツールが優れているというわけではなく、 「目的に応じた使い分け」 が重要であることが浮き彫りになりました。 比較項目 AIエージェント型(Cursor等) AI拡張開発型(Konveyor AI) 得意な領域 新規ロジックの実装、ゼロからの構築 既存システムの移行、エンタープライズのモダナイゼーション ビジネスロジック変更 変更(リファクタリング)される可能性がある 変更せず、お作法の変換のみに留める(安全) ナレッジの蓄積 AIのチャット履歴に埋もれがち 解析ルールとして組織の資産に残せる レビューの負荷 一括修正されるため、確認が非常に大変 箇所ごとにルールベースで修正されるため安心感がある エンタープライズ領域における「塩漬けコードの移行」では、 ビジネスロジックを安全に保ちつつ、移行のノウハウを組織に蓄積できる「Konveyor」 のアプローチが非常に有効です。一方で、新規開発やロジックそのものに手を入れるフェーズでは「Cursor」などのAIエージェントが圧倒的な力を発揮します。 モダナイゼーションを推進する皆様は、ぜひ自社のフェーズや目的に合わせて、最適なAIツールの導入を検討してみてはいかがでしょうか。 参考 Konveyor AI: supporting application modernization | CNCF State of Application Modernization Report 2024 | Konveyor From Code Complexity Metrics to Program Comprehension – Communications of the ACM 塩漬けコードの移行を確実に加速する実践知。CNCF Konveyor と『ナレッジ注入AI』で実現するモダナイゼーション - Speaker Deck
RHELのスペシャリストソリューションアーキテクトの田中司恩( @tnk4on )です。 Apple Silicon MacでRosetta for Linuxが利用可能になったことをきっかけに、私はPodmanへのRosetta統合を実装するPRを作成し、Podman v5.1に取り込まれました( PodmanでRosettaを使う【Podman v5.1】 )。これにより、QEMUよりも高速なx86_64エミュレーション環境をPodmanで利用できるようになりました。しかしその後、Linuxカーネル6.13以降とRosettaの間で互換性の問題が発生し、 Podman 5.6でRosettaはデフォルト無効化 されました。 一方、macOS向けのPodman MachineプロバイダーとしてはGPUが利用可能な libkrun が注目されており、次期Podman v6ではデフォルトプロバイダーになる予定です。しかし libkrun ではRosettaが使えず、x86_64エミュレーションはRosetta以前のQEMUユーザーモードに戻ることになります。libkrunでRosettaが使えない問題については私が調査レポートを作成し公開しています( libkrun + Rosetta investigation report 、英語)。 この状況を打開するために、Rosettaを利用せずに、さらにQEMU/Rosettaよりも高性能な FEX-Emu をPodmanで利用できるようにするプロジェクトを開始しました。現在、プレビューリリースとしてPodman Machine用のカスタムOSイメージを quay.io/tnk4on/machine-os で公開しています。この記事ではそのプロジェクト「 Podman FEX 」について紹介します。なお、このプロジェクトの内容はPodmanコミュニティの ディスカッション にも投稿しています。 注意 : これは個人プロジェクトであり、Podmanの公式製品ではありません。提供されるイメージには保証やサポートはありません。 背景と課題 Apple Silicon MacでPodman Machineを使ってx86_64コンテナーを実行する場合、これまで2つのエミュレーション方式が利用可能でした。しかし、いずれも問題を抱えています。 QEMUユーザーモードの問題: 命令の逐次変換のため動作が遅い rustcやPyArrowなど特定のワークロードでSIGSEGV(セグメンテーション違反)によるクラッシュが頻発する Rosetta 2 の制約: Podman 5.6以降、Linuxカーネルとの互換性問題により無効化されている libkrun プロバイダーでは利用できない 特定の条件下でコンテナーのシェルがハング(応答不能)するケースが報告されている 多くのx86_64コンテナーは問題なく動作しますが、特定のワークロードでクラッシュやハングが発生するケースがPodmanコミュニティで報告されています。aarch64イメージが提供されていないソフトウェアではx86_64コンテナーに頼るしかなく、こうした問題に遭遇した場合に回避手段がないことがApple Silicon Macユーザーにとって大きな障壁となっていました。 FEX-Emu とは FEX-Emu ( GitHub )は、AArch64 Linux上でx86およびx86_64アプリケーションを実行するためのJITベースのエミュレーターです。QEMUのような逐次的な命令変換ではなく、JIT(Just-In-Time)コンパイルによりx86_64命令をARM64命令に変換して実行するため、高いパフォーマンスが得られます。さらに、変換結果をコードキャッシュとしてディスクに保存し、繰り返し実行時にはキャッシュから直接実行できます。 Fedora 42で公式に採用 されており、コミュニティでの実績もあります。 Podman FEX の特徴 本プロジェクトでは、FEX-EmuをPodman Machineに統合するために、FEX-Emu、Podman、およびPodman関連のアップストリームプロジェクトに対して必要な修正と機能追加を行いました。その結果、以下の特徴を実現しています。 特徴 説明 OCI Hook統合 x86_64コンテナーにのみFEXをマウント。ARM64コンテナーはオーバーヘッドゼロ SELinux Enforcing セキュリティポリシーを有効にしたまま動作 FEX-2604 プレビュー公開時点でFEX-Emuの最新リリースをサポート JITコードキャッシュ デフォルトで有効化(無効化も可能) QEMUフォールバック FEXを無効にしてQEMUに切り替え可能 アーキテクチャー Podman Machineのアーキテクチャーは以下の通りです。 FEX-Emuを使ったPodman machineのアーキテクチャー Podman FEXのVM内部の構成を以下に示します。 macOS (Apple Silicon) └── libkrun VM (Fedora CoreOS, aarch64) ├── FEX-Emu │ ├── FEXInterpreter (static-pie, binfmt_misc) │ ├── FEXServer (コンテナーごとのライフサイクル) │ └── x86_64 RootFS (EROFS loop mount, 1.8GB) ├── OCI precreate hook │ └── amd64 annotation フィルター → FEX bind mounts ├── containers.conf │ └── FEX_APP_* 環境変数 + コードキャッシュ設定 └── QEMU-user-static (フォールバック用) OCI precreate hookにより、コンテナーの platform アノテーションを判定し、x86_64コンテナーの場合のみFEX-Emuのバイナリーとライブラリーをbind mountします。ARM64コンテナーには一切影響しないため、パフォーマンスへの悪影響はありません。 Podman Machine用のカスタムOSイメージ( quay.io/tnk4on/machine-os )には以下のコンポーネントが含まれています。 コンポーネント バージョン ゲストOS Fedora CoreOS (aarch64) カーネル 6.19.10-200.fc43.aarch64 FEX-Emu FEX-2604(static-pie、コンテナー対応パッチ4件) Podman (VM内) v5.8 / v6.0(イメージタグで切り替え) SELinux Enforcing クイックスタート 前提条件 要件 詳細 ハードウェア Apple Silicon Mac Podman v5.8以上 プロバイダー libkrun (必須) libkrunプロバイダーの設定 Podman 5.8ではデフォルトのプロバイダーが libkrun ではないため、明示的に設定する必要があります。 mkdir -p ~/.config/containers cat >> ~/.config/containers/containers.conf << 'EOF' [machine] provider = "libkrun" EOF 設定の確認: podman machine info --format '{{.Host.DefaultMachineProvider}}' # libkrun と表示されること FEX-Emu マシンの作成 Option A: クリーンインストール (既存のデフォルトマシンを置き換え) # 既存のデフォルトマシンを削除 podman machine stop podman machine rm -f # FEX-Emuマシンを作成(Podman 5.x は :5.8、Podman 6.x は :6.0) podman machine init \ --image docker://quay.io/tnk4on/machine-os:5.8 --now Option B: サイドバイサイド (既存マシンを保持) # "fex"という名前で別マシンを作成 podman machine init fex \ --image docker://quay.io/tnk4on/machine-os:5.8 --now # すべてのコマンドに --connection fex を付与 podman --connection fex run --rm --platform linux/amd64 alpine uname -m 動作確認 # x86_64 コンテナー podman run --rm --platform linux/amd64 alpine uname -m # → x86_64 # ARM64 コンテナー(リグレッションチェック) podman run --rm --platform linux/arm64 alpine uname -m # → aarch64 テスト結果:コミュニティ報告の17件を検証 Podmanコミュニティで報告されたx86_64エミュレーションの問題17件に対してテストを実施しました。 カテゴリー別の結果 カテゴリー テスト数 成功 成功率 QEMU SIGSEGV 5 5 100% ハング / フリーズ 5 5 100% ビルド失敗 5 2 40% Rosettaクラッシュ 1 0 0% 動作不良 1 1 100% 合計 17 13 76.5% Issue別の詳細 全17件の結果一覧(クリックで展開) # Issue 問題 元のエミュレーター FEX結果 1 #28169 rustc SIGSEGV QEMU 修正 2 #26036 PyArrow SIGSEGV QEMU 修正 3 #27320 jemalloc SIGSEGV QEMU 修正 4 #23219 gawk SIGSEGV (OpenWrt) QEMU 修正 5 #27601 redis-cluster SIGSEGV QEMU 修正 6 #27210 Arch Linuxハング Rosetta 修正 7 #27817 Fedoraシェルハング Rosetta 修正 8 #27799 Ubuntu 25.10ハング Rosetta 修正 9 #26572 Node.js Expressフリーズ Rosetta 修正 10 #23269 Next.jsビルドハング (SWC) Rosetta 修正 11 #24647 sudo BuildKit Rosetta 修正 12 #26656 su -l ログインシェル Rosetta 修正 13 #26881 Go buildパニック Rosetta タイムアウト 14 #25272 Angular ng buildハング QEMU Go/esbuild SIGSEGV 15 #26919 Go godumpビルド Rosetta Go FIPSクラッシュ 16 #27078 MSSQL 2022 SIGSEGV Rosetta ランタイムクラッシュ 17 #28184 MSSQL 2025 AVXクラッシュ Rosetta ランタイムクラッシュ すべてのハング/フリーズ問題(100%)およびすべてのQEMU SIGSEGV問題(100%)が修正されました。残る未解決の問題は、MSSQL Serverのランタイムクラッシュ(原因調査中)とGo 1.24+の crypto/internal/fips140 に起因するSIGSEGV(FEX-Emuの上流Issue)です。 各Issueの再現コマンドや詳細なログは、プロジェクトリポジトリの TEST-RESULTS.md を参照してください。 パフォーマンス MacBook Pro M1 Max、macOS 26.4.1、Podman 5.8で測定した結果です。 起動レイテンシー FEX-Emuによるコンテナー起動のオーバーヘッドは最小限です。 モード podman run --rm alpine echo hello 備考 ネイティブARM64 約2.1秒 ベースライン FEX-Emu x86_64(コールド) 約2.8秒 初回実行、JITコンパイル FEX-Emu x86_64(ウォーム) 約2.4秒 コードキャッシュ適用後 ウォーム時の約0.3秒のオーバーヘッドは、FEX-Emuの初期化(FEXServer起動、RootFSアクセス、binfmt_miscディスパッチ)によるものです。 JITコードキャッシュのウォームアップ JITコードキャッシュの蓄積には段階があります。初回実行(Run 1)ではフルJITコンパイルが発生するため最も遅く、コンパイル結果は非同期でディスクに書き込まれます。2回目(Run 2)ではキャッシュの書き込み処理が並行するため、初回より遅くなる場合もあります。3回目(Run 3)以降でキャッシュが十分に蓄積され、ネイティブに近い速度で動作するようになります。 以下は同一コンテナー内でコマンドを5回繰り返し実行した測定結果です(上位5件、Run 1とRun 4/5を比較)。 ワークロード イメージ 初回 4/5回目 スピードアップ python3 -c 'print(42)' python:3.12 3,371ms 111ms 30.4倍 g++ --version gcc:14-bookworm 1,328ms 45ms 29.5倍 perl -e 'print 42' perl:5 1,042ms 47ms 22.2倍 dpkg -l | wc -l ubuntu:24.04 1,280ms 69ms 18.6倍 rpm -V bash fedora:42 2,331ms 141ms 16.5倍 コードキャッシュはコンテナーのライフタイムに紐づくエフェメラルなもので、コンテナーを削除するとキャッシュは失われます。全32ワークロードの測定結果は、プロジェクトリポジトリの BENCHMARK.md を参照してください。 FEXの無効化(QEMUフォールバック) FEX-Emuはデフォルトで有効になっています。QEMUにフォールバックしたい場合は、VM内にマーカーファイルを作成して再起動します。 # FEXを無効化 → QEMUフォールバック podman machine ssh -- "sudo touch /etc/containers/disable-fex-emu" podman machine stop && podman machine start # FEXを再有効化 podman machine ssh -- "sudo rm /etc/containers/disable-fex-emu" podman machine stop && podman machine start アクティブなエミュレーターの確認: podman machine ssh -- "ls /proc/sys/fs/binfmt_misc/ | grep -E 'FEX|qemu'" # FEX有効時: FEX-x86 FEX-x86_64 qemu-aarch64_be # FEX無効時: qemu-aarch64_be qemu-i386 qemu-i486 qemu-x86_64 既知の制限事項 ケース 原因 回避策 MSSQL Server ランタイムクラッシュ(原因調査中) ネイティブx86_64ホストを使用 Go 1.24+ crypto crypto/internal/fips140 SIGSEGV Go 1.23以前を使用 Angular/Node (esbuild) esbuild (Go) SIGSEGV 上記Go cryptoと同じ原因 applehv プロバイダー libkrun が必須 プロバイダーを libkrun に設定 まとめ Rosettaの無効化とlibkrunへの移行により、Apple Silicon MacでのPodmanのx86_64エミュレーションはQEMUユーザーモードに戻らざるを得ない状況でした。 Podman FEXは、主要なコンテナーランタイムの中でPodmanが初めてFEX-Emuをネイティブに統合した取り組みと して、この課題に対する新たな選択肢を提供します。 コミュニティで報告された17件のx86_64エミュレーション問題のうち13件(76.5%)が解決され、特にハング/フリーズ問題とSIGSEGVクラッシュはすべて修正されています。JITコードキャッシュによる最大30倍のスピードアップも、繰り返しビルドや開発作業を行うユーザーにとって大きなメリットです。 Podmanは開かれたコミュニティであり、モジュラーなアーキテクチャーを採用しているため、今回のような新しい機能を実装しやすい構造になっています。以前のRosetta統合と同様に、FEX-Emuの統合もこのアーキテクチャーの恩恵を受けて実現できました。現在、FEX-Emu、Podman、およびPodman関連リポジトリへの各種PRを準備中です。 このプロジェクトは個人的な取り組みであり、Podmanの公式製品ではありません。ぜひプレビューを試していただき、フィードバックやバグ報告を Podman Discussions にお寄せください。報告の際には、macOSバージョン、Apple Siliconチップモデル、Podmanバージョン、利用プロバイダーの情報を添えていただけると助かります。 最終的にはPodmanへのFEX-Emuの実装に向けたPRに取り組んでいきます。 リンク Podman FEX リポジトリ Podman コミュニティディスカッション: FEX-Emu for Podman Machine FEX-Emu プロジェクト (GitHub) FEX-Emu 公式サイト Fedora 42 Changes/FEX PodmanでRosettaを使う【Podman v5.1】 Podman 5.6 Released — Rosetta Status Update libkrun + Rosetta investigation report テスト結果の詳細 (TEST-RESULTS.md) ベンチマーク結果 (BENCHMARK.md)
はじめに レッドハットのソリューションアーキテクトの森です。 前回の記事 では、Red Hat Connectivity Linkの概要とOpenShift Container Platformへのインストール方法を解説しました。 第2回となる今回は、実際にGatewayを作成し、各種Policyを適用してAPIを公開する手順を詳しく解説します。 具体的には、Kubernetes Gateway APIを使用したゲートウェイの作成、HTTPRouteの定義、そしてTLSPolicy、DNSPolicy、AuthPolicy、RateLimitPolicyの設定方法を扱います。 前回の記事はこちら rheb.hatenablog.com 本記事の前提条件 本記事では、以下の環境を前提として解説を進めます: DNSプロバイダー : AWS Route 53 TLS証明書 : Let's Encrypt(DNS-01チャレンジでAWS Route 53を使用) 必要なもの : AWSアカウント Route 53でホスト済みのドメイン(Hosted Zone) AWS Access Key ID と Secret Access Key 注 : Google Cloud DNS、Azure DNS、またはオンプレミスCoreDNSを使用する場合は、DNSPolicyとClusterIssuerの設定を適宜読み替えてください。詳細は Red Hat Connectivity Link 公式ドキュメント を参照してください。 主要コンポーネントの概要 本記事で扱う主要なコンポーネントの関係性を理解しておきましょう。 GatewayとHTTPRoute 図1: GatewayとHTTPRouteの関係 Gateway は、クラスター外部からのトラフィックを受け入れる入口として機能します。リスナー(ポート、プロトコル、ホスト名)を定義し、どのようなトラフィックを受け付けるかを制御します。 HTTPRoute は、Gatewayで受け付けたトラフィックを具体的なバックエンドサービスにルーティングするためのルールを定義します。パス、ヘッダー、メソッドなどの条件に基づいて、リクエストを適切なサービスに転送します。 重要な特徴として、 HTTPRouteはGatewayとは異なるネームスペースに配置可能 です。これにより、プラットフォームエンジニアがGatewayを管理し、アプリケーション開発者が各自のネームスペースでHTTPRouteを管理するという役割分担が可能になります。 Policy APIs 図2: Policy APIの概要 Connectivity Linkは、以下のPolicyをGatewayまたはHTTPRouteに適用できます: TLSPolicy : cert-managerと連携して、TLS証明書を自動的に発行・更新します。Let's EncryptやCA証明書など、さまざまな発行方法に対応しています。 DNSPolicy : AWS Route 53、Google Cloud DNS、Azure DNSなどのクラウドDNSプロバイダーと連携し、DNSレコードの自動作成とロードバランシングを実現します。ヘルスチェックと地理的負荷分散もサポートします。 AuthPolicy : Authorino(Envoy External Authorization)を使用して、API Key、JWT、OAuth 2.0、Keycloakなどの認証・認可を実現します。 RateLimitPolicy : Limitadorを使用して、IPアドレス、ユーザー、APIキーなどの単位でレート制限を適用します。単一クラスター環境ではインメモリモード、マルチクラスター環境ではRedis互換ストアを使用した分散レート制限が可能です。 これらのPolicyは、 Gatewayレベル で適用してデフォルトの動作を定義し、 HTTPRouteレベル で上書きすることで、アプリケーションごとに柔軟なカスタマイズが可能です。 環境セットアップ まず、作業に必要な環境変数を設定し、サンプルアプリケーションをデプロイします。 環境変数の設定 export KUADRANT_GATEWAY_NS=api-gateway export KUADRANT_GATEWAY_NAME=external export KUADRANT_DEVELOPER_NS=news-api export KUADRANT_AWS_ACCESS_KEY_ID=<your-aws-access-key> export KUADRANT_AWS_SECRET_ACCESS_KEY=<your-aws-secret-key> export KUADRANT_ZONE_ROOT_DOMAIN=<your-route53-domain> export KUADRANT_CLUSTER_ISSUER_NAME=letsencrypt-prod サンプルアプリケーションのデプロイ 本記事では、 Kuadrantコミュニティプロジェクト が提供する News API というサンプルアプリケーションを使用します。 News APIは、ニュース記事を管理するシンプルなRESTful APIで、以下のエンドポイントを提供します: POST /{category} - カテゴリに新しい記事を作成 GET /{category} - カテゴリの記事一覧を取得 GET /{category}/{id} - 特定の記事を取得 DELETE /{category}/{id} - 記事を削除 記事オブジェクトには以下のフィールドが含まれます: - id : UUID形式の一意な識別子(自動生成) - title : 記事のタイトル - body : 記事の本文(オプション) - date : 作成日時(自動生成) - author : 著者名(デフォルト: "Unknown") - user_id : ユーザーID(オプション) データは Pod内メモリ に保存されます(外部DBは不要)。 # ネームスペースの作成 oc create ns ${KUADRANT_DEVELOPER_NS} # News APIアプリケーションのデプロイ oc apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: news-api namespace: ${KUADRANT_DEVELOPER_NS} labels: app: news-api spec: replicas: 1 selector: matchLabels: app: news-api template: metadata: labels: app: news-api spec: containers: - name: news-api image: quay.io/kuadrant/authorino-examples:news-api env: - name: PORT value: "3000" ports: - containerPort: 3000 name: http --- apiVersion: v1 kind: Service metadata: name: news-api namespace: ${KUADRANT_DEVELOPER_NS} spec: selector: app: news-api ports: - name: http port: 80 protocol: TCP targetPort: 3000 EOF GatewayClassの作成 Gateway APIを使用するには、まずGatewayClassを作成する必要があります。GatewayClassは、どのコントローラー(この場合はIstio)がGatewayを管理するかを定義します。 # 既存のGatewayClassを確認 oc get gatewayclass # 存在しない場合は作成 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: istio spec: controllerName: istio.io/gateway-controller EOF GatewayClassが正常に作成されたことを確認します: oc get gatewayclass istio -o jsonpath='{.status.conditions[?(@.type=="Accepted")].status}' # 出力: True 注 : GatewayClassのステータスが True にならない場合は、OpenShift Service Mesh 3が正常にセットアップされているか確認してください。 DNS Provider Secretの設定 DNSPolicyを使用するには、まずDNSプロバイダーの認証情報を設定する必要があります。 # Gatewayネームスペースの作成 oc create ns ${KUADRANT_GATEWAY_NS} # AWS認証情報Secretの作成(Gatewayネームスペース用) oc -n ${KUADRANT_GATEWAY_NS} create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY # cert-managerネームスペース用 oc -n cert-manager create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY 重要 : Secretは必ずGatewayと同じネームスペースに作成してください。cert-manager用のSecretも別途必要です。 TLS証明書Issuerの設定 GatewayでHTTPSを使用するため、TLS証明書の発行者を設定します。 Let's Encryptを使用する場合 oc apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: ${KUADRANT_CLUSTER_ISSUER_NAME} spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: <your-email-address> privateKeySecretRef: name: letsencrypt-prod solvers: - dns01: route53: region: <your-aws_region> accessKeyIDSecretRef: name: aws-credentials key: AWS_ACCESS_KEY_ID secretAccessKeySecretRef: name: aws-credentials key: AWS_SECRET_ACCESS_KEY EOF Gatewayの作成 Kubernetes Gateway APIを使用して、Gatewayリソースを作成します。 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: ${KUADRANT_GATEWAY_NAME} namespace: ${KUADRANT_GATEWAY_NS} labels: kuadrant.io/gateway: "true" spec: gatewayClassName: istio listeners: - name: api hostname: "api.${KUADRANT_ZONE_ROOT_DOMAIN}" port: 443 protocol: HTTPS allowedRoutes: namespaces: from: All tls: mode: Terminate certificateRefs: - name: api-${KUADRANT_GATEWAY_NAME}-tls kind: Secret EOF 主要フィールドの説明 gatewayClassName : istio - OpenShift Service Mesh (Istio) を使用 listeners : Gatewayが受け付けるトラフィックの定義 allowedRoutes.namespaces.from : All - すべてのネームスペースからのルートを許可 tls.mode : Terminate - GatewayでTLSを終端 TLSPolicyの適用 GatewayのHTTPSリスナーに自動的にTLS証明書を発行・更新するため、TLSPolicyを適用します。 oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: TLSPolicy metadata: name: ${KUADRANT_GATEWAY_NAME}-tls namespace: ${KUADRANT_GATEWAY_NS} spec: targetRef: name: ${KUADRANT_GATEWAY_NAME} group: gateway.networking.k8s.io kind: Gateway issuerRef: group: cert-manager.io kind: ClusterIssuer name: ${KUADRANT_CLUSTER_ISSUER_NAME} EOF TLSPolicyは、Gatewayのリスナーから証明書が必要なホスト名を検出し、cert-managerを使用して自動的にTLS証明書を発行・更新します。 注 : Let's EncryptによるTLS証明書の発行には、DNS-01チャレンジの完了まで数分かかる場合があります。 Enforced ステータスが certificate is not ready: DoesNotExist - Issuing certificate と表示される場合は、証明書発行中ですので、しばらく待ってから再度確認してください。 HTTPRouteの定義 Gatewayを通じてバックエンドアプリケーションにトラフィックをルーティングするため、HTTPRouteを定義します。 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: news-api namespace: ${KUADRANT_DEVELOPER_NS} labels: app: news-api spec: parentRefs: - name: ${KUADRANT_GATEWAY_NAME} namespace: ${KUADRANT_GATEWAY_NS} hostnames: - "api.${KUADRANT_ZONE_ROOT_DOMAIN}" rules: - matches: - path: type: PathPrefix value: "/" backendRefs: - name: news-api port: 80 EOF 主要フィールドの説明 parentRefs : このルートが接続するGatewayの参照(クロスネームスペース参照が可能) hostnames : このルートが処理するホスト名のリスト rules.matches : リクエストのマッチング条件(method、path、headers、queryParamsなど) backendRefs : トラフィックを転送するバックエンドサービス DNSPolicyの適用 外部からのトラフィックをGatewayにルーティングするため、DNSPolicyを設定します。 oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: DNSPolicy metadata: name: ${KUADRANT_GATEWAY_NAME}-dnspolicy namespace: ${KUADRANT_GATEWAY_NS} spec: targetRef: name: ${KUADRANT_GATEWAY_NAME} group: gateway.networking.k8s.io kind: Gateway healthCheck: failureThreshold: 3 interval: 1m path: /health loadBalancing: defaultGeo: true geo: GEO-NA weight: 120 providerRefs: - name: aws-credentials EOF 主要フィールドの説明 healthCheck : ヘルスチェック設定(failureThreshold、interval、path) loadBalancing : ロードバランシング戦略(geo、weight) providerRefs : DNSプロバイダーの認証情報Secret 注 : loadBalancing.geo は、使用しているAWSリージョンに応じて変更してください。 GEO-NA (北米): us-east-* , us-west-* , ca-central-* リージョン GEO-EU (ヨーロッパ): eu-west-* , eu-central-* , eu-north-* リージョン GEO-AP (アジア太平洋): ap-northeast-* , ap-southeast-* , ap-south-* リージョン GEO-SA (南米): sa-east-* リージョン 注 : DNSレコードの作成には数分かかる場合があります。 図3: DNS Policy より生成された DNS Records 基本的な動作確認 Gateway、TLSPolicy、HTTPRoute、DNSPolicyが正常に動作していることを確認します。 DNS解決の確認 # DNSレコードを確認 nslookup api.${KUADRANT_ZONE_ROOT_DOMAIN} 期待される出力例: Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: api.sandbox1479.opentlc.com canonical name = klb.api.sandbox1479.opentlc.com. klb.api.sandbox1479.opentlc.com canonical name = geo-na.klb.api.sandbox1479.opentlc.com. geo-na.klb.api.sandbox1479.opentlc.com canonical name = a95f50f4cfe964480a3619bd3bccd4f3-1637257742.us-east-2.elb.amazonaws.com. Name: a95f50f4cfe964480a3619bd3bccd4f3-1637257742.us-east-2.elb.amazonaws.com Address: 13.58.10.75 Name: a95f50f4cfe964480a3619bd3bccd4f3-1637257742.us-east-2.elb.amazonaws.com Address: 13.58.12.24 DNSPolicyによって作成されたCNAMEレコードと、最終的にAWS ELBのIPアドレスに解決されることを確認してください。 ヘルスチェックエンドポイントのテスト curl -ik https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/health 期待される出力例: HTTP/2 200 content-type: application/json server: istio-envoy date: Thu, 23 Apr 2026 09:22:58 GMT content-length: 2 x-envoy-upstream-service-time: 2 [] 注 : -i オプションでHTTPステータスコードとレスポンスヘッダーを確認できます。 HTTP/2 200 と server: istio-envoy が表示されていれば、Gateway、TLSPolicy、HTTPRoute、DNSPolicyが正常に動作しています。News APIの /health エンドポイントは空の配列 [] を返します。 News APIへのアクセステスト カテゴリの記事一覧を取得してみます: curl -k https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力例: [] 空の配列が返されます。まだ記事が投稿されていないためです。 試しに記事を投稿してみましょう: curl -ik -X POST \ -H "Content-Type: application/json" \ -d '{"title":"First Article","content":"This is a test article"}' \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力例: HTTP/2 200 content-type: application/json server: istio-envoy date: Thu, 23 Apr 2026 09:24:08 GMT content-length: 150 ... {"id":"69ebc38b-e24f-4108-864b-34cae563a665","title":"First Article","body":null,"date":"2026-04-23 09:24:08 +0000","author":"Unknown","user_id":null} 注 : News APIは記事作成時にUUID形式のIDを自動生成します。 body 、 date 、 author 、 user_id フィールドも自動的に追加されます。 再度一覧を取得すると、投稿した記事が表示されます: curl -k https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力例: [{ " id ":" 69ebc38b-e24f-4108-864b-34cae563a665 "," title ":" First Article "," body ": null ," date ":" 2026-04-23 09:24:08 +0000 "," author ":" Unknown "," user_id ": null }] この時点では、認証やレート制限は設定されていないため、すべてのリクエストが成功します。 ポリシーの階層と優先順位 Connectivity Linkでは、ポリシーを複数のレベルで定義できます。 defaultsとoverridesの違い defaults : HTTPRouteレベルのポリシーで上書き可能 overrides : HTTPRouteレベルのポリシーより優先(強制適用) spec : defaults : # HTTPRouteで上書き可能 limits : "default-limit" : rates : - limit : 100 window : 1m overrides : # HTTPRouteで上書き不可(強制適用) limits : "global-limit" : rates : - limit : 1000 window : 1h AuthPolicyの設定 Gatewayレベルでデフォルトの認証・認可ポリシーを設定します。 oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: ${KUADRANT_GATEWAY_NAME}-auth namespace: ${KUADRANT_GATEWAY_NS} spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: ${KUADRANT_GATEWAY_NAME} defaults: rules: authorization: deny-all: opa: rego: "allow = false" response: unauthorized: headers: "content-type": value: application/json body: value: | { "error": "Forbidden", "message": "Access denied by default. Please configure a specific auth policy." } EOF この設定により、すべてのリクエストはデフォルトで拒否されます。各HTTPRouteで個別のAuthPolicyを設定することで、この動作を上書きできます。 AuthPolicyの動作確認 AuthPolicyを適用すると、すべてのエンドポイントへのアクセスが拒否されるようになります。 curl -k https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力例: { " error ": " Forbidden ", " message ": " Access denied by default. Please configure a specific auth policy. " } ヘルスチェックエンドポイントも同様に拒否されます: curl -k https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/health 期待される出力例: { " error ": " Forbidden ", " message ": " Access denied by default. Please configure a specific auth policy. " } RateLimitPolicyの設定 APIを保護するため、レート制限ポリシーを設定します。 oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: RateLimitPolicy metadata: name: ${KUADRANT_GATEWAY_NAME}-rlp namespace: ${KUADRANT_GATEWAY_NS} spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: ${KUADRANT_GATEWAY_NAME} defaults: limits: "low-limit": rates: - limit: 5 window: 10s EOF この例では、10秒あたり5リクエストの制限を設定しています。これはテスト用の厳しい設定です。本番環境では、想定されるトラフィックに応じた適切な値(例: 100リクエスト/分、1000リクエスト/時間など)を設定してください。 RateLimitPolicyの動作確認 連続してリクエストを送信し、レート制限が機能することを確認します。 現在の設定では、10秒あたり5リクエストの制限があるため、6回目以降のリクエストで429エラーが返されるはずです。 for i in {1..10}; do curl -k --write-out " - Response: %{http_code}\n" --silent --output /dev/null \ "https://api.$KUADRANT_ZONE_ROOT_DOMAIN/technology" | \ grep -E --color "\b(429)\b|$" sleep 0.1 done 期待される出力例: - Response: 403 - Response: 403 - Response: 403 - Response: 403 - Response: 403 - Response: 429 ← 6回目以降はレート制限 - Response: 429 - Response: 429 - Response: 429 - Response: 429 制限を超えると、HTTP 429 (Too Many Requests) が返されます。10秒待つと再び403が返されます。 HTTPRouteレベルでのポリシーオーバーライド ここまでGatewayレベルでデフォルトポリシーを設定してきました。次に、アプリケーション開発者がHTTPRouteレベルで独自のポリシーを設定し、Gatewayレベルのデフォルト設定を上書きする方法を説明します。 AuthPolicyのオーバーライド - API Key認証の追加 Gatewayではdeny-allのAuthPolicyを設定していますが、News APIアプリケーションに対してAPI Key認証を有効にします。 まず、API Keyを含むSecretを作成します: oc apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: api-keys namespace: kuadrant-system labels: authorino.kuadrant.io/managed-by: authorino app: news-api stringData: api_key: "secret-key-12345" type: Opaque EOF 重要 : Secretは、 Kuadrant CRが配置されているネームスペース (本記事の場合は kuadrant-system )に作成する必要があります。 次に、HTTPRouteレベルでAuthPolicyを作成します: oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: AuthPolicy metadata: name: news-api-auth namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: news-api rules: authentication: api-key: apiKey: selector: matchLabels: app: news-api credentials: authorizationHeader: prefix: APIKEY authorization: allow-all: opa: rego: "allow = true" response: unauthenticated: headers: "content-type": value: application/json body: value: | { "error": "Unauthenticated", "message": "Valid API key is required. Use header: Authorization: APIKEY <your-key>" } EOF この設定により、News APIエンドポイントへのアクセスにAPI Keyが必要になります。 AuthPolicyの動作確認 API Keyなしでアクセス(401エラー): curl -ik https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力例: HTTP /2 401 content - type : application / json x - ext - auth - reason : credential not found content - length : 121 date : Thu , 23 Apr 2026 09:32:01 GMT server : istio - envoy { " error ": " Unauthenticated ", " message ": " Valid API key is required. Use header: Authorization: APIKEY <your-key> " } API Keyありでアクセス(成功): curl -ik -H "Authorization: APIKEY secret-key-12345" \ https://api.${KUADRANT_ZONE_ROOT_DOMAIN}/technology 期待される出力例: HTTP/2 200 content-type: application/json ... [{"id":"69ebc38b-e24f-4108-864b-34cae563a665","title":"First Article","body":null,"date":"2026-04-23 09:24:08 +0000","author":"Unknown","user_id":null}] 注 : HTTPステータスコードが 200 で、基本的な動作確認セクションで投稿した「First Article」が表示されていれば、API Key認証が成功しています。 RateLimitPolicyのオーバーライド - ユーザー別の制限設定 Gatewayでは10秒あたり5リクエストの制限を設定していましたが、News APIアプリケーションに対して、認証されたユーザーごとに異なるレート制限を適用します。 oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: RateLimitPolicy metadata: name: news-api-ratelimit namespace: ${KUADRANT_DEVELOPER_NS} spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: news-api limits: "authenticated-user-limit": rates: - limit: 10 window: 1m counters: - expression: auth.identity.api_key EOF この設定により、以下が実現されます: 各API Keyごとに1分あたり10リクエストの制限 すべてのエンドポイントに適用 Gatewayレベルの制限(10秒5リクエスト)は上書きされます RateLimitPolicyの動作確認 連続してリクエストを送信し、ユーザー単位のレート制限を確認: # 20回連続でリクエストを送信 for i in {1..20}; do curl -k -H "Authorization: APIKEY secret-key-12345" \ --write-out " - Response: %{http_code}\n" --silent --output /dev/null \ "https://api.$KUADRANT_ZONE_ROOT_DOMAIN/technology" | \ grep -E --color "\b(429)\b|$" sleep 0.1 done 最初の10リクエストは200で成功し、11回目以降は429 (Too Many Requests) が返されます。1分待つと再び200が返されます。 ポリシーオーバーライドのまとめ HTTPRouteレベルでポリシーを設定することで、以下が可能になります: Gatewayレベル(プラットフォームエンジニア): - すべてのアプリケーションに適用されるデフォルトセキュリティポリシー - 組織全体のセキュリティ要件を強制 - overrides を使用して、絶対に上書きできないルールを設定 HTTPRouteレベル(アプリケーション開発者): - アプリケーション固有の認証方式を実装 - サービスレベルに応じたレート制限を設定 - ビジネスロジックに基づいた柔軟なポリシー適用 この階層的なアプローチにより、セキュリティとガバナンスを保ちつつ、開発者に必要な柔軟性を提供できます。 まとめ 本記事では、Red Hat Connectivity LinkでGatewayを作成し、各種Policyを適用する手順を解説しました。 本記事で学んだこと 環境セットアップ : 環境変数の設定とサンプルアプリケーションのデプロイ DNS Provider Secretの設定 : AWS Route 53認証情報の設定 TLS証明書Issuerの設定 : cert-managerを使用した証明書発行者の設定 Gatewayの作成 : Kubernetes Gateway APIを使用したゲートウェイの定義 Gatewayレベルのポリシー適用 : TLSPolicy、AuthPolicy、RateLimitPolicy、DNSPolicyの設定 HTTPRouteの定義 : バックエンドサービスへのルーティング設定 HTTPRouteレベルのポリシーオーバーライド : アプリケーション固有のAuthPolicyとRateLimitPolicyの設定 動作確認 : 各ポリシーの動作テスト 次のステップ 次回以降の記事では、以下のようなトピックを扱う予定です: 高度な認証設定 : JWT、OAuth2.0、Keycloak連携 観測性の設定 : メトリクス、ログ、トレーシングの統合 TokenRateLimitPolicy : LLM APIなどのトークンベースのレート制限