赤帽エンジニアブログ 2024-03-19T08:22:20+09:00 rheb Hatena::Blog hatenablog://blog/10257846132643728507 Migration Toolkit for Applicationsを使って組織のシステムのクラウドへの移行を促進させる 2.インストール編 hatenablog://entry/6801883189091669833 2024-03-19T08:22:20+09:00 2024-03-19T08:22:20+09:00 OpenShift AppDev SSAの瀬戸です。 Migration Toolkit for Applications(以下MTA)という製品をご存知でしょうか?Red Hatが出している静的解析ツールで、古いバージョンのJBoss EAPやOpenJDKなどのミドルウェアで動いているアプリケーションを最新のミドルウェア上で動作させるために必要な修正を洗い出してくれます。 実は、それだけではなく、組織のアプリケーションのモダナイゼーションのサポートもしてくれます。この記事では3回にわけて、どういった機能があるのかから実際の使い方をご紹介したいと思います。 ちなみに、MTAは無償でお使いいた… <p>OpenShift AppDev SSAの瀬戸です。</p> <p>Migration Toolkit for Applications(以下MTA)という製品をご存知でしょうか?Red Hatが出している静的解析ツールで、古いバージョンのJBoss EAPやOpenJDKなどのミドルウェアで動いているアプリケーションを最新のミドルウェア上で動作させるために必要な修正を洗い出してくれます。</p> <p>実は、それだけではなく、組織のアプリケーションのモダナイゼーションのサポートもしてくれます。この記事では3回にわけて、どういった機能があるのかから実際の使い方をご紹介したいと思います。</p> <p>ちなみに、MTAは無償でお使いいただくことが可能です。</p> <p>前回はMTAの概要を説明しました。今回は使うまでの準備(インストール)をしたいと思います。</p> <p>前回の記事はこちら。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2024%2F03%2F18%2F100204" title="Migration Toolkit for Applicationsを使って組織のシステムのクラウドへの移行を促進させる 1.概要編 - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2024/03/18/100204">rheb.hatenablog.com</a></cite></p> <p>この記事では OpenShift 4.15/MTA 7.0.1を使用しています。バージョンによって多少挙動が違う可能性がありますので必要に応じて使用されるバージョンのマニュアルをご参照ください。</p> <p>MTAの全機能を使うためにはOpenShiftが必要です。また、デフォルトで4vCPUと8Gバイト以上のメモリ割り当て、150 Gバイト以上の永続ストレージの割り当て<a href="#f-4fd6f3f2" id="fn-4fd6f3f2" name="fn-4fd6f3f2" title="設定を見直すことで最低40Gバイト以上の永続ストレージで動作させることが可能ですが、設定変更方法については割愛します。">*1</a>と、インストール時に <code>cluster-admin</code> 権限が必要になります。詳細についてはドキュメントを参照してください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fmigration_toolkit_for_applications%2F7.0%2Fhtml%2Fuser_interface_guide%2Fmta-7-installing-web-console-on-openshift_user-interface-guide" title="第3章 Migration Toolkit for Applications ユーザーインターフェイスのインストール Migration Toolkit for Applications 7.0 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/migration_toolkit_for_applications/7.0/html/user_interface_guide/mta-7-installing-web-console-on-openshift_user-interface-guide">access.redhat.com</a></cite></p> <p>OpenShiftのサブスクリプションが足りていない場合は、OpenShift Localにインストールすることも可能です。OpenShift LocalはHyper-V上にインストールできるOpenShiftの簡易的なお試し環境です。 ただ、Windows上のOpenShift Local 4.14.2で試したところ、デフォルトのメモリ割り当てが小さするのと、デフォルトで作成される仮想ディスクファイル(vhdx)が小さすぎて拡張が行えない問題が発生しました。手動でメモリ割り当て<a href="#f-e0a76b3c" id="fn-e0a76b3c" name="fn-e0a76b3c" title="余裕をもって20Gまで増やしました。">*2</a>や、vhdxのファイルサイズ<a href="#f-545c57fb" id="fn-545c57fb" name="fn-545c57fb" title="余裕をもって200Gまで増やしました。">*3</a>を増やしてあげる必要がありました。ご注意ください。 メモリ割り当ての増やし方は特殊な方法が必要になるので以下のドキュメントを参照してください。vhdxの容量についてはHyper-Vの管理コンソールから増やすことが可能です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fmigration_toolkit_for_applications%2F7.0%2Fhtml%2Fuser_interface_guide%2Fmemory_requirements_for_running_mta_on_red_hat_openshift_local" title="3.4. Red Hat OpenShift Local で MTA を実行するためのメモリー要件 Migration Toolkit for Applications 7.0 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/migration_toolkit_for_applications/7.0/html/user_interface_guide/memory_requirements_for_running_mta_on_red_hat_openshift_local">access.redhat.com</a></cite></p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fred_hat_openshift_local%2F2.25%2Fhtml-single%2Fgetting_started_guide%2Findex%23configuring-the-instance_gsg" title="スタートガイド Red Hat OpenShift Local 2.25 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/red_hat_openshift_local/2.25/html-single/getting_started_guide/index#configuring-the-instance_gsg">access.redhat.com</a></cite></p> <p>OpenShift Localについては以下のページからダウンロードが可能です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fconsole.redhat.com%2Fopenshift%2Fcreate%2Flocal" title="Hybrid Cloud Console" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://console.redhat.com/openshift/create/local">console.redhat.com</a></cite></p> <h3 id="MTAのインストール">MTAのインストール</h3> <p>MTAはOpenShift上のOperatorHubからインストールすることができます。 <code>cluster-admin</code> 権限を持ったユーザーでログインし、右のメニューからOperator→OperatorHubを選択し、Migration Toolkit for Applicationsで検索をしてください。</p> <p><figure class="figure-image figure-image-fotolife" title="OperatorHub"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101318.png" width="1089" height="766" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>OperatorHub</figcaption></figure></p> <p>選択するとインストール画面が表示されるので、そのままインストールを押します。</p> <p><figure class="figure-image figure-image-fotolife" title="インストール画面"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101337.png" width="1078" height="724" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>インストール画面</figcaption></figure></p> <p>次の画面でもそのままインストールボタンを押します。</p> <p> <figure class="figure-image figure-image-fotolife" title="インストール設定"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101355.png" width="996" height="1111" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>インストール設定</figcaption></figure></p> <p>そのままインストールがはじまります。</p> <p><figure class="figure-image figure-image-fotolife" title="インストール中"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101413.png" width="648" height="258" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>インストール中</figcaption></figure></p> <p>そのうち、Tackleの作成ボタンが表示されます。必要な依存リソースなのでTackleの作成ボタンを押します。</p> <p> <figure class="figure-image figure-image-fotolife" title="Tackleのインストール"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101427.png" width="633" height="476" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>Tackleのインストール</figcaption></figure></p> <p>Tackleの作成画面が開くので、そのまま作成ボタンを押します。</p> <p><figure class="figure-image figure-image-fotolife" title="Tackleの作成"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101447.png" width="969" height="660" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>Tackleの作成</figcaption></figure></p> <p><strong>10分ぐらい待つと</strong>環境が完成します。Developerパースペクティブからトポロジーを開いて、openshift-mtaプロジェクトを選択します。</p> <p><figure class="figure-image figure-image-fotolife" title="トポロジーの選択"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101508.png" width="974" height="573" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>トポロジーの選択</figcaption></figure></p> <p>インストールが完了している場合は以下のように表示されます。すべてのpodが青くなっている 事を確認したうえで、mta-uiのURLを開くを選択します。</p> <p><figure class="figure-image figure-image-fotolife" title="MTAのURLを開く(mta-uiと名前の付いたpodの右上のボタン)"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101537.png" width="1090" height="590" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>MTAのURLを開く(mta-uiと名前の付いたpodの右上のボタン)</figcaption></figure></p> <p>※いつまで待っても青くならない場合はリソースが不足していることが考えられます。メモリや永続化ボリュームの割り当て量が問題ないことを確認してください。</p> <p>クリックするとログイン画面が表示されます。</p> <p>Admin / Passw0rd! でログインすることができます。</p> <p><figure class="figure-image figure-image-fotolife" title="ログイン"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101635.png" width="886" height="576" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ログイン</figcaption></figure></p> <p>初回はパスワードの変更画面が表示されますので、好きなパスワードを入力してください。</p> <p><figure class="figure-image figure-image-fotolife" title="パスワード変更画面"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101651.png" width="886" height="766" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>パスワード変更画面</figcaption></figure></p> <p>そうすることで、ログインすることができました。</p> <p><figure class="figure-image figure-image-fotolife" title="ログイン後初期画面"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318101723.png" width="886" height="337" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ログイン後初期画面</figcaption></figure></p> <h3 id="まとめ">まとめ</h3> <p>これでMTAを使用し始める準備が整いました。次回は実際にMTAを操作していきます。</p> <div class="footnote"> <p class="footnote"><a href="#fn-4fd6f3f2" id="f-4fd6f3f2" name="f-4fd6f3f2" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">設定を見直すことで最低40Gバイト以上の永続ストレージで動作させることが可能ですが、設定変更方法については割愛します。</span></p> <p class="footnote"><a href="#fn-e0a76b3c" id="f-e0a76b3c" name="f-e0a76b3c" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">余裕をもって20Gまで増やしました。</span></p> <p class="footnote"><a href="#fn-545c57fb" id="f-545c57fb" name="f-545c57fb" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">余裕をもって200Gまで増やしました。</span></p> </div> megascus Migration Toolkit for Applicationsを使って組織のシステムのクラウドへの移行を促進させる 1.概要編 hatenablog://entry/6801883189091665675 2024-03-18T10:02:04+09:00 2024-03-19T08:22:54+09:00 OpenShift AppDev SSAの瀬戸です。 Migration Toolkit for Applications(以下MTA)という製品をご存知でしょうか?Red Hatが出している静的解析ツールで、古いバージョンのJBoss EAPやOpenJDKなどのミドルウェアで動いているアプリケーションを最新のミドルウェア上で動作させるために必要な修正を洗い出してくれます。 実は、それだけではなく、組織のアプリケーションのモダナイゼーションのサポートもしてくれます。この記事では3回にわけて、どういった機能があるのかから実際の使い方をご紹介したいと思います。 ちなみに、MTAは無償でお使いいた… <p>OpenShift AppDev SSAの瀬戸です。</p> <p><a href="https://developers.redhat.com/products/mta/overview">Migration Toolkit for Applications</a>(以下MTA)という製品をご存知でしょうか?Red Hatが出している静的解析ツールで、古いバージョンのJBoss EAPやOpenJDKなどのミドルウェアで動いているアプリケーションを最新のミドルウェア上で動作させるために必要な修正を洗い出してくれます。</p> <p>実は、それだけではなく、組織のアプリケーションのモダナイゼーションのサポートもしてくれます。この記事では3回にわけて、どういった機能があるのかから実際の使い方をご紹介したいと思います。</p> <p>ちなみに、MTAは無償でお使いいただくことが可能です。</p> <h3 id="Red-Hatの6R">Red Hatの6R</h3> <p>Red Hatはモダナイゼーションの移行戦略として6Rを提唱しています。次のようなものです。</p> <p><figure class="figure-image figure-image-fotolife" title="Red Hatの6R"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318095133.png" width="886" height="437" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>Red Hatの6R</figcaption></figure></p> <p>モダナイゼーションの移行戦略といったときに単一のシステムの移行を想像されるでしょうか?</p> <p>このツールは単一のシステムを移行させるのに必要な情報を提供するだけではなく、企業内の複数のシステムを移行する際にどのシステムから移行するべきかを検討する判断材料を提供してくれます。</p> <p>現在の企業システムは複雑に絡み合っています。新しく作るシステムをクラウド上にデプロイすることは簡単ですが、古くから動作しているシステムをクラウドに移行しようとする場合は、システムの状態や依存関係を把握したうえで、優先順位をつけて順序良くクラウドに移行する必要が出てきます。</p> <p>まれにすべての基盤システムを一度に更改し、数年かけて基盤入れ替えを行ってしまうような企業もありますが、多くの企業にとっては現実的ではありません。 また、移行を検討する中では、実は移行をする必要がないシステム(数年後には不要になるシステム等)が見つかることもあります。少なくとも、何も考えずに全部のシステムをクラウドに移行するべきというわけではありません。移行するための費用の無駄となります。</p> <h3 id="MTAの機能">MTAの機能</h3> <p>MTAの全機能を使うためにはOpenShift上で動作させる必要があります。 。 OpenShift上で動作させるMTAには次の機能が含まれます。</p> <ul> <li>移行対象の管理 - 組織がクラウドに移行しようとしているアプリケーションを一覧化し、どのアプリケーションの移行が必要なのかを管理できます。</li> <li>移行対象の優先順位付け - アプリケーションの利用状況や開発、運用の情報をまとめ、状況に基づいた意思決定を行えるようにし、移行と最新化の優先順位をつけます。</li> <li>アプリケーションの静的解析 - 複数のオープンソースツールに込められた知見を活用し、事前にどのような修正が必要なのか一覧を作成し、移行方法を解析します。</li> </ul> <p>このうちアプリケーションの静的解析に関しては以前から持っている機能となり、以前もJBoss EAPの最新化の記事でご紹介をさせていただいたことがあります。</p> <h4 id="移行対象の管理">移行対象の管理</h4> <p>企業は複数のアプリケーションを保持しています。単一のアプリケーションしか持っていない企業はごく少数でしょう。どのようなアプリケーションがあるのかを一覧として管理することができます。それぞれのアプリケーションには依存関係があるはずです、依存関係や、そのアプリケーションが持っている特性をメタデータとして管理することができます。どのビジネスサービスからどのアプリケーションを使用しているのかをリンクすることもできます。</p> <p><figure class="figure-image figure-image-fotolife" title="移行対象の管理"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318100029.png" width="1200" height="619" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>移行対象の管理</figcaption></figure></p> <h4 id="移行対象の優先順位付け">移行対象の優先順位付け</h4> <p>アプリケーションの状態をアンケートとして入力することにより、アプリケーションを取り巻く環境がクラウド化に適しているのかを評価します。 アプリケーションの使用状況や、クラウド上でベストプラクティスとされている手法が運用上すでに行われているのかを評価し、クラウドへの移行優先度、移行難易度を推定します。</p> <p>その中で、移行が簡単だと思われるものや、ビジネス価値が高いものについては移行の優先順位が高くなりますし、どれだけビジネス価値が高かろうとも、移行難易度が極限まで高ければ移行しないという判断を行うことができます。</p> <p><figure class="figure-image figure-image-fotolife" title="移行対象の優先順位付け"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318100053.png" width="1200" height="619" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>移行対象の優先順位付け</figcaption></figure></p> <p>このアンケートは組み込みのものを使う事もできますし、お客様でカスタマイズすることも可能です。お客様固有の事情がある場合、例えば、レガシーな社内フレームワークを使っており、リプレイスが必要となっている場合、などはアンケートに項目を追加する事で社内システムの評価項目に加えることもできます。その他、どのような質問が必要なのかについては弊社コンサルタントがお手伝いすることもできますので、必要に応じてお問い合わせください。</p> <h4 id="アプリケーションの静的解析">アプリケーションの静的解析</h4> <p>第三者目線によるアプリケーションの解析を行い、アプリケーションにどういった修正が必要なのかを洗い出してくれます。すべてを洗い出してくれるわけではありませんが、主だった修正を簡単に潰しこむことが出来るようになります。アンケートはどうしても担当者の思い込みが入り込みますが、この機能の場合は思い込みが入り込むことはありません。移行が簡単だと思ってたけれども実は大変だったといったことを防ぐことができます。</p> <p>また、クラウドに移行したいけれども、移行順序の評価までは必要がないが、具体的にどういう修正が必要なのかがわからないという方はこちらを動作させるだけでも助けになります。 ただし、現時点ではJava言語のみサポートされております。他言語についても逐次対応予定なので、少々お待ちください。<a href="#f-dd2a7cea" id="fn-dd2a7cea" name="fn-dd2a7cea" title="Go言語がtech preview中、.NET、TypeScript、Pythonのサポートがマイナーアップデートで提供予定">*1</a></p> <p><figure class="figure-image figure-image-fotolife" title="静的解析"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240318/20240318100123.png" width="1200" height="619" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>静的解析</figcaption></figure></p> <p>この機能のみコマンドライン版で動作させることができます。実際にクラウドへの移行のためのアプリケーションの修正を始めた後はOpenShift上から動作させるのに比べてコマンドラインから動作させる方が簡単なので、そちらから使用する事が推奨です。</p> <h3 id="まとめ">まとめ</h3> <p>ここまででMTAが持っている機能を一通り紹介しました。 次回は、MTAをインストールして実際に使える状態にします。</p> <p>次回の記事はこちらから。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2024%2F03%2F19%2F082220" title="Migration Toolkit for Applicationsを使って組織のシステムのクラウドへの移行を促進させる 2.インストール編 - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2024/03/19/082220">rheb.hatenablog.com</a></cite></p> <div class="footnote"> <p class="footnote"><a href="#fn-dd2a7cea" id="f-dd2a7cea" name="f-dd2a7cea" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">Go言語がtech preview中、.NET、TypeScript、Pythonのサポートがマイナーアップデートで提供予定</span></p> </div> megascus Event-Driven Ansible と IBM Turbonomic / Instana の連携 hatenablog://entry/6801883189085190010 2024-03-07T15:10:59+09:00 2024-03-08T10:18:27+09:00 皆さんこんにちは、Red Hat の岡野です。 前回 Event-Driven Ansible のお試し方法についてご紹介させていただきましたが、今回は一歩踏み込んで、サードパーティ製のアプリケーションと連携した動作についてご紹介します。 Event-Driven Ansible (EDA) は以下のような様々なイベントソースと連携し動作します。 ・Zabbix ・IBM Instana, Turbonomic ・Dynatrace ・CrowdStrike ・AWS Cloudtrail, SQS ・Azure Service Bus など 今回この中から、IBM 社の Turbonomic… <p>皆さんこんにちは、Red Hat の岡野です。</p> <p>前回 Event-Driven Ansible のお試し方法についてご紹介させていただきましたが、今回は一歩踏み込んで、サードパーティ製のアプリケーションと連携した動作についてご紹介します。</p> <p>Event-Driven Ansible (EDA) は以下のような様々なイベントソースと連携し動作します。</p> <p>・Zabbix<br/> ・IBM Instana, Turbonomic<br/> ・Dynatrace<br/> ・CrowdStrike<br/> ・AWS Cloudtrail, SQS<br/> ・Azure Service Bus など</p> <p>今回この中から、IBM 社の Turbonomic および Instana との連係動作についてご紹介したいと思います。</p> <h3 id="IBM-Turbonomic-と-Instana">IBM Turbonomic と Instana</h3> <p>IBM Instanaは、WebSpere や DB2、Oracle など従来型アプリケーションから最新のクラウドネイティブアプリケーションにも対応したアプリケーション・パフォーマンスの管理ソリューションです。分散トレーシングによりサービスの依存関係を自動的に可視化。アプリケーションを構成する各マイクロサービスのアクセスレイテンシレベルまで可視化されます。</p> <p>この可視化された情報を元に AI を活用してサービスレベルの監視を行い、アプリケーションの日時や季節性も考慮した、</p> <p>『普段と異なるアプリケーションの状態』</p> <p>を即座に検知。必要に応じ、動的なアラートを発砲することが可能となっています。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.ibm.com%2Fjp-ja%2Fproducts%2Finstana%3Futm_content%3DSRCWW%26p1%3DSearch%26p4%3D43700078039587241%26p5%3De%26gad_source%3D1%26gclid%3DEAIaIQobChMIx9_R3pDhhAMVssNMAh1dwwYuEAAYASAAEgIcw_D_BwE%26gclsrc%3Daw.ds" title="IBM Instana Observability APMソリューション - 日本" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.ibm.com/jp-ja/products/instana?utm_content=SRCWW&p1=Search&p4=43700078039587241&p5=e&gad_source=1&gclid=EAIaIQobChMIx9_R3pDhhAMVssNMAh1dwwYuEAAYASAAEgIcw_D_BwE&gclsrc=aw.ds">www.ibm.com</a></cite></p> <p>一方、Turbonomic はリソースの利用状況の把握と最適化を行うことが出来ます。オンプレやパブリッククラウド含めたアプリケーションが稼働するインフラの把握と、リソースの利用状況を自動的に検知しグラフィカルに可視化。</p> <p>『リソースの過不足をリアルタイムかつ継続的に監視』することにより、アプリケーションに影響を与え得るリソース上の制約、将来の予測分析などをAIを用いて把握した上で、必要があればインスタンスの『スケールイン/スケールアウト』、『スケールアップ/ダウン』を行う機能を提供します。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.ibm.com%2Fjp-ja%2Fproducts%2Fturbonomic%3Futm_content%3DSRCWW%26p1%3DSearch%26p4%3D43700074935681884%26p5%3Dp%26gad_source%3D1%26gclid%3DEAIaIQobChMI68bj_I_hhAMV4wh7Bx3ZYgRoEAAYASAAEgKtW_D_BwE%26gclsrc%3Daw.ds" title="IBM Turbonomic " class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.ibm.com/jp-ja/products/turbonomic?utm_content=SRCWW&p1=Search&p4=43700074935681884&p5=p&gad_source=1&gclid=EAIaIQobChMI68bj_I_hhAMV4wh7Bx3ZYgRoEAAYASAAEgKtW_D_BwE&gclsrc=aw.ds">www.ibm.com</a></cite></p> <p>IT 運用の現場では様々な監視ツールが利用されていますが、何か問題が起こってアラームが通知されたとき、『原因』や『修正方法』、『修正作業中のサービスへの影響範囲』などを把握すること、さらに、それらを理解した上で修正実行の要否や時期を判断。また、修正実施後にはサービスの正常稼働を確認する必要があることなどから、問題解決までには多くの時間と労力を要します。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240307/20240307115418.png" width="1200" height="561" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>その手間と時間を大幅に削減してくれる魅力ある機能を提供するのが Event-Driven Ansible です。Instana や Turbonomic から得られる様々な情報を元に、問題が発生した場合は Event-Driven Ansible で自動的に修正を行います。修正アクションは完全自動実行も可能ですし、Ansible Automation Controller のワークフロー内に承認フローを入れたり、Servicenow などのチケット管理システムなどを挟んで、最終実行は『人』が判断することも可能です。</p> <p>今回はEvent-Driven Ansible のイベントソースとして、『Instana を使ったアプリケーション障害復旧の自動化』と、『Turbonomic を使ったインフラリソースの自動最適化』に関するデモ動画を作成してみました。是非ご覧ください。<br/> ※デモ動画は音声付きですのでリンクをクリックする際はご注意ください。</p> <h4 id="Instana--Event-Driven-Ansible-によるアプリケーション障害復旧の自動化デモ動画はこちら">Instana + Event-Driven Ansible によるアプリケーション障害復旧の自動化(デモ動画は<a href="https://youtu.be/RQrNX88L9pg">こちら</a>)</h4> <ol> <li>コンテナアプリケーション(Quote of the Day)に障害が発生</li> <li>Instana がアプリケーションの障害を検知しアラームを発砲</li> <li>Webhook 経由でアラームが Event-Driven Ansible へ通知される</li> <li>Event-Driven Ansible 内で Rulebook を元に Action 実行が必要と判断</li> <li>Action を実行し、Ansible Automation Controller 内のジョブテンプレートを実行</li> <li>アプリケーションが正常に稼働</li> </ol> <h4 id="Turbonomic--Event-Driven-Ansible-による-IT-リソースの自動最適デモ動画はこちら">Turbonomic + Event-Driven Ansible による IT リソースの自動最適(デモ動画は<a href="https://youtu.be/zyPXm4kUSa4">こちら</a>)</h4> <ol> <li>AWS 上のインスタンスのリソース利用状況を監視</li> <li>リソース状況に応じた推奨(インスタンスタイプの変更)を提示</li> <li>Webhook 経由でインスタンスタイプの変更を Event-Driven Ansible へ通知</li> <li>Event-Driven Ansible が Rulebook を元に、AWS のタグ情報を含め、インスタンスタイプ変更の可否を判断</li> <li>インスタンスタイプの変更を実施し、アプリケーションの稼働を確認</li> </ol> <h3 id="まとめ">まとめ</h3> <p>今回は、IT 運用監視系のツールである、IBM 社の Instana 及び Turbonomic と Red Hat Event-Driven Ansible の連携よる IT 運用自動化のお話でした。如何でしたでしょうか?先述の通り、IT 運用においては様々な監視ツールからアラームが上がってきます。その際、そもそも対応が必要なのかどうか?という判断から始まり、障害内容の把握、対処法の確認、実施の判断、作業員の確保と実施、実施後の正常動作の確認...など、多くの時間と労力が必要となります。</p> <p>このような運用に対し、</p> <p>『あらかじめ課題解決のルール』</p> <p>を定義しておき、問題が起こった時にはそのルールに従うことで手間なく自動的に修正ができる、というのが今回のブログの趣旨となります。</p> <p>勿論、あらかじめ準備されたものに関しては、導入当初は『抜け・漏れ』や『修正できない』などの問題が数多く発生することが予想されますが、運用上発生したそういった問題を都度システム側にフィードバックしていくことで Instana / Turbonomic 及び、Event-Driven Ansible、Ansible Automation Controller 内に IT 運用のナレッジがたまっていきます。</p> <p>つまり、運用すればするほど賢くなっていきます。そして、いずれ『人依存』からの脱却が可能となるのではと思います。</p> <p>こちらのソリューションにご興味ある方は是非 Red Hat 担当までご連絡ください。</p> hokn5 JBoss Enterprise Application Platform 8.0 の新機能 hatenablog://entry/6801883189080939196 2024-02-06T08:27:58+09:00 2024-03-19T08:26:25+09:00 Red Hat のソリューションアーキテクトの瀬戸です。 この記事はRed Hat Developerのブログ記事、What's new in JBoss Enterprise Application Platform 8.0 | Red Hat Developerを、許可をうけて翻訳したものです。 Red Hat は最近、Jakarta EE 準拠プラットフォームの最新リリースであるJBoss EAP 8.0を発表しました。このリリースにより、企業は最新のJakarta EE APIを活用し、エンタープライズ Java アプリケーションのライフサイクルを大幅に延長できるようになります。 JB… <p>Red Hat のソリューションアーキテクトの瀬戸です。</p> <p>この記事はRed Hat Developerのブログ記事、<a href="https://developers.redhat.com/articles/2024/02/05/whats-new-jboss-enterprise-application-platform-8">What&#39;s new in JBoss Enterprise Application Platform 8.0 | Red Hat Developer</a>を、許可をうけて翻訳したものです。</p> <hr /> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240206/20240206092201.png" width="960" height="480" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>Red Hat は最近、<a href="https://developers.redhat.com/products/eap/overview">Jakarta EE 準拠プラットフォームの最新リリースであるJBoss EAP 8.0</a>を発表しました。このリリースにより、企業は最新のJakarta EE APIを活用し、エンタープライズ Java アプリケーションのライフサイクルを大幅に延長できるようになります。</p> <p>JBoss EAP 8.0 では、管理コンソールと CLI、セキュリティ、クラスタリング、データソース、EJB サブシステムなど、プラットフォームの多くの領域にわたって改善が加えられています。新しい機能と拡張機能、および削除された機能と非推奨になった機能の詳細なリストについては、<a href="https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/8.0/html/release_notes_for_red_hat_jboss_enterprise_application_platform_8.0/index">JBoss EAP 8.0 リリースノート</a>を参照してください。</p> <p>この記事では、JBoss EAP 8.0 の新しい機能と、顧客が古いバージョンの JBoss EAP から移行できるように Red Hat が提供するツールについて説明します。</p> <h3 id="Jakarta-EE-アプリケーションの長期サポート">Jakarta EE アプリケーションの長期サポート</h3> <p><a href="https://access.redhat.com/support/policy/updates/jboss_notes#p_eap">サポートライフサイクルページ</a>に示されているように、JBoss EAP 8.0 は長期ライフサイクルサポートポリシーを採用しています。</p> <h4 id="Jakarta-EE-10-の互換性">Jakarta EE 10 の互換性</h4> <p>Jakarta EE 8をサポートするJBoss EAP 7.4とは異なり、JBoss EAP 8.0 は <a href="https://jakarta.ee/specifications/platform/10/">Jakarta EE 10</a> API の実装を提供します。Jakarta EE 10 には、Jakarta EE に対する多くの変更が加えられています。<a href="https://access.redhat.com/articles/6980265">JBoss EAP アプリケーションを Jakarta EE 8 から Jakarta EE 10 に移行する方法</a>について詳しく学習してください 。</p> <p>Jakarta EE 10 への移行での最も重要な変更の 1 つは、ネームスペース(パッケージ)が javax から jakarta に変更されたことです。これはJava EE がEclipse Foundation へ移管され Jakarta EEの確立されたことに続くものです。</p> <p>Red Hat は、この移行に必要なアプリケーションコードの変更についてお客様を支援するためのルールを備えた<a href="https://developers.redhat.com/products/mta/overview">Migration Toolkit for Applications (MTA)</a>を更新しました。</p> <h4 id="Jakarta-EE-10-Core-Profile">Jakarta EE 10 Core Profile</h4> <p>Jakarta EE 10 Core Profileが JBoss EAP 8.0 で利用できるようになりました。Jakarta EE Core Profile は Jakarta EE 10 で導入され、クラウドネイティブ開発とマイクロサービスをサポートする最小限の API セットに重点を置いた最新のクラウド アプリケーションの開発者を対象としています。Jakarta EE 10 Core Profileは、Galleon プロビジョニング レイヤー、ee-core-profile-server として利用できます。</p> <h3 id="最新のプロビジョニング-システム">最新のプロビジョニング システム</h3> <p>JBoss EAP 8.0 は、すべてのデプロイメントターゲット (ベアメタルやVM、クラウド) 全体で一貫性を高め、テスト/ステージング環境と実稼働環境の間の差異を削減する新しいプロビジョニングシステムを導入します。</p> <p>ターゲット環境に応じて、適切なツールがプロビジョニングを実行します (例: クラウド用の Maven プラグイン、またはベアメタル/VM 用の jboss-eap-installation-manager CLI)。これらのツールの中核には、機能パック、レイヤー、チャネルという同じ 3 つの概念があります。チャネルは、特定の製品バージョン (8.0、8.1 など) をプロビジョニングするために必要なコンポーネントの下位互換性リリースのコレクションです。クラウド展開の場合、プロビジョニング システムは、アプリケーションの依存関係をサポートするために必要なレイヤーのみを展開するように設計されており、その結果、イメージサイズと取り組み対象領域が縮小されます。</p> <p>運用チームは、同じデータソースレイヤーを使用して VM とクラウドにデータベース用のドライバーを展開するなど、展開対象や環境に関係なく、一貫した構成とこれらの概念の利用から恩恵を受けます。</p> <p>新しいプロビジョニング システムは、オンラインとオフラインの両方の展開をサポートします。オンライン デプロイメントの依存関係は、Red Hat Maven リポジトリから取得されます。オフライン デプロイメントは、Red Hat のダウンロード サーバーからダウンロードできる Maven リポジトリのローカル アーカイブを使用することで利用できます。</p> <h3 id="改善されたクラウド-ワークフロー-ツール">改善されたクラウド ワークフロー ツール</h3> <p>JBoss EAP 8.0 では、<a href="https://www.redhat.com/en/technologies/cloud-computing/openshift">Red Hat OpenShift Container Platform</a>上で実行するための JBoss EAP 8.0 アプリケーションイメージのプロビジョニングを支援する更新されたツールが導入されています。これらのツールを使用する事で、開発者は、Red Hat OpenShift などの Kubernetes プラットフォーム上での Jakarta EE アプリケーションのデプロイメントを管理および最適化できます。JBoss EAP 8.0 を使用する事で、開発者は OpenShift 上で JBoss EAP をデプロイおよび設定する方法をより詳細に制御できるようになり、生産性が向上し、より合理化された安全な OpenShift イメージが実現します。</p> <p>主な改善点の 1 つは <a href="https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/8.0#assembly_provisioning-a-jboss-eap-server-using-the-maven-plugin_assembly_environment-variables-and-model-expression-resolution">JBoss EAP Maven プラグイン</a>の導入です。これにより、OpenShift での JBoss EAP の設定がより簡単かつ柔軟になる大幅な改善が行われます。</p> <p>詳細については、記事:<a href="https://developers.redhat.com/articles/2023/02/08/how-jboss-eap-8-beta-makes-deployment-openshift-easier">JBoss EAP 8 の OpenShift へのデプロイメントを簡単にする方法</a>を参照してください。</p> <h3 id="セキュリティの強化">セキュリティの強化</h3> <p>JBoss EAP 8.0 によって導入されたセキュリティ強化には、OpenID Connect のネイティブサポートを提供する新しい elytron-oidc-client サブシステムが含まれています。JBoss EAP では、RH SSO OIDC アダプターが提供されなくなった代わりに、OIDC を使用して JBoss EAP 8.0 にデプロイされたアプリを保護できるようになりました。</p> <p>JBoss EAP 8.0 でレガシーセキュリティフレームワーク (picketlink および picketbox) が削除されました。これらは JBoss EAP 7.1 から非推奨になっていました。JBoss EAP 8.0 のセキュリティー強化の詳細についてはリリースノートのセキュリティーセクションを参照してください。</p> <h3 id="JDKのサポート">JDKのサポート</h3> <p>JBoss EAP 7.4 から JDK 11 のサポートは非推奨になっており、Red Hat は JDK 17 の使用を推奨します。JBoss EAP 8.0 でもJDK 11 は引き続きサポートされていますが、非推奨です。</p> <p>Java SE 21 のサポートは、JBoss EAP 8 の将来のリリースで計画されています。</p> <h3 id="移行ツール">移行ツール</h3> <p>Red Hat は、お客様が以前のバージョンの JBoss EAP から JBoss EAP 8.0 に、また Java 8 から Java 11 / 17 に移行できるように、更新された<a href="https://developers.redhat.com/products/mta/overview">Migration Toolkit for Applications (MTA)</a>を提供しています。</p> <p>MTA のアップデートに加えて、Red Hat はサーバー移行ツールも更新してリリースしています。JBoss EAP 7.x から JBoss EAP 8.0 へのアップグレードに必要なサーバー設定の変更を自動化します。</p> <h3 id="データソース機能パックのサポート">データソース機能パックのサポート</h3> <p><a href="https://github.com/jbossas/eap-datasources-galleon-pack">eap-datasources-galleon-pack</a> Galleon 機能パックには、Oracle、Microsoft SQL Server、PostgreSQL のデータベースに必要なドライバーとモジュールを提供するレイヤーが含まれています。</p> <p>最新のプロビジョニング システムを使用する事で、これらのドライバーを任意の対象環境 (ベアメタルやVM、クラウドなど) に展開して構成できます。</p> <h3 id="JBoss-EAP-XP-expansion-pack-50">JBoss EAP XP (expansion pack) 5.0</h3> <p>JBoss EAP 8.0 GA リリース後、互換性のある拡張パックとして JBoss EAP XP 5.0 GA と、Jakarta EE 10 に準拠した Eclipse MicroProfile バージョンをリリースする計画があります。</p> <p>拡張パックを JBoss EAP に追加する事で、開発者はメトリクス、ヘルスエンドポイント、リアクティブメッセージングサポートの追加など、クラウドネイティブ機能を既存の Jakarta EE アプリケーションに追加できるようになります。</p> <p>JBoss EAP XP 5.0 では暫定的に以下のサポートを追加する予定です。</p> <ul> <li>MP OpenTracing を置き換える MP OpenTelemetry</li> <li>OpenShift / Kubernetes クラウドネイティブのさらなる機能強化: <ul> <li>EAP XP テンプレート機能の Helm チャート</li> </ul> </li> <li>Micrometer Metrics version 1.9</li> <li>MicroProfile LRA (長時間実行アクション) - Tech Preview</li> <li>MP Reactive Messagingを使用した AMQ Broker への AMQP Connector のサポート</li> </ul> <p>正確な機能セットについては、JBoss EAP 拡張パック 5.0 のリリース後に リリースノートを参照してください。</p> <h3 id="まとめ">まとめ</h3> <p>JBoss EAP 8.0 のリリースにより、Red Hat は Jakarta EE アプリケーションのサポートを提供し、更新された Jakarta EE API の使用を可能にし、ターゲット環境に依存しない一貫したデプロイメントアプローチを提供することに継続的に取り組んでいることを示しています。JBoss EAP 8.0 は、レガシーセキュリティフレームワークの削除とネイティブ OpenID コネクトのサポートの導入により、アプリケーションのセキュリティを強化します。</p> <p>Red Hat は、Jakarta EE アプリケーションを最新化し、クラウドネイティブ環境に移行したいお客様に、Jakarta EE Core Profileのサポートと改善されたクラウド ワークフロー ツールを提供します。</p> megascus Event-Driven Ansible の始め方 hatenablog://entry/6801883189075764347 2024-01-31T16:14:06+09:00 2024-01-31T16:14:06+09:00 皆さんこんにちは、Red Hat の岡野です。 前回の『Ansible Lightspeed の始め方』に引き続き、AAP 2.4 のもう 1 つの注目の新機能、Event-Driven Ansible (EDA) のお試し方法についてご紹介したいと思います。EDA を利用することにより、IT 運用において発生する様々なイベントを自動的に処理することが可能となります。EDA の概要は、こちらをご確認ください。 1. EDA と環境概要 Event-Driven Ansible (以下 EDA)は、Ansible Automation Platform 2.4 (AAP 2.4) から新たに追加… <p>皆さんこんにちは、Red Hat の岡野です。</p> <p>前回の『Ansible Lightspeed の始め方』に引き続き、AAP 2.4 のもう 1 つの注目の新機能、Event-Driven Ansible (EDA) のお試し方法についてご紹介したいと思います。EDA を利用することにより、IT 運用において発生する様々なイベントを自動的に処理することが可能となります。EDA の概要は、<a href="https://rheb.hatenablog.com/entry/aap24-1">こちら</a>をご確認ください。</p> <h3 id="1-EDA-と環境概要">1. EDA と環境概要</h3> <p>Event-Driven Ansible (以下 EDA)は、Ansible Automation Platform 2.4 (AAP 2.4) から新たに追加された GUI サービスを提供するコンポーネントです。AAP 2.3 までは、Ansible Automation Controller (AAC) と Private Automation Hub (PAH) の 2つが GUI サービスを持つコンポーネントとして提供されてていましたが、3 つめのコンポーネントとして、EDA Controller が追加されました。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240118/20240118183926.png" width="999" height="446" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>今回はイベントソースに webhook を利用し、EDA Controller と AAC を連携させた動作を確認してみます。</p> <p><strong>構成</strong><br/> ・EDA Controller <br/> ・Ansible Automation Controller (AAC)<br/> ・PostgreSQL (for EDA Controller &amp; AAC)</p> <p><strong>イベントソース</strong><br/> ・webhook</p> <h3 id="2-EDA-のインストール方法">2. EDA のインストール方法</h3> <p>EDA のインストールは簡単です。AAC や PAH と同様、Inventory ファイルに EDA の情報を記載するだけで OK です。詳細は以下のドキュメントをご確認ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fred_hat_ansible_automation_platform%2F2.4%2Fhtml-single%2Fred_hat_ansible_automation_platform_installation_guide%2F" title="Red Hat Ansible Automation Platform インストールガイド Red Hat Ansible Automation Platform 2.4 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/red_hat_ansible_automation_platform/2.4/html-single/red_hat_ansible_automation_platform_installation_guide/">access.redhat.com</a></cite></p> <p>マニュアルにも構成例とその際の Inventory ファイルが記載されていますが、AAC と EDA Controller を 外部 DB 共有の形でインストールする場合、Inventory ファイルを以下のように記載すればインストールできると思います。</p> <pre class="code" data-lang="" data-unlink>[automationcontroller] aap.example.com [automationedacontroller] eda.example.com [database] db.example.com [all:vars] admin_password=&#39;&lt;your_password&gt;&#39; pg_host=&#39;db.example.com&#39; pg_port=5432 pg_database=&#39;awx&#39; pg_username=&#39;awx&#39; pg_password=&#39;&lt;your_password&gt;&#39; pg_sslmode=&#39;prefer&#39; # set to &#39;verify-full&#39; for client-side enforced SSL registry_url=&#39;registry.redhat.io&#39; registry_username=&#39;&lt;registry username&gt;&#39; registry_password=&#39;&lt;registry password&gt;&#39; receptor_listener_port=27199 automationedacontroller_admin_password=&#39;&lt;your_password&gt;&#39; automationedacontroller_pg_host=&#39;db.example.com&#39; automationedacontroller_pg_port=5432 automationedacontroller_pg_database=&#39;automationedacontroller&#39; automationedacontroller_pg_username=&#39;automationedacontroller&#39; automationedacontroller_pg_password=&#39;&lt;your_password&gt;&#39; </pre> <h3 id="3-EDA-の使い方">3. EDA の使い方</h3> <p>では、実際に EDA Controller と AAC の設定を行い連携動作させてみましょう。これには以下のような作業が必要となります。</p> <h4 id="3-1-Rulebook-の作成と-Github-上への配置">3-1. Rulebook の作成と Github 上への配置</h4> <p>今回、Rulebook は以下を使います。すべてのホストからの webhook を5000番ポートで待ち受け、webhook のイベントを受け取ったら、 その中のメッセージを確認し、Ansible is super cool という文字列と一致した場合に、 AAC 内にあらかじめ作成された Demo Job Template というジョブテンプレートを実行するというものです。</p> <pre class="code" data-lang="" data-unlink>--- - name: Listen for events on a webhook hosts: all sources: - name: Wait for Webhook Message ansible.eda.webhook: host: 0.0.0.0 port: 5000 rules: - name: Say Hello condition: event.payload.message == &#34;Ansible is super cool&#34; action: run_job_template: name: Demo Job Template organization: Default</pre> <p>Rulebook は、Git 上に配置する必要があります。AAC ではローカルホルダーもサポートされていますが、EDA は現時点では、ローカルパスはサポートされていません。また、Git上での配置場所ですが、各リポジトリの extensions/eda/rulebooks 配下に置く必要があります。今回は、<a href="https://github.com/hiro52/eda_demo">こちら</a>を利用します。勿論、ご自身の Github 上において利用いただいてもかまいませんが、Rulebook を配置するパスに注意ください。</p> <h4 id="3-2-EDA--AAC-の認証情報の設定">3-2. EDA → AAC の認証情報の設定</h4> <p>今回、EDA Controller から AAC に接続しジョブテンプレートを稼働させる必要があります。このため何かしらの認証の仕組みが必要になるのですが、EDA Controller と AAC 間の認証にはトークンを使います。作業は簡単です。まずは、<strong>AAC 側</strong>で、『ユーザー』→『admin』→『トークン』と進み、『範囲』で『書き込み』を選択、保存します。保存をクリックするとトークンが表示されますので、クリップボードにコピーします。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240131/20240131145429.png" width="1200" height="726" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>次は、コピーした AAC トークンの EDA Controller へのペースト作業です。<strong>EDA Controller</strong> で『ユーザー』→『admin』→『コントローラートークン』と進み、『コントローラートークンの作成』をクリック。『トークン』に先ほどAACからコピーしたトークンをペーストして、『コントローラートークンの作成』をクリックします。これで EDA Controller と AAC の認証設定は終了です。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240131/20240131151818.png" width="1200" height="1039" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h4 id="3-3-Rulebook-のアクティベーション">3-3. Rulebook のアクティベーション</h4> <p>ここまで準備ができれば、Rulebook のアクティベーションが可能です。まずはプロジェクトで Rulebook が存在する Git の URL を定義します。SCM のURLは、<code>https://github.com/hiro52/eda_demo/</code>です。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240131/20240131152952.png" width="1200" height="465" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>いよいよルールのアクティベーションです。左ペインで『ルールブックのアクティベーション』を選択し、適当に名前を入力、先ほど作成したプロジェクトを選択し、『ルールブック』で、<code>eda_test.yml</code> を選択します。決定環境は、Default Decision Environment を選択。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240131/20240131153246.png" width="1200" height="429" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>『ルールブックのアクティベーションの作成』をクリックすると、以下のように、ルールブックのアクティベーションステータスが『実行中』となります。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240131/20240131161214.png" width="888" height="415" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h4 id="3-4-動作確認">3-4. 動作確認</h4> <p>では、実際に webhook で文字列を投げて動作を確認してみましょう。Firewall などのポートの制限がなく、EDA に接続可能な適当なホスト上(EDA 上でも勿論OK)で以下のコマンドを実行して、EDA Controller に webhook を介してメッセージ <code>Ansible is super cool</code> を送ってみます。</p> <p><code>$ curl -H 'Content-Type: application/json' -d "{\"message\": \"Ansible is super cool\"}" &lt;EDA FQDN&gt;:5000</code></p> <p>設定に間違いがなければ、AAC 上で、Demo Job Template が起動します。ご確認ください。</p> <h3 id="5-まとめ">5. まとめ</h3> <p>いかがでしたでしょうか。Event-Driven Ansible は IT 運用で発生する様々なイベントを自動的に処理することが出来ます。今回は、ソースとして Webhook を直接コマンドでたたくという簡易的動作確認を行いましたが、次回は、実際のアプリケーションをソースとした連携についてデモ動画を交えてご説明したいと思います。</p> hokn5 Red Hat Developer Hub (Backstage) でGolden Pathを作ろう! hatenablog://entry/6801883189076007100 2024-01-18T14:00:37+09:00 2024-01-18T14:00:37+09:00 こんにちは、Red Hatでソリューションアーキテクトをしている北村です。 2024/1/17に"Red Hat Developer Hub: 一貫した開発への入り口"という記事がエントリーされました。こちらの記事に記載がある通り、Red Hatは2024/1/16にRed Hat Developer Hub(以下、RHDH)をGAリリースしました。 rheb.hatenablog.com Red Hat Developer Hubとは RHDHはBackstageをベースとしたInternal Developer Portalであり、Backstageの基本機能に加え、サンプルのGolden… <p>こんにちは、Red Hatでソリューションアーキテクトをしている北村です。 2024/1/17に"<a href="https://rheb.hatenablog.com/entry/2024/01/17/100358">Red Hat Developer Hub: 一貫した開発への入り口</a>"という記事がエントリーされました。こちらの記事に記載がある通り、Red Hatは2024/1/16に<a href="https://developers.redhat.com/rhdh">Red Hat Developer Hub</a>(以下、RHDH)をGAリリースしました。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2024%2F01%2F17%2F100358" title="Red Hat Developer Hub: 一貫した開発への入り口 - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2024/01/17/100358">rheb.hatenablog.com</a></cite></p> <h1 id="Red-Hat-Developer-Hubとは">Red Hat Developer Hubとは</h1> <p>RHDHはBackstageをベースとしたInternal Developer Portalであり、Backstageの基本機能に加え、サンプルのGolden Pathや、他のRed Hat製品との連携を強化するプラグイン、ならびにエンタープライズレベルのサポートを提供します。</p> <p>このRHDHは大きく2つの価値を開発者に提供します。</p> <ul> <li>Golden Path - 開発のベストプラクティスを実際に動作する環境と共に提供</li> <li>開発者がOpenShift上で開発する上で必要となる様々な情報を一元化</li> </ul> <p>特にGolden PathはRHDHの根幹となる仕組みであり、Platform Engineering TeamはこのGolden Pathをいかに効率よく開発チームに提供できるのかが重要になります。 <figure class="figure-image figure-image-fotolife" title="Golden Path"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/s/shin7446/20240118/20240118134454.png" width="1200" height="533" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>Golden Path</figcaption></figure> 昨今話題となっているPlatform EngineeringとRHDH(Backstage)の関係性についてはCNDT2023でお話させていただいたので、こちらも是非見ていただければと思います。<br/> <a href="https://cloudnativedays.jp/cndt2023/talks/2067">&#x3053;&#x308C;&#x304B;&#x3089;&#x306E;Platform Engineering&#x3092;&#x652F;&#x3048;&#x308B;&#x30B3;&#x30F3;&#x30C6;&#x30CA;&times;Backstage&#x306E;&#x771F;&#x4FA1;</a></p> <h1 id="Red-Hat-Developer-HubでGolden-Pathを作るには">Red Hat Developer HubでGolden Pathを作るには?</h1> <p>RHDHはその特性上、開発者の体験にフォーカスした特徴やメリットが前面に出されます。そして、そういった利用者(ここでは開発者)の視点のみで製品を捉え導入しても、残念ながら導入価値を最大化することは困難です。製品導入においては、<strong>開発者に価値を提供するために必要なRHDHの運用方法</strong>を理解しておくことが重要です。</p> <p>そこで、今回は現時点でのリリースバージョンにおけるRHDHの具体的な設定方法、特に<strong>Golden Pathの作成と実行</strong>にフォーカスしたQiita記事をエントリーしました。</p> <p>これからこういったInternal Developer Portalの導入を検討される方や、今OpenShiftをお使いの方で、少し興味がある方は是非触ってみていただければと思います。</p> <h1 id="コンテンツ">コンテンツ</h1> <p>記事は全部で6つに分かれており、現在5つの記事まで公開しています。こちらは順番に実施するWorkshop形式で記載しています。 <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fshin7446%2Fitems%2Fbafb3619caf5c8ba28c1" title="Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜環境導入編〜 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/shin7446/items/bafb3619caf5c8ba28c1">qiita.com</a></cite> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fshin7446%2Fitems%2Fb54ebda4ee91ea5f4ca2" title="Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜認証設定編〜 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/shin7446/items/b54ebda4ee91ea5f4ca2">qiita.com</a></cite> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fshin7446%2Fitems%2Fc35010c3ea566beadc5a" title="Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜GitHub Integration編〜 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/shin7446/items/c35010c3ea566beadc5a">qiita.com</a></cite> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fshin7446%2Fitems%2Fce86d9bbb5121579f9ce" title="Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜Golden Path作成編①〜 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/shin7446/items/ce86d9bbb5121579f9ce">qiita.com</a></cite> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fshin7446%2Fitems%2F0c181c2f7cc63917bd7c" title="Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜Golden Path作成編②〜 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/shin7446/items/0c181c2f7cc63917bd7c">qiita.com</a></cite></p> <h1 id="さいごに">さいごに</h1> <p>RHDHはOpenShift Container Platformとは別サブスクリプションとなるため、残念ながら気軽に利用することが難しいですが、RHDHのアップストリームである<a href="https://janus-idp.io/">Janus Project</a>でもRHDHと近しい体験を得ることができます。Qiitaの中ではJanusのインストール方法も記載していますので、まずはこちらで気軽に試してみるところから始めてみてもいいかと思います。</p> <p>2024年はRed Hat Developer Hubでさらに快適なCloud Native開発を目指してみてはいかがでしょうか?</p> shin7446 Red Hat Developer Hub: 一貫した開発への入り口 hatenablog://entry/6801883189075696311 2024-01-17T10:03:58+09:00 2024-01-17T10:03:58+09:00 Red Hat のソリューションアーキテクトの瀬戸です。 この記事はRed Hat Developerのブログ記事、Red Hat Developer Hub: Your gateway to seamless development | Red Hat Developer を、許可をうけて翻訳したものです。 Red Hat Developer Hub がGAになり一般提供が開始されました。 この記事では、Developer Hub の紹介と共に、Developer Hub が開発プロセスをどのように合理化するかについて説明します。 また、Red Hat Developer Hub を介してプ… <p>Red Hat のソリューションアーキテクトの瀬戸です。</p> <p>この記事はRed Hat Developerのブログ記事、<a href="https://developers.redhat.com/articles/2024/01/16/red-hat-developer-hub-your-gateway-seamless-development">Red Hat Developer Hub: Your gateway to seamless development | Red Hat Developer</a> を、許可をうけて翻訳したものです。</p> <hr /> <p><a href="https://developers.redhat.com/rhdh">Red Hat Developer Hub</a> がGAになり一般提供が開始されました。 この記事では、Developer Hub の紹介と共に、Developer Hub が開発プロセスをどのように合理化するかについて説明します。 また、Red Hat Developer Hub を介してプロジェクトで Backstage の機能を活用するための基本的な概念についても詳しく説明します。</p> <h3 id="Backstage-とは何ですか">Backstage とは何ですか?</h3> <p>ソフトウェア開発の活動的な世界ではチームワークと効率が不可欠です。Backstage プロジェクトは開発チームの負担を軽減し、シンプルにすることを約束します。 Backstage はもともと Spotify によって作成され、オープンソース プロジェクトとして Cloud Native Computing Foundation (CNCF) と共有されました。開発チームの中心のハブとして機能し、ソフトウェア開発ライフサイクルをより管理しやすくし、新しいメンバーのオンボーディングを加速し、リソースを一元化したいプロジェクトで使用されます。Backstageは、利害関係者ができる限り少ない労力で関連情報やリソースにアクセスできる中央リポジトリとして機能することで、膨大な数の開発ツールの管理を支援します。</p> <p>Backstage が有益である重要な要素には、プラグインによる拡張や、プロジェクト コンポーネントの動的なカタログ、プロジェクト間で共有できるテンプレートを作成する機能などがあります。Backstage は単なるポータルではなく、開発チームがタスクに優先順位を付けて完了する方法を変革するツールです。</p> <h3 id="Backstage-と-Red-Hat-Developer-Hub-はどのような関係ですか">Backstage と Red Hat Developer Hub はどのような関係ですか?</h3> <p>Backstage は、Spotify が必要なこと、まさに Spotify が望んでいることを実現するために Spotify によって作成されたオープンソース プロジェクトです。サポートや延長されたライフサイクル、認定、テスト、古いバージョンのバグ修正などのエンタープライズ向け機能はありません。</p> <p>Backstage は社内開発者ポータルを作成するための「フレームワーク」であるにもかかわらず、顧客はポータルをカスタマイズし、開発者がアクセスするツールのさまざまなプラグインを統合する必要があります。そこで Red Hat Developer Hub の出番です。Backstage をRed Hat テクノロジーと統合するためにサポートされているプラ​​グインを備えたエンタープライズグレードの内部開発者ポータルに変換します。 また、私たちはコミュニティに還元し、私たちが面倒なタスクに集中している間、コミュニティがイノベーションに集中できるようにします。</p> <p>Red Hat Developer Hub (図 1) は、Backstage オープンソース プロジェクトのエンタープライズ グレードのバージョンを提供するための Red Hat がサポートするビルドです。</p> <p><figure class="figure-image figure-image-fotolife" title="図 1: The Developer Hub UI"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240117/20240117092408.png" width="600" height="445" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>図 1: The Developer Hub UI</figcaption></figure></p> <h3 id="Red-Hat-Developer-Hub-を理解する-開発者の天国">Red Hat Developer Hub を理解する: 開発者の天国</h3> <p>ソフトウェア開発の分野では、Red Hat Developer Hub は集中制御装置として機能し、拡張可能なプラグイン アーキテクチャを利用して多様なツールをシームレスに統合します。図 2 に示すように、各プラグインは依存関係の管理から自動ビルドに至るまで開発プロセス内のそれぞれの機能に対応しています。このモジュール式のアプローチによりソフトウェアの開発環境が合理化されます。Developer Hub にはコンテナーイメージに組み込まれたサポートされているプラ​​グインが含まれています。ユーザーは、サードパーティから提供された/自分で構築した独自のプラグインを持ち込んでさらにカスタマイズすることもできます。</p> <p><figure class="figure-image figure-image-fotolife" title="図 2: Developer Hub のプラグイン アーキテクチャ"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20240117/20240117092944.png" width="600" height="215" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>図 2: Developer Hub のプラグイン アーキテクチャ</figcaption></figure></p> <p><a href="https://developers.redhat.com/articles/2023/05/23/developers-guide-red-hat-developer-hub-and-janus#overview_of_backstage_and_project_janus">この優れた記事</a>でプラグインについてさらに詳しく調べてください。この記事では、より多くのコンテキストが提供されています。</p> <p>Red Hat Developer Hub の機能の基礎となっているのは動的なコンポーネントカタログです。このカタログは集中リポジトリとして機能し、プロジェクトのコンポーネントやサービス、依存関係を体系的に整理します。プロジェクトの要素の統合ビューを提供することで、開発者向けのナビゲーション ツールとしても機能します。Red Hat Developer Hub は、体系化されたサマリーを提供することで曖昧さを軽減し、チームの協力を促進します。基本的に、組織化された共有スペースとして機能し、開発者から見ると、プロジェクトで使用している機能へのアクセシビリティと明確性が向上します。</p> <p>Red Hat Developer Hub の価値提案は、従来のプロジェクト管理の制約を超越する能力に基づいています。Red Hat Developer Hub は、共有可能なツールの統合を通じてコラボレーション環境を促進します。開発チームは、特定の要件に合わせて調整されたツールを自ら組み込んで適用し、プロジェクト全体で共有して、一貫性と効率性を促進できます。Red Hat Developer Hub はプラットフォームとして、単なる促進装置ではありません。プロジェクトの複雑さを解消し、アプリケーション開発への集中的なアプローチを可能にする実用的なソリューションです。</p> <h3 id="開発チームの効率を促進するツール">開発チームの効率を促進するツール</h3> <p>Red Hat Developer Hub の 2 つの重要なツールにより、すべてのチームメンバーのソフトウェア開発体験がとても良くなります。</p> <ul> <li>ソフトウェアテンプレート</li> <li>コンポーネントカタログ</li> </ul> <h4 id="ソフトウェアテンプレート">ソフトウェアテンプレート</h4> <p>ソフトウェア テンプレートは、簡単に言えば、プロジェクトを構築するための既製の計画です。「整備された道路」と呼ばれることもあります。ソフトウェア テンプレートにはプロジェクトを開始するために必要なすべての設定と構成が含まれています。Red Hat Developer Hub を使用してチームの開発作業を開始するときにはサンプルのテンプレートを使用できます。サンプルのテンプレートは、開発を最適化する構成が最初からセットアップされているため、初期セットアップに費やす時間が短縮されます。プロジェクトのスケジュールが短縮され、新しいプロジェクトに対応する労力が軽減されます。</p> <p>技術リーダーはソフトウェア テンプレートを使用して、新しいプロジェクトやソフトウェア コンポーネント向けにカスタマイズされた標準構成を開発者に提供できます。これらのテンプレートには、コードのエラーチェック、セキュリティ検証の検証、安全なサプライ チェーンの信頼できるパイプラインの構築のための組織の推奨ツールが含まれる場合があります。</p> <h4 id="コンポーネントカタログ">コンポーネントカタログ</h4> <p>コンポーネント カタログは、プロジェクト内のすべてのもののマスターリストであり、基本的には、必要なパーツ、サービス、その他の必要なコンポーネントを追跡できる、よく整理された検索可能なインベントリです。開発チームにとって、このカタログは、プロジェクトの依存関係を管理し、相互に依存しているさまざまな要素間の全体的なリスクを軽減するのに特に役立ちます。コンポーネントカタログを使用することで、すべての関係者がこれらの構成要素を表示、整理、管理できるため、スムーズで秩序ある開発プロセスが保証されます。</p> <p>ここで説明したようなツールは、単純な整備にとどまらず、拡張され、その使用を通じて具体的な利点が組み込まれています。これらはチームワークとコラボレーションに貢献し、誰もが簡単に会社のガイドラインに従って同じ方法でプロジェクトを開始できるようにします。Red Hat Developer Hub をさらに深く知っていくと、これらの機能が重要な味方となり、より効率的に作業し、一貫性を維持し、プロジェクトの全行程を通じてシームレスに共同作業するのに役立つことに気が付くでしょう。---これらすべてが組織の競争上の優位性に貢献します。</p> <h3 id="Red-Hat-Developer-Hub-の使用を開始する方法">Red Hat Developer Hub の使用を開始する方法</h3> <p>Red Hat Developer Hub 1.0 のリリースについて、私たちと同じように皆さんも興奮していただけると嬉しいです。さらに読み進めたり、実践したりする準備ができている場合は、いくつかの方法から始めることができます。</p> <ul> <li>社内向けの開発者ポータルを構築する予定なら、<a href="https://developers.redhat.com/learn/openshift/install-and-configure-red-hat-developer-hub-and-explore-templating-basics">プラットフォームエンジニア向けの新しい学習パス</a>に従って、Developer Sandbox for Red Hat OpenShift で独自のバージョンを無料で立ち上げ、実行することができます。</li> <li>Joshua Wood、Hans-Peter Grahsl、Ryan Jarvinen 著の近日発売予定の電子書籍『<a href="https://developers.redhat.com/e-books/developer-portals">Developer Portals: Prepare to Perform with Red Hat Developer Hub</a>』から 3 つのプレビュー チャプターをダウンロードしてください。</li> <li>進んで自分自身でデプロイする準備ができていますか? <a href="https://access.redhat.com/downloads/">access.redhat.com</a>から評価版を入手し、独自のクラスターで起動します。コンテキストと詳細情報については、必ず<a href="https://access.redhat.com/documentation/en-us/red_hat_developer_hub/1.0?extIdCarryOver=true&amp;sc_cid=7015Y000003sfSQQAY">ドキュメント</a>を確認してください。</li> </ul> <p>Red Hat Developer Hub と共に飛び込んで探索し、あなたのプロジェクトの潜在的な可能性を解き放ちましょう。</p> megascus Ansible Lightspeed の始め方 hatenablog://entry/6801883189073694449 2024-01-12T17:51:45+09:00 2024-01-15T16:28:38+09:00 皆さんこんにちは、Red Hat ソリューションアーキテクトの岡野です。2024 年が始まりましたね。今年もたくさんの Ansible Automation Platform 関連の情報をお届けできればと考えています。是非お付き合いください。 さて、昨年末こちらで予告させていただいた通り、まずは、Ansible Lightspeed のお試し方法についてご紹介したいと思います。実は昨年の12月にパートナー様向けに Ansible Automation Platform 最新情報に関するセミナーを開催したのですが、その際も Ansible Lightspeed は大変引き合いが強く、 『すぐに試… <p>皆さんこんにちは、Red Hat ソリューションアーキテクトの岡野です。2024 年が始まりましたね。今年もたくさんの Ansible Automation Platform 関連の情報をお届けできればと考えています。是非お付き合いください。</p> <p>さて、昨年末<a href="https://rheb.hatenablog.com/entry/aap24-1">こちら</a>で予告させていただいた通り、まずは、Ansible Lightspeed のお試し方法についてご紹介したいと思います。実は昨年の12月にパートナー様向けに Ansible Automation Platform 最新情報に関するセミナーを開催したのですが、その際も Ansible Lightspeed は大変引き合いが強く、</p> <p>『すぐに試したいのでやり方教えてください!!』</p> <p>という声をたくさんいただきましたので、その声にお応えすべく。</p> <p>ただし、一点、初めにお断りしておきます。<a href="https://access.redhat.com/articles/7039771">こちら</a>に記載の通り、評価環境構築に関してはよりスマートな方法が2024年初頭(ということなのでもうすぐ)提供されるとのことです。お急ぎでない場合はそちらをお待ちいただくのも良いかもしれません。</p> <p>ただ、私のところにも社内外から構築方法について多くの問い合わせをいただいているのと、また、そもそもIBM クラウド独特の言葉の意味がわからず、私自身結構苦労しましたので急ぎ確認したい方が同じ轍を踏まないために。(^^)</p> <p>では早速。</p> <h3 id="Ansible-Lightspeed-の環境構築方法">Ansible Lightspeed の環境構築方法</h3> <h4 id="評価版の利用">評価版の利用</h4> <p>製品版の Ansible Lightspeed を利用する場合、以下2つを購入する必要があります。このそれぞれに評価版(無償枠)が提供されていますのでこちらを利用します。</p> <ul> <li><p>Ansible Automation Platform (AAP)<br/> 以下から評価版のサブスクリプションを入手します。<br/> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.redhat.com%2Fen%2Ftechnologies%2Fmanagement%2Fansible%2Ftrial" title="Red Hat Ansible Automation Platform | Product Trial" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.redhat.com/en/technologies/management/ansible/trial">www.redhat.com</a></cite></p></li> <li><p>IBM watsonx Code Assistant for Red Hat Ansible Lightspeed<br/> IBM クラウドに登録し、無償利用枠$200を利用します <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fcloud.ibm.com%2Fregistration" title="Sign up for IBM Cloud" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://cloud.ibm.com/registration">cloud.ibm.com</a></cite></p></li> </ul> <p>※ IBM クラウドの無償利用枠は $200までです。Lightspeed の場合 1か月分となりますので、テスト利用が終了したらデータの削除等対応ください。放置すると請求が発生します。また、アカウントの削除は AWS などと異なり、ケースによる対応が必要で結構手間がかかります。アカウント新規作成の際は、その点ご了承の上ご利用ください。</p> <p>もちろん、既にAAPのサブスクリプションを所有している方、IBM クラウドの既存ユーザーの方はそちらを利用することも可能です。今回は入手した評価版/無償枠を利用して環境構築を行っていきます。</p> <h3 id="1-IBM-クラウドでの作業">1. IBM クラウドでの作業</h3> <h4 id="1-1-サービス-ID-と-watsonx-Code-Assistant-WCA-キーの作成">1-1. サービス ID と watsonx Code Assistant (WCA) キーの作成</h4> <p>まずは、Ansible Lightspeed が WCA にアクセスするための ID とアクセスキーを作成します。<a href="https://cloud.ibm.com/iam/serviceids">こちら</a>(IBM Cloud内)から、名前(ここでは "watsonx Code Assistant user")を入力してサービス ID を作成します。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110140309.jpg" width="1200" height="564" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>次に、作成した ID 内のタブ『API キー』を開き、APIキーの名前を入力し作成をクリックすると、APIキーのコピーとダウンロードを促す画面が表示されます。この画面は閉じると2度とキーの取得ができませんので、クリップボードへのコピー、およびダウンロードしておきます。コピーした APIキーは手順 2-1 の登録の際に利用します。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110141703.jpg" width="957" height="409" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h4 id="1-2-watsonx-Code-Assistant-for-Ansible-Lightspeed-モデルのデプロイメント">1-2. watsonx Code Assistant for Ansible Lightspeed モデルのデプロイメント</h4> <p> Ansible Lightspeed で利用する AI モデルをデプロイします。<br/> <a href="https://cloud.ibm.com/catalog">こちら</a>から、『watsonx Code Assistant』を検索し、『IBM watsonx Code Assistant』をクリックします。以下のスクリーンキャプチャーを参考に、『IBM watsonx Code Assistant for Red Hat Ansible Lightspeed Essentials』を選択し、同意にチェックの上作成をクリック。遷移した画面で『10 user』となっていることを確認し 『Launch watson Code Assistant』 をクリックします。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110183421.png" width="1200" height="690" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>しばらくすると以下のような画面が表示されます。こちらを順に実行していきます。右にある矢印は各設定を行うためのリンクです。一番上の手順は既に先の手順で設定が完了しているサービスID及び API キーの作成です。構築済みですので一度矢印をクリックし、何もせずこちらの画面に戻ります。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110155541.png" width="1200" height="475" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>次にデプロイメント・スペースの作成の矢印をクリックします。デプロイメントスペース作成画面で『名前』を入力し、『コードアシスタントサービス』をプルダウンで選択した上で、『作成』をクリック。完了画面が出て作成が完了します。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110163459.png" width="1200" height="468" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>デプロイメント・スペースの作成が完了すると、ベース・モデル ID が割り振られます。このベース・モデルIDは、手順2で利用します。以下赤枠の中に値が入力されていることを確認の上、『サービスIDをスペースコラボレーターとして追加する』手順に進みます。矢印をクリックします。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110164203.png" width="1200" height="634" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>『watsonx Code Assistant user』 にチェックを入れます。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110164658.png" width="1200" height="464" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>これで IBM クラウド側の設定は完了です。以下参考に、矢印をクリックして手順 2 Ansible Lightspeed 管理ポータルでの設定に進みます。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110165305.png" width="1200" height="749" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h3 id="2-Ansible-Lightspeed-管理ポータルでの作業">2. Ansible Lightspeed 管理ポータルでの作業</h3> <h4 id="2-1-WCA-キーとベースモデルの-ID-の登録">2-1. WCA キーとベース・モデルの ID の登録</h4> <p>Ansible Lightspeed 管理ポータルが表示されていると思います。もし表示されてない場合は、<a href="https://c.ai.ansible.redhat.com/">こちら</a>をクリックください。IBM Cloud API Key と Model ID を入力する画面となりますので、手順 1-1、1-2でそれぞれ作成した WCA キーとベース・モデルID をそれぞれコピー&ペーストします。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110184805.png" width="1200" height="543" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h4 id="2-2-VSCode-Extension-のインストール">2-2. VSCode Extension のインストール</h4> <p>※Ansible Lightspeed は VS Code の拡張機能として動作します。まだ VS Code をインストールしていない場合はインストールの上、以下実施ください。逆に、既に VS Code や Extension をインストールしている場合は、バージョンに注意してください。Ansible Lightspeed でサポートされるバージョンは以下の通りです。</p> <p>・VS Code version 1.70.1 or later<br/> ・Ansible extension for VS Code version 2.8 or later</p> <p>VS Code の Ansible Exension をインストールします。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110173334.png" width="434" height="357" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>さらに、以下参考に、拡張機能で、Lightspeed に関する設定(2か所)にチェックを入れて Lightspeed を有効化。さらに Ansible アイコンをクリックしてConnect をクリックします。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110175027.png" width="1200" height="593" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>この後、4つほど確認画面が表示されますが、『Allow』→『Open』→『Authorize』→『Open』など、クリックして進めてください。<br/> ブラウザが立ち上がって、『Red Hat Ansible Lightspeed with IBM watsonx Code Assistant』の画面が表示されればこの手順は完了です。</p> <h3 id="3Hybrid-Cloud-Console-での作業">3.Hybrid Cloud Console での作業</h3> <p>Ansible Lightspeed を利用するには、AAP のサブスクリプションが必要になります。この作業は AAP のサブスクリプションを持つユーザーに対して Ansible Lightspeed を利用する権限(シートライセンス)を与える設定です。<a href="https://console.redhat.com/ansible/seats-administration/">こちら</a>から Hybrid Cloud Console 上で、Assign users をクリックの上、必要なユーザーを登録します。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240110/20240110191336.png" width="1200" height="559" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>再度<a href="https://c.ai.ansible.redhat.com/">こちら</a>をクリックしてみてください。ログイン後に『licensed user』と表記されていればこの設定が完了しています。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240112/20240112144740.png" width="599" height="373" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h3 id="Ansible-Lightspeed-で-Playbook-を作成">Ansible Lightspeed で Playbook を作成!</h3> <p>早速簡単なPlaybook を作成してみましょう。VS Code 上で、新しいファイルを拡張子 『yaml』 で作成・保存します。実は拡張子は何でも良いのですが、関連付けもできるので後々便利です。下の『yaml』をクリック、さらに、言語モードとして『Ansible』を選択します(今後のため関連付けを行っておくと便利です)。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240112/20240112150141.png" width="916" height="543" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>Extension に関するエラーが出るかもしれませんが、下に 『Lightspeed (licenced)』 と出ていれば気にしなくても大丈夫です。エラーが気になるようであれば、Ansible-lint 関連や、Ansible › Validation: Enabled のチェックを外すとエラーは出なくなると思います。</p> <p>では Lightspeed に Task を作成してもらいましょう。試しに以下のように書いて、『・・・即座に開く』の後ろで改行してみてください。複数にまたがる推奨のタスクが出てくれば成功です。確定は『Tab』キー、拒否は『Esc』キーです。</p> <p>『#』と『&amp;』が意味を持ちますので重要です。</p> <pre class="code" data-lang="" data-unlink>--- - name: my first lightsppd yml hosts: all tasks: # 最新バージョンの httpd をインストール &amp; httpd サービスの有効化と開始 &amp; 80/443 ポートをFireall で恒久的に即座に開く</pre> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240112/20240112161325.png" width="1200" height="582" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>推奨がどこから出てきたのか、その出所は、右上のパネルの切り替えをクリックし、出てきたウィンドウで 『ANSIBLE』をクリックすることで確認することが出来ます。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20240112/20240112164947.png" width="1168" height="1195" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h3 id="まとめ">まとめ</h3> <p>いかがでしたでしょうか?</p> <p>生成 AI の利用については色々と議論が始まったばかりですが、その課題の一つが、</p> <p>『得られたデータがどこから来たのか?』</p> <p>ということだと思います。先日も New York Times が OpenAI に対し著作権侵害...などという記事が出ていて、個人的に、ありがちな事だなぁと感じていました。</p> <p>この点、Ansible Lightspeed で利用される『watsonx Code Assistant for Ansible Lightspeed』は、 Ansible Galaxy コンテンツとその他のオープン・データ・ソースおよび、Red HatとIBMの自動化に関する専門知識が注入された、Ansible固有の「トレーニング」データ・セットとなっているため、生成されたコードの質が高く、さらに、上記の通り、生成されたコードがどこから来たのか、そのソースを確認することもできることから、コードの脆弱性や不意のライセンス違反などを気にすることなく、安心して利用することが可能となっています。</p> <p>Ansible Lightspeed は今後も機能拡張を続けていきます。今回の機能提供はその第一弾、『ほんのさわりの部分』と考えていただいても良いと思います。Ansible Lightspeed に関するさらに詳細なご説明をご希望の方、また、機能拡張のロードマップを教えてほしいなどございましたら弊社担当までお問い合わせください。</p> <h4 id="関連ドキュメントのリンク">関連ドキュメントのリンク</h4> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fen-us%2Fred_hat_ansible_lightspeed_with_ibm_watsonx_code_assistant%2F2.x_latest%2Fhtml-single%2Fred_hat_ansible_lightspeed_with_ibm_watsonx_code_assistant_user_guide%2Findex" title="Red Hat Ansible Lightspeed with IBM watsonx Code Assistant User Guide Red Hat Ansible Lightspeed with IBM watsonx Code Assistant 2.x_latest | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/en-us/red_hat_ansible_lightspeed_with_ibm_watsonx_code_assistant/2.x_latest/html-single/red_hat_ansible_lightspeed_with_ibm_watsonx_code_assistant_user_guide/index">access.redhat.com</a></cite></p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fcloud.ibm.com%2Fdocs%2Fwatsonx-code-assistant%3Ftopic%3Dwatsonx-code-assistant-cloud-setup-a" title="IBM Cloud Docs" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://cloud.ibm.com/docs/watsonx-code-assistant?topic=watsonx-code-assistant-cloud-setup-a">cloud.ibm.com</a></cite></p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Farticles%2F7039771" title="Red Hat Ansible Lightspeed with IBM watsonx Code Assistant - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/articles/7039771">access.redhat.com</a></cite></p> hokn5 書籍「Podmanイン・アクション」の紹介 hatenablog://entry/6801883189074080187 2024-01-11T07:00:00+09:00 2024-01-16T21:58:44+09:00 Podmanイン・アクション Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。今回は私も執筆に参加した書籍「Podmanイン・アクション」について紹介いたします。 (2024年1月16日、更新)インフラエンジニアBooksのアーカイブURLと資料のリンクを追記しました。 Podmanイン・アクション 2023年9月に翻訳本である「Podmanイン・アクション」が発売されました。Podmanイン・アクションの原著は以前に紹介した「Podman in Action」です。 rheb.hatenablog.com Podmanイン・アクションはレッドハット株式会社… <p><figure class="figure-image figure-image-fotolife" title="Podmanイン・アクション"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tnk4on/20240111/20240111010246.jpg" alt="Podman&#x30A4;&#x30F3;&#x30FB;&#x30A2;&#x30AF;&#x30B7;&#x30E7;&#x30F3;" width="465" height="600" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>Podmanイン・アクション</figcaption></figure></p> <p>Red Hatでソリューションアーキテクトをしている田中司恩(<a href="https://twitter.com/tnk4on">@tnk4on</a>)です。今回は私も執筆に参加した書籍「Podmanイン・アクション」について紹介いたします。</p> <p>(2024年1月16日、更新)インフラエンジニアBooksのアーカイブURLと資料のリンクを追記しました。</p> <h2 id="Podmanインアクション">Podmanイン・アクション</h2> <p>2023年9月に翻訳本である「Podmanイン・アクション」が発売されました。Podmanイン・アクションの原著は以前に紹介した「Podman in Action」です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2Fpodman-in-action" title="(電子書籍)「Podman in Action」の紹介 - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/podman-in-action">rheb.hatenablog.com</a></cite></p> <p>Podmanイン・アクションはレッドハット株式会社の有志メンバーが集まって翻訳を行い、またそのチームメンバーもソリューションアーキテクト、コンサルタント、サポート、テクニカルトランスレーターと、さまざまな構成となっています。出版社の担当者を始め多くの方の協力を得ることで、原著のリリースから比較的短期間で翻訳本のリリースを行うことができました。書籍は B5変形版・376ページの技術書で、Part1からPart4までの4部10章+Appendixからなる構成です。実際に読んでみるとルートレスやセキュリティに関する部分は高密度で書かれており、かなり読み応えのある内容となっています。現時点でのPodmanに関する決定版書籍として十分にご活用いただけます。</p> <p>(出版社)秀和システムのサイト: <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.shuwasystem.co.jp%2Fbook%2F9784798070209.html" title="Podmanイン・アクション - 秀和システム あなたの学びをサポート!" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.shuwasystem.co.jp/book/9784798070209.html">www.shuwasystem.co.jp</a></cite></p> <h2 id="次世代コンテナエンジンの基礎からセキュリティまで徹底解説">次世代コンテナエンジンの基礎からセキュリティまで徹底解説</h2> <p>本のサブタイトルにもあるように「次世代コンテナエンジン」というキーワードがこの本の大きな特徴になっています。Linuxコンテナ(以下、コンテナ)についてはすでに多くのDockerに関する書籍が出版されています。そのようなある意味「情報過多」になっている状況でこの本が存在する意義とは、Dockerに対する新しいコンテナツール(コンテナエンジン)としてのPodmanの優位性があるからに他なりません。広く使われるDockerに対するPodmanの新しさとは何か、Podmanが生まれることになった背景やその思想とは何かといったことを知ることができ、単なるコンテナを実行するコマンドや技術解説に留まららない内容となっています。 コンテナ技術そのものを深く掘り下げていくとLinux(Linuxカーネル)のセキュリティ機能を利用していることを知ることになります。コンテナを使っていると、時にはそのセキュリティ機能が働きそれを回避するために<code>--privileged</code>オプションを付けて実行したくなることもあるでしょう。その時に重要なのはなぜコンテナの仕組みがそのようになっているのだろうか?と考え、思考を止めないことです。多くのDockerの解説本ではこのようなコンテナセキュリティの根本の部分に関して明確に書かれておらず、曖昧な知識のままになっている人も多いのではないでしょうか。Podmanの新しさとはこうしたDockerでは当たり前のDockerデーモンのアーキテクチャーやデフォルトではルート権限でDockerデーモンが実行されるといったセキュリティ面への課題解決を目指したところからアーキテクチャーが構築されているという点にもあります。その他にも、Dockerで実行するコンテナはDockerデーモンの子プロセスとして実行されるというアーキテクチャーとの違いや、コンテナイメージの短縮名がdocker.ioにハードコードされている問題などにもPodmanでは対処する機能や仕組みがあります。 つまり、DockerユーザーにとってPodmanについて学ぶことはコンテナへの理解をより一歩深く前進させることに他なりません。Dockerユーザーの方もこれからコンテナを始める初心者の方も是非一度、本書を手に取って内容をお確かめください。</p> <h2 id="宣伝インフラエンジニアBooks-30分でわかるPodmanインアクション">(宣伝)インフラエンジニアBooks 30分でわかる「Podmanイン・アクション」</h2> <p>来週1月15日に株式会社エーピーコミュニケーションズ様主催のオンラインイベント「<a href="https://infra-eng-books.connpass.com/event/303884/">インフラエンジニアBooks</a>」に登壇して本書「Podmanイン・アクション」の解説を行います。本記事では紹介しきれなかった実際の中身の見どころなどを紹介いたします。参加者の中から抽選で書籍プレゼントもありますので、ぜひ奮ってイベントにご参加ください! 登録は下記connpassのページからお願いいたします。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Finfra-eng-books.connpass.com%2Fevent%2F303884" title="インフラエンジニアBooks 30分でわかる「Podmanイン・アクション」 (2024/01/15 20:00〜)" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://infra-eng-books.connpass.com/event/303884">infra-eng-books.connpass.com</a></cite></p> <ul> <li>アーカイブ:<a href="https://youtu.be/ufTrB576A1U">https://youtu.be/ufTrB576A1U</a></li> <li>資料:<a href="https://speakerdeck.com/tnk4on/infra-engineer-books-podman-in-action">https://speakerdeck.com/tnk4on/infra-engineer-books-podman-in-action</a></li> </ul> tnk4on OVN-Kubernetes with OVN Interconnectのご紹介 hatenablog://entry/6801883189070978128 2024-01-05T19:32:58+09:00 2024-01-05T19:32:58+09:00 OVN-Kubernetes with OVN Interconnectのご紹介 <p>本ブログ記事は、OpenShift Advent Calendar 2023のエントリーです。(年を越してしまいましたが...)</p> <p>OpenShift v4.14のリリースノートに、「<a href="https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.14/html/release_notes/ocp-4-14-notable-technical-changes#ocp-4-14-ovn-k-interconnect">Open Virtual Network (OVN) 最適化によるスケーリングと安定性の向上</a>」という項目があり、下記のような記述になっています。</p> <blockquote><p>OpenShift Container Platform 4.14 では、Open Virtual Network Kubernetes (OVN-K) の最適化が導入されており、内部アーキテクチャーが変更されて運用遅延が短縮され、ネットワーキングコントロールプレーンのスケールとパフォーマンスに対する障壁が取り除かれています。ネットワークフローデータは、コントロールプレーンに情報を集中させるのではなく、クラスターノードにローカライズされるようになりました。これにより、操作遅延が短縮され、ワーカーノードとコントロールノード間のクラスター全体のトラフィックが削減されます。その結果、ノードが追加されるたびにネットワーク容量が追加され、大規模なクラスターが最適化されるため、クラスターネットワークのノード数は線形にスケールします。ネットワークフローはすべてのノードでローカライズされるため、コントロールプレーンノードの RAFT リーダー選出は必要なくなり、不安定性の主な原因が除去されました。ローカライズされたネットワークフローデータのさらなる利点は、ネットワーク上のノード損失の影響が障害が発生したノードに限定され、クラスターの残りのネットワークには影響を及ぼさないため、クラスターの障害シナリオに対する回復力が高まることです。詳細は、OVN-Kubernetes アーキテクチャー を参照してください。</p></blockquote> <p>この中身について簡単にご紹介します。</p> <p>...とその前に。本題に入る前に書いておきたいことがありまして、それはOpenShift/Kubernetes (もしくはCNIプラグイン) の観点からは、OVNK LegacyもOVNK Interconnectも同じように見える、という点です。したがいまして、OpenShift v4.13 (OVNK Legacy) からv4.14 (OVNK Interconnect) にアップグレードした場合でも、利用者(Pod/Service/Network Policy等のk8s API)の観点からは全く同じ使い方ができます。</p> <h1 id="OVN-KubernetesOVNOVN-InterconnectOVN-Kubernetes-with-OVN-Interconnect">OVN-Kubernetes、OVN、OVN Interconnect、OVN-Kubernetes with OVN Interconnect</h1> <p>まずはじめにOVN周りの用語を整理したいと思います。</p> <ul> <li><a href="https://www.ovn.org/en/">OVN (Open Virtual Network)</a>: Software Defined Networkingを実現するOSSのひとつ。主にOpen vSwitchコミュニティのメンバーで開発されています。さまざまなCMS (Cloud Management System、仮想基盤やコンテナ基盤のコントローラと思ってください) と連携することを想定しています。具体的には、OpenStack、oVirt、Docker、Kubernetes等から使用することができます。</li> <li><a href="https://docs.ovn.org/en/latest/tutorials/ovn-interconnection.html">OVN Interconnect</a>: OVNのクラスター間をGeneveトンネルで結ぶことで、複数のOVNクラスターを接続するOVNの機能。OVN-ICと略すこともあります</li> <li><a href="https://github.com/ovn-org/ovn-kubernetes">OVN-Kubernetes</a>: Kubernetes上でOVNを使ってPod/Serviceの通信を行うためのCNIプラグイン。OpenShiftでは、OVN-Kubernetesはv4.2からTech Previewとして導入され、v4.6から正式サポートのCNIプラグインとなりました。v4.12以降はOVN-KubernetesがデフォルトのCNIプラグインです。OVNK、OVN-Kなどと略すこともあります</li> <li>OVN-Kubernetes with OVN Interconnect: OVN-Kubernetesの中でOVN Interconnectを使う構成のこと。OVNK-ICと略すこともあります</li> </ul> <p>冒頭のOpenShift v4.14のリリースノートの文言は、OpenShiftでOVN-Kubernetesを使う際の構成が、従来のOVN-KubernetesからOVN-Kubernetes with OVN Interconnectに変わった、ということを意味しているのでした。</p> <h1 id="従来のOVN-Kubernetesの構成">従来のOVN-Kubernetesの構成</h1> <p>OVNを構成するコンポーネントは、図1のようになっています。</p> <p><figure class="figure-image figure-image-fotolife" title="図1: OVNの構成要素"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/o/orimanabu/20240104/20240104232823.png" width="1138" height="605" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>図1: OVNの構成要素</figcaption></figure></p> <p>従来のOVN-Kubernetes (OVNK Legacy) では図2のように、OVNを構成するコンポーネントのうち、コントロールプレーンを構成するNorthboud DB (nbdb)、northd、Southbound DB (sbdb) がcontrol planeノードで <code>ovnkube-master</code> というPodとして稼働し、データプレーンとなるovn-controllerおよびovs-vswitchd、ovsdb-serverが全ノードで稼働します。</p> <p><figure class="figure-image figure-image-fotolife" title="図2: OVN-Kubernetes Legacyの構成要素"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/o/orimanabu/20240105/20240105015200.png" width="1167" height="578" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>図2: OVN-Kubernetes Legacyのコンポーネント</figcaption></figure></p> <p>OVN-Kubernetesのおおまかな動きとしては、OVNのオーバーレイ論理ネットワークに変化が起きた場合 (例えばPodを新たにデプロイした場合)、ovnkube-masterがk8sのAPIリソースの更新を検知してNorthbound DB (nbdb) にオーバーレイ論理ネットワークの更新を書き込みます。その後northdがそれを検知して論理フローに変換してSouthbound DB (sbdb) に書き込み、ovn-controllerがそれを検知して自ノードのOVSブリッジに必要なOpenFlowのフローを投入します。何らかのイベントによってノードのポート状態が変化した場合 (例えばPodが死んだ場合) は逆に、該当Podが稼働するノードのovn-controllerがそれを検知してSouthbound DBに書き込み、northdがそれを検知してNorthbound DBを更新し、最後にovnkube-masterがk8sのAPIサーバ経由でetcdにその情報を記録します。</p> <p>nbdb, sbdbは各control planeノードで稼働するOVSDBで、OVNK Legacyではそれぞれが冗長化のためにcontrol planeノード間でRAFTクラスターを構成します。また各ノードのovn-controllerはcontrol planeノードのsbdbにOVSDB Management Protocolで接続します。このためOVNK Legacyには、ノード数が増えるとその分sbdbに対する接続数が増え、またPodやServiceが増えるとその分「control planeノードのsbdb」↔「各ノードのovn-controller」の通信が増える、という課題がありました。</p> <h1 id="OVN-Kubernetes-with-OVN-Interconnectionの構成">OVN-Kubernetes with OVN Interconnectionの構成</h1> <p>OVN Interconnectは元々、Kubernetesとは関係なく、複数のOVNクラスターを接続するために考案されたアーキテクチャです。これをOVN-Kubernetesに応用したものが、OVNK Interconnectです。OVNK Interconnectの構成は図3のようになります。</p> <p><figure class="figure-image figure-image-fotolife" title="図3: OVN-Kubernetes Interconnectの構成要素"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/o/orimanabu/20240105/20240105015228.png" width="1168" height="577" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>図3: OVN-Kubernetes Legacyのコンポーネント</figcaption></figure></p> <p>OVNK Legacyでは、OpenShift/Kubernetesクラスター1つに対してOVNクラスターを1つデプロイしていましたが、OVNK Interconnectでは、各ノードごとに1つのOVNスタックを配置します。具体的には、OVNのコントロールプレーンとなるnbdb, sbdb, northdといったコンテナが、control planeノードではなく、全ノード上の <code>ovnkube-node</code> Pod内で稼働します。OVNK Legacyでは、nbdbおよびsbdbはcontrol planeノード上で稼働し、OpenShift/Kubernetesクラスター全体のオーバーレイ論理ネットワークの情報を格納していましたが、OVNK Interconnectでは各ノードに分散し、自ノードの論理ネットワークの情報だけを持ちます。また、OVNK Legacyのnbdb, sbdbは3台のcontrol planeノード間でRAFTクラスターを構成して冗長化しましたが、OVNK Interconnectではシングル構成で冗長化はしません。結果としてOVNK Interconnectでは、OVSDB Management Protocolによる通信は完全にノード内に閉じる形になります。</p> <p>control planeで稼働するPod (<code>ovnkube-cluster-manager</code>) はクラスター全体の情報 (ノードごとのサブネット、Egress IP等) を管理し、nbdbやsbdbにはアクセスしません (情報は主にノードのannotationに記録します)。</p> <h1 id="OVNK-Interconnectにすることで期待できること">OVNK Interconnectにすることで期待できること</h1> <p>OVN-KubernetesをOVN Interconnect化し、各ノードで独立したOVNスタックを持つことで、下記のようなメリットを享受することができます。</p> <ul> <li>OVN的な処理のレイテンシーの改善 (Legacyでは論理ネットワーク全体のDB更新が必要だったのに対して、ICでは各ノードが自ノード上の論理ネットワークのみを処理するため)</li> <li>スケーラビリティの改善 (Legacyではnbdb, sbdb, northdがボトルネックになっていたが、ICではこれらを各ノードに分散したため)</li> <li>control planeノードの負荷の軽減 (OVNのコントロールプレーンコンポーネントであるnbdb, sbdb, northdの負荷が各ノードに分散するため)</li> <li>ノード間通信のシンプル化 (ICではOVSDB Management Protocolによるノード間通信が必要ないため)</li> <li>TLS証明書管理の軽減 (Legacyではノード間のOVSDB Management Protocolで使用するTLS証明書を管理する必要があったのに対して、ICではUNIXドメイン通信で済むため)</li> <li>OVSDBのシングル構成化による運用負荷の軽減 (ICではRAFTによるクラスター化を行わないため)</li> </ul> <p>このメリットは、特にHosted Control Planeで効いてきます。Hosted Control Planeとは</p> <ul> <li>ひとつのManagement cluster: 各Hosted clusterのcontrol planeの機能をPodとして収容するOpenShiftクラスター</li> <li>複数のHosted cluster: workerノードのみのOpenShiftクラスター</li> </ul> <p>という形で複数クラスターを管理する方式です。OVNK Interconnectにすることで、control planeのコンポーネントが小さくなり、より多くのHosted clusterをManagement clusterでホストできるようになります。</p> <p>AWSでのマネージドサービスであるRed Hat OpenShift Service on AWS (ROSA)では、Hosted clusterとしてOpenShiftクラスターをデプロイすることが可能になっています(現時点ではリージョンによってはまだ使用できませんが)。ROSAのHosted Control Planeでは、Management clusterはRed Hat SREが管理するので、control planeのコンポーネントがスリム化するのはとてもうれしいのでした。</p> <p>ROSA with HCPについては、こちらの記事をご参照ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F202312-rosa-hcp-trial" title="Red Hat OpenShift Service on AWS (ROSA)を無料で試してみよう - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/202312-rosa-hcp-trial">rheb.hatenablog.com</a></cite></p> <p>一方で、OVNK Interconnectのデメリットとして下記が考えられます。</p> <ul> <li>ログの増加 (各ノードでOVNスタックを持つため)</li> <li>各ノードのCPU/メモリ負荷の増加 (各ノードでnbdb, sbdb, northdを動かすため)</li> <li>論理ネットワークのパケットトレースの複雑化 (ovnkube-trace等のツールを改良中)</li> </ul> <p>とはいえ、workerノードのリソースがかつかつな場合以外は、基本的にはそれほど大きな影響はないかと思います。</p> <h1 id="論理ネットワーク">論理ネットワーク</h1> <p>OVNで作る仮想的な論理ネットワークの構成も、OVNK LegacyとOVNK Interconnectで少し異なります。OVNK Legacyの場合は<a href="https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.13/html/networking/ovn-kubernetes-architecture-assembly#ovn-kubernetes-logical-architecture-con_ovn-kubernetes-architecture">図4</a>のようなトポロジーです。ノード間を接続する論理ルーター <code>ovn_cluster_router</code> と論理スイッチ <code>join</code> が各ノードに分散します。</p> <p><figure class="figure-image figure-image-fotolife" title="図4: OVN-Kubernetesのロジカルネットワーク(v4.13)"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/o/orimanabu/20231230/20231230170615.png" width="1200" height="947" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>図4: OVN-Kubernetesのロジカルネットワーク(v4.13)</figcaption></figure></p> <p>一方、OVNK Interconnectの場合は<a href="https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.14/html/networking/ovn-kubernetes-architecture-assembly#ovn-kubernetes-logical-architecture-con_ovn-kubernetes-architecture">図5</a>のようになります。<code>ovn_cluster_router</code> および <code>join</code> スイッチは分散せずに各ノード内に配置します。その代わりに、ノード間を接続する <code>transit_switch</code> がノードに分散する形で作られます。</p> <p><figure class="figure-image figure-image-fotolife" title="図5: OVN-Kubernetesのロジカルネットワーク(v4.14)"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/o/orimanabu/20231230/20231230170659.png" width="1200" height="1119" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>図5: OVN-Kubernetesのロジカルネットワーク(v4.14)</figcaption></figure></p> <h1 id="最後に">最後に</h1> <p>冒頭にも書きましたが、細かい内部の話は、ユーザーの立場からはぶっちゃけあんまり気にしなくても大丈夫です。今までと同じようにご利用いただければと思います。</p> <h1 id="参考文献">参考文献</h1> <ul> <li>ovscon2019: <a href="https://www.openvswitch.org/support/ovscon2019/#3.4F">Multi-tenant Inter-DC tunneling with OVN (Han Zhou, eBay)</a> (<a href="https://www.openvswitch.org/support/ovscon2019/day1/1501-Multi-tenant%20Inter-DC%20tunneling%20with%20OVN(4).pdf">slides</a>, <a href="https://youtu.be/YoAHurcAToE">video</a>) (OVN Interconnectについての最初の講演です。OVN-Kubernetesの話はありません)</li> <li>ovscon2022: <a href="https://www.openvswitch.org/support/ovscon2022/#t2">Using OVN Interconnect for scaling (OVN) Kubernetes deployments</a> (<a href="https://www.openvswitch.org/support/ovscon2022/slides/OVN-IC-OVSCON.pdf">slides</a>, <a href="https://youtu.be/TEl6OxjwmlQ">video</a>) (OVNK-ICについての講演です。開発中の話なので、Podの構成等が今と若干異なる部分があります)</li> <li>blog: <a href="https://www.redhat.com/en/blog/how-the-new-ovn-kubernetes-architecture-helps-with-scaling-openshift">How the new OVN Kubernetes architecture helps with scaling OpenShift</a> (OVNK-ICについての最新ブログ記事)</li> <li>doc: <a href="https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.14/html/networking/ovn-kubernetes-architecture-assembly#ovn-kubernetes-logical-architecture-con_ovn-kubernetes-architecture">25.2.7. OVN-Kubernetes の論理アーキテクチャー</a> (公式ドキュメント)</li> <li>OpenShift.Run 2023: <a href="https://speakerdeck.com/orimanabu/ovn-kubernetes-introduction-ja-2023-01-27">OVN-Kubernetes Deep Dive - OCP v4.12</a> (OVNK Legacyについての日本語講演資料)</li> </ul> <h1 id="余談">余談</h1> <p>通常OVN Interconnectを構成するには、複数のOVNデプロイメントを管理し、クラスター間の接続情報を管理するための「ovn-ic (OVN Interconnection controller)」というデーモン(OVN-ICと紛らわしいですが、だいたい文脈でわかります)およびIC_NB/IC_SBというデータベースが必要です。しかし、OVN-Kubernetes with OVN Interconnectの場合は、全体の構成はKubernetesのetcdに情報があり、ovnkube-cluster-managerがovn-ic的な役割を果たすため、ovn-icおよびIC_NB/IC_SBは存在しません。</p> orimanabu 2024年のAnsibleとわたし hatenablog://entry/6801883189069425252 2023-12-25T00:01:14+09:00 2023-12-25T10:54:14+09:00 みなさんメリークリスマス! Red Hatのさいとう(@saito_hideki)です。 この記事は、Ansible Advent Calendar/Red Hat Advent Calendarの2023年最終日の記事です。 ここ数年、Ansible Advent Calendar/Red Hat Adivent Calendarでは、最終日に翌年のAnsibleプロジェクトに関連する動向を予想したお話を書いてきました。今回は、Event Driven Ansibleのダッシュボードを含めたコントロールプレーンを提供するためのアップストリームプロジェクトである EDA Serverを取り上げ… <p>みなさんメリークリスマス! Red Hatのさいとう(<a href="https://twitter.com/saito_hideki">@saito_hideki</a>)です。</p> <p>この記事は、<a href="https://qiita.com/advent-calendar/2023/ansible">Ansible Advent Calendar</a>/<a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar</a>の2023年最終日の記事です。</p> <p>ここ数年、Ansible Advent Calendar/Red Hat Adivent Calendarでは、最終日に翌年のAnsibleプロジェクトに関連する動向を予想したお話を書いてきました。今回は、Event Driven Ansibleのダッシュボードを含めたコントロールプレーンを提供するためのアップストリームプロジェクトである <a href="https://github.com/ansible/eda-server/">EDA Server</a>を取り上げてます。</p> <p>具体的には、2024年のEDA Serverを体験するために、現在の開発版のインストールと起動方法についてご紹介しようと思います。今年も文字多めです。</p> <h5 id="2023年に公開された新技術">2023年に公開された新技術</h5> <p>2023年のトピックは、<a href="https://twitter.com/akira6592">@akira6592</a>さんが、Ansible Advent Calendar 2023 12月24日の記事(<a href="https://tekunabe.hatenablog.jp/entry/2023/12/24/ansible_recap2023">[Ansible] 2023年の Ansible 関連リリースや動向まとめ</a>)としてまとめてくれています(感謝!)</p> <p>そこで言及されている通り、2023年には新たに以下の2つのプロダクトがリリースされました。</p> <ol> <li><a href="https://www.redhat.com/ja/technologies/management/ansible/event-driven-ansible">Event-Driven-Ansible</a> -> 以降EDA</li> <li><a href="https://www.redhat.com/ja/technologies/management/ansible/ansible-lightspeed">Ansible Lightspeed</a> -> 以降 Lightspeed</li> </ol> <p>これらについては、ダウンストリームのRed Hat Ansible Automation Platform 2.4の新機能として、<a href="https://rheb.hatenablog.com/entry/aap24-1">Ansible Automation Platform 2.4 注目の新機能紹介</a>でまとめられていますので、興味のある方はご一読ください。</p> <p>EDAとLightspeedは、これまでにない新しい試みでした。2024年は、これらのプロジェクトの機能追加とバグフィックスを中心として「改修と改善」がメイントピックになりそうで、現時点での予想として来年はびっくりするような飛び道具は、おそらくなしです。</p> <h4 id="EDA-Serverの2024年を覗く">EDA Serverの2024年を覗く</h4> <p>今回の開発環境は以下のスペックのFedora39のVirtualMachineです。</p> <pre class="code" data-lang="" data-unlink>OS: Fedora39(x86_64) CPU: 2 Memory: 4096 HDD: 20GB</pre> <p>以降の手順は、基本的には公式ドキュメント<a href="https://github.com/ansible/eda-server/blob/main/docs/development.md">Development environment setup</a>に従ってFedora39にEDA Serverをインストールすることを想定して書いています。<a href="https://github.com/ansible/eda-server/blob/main/poetry.lock">poetry.log</a>でガッチリとPythonライブラリのバージョンが固定されているので、開発環境のディストリビューションやバージョンを外すとちょっと厄介です。注意しましょう。</p> <p>EDA Serverのビルドに必要となるパッケージ群をインストールします。今回は、プラットフォームにFedora39を利用し、コンテナエンジンとしてPodmanを利用します。</p> <pre class="code" data-lang="" data-unlink>$ sudo dnf install libffi-devel libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel openldap-devel python3.11 python3.11-devel podman</pre> <p>podman.socketサービスをrootlessで起動します。サービスのステータスとAPIアクセスを念のため確認しておきましょう。</p> <pre class="code" data-lang="" data-unlink>$ systemctl --user enable --now podman.socket Created symlink /home/hsaito/.config/systemd/user/sockets.target.wants/podman.socket → /usr/lib/systemd/user/podman.socket. $ systemctl --user status podman.socket ● podman.socket - Podman API Socket Loaded: loaded (/usr/lib/systemd/user/podman.socket; enabled; preset: disabled) Active: active (listening) since Sun 2023-12-24 21:45:10 JST; 22s ago Triggers: ● podman.service Docs: man:podman-system-service(1) Listen: /run/user/1000/podman/podman.sock (Stream) CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/podman.socket $ curl -s --unix-socket /run/user/1000/podman/podman.sock http://d/v3.0.0/libpod/info | jq .version { &#34;APIVersion&#34;: &#34;4.8.1&#34;, &#34;Version&#34;: &#34;4.8.1&#34;, &#34;GoVersion&#34;: &#34;go1.21.4&#34;, &#34;GitCommit&#34;: &#34;&#34;, &#34;BuiltTime&#34;: &#34;Tue Dec 5 21:00:50 2023&#34;, &#34;Built&#34;: 1701777650, &#34;OsArch&#34;: &#34;linux/amd64&#34;, &#34;Os&#34;: &#34;linux&#34; }</pre> <p>docker-composeをインストールします。Ansibleのさまざまなプロジェクト(Ansible Core/AWX/Galaxy NG/EDA Server等々)の開発環境の構築手法は、プロジェクト毎にバラバラでまったく統一されていませんが、「コンテナをビルドしてdocker-composeでサービスとして起動する」という方法が主流です。</p> <pre class="code" data-lang="" data-unlink>$ mkdir ~/.local/bin $ curl -L https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64 &gt; ~/.local/bin/docker-compose $ chmod +x ~/.local/bin/docker $ docker-compose --version Docker Compose version v2.23.3</pre> <p>EDA Serverの開発環境用にvirtualenvを作成します。Fedora39のデフォルトPythonインタプリタは3.12ですが、EDA Serverの開発環境は、現時点(2023年12月25日)では、<a href="https://github.com/ansible/eda-server/blob/main/pyproject.toml#L28">Python3.9から3.11までを想定している</a>ため、ここでは事前にインストールしておいたPython.3.11を利用しています。</p> <pre class="code" data-lang="" data-unlink>$ python3.11 -m venv ~/work/venv $ source ~/work/venv/bin/activate (venv) pip install -U pip</pre> <p>EDA Serverは、Djangoのアプリケーションです。起動に必要とするPythonライブラリ群はpoetryとre-commitを利用してインストールします。そのまえに、これらのツールをpipでインストールしておきましょう。</p> <pre class="code" data-lang="" data-unlink>(venv)$ pip install pre-commit (venv)$ pip install poetry</pre> <p>docker-composeや、EDA Serverの管理コマンドのラッパーとして振る舞ってくれるTaskfile(taskコマンド)をインストールします。taskコマンドがラップしてくれる機能は<a href="https://github.com/ansible/eda-server/blob/main/Taskfile.dist.yaml">こちら</a>から確認できます。</p> <p>Taskfileやpoetryは、他のプロジェクトの開発環境構築では、これまで使われてこなかった仕組みなので、ちょっと新鮮です。</p> <pre class="code" data-lang="" data-unlink>(venv)$ sh -c &#34;$(curl --location https://taskfile.dev/install.sh)&#34; -- -d -b ~/.local/bin (venv)$ task --version Task version: v3.33.1 (h1:JJSRANHH7RQrr5Z2CTvSnTH7iWlfBlKV2W2O0JiZoLk=)</pre> <p>ソースコードをチェックアウトし、taskコマンドでビルドに必要となるモジュール群をインストールします。</p> <pre class="code" data-lang="" data-unlink>(venv)$ git clone https://github.com/ansible/eda-server.git/ (venv)$ cd eda-server (venv)$ task dev:init task: [dev:init] poetry install -E dev Installing dependencies from lock file Package operations: 109 installs, 11 updates, 0 removals • Downgrading certifi (2023.11.17 -&gt; 2023.7.22): Pending... • Downgrading cffi (1.16.0 -&gt; 1.15.1): Pending... • Downgrading charset-normalizer (3.3.2 -&gt; 3.1.0): Pending... • Downgrading idna (3.6 -&gt; 3.4): Pending... • Installing pyasn1 (0.5.0): Pending... • Downgrading urllib3 (2.1.0 -&gt; 1.26.15): Pending... [...] Installing the current project: aap-eda (0.1.0) task: [dev:init] pre-commit install pre-commit installed at .git/hooks/pre-commit</pre> <p>続いて、taskコマンドからdockerコンテナをビルドします。ここではdocker-composeを利用するので、環境変数DOCKER_HOSTに、podman.serviceのsocketファイルを指定してから実行します。DOCKER_HOSTの設定は、必要に応じて.bashrcなどのrcファイルに追加しておいてください。</p> <pre class="code" data-lang="" data-unlink>(venv)$ podman info -f &#39;{{.Host.RemoteSocket.Path}}&#39; /run/user/1000/podman/podman.sock (venv)$ export DOCKER_HOST=&#34;unix://`podman info -f &#39;{{.Host.RemoteSocket.Path}}&#39;`&#34; (venv)$ echo $DOCKER_HOST DOCKER_HOST=unix:///run/user/1000/podman/podman.sock (venv)$ docker-compose ls NAME STATUS CONFIG FILES (venv)$ task docker:build task: [docker] docker-compose -p eda -f tools/docker/docker-compose-dev.yaml build [+] Building 5.1s (0/1) docker-container:default =&gt; [eda-api internal] booting buildkit 5.1s =&gt; =&gt; pulling image moby/buildkit:buildx-stable-1 5.1s [...] =&gt; =&gt; exporting layers 14.3s =&gt; =&gt; exporting manifest sha256:4051e5517b307516aa49095b0b1aa70647fa0395ca993e15b4a36bafdff52d78 0.1s =&gt; =&gt; exporting config sha256:c91c61d366dc2b91c0b0e6aa7d9814c0e9ac37e53ae7d242c1fbf5aaa7c1d863 0.1s =&gt; =&gt; sending tarball 14.1s =&gt; [eda-api] importing to docker (venv)$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/aap-eda latest c91c61d366dc 2 minutes ago 1 GB docker.io/moby/buildkit buildx-stable-1 be698b50dea4 3 weeks ago 173 MB</pre> <p>環境変数EDA_CONTROLLERにAutomation controllerやAWXのURLを指定し、taskコマンドでEDA Serverを起動します。<code>task docker:up</code>は<code>docker-compose up -d</code>を実行します</p> <pre class="code" data-lang="" data-unlink>(venv)$ export EDA_CONTROLLER_URL=https://&lt;IPADDRESS&gt; (venv)$ task docker:up [...] [+] Running 14/14 ✔ Network eda_default Created 0.0s ✔ Volume &#34;eda_podman_data&#34; Created 0.1s ✔ Volume &#34;eda_postgres_data&#34; Created 0.1s ✔ Container eda-redis-1 Healthy 1.0s ✔ Container eda-podman-pre-setup-1 Started 1.0s ✔ Container eda-postgres-1 Healthy 1.5s ✔ Container eda-podman-1 Started 0.6s ✔ Container eda-eda-scheduler-1 Started 0.7s ✔ Container eda-eda-api-1 Healthy 0.4s ✔ Container eda-eda-activation-worker-2 Started 0.4s ✔ Container eda-eda-ui-1 Started 0.8s ✔ Container eda-eda-ws-1 Started 0.8s ✔ Container eda-eda-default-worker-1 Started 0.7s ✔ Container eda-eda-activation-worker-1 Started 0.4s</pre> <p>最後に、taskコマンドから管理ユーザアカウント(admin)のパスワードを設定しましょう。実際には<code>aap-eda-manage changepassword</code>を実行しています。</p> <pre class="code" data-lang="" data-unlink>(venv)$ $ task manage -- changepassword admin Changing password for user &#39;admin&#39; Password: changeme2024 Password (again): changeme2024 Password changed successfully for user &#39;admin&#39;</pre> <p>EDA Serverのフロントエンドは、Port:8443でListenします。firewalldでPort:8443を許可しておきましょう。</p> <pre class="code" data-lang="" data-unlink>(venv)$ sudo firewall-cmd --zone=public --permanent --add-port=8443/tcp success (venv)$ sudo firewall-cmd --reload success</pre> <p>ダッシュボードにアクセスし、adminアカウントでログインしてみましょう。<code>/eda/</code>を忘れずに。</p> <ul> <li><code>https://EDA_SERVER_URL:8443/eda/</code></li> </ul> <p>ログイン画面が表示され、これで<a href="https://github.com/ansible/eda-server">eda-serverリポジトリ</a>のmainブランチからビルドしたEDA Serverにログインできます。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/p/pyde/20231224/20231224231314.png" width="1200" height="988" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/p/pyde/20231224/20231224231320.png" width="1200" height="1006" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h5 id="起動したコンテナの確認">起動したコンテナの確認</h5> <p>taskコマンドで起動したコンテナには、ビルド元になったソースコードのパスがマウントされています。必要に応じて自身でソースコードを改変し、taskコマンドでdown->upすれば、改修内容もチェックできますね。</p> <pre class="code" data-lang="" data-unlink>(venv)$ podman inspect eda-eda-api-1 [...] &#34;Mounts&#34;: [ { &#34;Type&#34;: &#34;bind&#34;, &#34;Source&#34;: &#34;/home/hsaito/work/eda-server&#34;, &#34;Destination&#34;: &#34;/app/src&#34;, &#34;Driver&#34;: &#34;&#34;, &#34;Mode&#34;: &#34;&#34;, &#34;Options&#34;: [ &#34;rbind&#34; ], &#34;RW&#34;: true, &#34;Propagation&#34;: &#34;rprivate&#34; } ], [...]</pre> <p>サービスの停止と起動方法は以下の通りです。</p> <pre class="code" data-lang="" data-unlink>(venv)$ task docker:down (venv)$ task docker:up</pre> <h4 id="まとめ">まとめ</h4> <p>この記事では、EDA Serverをmainブランチからビルドすることで、コントロールプレーンの最新のダッシュボードを含めた機能を体験する方法をご紹介しました。2024年は「改修と改善」の年になるでしょう。個人的には2023年は何だか忙しく、アップストリームに貢献することがほとんできない年でした。今回の記事に書いた開発版の構築手法を活用しながら、2024年はもう少しアップストリームに貢献したいなと考えてます。みなさんも是非 ;)</p> <p>それではみなさん、2024年もHappy Automation!</p> <h4 id="参考情報">参考情報</h4> <ul> <li><a href="https://tekunabe.hatenablog.jp/entry/2023/12/24/ansible_recap2023">[Ansible] 2023年の Ansible 関連リリースや動向まとめ</a></li> <li><a href="https://rheb.hatenablog.com/entry/aap24-1">Ansible Automation Platform 2.4 注目の新機能紹介</a></li> <li><a href="https://rheb.hatenablog.com/entry/podman3-rootless-docker-compose">【Podman v3】ルートレスモードでdocker-composeを実行する</a></li> <li><a href="https://github.com/ansible/eda-server/blob/main/docs/development.md">Development environment setup</a></li> </ul> pyde cisco.iosxr.iosxr_config モジュールの match に与える4種それぞれのオプションの違いについて hatenablog://entry/6801883189069323322 2023-12-24T12:47:06+09:00 2023-12-24T12:48:56+09:00 こんにちは。Red Hat にて Ansible Automation Platform のテクニカルサポートをしている呉です。 ※暖房が効かなくなってしまい、極寒の家で毛布被って体育座りしながら書いてますので、以下、暖い心で読んでいただけましたら幸いです。;) 今回は、Ansible モジュールの小ネタの一つとして cisco.iosxr.iosxr_config モジュール(https://docs.ansible.com/ansible/latest/collections/cisco/iosxr/iosxr_config_module.html)の match に与える事のできる以下の… <p>こんにちは。Red Hat にて Ansible Automation Platform のテクニカルサポートをしている呉です。</p> <p>※暖房が効かなくなってしまい、極寒の家で毛布被って体育座りしながら書いてますので、以下、暖い心で読んでいただけましたら幸いです。;)</p> <p>今回は、Ansible モジュールの小ネタの一つとして <code>cisco.iosxr.iosxr_config</code> モジュール(<a href="https://docs.ansible.com/ansible/latest/collections/cisco/iosxr/iosxr_config_module.html">https://docs.ansible.com/ansible/latest/collections/cisco/iosxr/iosxr_config_module.html</a>)の <code>match</code> に与える事のできる以下のオプションのそれぞれの違いについて紹介したいと思います。</p> <ul> <li>line (default)</li> <li>strict</li> <li>exact</li> <li>none</li> </ul> <p>手始めに、以下はドキュメントに記載されている <code>match</code> の説明文を ChatGPT に翻訳してもらったものになります。</p> <blockquote><p>このモジュールに、一連のコマンドを現在のデバイス設定に対してどのように照合するかを指示します。matchがlineに設定されている場合、コマンドは行ごとに照合されます。matchがstrictに設定されている場合、コマンド行は位置に応じて照合されます。matchがexactに設定されている場合、コマンド行は完全に一致していなければなりません。最後に、matchがnoneに設定されている場合、モジュールはソース設定をリモートデバイス上の実行中の設定と比較しようとはしません。</p></blockquote> <p>私は正直、こちらを読んでもよく理解できませんでしたので、検証してみました :) 以下にその結果を記載します。</p> <h2 id="1-line-default-について">1. line (default) について</h2> <p>こちらは、<code>cisco.iosxr.iosxr_config</code> モジュールの <code>lines</code> に与えられたコンフィグが <code>running-config</code> に存在しているかどうかを確認します。ただし、投入されているコンフィグの順番は考慮しません。あくまで、コンフィグが存在しているかどうかのみを確認します。</p> <p>※例:</p> <p>running-config</p> <pre class="code" data-lang="" data-unlink>ipv4 access-list IPv4-ACL 10 deny tcp any 1.1.1.1 0.0.0.255 20 permit tcp any 2.2.2.2 0.0.0.255 30 permit tcp any 3.3.3.3 0.0.0.255 40 permit tcp any any</pre> <p>例えば、上記のコンフィグに対し以下のプレイブックが渡されても、既にコンフィグが存在するので、iosxr_config モジュールは何もしません。</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink><span class="synStatement">- </span><span class="synIdentifier">name</span><span class="synSpecial">:</span> iosxr_config <span class="synConstant">&quot;line&quot;</span> test <span class="synIdentifier">cisco.iosxr.iosxr_config</span><span class="synSpecial">:</span> <span class="synIdentifier">lines</span><span class="synSpecial">:</span> <span class="synStatement">- </span><span class="synConstant">20</span> permit tcp any 2.2.2.2 0.0.0.255<span class="synComment"> #&lt;--- 順番が入れ替わっている箇所</span> <span class="synStatement">- </span><span class="synConstant">10</span> deny tcp any 1.1.1.1 0.0.0.255<span class="synComment"> #&lt;--- 順番が入れ替わっている箇所</span> <span class="synStatement">- </span><span class="synConstant">30</span> permit tcp any 3.3.3.3 0.0.0.255 <span class="synStatement">- </span><span class="synConstant">40</span> permit tcp any any <span class="synIdentifier">parents</span><span class="synSpecial">:</span> ipv4 access-list IPv4-ACL <span class="synIdentifier">match</span><span class="synSpecial">:</span> line </pre> <h2 id="2-strict-について">2. strict について</h2> <p>こちらは、<code>cisco.iosxr.iosxr_config</code> モジュールの <code>lines</code> に与えられたコンフィグが <code>running-config</code> に存在しているかどうかだけでなく、<code>lines</code> に与えられた順番通りに存在しているかどうかまでを確認します。コンフィグが存在していても、設定されているコンフィグの順番に差分がある場合には、<code>lines</code> に与えられた順番通りになるよう変更を試みます。</p> <p>※例:</p> <p>running-config</p> <pre class="code" data-lang="" data-unlink>ipv4 access-list IPv4-ACL 10 deny tcp any 1.1.1.1 0.0.0.255 20 permit tcp any 2.2.2.2 0.0.0.255 30 permit tcp any 3.3.3.3 0.0.0.255 40 permit tcp any any</pre> <p>例えば、上記のコンフィグに対し以下のプレイブックが実行された場合、順番に差分がありますので、<code>iosxr_config</code> モジュールは設定変更を試みます。</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink><span class="synStatement">- </span><span class="synIdentifier">name</span><span class="synSpecial">:</span> iosxr_config <span class="synConstant">&quot;strict&quot;</span> test <span class="synIdentifier">cisco.iosxr.iosxr_config</span><span class="synSpecial">:</span> <span class="synIdentifier">lines</span><span class="synSpecial">:</span> <span class="synStatement">- </span><span class="synConstant">20</span> permit tcp any 2.2.2.2 0.0.0.255 <span class="synStatement">- </span><span class="synConstant">10</span> deny tcp any 1.1.1.1 0.0.0.255 <span class="synStatement">- </span><span class="synConstant">30</span> permit tcp any 3.3.3.3 0.0.0.255 <span class="synStatement">- </span><span class="synConstant">40</span> permit tcp any any <span class="synIdentifier">parents</span><span class="synSpecial">:</span> ipv4 access-list IPv4-ACL <span class="synIdentifier">match</span><span class="synSpecial">:</span> strict </pre> <h2 id="3-exact-について">3. exact について</h2> <p><code>exact</code> は <code>strict</code> と非常によく似た機能なのですが、<code>strict</code> との相違点としては、<code>cisco.iosxr.iosxr_config</code> モジュールの <code>lines</code> に与えられたコンフィグと <code>running-config</code> との比較だけでなく、<code>parents</code> に指定されたブロック全体の「行数」まで比較を行う点にあります。</p> <p>※例:</p> <p>running-config</p> <pre class="code" data-lang="" data-unlink>interface GigabitEthernet0/0/0/1 description ansible test hogehoge shutdown</pre> <p>例えば、上記のコンフィグを持つインターフェイス(GigabitEthernet0/0/0/1)に以下のプレイブックを実行した場合、何度実行しても"TEST EXACT"タスクの <code>lines</code> に指定した設定が常に適用され、status は changed となります。理由としましては、<code>lines</code> に与えられたコンフィグの合計の行数が 2 行(interface GigabitEthernet0/0/0/1 と description ansible test hogehoge) に対し、現在の <code>running-config</code> が 3 行となるので、差分があると判定し、変更を試みるためです。</p> <p>サンプル Playbook 1</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink><span class="synPreProc">---</span> <span class="synStatement">- </span><span class="synIdentifier">hosts</span><span class="synSpecial">:</span> example01.com <span class="synIdentifier">gather_facts</span><span class="synSpecial">:</span> <span class="synConstant">false</span> <span class="synIdentifier">tasks</span><span class="synSpecial">:</span> <span class="synStatement">- </span><span class="synIdentifier">name</span><span class="synSpecial">:</span> TEST EXACT <span class="synIdentifier">cisco.iosxr.iosxr_config</span><span class="synSpecial">:</span> <span class="synIdentifier">lines</span><span class="synSpecial">:</span> <span class="synStatement">- </span>description ansible test hogehoge <span class="synComment"># - shutdown</span> <span class="synIdentifier">parents</span><span class="synSpecial">:</span> interface GigabitEthernet0/0/0/1 <span class="synIdentifier">match</span><span class="synSpecial">:</span> exact </pre> <p>尚、<code>strict</code> の場合は、<code>lines</code> に指定した各行レベルでの比較のみを行います。 例えば以下のプレイブック(match: strict の箇所以外は サンプル Playbook 1と同じ)を実行しても、<code>lines</code> に指定した <code>description</code> の設定が <code>running-config</code> と一致している場合は、設定の変更は試みられず、プレイブックの実行 status は常に ok となります。これは、ブロック内の行数については比較しないためです。</p> <p>サンプル Playbook 2</p> <pre class="code lang-yaml" data-lang="yaml" data-unlink><span class="synPreProc">---</span> <span class="synStatement">- </span><span class="synIdentifier">hosts</span><span class="synSpecial">:</span> example01.com <span class="synIdentifier">gather_facts</span><span class="synSpecial">:</span> <span class="synConstant">false</span> <span class="synIdentifier">tasks</span><span class="synSpecial">:</span> <span class="synStatement">- </span><span class="synIdentifier">name</span><span class="synSpecial">:</span> TEST STRICT <span class="synIdentifier">cisco.iosxr.iosxr_config</span><span class="synSpecial">:</span> <span class="synIdentifier">lines</span><span class="synSpecial">:</span> <span class="synStatement">- </span>description ansible test hogehoge <span class="synComment"># - shutdown</span> <span class="synIdentifier">parents</span><span class="synSpecial">:</span> interface GigabitEthernet0/0/0/1 <span class="synIdentifier">match</span><span class="synSpecial">:</span> strict </pre> <h2 id="4-none-について">4. none について</h2> <p>こちらは、<code>lines</code> に与えられたコンフィグと <code>running-config</code> の比較を行いません。したがって、<code>lines</code> に与えられたコンフィグが <code>running-config</code> に存在しているかどうかにかかわらず、常に設定を試みます。</p> <p>以上、ご参考になれば幸いです。 Happy holiday &amp; Automation!</p> MahoutukaiS 効果的なテクニカルサポートへの問い合わせ方法とは hatenablog://entry/6801883189068764939 2023-12-23T09:54:28+09:00 2023-12-23T09:54:28+09:00 ※この記事はRed Hat Advent Calendar 2023 の23日目です。 qiita.com こんにちは。Red Hat にてOpenStackのテクニカルサポートの担当をしている井川です。 日頃、サポートケースを通じて多くの問い合わせを頂いておりますが、認識の齟齬や状況・問題の把握に時間を要し、残念ながら解決までに時間のかかることもあるのが現状です。 今回、より早く解決させるためのコツ(tips)・ベストプラクティスについて、「サポートサービス利用ガイド」の中から「サポートサービスをうまく活用するコツ」をご紹介したいと思います。 サポートサービスをうまく活用するコツ 詳細を記載… <p>※この記事は<a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar 2023</a> の23日目です。 <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fadvent-calendar%2F2023%2Fredhat" title="Red Hatのカレンダー | Advent Calendar 2023 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/advent-calendar/2023/redhat">qiita.com</a></cite></p> <p>こんにちは。Red Hat にてOpenStackのテクニカルサポートの担当をしている井川です。</p> <p>日頃、サポートケースを通じて多くの問い合わせを頂いておりますが、認識の齟齬や状況・問題の把握に時間を要し、残念ながら解決までに時間のかかることもあるのが現状です。</p> <p>今回、より早く解決させるためのコツ(tips)・ベストプラクティスについて、「<a href="https://www.redhat.com/rhdc/managed-files/red_hat_support_portal_guide_ja_20230922v1_04.pdf">サポートサービス利用ガイド</a>」の中から「サポートサービスをうまく活用するコツ」をご紹介したいと思います。</p> <h1 id="サポートサービスをうまく活用するコツ">サポートサービスをうまく活用するコツ</h1> <h2 id="詳細を記載する">詳細を記載する</h2> <p>特にトラブルシュートや障害調査では、可能なかぎり詳細を記載することにより、サポートエンジニアが状況を把握しやすくなり、トラブル解決へのスピードが早くなることが期待されます。トラブル発生時にはバタバタしてしまい、なかなか冷静でいることは難しい状況です。</p> <p>しかし、ここを省略してしまうと、サポートエンジニアとの情報のやりとりが増えることとなり、結果、トラブル解決にかかる時間が増大してしまう可能性が大きくなります。</p> <h3 id="記載すべき情報の例">記載すべき情報の例</h3> <ul> <li>現象発生日時 (日付・時刻)</li> <li>発生頻度 (1度のみ発生、くりかえし発生、不定期に発生)</li> <li>タイミング(再起動時に発生、毎日 0:00 に発生、タイミング不明)</li> <li>事象発生前に実施した作業やオペレーションの有無</li> <li>パッケージやソフトウェアのアップデート</li> <li>環境や設定の変更 ・ 環境の詳細 (ホスト名、カーネルバージョン、パッケージバージョン等)</li> </ul> <h2 id="ログやデータなどの情報で事象を説明する">ログやデータなどの情報で事象を説明する</h2> <p>上記「詳細を記載する」にも関連しますが、以下のような具体的な情報をご提供いただくことで、事象把握の大きな助けとなります。 しばしば、「インターネットに繋がっていない環境なのでsosreportなどを送付できない」というケースも見受けられます。しかし、サポートエンジニアとしては、これらの具体的な情報が無いとシステムや事象の詳細がわからず解決に非常に時間がかかる結果となってしまいます。</p> <p>このため、重要なシステムであればあるほど、トラブル発生時に下記の様な情報をどのように送付するのか?を予め計画・テストしておくことが大切となります。</p> <h3 id="記載添付すべき情報の例">記載・添付すべき情報の例</h3> <ul> <li>コマンド出力結果</li> <li>sosreportやログ情報抜粋</li> <li>画面ショット (スクリーンショット)</li> </ul> <h2 id="トピック問題ごとにサポートケースを分けて登録する">トピック・問題ごとにサポートケースを分けて登録する</h2> <p>1つのサポートケースで複数のトピックや問題が扱われると、どちら事象についての話なのかが分かりづらくなり、お客様もサポートエンジニアも混乱が発生する可能性があります。</p> <p>このようなことを避ける為、トピック・問題ごとにサポートケースをご登録いただければと思います。</p> <h3 id="例">例</h3> <p>同じホストで以下 a と b の2つの事象が発生したとします。 1つのサポートケースで a,b 両方をお問い合わせ頂くより、別の (2つの)サポートケースでお問い合わせ頂いた方がスムーズに対応が進みます。</p> <ol type="a"> <li>OS再起動時に時間がかかるので、短くする方法を教えて欲しい。</li> <li>パッケージのアップデートを試みたらエラーで失敗した。対処方法を教えてほしい。</li> </ol> <p>また、サポートケースのやり取りの中で新たな問題やトピックが出てくることもよくありますが、その場合には、サポートエンジニアより、新たなサポートケースの登録をお願いすることもありますので、ご了承いただければと思います。</p> <h2 id="適切な重大度を指定する">適切な重大度を指定する</h2> <p>「<a href="https://access.redhat.com/support/policy/severity/">重大度の定義</a>」の通り、重大度 1や2は業務を提供している本番環境向けにおける深刻・重大な問題向けのものです。 あてはまらない環境・問題でも選択できてしまいますが、実際のシステム・業務の状況をお伺いしたり、状況に応じて重大度の調整をお願いさせて頂く場合があります。 <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fsupport%2Fpolicy%2Fseverity%2F" title="Red Hat Support Severity Level Definitions - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/support/policy/severity/">access.redhat.com</a></cite></p> <hr /> <h1 id="その他">その他</h1> <h2 id="Red-Hat-テクニカルアカウントマネジメントTAMを購入する">Red Hat テクニカル・アカウント・マネジメント(TAM)を購入する</h2> <p>通常のテクニカルサポートでは、リアクティブな対応となり、また、システム構成や状況は把握していないため、ケース作成毎に毎回説明していただく必要があります。</p> <p>一方、<a href="https://www.redhat.com/ja/services/support/technical-account-management">TAM</a>においては、お客様の単一連絡窓口のテクニカルアドバイザーとなり、定期的なリモート会議に参加し、予めシステム構成等を把握し、プロアクティブにサポートを行うことなどが可能となります。</p> <p>このため、トラブルの発生を未然に防ぐことが可能となり、また、トラブル発生時にも担当TAMがすでに把握してる情報を再度やり取りすることがなく、通常のテクニカルサポートと比較し、迅速に解決に導ける可能性が高まります。</p> <p>重要なシステムにおいては <a href="https://www.redhat.com/ja/services/support/technical-account-management">TAM</a> のご購入を検討いただければ幸いです。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.redhat.com%2Fja%2Fservices%2Fsupport%2Ftechnical-account-management" title="テクニカル・アカウント・マネジメント" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.redhat.com/ja/services/support/technical-account-management">www.redhat.com</a></cite></p> <h2 id="サポート利用に関するリンク">サポート利用に関するリンク</h2> <ul> <li><a href="https://access.redhat.com/ja/solutions/6999046">サポートサービスやカスタマーポータルについての日本語のガイドはありますか?</a></li> </ul> <p>本記事を書くにあたり<s>コピペ</s><a href="https://red.ht/support-portal-guide-ja">参考にした資料</a>へのリンクです。リンク先の資料には、サポートサービス・カスタマーポータルの利用方法が丁寧に書かれています。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fja%2Fsolutions%2F6999046" title="サポートサービスやカスタマーポータルについての日本語のガイドはありますか? - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/ja/solutions/6999046">access.redhat.com</a></cite></p> <ul> <li><a href="https://access.redhat.com/ja/articles/6970077">Red Hat サポートを利用するためのリファレンスガイド</a></li> </ul> <p>上記で述べた事も一部含まれていますが、各製品毎のログ収集方法へのリンク等あります。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fja%2Farticles%2F6970077" title="Red Hat サポートを利用するためのリファレンスガイド - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/ja/articles/6970077">access.redhat.com</a></cite></p> <ul> <li><a href="https://access.redhat.com/solutions/2055933">How to collect all required logs for Red Hat Support to investigate an OpenStack issue</a></li> </ul> <p>Red Hat OpenStack Platform において発生した事象を解析するためのログ収集方法について書かれたドキュメントです。英語が苦手な場合には、<a href="https://access.redhat.com/mt/ja/solutions/2055933">機械翻訳</a>を参考としていただければと思います。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fsolutions%2F2055933" title="How to collect all required logs for Red Hat Support to investigate an OpenStack issue - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/solutions/2055933">access.redhat.com</a></cite></p> <hr /> <h1 id="おまけ">おまけ</h1> <p>ChatGPT 4に、問い合わせる際のコツを聞いてみました。</p> <h2 id="ChatGPT4への質問1">ChatGPT4への質問1</h2> <p>Red Hat のテクニカルサポートへ問い合わせる際、より効果的な回答を得るための方法やコツを挙げられるだけ挙げてください。</p> <h2 id="回答">回答</h2> <blockquote><p>Red Hatのテクニカルサポートに問い合わせる際、効果的な回答を得るためには以下の方法やコツが有効です:</p> <ol> <li><p><strong>明確な問題の説明</strong>:問題の詳細を具体的かつ明確に説明してください。何が起きているのか、どのような状況で問題が発生しているのか、影響を受けているシステムやソフトウェアのバージョンなどを含めます。</p></li> <li><p><strong>再現手順の提供</strong>:問題を再現するための具体的な手順を提供することで、サポートチームが問題をより迅速に理解し、解決策を見つけやすくなります。</p></li> <li><p><strong>エラーメッセージとログの共有</strong>:エラーメッセージやシステムログ、コンフィギュレーションファイルなどの詳細情報を提供することで、問題の原因を特定しやすくなります。</p></li> <li><p><strong>優先度の設定</strong>:問題の緊急度やビジネスへの影響度を伝えることで、サポートチームが対応の優先度を適切に設定できます。</p></li> <li><p><strong>既存のトラブルシューティングの結果の共有</strong>:既に試みた解決策やトラブルシューティングの手順を共有することで、サポートチームが同じ手順を繰り返さずに済みます。</p></li> <li><p><strong>具体的な質問や要望の提示</strong>:どのような解決策を求めているのか、具体的な質問や要望を明確にすることが大切です。</p></li> <li><p><strong>連絡先情報の確認</strong>:連絡が取れる電話番号やメールアドレスを確認し、必要に応じて連絡可能な時間帯も伝えておきます。</p></li> <li><p><strong>関連する環境情報の提供</strong>:問題が発生している環境(ハードウェア、OS、ネットワーク構成など)に関する情報も重要です。</p></li> <li><p><strong>継続的なコミュニケーション</strong>:問い合わせ後も状況が変わった場合は、追加情報を提供するなどして継続的にコミュニケーションを取ります。</p></li> <li><p><strong>サポートポータルやコミュニティの利用</strong>:Red Hatのサポートポータルやコミュニティフォーラムで、似たような問題や解決策がないか探してみるのも一つの方法です。</p></li> </ol> <p>これらのコツを実践することで、Red Hatのテクニカルサポートからより迅速で的確な回答を得ることができるでしょう。</p></blockquote> <h3 id="筆者補足">筆者補足</h3> <ul> <li>「4. <strong>優先度の設定</strong>」</li> </ul> <p> → Severity(重大度)にて設定できます。</p> <ul> <li>「7. <strong>連絡先情報の確認</strong>」</li> </ul> <p> → 通常、サポートケースを通じてのやりとりとなりますので、特段の注意は不要です。</p> <ul> <li>「8. <strong>関連する環境情報の提供</strong>」:問題が発生している環境(ハードウェア、OS、ネットワーク構成など)に関する情報も重要です。</li> </ul> <p> → sosreport が非常に有効ですが、お問い合わせの問題に関連すると思われる環境の情報があれば、付け加えていただくとより効果的です。</p> <ul> <li>「10. <strong>サポートポータルやコミュニティの利用</strong>」:Red Hatのサポートポータルやコミュニティフォーラムで、似たような問題や解決策がないか探してみるのも一つの方法です。</li> </ul> <p> → 弊社<a href="https://access.redhat.com/products/">ドキュメント</a>・<a href="https://access.redhat.com/solutions/">ナレッジベース</a> には非常に多くの情報が蓄積されております。お問い合わせの際に、一度ご確認いただくことにより、回答が素早く見つかる可能性もあります。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fproducts%2F" title="Red Hat Customer Portal - Access to 24x7 support and knowledge" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/products/">access.redhat.com</a></cite> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fsolutions%2F" title="Customer Portal Search" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/solutions/">access.redhat.com</a></cite></p> <h2 id="ChatGPT4への質問2">ChatGPT4への質問2</h2> <p>RHOSPに関する問い合わせの場合、特に注意すべき点やコツなどあれば教えてください。</p> <h2 id="回答-1">回答</h2> <blockquote><p>Red Hat OpenStack Platform(RHOSP)に関する問い合わせの際に特に注意すべき点やコツは以下の通りです:</p> <ol> <li><p><strong>バージョン情報の提供</strong>:問題が発生しているRHOSPのバージョンを明確に伝えてください。異なるバージョンで異なる問題や解決策が存在する可能性があります。</p></li> <li><p><strong>デプロイメントの詳細</strong>:デプロイメントの設定や構成(ノードの数、使用しているストレージやネットワーキングの設定など)に関する詳細情報を提供します。</p></li> <li><p><strong>具体的な症状の説明</strong>:問題の症状を具体的に説明します。例えば、特定のサービスが応答しない、パフォーマンスが低下している、あるいは特定の操作が期待通りに動作しないなどです。</p></li> <li><p><strong>関連するログファイルの提供</strong>:OpenStackの各コンポーネントからのログファイルを集め、問題の解析に役立つ情報を提供します。</p></li> <li><p><strong>エラーメッセージの共有</strong>:発生しているエラーメッセージを可能な限り詳細に共有します。</p></li> <li><p><strong>変更履歴の記録</strong>:問題発生前に行われたシステムやネットワークの変更、アップデート、設定の変更などの履歴を提供します。</p></li> <li><p><strong>スケールや負荷の情報</strong>:問題が発生している環境のスケール(仮想マシンの数、使用中のリソース量など)や現在の負荷に関する情報も有効です。</p></li> <li><p><strong>環境固有の情報</strong>:自社の環境に特有の設定やカスタマイズがある場合は、それに関する情報も共有してください。</p></li> <li><p><strong>既に試みた解決策</strong>:問題解決のために既に行った試みや、実施したトラブルシューティング手順を共有します。</p></li> <li><p><strong>継続的なコミュニケーション</strong>:問題解決に向けた継続的なコミュニケーションを保ち、新たな情報が得られたらそれを迅速に共有します。</p></li> </ol> <p>Red Hat OpenStack Platformは複雑なシステムですので、これらの情報を詳細に提供することで、テクニカルサポートチームがより効果的に問題を理解し、解決策を提供しやすくなります。</p></blockquote> <h3 id="筆者補足-1">筆者補足</h3> <p>いずれも重要な視点と感じます。特に最後の</p> <blockquote><p>Red Hat OpenStack Platformは複雑なシステムですので</p></blockquote> <p>は、とても染み入る言葉と感じます。</p> <hr /> <p>以上、効果的なテクニカルサポートへの問い合わせのヒントとなれば幸いです。</p> migawa-rh Ansible Automation Platform 2.4 注目の新機能紹介 hatenablog://entry/6801883189068320172 2023-12-22T18:58:10+09:00 2024-01-31T12:21:49+09:00 皆さんこんにちは、Red Hat ソリューションアーキテクトの岡野です。 2023 年も残すところあと少しとなりました。さて、今回は、注目の新機能をサポートし、今年GAとなった Ansible Automation Platform 2.4 について、2023 年の締めくくりとして書いておきたいと思います。それぞれのお試し方法については、年明け、またこちらの Blog でご紹介予定です。 Ansible Automatio Platform 2.4 (以下 AAP2.4) の新機能、細かいところを上げるとたくさんあるのですが、なんといっても注目は、 ・Event-Driven Ansible … <p>皆さんこんにちは、Red Hat ソリューションアーキテクトの岡野です。 2023 年も残すところあと少しとなりました。さて、今回は、注目の新機能をサポートし、今年GAとなった Ansible Automation Platform 2.4 について、2023 年の締めくくりとして書いておきたいと思います。それぞれのお試し方法については、年明け、またこちらの Blog でご紹介予定です。</p> <p>Ansible Automatio Platform 2.4 (以下 AAP2.4) の新機能、細かいところを上げるとたくさんあるのですが、なんといっても注目は、</p> <p>・Event-Driven Ansible<br/> ・Ansible Lightspeed</p> <p>の2つです。では、そのそれぞれについてご説明します。</p> <h4 id="Event-Driven-Ansible">Event-Driven Ansible</h4> <p>AAP 2.4 では、IT の運用で発生する様々なイベントに対するオペレーションを自動化する、Event-driven Ansible (以下 EDA) が新たに追加されました。AAP 2.3 までは、GUI サービスを提供するコンポーネントとして、Ansible Automation Controller(以下 AAC)と Private Automation Hub (PAH) が提供されていましたが、AAP 2.4 では EDA Controller が GUI を提供する 3つ目のコンポーネントとして追加されています。従来の AAP では、IT システム運用の際の様々な作業を Playbook として定義し、さらにそれをサービス化することで作業工数の大幅な削減を実現しましたが、ここに EDA が追加されることにより、IT 運用の現場で日々発生する、様々なイベントを自動的に処理し、その結果として例えば、AAC と連携した Playbook の実行ができるようになります。イメージは以下の通りです。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20231221/20231221180853.png" width="1200" height="674" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>EDA の動作は、AAC とよく似ています。AAC では yaml 形式で書かれた Playbook をジョブテンプレート経由で実行しますが、EDA では同じく yaml 形式で書かれた Rulebook を実行します。Playbook も Rulebook も同じ yaml 形式ですから、Playbook の作成・編集に慣れた方であればほとんどハードルなく Rulebook の作成ができるのではないかと思います。</p> <p>Rulebook には以下の内容が記載されており、あらかじめ EDA Controller 上でアクティベーション(イベントを待ち受ける状態)されています。</p> <p><strong>・sources(何が)</strong><br/>  イベントの提供元に関する情報<br/> <strong>・rules</strong><br/>  <strong>condition(どうなったら)</strong><br/>   実行条件 (not equal, equal, and / or, defined など柔軟に指定可能)<br/>  <strong>action(どうする)</strong></p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20231222/20231222103948.png" width="1200" height="539" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>EDA の動作のトリガーとなるソースに関しては、サードパーティ製のソフトウェアと連携する形をとります。例えば、IBM社の Instana、Turbonomic、Zabbix、Dynatrace、Paloalto など EDA をサポートするソフトウェアから発砲されたイベントをソースとして利用することができます。EDA が <strong>source</strong> からイベントを受け取ると、Rulebook に記載された内容に基づき、<strong>condition</strong> に記載された条件と一致するかどうかを判断し、一致した場合は、<strong>action</strong> に記載された内容を実行します。<strong>action</strong> には、ポストイベントの発砲など含めいくつかの種類がありますが、AAC 内にあらかじめ準備されたジョブテンプレートやワークフローテンプレートを呼び出して Playbook を実行することも可能です。</p> <p>例えば、以下は簡単な Rulebook の一例ですが、このケースでは、すべてのホストからの webhook を5000番ポートで待ち受け、webhook のイベントを受け取ったら、 その中のメッセージを確認し、<strong>Ansible is super cool</strong> という文字列と一致した場合に、 AAC 内にあらかじめ作成された <strong>say-what</strong> というジョブテンプレートを実行するという動作になります。</p> <pre class="code" data-lang="" data-unlink>--- - name: Listen for events on a webhook hosts: all sources: - name: Wait for Webhook Message ansible.eda.webhook: host: 0.0.0.0 port: 5000 rules: - name: Say Hello condition: event.payload.message == &#34;Ansible is super cool&#34; action: run_job_template: name: say-what organization: Default</pre> <p>AAC は実行環境で Playbook を実行しますが、EDA Controller も同じように、決定環境と呼ばれるコンテナ内部で Rulebook を実行します。 決定環境の中には <strong>ansible.eda</strong> というイベントソースプラグインがあらかじめパッケージ化されており、インストール直後から利用可能です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fansible.readthedocs.io%2Fprojects%2Frulebook%2Fen%2Flatest%2Fsources.html%23event-source-plugins" title="Event Source Plugins — Ansible Rulebook Documentation" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://ansible.readthedocs.io/projects/rulebook/en/latest/sources.html#event-source-plugins">ansible.readthedocs.io</a></cite></p> <p>詳細については以下をご確認ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fansible%2Fevent-driven-ansible%2Ftree%2Fmain%2Fextensions%2Feda%2Fplugins%2Fevent_source" title="event-driven-ansible/extensions/eda/plugins/event_source at main · ansible/event-driven-ansible" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/ansible/event-driven-ansible/tree/main/extensions/eda/plugins/event_source">github.com</a></cite></p> <p>ansible.eda 以外のプラグインは Red Hat Hybrid Cloud Console から Collections として提供されています。このあたりの実装は、AAC と同じです。以下のリンクは、 Red Hat Hybrid Cloud Console を文字列 <strong>eda</strong> で検索した結果です。EDA ではこれらの Collections が利用可能です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fconsole.redhat.com%2Fansible%2Fautomation-hub%3Fpage_size%3D10%26view_type%3Dnull%26keywords%3Deda%26page%3D1" title="Hybrid Cloud Console" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://console.redhat.com/ansible/automation-hub?page_size=10&view_type=null&keywords=eda&page=1">console.redhat.com</a></cite></p> <p>EDA の具体的な動作テストの方法は年明けに、こちらのブログでご紹介したいと思います。</p> <h4 id="Ansible-Lightspeed">Ansible Lightspeed</h4> <p>AAP 2.4 のもう一つの大きな目玉、Ansible Lightspeed についてご紹介します。</p> <p>Ansible Lightspeed は、IBM Cloud 上でサービス提供される watsonx Code Assistant for Ansible Lightspeed を利用した生成 AI による Playbook 作成支援機能です。生成 AI というと ChatGPT を思い浮かべる方も多いかもしれませんが、Ansible Lightspeed で利用される watsonx Code Assistant for Ansible Lightspeed は Ansible Galaxyコンテンツとその他のオープン・データ・ソースおよび、Red HatとIBMの自動化に関する専門知識が注入された、Ansible固有の「トレーニング」データ・セットとなっているため、生成されたコードの質が高く、また、生成されたコードがどこから来たのか、そのソースを確認することもできることから、コードの脆弱性や不意のライセンス違反などを気にすることなく、安心して利用することが可能です。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/hokn5/20231222/20231222180042.png" width="1200" height="548" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>Ansible Lightspeed は VSCode の拡張機能として利用することができます。現在サポートされている機能は以下の通りです。</p> <ul> <li>タスクの作成<br/> 自然言語プロンプトからの Ansible Playbook または Roles のタスクの生成</li> <li>マルチタスクの作成<br/> YAML コメント (#) 行でアンパサンド (&amp;) を使用して連鎖した自然言語タスク プロンプトの連続チェーンを提供することにより、Ansible タスク ファイルと Playbook に対する複数の Ansible タスク提案を生成する</li> <li>コンテンツソースマッチング<br/> 生成された各コードの推奨事項を、Ansible コンテンツ、コンテンツ作成者、コンテンツ ライセンスなど、最も近い潜在的なデータ トレーニング ソースの上位 3 つと照合する</li> <li>ポストプロセッシングルール<br/> 生成されたコードの推奨事項を拡張し、Ansible のベストプラクティスに確実に準拠するようにする</li> </ul> <p>詳しくはこちらのデータシートをご確認ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.redhat.com%2Fen%2Fresources%2Fansible-lightspeed-ibm-watsonx-code-assistant-datasheet" title="Red Hat Ansible Lightspeed with IBM watsonx Code Assistant" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.redhat.com/en/resources/ansible-lightspeed-ibm-watsonx-code-assistant-datasheet">www.redhat.com</a></cite></p> <p>一つの例として、Ansible Lightspeed を使って、Playbook 内に以下ようなタスクを作成してみました。</p> <p><strong>入力した自然言語</strong><br/> <code>#最新バージョンの httpd をインストール &amp; httpd サービスの有効化と開始 &amp; 80/443 ポートをFireall で恒久的に即座に開く</code></p> <p><strong>Ansible Lightspeed によるマルチタスク作成結果</strong></p> <pre class="code" data-lang="" data-unlink> tasks: # 最新バージョンの httpd をインストール &amp; httpd サービスの有効化と開始 &amp; 80/443 ポートをFireall で恒久的に即座に開く - name: 最新バージョンの httpd をインストール ansible.builtin.package: name: httpd state: latest - name: Httpd サービスの有効化と開始 ansible.builtin.service: name: httpd state: started enabled: true - name: 80/443 ポートをFireall で恒久的に即座に開く ansible.posix.firewalld: port: &#39;{{ item }}/tcp&#39; permanent: true state: enabled immediate: true loop: - 80 - 443</pre> <p>簡単なデモ動画も作成してみました。</p> <p><iframe width="560" height="315" src="https://www.youtube.com/embed/ZSSfyUKA8DU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Ansible Lightspeed"></iframe><cite class="hatena-citation"><a href="https://youtu.be/ZSSfyUKA8DU">youtu.be</a></cite></p> <p>いかがでしたでしょうか?次回は年明け、EDA、Lightspeed の実際のお試し方法についてご紹介したいと思います。</p> <p>なお、今回ご紹介した EDA は AAP のサブスクリプションに含まれておりますが、Ansible Lightspeed に関しては、IBM Cloud によるサービス提供となるため、別途追加費用が必要となります。具体的な価格に関しては弊社担当までお問い合わせください。</p> hokn5 Vectorで遊ぶ hatenablog://entry/6801883189068875906 2023-12-22T17:29:35+09:00 2024-01-11T10:17:26+09:00 id:nekop です。この記事はOpenShift Advent Calendar 2023のエントリです。 OpenShift Loggingでは長くEFK (Elasticsearch, Fluentd, Kibana)スタックが利用されていましたが、現在のリリースはLoki Vectorスタックを標準的に利用するようになっています。Elasticsearchは2022-07に非推奨、Fluentdは2023-01に非推奨となりました。 OpenShift LoggingではVectorによるログ収集と転送がサポートされています。VectorはDatadog社により開発されたデータ転送処… <p><a href="http://blog.hatena.ne.jp/nekop/">id:nekop</a> です。この記事は<a href="https://qiita.com/advent-calendar/2023/openshift">OpenShift Advent Calendar 2023</a>のエントリです。</p> <p>OpenShift Loggingでは長くEFK (Elasticsearch, Fluentd, Kibana)スタックが利用されていましたが、現在のリリースはLoki Vectorスタックを標準的に利用するようになっています。Elasticsearchは2022-07に非推奨、Fluentdは2023-01に非推奨となりました。</p> <p>OpenShift Loggingでは<a href="https://docs.openshift.com/container-platform/4.14/logging/log_collection_forwarding/log-forwarding.html">Vectorによるログ収集と転送</a>がサポートされています。VectorはDatadog社により開発されたデータ転送処理ソフトウェアです。Sourceと呼ばれる入力、Transformerによる加工、Sinkと呼ばれる出力の3つのコンポーネントを利用してデータの転送処理を行います。</p> <p>今回はこのVectorにフォーカスして遊んでみます。通常構成のログストアであるLokiは利用せず、クラスタ内に受信側となる別のVector podを用意してそちらにログ転送してファイル出力を行う設定で構成します。</p> <p>受信側Vectorは<a href="https://vector.dev/docs/reference/configuration/sources/http_server/">http_server source</a>で8080ポート待ち受け、<a href="https://vector.dev/docs/reference/configuration/sinks/file/">file sink</a>でファイル出力する設定です。/tmp配下のファイルとして保存します。</p> <pre class="code" data-lang="" data-unlink>TARGET_PROJECT=tkimura-infra cat &lt;&lt;EOF &gt; vector.toml expire_metrics_secs = 60 [api] enabled = true [sources.http_server_source] type = &#34;http_server&#34; address = &#34;0.0.0.0:8080&#34; decoding.codec = &#34;json&#34; [sinks.file_sink] type = &#34;file&#34; inputs = [ &#34;http_server_source&#34; ] path = &#34;/tmp/vector-%Y-%m-%d.log&#34; encoding.codec = &#34;json&#34; EOF oc -n $TARGET_PROJECT create configmap vector-http --from-file=vector.toml oc -n $TARGET_PROJECT create deployment vector-http --image=quay.io/openshift-logging/vector:5.8 --port=8080 oc -n $TARGET_PROJECT set volume deploy/vector-http --add --name=vector-http-config --configmap-name=vector-http --mount-path=/etc/vector oc -n $TARGET_PROJECT expose deploy/vector-http oc -n openshift-logging create -f - &lt;&lt;EOF apiVersion: logging.openshift.io/v1 kind: ClusterLogging metadata: name: instance namespace: openshift-logging spec: collection: type: vector --- apiVersion: logging.openshift.io/v1 kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging spec: outputs: - name: ext-vector-http type: http url: &#39;http://vector-http.$TARGET_PROJECT.svc:8080&#39; pipelines: - name: forward-to-ext-vector-http inputRefs: - application - infrastructure outputRefs: - ext-vector-http EOF</pre> <p>デプロイすると、受信側Vectorで転送されたログを確認することができます。</p> <pre class="code" data-lang="" data-unlink>$ oc -n tkimura-infra rsh deploy/vector-http ls -la /tmp total 131968 drwxrwxrwt. 1 root root 35 Dec 22 07:44 . dr-xr-xr-x. 1 root root 39 Dec 22 07:44 .. -rw-r--r--. 1 1000710000 root 101867631 Dec 22 08:22 vector-2023-12-22.log $ oc -n tkimura-infra rsh deploy/vector-http tail -n2 /tmp/vector-2023-12-22.log {&#34;@timestamp&#34;:&#34;2023-12-22T07:57:53.432429470Z&#34;,&#34;hostname&#34;:&#34;ip-10-0-45-201.ap-northeast-1.compute.internal&#34;,&#34;kubernetes&#34;:{&#34;annotations&#34;:{&#34;openshift.io/scc&#34;:&#34;hostaccess&#34;},&#34;container_id&#34;:&#34;cri-o://465432752c76d4aff0419119d2365fbbf38cee44620ff746c974380df12cbeef&#34;,&#34;container_image&#34;:&#34;quay.io/openshift-release-dev/ocp-release@sha256:e5128c3b0ab225e0abf9344dae504e08b82dda4885bbd047e2dbc13cc3d9879b&#34;,&#34;container_name&#34;:&#34;cluster-version-operator&#34;,&#34;labels&#34;:{&#34;k8s-app&#34;:&#34;cluster-version-operator&#34;,&#34;pod-template-hash&#34;:&#34;678d8bb44&#34;},&#34;namespace_id&#34;:&#34;e0c35f25-5a1f-4682-bfa2-d69dab7418fc&#34;,&#34;namespace_labels&#34;:{&#34;kubernetes_io_metadata_name&#34;:&#34;openshift-cluster-version&#34;,&#34;name&#34;:&#34;openshift-cluster-version&#34;,&#34;olm_operatorgroup_uid_32e3efbd-dac1-4364-bab3-cd37df669a1e&#34;:&#34;&#34;,&#34;openshift_io_cluster-monitoring&#34;:&#34;true&#34;,&#34;openshift_io_run-level&#34;:&#34;&#34;,&#34;pod-security_kubernetes_io_audit&#34;:&#34;privileged&#34;,&#34;pod-security_kubernetes_io_enforce&#34;:&#34;privileged&#34;,&#34;pod-security_kubernetes_io_warn&#34;:&#34;privileged&#34;},&#34;namespace_name&#34;:&#34;openshift-cluster-version&#34;,&#34;pod_id&#34;:&#34;4b2b3ab9-297a-4480-8857-d80244289da1&#34;,&#34;pod_ip&#34;:&#34;10.0.45.201&#34;,&#34;pod_name&#34;:&#34;cluster-version-operator-678d8bb44-s8c7x&#34;,&#34;pod_owner&#34;:&#34;ReplicaSet/cluster-version-operator-678d8bb44&#34;},&#34;level&#34;:&#34;info&#34;,&#34;log_type&#34;:&#34;infrastructure&#34;,&#34;message&#34;:&#34;I1222 07:57:53.432384 1 sync_worker.go:990] Done syncing for cloudcredential \&#34;cluster\&#34; (269 of 860)&#34;,&#34;openshift&#34;:{&#34;cluster_id&#34;:&#34;1e0f1eb9-9174-426b-8e2e-6b401fca7fbe&#34;,&#34;sequence&#34;:29292},&#34;path&#34;:&#34;/&#34;,&#34;source_type&#34;:&#34;http_server&#34;,&#34;timestamp&#34;:&#34;2023-12-22T07:57:53.454795108Z&#34;} {&#34;@timestamp&#34;:&#34;2023-12-22T07:57:53.432429470Z&#34;,&#34;hostname&#34;:&#34;ip-10-0-45-201.ap-northeast-1.compute.internal&#34;,&#34;kubernetes&#34;:{&#34;annotations&#34;:{&#34;openshift.io/scc&#34;:&#34;hostaccess&#34;},&#34;container_id&#34;:&#34;cri-o://465432752c76d4aff0419119d2365fbbf38cee44620ff746c974380df12cbeef&#34;,&#34;container_image&#34;:&#34;quay.io/openshift-release-dev/ocp-release@sha256:e5128c3b0ab225e0abf9344dae504e08b82dda4885bbd047e2dbc13cc3d9879b&#34;,&#34;container_name&#34;:&#34;cluster-version-operator&#34;,&#34;labels&#34;:{&#34;k8s-app&#34;:&#34;cluster-version-operator&#34;,&#34;pod-template-hash&#34;:&#34;678d8bb44&#34;},&#34;namespace_id&#34;:&#34;e0c35f25-5a1f-4682-bfa2-d69dab7418fc&#34;,&#34;namespace_labels&#34;:{&#34;kubernetes_io_metadata_name&#34;:&#34;openshift-cluster-version&#34;,&#34;name&#34;:&#34;openshift-cluster-version&#34;,&#34;olm_operatorgroup_uid_32e3efbd-dac1-4364-bab3-cd37df669a1e&#34;:&#34;&#34;,&#34;openshift_io_cluster-monitoring&#34;:&#34;true&#34;,&#34;openshift_io_run-level&#34;:&#34;&#34;,&#34;pod-security_kubernetes_io_audit&#34;:&#34;privileged&#34;,&#34;pod-security_kubernetes_io_enforce&#34;:&#34;privileged&#34;,&#34;pod-security_kubernetes_io_warn&#34;:&#34;privileged&#34;},&#34;namespace_name&#34;:&#34;openshift-cluster-version&#34;,&#34;pod_id&#34;:&#34;4b2b3ab9-297a-4480-8857-d80244289da1&#34;,&#34;pod_ip&#34;:&#34;10.0.45.201&#34;,&#34;pod_name&#34;:&#34;cluster-version-operator-678d8bb44-s8c7x&#34;,&#34;pod_owner&#34;:&#34;ReplicaSet/cluster-version-operator-678d8bb44&#34;},&#34;level&#34;:&#34;info&#34;,&#34;log_type&#34;:&#34;infrastructure&#34;,&#34;message&#34;:&#34;I1222 07:57:53.432416 1 sync_worker.go:975] Running sync for rolebinding \&#34;openshift-cloud-credential-operator/cloud-credential-operator\&#34; (270 of 860)&#34;,&#34;openshift&#34;:{&#34;cluster_id&#34;:&#34;1e0f1eb9-9174-426b-8e2e-6b401fca7fbe&#34;,&#34;sequence&#34;:29293},&#34;path&#34;:&#34;/&#34;,&#34;source_type&#34;:&#34;http_server&#34;,&#34;timestamp&#34;:&#34;2023-12-22T07:57:53.454795108Z&#34;}</pre> <p>設定ファイルを見てみましょう。vector.tomlは大まかに以下の設定になっています。</p> <ul> <li>kubernetes_logs source</li> <li>journald source</li> <li>基本的な加工</li> <li>openshift, kube namespaceのログとjournaldをinfrastructureに分類、その他をapplicationに分類</li> <li>受信側vectorへのhttp sink</li> </ul> <pre class="code" data-lang="" data-unlink>$ oc -n openshift-logging extract secret/collector-config vector.toml run-vector.sh $ cat vector.toml expire_metrics_secs = 60 [api] enabled = true # Logs from containers (including openshift containers) [sources.raw_container_logs] type = &#34;kubernetes_logs&#34; max_read_bytes = 3145728 glob_minimum_cooldown_ms = 15000 auto_partial_merge = true exclude_paths_glob_patterns = [&#34;/var/log/pods/openshift-logging_logfilesmetricexporter-*/*/*.log&#34;, &#34;/var/log/pods/openshift-logging_elasticsearch-*/*/*.log&#34;, &#34;/var/log/pods/openshift-logging_*/loki*/*.log&#34;, &#34;/var/log/pods/openshift-logging_kibana-*/*/*.log&#34;, &#34;/var/log/pods/openshift-logging_*/gateway/*.log&#34;, &#34;/var/log/pods/openshift-logging_*/opa/*.log&#34;, &#34;/var/log/pods/*/*/*.gz&#34;, &#34;/var/log/pods/*/*/*.tmp&#34;] pod_annotation_fields.pod_labels = &#34;kubernetes.labels&#34; pod_annotation_fields.pod_namespace = &#34;kubernetes.namespace_name&#34; pod_annotation_fields.pod_annotations = &#34;kubernetes.annotations&#34; pod_annotation_fields.pod_uid = &#34;kubernetes.pod_id&#34; pod_annotation_fields.pod_node_name = &#34;hostname&#34; namespace_annotation_fields.namespace_uid = &#34;kubernetes.namespace_id&#34; rotate_wait_ms = 5000 [sources.raw_journal_logs] type = &#34;journald&#34; journal_directory = &#34;/var/log/journal&#34; [sources.internal_metrics] type = &#34;internal_metrics&#34; [transforms.container_logs] type = &#34;remap&#34; inputs = [&#34;raw_container_logs&#34;] source = &#39;&#39;&#39; .openshift.cluster_id = &#34;${OPENSHIFT_CLUSTER_ID:-}&#34; if !exists(.level) { .level = &#34;default&#34; if match!(.message, r&#39;Warning|WARN|^W[0-9]+|level=warn|Value:warn|&#34;level&#34;:&#34;warn&#34;|&lt;warn&gt;&#39;) { .level = &#34;warn&#34; } else if match!(.message, r&#39;Error|ERROR|^E[0-9]+|level=error|Value:error|&#34;level&#34;:&#34;error&#34;|&lt;error&gt;&#39;) { .level = &#34;error&#34; } else if match!(.message, r&#39;Critical|CRITICAL|^C[0-9]+|level=critical|Value:critical|&#34;level&#34;:&#34;critical&#34;|&lt;critical&gt;&#39;) { .level = &#34;critical&#34; } else if match!(.message, r&#39;Debug|DEBUG|^D[0-9]+|level=debug|Value:debug|&#34;level&#34;:&#34;debug&#34;|&lt;debug&gt;&#39;) { .level = &#34;debug&#34; } else if match!(.message, r&#39;Notice|NOTICE|^N[0-9]+|level=notice|Value:notice|&#34;level&#34;:&#34;notice&#34;|&lt;notice&gt;&#39;) { .level = &#34;notice&#34; } else if match!(.message, r&#39;Alert|ALERT|^A[0-9]+|level=alert|Value:alert|&#34;level&#34;:&#34;alert&#34;|&lt;alert&gt;&#39;) { .level = &#34;alert&#34; } else if match!(.message, r&#39;Emergency|EMERGENCY|^EM[0-9]+|level=emergency|Value:emergency|&#34;level&#34;:&#34;emergency&#34;|&lt;emergency&gt;&#39;) { .level = &#34;emergency&#34; } else if match!(.message, r&#39;(?i)\b(?:info)\b|^I[0-9]+|level=info|Value:info|&#34;level&#34;:&#34;info&#34;|&lt;info&gt;&#39;) { .level = &#34;info&#34; } } pod_name = string!(.kubernetes.pod_name) if starts_with(pod_name, &#34;eventrouter-&#34;) { parsed, err = parse_json(.message) if err != null { log(&#34;Unable to process EventRouter log: &#34; + err, level: &#34;info&#34;) } else { ., err = merge(.,parsed) if err == null &amp;&amp; exists(.event) &amp;&amp; is_object(.event) { if exists(.verb) { .event.verb = .verb del(.verb) } .kubernetes.event = del(.event) .message = del(.kubernetes.event.message) set!(., [&#34;@timestamp&#34;], .kubernetes.event.metadata.creationTimestamp) del(.kubernetes.event.metadata.creationTimestamp) . = compact(., nullish: true) } else { log(&#34;Unable to merge EventRouter log message into record: &#34; + err, level: &#34;info&#34;) } } } del(.source_type) del(.stream) del(.kubernetes.pod_ips) del(.kubernetes.node_labels) del(.timestamp_end) ts = del(.timestamp); if !exists(.&#34;@timestamp&#34;) {.&#34;@timestamp&#34; = ts} &#39;&#39;&#39; [transforms.drop_journal_logs] type = &#34;filter&#34; inputs = [&#34;raw_journal_logs&#34;] condition = &#34;.PRIORITY != \&#34;7\&#34; &amp;&amp; .PRIORITY != 7&#34; [transforms.journal_logs] type = &#34;remap&#34; inputs = [&#34;drop_journal_logs&#34;] source = &#39;&#39;&#39; .openshift.cluster_id = &#34;${OPENSHIFT_CLUSTER_ID:-}&#34; .tag = &#34;.journal.system&#34; del(.source_type) del(._CPU_USAGE_NSEC) del(.__REALTIME_TIMESTAMP) del(.__MONOTONIC_TIMESTAMP) del(._SOURCE_REALTIME_TIMESTAMP) del(.JOB_RESULT) del(.JOB_TYPE) del(.TIMESTAMP_BOOTTIME) del(.TIMESTAMP_MONOTONIC) if .PRIORITY == &#34;8&#34; || .PRIORITY == 8 { .level = &#34;trace&#34; } else { priority = to_int!(.PRIORITY) .level, err = to_syslog_level(priority) if err != null { log(&#34;Unable to determine level from PRIORITY: &#34; + err, level: &#34;error&#34;) log(., level: &#34;error&#34;) .level = &#34;unknown&#34; } else { del(.PRIORITY) } } .hostname = del(.host) # systemd’s kernel-specific metadata. # .systemd.k = {} if exists(.KERNEL_DEVICE) { .systemd.k.KERNEL_DEVICE = del(.KERNEL_DEVICE) } if exists(.KERNEL_SUBSYSTEM) { .systemd.k.KERNEL_SUBSYSTEM = del(.KERNEL_SUBSYSTEM) } if exists(.UDEV_DEVLINK) { .systemd.k.UDEV_DEVLINK = del(.UDEV_DEVLINK) } if exists(.UDEV_DEVNODE) { .systemd.k.UDEV_DEVNODE = del(.UDEV_DEVNODE) } if exists(.UDEV_SYSNAME) { .systemd.k.UDEV_SYSNAME = del(.UDEV_SYSNAME) } # trusted journal fields, fields that are implicitly added by the journal and cannot be altered by client code. .systemd.t = {} if exists(._AUDIT_LOGINUID) { .systemd.t.AUDIT_LOGINUID = del(._AUDIT_LOGINUID) } if exists(._BOOT_ID) { .systemd.t.BOOT_ID = del(._BOOT_ID) } if exists(._AUDIT_SESSION) { .systemd.t.AUDIT_SESSION = del(._AUDIT_SESSION) } if exists(._CAP_EFFECTIVE) { .systemd.t.CAP_EFFECTIVE = del(._CAP_EFFECTIVE) } if exists(._CMDLINE) { .systemd.t.CMDLINE = del(._CMDLINE) } if exists(._COMM) { .systemd.t.COMM = del(._COMM) } if exists(._EXE) { .systemd.t.EXE = del(._EXE) } if exists(._GID) { .systemd.t.GID = del(._GID) } if exists(._HOSTNAME) { .systemd.t.HOSTNAME = .hostname } if exists(._LINE_BREAK) { .systemd.t.LINE_BREAK = del(._LINE_BREAK) } if exists(._MACHINE_ID) { .systemd.t.MACHINE_ID = del(._MACHINE_ID) } if exists(._PID) { .systemd.t.PID = del(._PID) } if exists(._SELINUX_CONTEXT) { .systemd.t.SELINUX_CONTEXT = del(._SELINUX_CONTEXT) } if exists(._SOURCE_REALTIME_TIMESTAMP) { .systemd.t.SOURCE_REALTIME_TIMESTAMP = del(._SOURCE_REALTIME_TIMESTAMP) } if exists(._STREAM_ID) { .systemd.t.STREAM_ID = ._STREAM_ID } if exists(._SYSTEMD_CGROUP) { .systemd.t.SYSTEMD_CGROUP = del(._SYSTEMD_CGROUP) } if exists(._SYSTEMD_INVOCATION_ID) {.systemd.t.SYSTEMD_INVOCATION_ID = ._SYSTEMD_INVOCATION_ID} if exists(._SYSTEMD_OWNER_UID) { .systemd.t.SYSTEMD_OWNER_UID = del(._SYSTEMD_OWNER_UID) } if exists(._SYSTEMD_SESSION) { .systemd.t.SYSTEMD_SESSION = del(._SYSTEMD_SESSION) } if exists(._SYSTEMD_SLICE) { .systemd.t.SYSTEMD_SLICE = del(._SYSTEMD_SLICE) } if exists(._SYSTEMD_UNIT) { .systemd.t.SYSTEMD_UNIT = del(._SYSTEMD_UNIT) } if exists(._SYSTEMD_USER_UNIT) { .systemd.t.SYSTEMD_USER_UNIT = del(._SYSTEMD_USER_UNIT) } if exists(._TRANSPORT) { .systemd.t.TRANSPORT = del(._TRANSPORT) } if exists(._UID) { .systemd.t.UID = del(._UID) } # fields that are directly passed from clients and stored in the journal. .systemd.u = {} if exists(.CODE_FILE) { .systemd.u.CODE_FILE = del(.CODE_FILE) } if exists(.CODE_FUNC) { .systemd.u.CODE_FUNCTION = del(.CODE_FUNC) } if exists(.CODE_LINE) { .systemd.u.CODE_LINE = del(.CODE_LINE) } if exists(.ERRNO) { .systemd.u.ERRNO = del(.ERRNO) } if exists(.MESSAGE_ID) { .systemd.u.MESSAGE_ID = del(.MESSAGE_ID) } if exists(.SYSLOG_FACILITY) { .systemd.u.SYSLOG_FACILITY = del(.SYSLOG_FACILITY) } if exists(.SYSLOG_IDENTIFIER) { .systemd.u.SYSLOG_IDENTIFIER = del(.SYSLOG_IDENTIFIER) } if exists(.SYSLOG_PID) { .systemd.u.SYSLOG_PID = del(.SYSLOG_PID) } if exists(.RESULT) { .systemd.u.RESULT = del(.RESULT) } if exists(.UNIT) { .systemd.u.UNIT = del(.UNIT) } .time = format_timestamp!(.timestamp, format: &#34;%FT%T%:z&#34;) ts = del(.timestamp); if !exists(.&#34;@timestamp&#34;) {.&#34;@timestamp&#34; = ts} &#39;&#39;&#39; [transforms.route_container_logs] type = &#34;route&#34; inputs = [&#34;container_logs&#34;] route.app = &#39;!((starts_with!(.kubernetes.namespace_name,&#34;kube-&#34;)) || (starts_with!(.kubernetes.namespace_name,&#34;openshift-&#34;)) || (.kubernetes.namespace_name == &#34;default&#34;) || (.kubernetes.namespace_name == &#34;openshift&#34;) || (.kubernetes.namespace_name == &#34;kube&#34;))&#39; route.infra = &#39;(starts_with!(.kubernetes.namespace_name,&#34;kube-&#34;)) || (starts_with!(.kubernetes.namespace_name,&#34;openshift-&#34;)) || (.kubernetes.namespace_name == &#34;default&#34;) || (.kubernetes.namespace_name == &#34;openshift&#34;) || (.kubernetes.namespace_name == &#34;kube&#34;)&#39; # Set log_type to &#34;application&#34; [transforms.application] type = &#34;remap&#34; inputs = [&#34;route_container_logs.app&#34;] source = &#39;&#39;&#39; .log_type = &#34;application&#34; &#39;&#39;&#39; # Set log_type to &#34;infrastructure&#34; [transforms.infrastructure] type = &#34;remap&#34; inputs = [&#34;route_container_logs.infra&#34;,&#34;journal_logs&#34;] source = &#39;&#39;&#39; .log_type = &#34;infrastructure&#34; &#39;&#39;&#39; [transforms.forward_to_ext_vector_http_user_defined] type = &#34;remap&#34; inputs = [&#34;application&#34;,&#34;infrastructure&#34;] source = &#39;&#39;&#39; . &#39;&#39;&#39; [transforms.ext_vector_http_normalize_http] type = &#34;remap&#34; inputs = [&#34;forward_to_ext_vector_http_user_defined&#34;] source = &#39;&#39;&#39; del(.file) &#39;&#39;&#39; [transforms.ext_vector_http_dedot] type = &#34;lua&#34; inputs = [&#34;ext_vector_http_normalize_http&#34;] version = &#34;2&#34; hooks.init = &#34;init&#34; hooks.process = &#34;process&#34; source = &#39;&#39;&#39; function init() count = 0 end function process(event, emit) count = count + 1 event.log.openshift.sequence = count if event.log.kubernetes == nil then emit(event) return end if event.log.kubernetes.labels == nil then emit(event) return end dedot(event.log.kubernetes.namespace_labels) dedot(event.log.kubernetes.labels) emit(event) end function dedot(map) if map == nil then return end local new_map = {} local changed_keys = {} for k, v in pairs(map) do local dedotted = string.gsub(k, &#34;[./]&#34;, &#34;_&#34;) if dedotted ~= k then new_map[dedotted] = v changed_keys[k] = true end end for k in pairs(changed_keys) do map[k] = nil end for k, v in pairs(new_map) do map[k] = v end end &#39;&#39;&#39; [sinks.ext_vector_http] type = &#34;http&#34; inputs = [&#34;ext_vector_http_dedot&#34;] uri = &#34;http://vector-http.tkimura-infra.svc:8080&#34; method = &#34;post&#34; [sinks.ext_vector_http.encoding] codec = &#34;json&#34; [sinks.ext_vector_http.buffer] when_full = &#34;drop_newest&#34; [sinks.ext_vector_http.request] retry_attempts = 17 timeout_secs = 10 # Bearer Auth Config [sinks.ext_vector_http.auth] strategy = &#34;bearer&#34; token = &#34;eyJhbGciOiJSUzI1NiIsImtpZCI6Im03RElRbTF6ZXdvU01mQ3lRcGZUUTZWUXRlVVJ1WHJtdWlVaUo0Y0tmSUUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJvcGVuc2hpZnQtbG9nZ2luZyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJsb2djb2xsZWN0b3ItdG9rZW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoibG9nY29sbGVjdG9yIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMjk1N2NjNDAtZTRjNS00YzMzLWE2MGQtMGFiZDU5ZGRjMGJlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Om9wZW5zaGlmdC1sb2dnaW5nOmxvZ2NvbGxlY3RvciJ9.OTVa3zjpdEUCPmQ2vru3UexUBsp63cb6wZWOLdM0cPKAYRj-clibbFa36WBV9OG__L0ujRVnPBBetkh1r9QwO4HpOPCi7owlcDWn_yOc3_tEVsWge5LZT28QEVm2vQh4n_sON1HRcwmnYKqJVMOStpD6WjIW9tIADai9RlW-d47iumC6j8eqXVF1zY-N09jkLAA3ZuBXqBpPmI4W24FZOlPmEAEGwE--H8dYxUjwheD12e1EntYBOjRpnUb9Sx86GqOnG1LIbfb3jv0MbndOFs7kIbus2Xc516OaHoFJfEoxl-SMxGdKcCOtm38S5ikpsfEC6LfcapTV0mg5JitpgOJI9QiUDwZ8ClOKk0z1JxNQQJcJPjg1zy0OjqZrSeIS4TqdzLsAUrA-tuu7HWpbKlwuNVNiLBqKw8N3JqTTEK3j0WeVvEYlBacZsyCBpfH8Vt8234r9ckbs67278tniUmQ5Y-4Y8ybEUjp6cIcs28T13DGfQmWOftlBgltTAmvpXAUCgBu6bTPXZLXCCmCs5VzTfK8W9NcVjOp-fmyIYVm2uBY1mSw5WXIP15I8FCsa22zzMXlGPU1IIDQuNQJCFvGQxeeWa0rZP5T_8wxjhi6tScJHh_XTKcx8sxKJHagYmIvYfF39oI0ZCo_pdCTI5EZ990JiFch5-dVv3zBzIyc&#34; [transforms.add_nodename_to_metric] type = &#34;remap&#34; inputs = [&#34;internal_metrics&#34;] source = &#39;&#39;&#39; .tags.hostname = get_env_var!(&#34;VECTOR_SELF_NODE_NAME&#34;) &#39;&#39;&#39; [sinks.prometheus_output] type = &#34;prometheus_exporter&#34; inputs = [&#34;add_nodename_to_metric&#34;] address = &#34;[::]:24231&#34; default_namespace = &#34;collector&#34; [sinks.prometheus_output.tls] enabled = true key_file = &#34;/etc/collector/metrics/tls.key&#34; crt_file = &#34;/etc/collector/metrics/tls.crt&#34; min_tls_version = &#34;VersionTLS12&#34; ciphersuites = &#34;TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305,DHE-RSA-AES128-GCM-SHA256,DHE-RSA-AES256-GCM-SHA384&#34;</pre> <p>また、以前のFluentdではディスクバッファを利用する設定でしたが、Vectorではディスクを利用しないメモリバッファ設定となります。理由はいくつかあり、リソース消費が大きく遅い、遅いのでログが消失する、単に無駄、というものが大きな理由です。</p> <p>ディスクバッファ設定では、ディスクバッファに一度書いてから転送してバッファ削除、という処理となります。入力がネットワーク受信したログなどであれば合理的な構成ですが、入力がディスク上のログなので、それを読み込んでもう一度ディスクに書き込むのは大きな無駄です。基本的には元となるコンテナログの保持サイズ、期間を伸ばせば済むところです。当然処理が多くなるので、パフォーマンスが低く、CPUやメモリの消費量が大きくなり、かつ転送処理が大幅に遅くなります。ログ出力レートが高いと転送が追いつかなくなり、バッファがフルになり入力がブロックされ(もしくはダイレクトにログ転送破棄が行われ)、その間にもログローテーションが発生すると転送されないログが発生してログ消失となります。ログ出力が多い、nodeあたりPod数が多い、などの条件で顕著にログ消失が発生してしまいます。言い換えると、Fluentd構成でログ消失をなるべく防ぎたい、という場合はノード一台あたりのログ出力レートを小さく保つ必要があるため、多数のコンテナが稼働する大きいサイズのノードを利用することができなくなります。</p> <p>対してメモリバッファでは単純な強制終了で少量のログが転送されず消失するリスクがある、という点はありますが、上記の問題はすべて回避でき、また以前のFluentdの構成と比べて何十倍という単位で高速で動作するので、リスクとなる「転送処理中のログ」自体が非常に小さく保てます。Vectorにもdisk bufferオプションはありますが、500msインターバルでメモリを永続化する非同期のモデルとなっており、同期ではないので、ディスクバッファ設定を行ったとしても耐障害性ではメモリバッファとあまり大差はなさそうです。</p> <p>たとえばもし強制終了が多く発生する、そのときにログ転送のログ消失は防止したい、といった特殊な前提条件があるのであれば、Vectorはその要件を満たすことはできなさそうですので、OpenShift LoggingのVectorではなく自前でログ収集エージェントを選定して設定したほうが良いでしょう。</p> <p>検証していても、以前のFluentd設定では初期設定からログが収集されるまで小一時間待つ必要がありましたが、Vectorでは一瞬で全ログが転送されるのが便利です。</p> nekop マイクロサービスとメッセージングのなぜ [希望編] hatenablog://entry/6801883189067607298 2023-12-22T07:00:00+09:00 2023-12-22T07:00:00+09:00 レッドハットでインテグレーションのためのミドルウェアのテクニカルサポートを担当している山下です。以前、SAGAやEventStormingについて記述すると宣言していたのですが、実際のところ私が書くよりもよっぽど良い日本語の書籍や記事がでていて、もう書く必要もないと思っていたのですが、今回機会をいただいたので約4年ぶりに”マイクロサービスとメッセージングのなぜ"の希望編を書くことになりました。今回の記事ではSAGAやEventStormingの詳細は書かないのですが、私がイベントやメッセージングが必要と考えるに至った危機感や希望を共有します。そうした意味ではむしろ原点ともいえる内容になっていま… <p>レッドハットでインテグレーションのためのミドルウェアのテクニカルサポートを担当している山下です。以前、SAGAやEventStormingについて記述すると宣言していたのですが、実際のところ私が書くよりもよっぽど良い日本語の書籍や記事がでていて、もう書く必要もないと思っていたのですが、今回機会をいただいたので約4年ぶりに”マイクロサービスとメッセージングのなぜ"の希望編を書くことになりました。今回の記事ではSAGAやEventStormingの詳細は書かないのですが、私がイベントやメッセージングが必要と考えるに至った危機感や希望を共有します。そうした意味ではむしろ原点ともいえる内容になっています。なお今回記事にはとりわけ個人的な経験や意見が多く含まれますので、事前に異論は認めることにします。</p> <ul> <li>以前の記事はこちら: <ul> <li>「<a href="https://rheb.hatenablog.com/entry/microservices_messaging">マイクロサービスとメッセージングのなぜ [概要編]</a>」</li> <li>「<a href="https://rheb.hatenablog.com/entry/microservices_messaging_2">マイクロサービスとメッセージングのなぜ [疑問編]</a>」</li> </ul> </li> </ul> <h2 id="終わりのなく続く名詞集めとモノリシックなモデル">終わりのなく続く名詞集めとモノリシックなモデル</h2> <p>リレーショナルデータベース中心アーキテクチャによってプロジェクトを進めてきた方は私を含め多くいらっしゃるのではないでしょうか。様々な方法がありますが、それは例えば、ユースケースから名詞を拾い集め、データ中心によるモデル、とりわけデータ構造を定義していく方法があります。</p> <p>要件やビジネスプロセスを分析して、ユースケースの詳細を記述したユースケース記述では、システムがどのように使用されるかをユーザーや外部システムの視点から記述します。そこでは画面UIなどからシステムへのクエリやコマンドで利用される具体的な名詞(≒ データ)が記述されています。そしてそれらの名詞を洗い出してデータの正規化を行ない、そうしてできたデータ構造はER図やメソッドが省略されたクラス図に落とし込んでシステムの骨格を形づくっていきます。データ構造が決まれば、それらを利用する処理を配置するクラスは自ずと明らかになるので、プロラミングではデータ構造に肉付けするように開発を進めていくことができるようになるのです。</p> <p>おそらくこれは現在でも最も実践的な方法の1つであり、適したプロジェクトも数多くあります。実際私もこうした方法を実践してきました。この方法に一概に問題があるというつもりは全くないのですが、しかし限界もあります。</p> <div align="center"> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tyamashi-oss/20231218133939" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tyamashi-oss/20231218/20231218133939.jpg" width="926" height="478" loading="lazy" title="" class="hatena-fotolife" style="width:700px" itemprop="image"></a></span> </div> <h5 id="変更コストは高い事前に予期して完璧なモデルを作成する">変更コストは高い、事前に予期して完璧なモデルを作成する</h5> <p>こうしたデータ構造のモデルは画面などと比べれば安定しているともいわれたりしますが、とはいえシステム要件が追加されることで変わっていくことはよくあり、実際のところ安定しているなどとはとてもいえないものです。また些細なように見える追加要件がドラスティックにデータ構造のモデルを変えて、そこから各種の設計書やUIに変更が波及し続ける開発を自分を含め多くの方が経験しているでしょう。データ構造の変更はそれに依存した多くの実装への修正を伴うために、大きな手戻りやコストを伴います。ですから、どれだけ要件を予め洗い出すことができるのか、また顧客のニーズを予期して、できるだけ事前にモデルに取り入れることに努めて、実装に進む前により完璧なモデルを追求することになります。</p> <h5 id="境界なくフラットに広がり続けるデータ構造のモデル">境界なくフラットに広がり続けるデータ構造のモデル</h5> <p>より完璧なモデルを追求する中で、様々な要件や一見して想定しえないような例外的な要件であったとしてもモデルはそれを飲み込み続けなければなりません。なぜなら想定されなかった要件や事実をモデルは受け入れず、その事実自体がむしろ存在しなかったように否定されてしまうからです。”一度の注文でも発送は数回に分割することが時々ある”、“あとから当時の状況がわかるように履歴を作りたい”、”棚下しの中でで発送したはずの商品がバーコードで検出された”、どれも胃が痛くなってきます。こうして、様々なドメインを巻き込みながら、履歴/事実、状態、例外状態、あらゆるコマンドやクエリに対応して、境界なくフラットにデータ構造のモデルは広がり続けます。</p> <h5 id="ブロックされる開発">ブロックされる開発</h5> <p>広がり続けるモデルの一方で、要件をできるだけヒアリングして網羅しモデルやデータ構造が十分に納得できるまで、開発が進められないといったことが起こります。後戻りのコストは高くつくために、モデルがより完璧でなければならないのです。とはいえどこかで区切りをつけて開発を開始しなければなりません。逆算してプロジェクトのデッドラインが許すまでの分析を続けることになります。そして開発が始まった後には、データ構造のモデルが変化するような要件が発覚しないよう、不安を抱えながら祈り続けるのです。</p> <h5 id="モノリシックなシステムに突き進む">モノリシックなシステムに突き進む</h5> <p>名詞集めは十分に実践的ですが、様々な要件のクエリやコマンドから名詞を洗い出し、それらすべての整合性を保ったデータ構造を設計し続けなければなりません。新たな要件を満たすように少しづつ巨大化していくデータ構造のモデルは、フラットに広がり続けます。モデルは想定を超えて大きくなり、その大きな役割をますますリレーショナルデータベースに頼るようになります。実際のところ様々な要件を満たす完璧なモデルには近づくことさえ難しいことも多くの方はご存知でしょう、新しい要件の統合はより難しさ増していきます。しかし整理したり分割しようとしても、データベース中心アーキテクチャで確立されたモデルを分割することは、ソフトウェア開発における最も高価なリファクタリングの1つです。後戻りもできないままに、重箱の隅をつつくように名詞を集め続け、より完璧なモデルを追求しながらモノリシックなモデル、そしてモノリシックなシステムへと突き進み続けることになります。</p> <h2 id="イベントを集めるEventStorming">イベントを集めるEventStorming</h2> <p>上記のような名詞を集める方法に対して、イベントを集めるEventStormingという方法があります。これはポストイットを使ったコラボレーションワークショップで、イベントを中心としたアプローチが特徴です。EventStormingの目的には、ドメインを理解するための学習やチームワーク、問題発見や解決策の創出、ビジネスプロセスの可視化や、境界づけられたコンテキストや集約の識別などがあり、それらの目的に応じて様々なテクニックや手法を調整して利用します。</p> <div align="center"> <figure class="figure-image figure-image-fotolife"> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tyamashi-oss/20231217224236" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tyamashi-oss/20231217/20231217224236.jpg" width="1200" height="417" loading="lazy" title="" class="hatena-fotolife" style="width:700px" itemprop="image"></a></span> <figcaption>出典: <a href="https://openpracticelibrary.com/practice/event-storming/">https://openpracticelibrary.com/practice/event-storming/</a> </figcaption> </figure> </div> <p>ここではEventStormingの詳細は説明しませんが、大まかには以下のような手順で進みます。</p> <h5 id="1-イベントオレンジ色のポストイットを洗い出す">1. イベント(オレンジ色のポストイット)を洗い出す</h5> <p>まずビジネスプロセスに関連するイベントを、大まかな時系列に沿って洗い出していきます。イベントは通常「~した」という過去形あるいは過去分詞形の形式で記述され、システムに関連した事実を表します。イベントは、ユーザーの操作、外部システム、時間、他のイベントなどから発生しますが、しかしとりわけこの時点では特定の発生元に囚われることなく当該のドメイン内で発生している事実を洗い出していきます。またイベント名に過去の時制の動詞を使用して、状態遷移に焦点を当てることで、その推論からドメイン全体の探索へ繋げていきます。</p> <h5 id="2-コマンド青色のポストイットの特定">2. コマンド(青色のポストイット)の特定</h5> <p>各イベントをトリガーするコマンドを特定します。コマンドはアクターの判断の結果として行われるシステムへの指示で「~する」という形式で記述されます。なおアクターは黄色のポストイットで表します。</p> <h5 id="3-リードモデル緑色のポストイットの追加">3. リードモデル(緑色のポストイット)の追加</h5> <p>アクターがコマンドを実施する際の判断に必要な情報をリードモデルとして追加します。リードモデルは、データの表示や分析に特化したモデルでクエリ操作のために利用されます。</p> <h5 id="4-ポリシーライラック色のポストイットの追加">4. ポリシー(ライラック色のポストイット)の追加</h5> <p>何らかのイベントが発生した時にコマンドを発行するルールとしてポリシーを追加します。これらは「〜(何らかのイベント) するときはいつでも」で始まることも多く、システムが自動的に行うことや、人が記憶しておくべきことなどを表します。</p> <h5 id="5-集約大きな薄黄色のポストイットの識別">5. 集約(大きな薄黄色のポストイット)の識別</h5> <p>関連するイベントやコマンド群、ビジネスルールやトランザクションによるデータ整合性を維持するための集約を識別します。集約はドメインモデルの一部で、データと処理をカプセル化した責務を持つ単位です。集約は、イベントソーシングの文脈ではデータの書き込みに特化したライトモデルに対応し、コマンドに対して異なる応答をするので、小さなステートマシンのようにみえることもあります。</p> <div align="center"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tyamashi-oss/20231218/20231218002927.jpg" width="1200" height="602" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span> </div> <h5 id="6-境界づけられたコンテキストを定義する">6. 境界づけられたコンテキストを定義する</h5> <p>言葉や意味の一貫性の程度が高いグループ、同時に変更される可能性が高い機能のまとまりから、境界づけられたコンテキストを定義します。モデルの一貫性は境界づけられたコンテキスト内のでのみ達成でき、そのモデルは限界を超えて大きくすることはできません。意味の一貫性の程度が高い複数の比較的小さなモデルを目指します。</p> <h5 id="集約の定義は意図的に延期されている">集約の定義は意図的に延期されている</h5> <p>EventStormingでははじめにイベントを集めていく一方で、集約の識別は手順の終わりの方になるまで意図的に延期されます。ビジネスプロセスやシステムの振る舞いを十分に理解した後に、コマンドやイベント、ポリシーなどを頼りにして、責務に基づいた精度の高い集約のモデリングが可能になります。私たちはモデルの内部構造について画面上で見たいものを重ね合わせ、名詞を集めてくる習慣によって、責務ではなく背後にあるデータの正規化から暗に集約を見つけようとしてしまうことがあります。しかしそうすると同じ識別子(ID)に紐づくデータとそれに関連するイベントやコマンドまでも引きづられて塊になり、集約が肥大化して分割が難しくなるので注意してください。</p> <h2 id="イベントを集めてもっと小さく柔軟で進化するモデルへ">イベントを集めてもっと小さく柔軟で進化するモデルへ</h2> <h5 id="リードモデル集約ライトモデルイベント">リードモデル、集約(ライトモデル)、イベント</h5> <p>EventStormingではリードモデルと集約(ライトモデル)の2つの役割のモデルがあります。また事実や履歴についてはイベントに任せることができるでしょう。さらには境界づけられたコンテキストごとに必要な機能や責務によってもモデルを分割できる柔軟性があります。</p> <div align="center"> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tyamashi-oss/20231218/20231218134324.jpg" width="1200" height="613" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span> </div> <p>これらは基礎としてイベントが存在していることによって実現されます。マイクロサービスのような小さく独立したサービス間での連携が行えるほか、データ転送によって統合された表示用のリードモデルを実現することができます。またシステムの状態変化をイベントとして蓄積(イベントソーシング)すれば、イベント自体が事実や履歴となり、またモデルの変更があっても過去のイベントの蓄積から再評価して新しいモデルへと柔軟に進化させることができます。さらには過度な要件をモデルに取り込まないという選択ができることもあります。例えば本来想定しえないような稀で例外的な要件は、イベントに保存しておき、集約(ライトモデル)には取り込まずに例外のレポートを出力させるに留めるといった方法もありえます。</p> <h5 id="境界づけられたコンテキストによる分割">境界づけられたコンテキストによる分割</h5> <p>また境界づけられたコンテキストにより、同じ識別子(ID)を共有するエンティディであったとしても、それぞれに特化したモデルに分割できることもあります。例えば一口に"ユーザ"という同じ識別子(ID)を共有するエンティティであったとしても、境界づけられたコンテキストが異なれば、受注では購入者、請求では請求先、出荷では配送先、CRMでは顧客、システム上ではログインユーザといった具合に独自のモデルによってデータや機能が異なることがありえます。</p> <div align="center"> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tyamashi-oss/20231218155413" class="hatena-fotolife" itemprop="url"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tyamashi-oss/20231218/20231218155413.jpg" width="1187" height="596" loading="lazy" title="" class="hatena-fotolife" style="width:800px" itemprop="image"></a></span> </div> <p>上記は単純な例ではありますが、これらは同じユーザIDを持ちながらも、境界づけられたコンテキストごとに異なるデータや振る舞いを持った集約として分割されました。ところで集約はトランザクションによるデータ整合性を維持する単位でもあるため、更新時の排他制御やロックも考慮することになります。一般的にはレコード単位を集約ルートのインスタンスして、そこにロックをかけてデータ整合性を確保することが多いでしょう。しかし例えばログインユーザの場合にはログインユーザ名やメールアドレスが全体の中でユニークでなければならないといった要件を実現するために縦にカラム一式を排他制御するするシングルトンの集約にすることも考えられるかもしれません。レコードによる主キーや正規化にばかりに気を取られずに、集約の振る舞いに注目すれば、もっと自由な視点でモデルを分割できる可能性が広がります。</p> <p>イベントを導入することで、システム内のサービスは小さな独立したモデルに分割され、それぞれが特定イベントに反応して動作するようになります。そして各モデルが新しい要件に柔軟に対応でき、全体のシステムを複雑化することなく進化し続けることができます。</p> <h1 id="まとめ">まとめ</h1> <p>今回は、ソフトウェア開発における名詞を集めてデータ構造を定義していくアプローチと、EventStormingによるイベント集めのアプローチについて説明しました。名詞を集めてデータ構造を定義していく方法は十分に実践的で、それが適したプロジェクトも数多くあります。しかしあらゆる要件を満たすように少しづつ巨大化して、柔軟性に欠けたモノリシックなシステムへと突き進み続けることになる可能性があります。</p> <p>一方、EventStormingによるイベント集めのアプローチでは、イベント、コマンド、リードモデル、ポリシー、集約などを用いて、ビジネスプロセスを理解し、より柔軟で適応性の高いモデルを構築します。またリードモデルや集約(ライトモデル)、イベントなど異なる役割を持ったモデルに分割され、さらには境界づけられたコンテキストごとに必要な機能や責務によってもモデルを分割できる柔軟性があります。こうした分割により新しい要件に対して柔軟に対応でき、全体のシステムが過度に複雑化することなく個別に進化し続けることが可能になります。イベントやメッセージングはマイクロサービスには欠かすことができないものです。</p> <p>私がイベントやメッセージングが必要と考えるに至った危機感がいくらかでも共有しできたでしょうか。名詞を集めてデータ構造を定義していく方法ははじめはパズルを解くような楽しさもありますが、選択肢が少なく、どこか予め決められた道を歩かされているような窮屈さがあります。それはレールが続いているのか崖になっているのかも分からないジェットコースターにチーム全体がのって進まされているような恐怖とでもいいましょうか。要件が複雑であったりシステムが進化していくことを前提とすると、こうした名詞集めによるモノリシックなモデルにはずっと限界を感じてきました。より完璧なデータ構造を求めて残業を続けたことも、大きな手戻りを恐れて名詞を集め続けながら開発フェーズに進めなかったことも、データ構造のモデルが変化するような要件が発覚しないよう不安を抱えて祈り続けたことも、これらは全て自分の苦い経験ではありますが、おそらく責任ある多くのエンジニアにも似た経験があるのではないかとも思います。イベントやメッセージングにも特有の難しさはあり、手放しで簡単だというつもりはありませんし、確実な未来もわかりません。しかしこの希望編から、もっとモデルに選択肢があるかもしれない、もっと柔軟にモデルを描いてもいいかもしれない、イベントやメッセージングを導入してもよいかもしれない、と少しでも考えるきっかけになれば幸いです。</p> <h2 id="参考文献">参考文献</h2> <ul> <li><a href="https://leanpub.com/introducing_eventstorming">Introducing EventStorming</a></li> <li><a href="https://www.manning.com/books/microservices-patterns">Microservices Patterns</a></li> <li><a href="https://www.enterpriseintegrationpatterns.com/index.html">Enterprise Integration Patterns</a></li> <li><a href="https://github.com/microsoftarchive/cqrs-journey/blob/master/docs/Journey_00_Preface.markdown">Exploring CQRS and Event Sourcing</a></li> </ul> <h2 id="PR">[PR]</h2> <ul> <li>オープンソースの<a href="https://kafka.apache.org">Apache Kafka</a>をベースとした製品として、Red Hatから<a href="https://access.redhat.com/products/red-hat-amq-streams/">AMQ Streams</a>が提供されています。<a href="https://access.redhat.com/products/red-hat-amq-streams/">AMQ Streams</a>にはさらに、KubernetesやOpenShiftの上でApache Kafkaの運用の自動化を実現する、オープンソースの<a href="https://strimzi.io">Strimzi</a>をベースとした機能も含まれています。Red Hat製品に興味ない方もKubernetesを利用している方は<a href="https://strimzi.io">Strimzi</a>をぜひ使ってみてください。</li> </ul> tyamashi-oss Red Hat OpenShift Service on AWS (ROSA)を無料で試してみよう hatenablog://entry/6801883189068352728 2023-12-21T13:29:40+09:00 2024-01-12T17:52:15+09:00 OpenShift Advent Calendar 2023/AWS Containers Advent Calendar 2023の12/14の記事です。 Red Hatの小島です。 2023年12月に、Managed OpenShiftサービスの1つであるROSAを無料で試せるROSA Hands-on Experienceというサービスがリリースされました。本記事では、同時期に提供開始しましたROSA Hosted Control Plane (HCP)の特徴と共に、ROSA Hands-on Experienceの概要をご紹介します。 ROSA Hosted Control Plane… <p><a href="https://qiita.com/advent-calendar/2023/openshift">OpenShift Advent Calendar 2023</a>/<a href="https://qiita.com/advent-calendar/2023/aws-containers">AWS Containers Advent Calendar 2023</a>の12/14の記事です。</p> <p>Red Hatの小島です。<br> 2023年12月に、Managed OpenShiftサービスの1つであるROSAを無料で試せる<a href="https://console.redhat.com/openshift/overview/rosa/hands-on">ROSA Hands-on Experience</a>というサービスがリリースされました。本記事では、同時期に提供開始しましたROSA Hosted Control Plane (HCP)の特徴と共に、ROSA Hands-on Experienceの概要をご紹介します。</p> <ul class="table-of-contents"> <li><a href="#ROSA-Hosted-Control-Plane-HCP">ROSA Hosted Control Plane (HCP)</a></li> <li><a href="#ROSA-HCPの料金情報">ROSA HCPの料金情報</a></li> <li><a href="#ROSA-Hands-on-Experience">ROSA Hands-on Experience</a></li> <li><a href="#ROSA-HCPワークショップ日本語コンテンツ">ROSA HCPワークショップ日本語コンテンツ</a></li> </ul> <h5 id="ROSA-Hosted-Control-Plane-HCP">ROSA Hosted Control Plane (HCP)</h5> <p>ROSA HCPは、OpenShift 4.14のベアメタルおよびOpenShift Virtualizationで正式にリリースされた<a href="https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.14/html-single/hosted_control_planes/index">Hosted Control Plane</a>が取り入れられたROSAです。ROSA HCPでは、OpenShiftのコントロールプレーンがRed Hat SREチームのAWSアカウントに作成されるOpenShiftクラスターのPodとしてデプロイされるようになり、ユーザーのAWSアカウントにはワーカーノードのみデプロイされます。これによって、ユーザーにはコントロールプレーンが隠蔽されてワーカーノードしか見えなくなる、というシンプルな構成になりました。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/h-kojima/20231220/20231220162114.png" width="1200" height="735" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>ROSA HCPは、コントロールプレーン/インフラノード/ワーカーノードが全てユーザーのAWSアカウントに作成される従来のROSA(ROSA Classicと定義しています)に比べると使い勝手がかなり向上しており、次のような特徴を持つため、Kubernetesインフラ観点ではAmazon EKSなどのManaged Kubernetesサービスに近いものとなっています。</p> <ul> <li>最小構成がワーカーノード2台構成 (SingleAZ/MultiAZ共通。デフォルトはm5.xlarge(4vCPU/RAM16GiB) x2)</li> <li>クラスターデプロイ時間の短縮 (ROSA Classic: 40分~。ROSA HCP: 25分~)</li> <li>ワーカーノードをAZ単位で1台から追加可能 (SingleAZ/MultiAZ共通)</li> <li>ワーカーノード追加時のバージョン選択が可能</li> <li>コントロールプレーンの更新時間の短縮 (ROSA Classic: 90分ほど。ROSA HCP: 15分ほど)</li> <li>コントロールプレーンとワーカーノードの更新の分離</li> <li>一部のワーカーノードのみを更新するという部分更新の対応</li> </ul> <p>これらのインフラ的な特徴に加えて、</p> <ul> <li>コンテナアプリケーションの開発/運用を支援するための様々な機能 <ul> <li>アプリケーションのトポロジー/モニタリング/ロギングを利用するためのWebコンソール</li> <li>Visual Studio Code的なWeb IDE (AI搭載生産性向上ツールである<a href="https://aws.amazon.com/jp/codewhisperer/">Amazon CodeWhisperer</a>プラグインも利用可能)</li> <li>様々なフォーマットの入力に対応した、アプリケーションビルド/デプロイの自動化 <ul> <li>Gitリポジトリのソースコード/Dockerfile, コンテナイメージ, JARファイルなど</li> </ul> </li> <li>アプリケーションのベースOSとなるRHELのサポート</li> <li>Red Hatのパートナーエコシステムによる、様々なミドルウェアのサポート (Kubernetes Operator含む)</li> </ul> </li> <li>上記機能をマルチテナント的に利用するための、外部認証プロバイダーとの連携</li> <li>エンタープライズシステムとして利用するための、Kubernetes基盤のセキュリティ強化 (コンテナアプリでのroot利用禁止など)</li> </ul> <p>といったOpenShiftならではの特徴も備えているため、エンタープライズ用途にパッケージングされたManaged KubernetesサービスをAWS上で利用したい場合に、ROSA HCPが適したサービスであると言えます。</p> <h5 id="ROSA-HCPの料金情報">ROSA HCPの料金情報</h5> <p>ROSA HCPを利用する場合、次の3つの合計金額がAWSからユーザーに請求されます。Red Hatからの請求料金はありません。</p> <ul> <li>ROSA HCPのクラスター料金 (1クラスター辺りの料金。0.25USD/cluster/時間)</li> <li>ワーカーノードのサービス料金 (0.171USD/4vCPU/時間)</li> <li>AWSリソースの利用料金 (ワーカーノードのEC2インスタンス, EBS, S3, NAT Gatewayなど)</li> </ul> <p>デフォルトはm5.xlarge(4vCPU/RAM16GiB)インスタンスの2台構成となりますので、AWS料金情報に基づいて、オハイオリージョンでのSingleAZ2台構成の1時間辺りの利用料金を計算してみると、大体の目安は<strong><span style="color: #ff0000">$1.3/時間~</span></strong>となります。主なAWSサービスの料金内訳は次のようになります。計算の簡単化のために、料金内訳からはS3やデータ転送などの利用料金を除いています。</p> <ul> <li>クラスター料金 <ul> <li><strong>$0.25</strong> (0.25(USD/cluster) x 1(cluster))</li> </ul> </li> <li>ワーカーノードのサービス料金 <ul> <li><strong>$0.342</strong> (0.171(USD/4vCPU) x 2(4vCPU))</li> </ul> </li> <li>ワーカーノードのEC2/EBS(300GiB x2)の利用料金 <ul> <li><strong>$0.467</strong> (0.192(USD) x 2 + 0.1(USD/GB/month) x 300(GB) / 720(時間/month) x 2)</li> </ul> </li> <li>NAT Gatewayの利用料金 (プライベートサブネット1つに付き1つ作成されます) <ul> <li><strong>$0.045</strong></li> </ul> </li> <li>NLBの利用料金 <ul> <li><strong>$0.0225</strong></li> </ul> </li> </ul> <p>コントロールプレーンとインフラノードも料金請求の対象であった従来のROSA Classicと比較すると、かなりスリム化した料金となっています。なお、ROSA HCPでは、インフラノードとしてみなされるワーカーノードはありません。ルーター/レジストリ/モニタリングなどのコンポーネントは全てワーカーノード上で稼働し、全てのワーカーノードの利用料金が請求されることになります。</p> <h5 id="ROSA-Hands-on-Experience">ROSA Hands-on Experience</h5> <p>本題です。<a href="https://console.redhat.com/openshift/overview/rosa/hands-on">ROSA Hands-on Experience</a>は、Red Hatのデモプラットフォームを利用して、ユーザーが無料でROSA HCPクラスターにアクセスして、ハンズオンができるサービスです。Red Hatアカウントでログインして「Request experience」をクリックすると、大体数十秒でデモプラットフォーム上のROSA HCPクラスターにアクセスできるようになっています。このサービスを利用する場合、AWSアカウントをご用意いただく必要はありません。</p> <p>また、この画面からROSAコミュニテイのSlackチャネル(英語)に参加できるだけでなく、ハンズオン中に質問がある場合、画面右下のRed Hatロゴをクリックすることで、Red Hatのカスタマーサクセスチームと英語チャットができるようになっています。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/h-kojima/20231220/20231220193054.png" width="1200" height="729" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>デモプラットフォームにアクセスすると、次のような画面が表示されます。ユーザーは画面左半分のコンテンツに表示されるコマンドを、画面右半分のTerminalにコピペして、ROSA HCPクラスターを操作していく流れとなります。また、ROSA HCPクラスターの管理者アカウントで、Webコンソールにログインして利用できるようにもなっています。これらのコンテンツは全て英語となっているため、必要に応じてWebブラウザの機械翻訳機能を使ってください。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/h-kojima/20231220/20231220194155.png" width="1200" height="594" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>2023年12月時点での、ROSA Hands-on Experienceのコンテンツは下記の16項目です。ROSA特有の項目だけ学習したい場合は、<code>1. Explore the ROSA environment</code>から<code>6. Configure Red Hat SSO IDP for ROSA</code>までだけを実行してもいいでしょう。</p> <p><strong>・ROSA特有の内容を含むコンテンツ</strong></p> <ol> <li>Explore the ROSA environment</li> <li>Upgrade your ROSA cluster</li> <li>Managing Worker Nodes</li> <li>Autoscale your ROSA Cluster</li> <li>Labeling your Worker Nodes</li> <li>Configure Red Hat SSO IDP for ROSA</li> </ol> <p><strong>・ROSAだけでなく、Self-Managed OpenShiftでも実行可能なコンテンツ</strong></p> <ol> <li>Configure Red Hat OpenShift Logging with AWS Cloudwatch</li> <li>Deploy an Application with AWS Database</li> <li>Deploy an Application with Red Hat OpenShift GitOps</li> <li>Secure your applications with Network Policies</li> <li>Make your application resilient</li> <li>Service Mesh Introduction</li> <li>Install Service Mesh Operator</li> <li>Deploy Service Mesh Control Plane</li> <li>Deploy a Service Mesh example application</li> <li>Configure and observe Service Mesh traffic</li> </ol> <p>なお、ROSA Hands-on Experienceについては、<strong><span style="color: #ff0000">8時間/1回の利用を3回まで(延べ24時間)</span></strong>という制限があります。4回目以降の利用はできませんので、ご注意ください。</p> <h5 id="ROSA-HCPワークショップ日本語コンテンツ">ROSA HCPワークショップ日本語コンテンツ</h5> <p>上記を翻訳したコンテンツではありませんが、主にROSA HCP特有の項目にフォーカスして、ROSA HCPクラスターでのアプリケーション開発/運用の基礎を体感していただくための日本語コンテンツ(下図の「ROSA Lab」と記載しているもの)も別途提供しています。この日本語コンテンツを参考にしながら、ROSA Hands-on Experienceで払い出されたROSA HCPクラスターでハンズオンを実施することもできます。ただし、その場合は次の制限がありますのでご注意ください。</p> <ul> <li><strong>この日本語コンテンツは、Red Hatのカスタマーサクセスチームの管理下にないため、チャットやSlackでの質問はできません。</strong></li> <li>ROSA HCPクラスターの作成手順は実行できません。</li> <li>ROSA Hands-on ExperienceではAWS IAMユーザーを払い出さないため、この日本語コンテンツで紹介しているCloudWatchでのロギング設定/確認手順は実行できません。</li> <li>ワーカーノードについては、既存のMachinepool(ROSAでワーカーノードを扱う単位)についてのみ編集(ワーカーノードの追加/削除/オートスケール化/更新など)できます。そのため、新規Machinepoolの追加や削除は実行できません。</li> <li>最新版のROSA HCPクラスターが払い出されている場合、ROSA HCPクラスターの更新手順は実行できません。</li> </ul> <p>ROSA HCPワークショップ日本語コンテンツは、下記のリンクからご参照ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frh-open.github.io%2Focp-handson%2Fopenshift-services%2F50-rosa-info.html" title="はじめに :: OpenShift Handson" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rh-open.github.io/ocp-handson/openshift-services/50-rosa-info.html">rh-open.github.io</a></cite></p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/h-kojima/20231220/20231220202132.png" width="1200" height="1043" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>このワークショップ日本語コンテンツについては、ご要望次第で個社向けにも開催しています。ご興味がありましたら、Red Hatの担当営業や下記の「購買専用のお問い合わせ」フォーム(「追加情報」記入欄に「赤帽ブログで見た個社向けROSA HCPワークショップについての詳細を希望」などをご記入ください)からお問い合わせください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.redhat.com%2Fja%2Fcontact" title="Red Hat へのお問い合わせ" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.redhat.com/ja/contact">www.redhat.com</a></cite></p> h-kojima systemdのserviceをstraceする時のtips hatenablog://entry/6801883189067523738 2023-12-21T00:00:00+09:00 2023-12-21T08:09:58+09:00 Red Hatの森若です。 この記事はRed Hat Advent Calendar 2023 の21日目です。 デバッグなどのためにsystemdのservice unitで起動されるプロセスにstraceを仕掛けたいとき、ちょっとしたハマり所があるのでその説明とワークアラウンドを紹介します。 目次 実行中のserviceをstraceする 実行開始からserviceをstraceする Type=forking 時の問題 参考文献 おまけの宣伝 実行中のserviceをstraceする この場合は特にハマるところはありません。 既に実行中のプロセスへのstraceは、cgroupで関連するプ… <p>Red Hatの森若です。</p> <p>この記事は<a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar 2023</a> の21日目です。</p> <p>デバッグなどのためにsystemdのservice unitで起動されるプロセスにstraceを仕掛けたいとき、ちょっとしたハマり所があるのでその説明とワークアラウンドを紹介します。</p> <p>目次</p> <ul class="table-of-contents"> <li><a href="#実行中のserviceをstraceする">実行中のserviceをstraceする</a></li> <li><a href="#実行開始からserviceをstraceする">実行開始からserviceをstraceする</a><ul> <li><a href="#Typeforking-時の問題">Type=forking 時の問題</a></li> </ul> </li> <li><a href="#参考文献">参考文献</a></li> <li><a href="#おまけの宣伝">おまけの宣伝</a></li> </ul> <h3 id="実行中のserviceをstraceする">実行中のserviceをstraceする</h3> <p>この場合は特にハマるところはありません。 既に実行中のプロセスへのstraceは、cgroupで関連するプロセス一覧が管理されているので、それを利用します。関連する全てのプロセスを指定し、<code>-f</code>でforkも追跡することで、関連する全プロセスを指定します。</p> <ol> <li>serviceに対応するcgroupを確認する。</li> </ol> <pre class="code" data-lang="" data-unlink>$ systemctl show dbus-broker.service |grep ControlGroup= ControlGroup=/system.slice/dbus-broker.service または $ systemctl status dbus-broker.service |grep CGroup CGroup: /system.slice/dbus-broker.service</pre> <ol> <li>cgroupの <code>cgroup.procs</code> を利用してstrace の -p オプションに関連プロセスを指定する</li> </ol> <pre class="code" data-lang="" data-unlink># strace -fttTvyy -s 4096 -o /tmp/dbus.strace -p $(tr \\n , &lt; /sys/fs/cgroup/system.slice/dbus-broker.service/cgroup.procs)</pre> <h3 id="実行開始からserviceをstraceする">実行開始からserviceをstraceする</h3> <p>実行開始直後の初期化なども観測対象にする場合、起動時に straceの子プロセスとしてプログラムを実行開始します。 つまり以下のように指定して実行します。以下で説明しますが一部で問題が発生します。</p> <pre class="code" data-lang="" data-unlink>ExecStart=/usr/bin/strace -fttTvyy -s 4096 -o /tmp/strace.log もとのコマンド…</pre> <h4 id="Typeforking-時の問題">Type=forking 時の問題</h4> <p>systemdのservice unitにはType という属性がありsimple, oneshot, forkingなどいくつかの種類にわかれています。<code>Type=forking</code>の場合にはExecStartの書き換えだけでは期待通りに動作しません。 <code>systemctl start foobar.service</code> としたあとしばらく activating状態で動作し、起動に失敗したとして終了します。</p> <p>まずType=forkingの通常の動作について紹介します。この場合systemdが直接実行する「起動プロセス」と実際にサービスを提供する「サービスプロセス」が別になっています。</p> <p><figure class="figure-image figure-image-fotolife" title="Type=forkingの通常の動作"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/mrwk/20231217/20231217120131.png" width="1141" height="1200" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>Type=forkingの通常の動作</figcaption></figure></p> <p>上図のように、systemdは起動プロセスの実行終了をもって、service unitがactiveになったとみなします。</p> <p><figure class="figure-image figure-image-fotolife" title="ExecStartにstraceを付与した時の動作"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/mrwk/20231217/20231217120407.png" width="1149" height="1200" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ExecStartにstraceを付与した時の動作</figcaption></figure></p> <p>単純にExecStartの先頭にstraceを付与した場合、上図のようになります。straceは起動プロセスとサービスプロセスの両方をトレースしてログを出力し続けます。起動プロセスは終了し、サービスプロセスも通常どおりサービスを提供します。</p> <p>このときsystemdの視点では実行したプロセス(strace)が終了しないので、起動処理が完了しません。デフォルトでは1分30秒でsystemdはservice unitの起動が失敗したと判断し、シグナルを送信して関連するプロセスを停止します。これがさきほどの終了の原因です。</p> <p>ここまでわかれば対策は単純です。<code>Type=forking</code> を <code>Type=simple</code> のように変更します。 Type=simpleの場合、最初のfork実行時点でactiveとなり、プログラムが終了するとサービスがinactiveになります。</p> <p>さて <code>Type=oneshot</code>では、長時間動作するサービスプロセスにあたるものはなく、プロセスもタイムアウトより早く終了することが求められます。straceは全プロセス終了にともない早く終了します。そのため本来は類似の問題はほぼ発生しません。 ただし<code>Type=forking</code>を指定するべきアプリケーションに誤って<code>Type=oneshot</code>が指定されている場合があり、そのような場合には同様の問題が発生します。</p> <h3 id="参考文献">参考文献</h3> <p>詳しくは以下のman pagesに記載があります。</p> <ul> <li><a href="https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html#">systemd.service</a></li> <li><a href="https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#">systemd.exec</a></li> <li><a href="https://man7.org/linux/man-pages/man1/strace.1.html">strace</a></li> </ul> <h3 id="おまけの宣伝">おまけの宣伝</h3> <ul> <li><a href="https://gihyo.jp/book/2024/978-4-297-13893-6">systemdの思想と機能 ―Linuxを支えるシステム管理のためのソフトウェアスイート</a> 本日発売です</li> </ul> mrwk 【Ansible】win_shellモジュールで実行したコマンドの文字化けを修正する hatenablog://entry/6801883189068053387 2023-12-20T07:00:00+09:00 2023-12-20T07:00:00+09:00 この記事は、「Red Hat Advent Calendar 2023」20日目の記事です。 Windowsの文字化け問題 AnsibleでWindowsノードを管理していると、特にwin_shellモジュールでコマンドを実行した際などの実行結果が時折文字化けしてしまうケースがあります。こうなってしまうと、実行結果が正しく読み取れず、Windows自動化の障壁となってしまいます。 なぜ文字化けが発生するのか Ansibleでは、WinRM経由でWindowsに接続しますが、その際の新規セッションに対してはUTF-8を利用するよう指定して接続します。これは、通常のWindowsモジュールの実行で… <p>この記事は、「Red Hat Advent Calendar 2023」20日目の記事です。</p> <h3 id="Windowsの文字化け問題">Windowsの文字化け問題</h3> <p>AnsibleでWindowsノードを管理していると、特にwin_shellモジュールでコマンドを実行した際などの実行結果が時折文字化けしてしまうケースがあります。こうなってしまうと、実行結果が正しく読み取れず、Windows自動化の障壁となってしまいます。</p> <h2 id="なぜ文字化けが発生するのか">なぜ文字化けが発生するのか</h2> <p>Ansibleでは、WinRM経由でWindowsに接続しますが、その際の新規セッションに対してはUTF-8を利用するよう指定して接続します。これは、通常のWindowsモジュールの実行であれば問題は発生しません。</p> <p><a href="https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/winrm.py#L474-L477">https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/winrm.py#L474-L477</a></p> <pre class="code lang-python" data-lang="python" data-unlink> <span class="synComment"># open the shell from connect so we know we're able to talk to the server</span> <span class="synStatement">if</span> <span class="synStatement">not</span> self.shell_id: self.shell_id = protocol.open_shell(codepage=<span class="synConstant">65001</span>) <span class="synComment"># UTF-8</span> display.vvvvv(<span class="synConstant">'WINRM OPEN SHELL: %s'</span> % self.shell_id, host=self._winrm_host) </pre> <p>しかし、Shift_JISのような別の文字エンコーディングをデフォルトで利用しており、win_shellやwin_commandのようなPowerShell上でコマンドを実行するモジュールを利用する場合、実行されるコマンドはデフォルトの文字エンコーディングを利用するため、実行結果はShift_JISで返却されます。そのため、Ansibleに渡される実行結果はUTF-8でなくなり、文字化けが発生します。</p> <h2 id="対処方法">対処方法</h2> <p>上記のような想定していない文字化けに対処するため、win_shellモジュールなどでは「output_encoding_override」オプションが利用できます。</p> <p><a href="https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_shell_module.html">ansible.windows.win_shell module &ndash; Execute shell commands on target hosts &mdash; Ansible Documentation</a></p> <p>このオプションでは、返却された実行結果を指定した文字エンコーディングで上書きして解釈します。基本的に、Windows上で <code>[System.Text.Encoding]::GetEncodings()</code> を実行した際に返却される「Name」の文字エンコーディング(Shift_JISであればshift_jis)を指定できます。</p> <pre class="code" data-lang="" data-unlink>PS C:\Users\hiyoko&gt; [System.Text.Encoding]::GetEncodings() CodePage Name DisplayName -------- ---- ----------- 37 IBM037 IBM EBCDIC (US - カナダ) 437 IBM437 OEM アメリカ合衆国 500 IBM500 IBM EBCDIC (インターナショナル) 708 ASMO-708 アラビア語 (ASMO 708) 720 DOS-720 アラビア語 (DOS) 737 ibm737 ギリシャ語 (DOS) 775 ibm775 バルト言語 (DOS) 850 ibm850 西ヨーロッパ言語 (DOS) 852 ibm852 中央ヨーロッパ言語 (DOS) 855 IBM855 OEM キリル 857 ibm857 トルコ語 (DOS) 858 IBM00858 OEM マルチリンガル ラテン I 860 IBM860 ポルトガル語 (DOS) 861 ibm861 アイスランド語 (DOS) 862 DOS-862 ヘブライ語 (DOS) 863 IBM863 フランス語 (カナダ) (DOS) 864 IBM864 アラビア語 (864) 865 IBM865 北欧 (DOS) 866 cp866 キリル言語 (DOS) 869 ibm869 ギリシャ語, Modern (DOS) 870 IBM870 IBM EBCDIC (多国語ラテン 2) 874 windows-874 タイ語 (Windows) 875 cp875 IBM EBCDIC (ギリシャ語 Modern) 932 shift_jis 日本語 (シフト JIS) 936 gb2312 簡体字中国語 (GB2312) 949 ks_c_5601-1987 韓国語 950 big5 繁体字中国語 (Big5) 1026 IBM1026 IBM EBCDIC (トルコ語ラテン 5) 1047 IBM01047 IBM ラテン-1 1140 IBM01140 IBM EBCDIC (US - カナダ - ヨーロッパ) 1141 IBM01141 IBM EBCDIC (ドイツ - ヨーロッパ) 1142 IBM01142 IBM EBCDIC (デンマーク - ノルウェー - ヨーロッパ) 1143 IBM01143 IBM EBCDIC (フィンランド - スウェーデン - ヨーロッパ) 1144 IBM01144 IBM EBCDIC (イタリア - ヨーロッパ) 1145 IBM01145 IBM EBCDIC (スペイン - ヨーロッパ) 1146 IBM01146 IBM EBCDIC (UK - ヨーロッパ) 1147 IBM01147 IBM EBCDIC (フランス - ヨーロッパ) 1148 IBM01148 IBM EBCDIC (インターナショナル - ヨーロッパ) 1149 IBM01149 IBM EBCDIC (アイスランド語 - ヨーロッパ) 1200 utf-16 Unicode 1201 utf-16BE Unicode (Big-Endian) 1250 windows-1250 中央ヨーロッパ言語 (Windows) 1251 windows-1251 キリル言語 (Windows) 1252 Windows-1252 西ヨーロッパ言語 (Windows) 1253 windows-1253 ギリシャ語 (Windows) 1254 windows-1254 トルコ語 (Windows) 1255 windows-1255 ヘブライ語 (Windows) 1256 windows-1256 アラビア語 (Windows) 1257 windows-1257 バルト言語 (Windows) 1258 windows-1258 ベトナム語 (Windows) 1361 Johab 韓国語 (Johab) 10000 macintosh 西ヨーロッパ言語 (Mac) 10001 x-mac-japanese 日本語 (Mac) 10002 x-mac-chinesetrad 繁体字中国語 (Mac) 10003 x-mac-korean 韓国語 (Mac) 10004 x-mac-arabic アラビア語 (Mac) 10005 x-mac-hebrew ヘブライ語 (Mac) 10006 x-mac-greek ギリシャ語 (Mac) 10007 x-mac-cyrillic キリル言語 (Mac) 10008 x-mac-chinesesimp 簡体字中国語 (Mac) 10010 x-mac-romanian ルーマニア語 (Mac) 10017 x-mac-ukrainian ウクライナ語 (Mac) 10021 x-mac-thai タイ語 (Mac) 10029 x-mac-ce 中央ヨーロッパ言語 (Mac) 10079 x-mac-icelandic アイスランド語 (Mac) 10081 x-mac-turkish トルコ語 (Mac) 10082 x-mac-croatian クロアチア語 (Mac) 12000 utf-32 Unicode (UTF-32) 12001 utf-32BE Unicode (UTF-32 ビッグ エンディアン) 20000 x-Chinese-CNS 繁体字中国語 (CNS) 20001 x-cp20001 TCA 台湾 20002 x-Chinese-Eten 繁体字中国語 (Eten) 20003 x-cp20003 IBM5550 台湾 20004 x-cp20004 TeleText 台湾 20005 x-cp20005 Wang 台湾 20105 x-IA5 西ヨーロッパ言語 (IA5) 20106 x-IA5-German ドイツ語 (IA5) 20107 x-IA5-Swedish スウェーデン語 (IA5) 20108 x-IA5-Norwegian ノルウェー語 (IA5) 20127 us-ascii US-ASCII 20261 x-cp20261 T.61 20269 x-cp20269 ISO-6937 20273 IBM273 IBM EBCDIC (ドイツ) 20277 IBM277 IBM EBCDIC (デンマーク - ノルウェー) 20278 IBM278 IBM EBCDIC (フィンランド - スウェーデン) 20280 IBM280 IBM EBCDIC (イタリア) 20284 IBM284 IBM EBCDIC (スペイン) 20285 IBM285 IBM EBCDIC (UK) 20290 IBM290 IBM EBCDIC (日本語カタカナ) 20297 IBM297 IBM EBCDIC (フランス) 20420 IBM420 IBM EBCDIC (アラビア語) 20423 IBM423 IBM EBCDIC (ギリシャ語) 20424 IBM424 IBM EBCDIC (ヘブライ語) 20833 x-EBCDIC-KoreanExtended IBM EBCDIC (韓国語 Extended) 20838 IBM-Thai IBM EBCDIC (タイ語) 20866 koi8-r キリル言語 (KOI8-R) 20871 IBM871 IBM EBCDIC (アイスランド語) 20880 IBM880 IBM EBCDIC (キリル言語 - ロシア語) 20905 IBM905 IBM EBCDIC (トルコ語) 20924 IBM00924 IBM ラテン-1 20932 EUC-JP 日本語 (JIS 0208-1990 および 0212-1990) 20936 x-cp20936 簡体字中国語 (GB2312-80) 20949 x-cp20949 韓国語 Wansung 21025 cp1025 IBM EBCDIC (キリル言語 セルビア - ブルガリア) 21866 koi8-u キリル言語 (KOI8-U) 28591 iso-8859-1 西ヨーロッパ言語 (ISO) 28592 iso-8859-2 中央ヨーロッパ言語 (ISO) 28593 iso-8859-3 ラテン 3 (ISO) 28594 iso-8859-4 バルト言語 (ISO) 28595 iso-8859-5 キリル言語 (ISO) 28596 iso-8859-6 アラビア語 (ISO) 28597 iso-8859-7 ギリシャ語 (ISO) 28598 iso-8859-8 ヘブライ語 (ISO-Visual) 28599 iso-8859-9 トルコ語 (ISO) 28603 iso-8859-13 エストニア語 (ISO) 28605 iso-8859-15 ラテン 9 (ISO) 29001 x-Europa ヨーロッパ 38598 iso-8859-8-i ヘブライ語 (ISO-Logical) 50220 iso-2022-jp 日本語 (JIS) 50221 csISO2022JP 日本語 (JIS 1 バイト カタカナ可) 50222 iso-2022-jp 日本語 (JIS 1 バイト カタカナ可 - SO/SI) 50225 iso-2022-kr 韓国語 (ISO) 50227 x-cp50227 簡体字中国語 (ISO-2022) 51932 euc-jp 日本語 (EUC) 51936 EUC-CN 簡体字中国語 (EUC) 51949 euc-kr 韓国語 (EUC) 52936 hz-gb-2312 簡体字中国語 (HZ) 54936 GB18030 簡体字中国語 (GB18030) 57002 x-iscii-de ISCII デバナガリ文字 57003 x-iscii-be ISCII ベンガル語 57004 x-iscii-ta ISCII タミール語 57005 x-iscii-te ISCII テルグ語 57006 x-iscii-as ISCII アッサム語 57007 x-iscii-or ISCII オリヤー語 57008 x-iscii-ka ISCII カナラ語 57009 x-iscii-ma ISCII マラヤラム語 57010 x-iscii-gu ISCII グジャラート語 57011 x-iscii-pa ISCII パンジャブ語 65000 utf-7 Unicode (UTF-7) 65001 utf-8 Unicode (UTF-8)</pre> <p>もし実行結果が文字化けしてしまって困っている時には、上記オプションを試してみてください。</p> <p>Happy Automation!</p> hiyokotaisa Red Hat SSO改めRed Hat build of Keycloakの変更点やマイグレーション情報について hatenablog://entry/6801883189067507067 2023-12-18T12:53:16+09:00 2023-12-19T09:58:16+09:00 ※この記事は Red Hat Advent Calendar 2023 の 18日目の記事です。 qiita.com Red Hatのソリューションアーキテクトの井上たかひろです。 Red Hat SSO(Single sing-on)改めRed Hat build of Keycloakが2023年11月にGAになりました。 この記事では、Red Hat SSOからRed Hat build of Keycloakでの主な変更点とマイグレーション情報について記載します。 Red Hat SSOからRed Hat build of Keycloakでの主な変更点 Keycloakがメジャーにな… <p>※この記事は <a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar 2023</a> の 18日目の記事です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fadvent-calendar%2F2023%2Fopenshift" title="OpenShiftのカレンダー | Advent Calendar 2023 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/advent-calendar/2023/openshift">qiita.com</a></cite></p> <p>Red Hatのソリューションアーキテクトの井上たかひろです。</p> <p>Red Hat SSO(Single sing-on)改めRed Hat build of Keycloakが2023年11月にGAになりました。<br/> この記事では、Red Hat SSOからRed Hat build of Keycloakでの主な変更点とマイグレーション情報について記載します。</p> <h2 id="Red-Hat-SSOからRed-Hat-build-of-Keycloakでの主な変更点">Red Hat SSOからRed Hat build of Keycloakでの主な変更点</h2> <p>Keycloakがメジャーになりすぎたためや、Red Hat SSOの製品名称がバクっとしてて何かわかりづらかったなどの理由がありやなしやで、 製品名称がRed Hat build of Keycloakになりました。</p> <p>Keycloakは、2023年4月にCNCFでIncubating Projectで採択されてもっと利用が増えそうな点なども考慮すると、アップストリームのプロジェクト名と製品名が同じなのは、わかりやすくて良いかなと個人的には思っています。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.cncf.io%2Fprojects%2Fkeycloak%2F" title="Keycloak" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.cncf.io/projects/keycloak/">www.cncf.io</a></cite></p> <p>そして、Red Hat SSOからRed Hat build of Keycloakの主な変更点は以下となります。</p> <table> <thead> <tr> <th style="text-align:left;">項目</th> <th style="text-align:left;">Red Hat SSO</th> <th style="text-align:left;">Red Hat build of Keycloak</th> </tr> </thead> <tbody> <tr> <td style="text-align:left;">ソフトウェア構成</td> <td style="text-align:left;">ランタイムにJBoss EAPを採用</td> <td style="text-align:left;">ランタイムにQuarkusを採用</td> </tr> <tr> <td style="text-align:left;">バージョンアップ間隔</td> <td style="text-align:left;">v7.xでは、v7.1からv7.2等<br>マイナーバージョンアップは約年1回</td> <td style="text-align:left;">Keycloakと同じバージョン管理<br>22→24などで、バージョンアップは年2回を想定</td> </tr> <tr> <td style="text-align:left;">サブスクリプション</td> <td style="text-align:left;">JBoss EAP(JBCS)に含まれる<br>Red Hat Runtimesに含まれる<br>OpenShiftに含まれる</td> <td style="text-align:left;">Red Hat Runtimesに含まれる<br>OpenShiftに含まれる</td> </tr> </tbody> </table> <p>サポート構成やソフトウェア構成に関する情報は以下をご確認ください。</p> <p><a href="https://access.redhat.com/articles/7033107">Red Hat build of Keycloak Supported Configurations</a></p> <p><a href="https://access.redhat.com/articles/7027683">Red Hat build of Keycloak Component Details</a></p> <p>サブスクリプションに関する情報は以下をご確認ください。</p> <p><a href="https://access.redhat.com/articles/7044244">Subscriptions or Entitlements Requirements for Red Hat build of Keycloak</a></p> <p>サブスクリプションに関しては、JBoss EAPに含まれなくなっている点はご注意ください。</p> <h2 id="Red-Hat-build-of-Keycloak-22の新機能や機能強化">Red Hat build of Keycloak 22の新機能や機能強化</h2> <p>ランタイムがQuarkusになったことで、起動時間の短縮、処理性能向上、メモリリソース効率、コンテナ化がより容易になったなどのメリットも得られています。</p> <p>OpenShift Operatorについては、作り直しされており、Operator成熟モデルがPhase4のDeep Insightになっています。 <figure class="figure-image figure-image-fotolife" title="keycloak_operator"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/t/tinoue0219/20231217/20231217151736.png" width="1200" height="845" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></figure></p> <p>詳細は、Red Hat build of Keycloak 22のリリースノートをご確認ください。</p> <p><a href="https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/release_notes/red_hat_build_of_keycloak_22_0#new_operator">Chapter 1. Red Hat build of Keycloak 22.0 Red Hat build of Keycloak 22.0 | Red Hat Customer Portal</a></p> <h2 id="Red-Hat-SSOからRed-Hat-build-of-Keycloakへのマイグレーション">Red Hat SSOからRed Hat build of Keycloakへのマイグレーション</h2> <p>ランタイムが、JBoss EAPからQuarkusに変わったため、起動方法や定義部分で大きな変更があり、この対応のためマイグレーションガイドをRed Hat build of Keycloakのマニュアルで整備されています。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fen-us%2Fred_hat_build_of_keycloak%2F22.0%2Fhtml%2Fmigration_guide%2Findex" title="Migration Guide Red Hat build of Keycloak 22.0 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/migration_guide/index">access.redhat.com</a></cite></p> <p>マイグレーションガイドは、Red Hat Single Sing-on 7.6からのVMでのデプロイメント、OpenShift Operatorでのデプロイメントなどのデプロイメント別のマイグレーションや、カスタムプロバイダーやカスタムテーマの以降についても記載があります。 また、カスタムプロバイダーについては、Quarkus3.x系をベースにしているため、Java EE から Jakarta EE(Jakarta EE 10) への移行が必要となります。</p> <h2 id="最後に">最後に</h2> <p>簡単ではありますが、Red Hat SSOからのRed Hat build of Keycloakの変更点やマイグレーション情報について、ご紹介しました。 ランタイムがQuarkus変わる大きな変更ですが、Quarkusは環境変数で構成情報(管理者情報、DB接続情報など)を渡せるので、検証したりするのがより簡単になったなぁと思います。<a href="https://github.com/keycloak/keycloak/issues/22455">QuarkusのDev UI利用</a>などはこれからの検討なのですが、その機能が使えるようになると、内部の動きもわかりやすくなるなと感じています。</p> tinoue0219 Persistent Volume の Space Reclamation について草々 hatenablog://entry/6801883189066477884 2023-12-16T00:00:00+09:00 2023-12-16T00:00:51+09:00 ※この記事は Red Hat Advent Calendar 2023 の 16日目の記事です。 qiita.com こんにちは。レッドハットでクラウドインフラを生業にしている宇都宮(うつぼ)です。 早速ですがストレージに関する問題です。 問題 アリスはオンプレミスで展開された OpenShift(または Kubernetes)クラスタの管理者です。 クラスタには1つ 10TiB ものデカすぎる PV があります。この PV のバックエンドはブロックストレージで、Thin-provisioned な論理ボリュームを使っています。 ストレージの管理者であるボブからは「もうストレージの容量がなくな… <p>※この記事は <a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar 2023</a> の 16日目の記事です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fqiita.com%2Fadvent-calendar%2F2023%2Fopenshift" title="OpenShiftのカレンダー | Advent Calendar 2023 - Qiita" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://qiita.com/advent-calendar/2023/openshift">qiita.com</a></cite></p> <p>こんにちは。レッドハットでクラウドインフラを生業にしている宇都宮(うつぼ)です。<br/> 早速ですがストレージに関する問題です。</p> <h2 id="問題">問題</h2> <blockquote><p>アリスはオンプレミスで展開された OpenShift(または Kubernetes)クラスタの管理者です。<br/> クラスタには1つ 10TiB ものデカすぎる PV があります。この PV のバックエンドはブロックストレージで、Thin-provisioned な論理ボリュームを使っています。 ストレージの管理者であるボブからは「もうストレージの容量がなくなりそうだから、この PV から容量を返してくれ」と言われています。<br/> クラスタ管理者のアリスは、このデカすぎる PV を使うキャロルにこの話をして、PV 内に溜め込んだ不要なファイルを消してもらうことになりました。<br/> キャロルからは、「仰せの通りファイルを消した、3分の1 くらいになった」と報告を受けました。<br/> アリスはこれで一件落着と枕を高くして寝ました。しかし翌日ボブからは「もう本当にまずい!早く容量を返してくれ!」と言われ、困惑しています。<br/> さて、なぜでしょうか。なお、ボブもキャロルも嘘はついていないものとします。</p></blockquote> <h2 id="解答">解答</h2> <p>簡単ですね。正解は、<strong>ファイルを消してもファイルシステムは勝手に縮まないし、ファイルシステムが縮まなければボリュームサイズも減らないから</strong> です。</p> <p>これは別に Kubernetes とかに限った話ではありません。一般的な Linux サーバでも同じ現象は起こります。<br/> そもそも上の問題で一番ダメなのは 10TiB の PVC を許しているところで、OpenShift かストレージ側で Quota をかけて制限すべきです。<br/> ですが、ブロックストレージだとファイルシステムでファイルを消したら自動で空いた容量がストレージに帰っていくなんてことは無いので、アリスもぐっすり寝てる場合ではありません。</p> <h2 id="Space-Reclamation-と-PV">Space Reclamation と PV</h2> <p>一度使ったけど空いた容量をストレージ側に返すことを、Space Reclamation と言います。<br/> シックプロビジョニングではまず出てきませんが、シンプロビジョニングではおなじみの概念です。 シンプロビジョニングは「自分が必要な容量だけ使うべき」なポリシーですので、「必要なくなって取りすぎた容量は返すべき」だからです。</p> <p>通常の Linux で Space Reclamation するには、<code>fstrim</code> コマンドを実行してファイルシステムの使っていない領域を開放します。その後はストレージ側でそれを回収します。<br/> それでは Kubernetes PV の場合は?わざわざ Pod や Worker ノードに入って <code>fstrim</code> を実行する?そんな運用ありえないですよね。</p> <p>PV の場合は、CSI (Container Storage Interface) Add-on を使って Reclaim することができます。<br/> <code>ReclaimSpaceJob</code> というカスタムリソースを使います。Reclaim はそんなに常時やるものではないので、単発で Job 的に使います。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fcsi-addons%2Fkubernetes-csi-addons%2Fblob%2Fmain%2Fdocs%2Freclaimspace.md" title="kubernetes-csi-addons/docs/reclaimspace.md at main · csi-addons/kubernetes-csi-addons" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/csi-addons/kubernetes-csi-addons/blob/main/docs/reclaimspace.md">github.com</a></cite></p> <h2 id="ODF-で-PV-の-Space-Reclamation-を試してみる">ODF で PV の Space Reclamation を試してみる</h2> <p>Red Hat OpenShift Data Foundation(ODF)はこれに対応しているので、実際やってみましょう。<br/> ODF がインストールされたクラスタで適当なアプリを作って 50GiB PVC をアタッチします。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/u/ututaq/20231214/20231214173130.png" width="847" height="752" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>Pod からは <code>/dev/rbd0</code> として見えます。この時点ではほとんど空っぽ。</p> <pre class="code" data-lang="" data-unlink>sh-4.4$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop1 7:1 0 512G 0 loop rbd0 252:0 0 50G 0 disk /mnt nvme0n1 259:0 0 100G 0 disk |-nvme0n1p1 259:1 0 1M 0 part |-nvme0n1p2 259:2 0 127M 0 part |-nvme0n1p3 259:3 0 384M 0 part `-nvme0n1p4 259:4 0 99.5G 0 part /dev/termination-log sh-4.4$ df -h /mnt Filesystem Size Used Avail Use% Mounted on /dev/rbd0 49G 24K 49G 1% /mnt</pre> <p>ODF のダッシュボードで見ても、ほとんど使われていない初期状態です。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/u/ututaq/20231214/20231214173138.png" width="754" height="265" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>ここで 10GiB のダミーファイルを書き込みます。10GiB 増えています。(当たり前)</p> <pre class="code" data-lang="" data-unlink>sh-4.4$ dd if=/dev/random of=/mnt/10G.dat bs=1M count=10240 10240+0 records in 10240+0 records out 10737418240 bytes (11 GB, 10 GiB) copied, 81.0443 s, 132 MB/s sh-4.4$ sh-4.4$ df -h /mnt Filesystem Size Used Avail Use% Mounted on /dev/rbd0 49G 11G 39G 21% /mnt</pre> <p>ODF では三重でレプリケーションされるので、ダッシュボードで見ると 3倍の 30GiB ほどが増えていることがわかります。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/u/ututaq/20231214/20231214174041.png" width="780" height="246" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>それでは Pod でファイルを削除します。10GiB 減ります。</p> <pre class="code" data-lang="" data-unlink>sh-4.4$ rm -f /mnt/10G.dat sh-4.4$ sh-4.4$ df -h /mnt Filesystem Size Used Avail Use% Mounted on /dev/rbd0 49G 24K 49G 1% /mnt</pre> <p>ODF では、全然減ってません。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/u/ututaq/20231214/20231214174354.png" width="786" height="245" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>さてここで <code>ReclaimSpaceJob</code> を作って Reclaim してみましょう。</p> <pre class="code" data-lang="" data-unlink>apiVersion: csiaddons.openshift.io/v1alpha1 kind: ReclaimSpaceJob metadata: name: reclaim-odf-pvc namespace: test spec: target: persistentVolumeClaim: odf-pvc</pre> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/u/ututaq/20231214/20231214174731.png" width="672" height="351" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>これを実行すると、次のようになります。 <figure class="figure-image figure-image-fotolife" title="減っている!"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/u/ututaq/20231214/20231214174822.png" width="776" height="243" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>減っている!</figcaption></figure></p> <p>ODF の中で動く Ceph のブロックデバイス(RBD)は、シンプロビジョニングで作られます。<br/> この <code>ReclaimSpaceJob</code> によって、アプリ Pod と同じノードで動く CSI driver が <code>fstrim</code> を実行します。Ceph RBD は sparse なイメージファイルなので、ゼロ領域は自動的に Ceph のプールに返されます。 <figure class="figure-image figure-image-fotolife" title="CSIドライバのログより"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/u/ututaq/20231214/20231214184912.png" width="1002" height="585" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>CSIドライバのログより</figcaption></figure></p> <h2 id="Space-Reclamation-はスケジュールするともっと楽">Space Reclamation はスケジュールするともっと楽</h2> <p>ad hoc に Reclaim するなら <code>ReclaimSpaceJob</code> を作りますが、定期的に実行するようスケジュールしておくとよいです。<br/> <code>ReclaimSpaceCronJob</code> というカスタムリソースでスケジュールを設定できるのですが、対象の PVC に annotation を追加することで代用できます。</p> <pre class="code" data-lang="" data-unlink># oc annotate pvc odf-pvc &#34;reclaimspace.csiaddons.openshift.io/schedule=@weekly&#34; -n test persistentvolumeclaim/odf-pvc annotated</pre> <p>上の <code>@weekly</code> の部分は Cron と同じ書き方でもOKです。毎週金曜日の深夜0時に実行するなら、<code>0 0 * * 5</code> みたいな感じですね。<br/> これでアリスもボブも枕を高くしてぐっすり眠れることでしょう。</p> <h2 id="まとめ">まとめ</h2> <p>クラウド環境で Space Reclamation しないとマズい、ということはほとんど無いと思いますが、冒頭の問題のようにオンプレミス環境だったら意外とあるかもしれません。<br/> ストレージはあって当然使えて当然、とお思いの方もいるかもしれませんが、いやいや結構中の人は色々と工夫と苦労をしているんですね。<br/> 今回は ODF で確認しましたが、他のストレージの CSI はどうなのでしょう。すみません私もわかりません。色々と試してみるとよいのではないかなと思います。</p> <p>というわけで、今回はここまで。</p> ututaq Amazon Linux 2023でPodmanを動かす hatenablog://entry/6801883189066732781 2023-12-15T00:00:00+09:00 2023-12-15T00:13:15+09:00 Red Hatの織です。本記事はAWS Containers Advent Calendar 2023の12/15のエントリーです。 内容としてはAmazon Linux 2023でPodmanを動かしてみました、という話です(AWSのコンテナ関連サービスを使ってなくて申し訳ありません...)。一言でまとめると、現状いろいろパッケージが足りないため、頑張ってコンパイルしていくhard wayな感じです。男らしくmainブランチのHEADをごりごりとビルドしていきます。 いろいろコンパイル rpmがあるものについてはそれを活用します。 sudo dnf install -y git golang… <p>Red Hatの織です。本記事はAWS Containers Advent Calendar 2023の12/15のエントリーです。</p> <p>内容としてはAmazon Linux 2023でPodmanを動かしてみました、という話です(AWSのコンテナ関連サービスを使ってなくて申し訳ありません...)。一言でまとめると、現状いろいろパッケージが足りないため、頑張ってコンパイルしていくhard wayな感じです。男らしくmainブランチのHEADをごりごりとビルドしていきます。</p> <h1 id="いろいろコンパイル">いろいろコンパイル</h1> <p>rpmがあるものについてはそれを活用します。</p> <pre class="code" data-lang="" data-unlink>sudo dnf install -y git golang runc cni-plugins gpgme-devel</pre> <p>作業ディレクトリを作成しておきます。</p> <pre class="code" data-lang="" data-unlink>mkdir work cd work</pre> <p>最低限必要なソースコードをgit cloneします。</p> <pre class="code" data-lang="" data-unlink>git clone https://github.com/containers/podman.git git clone https://github.com/containers/conmon.git git clone https://gitlab.freedesktop.org/slirp/libslirp.git git clone https://github.com/rootless-containers/slirp4netns.git</pre> <h2 id="conmon">conmon</h2> <p>Podman(およびCRI-O)のコンテナモニター (コンテナプロセスのsubreaperとして動きます、containerdにおけるshim+αに相当します) であるconmonをコンパイルします。</p> <pre class="code" data-lang="" data-unlink>cd conmon sudo dnf install -y \ gcc \ git \ glib2-devel \ glibc-devel \ libseccomp-devel \ make \ pkgconfig \ runc make sudo make install cd ..</pre> <h2 id="slirp4netns">slirp4netns</h2> <p>rootless実行するときのユーザーランドネットワーキングで使用するslirp4netnsをコンパイルします...が、その前提となるlibslirpをまず作ります。</p> <pre class="code" data-lang="" data-unlink>cd libslirp sudo dnf install -y meson ninja-build meson build ninja -C build sudo ninja -C build install cd ..</pre> <p>次にslirp4netnsをビルドします。</p> <pre class="code" data-lang="" data-unlink>cd slirp4netns sudo dnf -y install autoconf automake libcap-devel ./autogen.sh LDFLAGS=&#39;-Wl,-R/usr/local/lib64&#39; ./configure make sudo make install cd ..</pre> <h2 id="podman">podman</h2> <p>本題のpodmanをビルドします。</p> <pre class="code" data-lang="" data-unlink>cd podman make sudo make install cd ..</pre> <p>最低限の設定ファイルを作っておきます。</p> <pre class="code" data-lang="" data-unlink>sudo mkdir /etc/containers cat &lt;&lt;END | sudo tee /etc/containers/policy.json { &#34;default&#34;: [ { &#34;type&#34;: &#34;insecureAcceptAnything&#34; } ] } END</pre> <h1 id="動作確認">動作確認</h1> <p>まずはHello Podman Worldしてみましょう。</p> <pre class="code" data-lang="" data-unlink>[ec2-user@ip-10-0-1-189 ~]$ podman run quay.io/podman/hello Trying to pull quay.io/podman/hello:latest... Getting image source signatures Copying blob d08b40be6878 done | Copying config e2b3db5d4f done | Writing manifest to image destination !... Hello Podman World ...! .--&#34;--. / - - \ / (O) (O) \ ~~~| -=(,Y,)=- | .---. /` \ |~~ ~/ o o \~~~~.----. ~~ | =(X)= |~ / (O (O) \ ~~~~~~~ ~| =(Y_)=- | ~~~~ ~~~| U |~~ Project: https://github.com/containers/podman Website: https://podman.io Documents: https://docs.podman.io Twitter: @Podman_io</pre> <p>いい感じですね。次はNginxを起動します。</p> <pre class="code" data-lang="" data-unlink>[ec2-user@ip-10-0-1-189 ~]$ podman run -d -p 8080:80 docker.io/library/nginx Trying to pull docker.io/library/nginx:latest... Getting image source signatures Copying blob 84b1ff10387b done | Copying blob 1f7ce2fa46ab done | Copying blob 9ea27b074f71 done | Copying blob 9b16c94bb686 done | Copying blob c6edf33e2524 done | Copying blob 9a59d19f9c5b done | Copying blob 517357831967 done | Copying config a6bd71f48f done | Writing manifest to image destination 3c1cb97dd6d3525383db7202c455817e3a635ae21e5205aa6fdfad1e528fd8ea</pre> <p>さらにNginx Podにアクセスしてみます。</p> <pre class="code" data-lang="" data-unlink>[ec2-user@ip-10-0-1-189 ~]$ curl -q -s -o /dev/null -w &#39;%{http_code}\n&#39; http://localhost:8080 200</pre> <p>rootlessコンテナへのネットワークアクセスも問題なさそうです。</p> <h1 id="おまけ">おまけ</h1> <p>最近のPodmanは、OCIランタイムとしてcrunを、ネットワークプラグインとしてnetavarkを使うことが多いです。これらもビルドして使ってみます。</p> <h2 id="crun">crun</h2> <pre class="code" data-lang="" data-unlink>git clone https://github.com/containers/crun.git cd crun sudo dnf install -y make python git gcc automake autoconf libcap-devel systemd-devel yajl-devel libseccomp-devel pkg-config libgcrypt-devel go-md2man glibc-static python3-libmount libtool golang-github-cpuguy83-md2man ./autogen.sh ./configure make -j sudo make install cd ..</pre> <h2 id="netavark">netavark</h2> <pre class="code" data-lang="" data-unlink>git clone https://github.com/containers/netavark.git cd netavark curl --proto &#39;=https&#39; --tlsv1.2 -sSf https://sh.rustup.rs | sh source &#34;$HOME/.cargo/env&#34; sudo dnf install protobuf-devel protobuf-c-devel make sudo make install cd ..</pre> <h2 id="aardvark">aardvark</h2> <pre class="code" data-lang="" data-unlink>git clone https://github.com/containers/aardvark-dns.git cd aardvark-dns make sudo make install cd ..</pre> <h1 id="動作確認-1">動作確認</h1> <p>まず、以前の設定(CNIプラグインで実行していたコンテナ等)をクリアしておきます。</p> <pre class="code" data-lang="" data-unlink>podman system reset</pre> <p>今のバージョンだと、crunとnetavarkがあればデフォルトでそちらを使うようになっていますので、これで準備は完了です。 念のため以下のコマンドで確認しておきます。</p> <pre class="code" data-lang="" data-unlink>$ podman info -f json | jq -r &#39;.host.ociRuntime.path, .host.networkBackendInfo.path&#39; /usr/local/bin/crun /usr/local/libexec/podman/netavark</pre> <p>あとは上でやったのと同じようにPodを起動してみましょう (結果は省略)。</p> <h1 id="最後に">最後に</h1> <p>Amazon Linux 2023でPodmanを動かしてみました。いろんな部品をコンパイルしないといけないのでちょっと面倒ですね...</p> orimanabu Windowsクライアント向けJavaアプリケーションをActive Directoryで配布する hatenablog://entry/6801883189066651340 2023-12-14T12:33:11+09:00 2023-12-19T10:57:45+09:00 Red Hat のソリューションアーキテクトの瀬戸です。 概要 以前jpackageを使ったクライアントアプリケーションのパッケージングの方法についてまとめました。 rheb.hatenablog.com その時にmsi形式でパッケージングをしましたが、このmsiという拡張子のついたファイルは何なのでしょうか? msiはWindows上で実行できるファイルの中で、ソフトウェアのインストールに使えるファイルにつけられる拡張子です。Microsoft Windows Installerの略となっています。 特別な拡張子が割り当てられているだけではなく、中に含まれるファイルの実行時のオプションや内容… <p>Red Hat のソリューションアーキテクトの瀬戸です。</p> <h3 id="概要">概要</h3> <p>以前jpackageを使ったクライアントアプリケーションのパッケージングの方法についてまとめました。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2023%2F10%2F25%2F110538" title="jpackageを使ってJavaアプリケーションの配布用パッケージを作成する - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2023/10/25/110538">rheb.hatenablog.com</a></cite></p> <p>その時にmsi形式でパッケージングをしましたが、このmsiという拡張子のついたファイルは何なのでしょうか? msiはWindows上で実行できるファイルの中で、ソフトウェアのインストールに使えるファイルにつけられる拡張子です。Microsoft Windows Installerの略となっています。 特別な拡張子が割り当てられているだけではなく、中に含まれるファイルの実行時のオプションや内容が仕様で決められており、Windows ServerのActive Directoryを使用することでクライアントサイドのWindowsに自動的にソフトウェアをインストールすることに使う事ができます。</p> <p>なぜmsi形式のファイルが作れると嬉しいかというと、この形式であればWindowsのアプリケーション管理機能に乗せて一元管理ができるからですね。 クライアントPCが数千台あったとしても1台ずつインストールをしていく必要はなくなります。</p> <p>普段から企業内でIT管理者をやっておりActive Directoryを触っている人からは常識なのですが、一般的な開発者はなかなかActive Directoryに触れる機会がないので、機能の紹介を兼ねて設定方法を説明していきます。</p> <h3 id="環境の説明">環境の説明</h3> <p>今回はWindows Server 2022を使って試していきます。</p> <h4 id="サーバークライアントの準備">サーバー、クライアントの準備</h4> <p>AWS上のWindows Server 2022 Data Center Editionと、オンプレのWindows 11 Professional Editionを利用しました。<a href="#f-f470db7b" id="fn-f470db7b" name="fn-f470db7b" title="つまり、そこらへんに転がってた自宅のPC">*1</a>Home EditionではActive Directory(ドメイン)に参加できないのでご注意ください。 また、Active Directoryについては設定済みとし、クライアントPCはすでにActive Directory(ドメイン)に参加しているものとしています。<a href="#f-b852ab85" id="fn-b852ab85" name="fn-b852ab85" title="つまり、一般的な企業でPCが管理されている状態">*2</a></p> <h4 id="使用するアプリケーションmsiファイルの準備">使用するアプリケーション(msiファイル)の準備</h4> <p>jpackageを使用して準備しました。オプションは次の通りです。</p> <pre class="code" data-lang="" data-unlink>&gt; jpackage --type msi --icon shadowman.ico --vendor &#34;red hat&#34; --app-version 1.0 --win-menu --win-shortcut --input .\target --win-upgrade-uuid 2bc2b28e-5b34-45e3-9e4f-11e87d88f7cb --name clientexample --main-class com.redhat.clientexample.App --main-jar clientexample.jar</pre> <p>自動インストール用を想定しているため、デフォルトでサイレントインストールになるように指定をしています。どういう意味を持つのかの詳細は前回までの記事を参照してください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2023%2F10%2F25%2F110538" title="jpackageを使ってJavaアプリケーションの配布用パッケージを作成する - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2023/10/25/110538">rheb.hatenablog.com</a></cite> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2023%2F11%2F01%2F155002" title="jpackageの踏み入った使い方 - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2023/11/01/155002">rheb.hatenablog.com</a></cite></p> <h3 id="実際に設定をする">実際に設定をする</h3> <p>次のような手順で行っていきます。</p> <ul> <li>共有フォルダにmsiファイルを設置する</li> <li>GPO(グループポリシーオブジェクト)でソフトウェアのインストールの設定を行う</li> <li>GPO(グループポリシーオブジェクト)をドメインに割り当てる</li> </ul> <h4 id="共有フォルダにmsiファイルを設置する">共有フォルダにmsiファイルを設置する</h4> <p>サーバーのフォルダを共有します。このフォルダはクライアント側からアクセスできるように設定されている必要があります。クライアント側からアクセスできれば良いので、NAS等を使って別途構築してある場所でも大丈夫です。</p> <p>今回はEveryone向けに読み取り権限を付けて共有します。</p> <p><figure class="figure-image figure-image-fotolife" title="ファイル共有設定"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214111621.png" width="603" height="909" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ファイル共有設定</figcaption></figure></p> <p><figure class="figure-image figure-image-fotolife" title="アクセス権の設定"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214111647.png" width="883" height="741" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>アクセス権の設定</figcaption></figure></p> <p>ネットワーク越しに参照できることを確認します。</p> <p><figure class="figure-image figure-image-fotolife" title="ネットワーク越しの確認"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214111742.png" width="886" height="275" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ネットワーク越しの確認</figcaption></figure></p> <p>これでインストールするmsiファイルの設置は終わりました。</p> <h4 id="GPOグループポリシーオブジェクトでソフトウェアのインストールの設定を行う">GPO(グループポリシーオブジェクト)でソフトウェアのインストールの設定を行う</h4> <p>ファイル名を指定して実行から mmcを実行することでMMC(Microsoft Management Console)が起動します。</p> <p>MMCのファイルメニューからスナップインの追加と削除を選択することでGPOの管理画面を開くことができます。</p> <p><figure class="figure-image figure-image-fotolife" title="ファイル名を指定して実行"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214111943.png" width="456" height="272" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ファイル名を指定して実行</figcaption></figure></p> <p><figure class="figure-image figure-image-fotolife" title="MMCの初期画面"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112032.png" width="886" height="467" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>MMCの初期画面</figcaption></figure></p> <p>初期画面には何もないので、ファイルのスナップインの追加と削除を選択します。</p> <p><figure class="figure-image figure-image-fotolife" title="GPOのファイルメニュー"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112119.png" width="792" height="642" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>GPOのファイルメニュー</figcaption></figure></p> <p>引き続きグループポリシーの管理を選択して追加します。次のように選択すればOKです。</p> <p><figure class="figure-image figure-image-fotolife" title="スナップインの追加と削除"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112139.png" width="886" height="615" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>スナップインの追加と削除</figcaption></figure></p> <p>ソフトウェアを配布したいドメインの中のグループポリシーオブジェクトのフォルダを選択します。</p> <p><figure class="figure-image figure-image-fotolife" title="GPOの管理画面"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112225.png" width="886" height="467" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>GPOの管理画面</figcaption></figure></p> <p>右クリックから新規を選択します。</p> <p><figure class="figure-image figure-image-fotolife" title="GPOの新規作成"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112334.png" width="659" height="548" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>GPOの新規作成</figcaption></figure></p> <p>新しいGPOの名前を指定します。今回はソフトウェア配布と付けています。</p> <p><figure class="figure-image figure-image-fotolife" title="新しいGPOに名前を付ける"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112359.png" width="878" height="417" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>新しいGPOに名前を付ける</figcaption></figure></p> <p>作成されました。</p> <p><figure class="figure-image figure-image-fotolife" title="GPOの作成"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112423.png" width="886" height="467" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>GPOの作成</figcaption></figure></p> <p>作成したGPOを右クリックメニューから編集します。</p> <p><figure class="figure-image figure-image-fotolife" title="ソフトウェア配布の編集"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112454.png" width="526" height="471" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ソフトウェア配布の編集</figcaption></figure></p> <p>グループポリシー管理エディタが開くので、コンピューターの構成→ポリシー→ソフトウェアの設定→ソフトウェアインストールを選択します。</p> <p><figure class="figure-image figure-image-fotolife" title="グループポリシー管理エディタ"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112547.png" width="886" height="636" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>グループポリシー管理エディタ</figcaption></figure></p> <p>右クリックからNew->Packageを指定してください。</p> <p><figure class="figure-image figure-image-fotolife" title="ソフトウェアインストールの選択"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112630.png" width="788" height="716" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ソフトウェアインストールの選択</figcaption></figure></p> <p>ファイルのダイアログが開くのでそのまま指定したいところですが、ローカルディスクのファイルを指定するとエラーメッセージが表示されます。クライアントから表示できるネットワークドライブ上のファイルのUNC<a href="#f-230e3c30" id="fn-230e3c30" name="fn-230e3c30" title="\\からはじまるやつ">*3</a>を指定する必要があります。ファイルダイアログからネットワークファイルを探して指定することでもUNCと解釈されます。</p> <p><figure class="figure-image figure-image-fotolife" title="ローカルファイルの指定"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112758.png" width="886" height="499" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ローカルファイルの指定</figcaption></figure></p> <p><figure class="figure-image figure-image-fotolife" title="ローカルファイルを指定したときのエラー"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112813.png" width="639" height="248" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ローカルファイルを指定したときのエラー</figcaption></figure></p> <p><figure class="figure-image figure-image-fotolife" title="ネットワークフォルダの指定時のパス"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214112913.png" width="886" height="115" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>ネットワークフォルダの指定時のパス</figcaption></figure></p> <p>引き続き、デプロイ方法を指定します。</p> <p>デプロイ方法は詳細設定を指定します。ここで割り当てを選んでしまった場合はクライアントの状況によってインストールできないことがあります。</p> <p><figure class="figure-image figure-image-fotolife" title="デプロイ方法の指定"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113006.png" width="778" height="563" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>デプロイ方法の指定</figcaption></figure></p> <p>詳細設定を選択してOKを押すと追加の設定画面が表示されます。割り当てを指定したあとにプロパティを開いても同じ画面を表示することができます。 こちらから、展開の詳細設定⇒詳細設定オプションのこのパッケージを展開するときは言語を無視するをチェックします。jpackageでは現時点では言語の指定が出来ないため、日本語Windowsにインストールしたい場合はこちらを有効にする必要があります。</p> <p><figure class="figure-image figure-image-fotolife" title="詳細設定画面"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113052.png" width="886" height="1044" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>詳細設定画面</figcaption></figure><figure class="figure-image figure-image-fotolife" title="詳細設定オプション"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113108.png" width="886" height="942" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>詳細設定オプション</figcaption></figure></p> <p>これでインストールするパッケージの指定が完了です。</p> <p><figure class="figure-image figure-image-fotolife" title="完了後画面"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113203.png" width="886" height="636" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>完了後画面</figcaption></figure></p> <p>今回は追加で、セキュリティーフィルターの処理で、インストールしたいPCを直接選択しています。実運用環境では対象となるPCのグループを指定することになるのではないかと思います。</p> <p><figure class="figure-image figure-image-fotolife" title="インストールしたいPCの指定"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113228.png" width="886" height="429" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>インストールしたいPCの指定</figcaption></figure></p> <h3 id="GPOグループポリシーオブジェクトをドメインに割り当てる">GPO(グループポリシーオブジェクト)をドメインに割り当てる</h3> <p>ここまで出来たら、最後にインストール処理を行いたいドメインに対してGPOのリンクを行います。 ドメインを選択して、既存のGPOのリンクから作成したGPOを選択します。</p> <p><figure class="figure-image figure-image-fotolife" title="GPOのリンク"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113439.png" width="736" height="401" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>GPOのリンク</figcaption></figure></p> <p>これでクライアントへの配布が行われるようになります。 ただし、GPOはクライアントに即座に反映されるわけではなく、組織の設定により遅延して反映されます。十分な時間を置いた後にクライアントPCを再起動するとソフトウェアが配布されているはずです。<a href="#f-0d9cdbcd" id="fn-0d9cdbcd" name="fn-0d9cdbcd" title="テスト目的などで強制的にGPOを適用したい場合はgpupdateというコマンドがあります。">*4</a></p> <p><figure class="figure-image figure-image-fotolife" title="デスクトップ上にアイコンがでてくる"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113718.png" width="203" height="209" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>デスクトップ上にアイコンがでてくる</figcaption></figure></p> <p><figure class="figure-image figure-image-fotolife" title="当然プログラムの追加と削除にもでてくる"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/megascus/20231214/20231214113737.png" width="886" height="85" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>当然プログラムの追加と削除にもでてくる</figcaption></figure></p> <h3 id="まとめ">まとめ</h3> <p>Active Directoryを使用したWindowsクライアントへのアプリケーションの配布方法の手順を説明してきました。</p> <p>JavaはWindows/Linux/Macのどこでも動くということもあり、Windows固有の情報についてJava開発者は疎くなりがちです。そのため、Windows上でのクライアント開発を行っても配布方法がわからないなどで.net等に後れを取っているのではないかと感じます。</p> <p>実際にはWindows Serverが標準的な配布の仕組みを持っており、msi形式のアプリケーションを配布できるので、特に問題は発生しないです。</p> <p>Windows/Unix/Macで動作するアプリケーションが作れますので、ぜひ使用をご検討ください。</p> <p><a href="https://learn.microsoft.com/ja-jp/windows/win32/msi/windows-installer-portal">Windows &#x30A4;&#x30F3;&#x30B9;&#x30C8;&#x30FC;&#x30E9;&#x30FC; - Win32 apps | Microsoft Learn</a></p> <p><a href="https://learn.microsoft.com/ja-jp/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview">Active Directory Domain Services &#x306E;&#x6982;&#x8981; | Microsoft Learn</a></p> <div class="footnote"> <p class="footnote"><a href="#fn-f470db7b" id="f-f470db7b" name="f-f470db7b" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">つまり、そこらへんに転がってた自宅のPC</span></p> <p class="footnote"><a href="#fn-b852ab85" id="f-b852ab85" name="f-b852ab85" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">つまり、一般的な企業でPCが管理されている状態</span></p> <p class="footnote"><a href="#fn-230e3c30" id="f-230e3c30" name="f-230e3c30" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">\\からはじまるやつ</span></p> <p class="footnote"><a href="#fn-0d9cdbcd" id="f-0d9cdbcd" name="f-0d9cdbcd" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">テスト目的などで強制的にGPOを適用したい場合はgpupdateというコマンドがあります。</span></p> </div> megascus OpenShift Logging の Loki にコマンドでアクセスしてみる hatenablog://entry/6801883189066551056 2023-12-14T08:31:11+09:00 2023-12-14T08:31:11+09:00 はじめに Loki について クエリの種類 Log クエリ Metric クエリ OpenShift Logging としての構築 Operator の導入 Loki のデプロイ Cluster Logging として利用する 簡単なアクセス確認 Web Console からのアクセス CLI からのアクセス アクセス方法の確認 Metric クエリを呼び出してみる LogCLI おわりに はじめに Red Hat Advent Calendar 2023 の 12月14日の記事です。OpenShift Cluster Logging で Loki が利用できるようになってからしばらく時間が経… <ul class="table-of-contents"> <li><a href="#はじめに">はじめに</a></li> <li><a href="#Loki-について">Loki について</a></li> <li><a href="#クエリの種類">クエリの種類</a><ul> <li><a href="#Log-クエリ">Log クエリ</a></li> <li><a href="#Metric-クエリ">Metric クエリ</a></li> </ul> </li> <li><a href="#OpenShift-Logging-としての構築">OpenShift Logging としての構築</a><ul> <li><a href="#Operator-の導入">Operator の導入</a></li> <li><a href="#Loki-のデプロイ">Loki のデプロイ</a></li> <li><a href="#Cluster-Logging-として利用する">Cluster Logging として利用する</a></li> </ul> </li> <li><a href="#簡単なアクセス確認">簡単なアクセス確認</a><ul> <li><a href="#Web-Console-からのアクセス">Web Console からのアクセス</a></li> <li><a href="#CLI-からのアクセス">CLI からのアクセス</a><ul> <li><a href="#アクセス方法の確認">アクセス方法の確認</a></li> <li><a href="#Metric-クエリを呼び出してみる">Metric クエリを呼び出してみる</a></li> <li><a href="#LogCLI">LogCLI</a></li> </ul> </li> </ul> </li> <li><a href="#おわりに">おわりに</a></li> </ul> <h1 id="はじめに">はじめに</h1> <p><a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar 2023</a> の 12月14日の記事です。OpenShift Cluster Logging で Loki が利用できるようになってからしばらく時間が経ち、段々と利用されつつあるのではないかと思います。 本記事では、OpenShift Cluster Logging (Loki) を OpenShift Web Console からではなく、あえて CLI 経由でアクセスしてみます。</p> <h1 id="Loki-について">Loki について</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgrafana.com%2Fdocs%2Floki%2Flatest%2Fget-started%2Foverview%2F" title="Loki overview | Grafana Loki documentation " class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://grafana.com/docs/loki/latest/get-started/overview/">grafana.com</a></cite></p> <p>Loki は Grafana Loki という名称で、Prometheus からインスパイアされたスケーラビリティ、可用性、マルチテナントに対応したログ収集システムです。 他のログシステムと異なり、ログ自身にはインデックスを持たず、メタデータのみをインデックス化して管理します。 ログはメタデータとしてラベルを持つことで管理されます。同じラベルをもつログのセットを Log Stream と呼びます。</p> <p>ログデータは圧縮され、オブジェクトストレージに格納されるためログデータを効率よく保持できる仕組みとなっています。</p> <h1 id="クエリの種類">クエリの種類</h1> <p>Loki の検索は LogQL を利用します。OpenShift の Web Console から呼び出すときに使います。格納されたログから特定のメッセージなどを絞り込んで見る際に利用します。LogQL は 2つの種類があり、それぞれ Log クエリと Metric クエリに別れます。</p> <h2 id="Log-クエリ">Log クエリ</h2> <p>ログデータを返却します。ログメッセージの絞り込みなどで目的のエラー情報などを検索するときに活躍します</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgrafana.com%2Fdocs%2Floki%2Flatest%2Fquery%2Flog_queries%2F" title="Log queries | Grafana Loki documentation " class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://grafana.com/docs/loki/latest/query/log_queries/">grafana.com</a></cite></p> <h2 id="Metric-クエリ">Metric クエリ</h2> <p>Log クエリの拡張版でログの検索結果をベースに演算することが目的です。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgrafana.com%2Fdocs%2Floki%2Flatest%2Fquery%2Fmetric_queries%2F" title="Metric queries | Grafana Loki documentation " class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://grafana.com/docs/loki/latest/query/metric_queries/">grafana.com</a></cite></p> <h1 id="OpenShift-Logging-としての構築">OpenShift Logging としての構築</h1> <p>まずは製品ドキュメントに従いながら、Loki を利用した Logging を構築していきます。</p> <p>まずは Operator の導入から。Operator は Loki Operator と OpenShift Cluster Logging Operator の 2 つが必要となります。それぞれをインストールします。</p> <h2 id="Operator-の導入">Operator の導入</h2> <p>Loki Operator をインストールする Namespace の作成</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt; EOF | oc create -f - apiVersion: v1 kind: Namespace metadata: name: openshift-operators-redhat annotations: openshift.io/node-selector: &#34;&#34; labels: openshift.io/cluster-monitoring: &#34;true&#34; EOF</pre> <p>Cluster Logging Operator をインストールする Namespace の作成</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt;EOF | oc create -f - apiVersion: v1 kind: Namespace metadata: name: openshift-logging annotations: openshift.io/node-selector: &#34;&#34; labels: openshift.io/cluster-monitoring: &#34;true&#34; EOF</pre> <p>OpenShift Cluster Logging 用の OperatorGroup と Subscription を作成する</p> <p>OperatorGroup の作成</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt;EOF | oc create -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: cluster-logging namespace: openshift-logging spec: targetNamespaces: - openshift-logging EOF</pre> <p>続いて、Subscription を作成します。</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt;EOF | oc create -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: cluster-logging namespace: openshift-logging spec: spec: channel: stable-5.8 installPlanApproval: Automatic name: cluster-logging source: redhat-operators sourceNamespace: openshift-marketplace startingCSV: cluster-logging.v5.8.0 EOF</pre> <p>次に、Loki Operator をインストールします。Cluster Logging Operator 同様に Subscription を作成します。</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt; EOF | oc create -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: loki-operator namespace: openshift-operators-redhat spec: channel: stable-5.8 installPlanApproval: Automatic name: loki-operator source: redhat-operators sourceNamespace: openshift-marketplace EOF</pre> <h2 id="Loki-のデプロイ">Loki のデプロイ</h2> <p>Loki は Object Storage を必要とします。今回の構築環境は AWS を利用しているので、適当に AWS S3 のバケットを作成して利用します。 Object Storage へのアクセス情報は Secret を利用して指定するため、接続情報を以下のように用意します。</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt;EOF | oc create -f - apiVersion: v1 kind: Secret metadata: name: logging-loki-s3 namespace: openshift-logging stringData: access_key_id: &lt;ACCESS KEY&gt; access_key_secret: &lt;ACCESS_KEY_SECRET&gt; bucketnames: &lt;BUCKET_NAME&gt; endpoint: https://s3.ap-southeast-2.amazonaws.com region: ap-southeast-2 EOF</pre> <p>次に、LokiStack Custom Resource を作成します。今回作成する LokiStack のサイズは <code>1x.small</code> とします。</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt;EOF | oc create -f - apiVersion: loki.grafana.com/v1 kind: LokiStack metadata: name: logging-loki # 1 namespace: openshift-logging spec: size: 1x.small #2 storage: schemas: - version: v12 effectiveDate: &#39;2022-06-01&#39; secret: name: logging-loki-s3 #3 type: s3 #4 storageClassName: gp3-csi #5 tenants: mode: openshift-logging EOF</pre> <p>パラメタの簡単な説明</p> <ol> <li>logging-loki という名前を使用してください。</li> <li>Loki の展開サイズを選択してください。</li> <li>ログストレージに使用するシークレットを指定してください。</li> <li>対応するストレージタイプを指定してください。</li> <li>一時的なストレージに既存のストレージクラスの名前を入力してください。最適なパフォーマンスを得るためには、ブロックストレージを割り当てるストレージクラスを指定してください。クラスタで利用可能なストレージクラスは、oc get storageclasses コマンドを使用してリストアップできます。</li> </ol> <h2 id="Cluster-Logging-として利用する">Cluster Logging として利用する</h2> <p>デプロイした Loki を OpenShift Cluster Logging として利用します。</p> <pre class="code" data-lang="" data-unlink>$ cat &lt;&lt; EOF | oc create -f - apiVersion: logging.openshift.io/v1 kind: ClusterLogging metadata: name: instance namespace: openshift-logging spec: logStore: type: lokistack lokistack: name: logging-loki collection: type: vector EOF</pre> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdocs.openshift.com%2Fcontainer-platform%2F4.14%2Flogging%2Fcluster-logging-deploying.html" title="Installing Logging | Logging | OpenShift Container Platform 4.14" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://docs.openshift.com/container-platform/4.14/logging/cluster-logging-deploying.html">docs.openshift.com</a></cite></p> <h1 id="簡単なアクセス確認">簡単なアクセス確認</h1> <h2 id="Web-Console-からのアクセス">Web Console からのアクセス</h2> <p>ここまでで、Loki が利用できるようになっているはずなので、Web Console からも簡単に確認してみます。 Web Console の Administrator の画面から、 Observe > Logs を選択すると画面が表示されます。</p> <p><figure class="figure-image figure-image-fotolife" title="Logs"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/f/foureyes-san/20231213/20231213213356.png" width="1200" height="527" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>Logs</figcaption></figure></p> <h2 id="CLI-からのアクセス">CLI からのアクセス</h2> <p>ここで本題です。今回 CLI アクセスを試すきっかけとなったのは、実は OpenShift Web Console からはまだ Metric クエリを実行することができません。そのため、Metric クエリを実行するにはどうしても CLI 経由での呼び出しが必要となります。</p> <h3 id="アクセス方法の確認">アクセス方法の確認</h3> <p>Loki へのアクセスは Route 経由で行います。</p> <pre class="code" data-lang="" data-unlink>$ oc get route -n openshift-logging NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD logging-loki logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com logging-loki-gateway-http public reencrypt None</pre> <p>呼び出し方を確認するため、試しに Route にアクセスしてみます。Loki は OpenShift による認証を利用しているため、OpenShift のユーザーのトークンを利用してアクセスしてみます。</p> <pre class="code" data-lang="" data-unlink>$ curl -k -s -H &#39;Authorization: Bearer &lt;TOKEN&gt;&#39; https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com { &#34;paths&#34;: [ &#34;/api/logs/v1/{tenant}/*&#34; ] }</pre> <p><code>{tenant}</code> を指定する必要がありそうです。テナントとは何でしょうか。実は、OpenShift Cluster Logging では Loki のマルチテナント機能を利用して、infrastracture ログ、application ログ、audit ログを分けて格納しています。 そのため、ここでいう <code>{tenant}</code> は <code>infrastructure</code>、<code>application</code>、<code>audit</code> となります。</p> <p>Loki の API のパスは製品ドキュメントに記載があり以下のようになっています。パスの最後にある <code>query_range</code> は呼び出すAPIにより代わりますが、今回は Metric クエリを呼び出すのでこちらを利用します。</p> <pre class="code" data-lang="" data-unlink>GET /loki/api/v1/query_range</pre> <p>これを合わせると次のようなURLを呼び出すことで、<code>curl</code> でアクセスできることがわかります。</p> <pre class="code" data-lang="" data-unlink>https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com/api/logs/v1/{tenant}/loki/api/v1/query_range</pre> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgrafana.com%2Fdocs%2Floki%2Flatest%2Freference%2Fapi%2F%23query-loki-over-a-range-of-time" title="Grafana Loki HTTP API | Grafana Loki documentation " class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://grafana.com/docs/loki/latest/reference/api/#query-loki-over-a-range-of-time">grafana.com</a></cite></p> <h3 id="Metric-クエリを呼び出してみる">Metric クエリを呼び出してみる</h3> <p>LogQL は空白やシングルクォートなども含むため、URLエンコードした形で指定します。curl コマンドではパラメタ指定によりURLエンコードを行うことはできますが、予めエンコードしておきます。</p> <p>今回テストするのは次の Metric クエリです。 Namespace 毎に log_type=infrastructure のログ数をカウントするというものです。</p> <pre class="code" data-lang="" data-unlink>sum by (kubernetes_namespace_name) (count_over_time({ log_type=&#34;infrastructure&#34; } [5m]) )</pre> <p>curl コマンドにすると以下のような感じです。</p> <pre class="code" data-lang="" data-unlink>$ curl -G -k -s -H &#39;Authorization: Bearer sha256~_hJqP4Ksy5Opcs1_37s2fC2_XFXWigO6iXJEDBpM_nA&#39; https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com/api/logs/v1/infrastructure/loki/api/v1/query_range --data &#39;query=sum%20by%20(kubernetes_namespace_name)%20(count_over_time(%7B%20log_type%3D%22infrastructure%22%20%7D%20%5B5m%5D)%20)&#39; --data-urlencode step=2m --data-urlencode start=1702467769 --data-urlencode end=1702471369</pre> <p>呼び出し結果</p> <pre class="code" data-lang="" data-unlink>{ &#34;status&#34;: &#34;success&#34;, &#34;data&#34;: { &#34;resultType&#34;: &#34;matrix&#34;, &#34;result&#34;: [ { &#34;metric&#34;: { &#34;kubernetes_namespace_name&#34;: &#34;openshift-apiserver&#34; }, &#34;values&#34;: [ [ 1702469160, &#34;1&#34; ], [ 1702469280, &#34;1&#34; ], [ 1702469400, &#34;5&#34; ], [ 1702469520, &#34;4&#34; ], [ 1702469640, &#34;4&#34; ], [ ...</pre> <p>うまく取得できたようです。</p> <h3 id="LogCLI">LogCLI</h3> <p>次に、Loki の CLI LogCLI でのアクセスを試します。 コマンドは、以下のページを参考に予め準備してください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgrafana.com%2Fdocs%2Floki%2Flatest%2Fquery%2Flogcli%2F" title="LogCLI | Grafana Loki documentation " class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://grafana.com/docs/loki/latest/query/logcli/">grafana.com</a></cite></p> <p>環境変数で接続先と認証情報を設定します。呼び出したいテナント毎に呼び出し先は変えてください。</p> <pre class="code" data-lang="" data-unlink>$ export LOKI_BEARER_TOKEN=&#34;&lt;TOKEN&gt;&#34; $ export LOKI_ADDR=https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com/api/logs/v1/infrastructure</pre> <p>コマンドを実行します。OpenShift の証明書は自己署名証明書を利用しているため、TLSのチェックはスキップするようにします。</p> <pre class="code" data-lang="" data-unlink>$ logcli query --tls-skip-verify &#39;sum by (kubernetes_namespace_name) (count_over_time({ log_type=&#34;infrastructure&#34; } [5m]) )&#39;</pre> <p>出力結果が取得できました。 curl で取得したときと異なり、result が抽出されてます。</p> <pre class="code" data-lang="" data-unlink>[ { &#34;metric&#34;: { &#34;kubernetes_namespace_name&#34;: &#34;openshift-apiserver&#34; }, &#34;values&#34;: [ [ 1702470154, &#34;4&#34; ], [ 1702470168, &#34;4&#34; ], [ 1702470182, &#34;4&#34; ], [ 1702470196, &#34;4&#34; ], [ 1702470210, ...</pre> <h1 id="おわりに">おわりに</h1> <p>今回は、CLI を用いて Loki へのアクセスをしてみました。これにより現在は Web Console から利用できない Metric クエリの結果を取得できることが試せました。 まだ発展途上のコンポーネントではありますが、こういった形でログの解析ができるようになっていくとログを利用した運用や調査などが進みそうです。</p> foureyes-san libkrunでのネットワーク通信 hatenablog://entry/6801883189066420067 2023-12-14T02:30:57+09:00 2023-12-14T02:43:55+09:00 Red Hatの織です。本記事はRed Hat Advent Calendar 12/5分の記事です (遅くなってしまいました)。また、Advent Calendar 12/3の「libkrunで遊ぶ」の続編でもあります。 Transparent Socket Impersonation libkrunでのネットワーク通信は、Transparent Socket Impersonation (TSI) という仕組みを使っています(直訳すると「透過的なソケットのなりすまし」)。TSIはlibkrun以外では聞いたことがないので、おそらく一般的な用語ではなくて、libkrun特有の概念ではないかと… <p>Red Hatの織です。本記事はRed Hat Advent Calendar 12/5分の記事です (遅くなってしまいました)。また、Advent Calendar 12/3の「<a href="https://rheb.hatenablog.com/entry/libkrun-intro">libkrunで遊ぶ</a>」の続編でもあります。</p> <h1 id="Transparent-Socket-Impersonation">Transparent Socket Impersonation</h1> <p>libkrunでのネットワーク通信は、Transparent Socket Impersonation (TSI) という仕組みを使っています(直訳すると「透過的なソケットのなりすまし」)。TSIはlibkrun以外では聞いたことがないので、おそらく一般的な用語ではなくて、libkrun特有の概念ではないかと思います。TSIの仕組みによって、仮想インターフェース (virtio-net) を使わずにネットワーク通信ができるようになります (ただしAF_INTのSOCK_DGRAMおよびSOCK_STREAMの通信のみ)。</p> <h1 id="TSI概要">TSI概要</h1> <p>libkrunでは、ゲストOSのカーネルおよびFirmwareに相当する<a href="https://github.com/containers/libkrunfw">libkrunfw</a>というコンポーネントがあります。libkrunのゲストOS内のプロセスが発行したシステムコールは、libkrunfwが処理します。 プロセスが通信を行う際はソケットAPIを使うことが多いと思いますが、ソケット関連のシステムコールもlibkrunfwによって処理されます。</p> <p>libkrunfwのLinuxカーネルには、「タイプがSOCK_DGRAMもしくはSOCK_STREAMのAF_INETソケットはAF_TSIに変換する」という<a href="https://github.com/containers/libkrunfw/blob/8a718429995dce928aa04872a5d8c3a700a39446/patches/0011-tsi-allow-hijacking-sockets-tsi_hijack.patch#L47-L52">パッチ</a>が当たっています。したがって、該当するソケット通信は全て、(クライアントはAF_INETとして通信しているつもりですがカーネル内ではAF_INETではなく)AF_TSIとして処理されます。</p> <p>AF_TSIはAF_INETとAF_VSOCKの両方を透過的に処理できるような構造になっており、libkrunfwカーネルはゲスト内のプロセスが出すAF_INETのソケット通信をAF_VSOCKに偽装します。この仕組みを使うことで、ゲスト内のプロセスからのAF_INETのソケットは、virtio-vsockデバイスを経由し、VMM(以下、「VMM」と「libkrun」は同じ意味で書いています)をプロキシーとすることで、外と通信できるようになります。</p> <p><figure class="figure-image figure-image-fotolife" title="libkrun TSI networking overview"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/o/orimanabu/20231214/20231214024245.png" width="914" height="501" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><figcaption>libkrun TSI networking overview</figcaption></figure></p> <p>突然AF_*のような用語が出てきました。AFはアドレスファミリー(Address Family)を表しており、ネットワークアドレスの種類と思ってください。AF_INETはおなじみのIPv4での通信を表します。AF_VSOCKは、仮想環境においてゲストとホストの間でのソケット通信をするためのアドレスファミリーです。典型的な使用例としては、ゲストエージェント(例えばVMware Tools的なもの)とホストとの通信が挙げられます。VSOCKは、最近ではコンテナ環境などいろんな場所で使われています。</p> <p>また、</p> <ul> <li>SOCK_DGRAM = UDP通信</li> <li>SOCK_STREAM = TCP通信</li> </ul> <p>を意味する、と思ってください。</p> <h1 id="詳細">詳細</h1> <p>「AF_INETとAF_VSOCKの両方を透過的に処理できる」「AF_INETのソケット通信をAF_VSOCKに偽装」の実装についてもう少し踏み込んでみましょう。以下では、「ゲストOS内のクライアントプロセスが、外部のサーバーに対してconnect(2)で接続し、write(2)で何かデータを書く」というユースケースを想定します。</p> <h2 id="tsi_sock構造体">tsi_sock構造体</h2> <p>Linuxカーネルでは、アドレスファミリーごとに、*_sockという構造体を用意しています。まずはAF_TSIの通信を表現するためのsock構造体(<a href="https://github.com/containers/libkrunfw/blob/8a718429995dce928aa04872a5d8c3a700a39446/patches/0010-Transparent-Socket-Impersonation-implementation.patch#L1493-L1504">struct tsi_sock</a>)を見てみましょう。</p> <pre class="code lang-c" data-lang="c" data-unlink><span class="synType">struct</span> tsi_sock { <span class="synComment">/* sk must be the first member. */</span> <span class="synType">struct</span> sock sk; <span class="synType">struct</span> socket *isocket; <span class="synComment">// inet通信用ソケット</span> <span class="synType">struct</span> socket *vsocket; <span class="synComment">// vsock通信用ソケット</span> <span class="synType">struct</span> socket *csocket; <span class="synComment">// VMM制御用ソケット(VMM内にinet-vsockプロキシーのエントリ追加依頼等で使用、これもvsock)</span> <span class="synType">unsigned</span> <span class="synType">int</span> status; u32 svm_port; u32 svm_peer_port; <span class="synType">struct</span> sockaddr_in *bound_addr; <span class="synType">struct</span> sockaddr_in *sendto_addr; }; </pre> <p>sock構造体の中にAF_INET通信用、AF_VSOCK通信用のsocket構造体を持つことで、場面に応じてそれぞれどちらの通信でも表現できるようになっていることがわかります。</p> <h2 id="connect2時の動き">connect(2)時の動き</h2> <p>外部のIPアドレスに接続する際に呼ばれる、connect(2)システムコールの処理を見てみましょう。libkrun仮想マシン内のプロセスがconnect(2)を呼び出すと、libkrunfwのカーネル内ではtsi_connect()がその処理を担当します。tsi_connect()はおおまかに次のような処理の流れになっています。</p> <pre class="code lang-c" data-lang="c" data-unlink><span class="synType">static</span> <span class="synType">int</span> <span class="synIdentifier">tsi_connect</span>(<span class="synType">struct</span> socket *sock, <span class="synType">struct</span> sockaddr *addr, <span class="synType">int</span> addr_len, <span class="synType">int</span> flags) { ... tsk = <span class="synIdentifier">tsi_sk</span>(sock-&gt;sk); isocket = tsk-&gt;isocket; vsocket = tsk-&gt;vsocket; ... <span class="synStatement">if</span> (isocket) { ... err = isocket-&gt;ops-&gt;<span class="synIdentifier">connect</span>(isocket, addr, addr_len, flags &amp; ~O_NONBLOCK); ... } <span class="synStatement">if</span> (vsocket) { ... <span class="synStatement">if</span> (!tsk-&gt;svm_port) { <span class="synStatement">if</span> (<span class="synIdentifier">tsi_create_proxy</span>(tsk, vsocket-&gt;type) != <span class="synConstant">0</span>) { err = -<span class="synConstant">EINVAL</span>; <span class="synStatement">goto</span> release; } } ... err = <span class="synIdentifier">tsi_control_sendmsg</span>(tsk-&gt;csocket, TSI_CONNECT, (<span class="synType">void</span> *)&amp;tc_req, <span class="synStatement">sizeof</span>(<span class="synType">struct</span> tsi_connect_req)); ... err = <span class="synIdentifier">tsi_control_recvmsg</span>(tsk-&gt;csocket, TSI_CONNECT, (<span class="synType">void</span> *)&amp;tc_rsp, <span class="synStatement">sizeof</span>(<span class="synType">struct</span> tsi_connect_rsp)); ... err = <span class="synIdentifier">kernel_connect</span>(vsocket, (<span class="synType">struct</span> sockaddr *)&amp;vm_addr, <span class="synStatement">sizeof</span>(<span class="synType">struct</span> sockaddr_vm), <span class="synConstant">0</span>); ... tsk-&gt;status = S_VSOCK; } ... } </pre> <p>今考えているユースケースでは、ゲスト→ホスト→外部という通信を想定しており、ゲストからの直接のconnectはできないため(<a href="https://rheb.hatenablog.com/entry/libkrun-intro">前回</a>の記事で確認したように、libkrunはvirtio-netは使っておらず、ゲスト内ではループバックインターフェースしか持っていません)、<code>if (isocket)</code> の節は飛ばして <code>if (vsocket)</code> のif節に入ります。</p> <p>この中では、おおまかに</p> <ol> <li>VMMに対してINET-VSOCKプロキシーをするためのエントリー作成する (<a href="">tsi_create_proxy()</a>)</li> <li>VMM内のINET-VSOCKプロキシー経由で外部サイトにconnectする (<a href="">tsi_control_sendmsg()</a>でTSI_CONNECTする)</li> </ol> <p>という処理をしています。</p> <p>INET-VSOCKプロキシーは、libkrun上では <code>VsockMuxer</code> および <code>TcpProxy</code> という構造体で表現されています。VsockMuxerがプロキシー全体を管理しており、プロキシーの各エントリーがTcpProxy、という役割になっています。</p> <ul> <li>VsockMuxer構造体</li> </ul> <pre class="code lang-rust" data-lang="rust" data-unlink><span class="synStatement">pub</span> <span class="synStatement">struct</span> <span class="synIdentifier">VsockMuxer</span> { cid: <span class="synType">u64</span>, host_port_map: <span class="synType">Option</span><span class="synStatement">&lt;</span>HashMap<span class="synStatement">&lt;</span><span class="synType">u16</span>, <span class="synType">u16</span><span class="synStatement">&gt;&gt;</span>, queue: <span class="synType">Option</span><span class="synStatement">&lt;</span>Arc<span class="synStatement">&lt;</span>Mutex<span class="synStatement">&lt;</span>VirtQueue<span class="synStatement">&gt;&gt;&gt;</span>, mem: <span class="synType">Option</span><span class="synStatement">&lt;</span>GuestMemoryMmap<span class="synStatement">&gt;</span>, rxq: Arc<span class="synStatement">&lt;</span>Mutex<span class="synStatement">&lt;</span>MuxerRxQ<span class="synStatement">&gt;&gt;</span>, epoll: Epoll, interrupt_evt: EventFd, interrupt_status: Arc<span class="synStatement">&lt;</span>AtomicUsize<span class="synStatement">&gt;</span>, intc: <span class="synType">Option</span><span class="synStatement">&lt;</span>Arc<span class="synStatement">&lt;</span>Mutex<span class="synStatement">&lt;</span>Gic<span class="synStatement">&gt;&gt;&gt;</span>, irq_line: <span class="synType">Option</span><span class="synStatement">&lt;</span><span class="synType">u32</span><span class="synStatement">&gt;</span>, proxy_map: ProxyMap, reaper_sender: <span class="synType">Option</span><span class="synStatement">&lt;</span>Sender<span class="synStatement">&lt;</span><span class="synType">u64</span><span class="synStatement">&gt;&gt;</span>, } </pre> <p>VsockMuxerには <code>proxy_map</code> というフィールドがあります。ProxyMap型のこのフィールドは、中身はHashMapです。dstポートとsrcポートをビットシフトして連結した値をプロキシーエントリーの "ID" とし、これをキーとして指定するとHashMapからTcpProxyが取り出せる、という作りになっています。</p> <ul> <li>ProxyMap</li> </ul> <pre class="code lang-rust" data-lang="rust" data-unlink> <span class="synStatement">pub</span> <span class="synStatement">type</span> <span class="synIdentifier">ProxyMap</span> <span class="synStatement">=</span> Arc<span class="synStatement">&lt;</span>RwLock<span class="synStatement">&lt;</span>HashMap<span class="synStatement">&lt;</span><span class="synType">u64</span>, Mutex<span class="synStatement">&lt;</span><span class="synType">Box</span><span class="synStatement">&lt;</span>dyn Proxy<span class="synStatement">&gt;&gt;&gt;&gt;&gt;</span>; </pre> <ul> <li>TcpProxy構造体</li> </ul> <pre class="code lang-rust" data-lang="rust" data-unlink><span class="synStatement">pub</span> <span class="synStatement">struct</span> <span class="synIdentifier">TcpProxy</span> { id: <span class="synType">u64</span>, cid: <span class="synType">u64</span>, parent_id: <span class="synType">u64</span>, local_port: <span class="synType">u32</span>, peer_port: <span class="synType">u32</span>, control_port: <span class="synType">u32</span>, fd: RawFd, <span class="synStatement">pub</span> status: ProxyStatus, mem: GuestMemoryMmap, queue: Arc<span class="synStatement">&lt;</span>Mutex<span class="synStatement">&lt;</span>VirtQueue<span class="synStatement">&gt;&gt;</span>, rxq: Arc<span class="synStatement">&lt;</span>Mutex<span class="synStatement">&lt;</span>MuxerRxQ<span class="synStatement">&gt;&gt;</span>, rx_cnt: Wrapping<span class="synStatement">&lt;</span><span class="synType">u32</span><span class="synStatement">&gt;</span>, tx_cnt: Wrapping<span class="synStatement">&lt;</span><span class="synType">u32</span><span class="synStatement">&gt;</span>, last_tx_cnt_sent: Wrapping<span class="synStatement">&lt;</span><span class="synType">u32</span><span class="synStatement">&gt;</span>, peer_buf_alloc: <span class="synType">u32</span>, peer_fwd_cnt: Wrapping<span class="synStatement">&lt;</span><span class="synType">u32</span><span class="synStatement">&gt;</span>, push_cnt: Wrapping<span class="synStatement">&lt;</span><span class="synType">u32</span><span class="synStatement">&gt;</span>, pending_accepts: <span class="synType">u64</span>, } </pre> <p>1.の処理(tsi_create_proxy())は、<code>TSI_PROXY_CREATE</code> というメッセージを、制御用VSOCKソケット(csocket)を使ってVMMに対して送信し、この後connectするために使用するプロキシーエントリーの作成を依頼します。</p> <p>このVSOCKメッセージを受けたVMMは、</p> <ul> <li>VsockMuxer.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/muxer.rs#L465">send_dgram_pkt()</a> @src/devices/src/virtio/vsock/muxer.rs</li> <li>VsockMuxer.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/muxer.rs#L267-L284">process_proxy_create()</a> @src/devices/src/virtio/vsock/muxer.rs</li> </ul> <p>という流れで処理が進み、TcpProxyのエントリーを作成後proxy_mapに格納します。</p> <p>2.の処理では、<code>TSI_CONNECT</code> というメッセージを、制御用VSOCKソケット(csocket)を使ってVMMに送信し、プロセスからのconnect(2)をlibkrunに代替してもらうよう依頼します。 このVSOCKメッセージを受けたVMMの中では、</p> <ul> <li>VsockMuxer.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/muxer.rs#L466">send_dgram_pkt()</a> @src/devices/src/virtio/vsock/muxer.rs</li> <li>VsockMuxer.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/muxer.rs#L321">process_connect()</a> @src/devices/src/virtio/vsock/muxer.rs</li> <li>TcpProxy.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/tcp.rs#L382-L385">connect()</a> @src/devices/src/virtio/vsock/tcp.rs</li> <li>nix::<a href="https://github.com/nix-rust/nix/blob/v0.24.1/src/sys/socket/mod.rs#L1882">connect()</a> @src/sys/socket/mod.rs</li> <li>libc::<a href="https://github.com/rust-lang/libc/blob/0.2.147/src/unix/mod.rs#L630">connect()</a> @/src/unix/mod.rs</li> </ul> <p>という流れで最終的にconnect(2)システムコールを呼び出します。</p> <h1 id="write2時の動き">write(2)時の動き</h1> <p>Linuxカーネルにおいて、ソケットに対してwrite(2)した場合、<code>socket_file_ops</code> の <code>.write_iter()</code> メンバ関数が呼ばれます。</p> <pre class="code lang-c" data-lang="c" data-unlink><span class="synType">static</span> <span class="synType">const</span> <span class="synType">struct</span> file_operations socket_file_ops = { .owner = THIS_MODULE, .llseek = no_llseek, .read_iter = sock_read_iter, .write_iter = sock_write_iter, .poll = sock_poll, .unlocked_ioctl = sock_ioctl, <span class="synPreProc">#ifdef CONFIG_COMPAT</span> .compat_ioctl = compat_sock_ioctl, <span class="synPreProc">#endif</span> .mmap = sock_mmap, .release = sock_close, .fasync = sock_fasync, .sendpage = sock_sendpage, .splice_write = generic_splice_sendpage, .splice_read = sock_splice_read, .show_fdinfo = sock_show_fdinfo, }; </pre> <p>さらにその後、</p> <pre class="code" data-lang="" data-unlink>sock_write_iter() → sock_sendmsg() → sock_sendmsg_nosec() → sock-&gt;ops-&gt;sendmsg()</pre> <p>という流れになり、最終的に <code>struct proto_ops</code> のメンバ関数 <code>sendmsg()</code> が呼び出されます。AF_TSIの場合は <code>tsi_stream_sendmsg()</code> (TCPの場合) もしくは <code>tsi_dgram_sendmsg()</code> (UDPの場合) が呼ばれることになります。ここではTCPを想定して <code>tsi_stream_sendmsg()</code> を見ていきましょう。</p> <pre class="code lang-rust" data-lang="rust" data-unlink><span class="synType">static</span> int <span class="synIdentifier">tsi_stream_sendmsg</span>(<span class="synStatement">struct</span> <span class="synIdentifier">socket</span> <span class="synType">*</span>sock, <span class="synStatement">struct</span> <span class="synIdentifier">msghdr</span> <span class="synType">*</span>msg, size_t len) { <span class="synStatement">struct</span> <span class="synIdentifier">sock</span> <span class="synType">*</span>sk <span class="synStatement">=</span> sock<span class="synStatement">-&gt;</span>sk; <span class="synStatement">struct</span> <span class="synIdentifier">tsi_sock</span> <span class="synType">*</span>tsk; <span class="synStatement">struct</span> <span class="synIdentifier">socket</span> <span class="synType">*</span>isocket; <span class="synStatement">struct</span> <span class="synIdentifier">socket</span> <span class="synType">*</span>vsocket; int err; <span class="synIdentifier">lock_sock</span>(sk); tsk <span class="synStatement">=</span> <span class="synIdentifier">tsi_sk</span>(sock<span class="synStatement">-&gt;</span>sk); isocket <span class="synStatement">=</span> tsk<span class="synStatement">-&gt;</span>isocket; vsocket <span class="synStatement">=</span> tsk<span class="synStatement">-&gt;</span>vsocket; <span class="synIdentifier">pr_debug</span>(<span class="synConstant">&quot;%s: s=%p vs=%p is=%p st=%d</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>, __func__, sock, vsocket, isocket, tsk<span class="synStatement">-&gt;</span>status); switch (tsk<span class="synStatement">-&gt;</span>status) { case S_HYBRID: err <span class="synStatement">=</span> <span class="synStatement">-</span>EINVAL; <span class="synStatement">break</span>; case S_INET: err <span class="synStatement">=</span> isocket<span class="synStatement">-&gt;</span>ops<span class="synStatement">-&gt;</span><span class="synIdentifier">sendmsg</span>(isocket, msg, len); <span class="synStatement">break</span>; case S_VSOCK: err <span class="synStatement">=</span> vsocket<span class="synStatement">-&gt;</span>ops<span class="synStatement">-&gt;</span><span class="synIdentifier">sendmsg</span>(vsocket, msg, len); <span class="synIdentifier">pr_debug</span>(<span class="synConstant">&quot;%s: s=%p vs=%p is=%p st=%d exit</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>, __func__, sock, vsocket, isocket, tsk<span class="synStatement">-&gt;</span>status); <span class="synStatement">break</span>; } <span class="synIdentifier">release_sock</span>(sk); <span class="synStatement">return</span> err; } </pre> <p>connect(2)時にtsk->statusに <code>S_VSOCK</code> を入れているので、ここではvsocketを使って <code>vsocket-&gt;ops-&gt;sendmsg()</code> でデータを送信していることがわかります。VSOCKでのsendmsg()では、最終的に <code>VIRTIO_VSOCK_OP_RW</code> というメッセージをVMMに対して依頼します。</p> <p>このVSOCKメッセージを受けたVMMでは、以下の流れで処理が進み、最終的にsend(2)を使ってファイルディスクリプタにデータを書き込みます。</p> <ul> <li>VsockMuxer.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/muxer.rs#L617">send_stream_pkt()</a> @src/devices/src/virtio/vsock/muxer.rs</li> <li>VsockMuxer.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/muxer.rs#L550">process_stream_rw()</a> @src/devices/src/virtio/vsock/muxer.rs</li> <li>TcpProxy.<a href="https://github.com/containers/libkrun/blob/fddb70e17a48eaa8e77573b95dcebd17b06133e1/src/devices/src/virtio/vsock/tcp.rs#L482">sendmsg()</a> @src/devices/src/virtio/vsock/tcp.rs</li> <li>nix::<a href="https://github.com/nix-rust/nix/blob/v0.24.1/src/sys/socket/mod.rs#L1951">send()</a> @src/sys/socket/mod.rs</li> <li>libc::<a href="https://github.com/rust-lang/libc/blob/0.2.147/src/unix/mod.rs#L1304">send()</a> @src/unix/mod.rs</li> </ul> <h1 id="まとめ">まとめ</h1> <p>というわけで、libkrunのゲスト内のプロセスから外部のIPアドレスに対してソケット通信をする様子を追いかけてみました。libkrunではvirtio-netを使用しないため、ゲストはループバックインターフェースしか持っていません。しかし、TSIの巧妙な仕組みによってINET通信をVSOCKに変換し、VMM内に持つINET-VSOCKプロキシーを介して、ゲスト↔VMMはVSOCKを、VMM↔外部はINETを使って通信する様子がわかりました。</p> orimanabu OpenShift Virtualization ( Kubevirt ) でVM管理もCloud Nativeに (2) hatenablog://entry/6801883189065050136 2023-12-11T07:30:00+09:00 2024-02-06T18:01:38+09:00 こんにちは、Red Hatでソリューションアーキテクトをしている石川です。 前回に引き続き、今回もOpenShift Virtualization(OCP Virt)について紹介していきたいと思います。 環境の構築やインストールに関しては前回の記事を参照下さい。 rheb.hatenablog.com この記事ではWindows ServerをOCP Virt上でVMとして構築し、関連してContainerized Data Importer(CDI)やDataVolumeについて紹介したいと思います。 Windows Serverの構築 Red HatはWindows Serverを実行する… <p>こんにちは、Red Hatでソリューションアーキテクトをしている石川です。</p> <p>前回に引き続き、今回もOpenShift Virtualization(OCP Virt)について紹介していきたいと思います。<br/> 環境の構築やインストールに関しては前回の記事を参照下さい。 <cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2023/11/15/174359">rheb.hatenablog.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2023%2F11%2F15%2F174359" title="OpenShift Virtualization(Kubevirt)でVM管理もCloud Nativeに (1) - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <p>この記事ではWindows ServerをOCP Virt上でVMとして構築し、関連してContainerized Data Importer(CDI)やDataVolumeについて紹介したいと思います。</p> <h3 id="Windows-Serverの構築">Windows Serverの構築</h3> <p>Red HatはWindows Serverを実行する仮想化ソフトウェアについて<a href="https://learn.microsoft.com/ja-jp/troubleshoot/windows-server/virtualization/non-microsoft-hardware-virtualization-software">Microsoftとパートナー</a>であり、OCP Virtも複数バージョンのWindows Serverの実行をサポートしています。<br/> <cite class="hatena-citation"><a href="https://access.redhat.com/articles/973163#ocpvirt">access.redhat.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Farticles%2F973163%23ocpvirt" title="Certified Guest Operating Systems in Red Hat OpenStack Platform, Red Hat Virtualization, Red Hat OpenShift Virtualization and Red Hat Enterprise Linux with KVM - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><br/> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208111728.png" width="1074" height="649" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>今回はWindows Server 2022をOCP Virtで実行したいと思います。 まずはOCPコンソールのカタログから対象のバージョンを選び、設定のカスタマイズを行なっていきます。<br/> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208111759.png" width="1200" height="626" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>前回の記事でRHEL9のVMを起動した際はOCP Virtをインストールした時点でOSのイメージがOCP環境上に準備されていましたが、Windows Serverを利用する場合はOSのISOファイルを準備する必要があります。 まず以下のサイトからISOをダウンロードするためのURLをコピーしておきます。 <cite class="hatena-citation"><a href="https://www.microsoft.com/ja-jp/evalcenter/download-windows-server-2022">www.microsoft.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.microsoft.com%2Fja-jp%2Fevalcenter%2Fdownload-windows-server-2022" title="Windows Server 2022 | Microsoft Evaluation Center " class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208111827.png" width="1200" height="657" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>画像のように"Boot from CD"にチェックを入れ、CD sourceとして"URL"を選択、そして"Image URL"にコピーしておいたURLを貼り付けます。</p> <p>あとはそのままの設定でVMを作成しましょう。 しばらくするとVMが起動しOSのセットアップが開始されます。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208111856.png" width="1200" height="571" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>OCP VirtではVNCコンソールを利用できるためここから設定を進めていきます。<br/> 設定が完了すると無事にWindows Serverを起動することができました。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208111925.png" width="1200" height="545" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h4 id="QEMU-Guest-Agentのインストール">QEMU Guest Agentのインストール</h4> <p>Windows Server起動後、VMの管理を円滑に行うためQEMU Guest Agentをインストールしたいと思います。 ドキュメントに関しては以下を参照下さい。 <cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.14/html-single/virtualization/index#installing-qemu-guest-agent-on-windows-vm_virt-installing-qemu-guest-agent">access.redhat.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fopenshift_container_platform%2F4.14%2Fhtml-single%2Fvirtualization%2Findex%23installing-qemu-guest-agent-on-windows-vm_virt-installing-qemu-guest-agent" title="仮想化 OpenShift Container Platform 4.14 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <p>ファイルエクスプローラーを開き画面左側から"virtio-win" CDドライブを選択します。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208111950.png" width="1032" height="732" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>"guest-agent"フォルダを開き、中にあるインストーラーを実行するとQEMU Guest Agentをインストールすることができます。</p> <p>PowerShellから<code>net start</code>コマンドを実行するとQEMU Guest Agentの実行を確認できます。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112012.png" width="442" height="180" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h4 id="リモートデスクトップ接続">リモートデスクトップ接続</h4> <p>起動したVMに対し、手元の環境(Mac)からRDPで接続してみたいと思います。 まずはVNCコンソールからサーバーマネージャーを開き、リモートデスクトップを有効化しておきます。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112032.png" width="711" height="386" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>その後コンソールをVNCコンソールから"Desktop viewer"に切り替え、"Create RDP Service"を実行します。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112053.png" width="1200" height="320" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span> これにより<code>type: NodePort</code>のServiceが新たに作成され、VMが起動するベアメタルNodeのIPを通じてクラスター外部からのRDP接続が可能となりました。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112148.png" width="370" height="271" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>ただし今回も前回同様にAWS上のベアメタルサーバーを利用しているため、手元の環境から上記のアドレスに直接のアクセスはできません。 そのためPublic Subnet上で踏み台サーバーを構築し、ポートフォワードを行うことで手元の環境からアクセスを可能としました。またAWSのSGについても適宜設定変更をしておきます。</p> <pre class="code" data-lang="" data-unlink>ssh -i ~/.ssh/cluster-key ec2-user@{踏み台のパブリックIP} -L 3389:10.0.68.1:31183 </pre> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112257.png" width="1200" height="666" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>無事手元の環境からアクセスすることができました。</p> <h3 id="Containerized-Data-ImporterCDI--DataVolume-について">Containerized Data Importer(CDI) / DataVolume について</h3> <p>今回はVMを作成するタイミングでコンソールからISOファイルのURLを指定しましたが、実際のファイルのダウンロードや、ダウンロード先としてのPVの作成などはDataVolumeと呼ばれるCRや、それを管理するContainerized Data Importer(CDI) Operatorにより行われます。 CDI OperatorはOCP VirtのOperatorをインストールし、HyperConverged CRを作成するとOpenShift環境にインストールされます。</p> <p>DataVolume CRを作成すると、OSイメージをダウンロードするためのImporter Podと保存用のPVが作成されます。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112327.png" width="807" height="207" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>指定したURLからOSイメージのダウンロードが完了するとImporter Pod等のリソースは削除され、VMを起動するためのVirt Launcher Podに先ほどのPVがアタッチされ、そこからOSの起動を可能としています。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112349.png" width="807" height="207" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>DataVolumeによるOSイメージを含むPVの作成はURLを指定してダウンロードする以外にも、 利用者の端末からのアップロードや、既存のPVからのコピー、PVのSnapshotsからの作成、さらにはコンテナ化されたOSイメージの利用と複数の方法を取ることができます。</p> <p>例えば、前回の記事ではRHEL9のVMを起動しましたが、この場合はOSイメージがVolumeSnapshotsとして保存されており、そこからPVが作成されVirt Launcher Podにアタッチされていました。</p> <p><code>openshift-virtualization-os-images</code>NameSpaceを見るとVolumeSnapshotsとしてCentOS StreamやFedora、そしてRHELのイメージが存在しているのがわかります。</p> <pre class="code" data-lang="" data-unlink># oc get volumesnapshots -n openshift-virtualization-os-images NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE centos-stream8-c323729af4d6 true centos-stream8-c323729af4d6 30Gi ocs-storagecluster-rbdplugin-snapclass snapcontent-a71a0072-a2e9-42f3-a54b-e480b3a2fe2d 20h 20h centos-stream9-e5a8aee22808 true centos-stream9-e5a8aee22808 30Gi ocs-storagecluster-rbdplugin-snapclass snapcontent-2f4aea79-e29e-44c1-8fc5-a1e13babf7d4 20h 20h centos7-680e9b4e0fba true centos7-680e9b4e0fba 30Gi ocs-storagecluster-rbdplugin-snapclass snapcontent-2126c3be-bb95-43d0-ad77-b9fee8486a4c 20h 20h fedora-498bd939ff7a true fedora-498bd939ff7a 30Gi ocs-storagecluster-rbdplugin-snapclass snapcontent-d774d73a-1c11-4572-bb84-024fb8770bd4 20h 20h rhel8-3d8ef774e232 true rhel8-3d8ef774e232 30Gi ocs-storagecluster-rbdplugin-snapclass snapcontent-d74e8c7d-f401-4bee-a14f-17e99c33d413 20h 20h rhel9-1467c655829b true rhel9-1467c655829b 30Gi ocs-storagecluster-rbdplugin-snapclass snapcontent-08727a8b-75f4-4b0b-b0d8-0b073e30cfc3 20h 20h</pre> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231208/20231208112408.png" width="807" height="207" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>さて、ではこのDataVolumeがいつ定義され作成されるのかというと、実はVirtualMachine CRを作成する際にDataVolumeTemplateとして設定が行われています。先ほどWindows Severを起動したyamlを見てみると以下のような記載となっています。</p> <pre class="code" data-lang="" data-unlink>apiVersion: kubevirt.io/v1 kind: VirtualMachine ---snip--- spec: dataVolumeTemplates: - apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: annotations: cdi.kubevirt.io/storage.bind.immediate.requested: &#39;true&#39; creationTimestamp: null name: win2k22-kvirt spec: source: blank: {} storage: resources: requests: storage: 30Gi - metadata: creationTimestamp: null name: win2k22-kvirt-installation-cdrom spec: source: http: url: &gt;- https://go.microsoft.com/fwlink/p/?LinkID=2195280&amp;clcid=0x411&amp;culture=ja-jp&amp;country=JP storage: resources: requests: storage: 30Gi</pre> <p><code>.spec.dataVolumeTemplates</code>の中に二つのDataVolume設定があり、一つは空のボリュームとして、もう一つがOSイメージをインストールするボリュームとしてGUIで入力したURLが記載されているのがわかります。 最初にVirtualMachine CRを作成するタイミングでこれらのDataVolumeも作成され一連のPVが準備されたのでした。</p> <h3 id="まとめ">まとめ</h3> <p>今回はOCP Virt上でWindows Serverを起動し、そこへのアクセスや、OSイメージをPVとして準備する仕組みについてご紹介しました。また別の記事にてOCP Virtに関する別のトピックについて紹介していきたいと思います。</p> jpishikawa libkrunで遊ぶ hatenablog://entry/6801883189065234835 2023-12-09T01:41:13+09:00 2023-12-14T09:45:23+09:00 Red Hatでコンサルタントをしている織です。本記事ではibkrunについて紹介します。Red Hat Advent Calender 2023の12/3のエントリです (だいぶ過ぎてますが、空いたままだったので急遽埋めました)。 libkrunについては、inductorさんによるKernel/VM探検隊online part2の講演が有名かもしれません。本記事(および続編...を書く予定です)では、別の観点でlibkrunをご紹介できればと思います。 libkrunとは libkrun とは動的ライブラリとして提供される仮想マシンモニター(VMM)です。とても簡単に言うと、このライブラリ… <p>Red Hatでコンサルタントをしている織です。本記事ではibkrunについて紹介します。Red Hat Advent Calender 2023の12/3のエントリです (だいぶ過ぎてますが、空いたままだったので急遽埋めました)。</p> <p>libkrunについては、inductorさんによる<a href="https://kernelvm.connpass.com/event/201059/">Kernel/VM探検隊online part2</a>の<a href="https://speakerdeck.com/inductor/i-wanted-to-understand-libkrun-but">講演</a>が有名かもしれません。本記事(および続編...を書く予定です)では、別の観点でlibkrunをご紹介できればと思います。</p> <h1 id="libkrunとは">libkrunとは</h1> <p><a href="https://github.com/containers/libkrun">libkrun</a> とは動的ライブラリとして提供される仮想マシンモニター(VMM)です。とても簡単に言うと、このライブラリを使うとプロセスをLinux KVMの仮想マシンとして隔離した状態で実行することができます。CのAPIを提供していますが、中の実装はほとんどRustで書かれています。Firecrackerやrust-vmmのコードも取り込んでいます。</p> <p>可能な限り軽量かつシンプルな実装を目指しており、使用している仮想デバイスも最小限です。</p> <ul> <li>virtio-console</li> <li>virtio-vsock (specialized for TSI, Transparent Socket Impersonation)</li> <li>virtio-fs</li> <li>virtio-baloon (only free-page reporting)</li> <li>virtio-rng</li> <li>virtio-block (for AMD SEV)</li> </ul> <h1 id="libkrunを動かしてみる">libkrunを動かしてみる</h1> <p>さっそく使ってみましょう。最近のFedoraだと、必要なコンポーネントは全てrpmで提供されています。以下の検証はFedora 38が稼働するノートPCで行いました。</p> <pre class="code" data-lang="" data-unlink>$ sudo dnf install -y libkrun libkrun-devel libkrunfw</pre> <p>最小限のコードは以下のような感じになります。</p> <pre class="code C" data-lang="C" data-unlink>#include &lt;libkrun.h&gt; void main() { char *const envp[] = {0}; int ctx_id = krun_create_ctx(); krun_set_vm_config(ctx_id, 1, 512); krun_set_root(ctx_id, &#34;rootfs&#34;); krun_set_exec(ctx_id, &#34;/bin/bash&#34;, 0, &amp;envp[0]); krun_start_enter(ctx_id); }</pre> <p><code>minimal.c</code> として保存し、コンパイルします。</p> <pre class="code" data-lang="" data-unlink>$ gcc -o minimal miniaml.c -lkrun</pre> <p><code>rootfs</code> というディレクトリを掘って、そこにLinuxとして稼働できる最小限のファイルツリーを作ります。まずはfedoraイメージでコンテナを実行します。</p> <pre class="code" data-lang="" data-unlink>$ podman run --name fedora fedora uname</pre> <p>コンテナのファイル群をrootfs以下にコピーします。</p> <pre class="code" data-lang="" data-unlink>$ mkdir rootfs $ podman export fedora | tar xf - -C rootfs</pre> <p>また、後の実験で使ういくつかのファイルもコピーしておきます。</p> <pre class="code" data-lang="" data-unlink>$ sudo cp /etc/resolv.conf ./rootfs/etc/ $ sudo cp /usr/sbin/ip ./rootfs/usr/sbin/ $ sudo cp /lib64/libbpf.so.1 ./rootfs/lib64/ $ sudo cp /lib64/libmnl.so.0 ./rootfs/lib64/</pre> <p>これで準備は整いました。libkrunをリンクした実行ファイル <code>minimal</code> を実行すると、rootfs以下のファイルを使って仮想マシンが作られ、その中でプロセスが起動します。</p> <pre class="code" data-lang="" data-unlink>$ ./minimal bash-5.2#</pre> <p>minimal.cの <code>krun_set_exec()</code> で呼び出したbashが起動しました。minimalの中では、Fedora 39 のコンテナイメージのファイルを使った仮想マシンが動いています。</p> <pre class="code" data-lang="" data-unlink>bash-5.2# cat /etc/fedora-release Fedora release 39 (Thirty Nine)</pre> <p>NICは何もついていません。</p> <pre class="code" data-lang="" data-unlink>bash-5.2# /usr/sbin/ip addr show 1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever</pre> <p>が、外と通信はできてしまいます。まずはminimalの中からインターネットにアクセスしてみます。</p> <pre class="code" data-lang="" data-unlink>bash-5.2# curl ftp.jaist.ac.jp lrwxrwxrwx 1 ftp ftp 17 Feb 15 2016 debian -&gt; pub/Linux/debian/ lrwxrwxrwx 1 ftp ftp 27 Feb 15 2016 debian-backports -&gt; pub/Linux/debian-backports/ lrwxrwxrwx 1 ftp ftp 20 Feb 15 2016 debian-cd -&gt; pub/Linux/debian-cd/ drwxr-xr-x 30 ftp ftp 32 May 16 2021 pub lrwxrwxrwx 1 ftp ftp 36 Feb 15 2016 raspbian -&gt; pub/Linux/raspbian-archive/raspbian/ lrwxrwxrwx 1 ftp ftp 17 Feb 15 2016 ubuntu -&gt; pub/Linux/ubuntu/</pre> <p>また、minimalを実行したKVMホストからminimalの中にアクセスしてみましょう。 まずはminimalの中で、ポート34000番でWebサーバを起動します。</p> <pre class="code" data-lang="" data-unlink>bash-5.2# python3 -m http.server 34000 Serving HTTP on 0.0.0.0 port 34000 (http://0.0.0.0:34000/) ...</pre> <p>次に別のターミナルを開き、KVMホストから該当ポートにアクセスします。</p> <pre class="code" data-lang="" data-unlink>$ curl localhost:34000 &lt;!DOCTYPE HTML&gt; &lt;html lang=&#34;en&#34;&gt; &lt;head&gt; &lt;meta charset=&#34;utf-8&#34;&gt; &lt;title&gt;Directory listing for /&lt;/title&gt; &lt;/head&gt; &lt;body&gt; ...</pre> <p>libkrunが外と通信する仕組みについては、<s>日を改めて紹介したいと思います</s> <a href="https://rheb.hatenablog.com/entry/libkrun-networking">こちら</a>に書きました。</p> <h1 id="Podmanのコンテナを仮想マシンで隔離して実行する">Podmanのコンテナを仮想マシンで隔離して実行する</h1> <p>最近のFedoraでは、Podmanを実行する際のOCIランタイムとしてcrunを使用します。crunは、コンテナ実行時に <code>run.oci.handler</code> というアノテーションが渡されると、その情報に応じて実行するハンドラを切り替える仕組みを持っています。この仕組みを使うことで、crunはコンテナを実行する際に、dlopen(3)でlibkrun.soをロードしlibkrunの仕組みを使ってコンテナプロセスを起動します。</p> <pre class="code" data-lang="" data-unlink>$ podman run -d \ -v /dev/kvm:/dev/kvm \ -p 8080:80 \ --annotation=run.oci.handler=krun \ --name nginx nginx</pre> <p>これで、nginxのコンテナがKVM仮想マシンの中に隔離された状態で起動しました。</p> <pre class="code" data-lang="" data-unlink>$ curl localhost:8080 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Welcome to nginx!&lt;/title&gt; &lt;style&gt; html { color-scheme: light dark; } ...</pre> <p>プロセスIDから見える情報を確認してみます。</p> <pre class="code" data-lang="" data-unlink>$ pid=$(podman inspect nginx | jq &#39;.[].State.Pid&#39;) $ ps -p ${pid} f PID TTY STAT TIME COMMAND 2839261 ? Ssl 0:01 [libcrun:krun] /docker-entrypoint.sh nginx -g daemon off;</pre> <p>なんとなくlibkrunを使って実行されている感があります。 このPIDで使用しているファイルディスクリプタを確認すると、実際KVM仮想マシン内で実行されていることを確認することができます。</p> <pre class="code" data-lang="" data-unlink>$ ls -l /proc/${pid}/fd | grep kvm lrwx------. 1 ori ori 64 Dec 9 01:24 19 -&gt; anon_inode:kvm-vm lrwx------. 1 ori ori 64 Dec 9 01:29 29 -&gt; anon_inode:kvm-vcpu:0 lrwx------. 1 ori ori 64 Dec 9 01:29 31 -&gt; anon_inode:kvm-vcpu:1 lrwx------. 1 ori ori 64 Dec 9 01:29 33 -&gt; anon_inode:kvm-vcpu:2 lrwx------. 1 ori ori 64 Dec 9 01:29 35 -&gt; anon_inode:kvm-vcpu:3 lrwx------. 1 ori ori 64 Dec 9 01:29 37 -&gt; anon_inode:kvm-vcpu:4 lrwx------. 1 ori ori 64 Dec 9 01:29 39 -&gt; anon_inode:kvm-vcpu:5 lrwx------. 1 ori ori 64 Dec 9 01:29 41 -&gt; anon_inode:kvm-vcpu:6 lrwx------. 1 ori ori 64 Dec 9 01:29 43 -&gt; anon_inode:kvm-vcpu:7</pre> orimanabu OpenShift AIで分散学習を試してみる hatenablog://entry/6801883189064527183 2023-12-08T08:34:28+09:00 2023-12-08T08:35:46+09:00 こんにちは、Red Hatでソリューションアーキテクトをしている石川です。 過去に何度かこのブログの中でOpenShift Data Scienceについて取り上げてきましたが、 直近のリリースバージョンであるv2.4から機械学習における分散学習を実現する機能がTech Previwとして追加されました。 access.redhat.com 今回はこちらの機能をデプロイしてみてどういった仕組みで分散学習を実現しているのか見ていきたいと思います。 なおTech Preview機能についての制約についてはこちらを参照下さい。 またプロダクトの正式名称がRed Hat OpenShift Data … <p>こんにちは、Red Hatでソリューションアーキテクトをしている石川です。</p> <p>過去に何度かこのブログの中でOpenShift Data Scienceについて取り上げてきましたが、 直近のリリースバージョンであるv2.4から機械学習における分散学習を実現する機能がTech Previwとして追加されました。 <cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/red_hat_openshift_data_science_self-managed/2.4/html-single/release_notes/index#technology-preview-features_relnotes">access.redhat.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fred_hat_openshift_data_science_self-managed%2F2.4%2Fhtml-single%2Frelease_notes%2Findex%23technology-preview-features_relnotes" title="2.4 リリースノート Red Hat OpenShift Data Science Self-managed 2.4 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <p>今回はこちらの機能をデプロイしてみてどういった仕組みで分散学習を実現しているのか見ていきたいと思います。 なおTech Preview機能についての制約については<a href="https://access.redhat.com/support/offerings/techpreview/">こちら</a>を参照下さい。</p> <p>またプロダクトの正式名称がRed Hat OpenShift Data Science(RHODS)からRed Hat OpenShift AI(RHOAI)に変更となりました。<br/> ドキュメントなどまだ直っていない部分もありますが今後はこちらの名称を使っていきたいと思います。</p> <p>そもそもRHOAIがどういった製品なのか、等については過去のブログにまとめてあるためこちらも合わせて参照下さい。</p> <p><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2023/02/20/234223">rheb.hatenablog.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2023%2F02%2F20%2F234223" title="OpenShift Data Scienceを使ってみよう - その1 - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><br/> <cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2023/03/20/165636">rheb.hatenablog.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2023%2F03%2F20%2F165636" title="OpenShift Data Scienceを使ってみよう - その2 - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><br/> <cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2023/07/20/222025">rheb.hatenablog.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2023%2F07%2F20%2F222025" title="OpenShift AIでAI/MLもOpenShiftにおまかせ! - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <h3 id="CodeFlare-Projectについて">CodeFlare Projectについて</h3> <p>分散学習に関する機能は<a href="https://github.com/project-codeflare/codeflare">CodeFlare</a>と呼ばれるOSSプロジェクトの中で開発が進められています。 CodeFlareプロジェクトには複数のコンポーネントで構成されます。<br/> ・CodeFlare SDK: Code Flareの各ツールをPythonで利用するためのSDK。<br/> ・MCAD: 学習のバッチ処理を行うためジョブのキューイングとディスパッチ。<br/> ・InstaScale: ジョブ要求に応じてオンデマンドにクラスタにGPUノードを追加。<br/> ・KubeRay: K8s上に分散処理を行うためのRayクラスタを構築。</p> <p>以下では順番を追って、インストール方法から各コンポーネントがどのように動作するのか見ていきたいと思います。</p> <h3 id="Operatorのインストール">Operatorのインストール</h3> <p>まずOpenShiftコンソールのOperatorHubより最新のOperatorをインストールします。<br/> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231206/20231206133759.png" width="893" height="452" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>CodeFlare関連の機能は最新のv2.4よりTPの対象となるため正しいバージョンをインストールできているか確認しましょう。</p> <p>Operatorのインストールが完了したら必要なコンポーネントをインストールするためDataScienceCluster(DSC) CRを作成します。 Operatorのバージョンがv1.xの時はKFDef CRを作成し、インストール対象のコンポーネントを選択していましたが、v2からはこのDSCにて設定するよう変更となりました。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231206/20231206133819.png" width="806" height="712" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>デフォルトの設定では<code>.spec.components.codeflare.managementState</code>がRemovedになっているため、画像の通りManagedに変更します。同じく<code>.spec.components.ray.managementState</code>についてもManagedとしましょう。</p> <p>設定したDSCを作成すると必要なコンポーネントがOpenShiftにインストールされます。</p> <h3 id="Ray-Clusterの定義と立ち上げ">Ray Clusterの定義と立ち上げ</h3> <p>CodeFalreでは分散学習用の基盤としてOSSの<a href="https://github.com/ray-project/ray">Ray</a>をOpenShift環境で立ち上げます。Rayは汎用的な分散処理を実現するOSSのフレームワークであり、複数のサーバーリソースをまとめることで、機械学習の各タスク(前処理、ハイパーパラメーターサーチ、学習、推論、等)における処理を効率化することが可能となります。</p> <p>Ray自体はコンテナ環境以外でも利用することが可能ですが、<a href="https://docs.ray.io/en/latest/cluster/kubernetes/index.html">KubeRay Operator</a>を利用することでKubernetes環境でも利用することができます。 CodeFlareを利用する場合、このKubeRay Operatorも自動でインストールされます。</p> <p>まずユーザーが行うことはCodeFlare SDKを使用し、必要なRay Clusterのリソースを定義することです。<br/> SDKについては<code>pip install codeflare-sdk</code>でインストールできます。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231206/20231206133945.png" width="765" height="410" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><br/> PythonスクリプトとしてRay Clusterの情報を定義し、その情報をMCADに対して送信します。 <a href="https://github.com/project-codeflare/codeflare-sdk/blob/main/demo-notebooks/guided-demos/0_basic_ray.ipynb">こちらのリポジトリ</a>にCodeFlareを試すためのサンプルNotebookファイルがあります。 以下はそこから一部抜粋、改変したコードとなります。</p> <pre class="code" data-lang="" data-unlink># CodeFlare SDKのインポート from codeflare_sdk.cluster.cluster import Cluster, ClusterConfiguration from codeflare_sdk.cluster.auth import TokenAuthentication # OpenShiftへのログイン情報定義とログイン auth = TokenAuthentication( token = &#34;SHA256...&#34;, # oc whoami -t の実行結果 server = &#34;https://api.sample.openshiftapps.com:6443&#34;, # OpenShift APIサーバーのURL skip_tls=False ) auth.login() # Ray Clusterの定義 cluster = Cluster(ClusterConfiguration( name=&#39;raytest&#39;, namespace=&#39;default&#39;, # Ray Clusterが立ち上がるNameSpace num_workers=2, # Ray Clusterを構成するWorker Podの数 # Rayの各Workerに割り当てるリソース (CPU/Memory/GPU) min_cpus=1, max_cpus=1, min_memory=4, max_memory=4, num_gpus=0, image=&#34;quay.io/project-codeflare/ray:latest-py39-cu118&#34;, # Worker Podのイメージ instascale=False # InstaScaleの利用有無 )) # Cluster情報のMCADへの送信 cluster.up() cluster.wait_ready() # 作成されたRay Clusterの表示 cluster.details()</pre> <p>SDKを通じてOpenShiftにログインし、clusterオブジェクトの中で必要なリソースの定義を行っています。 SDKの詳細な利用方法については以下のページを参照下さい。<br/> <cite class="hatena-citation"><a href="https://project-codeflare.github.io/codeflare-sdk/">project-codeflare.github.io</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fproject-codeflare.github.io%2Fcodeflare-sdk%2F" title="codeflare_sdk API documentation" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <p>ここからRay Clusterの立ち上げが開始します。 OpenShift内に先ほど定義したRay Clusterを立ち上げるのに十分なリソースがある場合、すぐに作成が始まりますが、そうでない場合Clusterの立ち上げリクエストはMCADの中でキューイングされた状態となります。 この時に活躍するのがCodeFlareのコンポーネントの一つであるInstaScaleです。 上記のコードの中でclusterオブジェクトの定義の中でInstaScaleを有効にすると不足するリソース分のNodeをOpenShiftクラスターに自動で追加することができます。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231206/20231206134012.png" width="789" height="405" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>Ray Clusterを作成するのに必要なWorker Nodeを動的にOpenShiftに追加し、ジョブ実行が完了したら追加したNodeを自動で削除することが可能となります。オンデマンドに追加Nodeを調達できるパブリッククラウド環境で有効な機能と言えるでしょう。</p> <p>RHOAIのv2.4ではInstaScaleがTPの対象機能となっていないため、ここでは概念の紹介のみに留めたいと思います。 <cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/red_hat_openshift_data_science_self-managed/2.4/html-single/working_on_data_science_projects/index#running-distributed-data-science-workloads-from-notebooks_distributed-workloads">access.redhat.com</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fred_hat_openshift_data_science_self-managed%2F2.4%2Fhtml-single%2Fworking_on_data_science_projects%2Findex%23running-distributed-data-science-workloads-from-notebooks_distributed-workloads" title="データサイエンスプロジェクトへの取り組み Red Hat OpenShift Data Science Self-managed 2.4 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <p>Ray Clusterが作成されると<code>cluster.details()</code>からUIへのアクセスが可能となります。 <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231206/20231206134033.png" width="652" height="353" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><br/> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231206/20231206134044.png" width="1200" height="508" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h3 id="分散学習の実行">分散学習の実行</h3> <p>作成したRay Clusterの上で学習を実行するには大きく2つの方法があります。<br/> a. CodeFlare SDKを通じてDDPJobを定義し実行する<br/> b. Rayライブラリを使用し学習を実行する<br/> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/j/jpishikawa/20231206/20231206134108.png" width="789" height="405" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>今回は一つ目のCode Flare SDKが提供する<code>DDPJobDefinition</code>クラスでジョブの定義を行います。 <a href="https://github.com/project-codeflare/codeflare-sdk/blob/main/demo-notebooks/guided-demos/2_basic_jobs.ipynb">こちらのNotebookファイル</a>からジョブの定義方法を見てみましょう。</p> <pre class="code" data-lang="" data-unlink>from codeflare_sdk.job.jobs import DDPJobDefinition # ジョブの定義 jobdef = DDPJobDefinition( name=&#34;mnisttest&#34;, script=&#34;mnist.py&#34;, # 学習実行用のスクリプト scheduler_args={&#34;requirements&#34;: &#34;requirements.txt&#34;} # 学習時の引数 ) # ジョブの実行 job = jobdef.submit(cluster)</pre> <p><code>DDPJobDefinition</code>の中で学習用のスクリプトであるmnist.pyと、Rayの各Worker Podで追加でインストールするライブラリをrequirements.txtとして渡しています。 これにより必要な依存関係のインストールを行なった上でジョブを実行します。</p> <p>DDPJobDefinitionではTorchXが提供するDDP(Distributed Data Parallel)の仕組みを活用しており、Ray Clusterの各Worker上にデータをシャードするデータパラレルな分散学習を実現します。<br/> <cite class="hatena-citation"><a href="https://pytorch.org/torchx/latest/components/distributed.html">pytorch.org</a></cite><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fpytorch.org%2Ftorchx%2Flatest%2Fcomponents%2Fdistributed.html" title="Distributed — PyTorch/TorchX main documentation" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe></p> <p>ジョブの実行状況についてはRayのダッシュボードや、<code>job.status()</code>により確認できます。 ジョブが完了したら<code>cluster.down()</code>にて作成したRay Clsuterを削除します。 これでCodeFalreを利用した分散学習の一連のプロセスが完了しました。</p> <p>もう一つの方法であるRayの提供するライブラリを利用する方法については、 <a href="https://github.com/project-codeflare/codeflare-sdk/blob/main/demo-notebooks/guided-demos/3_basic_interactive.ipynb">こちら</a>を参考にしてみて下さい。</p> <h3 id="まとめ">まとめ</h3> <p>今回はOpenShift AIでTech PreviewとなったCodeFlareによる分散学習についてご紹介しました。LLMをはじめとした大規模モデルの活用や、そのファインチューニングのニーズが増えるにつれ、こうした機能へのニーズはより高まってくると思われます。今後も機能のアップデートなど紹介していきたいと思います。</p> jpishikawa 今さら聞けない!? OpenShift4の多すぎるインストール方式をおさらいする hatenablog://entry/6801883189064304029 2023-12-07T17:53:17+09:00 2023-12-08T11:00:58+09:00 目次 目次 はじめに プラットフォーム まずはインストールするプラットフォームを選択する any platformとbaremetalの意味とちょっとした歴史的経緯 インストール方式 IPIとUPIは何が違うのか その他のインストール方式 SNO(Single Node OpenShift) Assisted Installer Agent-based installer インターネット非接続環境 インストールパターンと難易度について まとめ はじめに はじめまして、Red HatでOpenShift Container Platformのテクニカルサポートの野間です。Red Hat Adve… <h2 id="目次">目次</h2> <ul class="table-of-contents"> <li><a href="#目次">目次</a></li> <li><a href="#はじめに">はじめに</a></li> <li><a href="#プラットフォーム">プラットフォーム</a><ul> <li><a href="#まずはインストールするプラットフォームを選択する">まずはインストールするプラットフォームを選択する</a></li> <li><a href="#any-platformとbaremetalの意味とちょっとした歴史的経緯">any platformとbaremetalの意味とちょっとした歴史的経緯</a></li> </ul> </li> <li><a href="#インストール方式">インストール方式</a><ul> <li><a href="#IPIとUPIは何が違うのか">IPIとUPIは何が違うのか</a></li> <li><a href="#その他のインストール方式">その他のインストール方式</a><ul> <li><a href="#SNOSingle-Node-OpenShift">SNO(Single Node OpenShift)</a></li> <li><a href="#Assisted-Installer">Assisted Installer</a></li> <li><a href="#Agent-based-installer">Agent-based installer</a></li> </ul> </li> </ul> </li> <li><a href="#インターネット非接続環境">インターネット非接続環境</a></li> <li><a href="#インストールパターンと難易度について">インストールパターンと難易度について</a></li> <li><a href="#まとめ">まとめ</a></li> </ul> <h2 id="はじめに">はじめに</h2> <p>はじめまして、Red HatでOpenShift Container Platformのテクニカルサポートの野間です。<a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar 2023</a> の12/7の記事になります。別で<a href="https://qiita.com/advent-calendar/2023/openshift">OpenShift Advent Calendar 2023</a> もありますね、どちらも楽しんでください。</p> <p>OCP4.1がGAされた2019年に入社し、この製品と4年をともに過ごしました。現在ではマイナーバージョンも4.14まで更新され、あわせてインストール可能なプラットフォームやインストール方式も増えました。製品も成長したなあ、とふと<a href="https://docs.openshift.com/container-platform/4.14/installing/index.html">公式ドキュメントのinstallingの項目</a>を確認すると、、、ぶっちゃけ多すぎて読む気なくしません?同じ内容で日本語訳も読める<a href="https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.14/html/installing/index">こちらのドキュメントページ</a>ではsingle-pageでの表示もできるのですが、インストールのページをsingle-pageで開くと、量が多すぎて私のPCのブラウザが固まります。試してみる場合は注意してください。</p> <p>ソフトウェア利用の最初の一歩であるインストールがこんなに複雑ではやる気がなくなってしまいます。とうわけでユーザーが少しでも回れ右をしないように、必要な前提知識を整理してみます。</p> <h2 id="プラットフォーム">プラットフォーム</h2> <h3 id="まずはインストールするプラットフォームを選択する">まずはインストールするプラットフォームを選択する</h3> <p>プラットフォームを決定しないことには始まらないので、まずプラットフォームを選択しましょう。4.14時点でOpenShiftはAWS、Azure、vShereなど<a href="https://docs.openshift.com/container-platform/4.14/installing/index.html#supported-platforms-for-openshift-clusters_ocp-installation-overview">10のプラットフォーム</a>をサポートしています。</p> <p>インストールドキュメントが肥大化している一番の理由は、実はプラットフォーム毎に手順が存在しているためです。よく読むと、それぞれのプラットフォーム独自の手順以外は、同じ内容が記載されています。ひとつのプラットフォームを選択したら、ほかの手順は読む必要はありませんので、ドキュメントボリュームに気後れする必要はありません。</p> <h3 id="any-platformとbaremetalの意味とちょっとした歴史的経緯">any platformとbaremetalの意味とちょっとした歴史的経緯</h3> <p>プラットフォームのany platformとbaremetalについて補足します。any platform(日本語ドキュメントでは「任意のプラットフォーム」)はその名前の通りプラットフォームを選ばないインストール方法です。たとえばvSphereのVMをany platform方式でインストールしたり、もしくはドキュメントに記載のないプラットフォームに使うことができます。昔はbaremetalとして記載されていたのですが、仮想環境でも使用できることから正確性のために、4.6からany platformに変更されました。以降のbaremetalは、名称のとおり物理サーバーを想定した方法になっています。そのような経緯から今も混同されていることがありますので、注意してください。</p> <h2 id="インストール方式">インストール方式</h2> <h3 id="IPIとUPIは何が違うのか">IPIとUPIは何が違うのか</h3> <p>もっともスタンダードなインストール方式はIPI(Installer Provisioned Infrastructure)とUPI(User Provisioned Infrastructure)の2種類です。凄くザツに説明すると、「自動でおまかせ」モードと「イチからDIY」モードです。</p> <p>IPIでは、インストーラーにinstall-config.yamlファイルを読み込ませるだけで済みます。この方法では、必要なインフラをプラットフォームの機能と連携して自動的に構成します。例えばAWSでIPIを使用すると、ノード(EC2)はもちろん、Route 53のレコード登録やネットワークも作成してくれます。インストール後も引き続きプラットフォームと連携するため、OpenShiftの機能をフル利用できる構成です。</p> <p>UPIは基本的にインフラをユーザー側で用意して構成します。そのため当然ですがIPIと比べて手間や知識が必要となります。利点は、IPIでは構成できない細かいカスタマイズが可能になるという点です。そのため、基本的にはIPIで構成し、譲歩できないカスタマイズ要件が存在するユースケースではUPIを使う選択が一般的かと思います。インストールの簡単さとカスタマイズ性はトレードオフになると考えています。</p> <h3 id="その他のインストール方式">その他のインストール方式</h3> <p>IPIとUPI以外の以下のインストール手順はドキュメントは、プラットフォームに関わらず独立した項目になっています。下記の説明とともにリンクをご覧ください。</p> <h4 id="SNOSingle-Node-OpenShift"><a href="https://docs.openshift.com/container-platform/4.14/installing/installing_sno/install-sno-preparing-to-install-sno.html">SNO(Single Node OpenShift)</a></h4> <p>基本的には複数のノードで構成することが通常のOpenShiftですが、なんと一台でも作れてしまいます。想定されるユースケースは通信事業系のエッジコンピューティングや、導入として小さいリソースで検証するような場合です。当然ですが一台なのでHA(高可用性)機能は切り捨てられています。サポートされるプラットフォームなどに制限があるため、条件についてはドキュメントのRequirementsをご覧ください。</p> <h4 id="Assisted-Installer"><a href="https://docs.openshift.com/container-platform/4.14/installing/installing_on_prem_assisted/installing-on-prem-assisted.html">Assisted Installer</a></h4> <p>オンプレミス環境限定となりますが、Web上で対話式で設定できる支援サービスによりインストールできます。もう一つの利点ですが、bootstrap nodeが必要ありません。そのため、オンプレミス環境で課題となりがちなbootstrap用のリソース確保が不要となります。また、前述のSNOも構成できます。</p> <h4 id="Agent-based-installer"><a href="https://docs.openshift.com/container-platform/4.14/installing/installing_with_agent_based_installer/preparing-to-install-with-agent-based-installer.html">Agent-based installer</a></h4> <p>Assisted Installerは素晴らしい、しかし僕らが求めているオンプレ環境はインターネットに接続しないクローズド環境なんだ、というあなたにはAgent-based installerがあります。bootstrap不要、 SNOにも対応というAssitsted Installerの利点をいかしつつも、CLIで完全ローカルに構成することができます。比較的新しいインストール方式で4.12からGAとなっており、まだまだ機能強化が予定されています。</p> <h2 id="インターネット非接続環境">インターネット非接続環境</h2> <p>Agent-basedでも少し触れましたが、インターネットに接続しない閉じられたネットワーク環境での構成、つまり「インターネット非接続環境」が求められるケースがあります。英文ドキュメントやナレッジではdisconnected network、 restricted network もしくはair-gapped networkと呼ばれることもあります。</p> <p>IPIやUPIでも可能であり、各プラットフォームの項目に restricted network として別項で手順が記載されています。ただ、これだけでは手順は不足しており、事前にミラーレジストリホストを準備しておく必要があります。通常はクラスタがイメージなどのコンテンツをインターネットから取得するため、その代替をネットワーク内に構築する必要があるということです。ミラーの作成方法は幾通りかあるため<a href="https://docs.openshift.com/container-platform/4.14/installing/disconnected_install/index.html">ドキュメントのDisconnected installation mirroringの項目</a>を確認し作成してください。</p> <h2 id="インストールパターンと難易度について">インストールパターンと難易度について</h2> <p>インストールについての一通りを説明しましたが、組み合わせることでパターンは無数に存在します。選択肢が多いことはよいことですが、インストールの難易度(手間や事前知識)に差があることも留意してください。</p> <p>例えばAWSのようなクラウドプロバイダープラットフォームのIPIであればinstallerをダウンロードし、install-config.yamlを作成し実行するだけです。作業自体は慣れれば10分もかかりません。しかし、any platform方式のインターネット非接続環境となると、ユーザーがノードやネットワークおよびミラーレジストリホストを構築する必要があり、事前知識や手間が大きく異なります。あまり事例の無い組み合わせのレアなユースケースの場合は、蓄積されたナレッジも少ないため思わぬ落とし穴にはまるかもしれません。もちろん構成の選定はシステムの要件が基になるべきですが、まずは簡素な構成/方式からステップアップしていくことをおすすめいたします。</p> <h2 id="まとめ">まとめ</h2> <ul> <li><p>まずはサポートされているプラットフォームを選ぼう</p></li> <li><p>次にインストール方式を選ぼう。簡単なのはIPI、カスタマイズしたいならUPI。その他の方式も選べるよ</p></li> <li><p>インストール方式で手間や事前知識は大きく異なるので、例えばインターネット非接続環境のような条件付き構成は難易度が高くなることに注意しよう</p></li> </ul> rnoma4696 パブリッククラウド上の従量課金制RHELをRed Hat Satelliteで管理してみよう hatenablog://entry/6801883189064498232 2023-12-07T13:41:51+09:00 2023-12-09T09:35:45+09:00 Red Hat Advent Calendar 2023の12/6の記事です。 Red Hatの小島です。 AWS/Azure/GCPなどのパブリッククラウド上で提供している従量課金制のRHELには、Red Hat Satelliteで管理するためのサブスクリプションが含まれているため、無料でRed Hat Satelliteを利用できるようになっています。本記事では、Red Hat Satelliteでこれら従量課金制のRHELを管理するためのポイントをご紹介します。 前置き Red Hat Satelliteのサブスクリプション Red Hat Satellite利用時のポイント Exte… <p><a href="https://qiita.com/advent-calendar/2023/redhat">Red Hat Advent Calendar 2023</a>の12/6の記事です。</p> <p>Red Hatの小島です。<br> AWS/Azure/GCPなどのパブリッククラウド上で提供している従量課金制のRHELには、Red Hat Satelliteで管理するためのサブスクリプションが含まれているため、無料でRed Hat Satelliteを利用できるようになっています。本記事では、Red Hat Satelliteでこれら従量課金制のRHELを管理するためのポイントをご紹介します。</p> <ul class="table-of-contents"> <li><a href="#前置き">前置き</a></li> <li><a href="#Red-Hat-Satelliteのサブスクリプション">Red Hat Satelliteのサブスクリプション</a></li> <li><a href="#Red-Hat-Satellite利用時のポイント">Red Hat Satellite利用時のポイント</a></li> <li><a href="#Extended-Update-Support-EUSの利用">Extended Update Support (EUS)の利用</a></li> <li><a href="#参考情報">参考情報</a></li> </ul> <h5 id="前置き">前置き</h5> <p>AWS/Azure/GCPなどのパブリッククラウド上で提供される従量課金制のRHELを利用する場合、RHELを提供している各クラウドベンダーが運用している<a href="https://access.redhat.com/products/red-hat-update-infrastructure/">Red Hat Update Infrastructure (RHUI)</a>という、クラウド環境専用のRHELリポジトリを参照してRHELのパッケージのダウンロード/インストール/アップデートができるように予め設定されています。そのため、利用者は、クラウドベンダーが運用するRHUI経由でRHELパッケージを参照することが基本となります。</p> <p>ただし、RHUIを利用してRHELのパッケージ管理をする場合、以下のような要件に対応するための標準機能はありません。</p> <ul> <li>予めテスト済みのパッケージを利用させるための、特定の日時におけるパッケージリポジトリのスナップショット作成</li> <li>グループ化されたRHELサーバーを対象とした、一括アップデート</li> </ul> <p>これらの要件に対応させるためには、RHELなどのパッケージリポジトリ管理やリモート実行機能を持つRed Hat Satelliteを使ったRHELの管理が効果的となります。Red Hat Satelliteを使ったRHELのアップデートの概要については、下記の記事をご参照ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2F2018%2F10%2F30%2FRed_Hat_Enterprise_Linux%25E3%2582%2592%25E5%25AE%259A%25E6%259C%259F%25E7%259A%2584%25E3%2581%25AB%25E3%2582%25A2%25E3%2583%2583%25E3%2583%2597%25E3%2583%2587%25E3%2583%25BC%25E3%2583%2588%25E3%2581%2599%25E3%2582%258B" title="Red Hat Enterprise Linuxを定期的にアップデートする - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/2018/10/30/Red_Hat_Enterprise_Linux%E3%82%92%E5%AE%9A%E6%9C%9F%E7%9A%84%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B">rheb.hatenablog.com</a></cite></p> <h5 id="Red-Hat-Satelliteのサブスクリプション">Red Hat Satelliteのサブスクリプション</h5> <p>従量課金制のRHELを利用する環境でRed Hat Satelliteを利用したい場合、Red Hat SatelliteのサブスクリプションをRed Hatにリクエストします。このとき、Red Hatのアカウントを持っていなければ、<a href="https://access.redhat.com/">Red Hatのカスタマーポータル</a>からRed Hatアカウントを無料で作成していただき、作成いただいたRed HatアカウントにRed Hat Satelliteのサブスクリプションを紐づけることになります。</p> <p>Red Hat Satellitenのサブスクリプションのリクエスト先は、<a href="https://www.redhat.com/ja/contact/customer-service">Red Hatカスタマーサービス</a>となります。Red Hat カスタマーサービスでは、Red Hatのアカウントや請求、登録、サブスクリプション関連のお問い合わせに対応しています。</p> <p>これによって、「Red Hat Satellite Infrastructure Subscription」というRed Hat Satellite専用のサブスクリプションが割り当てられます。このサブスクリプションには、Red Hat Satelliteだけでなく、Red Hat Satelliteを実行するための専用のRHELサブスクリプションも含みます。このサブスクリプションを入手することで、Red Hat SatelliteをRHELにインストールして使うことができるようになるほかに、Red Hatがカスタマーポータル上で提供しているナレッジベースも見ることができるようになります。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/h-kojima/20231207/20231207192057.png" width="1060" height="928" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h5 id="Red-Hat-Satellite利用時のポイント">Red Hat Satellite利用時のポイント</h5> <p>Red Hat Satelliteをクラウド環境で利用する場合、DHCPサービスを利用したPXEによるプロビジョニングは利用不可などの制限事項があります。こうした情報については、AWSやAzure上でのRed Hat Satelliteデプロイガイドをご参照ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fred_hat_satellite%2F6.14%2Fhtml-single%2Fdeploying_red_hat_satellite_on_amazon_web_services%2Findex" title="Amazon Web Services への Red Hat Satellite のデプロイ Red Hat Satellite 6.14 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/red_hat_satellite/6.14/html-single/deploying_red_hat_satellite_on_amazon_web_services/index">access.redhat.com</a></cite></p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Farticles%2F4237261" title="Deploying Red Hat Satellite on Microsoft Azure - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/articles/4237261">access.redhat.com</a></cite></p> <p>Red Hat Satelliteで従量課金制のRHELを管理する場合、Simple Content Access (SCA)を有効にする必要があります。SCAはサブスクリプションの利用を簡単にするために、サブスクリプションの必要本数を管理・強制する機能が失われるオプションです。SCAによって、従量課金制のRHELサーバーに(Red Hatが発行する)RHELのサブスクリプションを都度割り当てることなく、Red Hat Satelliteで管理できるようになります。SCAは、Red Hatアカウントを新しく作るときはデフォルトで有効になっています。</p> <p>昔からRed Hatアカウントを持っていて、SCAが有効になっていない場合は、<a href="https://access.redhat.com/management">Red Hat Subscription Management</a>から有効にできます。また、Red Hat SattelliteにRed Hatサブスクリプションをインポートして、RHELなどのパッケージをRed HatのCDNからダウンロードするために利用するマニフェストでも、<a href="https://access.redhat.com/documentation/ja-jp/subscription_central/2023/html-single/creating_and_managing_manifests_for_a_connected_satellite_server/index#proc-setting-simple-content-access-console">SCAはデフォルトで有効</a>になっています。そのため、今から従量課金制のRHELを作って、Red Hat Satelliteで管理しようとする場合、SCAの設定について特に変更する必要はありません。</p> <p>SCAについては、下記のブログもご参照ください。 <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Frheb.hatenablog.com%2Fentry%2Fsimple-content-access" title="Simple Content Accessでサブスクリプション管理を簡単にしたい - 赤帽エンジニアブログ" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://rheb.hatenablog.com/entry/simple-content-access">rheb.hatenablog.com</a></cite></p> <p>Red Hat Satelliteが提供するRHELリポジトリだけを利用させる場合、従量課金制のRHELがRHUIを利用するための設定を削除しておきます。この設定は、各クラウドベンダーが提供するパッケージによってインストールされている場合、<code>yum remove</code>コマンドで削除できます。RHUIを利用する設定に戻すときのことも考えて、これらのパッケージを予め<code>yum download</code>コマンドでダウンロードしておいてもいいでしょう。AWS/Azure/GCPの場合の例を記載しておきます。</p> <p>AWS</p> <pre class="code" data-lang="" data-unlink>$ sudo yum download rh-amazon-rhui-client $ sudo yum remove rh-amazon-rhui-client</pre> <p>Azure (XにはRHELのメジャーリリースの番号(7, 8, 9など)が入ります)</p> <pre class="code" data-lang="" data-unlink>$ sudo yum download rhui-azure-rhelX $ sudo yum remove rhui-azure-rhelX</pre> <p>GCP (XにはRHELのメジャーリリースの番号(7, 8, 9など)が入ります)</p> <pre class="code" data-lang="" data-unlink>$ sudo yum download google-rhui-client-rhelX $ sudo yum remove google-rhui-client-rhelX</pre> <p>また、これらのRHELをRed Hat Satelliteに登録して利用する際に、RHELのSubscription Managerによってリポジトリ設定が無効化されているため、Red Hat Satelliteのリポジトリ利用が有効にならない場合があります。このときは、<code>subscription-manager</code>コマンドを利用して、リポジトリ設定を有効化します。</p> <pre class="code" data-lang="" data-unlink>$ sudo subscription-manager config --rhsm.manage_repos=1</pre> <p>なお、Red Hat SatelliteがRed Hat CDNからダウンロードするRHELパッケージと、RHUI経由でダウンロードできるRHELパッケージは同じものです。Red Hatは<a href="https://access.redhat.com/downloads/content/package-browser">パッケージブラウザのWebページ</a>で各RHELパッケージのSHA-256を公開しているため、それらの値と<code>sha256sum</code>コマンドの実行結果を照らし合わせることで確認できるようになっています。</p> <pre class="code" data-lang="" data-unlink>$ sha256sum XXX.rpm</pre> <p>そのため、クラウドベンダーがRHUI経由でダウンロードできるようにしているRHELパッケージについては、Red Hat Satellite経由でダウンロードして利用したとしても、クラウドベンダーのサポートを受けることができます。Red Hat Satelliteを利用する環境でのユースケースについて、問い合わせ先は下記のようになります。</p> <ul> <li>問い合わせ先が<b>クラウドベンダー</b>: <br> クラウドベンダーが提供するRHELと、RHUI経由で提供しているパッケージのインストール/利用/設定</li> <li>問い合わせ先が<b>Red Hat</b>: <br> Red Hat Satelliteのインストール/利用/設定やRed Hat SatelliteへのRHEL登録</li> </ul> <h5 id="Extended-Update-Support-EUSの利用">Extended Update Support (EUS)の利用</h5> <p>2023年12月時点では、AWSとAzureの従量課金制RHELには、RHEL8.8やRHEL9.2など特定のマイナーリリースにおいて<a href="https://access.redhat.com/ja/articles/3055941">EUS</a>という延長サポートが無料で利用できるようになっています。GCPの従量課金制RHELにはEUSは付いていません。EUSを利用することで、マイナーリリース間のアップグレード頻度を下げて、アプリケーションのテスト期間を十分に取ることができるようになります。</p> <p>AWSやAzureのRHEL EUSの利用方法については、下記をご参照ください。なお、AWSについては、2023年12月時点でRHEL8.6, 8.8, 9.0, 9.2のEUSが利用できるようになっています。RHEL7のEUSについてはすでに終了していますので、ご注意ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fja%2Fsolutions%2F7032598" title="AWS EC2 PAYG インスタンスで EUS リポジトリーをサブスクライブできない - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/ja/solutions/7032598">access.redhat.com</a></cite></p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Fazure%2Fvirtual-machines%2Fworkloads%2Fredhat%2Fredhat-rhui" title="Red Hat Update Infrastructure - Azure Virtual Machines" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://learn.microsoft.com/ja-jp/azure/virtual-machines/workloads/redhat/redhat-rhui">learn.microsoft.com</a></cite></p> <p>一方で、従量課金制のRHELユーザーが利用できるRed Hat Satelliteのマニフェストには、RHELのEUSは含まれていません。そのため、Red Hat SatelliteがRed Hat CDNからダウンロードできないようになっています。EUSのパッケージをRed Hat Satellite上のリポジトリとして利用できるようにするには、手元にダウンロードしたEUSのパッケージをRed Hat Satelliteにインポートするといった工夫が必要になってきます。</p> <p>上記のガイドに従って利用できるようにしたRHEL EUSのリポジトリについては、<code>reposync</code>コマンドで丸ごとダウンロードできます。<code>--download-metadata</code>オプションを指定することで、<a href="https://access.redhat.com/ja/articles/2280941">エラータ</a>などのメタデータもダウンロードします。下記は、RHEL9 EUSリポジトリを有効化したAWS上のRHEL9サーバーで、RHEL9 EUSのBaseOS, AppStreamリポジトリのパッケージをダウンロードする<code>reposync</code>コマンドの実行例です。</p> <pre class="code" data-lang="" data-unlink>$ sudo reposync -p &lt;ダウンロード先となるディレクトリのPATH&gt; --download-metadata \ --repoid=rhel-9-baseos-eus-rhui-rpms --repoid=rhel-9-appstream-eus-rhui-rpms</pre> <p>reposyncについては、下記のナレッジもご参照ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fja%2Fsolutions%2F7033793" title="Satellite サーバーを使用せずに Red Hat Enterprise Linux 8 および 9 の最新アップデートのローカルミラーを作成する方法 - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/ja/solutions/7033793">access.redhat.com</a></cite></p> <p>これによって、「rhel-9-baseos-eus-rhui-rpms」と「rhel-9-appstream-eus-rhui-rpms」ディレクトリが作成され、その中に、EUSリポジトリに含まれるパッケージとメタデータが保存されます。これらのディレクトリをRed Hat Satelliteにインポートして、EUSのリポジトリとして作成します。この場合、Red Hat SatelliteではカスタムRPMリポジトリとして扱われます。インポートには、パッケージの手動アップロードのほかに、外部リポジトリのURLとして<code>http(s)://</code>と<code>file://</code>を指定する方法があります。<code>file://</code>を指定する場合は、Red Hat Satelliteサーバーの<code>/var/lib/pulp/sync_imports/</code>ディレクトリーの下に「rhel-9-baseos-eus-rhui-rpms」と「rhel-9-appstream-eus-rhui-rpms」ディレクトリをコピーしておく必要があります。</p> <p>これらの具体的な手順については、下記をご参照ください。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fred_hat_satellite%2F6.14%2Fhtml-single%2Fmanaging_content%2Findex%23Importing_Content_content-management" title="コンテンツの管理 Red Hat Satellite 6.14 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/red_hat_satellite/6.14/html-single/managing_content/index#Importing_Content_content-management">access.redhat.com</a></cite></p> <p>このようにリポジトリを作成してRed Hat Satellite上で公開し、RHELをRed Hat Satelliteに登録すると、Red Hat Satellite上で登録したRHELの情報(インストール済みのパッケージや、インストール可能な更新パッケージなど)が確認できるようになり、グループ化されたRHELサーバーへの一括アップデートのリモート実行もできるようになります。これらの具体的な手順については、「参考情報」に記載しているRed Hat Satelliteのドキュメントをご参照ください。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/h/h-kojima/20231207/20231207191907.png" width="1200" height="472" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <h5 id="参考情報">参考情報</h5> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fja%2Fsolutions%2F7045559" title="Satellite Server を使用して PAYG On-Demand イメージを管理できますか? - Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/ja/solutions/7045559">access.redhat.com</a></cite></p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fja-jp%2Fred_hat_satellite" title="Product Documentation for Red Hat Satellite 6.14 | Red Hat Customer Portal" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://access.redhat.com/documentation/ja-jp/red_hat_satellite">access.redhat.com</a></cite></p> h-kojima