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

TECH PLAY

Red Hat  - Open Innovation Labs

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

全900件

みなさんこんにちは。レッドハットの杉村です。Ansible のテクニカルサポートをしています。 先日公開しましたこの記事なのですが、反響が思いのほか大きく、多くのご意見をいただきました。さまざまな立場の方に見ていただいていることを忘れ、配慮に欠けた表現がありましたことをお詫びします。内容としましても不正確な部分が含まれておりましたので、改めて修正したものを再度公開します。 毎日世界中からさまざまな問い合わせを受けている中での経験なのですが、「思ったように動かない」ときの原因としては、例えばこのような設定に起因することが多く見受けられます。 ファイアウォールで必要なポートを閉じている 権限をデフォルト値から変えている 必要な設定ファイルを書き換えている サポートされない組み合わせで使っている リソースが足りていないのに無理矢理動かしている 正常な動作を阻害する可能性のあるサービスを稼働させている などなどです。 製品を導入して実行していただく環境はお客さまによってさまざまで、制約もそれぞれ異なるものがあります。その制約に適合するように設定を変更して運用いただくことは自由に実施していただけますが、製品サポートの立場から見ますと、その設定では動かないこともありますねという場合があります。もちろん製品自体に不具合があって動かない可能性もありますので、再現して解決策を早期に提示できるよう、問題の切り分けのためにご協力をお願いすることがあります。 推奨する設定から変更される場合にご不安なことがありましたら、あらかじめご相談いただけますと運用時にトラブルを起こす可能性を軽減させることができます。 テクニカルサポートの範囲 運用を進めていきますと想定しないことが多く起こるものです。テクニカルサポートは、インストール時や運用中に発生した不具合の調査や解決を目的としています。 わたしが担当する製品の Ansible のテクニカルサポートで対応する範囲については、こちらでご案内しています。他の製品でも同じようなドキュメントを用意しています。 access.redhat.com access.redhat.com access.redhat.com このテクニカルサポートの範囲に限らず、レッドハットでは、お困りごとの内容に応じてさまざまな受付窓口を用意して対応しています。 Ansible のテクニカルサポートが対応する範囲外のこととして比較的多くいただくのは playbook の書き方やデバッグについてのお問い合わせなのですが、テクニカルサポートではお手伝いすることができません。状況によってはラーニングサービスをお勧めしています。RHCE をはじめ、Ansible のラーニングコースも目的に応じて用意しておりますのでご検討ください。 www.redhat.com また、システム設計時の検討のために必要なこととして製品全体の仕様確認や、ドキュメントに掲載している内容の解説を求められることがありますが、導入される前段階でのお客さま固有の事情を加味した設計支援については、コンサルティングサービスをご案内しています。他には、お客さまの運用標準に適合するために例えば設定項目を羅列して Excel 表に穴埋めしてほしいということや、バージョンごとの差分を列挙してそれぞれ解説してほしいというご要望を受けることがありますが、テクニカルサポートは作業のお手伝いはできませんので、こちらも合わせてコンサルティングサービスのご利用を検討いただくようご案内しています。 www.redhat.com お客さまの場面や状況に応じまして専門の担当者がそれぞれの範囲をカバーしていますので、詳しくは営業にご相談ください。 プリセールス: ご購入前のお問い合わせ コンサルティングサービス: お客さま固有の課題を含めた製品の活用を支援 テクニカルサポート: インストール時や運用中に発生した不具合の調査や解決 ラーニングサービス: 製品の学習 問い合わせをする前に 特に海外のお客さまからは「動かない!電話してくれ!zoom のURLはここだ!重要度は1だ!!」とだけお知らせいただくこともあるのですが、では一緒に見てみましょうとすぐ立ち向かっても、なかなかすぐには問題解決に結びつきません。 どのOS上でどのバージョンをどのような構成で稼働させているのか、何を操作したときに動かなくなったのか、環境の問題なのか設定の問題なのか、もしくは動かそうとしているジョブに問題があったのかなど、数多くの想定される原因を分析する必要があり、切迫された状況の中でリアルタイムに情報を収集して解決に導くということは容易ではありません。 初動を早めるために、お客さま独自のそういった稼働状況を熟知した専門の担当者をTAMとしてご契約いただくこともできます。普段の運用状況を定期的にご共有いただくことで問題が発生したときの迅速な対応ができたり、お客さまの目的に合った製品についてのご案内を提供したりなど、さまざまな利点がありますのでご検討ください。 www.redhat.com TAM のご契約がない場合には、我々テクニカルサポートエンジニアが直接対応します。幸いにも Ansible は世界中の非常に多くのお客さまに導入いただいておりまして、さまざまな構成や状況で稼働しています。バージョンによっても問題の絞り込み方が異なるものもありますので、まずは基本的な情報収集から着手します。 Ansible Tower の場合ですと、まずは基本的な API を呼び出していただいて構成状況の把握から始めます。例えば2月に書きましたこちらの記事のように、申告いただいた問題に応じて必要な情報の収集をお願いしています。 rheb.hatenablog.com 上の記事でも触れておりますが、ログやプロセスなどの情報を取得するために、RHEL に付属する sosreport を求めることもあります。これは OS に関するさまざまな情報を収集して一つのアーカイブにまとめてくれるものです。どんなものが収集されて、サポートエンジニアは何をまず見ているのかということにご興味あれば、お手元の検証環境で一度お手元で実行してみてください。Ansible Tower を導入されている場合での実行では大きな問題となる可能性は低いのですが、他の製品では状況によって多くのリソースを消費することがあると聞いていますので、お試しされる際には安全な環境で実施いただくことをお勧めします。 access.redhat.com 製品の仕様を理解されているお客さまですと、ある程度特定されたログやスクリーンショットを共有いただいて問題を追跡していくこともあります。問題が発生しているときにはログレベルを変更したいこともよくあることだと思いますので、そのようなエラーメッセージはどこに出力されるのか、より冗長なメッセージを出力するにはどうするのがよいかというお問い合わせもよくいただきます。 Ansible Tower の場合ですと、まずはこのあたりのファイルを見ていきます。 /var/log/tower/*.log /var/log/supervisor/*.log /var/log/nginx/*.log エラーメッセージが出ることがわかっているのであればあらかじめ網羅しておいてキーワードを決めて監視したいという要望もあります。しかしながら、多くの要素が複雑に関連している現代のソフトウェアにおいては、厳密にエラーメッセージを網羅することは現実的に不可能です。サービスとして全体を捉え、個別の事象を深く追跡することよりも、問題が発生した後の修復を行う方法を確立していくほうが価値が高い場合もあります。 また、エラーメッセージは通常は英語で表示されます。特に日本ではログをご提供いただくことが難しいお客様もいらっしゃいまして手で書き写されてくることもあるのですが、その際に綴りが正しくないものをいただくこともありまして、問題の理解に非常に時間を要します。平易な英語で書かれておりますので、お伝えいただくにしても何が書かれているかをご自身でも読み取っていただくことをまずお勧めします。画像ファイルや Excel 表などに加工せず、できるだけログファイルを直接そのままいただけたほうが問題解決にスムーズにつながりますので、ご協力いただけましたら幸いです。 製品の動作要件 運用のルールはそれぞれのお客さまごとに秘伝のタレのようになっていることも多く、製品の仕様や世の中の標準が随時アップデートされていくという中であっても、さまざまな制約を受けて一度決めた方法をそのまま踏襲していくということが行われている場合があります。 一般に製品を利用する場合には出荷時そのままの設定で使うことがもっともリスクが低く、独自に設定を変更していくことで問題が発生したときの追跡がどんどん困難になります。 具体的には、例えば「RHEL 7.4 を使うこと」と会社標準で決めてしまっている場合に、3年経ってもその標準をアップデートしなかったために、現在サポート対象となっている製品を動作させることができないということがありました。他にも、umask 0022 で使ってくださいとマニュアルに記載しているにもかかわらず、ルールとして適合しないからと umask 0077 などで利用されているために思いがけず動作しなくなるということもあります。そのような制約としては各お客さまの運用ルールや各国の法律、サブスクリプションの費用やクラウドサービスの運用費用の節約など、さまざまな要素を複雑に検討して決められていることが多いようです。 そのような事情があることは理解しておりますが Ansible はほかの製品と比べますと非常にライフサイクルが速く、ほぼ毎年アップデートしていくことをお願いしています。さらに、リリースノートには記載しておりますが、次期メジャーバージョンの Ansible Automation Platform は RHEL 7 では動作しないものとなる予定です。Ansible は普段運用されているシステムの外から制御対象に対して SSH 等で接続して自動化を行うものですので、Ansible だけでも速いライフサイクルに沿ってアップデートを見据えた運用をされることをお勧めします。 新しいものに追随しながらサービスを安定稼働させるためには、商用環境と同等の検証環境によるテストを常時実施していただくことが必要です。Ansible に限らずどの製品にも CI/CD を考慮したテストやデプロイの仕組みが整っていますので、積極的にご利用いただきたいです。 リソース Ansible の場合では、他のアプリケーションも同様にリソースとして CPU、メモリ、ストレージ、ネットワークを使用します。ストレージは比較的わかりやすくファイルとして計測しやすいため、積み上げで予測しやすいものとなっています。ネットワークの帯域についても、Ansible の場合は SSH で接続して小さなプログラムを送り込むという性質のものであることから、よほど大規模でない限りは、大きな問題となることは少ないようです。 しかしながらCPUやメモリのリソースの見積もりは簡単ではありません。「この playbook を動作させるためにはどれだけメモリを必要としますか」という簡単な問いに答えることも困難です。機能を動作確認するために最低限必要なリソース量はマニュアルに記載していますが、実際にお使いの環境でどのリソースがどれだけ必要になるのかについては、しばらく稼働させてみて様子をみていただくことをお勧めします。 Linux カーネルにはコントロールグループ (cgroup) の機能がありまして、稼働するプロセスに制限をかけたり、計測したりすることができます。 access.redhat.com Ansible Tower でもこの cgroup の機能を利用したプロファイリングを有効化する設定がありますので、必要であればご利用いただけます。 docs.ansible.com このような情報取得についてのお手伝いはできますが、実際にその内容を分析したり、設定の助言を差し上げることはテクニカルサポート範囲からは外れます。コンサルティングサービスにご相談ください。 おわりに 我々サポートエンジニアは製品の使い方についてのお問い合わせや問題解決だけを担当しますので、実際に長らく運用されているお客様がどのような工夫をされているのか、Ansible であればどんな制御対象に対してどんな自動化をしているのかということについては、実のところあまり触れる機会はありません。製品に詳しくなるにつれて、Ansible がどのように世の中に役に立っているのかを知りたくはなるものなのですが、日々の業務に忙殺されていますとその機会が少なく、歯がゆく感じているところがあります。 そんな中で実際によくやりとりされているお客様になりますと、これがうまく動くようになったことでこんなことも実現できるようになったとお知らせいただくこともあります。大規模なお客様の事例を見ますとビジネスも非常に大きく、問題解決のお手伝いができたことで一緒に何かを成し遂げたように感じることもあります。 Ansible はありがたいことに国内外さまざまなお客さまにご利用いただけるようになっていますので、グローバルのさまざまな事例に触れる立場から、何か日本のIT業界に対しても還元できるところがあればと思っています。Ansible はIT自動化ツールですので、従来の方法ですと100台程度までしかできなかったようなことが、数千台や1万台に対しても大きなコストを掛けずに制御することができるようになることがあります。さまざまな成功事例がありますので、お客さまのビジネスをより拡大していけるよう、テクニカルサポートの立場ではありますがお手伝いしたいと考えています。 技術的にも Ansible が扱う範囲は非常に幅広く、サーバやネットワーク機器、クラウドなどさまざまなものに及びます。今後は OpenShift や Insights のような弊社の他の製品とも連携が強まっていきますので、これから進化していくのも楽しみにしています。毎月のようにユーザー会がもくもく会のイベントを開催していますので、ご興味持たれましたらご参加ください。 ansible-users.connpass.com 最後になりますが、当初公開した記事では読者の立場によってはご不快な内容もあったことを重ねてお詫びいたします。 Ansible Automation Platform の評価ライセンスリクエストはこちらからご利用いただけます。 www.redhat.com Happy Automation!
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Get started with JDK Flight Recorder in OpenJDK 8u | Red Hat Developer の翻訳記事です。 OpenJDK 8u 262 release には、いくつかのセキュリティ関連のパッチと、新しい追加機能であるJDK Flight Recorder(JFR)が含まれています。この記事では、OpenJDKの開発者向けに、JDK Mission Controlや関連ユーティリティーを使ったJDK Flight Recorderの使い方を紹介します。また、コンテナJFRとして知られるProject Hamburgについても簡単に紹介します。 JDK Flight Recorderについて JDK Flight Recorder は、トラブルシューティング、モニタリング、プロファイリングを行うフレームワークで、Java 仮想マシン (JVM) コードに深く埋め込まれています。OpenJDK 11 で JEP 328 の一部として初めて導入されました。JDK Flight Recorderは、OpenJDK 11以前はJRockitにのみ商用機能として搭載されており、その後はJava Development Kit (JDK)のOracleディストリビューションに搭載されていました。JFRがOpenJDK 11で適切なオープンソースコンポーネントとしてリリースされて以来、 Java コミュニティのメンバーの中には、この機能を古いリリースでも利用できるようにしたいと考える人が増えてきました。 2019年、 FOSDEMのJava DevRoom と OpenJDK Committers Workshop において、OpenJDKコミッターのグループは、必要な変更や修正をOpenJDK 8uにバックポートすることを目標に、合同タスクフォースを結成することを決定しました。それから1年あまり、多くのパッチを経て、このプロジェクトは最終的にメインのアップストリームのOpenJDK 8u開発ツリーにマージされました。 最初に公開されたのは OpenJDK 8u 262 でしたが、自分で OpenJDK をコンパイルしようとすると、OpenJDK 8u 262 のデフォルトではコンパイル時に JFR をスキップすることがわかります。OpenJDK 8u 272 (10月予定)は、JFRをデフォルトでコンパイルする最初のリリースとなる予定です。 注意 : Red Hat Enterprise Linux または Fedora を通じて OpenJDK を利用している開発者は、JFR のサポートを含む Red Hat Package Manager (RPM) ファイルを入手できます。皆様のご意見、特にバグや問題点などをお聞かせください。 JDK Flight Recorderの概要 JDK Flight Recorderは主に2つのコンポーネントで構成されています。1つはデータを含む重要な部分、もう1つはデータを記録し公開するための内部インフラです。このデータは、 イベント と呼ばれる概念を介して抽象化されます。イベントには、様々な種類の有用な情報を関連付けることができ、時間内のサンプル、単一トリガーのイベント、または所定の時間を表すことができます。開発者は、メタデータやその他のコンテキスト情報をイベントの定義に追加し、その情報を使って分析ツールでイベントを説明したり、他の人間がイベントタイプをよりよく理解するために自己記述的にすることができます。例えば、ファイルアクセスが発生したときや、ガベージコレクション(GC)のコンパクションフェーズが始まったときに通知を受けたり、フルガベージコレクションのフェーズにかかった時間を知りたい場合があります。このようなイベントには、例えば、 Period(期間) や Frequency(周波数) などのアノテーションが可能なフィールドが含まれている場合があり、JFRのツールを使用することで、分析時に特定の方法で視覚化することができます。OpenJDK 8uでは、160以上のイベントを記録し、分析できます。 これらのイベントは発生時に記録されますが、JFR自体はリアルタイムツールではなく、呼び出し時にイベントをストリームすることはありません。(後のOpenJDKには JFR Event Streaming API がありますが、その目的はイベントをリアルタイムでストリームすることではありません) 代わりに、基礎となるフレームワークは、スレッドローカルのバッファにイベントを保存し、それをグローバルなリングバッファに書き込みます。これらのバッファが一杯になると、周期的なスレッドによって最終的にディスクにフラッシュされます。これは、トランザクション・データベースで使用されるメカニズムに似たメカニズムを使用しています。 注意 :JFRの設計は複雑に見えるかもしれませんが、メモリとCPUの両方を効率的に使用することができます。JFRのオーバーヘッドは一般的に約1%と非常に低く、ほとんどのケースではさらに低くなっています。オーバーヘッドが少ないということは、JFRを本番時に使用できる(している)ということです。これは、稼働コストが高くつく他の多くのソリューションとは異なります。 JFRの記録 JFRの記録ファイルは、すべてのイベントとそのメタデータをバイナリで表現したものです。この情報はチャンクに分けられています。チャンクとは、JFRの記録の中で、自己完結した情報の最小単位です。これは、別々に読んでも、チャンクに含まれるイベントを完全に説明できます。 すべての情報はLEB128エンコーディングの整数としてエンコードされています。これには、一定のプールポジションを参照する文字列も含まれます。このエンコーディングにより、各記録において高度なデータ圧縮が保証されます。また、GZip、LZMAとXZ、LZ4などの方法で記録を さらに圧縮 できます。記録のディスクへの書き込みは、設定に応じて、要求時またはプログラムの終了時に行われます。また、一定期間ごとにディスクに書き込まれるエンドレスの録画も可能です。これにより、アプリケーションの時間経過に伴う動作を確認できます。つまり、JFRの設定オプションは柔軟なのです。 JDK Flight Recorderの使い方 デフォルトでは、OpenJDKのJDK Flight Recorderを制御するためのいくつかのメカニズムが用意されています。これにより、手元のユースケースに合わせるのが非常に簡単になります。最初の選択肢は、例えばJVMでJFRを直接起動することです。 $ java -XX:StartFlightRecording your.application.ClassName コンマで区切ったオプションリストを使って、JFRをさらに設定できます。例として、終了時に記録をダンプできます。 $ java -XX:StartFlightRecording=dumponexit=true your.application.ClassName アプリケーションの起動後にJFRを制御するには、お馴染みの jcmd を使用します。 $ jcmd <pid> <pid>: The following commands are available: VM.unlock_commercial_features JFR.configure JFR.stop JFR.start JFR.dump JFR.check VM.native_memory ManagementAgent.stop ManagementAgent.start_local ManagementAgent.start VM.classloader_stats GC.rotate_log Thread.print GC.class_stats GC.class_histogram GC.heap_dump GC.finalizer_info GC.heap_info GC.run_finalization GC.run VM.uptime VM.dynlibs VM.flags VM.system_properties VM.command_line VM.version help For more information about a specific command use 'help <command>'. 直感的に言えば、 jcmd ユーティリティーを使うと、記録の開始と停止、記録の設定、記録の状態の確認、および録画のダンプができます。複数の記録を同時に実行することも可能です。 標準の Java Flight Recorder API (原文まま)を使用して、アプリケーションコードから直接記録にアクセスできます。このAPIを使用する際には、いくつかの点を理解する必要があります。そこで、このオプションについてさらに説明し、記事の最後に例を示します。 もうひとつの、間違いなくより便利な録画の取得方法は、 JDK Mission Control を介したものです。これは、記録の制御と分析のために特別に設計されたアプリケーションです。 注意 :利用可能な jcmd コマンドのリストの中に unlock_commercial_features フラグがあることに気付いたかもしれません。JFRはOpenJDKの商用機能ではないことを認識しておくことが重要です。しかし、JDK 11以前のすべてのOracle JDKでは商用機能となっています。私たちは互換性の理由からこのフラグを残していますが、これは何もしませんので、安全に無視することができます。 JDK Mission ControlでJDK Flight Recorderを使う OpenJDKには、 jfr というシンプルなツールがあります。これにより、JFRの記録を読み込んで、そこから有用なメトリクスを得られます。しかし、JFRレコーディングをJDK Mission Control (JMC)と組み合わせたときに、JFRレコーディングの本当の利点がわかるでしょう。JMCは、Fedoraおよび Red Hat Enterprise Linux (RHEL) 7では Red Hat Software Collections (RHSCL)経由で、RHEL 8ではモジュール経由で、Windowsユーザー向けには OpenJDK developer portal からすでに入手可能です。JDK Mission Controlは、 AdoptOpenJDK のようなダウンストリーム・ディストリビューションを通じても入手できます。 JMCの古いインストールを使用している場合、JDK Flight RecorderでOpenJDK 8uバージョンにアクセスしようとすると、警告ダイアログが表示されることがあります。これは、商用機能を使用しているかどうかを尋ねています。先に述べたように、OpenJDKでは(そしてOpenJDKのみでは)このメッセージを無視できます。このバグは、JDK Mission Controlの後のバージョンで修正されました。図1は、商用機能の警告を示しています。 図1:どのOpenJDKビルドでも、商用機能の警告を無視できます。 Demo: GC割り当てのプロファイリング JDK Mission ControlプロジェクトのリーダーであるMarcus Hirt氏は、JFRとJMCを一緒に使うための素晴らしい チュートリアルのセット とデモを用意しました。新しいデモを作成するのではなく、このセクションで彼のコードを参照します。特に、GCの割り当て動作に関する彼の例、 04_JFR_GC を使って、データを自動的に分析し、改善点を提案するJMCの能力を紹介します。JMCの分析は、ルールエンジンと呼ばれる機能に基づいています。ルールエンジンは現在、JMC 8.0に向けて 整備 されており、分析のためのオプションを増やし、ツールを介して直接利用するためのより良いAPIを提供し、全体的なパフォーマンスを向上させることを目的としています。 GCデモは、単純に多くのデータを割り当て、それをMapに保存します。そして、割り当てサイクルごとにMapの内容をチェックします。実際のプログラムでは、このデータを使ってもっと面白いことをするでしょうが、このパターンはHashMapの非常に典型的な使用例を示しています。私たちの場合、このプログラムは問題なく動作しており、メモリ不足などのエラーも発生していません。そのため、このデモは隠れたパフォーマンス問題を探り、ボトルネックや最適化の可能性をチェックするための完璧な候補となります。 テンプレートの使用 JMC や JFR には、テンプレートという便利な機能があります。これにより、デフォルトの設定とイベントで録画を開始できます。これらのテンプレートは、メモリの検証やTLABに問題がある場合、 jcmd で記録を取得する際に、コマンドラインインターフェイス(CLI)で渡すことができる設定に対応しています。しかし、グラフィカル・ユーザー・インターフェース(GUI)を使えば、より簡単に設定内容を理解できます。この実験では、 profiling テンプレートと、デフォルトの1分間の記録セッションを選択します。これで今回のデモには十分なデータが得られます。 図2に示すように、アプリケーションを実行して記録を取得すると、さらに調査しなくても、すぐに最適化したいことに対する直接的な答えを得られます。このアプリケーションでは、プリミティブからオブジェクトへの変換が非常に多く行われていますが、JMCではこれらの割り当てがどこで行われているかを教えてくれます。 図2:JDK Mission Controlの自動分析ビューでは、多くの問題が自動的に検出されます。 このデモは数年前のJava Oneでのハンズオンセッションのために作成されたもので、当時のJMCバージョンには高度な解析を行うオプションはありませんでした。セッションの参加者は、 Memory と TLAB タブを探索して、図3に見られるような、より詳細なメモリ圧の表示を得ることを勧められました。 図3:TLABタブに表示されたメモリの割り当て状況。 注意 :JMC 7以降のバージョンの解析ページは、より多くの情報を提供しており、さらに多くのルールや最適化戦略を提供しています。JMCは、HTMLページとしてエクスポートされるスタンドアロンのコンポーネントとして解析ページを提供しています。完全なIDEを使用せずに、JMCの分析をアプリケーションに簡単に統合できます。JFR APIと一緒に使用すると、JMCのスタンドアロン解析コンポーネントは、メモリオーバーヘッドを非常に低く抑えながら、インフラストラクチャに堅牢なモニタリングとプロファイリングソリューションを統合できます。 JFRのOld Object Sample Eventによるメモリプロファイリング 従来、効果的なメモリプロファイリングを行うためには、GCルートやアロケーションの履歴を確認するために、時間をかけて完全なヒープダンプにアクセスして調査する必要がありました。また、同様にコストのかかるオプションとして、Java Native Interface (JNI)を介してオブジェクトの割り当てを抽出するエージェントのような方法を使用できます。しかし、完全なヒープダンプに含まれる機密情報を考えると、それは必ずしも可能ではありません。JFRは、OpenJDK 8uにバックポートされたOld Object Sample Eventにより、ここでも助けになります。 注釈 :JFRのOld Object Sample Eventについてもっと知りたいという方には、 Marcus Hirt氏のブログ記事 を改めてご紹介します。彼のブログをぜひチェックしてみてください。プロファイリング、JMC、JFRについての情報、技、詳細など、信じられないほどの情報源です。 ここでは、JFRのOld Object Sample Eventを探るために、別の小さな自己完結型の例を使います。これは、コードを読めば一目瞭然の例ですが、私たちの選択肢を探るにはとても良いものです。 public class Leaks { private static final Map<Object, Object> SESSION_DATA = new HashMap<>(); public static class UserInformation { private byte [] data = new byte [ 10000 ]; } public static void main(String[] args) { String userId = "user" ; while ( true ) { UserInformation user = (UserInformation) SESSION_DATA.get(userId); if (user == null ) { user = findUserInformation(userId); // SESSION_DATA.put(userId, user); // 正しい SESSION_DATA.put(user, user); // 誤り } sleep(); } } private static UserInformation findUserInformation(String userId) { sleep(); return new UserInformation(); } private static void sleep() { try { Thread.sleep( 1 ); } catch (InterruptedException e) {} } } このコードで強調されているミスは、本番環境に移行する前に迅速なテストで発見されるようなエラーですが、例として、本番環境に入り込んでしまったコードのバグであると仮定しましょう。図4は、Old Object Sample EventのプロファイリングをオンにしたJFRセッションを示しています。(このセッションでは、ヒープダンプは害を及ぼされていません。) 図4:Old Object Sample Eventが自動分析ビューに表示されています。 その分析結果は、どこを見れば良いかを瞬時に教えてくれます。HashMapが何度も何度も埋められ、オブジェクトの数が増えているだけでなく、メモリの割り当ても多くなっています。コードを読まなくても、このMapはあまり制御されずにループでオブジェクトを埋めていることが予想されます。図5に示すように、 Memory タブではさらに多くのことがわかります。 図5:Live Objectページとアプリケーションコードを並べて表示したもの。行番号が一致していることに注目。 このタブでは、プログラムコードと Live Object ページを並べて表示しています。行番号の付いたスタックトレースは、どこに問題があるかを正確に示しています。 プロファイリングについての注意点 オブジェクトの割り当てと保持を追跡できることは、メモリ問題を分析する際に最も重要なツールの1つです。あるバグを思い出しました。これは、作成されたオブジェクトの数が膨大であったため、修正が困難でした。しかし、これはリモートのX11接続を介してアプリケーションのUIを実行しているときだけです。さらに、ユーザーがマウスを動かしたり、ボタンをクリックしたりするたびに、オブジェクトが作成されていました。これにより、多くのメソッドがグラフィカル・インターフェースの位置を再計算しています。しかし、これは一部のケースに限られます。 この2つの動作がリンクしているのは、リモート接続の処理にバグがあったからです。位置を計算するには、画面上のオブジェクトの相対的な位置を知る必要がありました。リモート接続であるため、多数のX11アトムというものが作成され、回線上を行き来していました。ユーザーが複数のアプリケーションを実行している場合は、さらに多くのトラフィックが発生します。Javaコードはこれらのアトムを傍受することになります。これは、Javaの表現を作り、さらに計算をして、それを繰り返しているのです。 当時はJMCではなく、 Thermostat という似たようなツールにアクセスしていました。 Byteman との統合を利用して、それらのオブジェクトがどこで作成されたのか、また、それらのオブジェクトを作成するに至ったコードパスがなぜ異なる形で実行されたのかを分析するスクリプトを作成しました。通常のメソッドプロファイラでは、結果が集約されてしまうため、このようなことは困難です。このような情報がJFRの記録から直接得られることは非常に重要であり、時間の節約にもなりました。さらに言えば、お客様が導入時に記録したものを送るだけで良いのです。ローカルでエラーを再現したり、ツールを追加インストールしたり、ポートを開いたり、エージェントを起動したりする必要はありません。この場合、必要なのは記録だけです。 JDK Flight Recorder API 先ほど、JFRには内部APIが付属していると述べました。このAPIは、 jdk.jfr 名前空間の下に存在し、記録を管理したり、アプリケーション用のカスタムイベントを作成したりするためのクラスを含んでいます。 最も簡単に書けるプログラムは、JFRが利用可能かどうかをチェックするものです。 public class CheckJFR { public static void main(String[] args) { boolean isAvailable = FlightRecorder.isAvailable(); System.err.println(isAvailable); } } そして、APIを使って、アプリケーションからプログラム的に記録を開始したり停止したりできます。例えば、以下のクラスは、JFRマネージャーを作成するための抽象化されたクラスです。 import java.io.File; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import jdk.jfr.Configuration; import jdk.jfr.Recording; public class LocalJFR { private Map<Long, Recording> recordings = new HashMap<>(); @Override public long startRecording(String configName) throws Exception { Configuration c = Configuration.getConfiguration(configName); return startRecording( new Recording(c), "jfr-recording" ); } @Override public long startRecording(String configName, String recordingName) throws Exception { Configuration c = Configuration.getConfiguration(configName); return startRecording( new Recording(c), recordingName); } @Override public long startRecording() throws Exception { return startRecording( new Recording(), "jfr-reopenjdk-jfr-2cording" ); } public long startRecording(Recording recording, String name) throws Exception { long id = recording.getId(); Path destination = File.createTempFile(name + "-" + id, ".jfr" ).toPath(); recording.setDestination(destination); recordings.put(id, recording); recording.start(); return id; } public File endRecording( long id) throws Exception { Recording recording = recordings.remove(id); recording.stop(); recording.close(); return recording.getDestination().toFile(); } } これは定義できる最もシンプルなイベントです。 @Label( "Basic Event" ) @Description( "An event with just a message as payload" ) public class BasicEvent extends Event { @Label( "Message" ) public String message; } プログラムによるJFRイベントの作成と監視 OpenJDKにおけるJFRの作者の一人であるEric Gahlin氏は、 JFR API を使用したデモや小規模なテストの包括的な一覧をまとめました。このAPIは、OpenJDK 11以降のJava仕様に含まれていますが、OpenJDK 8では仕様に含まれていないため、すべてのOpenJDKの実装で利用できるわけではありません。 バージョン間の移植や移行を容易にするために、空の実装を持つシンプルな compat-jfr を作成しました。このパッケージを使うと、ユーザーはコードを計測したり、カスタムイベントを作成したり、APIを使って記録を管理できます。しかし、実装は空なので、メソッドは何もせず、イベントはメモリやディスクに書込まれず、問い合せしてもJFRは利用できないと報告し、起動できません。アプリケーションは正しく機能し、コンパイルされ、実行されるので、互換性の面でも優れています。compact-jfrは、コマンドラインで依存関係にあるものとして使用するか、JDKの jre/lib/ext ディレクトリに追加して使用できます。 イベントAPIを使ってカスタムイベントを作成するだけでなく、実行中のアプリケーションにイベントを追加するとコードを計測できます。JMCには、 Agent という名前の便利なツールがあります。JMC Agentは、一連の設定を使用してイベントを定義し、実行中のコードでイベントを計測します。セッションが終了すると、計測は削除されます。Bytemanに精通している方(そうであるべきですが)、Agentは非常に似ていますが、自由に使えるチューリング完全な言語の代わりに、AgentはJFRイベントのみに焦点を当てています。スコープを縮小したことで、JFRをより細かいツールで計測するという問題に特化でき、セキュリティやパーミッションなどの問題も部分的に解決できます。また、Agentを制御・設定するためのJMCプラグインにも取り組んでいます。これは現在進行中ですが、すでに便利な機能を備えており、 こちらでご覧いただけます 。 コンテナでJFRを使う (Project Hamburg) この記事で紹介したツールはすべて、特定のデプロイメントに合わせてJDK Flight Recorderを微調整できるという点で素晴らしいものです。しかし、 コンテナ 内でJFRを使用する開発者には、まだかなりの作業が必要であることに気づきました。まず第一に、JFRの受信側には、Java Management Extensions(JMX)を介した接続が必要です。この接続はもちろん安全にできます(すべきです)が、 Red Hat OpenShift Container Platform (OCP)のようなコンテナプラットフォームでは、内部のポートを外部に開放することを禁止したり、困難にしたりできます。また、複数のプロセスを一度に追跡するには、上位のツールを使用しないと複雑です。OpenShift には、この作業を支援するデプロイメントコンソールがありますが、より一般的なソリューションがまだ必要です。 このため、私たちは Container JFR というプロジェクトを作成し、Project Hamburgとも呼ばれています。Container JFRは、シンプルな3層構造のアプリケーションです。これは、コンテナ内でJMXを介して様々なアプリケーションに接続し、外部にWebサービスのインターフェースを公開するコントローラエージェントを含んでいます。JMX接続はコンテナ内に隠すことができ、コンテナ以外の世界でも、つまりファイアウォールの後ろに置くことができます。一方、Webサービス・インターフェースは認証によって保護されています。このインターフェースでは、同じエンドポイントから複数のJVMを制御できるため、複数のデプロイメントに最適です。 もう一つのコンポーネントは、Webサービスを利用したWeb UIです。管理をシンプルにするだけでなく、何よりもJMCの自動分析機能を統合することで、 アプリケーションのパフォーマンス をすぐに見ることができ、分析によって特定の問題が指摘された場合にのみダウンロードする記録を決定できます。このプロジェクトには、ブラウザ上でグラフを作成できる Grafana データソースも含まれています(例えば、ユーザーがダッシュボードにレコーディングを統合できるようになります)。実験的な Prometheus エクスポーター(記録を処理するには最適な方法ではありませんが、それでも便利です)、そして最後に、OpenShiftやKubernetesのための包括的なOperator APIのセットがあります。これらのOperator APIを使用することで、マウスをクリックするだけでプロジェクトのインストール、実行、設定を行えます。 注:Gunnar Morlingが カスタム、アプリケーション固有のJFRイベントを使用してREST APIを監視 に関する包括的なブログ記事を書いています。この投稿では、ストリーミングAPIとカスタムJFRイベントが説明されているので、詳細はそちらを参照してください。Gunnarは最高です! 結論 JDK Flight Recorderは、ランタイムシステムに負担をかけることなく、このような高レベルの情報を公開できるOpenJDKで利用可能な初めてのモニタリングおよびプロファイリングツールです。JFRは、JVMに深く統合されているため、そのようなレベルの情報を提供します。イベントAPIやエージェント・ツールを使ってカスタム・イベントを作成できるので、ランタイムからだけでなく、アプリケーションの観点からもJFRを活用できます。 OpenJDKは大規模なコードの公開に貢献しましたが、JDK Flight RecorderはOpenJDKがオープンソース化されて以来、最も重要な貢献をしたと言えるでしょう。Oracle社がJDK Flight RecorderとJDK Mission Controlをオープンソース化した際には、Javaコミュニティに多大な貢献をしたことが認められるべきでしょう。今回のOpenJDK 8uへのバックポートにより、このインフラが、積極的にメンテナンスされているすべてのバージョンのOpenJDKにようやく導入されました。 私たちは、お客様がOpenJDKの新しいバージョンに移行して、すべての追加機能とパフォーマンスの改善の恩恵を受けることを望んでいます。JFRをツールボックスに追加することで、どのバージョンのOpenJDKでも、アプリケーションがより良く、より速く、より問題なく動作するようになります。 謝辞 お礼を申し上げたいと思います。 Marcus Hirt氏には、JDK Mission Controlプロジェクトのプロジェクトリーダーを務めていただきました。彼は、コミュニティへの貢献という点で、常に高い水準を保っています。また、彼のブログはインスピレーションと知識の素晴らしい源となっています。 Gunnar Morlingは、Container JFRの開発初期に協力してテストを行い、フィードバックや提案をしてくれました。 Red HatのJDK Mission Controlチームは、JMCへの素晴らしい貢献と、Agent、JFR Compact、Container JFRへの取り組みをしてくれました。 最後に、この素晴らしい技術を提供してくれたオリジナルのJDK Flight Recorderチームと、それをオープンソース化してくれたOracle社に感謝します。素晴らしいといえば、2020年にJMCが best Java Feature コンテストで優勝したことをご存知でしょうか? その他のリソース ここでは、この記事で紹介したリソースと、JDK Flight RecorderとJDK Mission Controlの詳細を知るために利用できるプレゼンテーション、記事、ソースコードへの興味深い追加リンクを紹介します。 An introduction to middleware application monitoring with Java Mission Control and Flight Recorder (FOSDEM presentation, 2019) JMC & JFR—2020 vision (FOSDEM presentation, 2020) More about the JFR compatibility API for OpenJDK 8 Low overhead method profiling with Java Mission Control (Marcus Hirt, 2013) Compressing flight recordings (Marcus Hirt, 2019) Using Java Flight Recorder with OpenJDK 11 (Laszlo Csontos, 2018) More about the Container JFR project More about JDK Mission Control Source code and examples for understanding how to create and use custom events with JDK Flight Recorder (Gunnar Morling, 2020) Flight Recorder samples : Code snippets illustrating how to use the JDK Flight Recorder API jmc-jshell : An easier way to experiment with the JDK Flight Recorder and the JMC core classes Introduction to JmFrX: a small utility to capture JMX data with JDK Flight Recorder (Gunnar Morling, 2020)
こんにちは。 Red Hatで通信事業者様向けSolution Specialistをしております久保田です。 本日はRed Hat Summit 2021の中から通信事業者様おすすめのセッションをご紹介します。 vRANセッション Verizonのソリューション Red Hat Summit 6月のおすすめ 今年のRed Hatサミットは4月と6月に分かれています。 一回目は日本のゴールデンウィーク直前にオンラインで行われました。 オンデマンドで視聴が可能ですので、登録してぜひセッションをご確認ください。 今日はその中から通信事業者様おすすめのセッションをご紹介します。 vRANセッション 一つ目はvRANに関してRed Hatのエキスパートによるパネルディスカッションです。 Unboxing cloud radio access network (RAN)  RAN(携帯無線のネットワーク)を紐解く 概要 Disaggregated(分散) RANとCloudインフラの概要 Cloud RAN・RANにおけるCNF化の利点 いち早く新しいRAN機能を導入 自動化、CI/CDパイプライン エッジアプリとRANアプリでインフラを共有 Telco RANとRed Hatの製品について Red Hat Openshiftに備わったRANに必要な機能 低遅延性 ネットワーキング デプロイ(フットプリント) ゼロタッチ・プロビジョニング 迅速な障害の発見とリカバリー コンフィグマネージメント トラブルシューティングとログ・インベントリ Red HatはO-RANアライアンスとTIPに貢献 アップストリーム(機能やAPIをオープンソースへ還元)ファースト ソースコードなどをダウンストリームとしてRed Hatの製品へ Red Hat Advanced Cluster ManagementとAnsibleでエッジデータセンターのクラスターを管理、自動化 下の黒い三角をクリックして詳細をご覧ください。 セッションの詳細 Senior Solution ArchitectのCristianを司会に、通信事業 Solution ArchitectureのディレクターとRed HatのRANのグルTimoによるパネルセッションです。 まずはRANの背景について、Timoによる説明から始まります。 RANはこれまではソフトウェア・ハードウェアともにプロパライエタリな一つのベンダーだけの技術で作られていました。 そしてソフトウェア・ハードウェアを分解し、アンテナ、RU, DU, CUの機能にわける技術が進んでいます。これは3GPPの標準のものです。 主に二つの配置方法があり - Centralized RAN:アンテナよりデータセンター側にRAN機能を配置 - Disaggregated RAN:RU,CU, DUをアンテナ側にも置くこともあるります。人口密集地や環境によって決まります。 Red HatではDU/CUをRed Hat OpenShiftなどのクラウドプラットフォームに載せ、Disaggregated RANを実現しています。 なぜいまCloud RANが注目されているのでしょう。 それは主に以下の理由があります。 タイトにインテグレートしていないので容易に早く新しい機能を無線ネットワークに導入することができる。 いろんな技術をマルチベンダーで実現できる。 RAN市場に新規参入を可能にする Cloud PlatformのRAN構築において、自動化を可能にする RANは何千ものエッジデータセンタで構成されているので、自動化がキー またCI/CDパイプラインも有益 Cloud Platformを使うことでRAN Intelligent Controller(RIC)などエッジアプリとRANアプリでインフラを共有できる ではRANに必要とされる機能とは何でしょう。 1.低遅延 5GにおけるRANのTransportネットワークでは時刻同期が必須です。 PTP(Precitsion TIme Protocol) はクロックの同期に使われるものです。タイムスタンプが使えるNICで使用できると、同期の精度が高まります。数マイクロセカンドまで遅延を抑えることができます。 Cloud RANにおける低遅延の特徴はRealtime Determinism、CPUの親和性と孤立性、トポロジー管理です。 CPUに関してはRANのアプリでもCPUクロックがとても重要です。アサインされたアプリ(低遅延を必要とするもの)にはCPUがリザーブされます。他のアプリケーションに使用させることなく、OSのカーネルなどハウスキーピングにリザーブされるのです。DPDKコンテナのRANアプリにはこのようにIsolateかつDedicatedなコアを使用しています。 トポロジー管理にはDualSocketのNUMAでスケジューリングします。 HWアクセラレータが配置される箇所にはリアルタイムポートがスケジューリングされるのです。 ネットワーキング RANアプリでは性能を発揮するのにDigital Signal Processing(DSP)のハードウェアデバイスでオフロードさせる必要があります。 通信事業(Telco)で使われているのは、例えばフィールドプログラマブル・ゲートウェイであるFPGA、様々な機能が決まったライフサイクル上で使用されるASIC、ハイパフォーマンス・データプレーンを実現するDPDKなどがあります。 Multusでは複数のNIC・IPをサポートし、マルチネットワーキング・インターフェースやSCTPのマルチホーム・サポートを実現します。 通信事業では大容量トラフィックと低遅延が必須なのはご存知の通りです。大容量の例としてはフロントホール・インターフェース(RU-DU間)で25−30Gbpsのスループット、低遅延はいくつかの要素はありますが、10−20マイクロセカンドほどと言われています。 デプロイ(フットプリント)と拡張性 vRAN(仮想RAN)のユースケースでは、このようなエッジクラウドがなるべくセルサイトに近くある必要があります。しかし、セルサイトはだいたいスペースや電源容量が制限されているものです。ですから、RANクラウドはフットプリントが小さくなくてはいけません。 そこで、Single Node OpenShift(SNO)やリモートワーカーノードなどの機能が有益となります。 SNOはマスターとワーカーノードを単一サーバーで動かすことができる機能です。リモートワーカーノード機能ではマスターノードを中央のデータセンタに置き、ワーカーを分散してエッジに配置できます。 もちろん、実際のデプロイにはCSPやNEPにより色々な好みや違いがあります。 ゼロタッチ・プロビジョニング(ZTP) 最後はZTPです。 大規模RANをデプロイするには、オペレーションの自動化が必須です。中央からデプロイ、アップグレード、コンフィグ、ハードウェア・プロビジョニングなどをリモートクラウドにする必要があります。 OpenShiftは上記の機能を実装しており、すでにパートナーと実証しています。 どのようにデリバー、スケール、自動化するかがキーとなります。これにはCloud RANをアプライアンスのように扱う、つまりLABで十分テストされていて、LAB同様にデプロイできる必要があります。 Cloud RANのデリバリーはDay1とDay2に分けられます。以下のような機能も必要となるでしょう。 通信事業基準のHigh Availability、迅速な障害の発見とリカバリー モバイルブロードバンドにはFive 9s(0.99999)の要件あり、つまり一年に5分と30秒のダウンタイムしか一年に許されないことが多くあります。 低遅延を考慮するとSix 9s (1年で30秒のダウンタイム)しか許容されません。 つまりHigh Availabilityは一番重要なCloud RANでの機能なのです。 コンフィグマネージメント 全てのクラウドの設定をPersistant DBに格納し、このデータをCLIとRESTで運用します。これはどのようにCloudを操作するか、ローリング・アップデートを行うか、ということです。また、一晩で4時間しかないメンテナンス時間内で何らかの操作の失敗の場合には、ロールバックを行う必要があります。 トラブルシューティングとログ・インベントリ アラームを収集、KPIやログをニアリアルタイムで収集しモニタリングツールのあるNORTHBANDインターフェースに提供します。  DUに関してはCPUマネージャー、Huge Pages、PTP、DPDK、SCTPなどの実装が必要になります。OpenShiftではこのようなケイパビリティが実証されています。 アプリのデプロイ、ストレージやファイアウォール、ネットワーク、ハードウェア、スイッチのプロビジョニングはAnsibleで自動化することが可能です。 ここで、リアルタイムな質問がチャットで投稿されます。 質問:HWアクセラレーションはOpenshiftでサポートされていますか? 答え:DUでも実証されています。 設定はAnsibleで自動化でき、Day1で自動化し、Day2でクラウドサイトにデプロイできます。 質問:通信事業産業について、どのスタンダードの組織にRed Hatは参加していますか 答え:通信事業はスタンダード(標準化)に依存しているのはご存知の通りです。これはデバイスやネットワークの相互接続性の観点、マルチベンダーを可能とするためです。3GPPとITUが主にありますが、Red Hatはその会員ではありません。 RANでは二つの主な団体があり、O-RANアライアンスにはRed HatもWG6・Cloudification and orchestrationにてインターフェースやアーキテクチャで貢献しています。また、Disagrigting RANで必要となるセキュリティでも貢献しています。 もうひとつはTIM (Telcom Infra Project)で、こちらはPoCや検証など実用的なことを行なっている団体です。Red HatはTIMのopen-RANグループに参加しており、13のOpenLabのうちいくつかに参加し、OCPをプラットフォームとして推進しています。 Red Hatはオープンソースのアップストリーム開発モデルとしてこの2つのRAN団体に貢献し、この結果をアップストリームにあげ、機能やAPIをオープンソースに還元しています。これはとても難しいことですが技術の発展には非常に重要なことです。 そして、そのソースコードなどをダウンストリームとしてRed Hatの製品にとしていれこみます。 これがRed Hatのアップストリームファーストの文化です。 質問:何千ものサイトがあるがどのように管理しているのでしょうか 答え:大規模なモバイルネットワークでは何千ものアンテナサイトがあり、DU/CUをホストしているエッジデータセンターも同じくらいあるでしょう。インストールとデプロイは未だ手動で行われています。 Red Hatではそれを自動化できるようにツールを促進しています。 Red Hat Advanced Cluster Management (RHACM)を適用し、何万ものエッジデータセンターのクラスターを管理したり、ポリシーベースのk8sモデルやアプリケーションのライフサイクルや監視を行うなど大規模なデプロイメントのクラスター管理に活用できます。 また自動化ツールであるAnsibleもこの何千ものエッジサイトのデプロイメントに活用することができます。 質問:Telco Edge Mobile ComputingとRANの関連とは? 答え:5Gにはビジネスと居住地での需要があり、アクセスにはいくつかの種類(FixWireless, CMTS などのケーブル、4/5G、Wifi、NB-IoTなど)があり、その技術は全てベアメタルでした。現在、それらは仮想・コンテナ・クラウド化され、全て同じクラウドで動くように融合されています。通信エッジクラウド全体で共有できるのです。それらのサービスはパフォーマンスだけでなくプライバシー、E2Eコントロールなどの必須要件定義があります。 また全てのサービスがエッジに配置されるわけではなく、大体がデータセンターに配置されます。例えば、自宅設備の自動化のツールは低遅延が必要ではないですよね。Private5Gなど、工場やスタジアムはエッジからデータセンターにデータを送るような必要もありません。つまりサービスをエッジに持ってきて、低遅延とエッジのプライバシーを確保する必要があるのです。 通信エッジクラウドはユーザーに近いクラウド、遅延の要求に耐え、かつ距離を許容できるものでなくてはいけません。 このタイプのクラウドは、まずはDUクラウドがあります。これはD-RANユースケースで、マルチテナントではなくシングルサーバーで動くことが多くあります。つまりアプライアンスのようなものと考えられます。 ただその次にくるクラウドはRICやMEC機能があるCUで、エッジで動くサービスへのブレークアウトが必要となります。 UPFのようなゲートウェイ機能をおく必要があり、UPFではMEC、マルチアクセス・エッジコンピューティングへのトラフィックのブレークアウトができます。 MECではVR・AR、スマート・マニュファクチャリングなどのアプリケーションが使えるようになるのです。 このように、通信事業用エッジは様々なアクセスネットワーク・テクニカルなアプリだけでなく、エッジにおかなければならないアプリやサービスの低遅延の要件に合わせることができます。 質問:CU/DUにおいて、VNFよりCNFが良い点とはなんですか 答え:コアアプリはベアメタルから仮想マシンに移行しましたが、全てのアプリが移行したわけではありません。仮想マシンのステップを経由しないで直接コンテナ化されたものもあります。 コンテナ化したアプリは通信クラウドに移行した利点があります。 そのひとつがCI/CDパイプラインで、これによって新しいRAN機能をいち早く使うことができます。 またエッジにおいてはDevSecOpsによってセキュリティを強化することが可能です。 以上が30分のvRANに関するセッションでした。 Verizonのソリューション 次はVerizonが採用した、AWS WavelengthとOpenShiftのエッジソリューションに関してのパネルディスカッションです。 Verizon 5G Edge with Red Hat OpenShift unleashes the next generation of applications 概要 ネットワーク コンピュートとストレージの全ての機能をリージョンに配置し、世界最大級のハイパースケーラー(AWS Wavelength)で提供 モバイル・エッジ・コンピューティングのポートフォリオであり、顧客に価値を与える5Gエッジ 遅延を減らすためコンピュートとストレージをユーザー側に配置したモバイル・エッジ・コンピューティング アクセスの形態(5G・ベライゾンのネットワーク)を意識することなく、顧客・開発者たちはシームレスにアプリケーションの開発・デプロイ マスターを通常のAWSのリージョナルゾーンに、ワーカーをWavellengthにデプロイし、アプリケーションがエッジで動く Red Hat OpenShift 5Gエコシステムに溶け込んだソリューションをRed Hatチームとともに実現 IPIインストールを使用 Single Node Openshiftによるエッジでの小さいフットプリント OpenShiftブログ より 下の黒い三角をクリックして詳細をご覧ください。 セッションの詳細 こちらはVerizonの Strategy Analystである Robert Belson とRed HatのPrincipal Specialist Solutions ArchitectであるAshish Aggarwalのパネルディスカッションです。Red HatのSachin Ratheeが司会を務めます。 まずVerizonのRobbie(Robert)がRed HatとVerizonの初期の活動について話しました。 2つのチームが一緒に動くために、まず初めに行ったのは基本的な5Gエッジの定義でした。「5Gエッジとは何か」、「そのポートフォリオがどのように顧客に価値を与えることができるか」を議論したそうです。 皆さんも日々のインターネット通信で体感されるように、ネットワークは通常は「ベストエフォート」であり、どうしても遅延に悩まされることが多いものです。 しかし、そこを差別化要因とし、アプリケーションのモダナイゼーションやコンテンツ・デリバリーネットワークを促進させ、ウェブページなどのアセットをユーザーにより近いところに配置しました。 このコンセプトをモバイル通信の世界にも持ってこれないかというところで、コンピュートとストレージをよりユーザーの近く持ってきたものが、モバイル・エッジ・コンピューティングのネットワークです。 それをもう一歩先に進めて、コンピュートとストレージの全ての機能をリージョンに配置し、世界最大級のハイパースケーラーに乗せネットワークエッジだけではなくモバイル・ネットワークエッジでサービスを提供しよう、というのが今回のVerizonのソリューションでした。 これによりアプリケーションチームがアプリケーションを最適化するように、モバイルの世界でも「どこにデプロイするかだけではなく、どのようにデプロイするか」さらにたくさんの選択肢を提供できるようになりました。k8sクラスターの載ったVM(仮想マシン)を使い、Red Hat OpenShiftのプラットフォームが使えるようになったのです。 ここで、本日のセッションのトピックでもあるVerizonによる、AWS Wavelengthの5Gエッジコンピューティングのソリューションについて話は深掘りされます。 Verizonの5Gエッジはモバイルエッジ・コンピューティング・ポートフォリオです。いいかえると、このAWSサービスはパブリック・モバイルコンピューティング的なものです。Verizonはプライベートエッジも提供しているそうですが、今回はパブリックにフォーカスを当てることにしたそうです。というのもARやVR、イーコマースや小売、V2Xなどのコンバージェンスをドライブするという価値がパブリックサービスにはあるからです。 AWSではコアサービスをエッジに、とくに4Gや5Gのモバイルエッジに持ってくることができます。 なぜコアサービスをエッジ側に配置すると良いのでしょう? エンドユーザーは4Gや5Gの基地局に接続するのですが、ここではモバイルパケットがアンカーされ、コンピュートが起こるからです。この通信はハイパースケーラー越しにデータセンターに接続されるとは言っても、トポロジカル的にはモバイル・エッジコンピューティング側に接続するのが近いのです。 さて、ここでVerizonのユーザーにとって大切なのは5Gのネットワークについて知ることではありません。ネットワークの詳細を知らなくてもハイパースケーラーとRed Hat OpenShiftを含むインテグレートされたプラットフォームを信頼することで、アプリケーションの開発に集中することです。 さて、ここで話はAshishに移ります。 AshishはRed Hat OpenShiftの利点を、デプロイの環境を気にすることなく 開発者が常に同じ環境で開発することだと述べています。例えば、アプリケーションの開発において、デプロイされるインフラストラクチャがエッジのどこにあるのか気にする必要がないのです。 ここでAshishはOpenShiftをWavelengthにデプロイするときの方法と変更点を聞かれます。 今回OpenShiftはカスタマイズすることなく、通常のIPIでデプロイされました。また、OpenShiftはシングル・ノードで運用も可能でフットプリントも小さいことも利点でした。 ただ、唯一の変更点はMTUの値です。 ちなみに詳細は こちらのブログ に載っておりますので、OpenShiftをAWSのWavelengthで試してみたい方は是非ご覧ください。 マスターノード(コントローラー)をAWSのペアレントリージョナルゾーンに、ワーカーノードをWavelengthにデプロイし、アプリケーションをエッジ側で動かすことに成功しました。これにより低遅延が実現されたのです。 OpenShiftのエコシステムによってk8sオペレーター機能、サーバーレス、サービスメッシュなどの機能を使用しアプリケーションをデプロイしました。 つまり、アベイラビリティ・ゾーンでシームレスにRed Hat OpenShiftを使えます。WavelengthはAZの一つとして扱われ、ユーザーはVerizonのネットワークなのか、5Gアクセスなのかを意識する必要がありません。 新しい技術や5Gの特性を学ぶ必要なく、ユーザーは5Gの恩恵を受けることができるのです。この点はVerizonのRobbyが付け足しながら絶賛した点です。 さて、ここでユースケースに話は移ります。 顧客がエッジで何をするか。 V2Xなどの自動車関連や安全性、インフォメーションに関するビジネス。コンタクトレスなパブリックなサービスとして、メディアやエンタテイメント。スタジアムに接続されたたくさんのカメラやセンサー。 これらはオーケストレーションやクラウド管理が必要なワークロードで、インテリジェントなトラフィック・ルーティングやクラウドの分析が必要です。 しかし、全てのカメラなどのデバイスをケーブルで繋げるのは拡張性が高いとは言えません。 また、少し前のテレビ中継でも皆さんご存知の通り、衛星を経由したテレビ放送は遅延が発生します。現地のレポーターとスタジオのキャスターのすれ違った会話がよく以前は見られましたよね? 現在では5Gネットワークに接続されたカメラとSDN(ソフトウェア・デファインド・ネットワーク)があれば、柔軟性と拡張性をもった放送が可能です。 低遅延、エッジでのフラッド検知、キャッシュによる遅延の緩和によって、時間と帯域を節約することができます。 なぜ、Verizonは5Gに取り組むのか、5Gの利点とは何か、というリアルタイムの質問に対して、Robbyは5Gはやはり高速であることをあげています。 LTEでは4秒かかっていた1メガのデータも5Gでは32ミリ秒で送信することができる。これによってユーザー・エクスペリエンスは飛躍的に向上します。 最後に5GエッジのエコシステムについてRobbyがVerizonの視点で答えます。 このエコシステムによって、開発者コミュニティを魅きつけ育成することができます。5Gエッジはすでに大企業にとってはインフラを拡張し、ROIや顧客体験を向上させるのために、すでに活発に発展・活用されている技術です。 コンテンツ面では、このウェビナーのようにコミュニティの認知度を高め、特にインフラに関して開発者にどこに、どのようにアプリケーションをデプロイするかの様々な選択肢を与えることができます。 それだけでなくまた Ashish や Robbieのブログ のようにリファレンスアーキテクチャによって簡単にデプロイメントする方法やクラウド構成のテンプレやモジュールなどを伝えることも可能です。 またVerizonの5Gラボでは仮想および物理のテストラボがあり、開発者たちはハンズオン体験をしたりアプリケーションを試験稼働したりできます。 アドボカシー面では顧客と働いたり開発者が既にいるチャネルにてコミュニティを作り上げることがエコシステムで大切なことです。 Sachinの#5GBuildRightと書かれたTシャツのように、とても深くエコシステムにインテグレートされて5Gを作り上げるのです。 だからRed Hatと一緒にこの場で講演できること、パートナーとして働けることを光栄に思っていると述べて、セッションは終わります。 その他にもSecurityやEdge関連の興味深いセッションがあります。 ぜひ ご登録 の上、オンデマンド配信をご覧ください。 Red Hat Summit 6月のおすすめ Red Hat Summit 2021は6月にも続きます。 その中から個人的注目セッションをご紹介いたします。 Cloud-native 5G with Verizon Wireless and Red Hat Verizon Wirelessの5Gコアのビジョン、Red Hatと協働する中でのアーキテクチャ要求や体験を5GデプロイやCNFとそのインフラプラットフォームのベストプラクティスを交えてお話しします。 Tuesday, Jun 15 2:00 PM - 2:30 PM JST(他) Lessons from a truly multivendor 5G standalone trial 真のマルチベンダーかつクラウドネイティブ 構成の5GSAをどのように実現・運用しているか。Telenorのソリューション・アーキテクトとリサーチサイエンティストが実体験を共有します。 Wednesday, Jun 16 1:00 PM - 1:30 PM JST(他) Delivering a unified 5G-edge solution for telco cloud and distributed datacenters 5Gネットワークを低コスト、高パフォーマンスでエッジ・ネイティブなアプリケーションで実現するために、Red HatとKaloomでどのようなコラボレーション・ソリューションを作り上げたかお話しします。 Wednesday, Jun 16 12:00 PM - 12:30 PM JST(他) ご登録は こちら から!
Red Hatのソリューションアーキテクトの小杉です。 Red Hat にはクラウドネイティブアプリの開発に役立つ、ソフトウェアのラインナップが充実していることをご存知ですか? ここでは、それらのソフトウェア [Red Hat Application Services] に関する注目ニュースを、各製品技術に特化したソリューションアーキテクトが、ご紹介します。 今回は 2021/6月号となります。 想定読者 エンタープライズアーキテクト アプリケーション開発者 システムの提案をするSIerの方 特集1: CodeReady Workspacesをカスタマイズして便利に開発してみよう その2 CodeReady Workspacesの便利なカスタマイズ方法の第二回目のご紹介です。CodeReadyWorkspacesはEclipse CheをベースとしたWeb上で動く統合IDEといったところですが、開発環境の標準化に一役買います。 rheb.hatenablog.com 特集2: Avro スキーマを使用した Apache Kafka クライアント開発 #1 Service Registry 構築編 Apache Kafka を使ったアプリケーション開発では、Kafka の送受信時に使うデータのスキーマを保存できる Service Registry を使用することができます。Service Registry を使用すると Kafka プロデューサー側の開発で使用するスキーマが Kafka コンシューマーが使用するスキーマより新しいケースや逆のケースにおいてもスキーマエラーを発生させることなく動作させることができる前方互換性や広報互換性を持たせることができます。Kafka に限らず、REST API (OpenAPI)や GraphQL のスキーマも保存することができます。 今回は OpenShift 上で Service Registry を構築する手順についてまとめました。構築の際には新たにリリースされた Red Hat Integration Operator を使用して、Service Registry や AMQ Streams(Apache Kafka)を構築しています。 kenta-kosugi.medium.com 特集3: 【海外事例】COVID-19のワクチン接種予約の最適化 ワクチン接種の予約殺到でシステムダウン...等の障害も出ていますが、ワクチン接種の予約システムは結構なことを考える必要があり、意外と難しい課題と思います。より良い接種スケジュールを計画し実行している事例があり、OptarPlanner Blogに掲載されていましたので翻訳して掲載しました。コミュニティ名OptaPlannerのRed Hat の製品名はRed Hat Decision Managerです。 rheb.hatenablog.com 好評開催中!クラウドネイティブアプリ開発関連のWebinar全6回 Cloud Nativeを見据えたアプリケーションアーキテクチャとレガシーモダナイゼーション コンテナ時代の開発ツールチェインと開発プロセスのベストプラクティス クラウド/コンテナを前提とした時代のアプリケーション実行環境の選択 マイクロサービス/サーバーレス実践入門 これからのシステム連携を実現するデジタル基盤とアプローチ Cloud Nativeなデータパイプラインの作り方とオープンハイブリッドクラウドへの展開 各回とも、オンデマンドで視聴出来ます。(お名前とメールアドレス等の登録のみで視聴可能です) 下記リンクよりぜひご登録ください。 www.redhat.com 直近GAになった製品群 最近リリースとなった Application Services 製品はありません。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Collect JDK Flight Recorder events at runtime with JMC Agent | Red Hat Developer の翻訳記事です。 JDK Flight Recorder 、通称JFRは、 OpenJDK 8u272 から利用可能なイベントベースの本番の環境のプロファイラです。HotSpotネイティブの機能であるJDK Flight Recorderは、空間と時間の両方を使用する点で、極めて低いオーバーヘッドで動作します。 JDK Flight Recorderは、デフォルトで基本的な Java ランタイム情報を収集しますが、JFRのEvent APIを使用してカスタムイベントを収集できます。アプリケーションレベルのイベントを収集したい開発者は、アプリケーションのソースコードで積極的にイベントを定義し、インスタンス化します。 この記事では、JMC AgentとJMC Agent Pluginを使用して、イベントを発するコードでアプリケーションクラスを測定する方法を紹介します。JMC AgentをJDK Flight Recorder Event APIと共に使用する場合、JVMをシャットダウンしたりアプリケーションコードを再コンパイルする必要はありません。 注 :この記事では、JDK Flight Recorder ツール群の概要を含めていますが、JMC AgentとJMC Agent Pluginの紹介に重点を置いています。JDK Flight Recorderの詳細については、以前の記事である Get started with JDK Flight Recorder in OpenJDK 8u をご参照ください。 JDK Flight Recorderツール群の概要 JMC Agentは、 JDK Mission Control (JMC)プロジェクトのサブコンポーネントです。JDK Mission Controlは、JDK Flight Recorderとの相互作用と、JDK Flight Recorderがダンプした記録の分析に焦点を当てています。ここでは、主にJMC AgentとJMC Agent Pluginについて説明しますが、ツール群の概要を知っておくと便利です。 JDK Flight Recorder JDK Flight Recorderは、もともとJRockitのJVM機能でした。JVMの主要な統計イベントをキャプチャし、フライトレコーディングファイルに記録してオフラインでの分析に利用します。2018年、Oracleはこの機能をJDK Flight Recorderという名前でオープンソース化し、OpenJDK 11に統合しました。JFRはOpenJDK 8にもバックポートされました。 開発者はJDK Flight Recorderを使用して、本番環境のJVMをプロファイリングします。JFRは、イベントをコンパクトなバイナリ形式で記録します。一目でわかるように、JFRはこれらのイベントをまずインメモリー・バッファーに保存します。定期的に、バッファをファイルシステムや他のストアにフラッシュします。JFRは「常にオン」の本番時のプロファイラーであることを意図しており、ほとんどのユースケースで2%未満のオーバーヘッドとなっています。 JDK Mission Control フライトレコーディングをバイナリ形式で取得しても、それだけでは役に立ちません。OpenJDKはこれらの記録にアクセスし、その内容を複合するツールを提供します。しかし、 JDK Mission Control は、フライトレコーディングを分析するための最も強力で柔軟な方法です。 JDK Mission Controlは、JFRの記録を分析するために特別に設計されたGUIツールです。JDK Flight Recorderと共に、JMCは開発者にアプリケーションのランタイム特性の詳細な視点を提供します。この視点を使用して、パフォーマンスのボトルネックを特定し、JVMを細かく調整できます。また、JMCは、ローカルで動作しているJVMに接続し、新しい記録を取り、進行中の記録を制御する機能を備えています。 JMCは、 Eclipse Rich Client Platform のアプリケーションです。様々なプラグインで拡張できます。また、JMCは、GUIアプリケーションとは別に、JFRの記録を読み込んで分析するための強力なスタンドアロンAPIを提供しています。 注 : JDK Mission Controlは、Fedoraおよび Red Hat Enterprise Linux (RHEL) 7 では Red Hat Software Collections (RHSCL)経由で、 RHEL 8 ではモジュール経由で 、Windowsユーザー向けに OpenJDK developer portal から提供されています。JDK Mission Controlは、 AdoptOpenJDK のようなダウンストリーム・ディストリビューションを通じて入手もできます。 JMC Agent JMC Agent は、JMCのサブプロジェクトです。このバイトコード変成器を使用すると、実行中のアプリケーションにJFRの使用を宣言的に追加できます。JMC Agentを使用する場合、ソースコードにJFRの使用をプログラムする必要はありません。 エージェントは、JVMと同じアドレス空間で動作するため、非常に汎用性があります。アプリケーションの開始時にロードすることも、いつでも動的にロードすることも可能です。実行中の JMC Agentは、リモート Java Management Extensions (JMX) を通じて設定を行う MBean コントローラを公開します。 JMC Agent Plugin JMC Agent Plugin は、JMC Agentの機能をJDK Mission Controlに統合するために開発されています。現在、外部プラグインとして別プロジェクトで開発されています。最終的には、JMCのサブモジュールとして再構築される予定です。開発者は「JMC Agent Plugin」を使用して、JMC Agentのライフサイクルを管理し、エージェントの動作を制御できます。 JMC Agent Pluginは初期の開発段階にありますが、重要な機能は既に使用可能です。以下のセクションでは、JMC AgentおよびJMC Agent Pluginについて、JDK Mission Controlで使用可能なエージェントプラグインの構築方法を含めて詳しく説明します。 JMC Agentの紹介 イベントを生成してJDK Flight Recorderに委ねる最も一般的な方法は、JDK 9で導入された標準の jdk.jfr.* APIを使用することです。 jdk.jfr.* APIを使用してイベントを生成し、そのインスタンスを操作したい開発者は、 jdk.jfr.Event から手動で拡張する必要があります。JMC Agentから利用できる代替案は、宣言的でいつでも取り替え可能な構成を使用することです。JDK Flight Recorderは、JMC Agentや標準APIがイベントを生成するかどうかに関わらず、すべてのイベントを同じように扱います。 JMC Agentによるイベントインスタンスの作成と操作 JMC Agentは Java Instrumentation API を使って、起動直後に ClassFileTransformer を登録します。クラスローダがクラスのロードを開始すると、エージェントの ClassFileTransformer は、供給された設定に従って生成されたイベント委譲用のバイトコードを注入することによって、クラスのバイトコードを変換します。 また、エージェントがターゲットクラスへの参照を取得できる限り、クラスを再変換してリロードすることで、機能の使用を元に戻したり、更新したりできます。 JMC Agentの設計にあたっては、以下の要件を優先しました。 宣言的であること:XML設定を使用して、注入するイベントを定義できます。 目立ちすぎないこと: JMC Agentを実装するためにソースコードを変更する必要はありません。 最小限のフットプリント:リフレクションを使用する必要がなく、イベント関連の関数呼び出しを行うだけです。 痛みを伴わない:JVMをシャットダウンする必要がありません。 (下記参照) これらの機能により、JMC Agentは安全に使用でき、副作用のない製品となっています。ソースが利用できない場合や、サービスやメンテナンスをすぐには停止できない場合の本番使用に最適です。JMC Agentは、アプリケーションのためにカスタム機能を作成する必要がある状況に特に適しています。 次に、JMC AgentとJMC Agent Pluginの使用方法について説明します。 イベントに記録する情報を設定する JMC Agent の機能は、1 つまたは複数の機能に適用されます。XML 設定では、以下の情報を有効または無効にできます。 機能の実行時の特性:開始時刻、終了時刻、継続時間。 関数の入力と出力:パラメータ、戻り値、例外(ある場合)。 イベントのメタデータ:ラベル、説明、スレッドID、およびコールスタック。 式の評価については、JMC Agentを使用して、一次式(訳注:Javaの最も単純な式の集合のこと。参考 Primary Expression )の限られたサブセットを有効または無効にできます。JMC Agentは、メソッドの呼び出し、配列へのアクセス、配列やインスタンスの生成を含むものを除き、すべてのJavaの一次式を受け入れます。この設計は、静的なチェックによって評価の安全性を確保し、一定時間のオーバーヘッドを保証することを目的としています。 エージェント設定ファイル エージェント設定ファイルは、JMC Agentがアプリケーションのバイトコードをどのように計測するかを制御するXML表現です。 ドキュメントのルートは <jfragent> 要素です。現在の実装では、JMC Agentは名前空間を必要としません。 <jfragent> 要素は内部のテキストを持たず、オプションで <config> と <events> 要素を囲みます。 <config> 要素には、すべてのイベントに適用されるグローバルオプションが含まれます。現在のところ、オプションは <classprefix> , <allowconverter> , <allowtostring> となっています。 <events> 要素は、任意の数の <event> 要素を囲んでおり、しばしばプローブと呼ばれます。各 <event> 要素は <class> , <method> , メソッド <descriptor> で識別される特定の機能ポイントに寄与します。 <parameter> と <field> 要素は、与えられたパラメータの値を記録し、それに応じた表現を行います。 注 : Java Fight Recorder Template(原文のまま)の一般的な使用方法 を示す例については、JMC Agentのリポジトリを参照してください。 JMC Agentの制限事項 JMC Agentは、まだ開発の初期段階にあります。この記事を書いている時点では、次のような制約を解決しようとしています。 JMC Agentは、合成クラスを扱えません。 また、ネストクラスのプライベートフィールドにアクセスできません。 新たにアップロードされた設定は、 SystemClassLoader で定義されたクラスでのみ動作します。 JMC Agentは現在、 jdk.internal.misc.Unsafe を使用しているため、--add-opens(下記参照)でモジュールを開く必要があります。 JMC Agentは現在、JDK Mission Controlとは統合されていません。 注 :合成クラスの機能化は、間違いなくゴールではありません。 生成されたクラスの正確な名前を決定することはしばしば困難であり、それらを扱うことは困難です。ほとんどの場合、生成されたコードを機能化することは意味がありません。 JMC Agent Pluginの紹介 JMCチームは、ありがたいことに、拡張性とモジュール性に優れたEclipse Rich Client Platform上でJMCを開発しました。そのため、JMC Agent Pluginは、新しいクライアントソフトウェアを作成するのではなく、JDK Mission Controlにエージェント関連の機能を追加します。 一言で言えば、JMC Agent Pluginは、JDK Mission ControlがJDK Flight Recorderであるように、JMC Agentにとってのプラグインです。つまり、JMC Agentを制御するものです。JMC Agent Pluginは、現在も開発が進められていますが、すでにJMC Agentのライフサイクルを舵取りするのに役立っています。このプラグインを使用すると、ローカルのJVMでJMC Agentを起動し、JMX APIを介してJMC Agentに接続できます。接続すると、新規または変更された構成を適用できます。また、JMC Agent Pluginは、変換結果に関する生の情報を表示します。また、事前設定マネージャで定義済みの設定を管理したり、一連のウィザードで設定を作成・編集できます。 ライブ設定 ライブ設定ページは、JMC Agent Pluginに追加された最初の機能の一つです。これを使うと、JMC Agentに現在適用されている設定を表形式で確認できます。図1に示すように、Live Config画面の左側には、JMC Agentインスタンスで計測されているすべてのイベントがリストアップされています。右側には、各イベントの定義が表示されます。 図1:JMC Agent PluginのLive Configurationページ。 注 :将来的には、ライブ設定を事前設定マネージャに直接保存し、後で使用できるようにすることをサポートする予定です。 編集ウィザードと事前設定マネージャ XML設定ファイルの編集は、初心者には難しく、経験豊富な開発者には退屈であり、また、エラーが発生しやすいものです。JMC Agent Pluginでは、そのような手間を省くために、編集ウィザードを導入しています。編集ウィザードは、事前編集されたマネージャと共に、事前設定として知られるローカル設定テンプレートの作成、変更、管理を効率化します。事前設定は、完全なXML構成を作成する必要のない構成やイベントオプションを必要としない場合に特に有効です。図2は、JMC Agent Pluginの事前設定編集ウィザードを事前設定マネージャ画面に表示したものです。 図2:事前編集マネージャの編集ウィザードを使って、イベント構成の作成、変更、管理を行う。 ウィザードで事前設定を編集する代わりに、内蔵のXMLソースエディタを使って生の設定ファイルを手動で編集できます。今はまだありませんが、最終的にはXMLソースエディタにインラインでのエラーや警告表示を追加する予定です。 JMC AgentとJMC Agent Pluginについてご紹介しました。最後に、これらのツールを構築し、アプリケーションで実行するための簡単な手順をご紹介します。記事の最後には、デモ動画も掲載していますので、ぜひご覧ください。 JMC Agent のビルドと実行 JMC Agentをビルドして実行するには、JDK 7 以降のバージョンが必要になります。まず、JMCのソースツリーをGitHubリポジトリからクローンします。 $ git clone https://github.com/openjdk/jmc.git そして、エージェントフォルダ内のMavenを使用します。 $ mvn clean package ビルドが成功すると、 target ディレクトリの下にエージェントのJARが表示されます。 $ ls target/org.openjdk.jmc.agent-*.jar エージェントが静的に接続された状態でアプリケーションを実行するには、 -javaagent オプションを使用して、エージェントのJARパスとオプションの設定パスを指定します。 $ java -XX:+FlightRecorde -javaagent:<path-to-agent-jar>[=<path-to-agent-config>] <rest-of-your-app-cmd> JDK 9 以上での Unsafe クラスのエクスポート JDK 9 以上の環境では、エージェントが使用する Unsafe クラスに --add-opens オプションを付けてエクスポートすることを忘れないでください。 --add-opens java.base/jdk.internal.misc=ALL-UNNAMED 例えば、JMC Agentに同梱されているサンプルプログラムを実行するには、次のように入力します。 $ java --add-opens java.base/jdk.internal.misc=ALL-UNNAMED -XX:+FlightRecorder -javaagent:target/org.openjdk.jmc.agent-1.0.0-SNAPSHOT.jar=target/test-classes/org/openjdk/jmc/agent/test/jfrprobes_template.xml -cp target/org.openjdk.jmc.agent-1.0.0-SNAPSHOT.jar:target/test-classes/ org.openjdk.jmc.agent.test.InstrumentMe JMC Agent Plugin を有効にして JMC をビルドする JMC Agent PluginがJDK Mission Controlに同梱されるまでは、自分でビルドする必要があります。以下の手順を実行する前に、システムにJDK 8とMavenがインストールされていることを確認してください。 まず、JMCのソースツリーをクローンしてください。 $ git clone https://github.com/openjdk/jmc.git そして、JMC Agent Pluginのソースツリーをクローンします。 $ git clone https://github.com/rh-jmc-team/jmc-agent-plugin.git JMC Agent Pluginのソースツリーから、 agent plugin とFeatureフォルダをJMCにコピーします。 $ cp -r jmc-agent-plugin/org.openjdk.jmc* jmc/application JMCのルートディレクトリにパッチを適用する。 $ cd jmc $ patch -p0 < ../jmc-agent-plugin/scripts/diff.patch サードパーティの依存関係をローカルの p2 リポジトリに取り込み、 localhost で利用できるようにします。 $ cd jmc/third-party && mvn p2:site && mvn jetty:run 最後に、別のターミナルで、JMCをコンパイルしてパッケージ化します。 $ cd jmc/core && mvn install && cd .. && mvn package JMC Agentでもっとできること:ビデオプレゼンテーションとデモ この記事は、Red Hat JDK Mission Control チームに向けて行った社内プレゼンテーションを基にしており、現在は一般公開されています。 youtu.be デモは8分50秒からで、最近、最新の開発状況を反映して更新されました。このデモのコードは、GitHubリポジトリの Dining philosophers demo にあります。 結論 JDK Flight Recorderは、本番時のプロファイラとしての役割を担っています。この文脈では、JMC AgentはJFRツール群の強力な追加要素となります。開発者としては、JMC Agentを使えば、JVMをシャットダウンすることなく、稼働しているアプリケーションを計測できます。アプリケーションを再デプロイするために、コードをリファクタリングして再コンパイルする必要もありません。 もちろん、JMC Agentを使用する代わりの方法もあります。例えば、 Byteman は、実行中のアプリケーションに同様の機能を注入するように設定できる強力なツールです。しかし、JMC Agentは、JFRイベントの計測に特化しているため、カスタムJFRイベントを必要とする問題に適しており、使いやすくなっています。まだまだ未完成ではありますが JDK Mission ControlにJMC Agent Pluginを追加することで、このツール群の使いやすさをさらに向上させることができます。 JMC AgentとJMC Agent Pluginは現在開発中で、新機能は常に計画・実装されています。このプロジェクトに貢献したい方、アイデアや提案、フィードバックがある方は、 JMC-dev mailing list で議論に参加することができます。
みなさんこんにちは、レッドハットでソリューションアーキテクトをしている暮林といいます。 CodeReady Workspacesの便利なカスタマイズ方法の第二回目のご紹介です。 第一回目はこちら。 rheb.hatenablog.com 今回のテーマはワークスペースの標準化です。 CodeReadyWork 2.8 変更点 CodeReadyWorkspacesのレジストリについて理解する devfileレジストリー プラグインレジストリー 前提 STEP1 ワークスペース内で動かすイメージの準備 STEP2 カスタマイズするdevfileの準備 STEP3 devfileレジストリーのビルドとプッシュ STEP4 カスタムdevfileレジストリーの起動 STEP5 CodeReadyWorkspacesのインスタンスの設定変更 まとめ CodeReadyWork 2.8 変更点 標準化のお話に入る前に、CodeReadyWorkspaces2.8がGAしいくつかアップデートがあったため変更点についてご紹介しようと思います。 下記のリンクが変更点の一覧です。(要ログイン) access.redhat.com 注目すべき変更点 新しいCodeReady Workspacesのダッシュボード ダッシュボードを使用したプライベートリポジトリーからのファクトリのOpenShift OAuthフローのサポート ファクトリーURLを簡略化 devfileを使わずにスタートしたワークスペースに対するプラグインの自動リコメンデーション Lombokプロジェクトのサポート VS Code エクステンションのサイドカーファイルシステムへのアクセスへのサポート Devfileからシングルルートモードとマルチルートモードを切り替え可能に 制限されたIBM Z環境におけるインストールのサポート 個人的に注目すべき点は太字で強調したマルチルートモードの切り替えが追加された点です。 マルチルートモードというのはエディタから複数のフォルダを開いた状態のことををいいます。 VSCodeエクステンションの多くはマルチルートモードを必要としますが、デフォルトでCodeReadyWorkspacesはシングルルートモードで起動します。これをdevfileから切り替えられるようにしたというものです。利用できるVSCodeプラグインが増えてより便利になりそうですね。 CodeReadyWorkspacesのレジストリについて理解する CodeReadyWorkspacesには2つのレジストリがありそれぞれ役割が異なります。 devfileレジストリー ワークスペースのテンプレートを保管しておくレジストリーです。 第一回では自分用のdevfileを修正してコンテナを追加しましたが、修正済みのdevfileをレジストリーに登録しておくことでほかのユーザーも同じスタック(設定のようなもの)でワークスペースを起動できるようになります。下記の画像はデフォルトのスタック一覧ですが、devfileレジストリーを変更することでここの一覧を変更できます。 デフォルトのスタック一覧 プラグインレジストリー デスクトップ版のVSCodeは自由にエクステンションをダウンロードして追加することができますが、CodeReadyWorkspacesでは利用したいプラグインをプラグインレジストリーに保管しておいて、これをdevfile経由で指定することで利用することができるようになります。2.8ではUIが変更されて、下記のようにワークスペース内のUIからプラグインを指定できるようになりました。プラグインレジストリーを変更することで、下記の画像の左側にあるプラグイン一覧に表示されるプラグインを変更することができます。 プラグイン一覧 今回はdevfileレジストリーのカスタマイズ方法を実際に試していきます。 (プラグインレジストリーの方が興味がある方多いかもしれませんが、次回にご期待ください!) 前提 第一回のしばりのまま行きたいところですが、CodeReadyWorkspacesのインスタンスに対する変更とレジストリのビルドが必要なため、下記のような条件が必要となります。 標準化担当は一般開発者に比べて強い権限が必要です。 openshiftプロジェクトへの変更権限 CodeReadyWorkspacesのインスタンスへの変更権限 OpenShift ImageRegistry Operatorの変更権限 podman(またはdockerかbuildah)が実行可能なラップトップ(またはサーバーなど) 1~3は実質cluster-adminが必要ということです。 この中で若干厳しいのはpodmanの実行環境だと思います。podmanはレジストリーイメージの構築に利用します。 実はdevfileレジストリーだけであればOpenShiftのビルド機能を使うことでなんとか逃れられるのですが、プラグインレジストリーではさらにnpmとnodejsを必要とするのでOpenShiftのビルド機能ではかなり苦しくなります。 プラグインレジストリーのビルドのためにも、レジストリービルド用の仮想マシンのようなもを準備しておくことをお勧めします。ビルドだけなので使い捨てでも構いません。 レジストリーのカスタマイズの公式のマニュアルは下記のページにあります。 access.redhat.com STEP1 ワークスペース内で動かすイメージの準備 レジストリのカスタマイズの前提としては、第一回でご紹介したようにワークスペースにあたらしいコンテナを追加したいというケースを想定します。 なおかつ準備したもの以外の選択肢を削除するものとします。これから作成するdevfileだけを選択可能にするということです。標準化の第一歩です。 OpenShiftの内部レジストリはアクセス制限がかかっていますが、「openshift」というproject(namespace)に登録されているイメージは、クラスター内からなら自由に使えます。 ということで、前回の手順をopenshift projectの中で実施してイメージを作成しておいてください。 STEP2 カスタマイズするdevfileの準備 この辺りは公式手順のままですが、cloneのプロトコルgit(ssh)のままだと困る方が多いと思うので、httpに変えた手順をのせておきます。 git clone https://github.com/redhat-developer/codeready-workspaces.git cd codeready-workspaces git checkout crw-2.8-rhel-8 ここでデフォルトの中身を少しのぞいてみましょう。 dependencies/che-devfile-registry/devfiles/の中を覗いてみると、どうやらワークスペースを選択するときの一覧に対応していそうなディレクトリがみえます。 ls -l dependencies/che-devfile-registry/devfiles/ total 0 drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 00_java11-maven-microprofile-bootable drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 00_java11-maven-microprofile-xp2 drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 00_java8-maven-eap drwxrwxr-x. 2 ec2-user ec2-user 97 May 10 04:54 02_java8-maven-fuse drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_camelk drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-gradle drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-lombok drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-quarkus drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-vertx drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-vertx-http-booster drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java8-maven-spring-boot-http-booster drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 04_nodejs-configmap drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 04_nodejs-mongo drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 04_nodejs-simple drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_cpp drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_dotnet drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_go drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_php-cake drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_php-di drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_python カスタマイズ元は 03_java11-maven-quarkus になります。これ以外をどけてしまいます。 cd dependencies/che-devfile-registry/ mv devfiles devfiles_old mkdir devfiles_old/03_java11-maven-quarkus/ devfiles/ あとはdevfile.yamlをカスタマイズします。第一回で紹介した方法と同じですが、コンテナイメージを置いているプロジェクトがopenshiftにかわっていることに注意してください。 - mountSources: true command: - tail args: - '-f' - /dev/null memoryLimit: 512Mi type: dockerimage alias: toolbox image: 'image-registry.openshift-image-registry.svc:5000/openshift/my-toolbox' STEP3 devfileレジストリーのビルドとプッシュ いよいよビルドですが、ビルドしたイメージをOpenShiftの内部レジストリにプッシュするために、内部レジストリをクラスターの外に公開しないといけません。 (docker.ioやquai.ioや別のプライベートリポジトリに公開してから内部レジストリにimportする手もあります) 手順は下記のマニュアルそのままです。 access.redhat.com 前提に書いたとおりのcluster-adminに近い権限を持ったユーザーでcliからOpenShiftクラスターにログインしておいてください。 そのあとは、公式マニュアルの通りpodman loginまで実行してください。Operatorにoc patchしてからrouteが作成されてまで少しかかるので注意してください。 oc login ~~~~ oc patch configs.imageregistry.operator.openshift.io/cluster --patch '{"spec":{"defaultRoute":true}}' --type=merge HOST=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}') podman login -u $(oc whoami) -p $(oc whoami -t) --tls-verify=false $HOST podmanビルドをするスクリプトを実行します。 --organizationにあたるところが、次の手順でプッシュする時のプロジェクト名にあたるので、CodeReadyWorkspaces本体が動いているプロジェクト名を指定しておきます。 ./build.sh --organization openshift-workspaces \ --registry $HOST \ --tag 1.0 STEP 38: COMMIT default-route-openshift-image-registry.apps.xxxxxxxxxxx/openshift-workspaces/devfileregistry-rhel8:1.0 ~~~ ビルドが成功したらイメージをプッシュします。 プッシュするイメージ名は、STEP38で出力されたものを使います。 podman push default-route-openshift-image-registry.apps.xxxxxxxxxxx/openshift-workspaces/devfileregistry-rhel8:1.0 Getting image source signatures Copying blob 54a71df94483 skipped: already exists Copying blob 27567a77cb0c skipped: already exists Copying blob 123257361dae skipped: already exists Copying blob dce1930497b5 skipped: already exists Copying blob 17b23f8c2a0f skipped: already exists Copying blob c9e02f9d3afe skipped: already exists Copying blob 5756f433aebc skipped: already exists Copying blob 373b8d0281c1 skipped: already exists Copying blob bdabcafc9438 skipped: already exists Copying blob 121b74199690 skipped: already exists Copying blob 780fcde908cf skipped: already exists Copying blob 9f39e0b6c7e2 skipped: already exists Copying blob 946d7c6db7ba [--------------------------------------] 0.0b / 0.0b Copying config 897558c499 done Writing manifest to image destination Storing signatures STEP4 カスタムdevfileレジストリーの起動 公式手順ではcliから oc new-app していますが、あえてGUIからやってみましょう。 DeveloperViewから+追加を選んでコンテナーイメージを選びます。 コンテナーイメージを選択 イメージのところで「Image stream tag from internal registry」を選択すると先ほどプッシュしたイメージが選択できるはずです。 リソースはDeploymentのままでもかまいませんが、DeploymentConfigの方が若干便利で個人的には好きです。(ロールアウト操作がある) 設定 ルーティングの設定はセキュアにしておいたほうがよいでしょう。 DeveloperViewにもどったら起動したアプリケーションの右上の矢印を押して、動作確認とURLのメモを行いましょう。 動作確認としては白地のテキストが画面が出力されればOKでしょう。 STEP5 CodeReadyWorkspacesのインスタンスの設定変更 ここまで来たらもう少しです。 Operatorからたどっていって、CodeReadyWorkspacesのインスタンスの設定を書き換えます。 serverセクションの後ろにcustomChePropertiesセクションを加えます。 その中に「CHE_WORKSPACE_DEVFILE REGISTRY INTERNAL URL」と「CHE_WORKSPACE_DEVFILE REGISTRY__URL」を追加し先ほどメモしたURLを設定します。 server: cheLogLevel: INFO customCheProperties: CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '5' CHE_LIMITS_WORKSPACE_IDLE_TIMEOUT: '-1' CHE_WORKSPACE_DEVFILE__REGISTRY__INTERNAL__URL: 'https://devfileregistry-rhel8-openshift-workspaces.xxxxxxxxxxxxxx' CHE_WORKSPACE_DEVFILE__REGISTRY__URL: 'https://devfileregistry-rhel8-openshift-workspaces.xxxxxxxxxxxxxx' ちなみにここで設定している「CHE_LIMITS_USER_WORKSPACES_RUN_COUNT」はユーザー当たり起動できるワークスペース数で、「CHE_LIMITS_WORKSPACE_IDLE_TIMEOUT」はアイドルタイムアウトでワークスペースが終了されるまでのリミット時間です。割と最初にユーザーから文句が出る箇所だと思いますが、気軽に増やすとクラスターのリソースがすぐなくなってしまうので、よく考えた方がよいかと思います。 この設定を終えればあとはOperatorが勝手にConfigMapの書き換えと、CodeReadyWorkspacesの再起動をしてくれます。 公式の手順では直接ConfigMapを更新していますがおそらくこれはUpstreamのEclipse cheの手順がそのままになっているように思います。試しにやってみたとろ、秒でOperatorさんにもとに戻されました…。 再度CodeReadyWorkspacesのURLを開きなおすと、このようにすっきりしていると思います。 まとめ ここまでいかがだったでしょうか。なかなかヘビーな手順です。 しかし一度やってしてしまえば二度目からはさほど難しくはありません。 こうなってくるアイコンやディスクリプションも書き換えたくなりませんか。 devfileをもっとカスタマイズして、オンボーディング資料格納したGitリポジトリを指定しておけば、CodeReadyWorkspacesへの初回ログインからメンバーの本格参画までがスムーズになりそうですね。 標準化というのは人を縛る(低い方に合わせる)ために行うのではなく、みなが高い生産性を出すことができるような方向性で考えることが、組織や企業をよりよくしていくためのコツだと思います。 次回はプラグインレジストリーのカスタマイズを行います。実は現時点でもトライ済みなのですが、公式手順通りではカスタマイズできていない気配を感じるため(詳細未確認)、前途多難かもしれません。
Red Hatでソリューションアーキテクトをしている田中司恩( @tnk4on )です。最近は Podman や OpenShift の良さをより簡潔に伝えられないかと日々考えながら記事の寄稿などの活動も行っています。 前回 の記事では RHEL 8.4 BetaとPodman v3について紹介しましたが、 ついにRHEL 8.4 がGAになりイメージの入手が可能になりました。有効なサブスクリプションをお持ちの場合や、 Red Hat Developer Program のアカウントをお持ちの場合は今すぐに入手できます。なお、 評価版 についてはこの記事執筆時点ではRHEL 8.3のままのようです。 今回は前回記事でも触れたPodman v3でdocker-composeを実行する方法について紹介します。 前回記事はこちらです。 rheb.hatenablog.com (追記)この記事の続きの記事を書きました。ルートレスモードでdocker-composeを使用する場合は下記記事を参照ください。 rheb.hatenablog.com PodmanのREST APIを確認してみる Podmanでdocker-composeを実行する docker-composeのインストール podman-pluginsのインストール podman.socketサービスの起動 docker-compose.ymlの作成 DOCKER_HOST環境変数の設定 docker-composeの実行 (参考)podman network まとめ PodmanのREST APIを確認してみる Podman v3におけるdocker-composのサポートはDocker互換のインターフェースとしてREST API *1 がサポートされたことにより実現しています。 PodmanのREST API仕様はこちら。 docs.podman.io RHEL 8.4上でPodmanのREST APIのテストをした結果はこちらです。なおPodman APIソケットを有効にするには、後ほど紹介する podman.socket サービスを起動する必要があります。 podman version に相当するコマンド # curl -s --unix-socket /run/podman/podman.sock http://d/v3.0.0/libpod/info | jq .version 出力結果を開く { "APIVersion": "3.0.0", "Version": "3.0.2-dev", "GoVersion": "go1.15.7", "GitCommit": "", "BuiltTime": "Wed Apr 7 17:36:54 2021", "Built": 1617784614, "OsArch": "linux/amd64" } podman pull docker.io/library/hello-world に相当するコマンド curl -XPOST --unix-socket /run/podman/podman.sock -v 'http://d/v3.0.0/images/create?fromImage=docker.io%2Flibrary%2Fhello-world' 出力結果を開く * Trying /run/podman/podman.sock... * Connected to d (/run/podman/podman.sock) port 80 (#0) > POST /v3.0.0/images/create?fromImage=docker.io%2Flibrary%2Fhello-world HTTP/1.1 > Host: d > User-Agent: curl/7.61.1 > Accept: */* > < HTTP/1.1 200 OK < Api-Version: 1.40 < Content-Type: application/json < Libpod-Api-Version: 3.0.0 < Server: Libpod/3.0.0 (linux) < Date: Tue, 18 May 2021 19:42:35 GMT < Content-Length: 198 < {"status":"pulling image () from docker.io/library/hello-world:latest (Download complete)","progress":"","progressDetail":{},"id":"d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726"} * Connection #0 to host d left intact podman list images に相当するコマンド # curl --unix-socket /run/podman/podman.sock -v 'http://d/v3.0.0/libpod/images/json' | jq 出力結果を開く * Trying /run/podman/podman.sock... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to d (/run/podman/podman.sock) port 80 (#0) > GET /v3.0.0/libpod/images/json HTTP/1.1 > Host: d > User-Agent: curl/7.61.1 > Accept: */* > < HTTP/1.1 200 OK < Api-Version: 1.40 < Content-Type: application/json < Libpod-Api-Version: 3.0.0 < Server: Libpod/3.0.0 (linux) < Date: Tue, 18 May 2021 19:44:59 GMT < Content-Length: 596 < { [596 bytes data] 100 596 100 596 0 0 8514 0 --:--:-- --:--:-- --:--:-- 8637 * Connection #0 to host d left intact [ { "Id": "d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726", "ParentId": "", "RepoTags": [ "docker.io/library/hello-world:latest" ], "RepoDigests": [ "docker.io/library/hello-world@sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792", "docker.io/library/hello-world@sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c" ], "Created": 1614986725, "Size": 19981, "SharedSize": 0, "VirtualSize": 19981, "Labels": null, "Containers": 0, "Names": [ "docker.io/library/hello-world:latest" ], "Digest": "sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c" } ] Podman v2でREST APIがサポートされた時の紹介記事も参考にしてください。 www.redhat.com Podmanでdocker-composeを実行する ここからはPodmanでdocker-composeを実行する手順を紹介します。 なお、RHEL 8.4に搭載されているPodman(v3.0.2-dev)ではルートモードによる実行しかサポートされていません。ルートレスで実行した場合にはエラーになります。ルートレスでdocker-composeを実行するには、現在開発中の Podman v3.2.0以降 が必要です(2021/5/19、時点)。 docker-composeのインストール docker-composeは pip で簡単にインストールできます。 docker-composeのドキュメント では配布バイナリを使用する方法も紹介されています。 # dnf install python3-pip # pip3 install -U pip # pip3 install docker-compose podman-pluginsのインストール docker-composeを使ったアプリケーションでは複数のコンテナ間の通信をコンテナ名で行うように指定されていることが多くありますが、Podmanはデフォルトでコンテナ名での通信はできません。Podmanでは dnsname プラグインを使用することでローカルDNSレコードをコンテナに割り当ててコンテナ間で通信することができます。 dnsname プラグインは podman-plugins という名前のパッケージで dnf コマンドで追加できます。また同時に dnsmasq も追加されます。 # dnf install podman-plugins podman.socket サービスの起動 Podmanのインストール初期状態ではREST APIの待ち受けサービス(Podman APIソケット)が起動していませんので、下記の手順でサービスを起動します。 # systemctl enable podman.socket Created symlink /etc/systemd/system/sockets.target.wants/podman.socket → /usr/lib/systemd/system/podman.socket. # systemctl start podman.socket # systemctl status podman.socket ● podman.socket - Podman API Socket Loaded: loaded (/usr/lib/systemd/system/podman.socket; enabled; vendor preset: disabled) Active: active (listening) since Wed 2021-05-19 04:35:50 JST; 17s ago Docs: man:podman-system-service(1) Listen: /run/podman/podman.sock (Stream) CGroup: /system.slice/podman.socket 5月 19 04:35:50 rhel84 systemd[1]: Listening on Podman API Socket. サービスの正常起動後、先に紹介したREST APIの確認手順で応答があれば準備完了です。 docker-compose.ymlの作成 docker-composeの実行サンプルアプリとしてWordPressを使用します。docker-composeの実行に必要な docker-compose.yml ファイルは、Docker Hubに載っているものを流用します。 https://hub.docker.com/_/wordpress 適当なディレクトリを作成して、 docker-compose.yml ファイルを配置してください。 # mkdir wordpress && cd wordpress # vi docker-compose.yml docker-compose.yml version: '3.1' services: wordpress: image: wordpress restart: always ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: exampleuser WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_NAME: exampledb volumes: - wordpress:/var/www/html db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: exampledb MYSQL_USER: exampleuser MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql volumes: wordpress: db: DOCKER_HOST環境変数の設定 通常、docker-composeは docker コマンドを介して実行されるため、DOCKER_HOST環境変数にはdockerデーモンのURLが指定されます。Podmanでdocker-composeを実行する場合は、 podman.socket サービスで起動したPodman APIソケットを指定します。 # export DOCKER_HOST=unix:///run/podman/podman.sock docker-composeの実行 docker-compose.yml ファイルがあるディレクトリで docker-compose up を実行します。 -d オプションをつけることでデタッチモードでの実行になります。 # docker-compose up -d Starting wordpress_db_1 ... done Starting wordpress_wordpress_1 ... done 正常にコンテナが実行されているか確認します。 # docker-compose ps Name Command State Ports ------------------------------------------------------------------------------ wordpress_db_1 docker-entrypoint.sh mysqld Up wordpress_wordpress_1 docker-entrypoint.sh apach ... Up :8080->80/tcp # podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bd63862f4042 docker.io/library/wordpress:latest apache2-foregroun... 12 minutes ago Up 13 seconds ago 0.0.0.0:8080->80/tcp wordpress_wordpress_1 bf023e2b9b71 docker.io/library/mysql:5.7 mysqld 12 minutes ago Up 13 seconds ago wordpress_db_1 ブラウザで http://<ホストのIPアドレス>:8080 へアクセスしてWordPressのインストール画面が表示されたらOKです。 WordPressのインストール画面 (参考)podman network docker-composeの実行時に自動的に専用のネットワーク(今回は wordpress_default )が作成されます。 # podman network ls NAME VERSION PLUGINS podman 0.4.0 bridge,portmap,firewall,tuning wordpress_default 0.4.0 bridge,portmap,firewall,tuning,dnsname 作成されたネットワークの設定ファイルは /etc/cni/net.d/ 配下にあり、中身を確認することもできます。 # cat /etc/cni/net.d/wordpress_default.conflist 出力結果を開く # cat /etc/cni/net.d/wordpress_default.conflist { "args": { "podman_labels": { "com.docker.compose.network": "default", "com.docker.compose.project": "wordpress", "com.docker.compose.version": "1.29.2" } }, "cniVersion": "0.4.0", "name": "wordpress_default", "plugins": [ { "type": "bridge", "bridge": "cni-podman1", "isGateway": true, "ipMasq": true, "hairpinMode": true, "ipam": { "type": "host-local", "routes": [ { "dst": "0.0.0.0/0" } ], "ranges": [ [ { "subnet": "10.89.0.0/24", "gateway": "10.89.0.1" } ] ] } }, { "type": "portmap", "capabilities": { "portMappings": true } }, { "type": "firewall", "backend": "" }, { "type": "tuning" }, { "type": "dnsname", "domainName": "dns.podman", "capabilities": { "aliases": true } } ] } まとめ RHEL 8.4から導入されたPodman v3を使ってdocker-composeを実行する方法をご紹介しました。RHEL 8.4に搭載されているPodman v3.0.1ではルートモードのみしかdocker-composeが実行できませんが、現在開発版として公開されているv3.2.0-RC1ではルートレスでdocker-composeが実行できることを確認しています。 RHEL 8.4でv3.2.0以降が使用できるようになった時は、ルートレスモードの実行方法についてもご紹介します。楽しみにしておいてください。 *1 : 本記事ではREST APIで統一して記載。REST APIはRESTful APIとも言います。REST APIに関するRed Hatの紹介ページはこちら。 https://www.redhat.com/ja/topics/api/what-is-a-rest-api
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Introduction to ContainerJFR: JDK Flight Recorder for containers - Red Hat Developer の翻訳記事です。 OpenJDKは長い間、実世界のアプリケーションやワークロードのトップに君臨してきました。これは、パフォーマンス、互換性、信頼性、そして観察可能性を一体化して選ばれています。長年にわたり、JDK Flight Recorder (JFR) と JDK Mission Control (JMC) は、OpenJDKの成功に貢献してきました。しかし最近まで、どちらも商用機能であり、特定のユーザやワークロードでしか利用できませんでした。 2018年、JDK Mission ControlとJDK Flight Recorderがオープンソース化されました。JDK Flight Recorderは現在、OpenJDK 8の後期リリースとOpenJDK 11以降のすべてのバージョンのJava Virtual Machine(JVM)に組み込まれています。これらのツールがオープンソース化されたことで、そのパワー(常時稼働、ゼロオーバーヘッドに近いプロダクション・プロファイリングとモニタリング、アプリケーション固有のカスタムイベント、統合コアJDK分析ツール)がすべてのJDKユーザーに提供されます。一方で、JDK Mission ControlとJDK Flight Recorderは、コンテナ化が急速に進む世界に登場しました。これは、これらのために設計された物の見方や捉え方ではありません。 デスクトップ専用のJDK Mission Controlアプリケーションでは、開発者や管理者がローカルディスク上のフライトレコーダにアクセスする必要があります。それ以外の場合は、クラウド上のJava Management Extensions(JMX)を介してアプリケーションに直接接続するという、複雑で潜在的に安全でない設定に頼ることになります。同様に、ベアメタルに特化したJDK Flight Recorderでは、JVMがローカル・ファイルシステムに記録をダンプできますが、アプリケーションがコンテナ内で実行されている場合はできません。その場合、ファイルシステムは外部から容易にアクセスできず、記録を取得して分析することはできません。 この記事では、Red Hatの製品になる途中の若いプロジェクトである ContainerJFR を紹介します。ContainerJFRは、クラウド上のJDK Flight Recorderと、エンドユーザーのワークステーションとの間の隙間を埋めることを目指しています。 手動でContainerJFRのインストールとセットアップ ContainerJFRを手動でインストールするには、 Quay.io で利用可能なイメージを使用するのが簡単です。以下を実行して、基本的なインストールと製品のデモを行ってください。 $ podman run -it --rm -p 8181 -e CONTAINER_JFR_WEB_HOST=0.0.0.0 quay.io/rh-jmc-team/container-jfr:latest より本格的なデモンストレーションを行うには、ContainerJFRのリポジトリをクローンして、その smoketest.sh を実行します。以下では、テストやデモのために、Podmanポッドにいくつかのコンテナをセットアップしています。 $ git clone https://github.com/rh-jmc-team/container-jfr $ cd container-jfr $ sh smoketest.sh ContainerJFRの認証情報は、今回の場合、 smoketest:smoketest です。もう一つのアプリケーションの認証情報は admin:adminpass123 です。 Red Hat OpenShiftでのContainerJFRをデプロイ Red Hat OpenShift や他のKubernetesクラスタにアクセスできる場合は、 ContainerJFR Operator を使ってContainerJFRをクラスタにデプロイできます。 $ git clone https://github.com/rh-jmc-team/container-jfr-operator $ cd container-jfr-operator $ oc login # 最初に稼働中のOpenShiftクラスタにログインしていることを確認してください。 $ make deploy # ContainerJFR CR、必要なServiceAccountとRole/RoleBindingsなどとともに、Operatorをクラスタに直接デプロイします。 $ make catalog # make deployの代替となります。これにより、カスタムカタログソースがクラスタに追加され、管理者ビューのOperatorHubパネルからOperatorをインストールできます。 注 :まだOpenShiftやKubernetesのクラスタにアクセスできない場合は、 Red Hat CodeReady Containers を試してみてください。 図1は、カスタムカタログソースを追加するために $ make catalog を発行した後のOpenShift OperatorHubのContainerJFRを示しています。 図1:OpenShift OperatorHubのContainerJFR 図2は、デフォルトの名前空間にインストールされたContainerJFRインスタンスです 図2:ContainerJFRをプロジェクトの名前空間にインストール ContainerJFRをインストールしたら、図3に示すように、そのためのカスタムリソースを作成します。名前は好きなものを選び、 minimal の設定は false のままにしておきましょう。 図3:ContainerJFRのカスタムリソースの作成と設定 しばらくすると、OperatorはContainerJFRとそのサービスのデプロイを終了します。公開されたルートURLを表示する任意のビューを使用して、ContainerJFRのWebクライアントを見られます。図4は、OpenShiftのトポロジービューでContainerJFRを示しています。 図4:OpenShiftのトポロジービューでのContainerJFR 次に、ContainerJFRの主な機能を紹介し、コンテナ管理されたOpenJDKアプリケーションに設定する方法を紹介します。 ContainerJFRによる発見 ContainerJFRは、OpenJDKアプリケーションと一緒に「サイドカー」として動作するコンテナ型のJVMです。ランタイム環境に応じて、JMX対応のアプリケーションを検出するための最適な戦略を自動的に選択します。 docker-compose や podman-compose で動作するアプリケーションの場合、ContainerJFRは Java Discovery Protocol (JDP)を使用します。KubernetesやOpenShiftで動作するアプリケーションの場合は、エンドポイントを使用することになります。これらは、ContainerJFRが現在提供しているプラットフォーム実装の一例に過ぎません。異なるコンテナプラットフォームのためにカスタマイズされたサポートが必要な場合は、簡単に拡張できます。 Java Management Extensions アプリケーションでJMXが有効になっており、JMXポートが公開されていてContainerJFRが到達可能であることを確認してください。現実的には、アプリケーションの起動時に以下のJVMフラグを渡すことを意味します。 -Dcom.sun.management.jmxremote.port=9091 -Dcom.sun.management.jmxremote.rmi.port=9091 次に、ポートを公開します。これには、お使いのコンテナプラットフォームが採用しているメカニズムを使用します。OpenShiftやKubernetesでは、デプロイメント用のサービスを作成し、そのサービスに公開ポートを追加します。デフォルトでは、ContainerJFRはJMXのために9091ポートを使用しますが、ポートに jfr-jmx という名前をつければ、任意のポート番号を使用できます。 図5は、OpenShift TopologyビューでContainerJFRと2つのサンプルアプリケーションを表示しています。 図5:ContainerJFRと2つのサンプルアプリケーション。 Java Discovery Protocol PodmanやDockerで動作させている場合や、ホストマシン上でローカルのJVMプロセスを直接動作させている場合は、Java Discovery Protocol(JDP)も有効にしておく必要があります。 -Dcom.sun.management.jmxremote.autodiscovery=true ContainerJFRのイベントテンプレート ContainerJFRは、JDK Flight Recorderのイベントテンプレートをサポートしています。これは、サポートされるイベントタイプと構成プロパティを事前に設定するものです。イベントテンプレートを使用することで、アプリケーションにとって意味のあるデータを取得する作業が簡単になります。また、ContainerJFRには、ターゲットJVMのJDK Flight Recorderフレームワークに登録されているすべてのイベントタイプを表示するビューがあります。このビューは、独自のイベントテンプレートを作成または修正する際に便利です。 図7のEvent Templatesビューには、あらかじめ設定されたイベントテンプレートが表示され、ローカルマシンにダウンロードして検証または修正できます。テンプレートを修正した後は、アップロードして再利用できます。また、テンプレートから記録を作成できます。 図7:ContainerJFRのイベントテンプレート 図8のEvent Typesビューには、選択したターゲットJVMに登録されているすべてのイベントタイプが表示されます。このビューを使用して、カテゴリ、キーワード、またはプロバイダでイベントを検索できます。 図8:ContainerJFRのイベントタイプ テンプレートの編集 ContainerJFRを使って、ターゲットJVMからローカルマシンにテンプレートをダウンロードし、お気に入りのテキストエディタでテンプレートのXMLドキュメントを開いて確認できます。JDK Mission Controlを使ってテンプレートをインポートし、編集することもできます。図9は、イベントテンプレートをダウンロードするためのダイアログです。 図9:イベントテンプレートをローカルディスクにダウンロードする カスタムテンプレート カスタムテンプレートを作成したり、既存のテンプレートに変更を加えた後、ContainerJFRに再アップロードすると、そのテンプレートは今後も使用できるように保持されます。このテンプレートは、JVMアプリケーションで新しいレコーディングを行う際に適用できます。 イベント・テンプレートは、任意のプレーンテキスト・エディターで開いて編集できます。また、JDK Mission Controlのグラフィカルなテンプレート・エディタを使用して、テンプレートのインポート、編集、エクスポートを行えます。図10は、プレーンテキスト・エディターのイベント・テンプレートを示しています。 図10:任意のエディタを使用して、XML形式のイベントテンプレートを修正 新規または修正したテンプレートをアップロードすると、ContainerJFRは図11に示すようにテンプレートを検証します。 図11:テンプレートは、サーバーが受信すると検証される 図12は、ContainerJFRインスタンスで利用可能なすべてのテンプレートを示しています。 図12:後で使用できるテンプレートの一覧。 これらの機能はすべて、JDK Flight RecorderのCustom Events APIとも連携しています。アプリケーションの開発中にアプリケーション固有のイベントタイプを作成し、これらのイベントを含むカスタムイベントテンプレートを作成して、独自の継続的な本番環境の記録を仕立てられます。 ContainerJFRでの録音 ContainerJFRでは、カスタムレコーディング、スナップショット、アーカイブなど、いくつかの方法でレコーディングをキャプチャし、保存できます。 カスタムレコーディング 図13は、新しいカスタムレコーディングを設定する際に定義する構成プロパティです。 図13:カスタムレコーディングの作成 まず、記録の名前ですが、ContainerJFRはターゲットごとの一意性を確保するために使用します。また、記録が自動的に停止されるまでの期間や、手動で停止されるまで継続して実行するかどうかを設定します。記録するイベントのイベント指定文字列またはテンプレートを設定する必要があります。高度なプロパティには、"to disk"、"max size"、"max age "などがあります。これらのプロパティの詳細については、JDK Flight Recorderのドキュメントをご参照ください。 スナップショット 図14は、新しいスナップショット記録を作成するためのダイアログです。スナップショットとは、他の記録で取得したすべての情報の概要です。 図14:ワンクリックでスナップショット記録を作成 ターゲットで複数のカスタム記録を同時に実行している場合、スナップショットを使用して、その時点で新しい記録ファイルを作成できます。スナップショットには、他のすべての記録のデータがマージされています。スナップショットは、特定の時点での単一の連続記録のデータを保存するのにも便利です。 データの流れ 記録を作成する際、ContainerJFRにフライトレコーダを開始する命令をターゲットJVMに送信するよう依頼します。この時点では、アプリケーションの外部にデータは転送されず、記録の名前、状態、開始時間、およびその他の基本的なメタデータのみが転送されます。記録データは、コンテナ内のターゲットアプリケーションのメモリにのみ保存されます。 図15:ContainerJFRは、選択したターゲットJVMに存在するすべてのレコーディングを表示 アーカイビング アーカイブは、記録のスナップショットをアプリケーションからContainerJFRにストリーミングします。ContainerJFRは直ちにスナップショットをローカルディスク(OpenShiftやKubernetesでは永続ボリューム)に書き込み、メモリから削除します。アプリケーションがスケールダウンするなどして消えてしまっても、分析のために記録データにアクセスできます。誤って .jfr ファイルを削除してしまっても、ワークステーションのローカルディスクからアーカイブに再アップロードできます。これは、ContainerJFRをクラスタから削除して、後で再インストールした場合にも有効です。 図16のアーカイブされた記録リストには、ContainerJFRのパーシステントストレージに保存されたすべての記録が表示されます。これは、すべてのターゲットJVMで共通です。 図16:ContainerJFRの永続ストレージに保存された記録データ ContainerJFRによる自動解析 ContainerJFRでは、ローカルマシンやクラスター外部にデータを転送することなく、クラウドのデプロイメント内でフライトレコーディングの自動分析を実行できます。この機能を使えば、接続速度の遅いホテルや空港から、スマホやタブレットだけでアプリケーションの健全性をチェックできます。 図17のアクティブな記録とアーカイブされた記録のリストを展開すると、クラスター内で生成された自動分析結果が表示されます。 図17: アクティブな記録とアーカイブされた記録の自動分析レポート 記録を拡張すると、ContainerJFRはJDK Mission Controlのバックエンドを使用して自動分析レポートを生成し、アプリケーションの明らかな問題や可能性のある問題を警告します。また、レポートをHTML形式で保存し、後で参照できます。 分析にGrafanaを使う 自動分析レポートに十分な情報が含まれていない場合や、より詳細に検証したい問題が指摘された場合は、ContainerJFRポッド内の jfr-datasource エクスポータに記録を送れます。そこから、 Grafana を使ってデータを見られます。図18は、記録リストアイテムのアクションメニューを示しており、これを使って記録をGrafanaダッシュボードに送信できます。 図 18: さらなる分析のために記録を Grafana ダッシュボードに送信 ContainerJFRは、時系列データを含む構成済みのダッシュボードを提供していますが、重要なメトリクスを含む独自のダッシュボードを作成することが推奨されます。繰り返しになりますが、あなたのデータはクラスタから出ないことに注意してください。 .jfr ファイルからGrafanaのメトリクスへの変換を行う jfr-datasource はContainerJFRポッド内に隠されており、Grafanaダッシュボードのインスタンスは生成された認証情報(OpenShiftやKubernetesのシークレットに保存されている)で保護されてから外部に公開されます。その生成された認証情報は、以下のコマンドで簡単に取り出すことができます。 $ oc get secret containerjfr-grafana-basic -o json | jq -crM .data.GF_SECURITY_ADMIN_USER | base64 -d $ oc get secret containerjfr-grafana-basic -o json | jq -crM .data.GF_SECURITY_ADMIN_PASSWORD | base64 -d 認証情報を取得したら、図19に示すように、Grafanaダッシュボードのログインページにプラグインして、メトリクスの表示を開始します。 図19:設定済みのGrafanaダッシュボードでは、アプリケーションのパフォーマンスをより詳細に把握できます(バッテリーが含まれインストール済)。 解析にJDK Mission Controlを使う 最後に、さらに詳細な情報が必要な場合は、ContainerJFRから記録ファイルをローカルディスクにダウンロードし、フル機能を備えたオフラインのJDK Mission Controlデスクトップ・アプリケーションで開くことができます。これは、記録ファイルが実際にクラスタを離れる唯一のシナリオです。 図20:JDK Mission Controlデスクトップ・アプリケーションを使用して、クラウド・アプリケーションから収集したデータを深堀り JDK Mission Controlデスクトップ・アプリケーションは豊富な機能を提供していますが、その議論は別の記事に譲りましょう。 ContainerJFRによるセキュアな認証 JDK Flight Recorderは、大きなランタイムオーバーヘッドなしに膨大な量のデータを取得します。データを安全に保ち、その完全性を確保することは極めて重要です。図21に示すように、ContainerJFRは、アプリケーションがJMX接続を世界中に公開する必要はなく、OpenShift名前空間やDockerまたはPodmanネットワーク内からの接続にのみ公開します。 図21: 安全なContainerJFRの展開の概要 ContainerJFRは、Java Flight Recorder(原文のまま)のデータのコピーを受け取った後は、指示に基づいて、セキュアなAPIリクエストを通じてのみデータにアクセスできます。セキュリティで保護されたAPIリクエストは、アプリケーションに接続するためのJMX認証と、ContainerJFRに接続するための別の認証層をサポートしています。 OpenShiftで実行する場合、図22に示すように、すべての機密性の高いAPIリクエストは、認証のためにユーザーアカウントトークンを必要とします。なお、HTTPまたはWebSocketを介したクライアントからContainerJFRへのリクエスト、およびJMXを介したContainerJFRからターゲットへのリクエストは、すべてデフォルトでSecure Socket LayerまたはTransport Layer Security(SSL/TLS)プロトコルをサポートし、有効になっています。 図22:ContainerJFRはOpenShiftクラスタの認証サーバを利用してユーザ認証 ContainerJFRの今後の予定 ContainerJFRはまだ若いプロジェクトであり、コンテナやモニタリングの世界は常に拡大しているため、私たちの視野には多くのものがあります。将来的には、ContainerJFRに以下のような変更や改良を加えていきたいと考えています。 ContainerJFRが対象となるアプリケーションを識別し、グループ化し、ラベル付けするためのより優れた柔軟な方法を実装します。例えば、OpenShiftやKubernetesのラベルやアノテーションを調べられます。 1回のリクエストでターゲットグループ全体の記録を管理するために使用される、バッチ操作のサポートを追加します。 トリガー機能の追加により、事前に定義されたイベントが発生したときに、ターゲットまたはターゲットグループで記録を自動的に開始および停止できるようになりました。例えば、新しいターゲットが現れたときに、事前に定義されたテンプレートで自動的に記録を開始できます。 Grafanaのビューやその他のビジュアライゼーションをContainerJFRのWebクライアントに直接埋め込む。 デスクトップのJDK Mission Controlアプリケーションに統合またはディープリンクを提供する。 今後のアップデートについては、 ContainerJFRリポジトリ をご覧ください。
こんにちは、Red Hat で OpenShift を担当しています。花田です。 Red Hat の Kubernetes の Cluster 管理製品である ACM (Advanced Cluster Management) では、バージョン2.2 より テクノロジープレビュー として、Sumbariner というコンポーネントが使えるようになりました。 Submariner は端的に言うと、異なる Kubnerentes クラスター間をオーバーレイネットワークで結ぶためのコンポーネントです。 正確には異なるクラスター間で、Kubernetes の Service 名を解決するための Lighthouse というプロジェクトもセットで使われています。 Submariner を使用するための現時点での条件 現時点での 前提条件 は複数ありますが、マニュアルから一部をピックアップすると ACM の Hub を稼働させる OCP 4.5 以上 相互ネットワークで接続されるクラスターのバージョンは OCP 4.4以降 各クラスターの Pod 、サービスが使用している CIDR は重複していない事 等があります。 最後のCIDRの重複については、アップストリームの Submariner 側では、 Globalnet Controller というオプショナルなコンポーネントを使って解決させる事が既に考えられているようです。 Submariner のアーキテクチャー 大体のアーキテクチャーと、コンポーネント名は覚えておいた方が何かと便利なので、ほぼ公式ドキュメントページの翻訳ですが、以下に記します。 コンポーネント名や用語が、アップストリームの Submariner のドキュメントと ACMのマニュアルで若干異なる所があるのですが、ここから以下はアップストリームの用語を基準としています。 Gateway Engine : クラスター間のトンネリングを管理する Engineです。Daemonsetとして、"submariner.io/gateway=true" のラベルが付いた Node に配られます。 Broker : Gatway Engine 間のメタデータの交換を助けるコンポーネントです。CRD(Custom Resrouce Definition) とそれを保管している Kubernetes の事を指し PodやService がデプロイされるわけではありませ Route Agent :ノードから アクティブな Gateway Engine へトラフィックをルートする Agentです。Kubernetes の各 Node に存在します。 Service Disovery : クラスター間の サービスの DNS解決を提供するコンポーネント Lighthouse Agent : 各クラスター内部に存在しているAgentで、Broker を通じて Service の情報の metadata を他のクラスターと交換します。 これらを図で表すと以下のような感じになります。ACM Hub は、この絵の中では、"Broker" となります。コンポーネントの配置は ACMでデプロイされる配置を実際に確認したわけではなく、アップストリーム Submariner のドキュメントを元に書き起こしたものになりますのでご了承下さい。 Gateway Engine の置かれた Gateway Node 間は、IPSECで結ぶ事で、異なるクラスター間のネットワークを接続します。仕組み自体は非常にシンプルです。 耐障害性も考えられており、トラフィックの出入り口になる Gateyway Node は、Acitve - Passive構成を取り、Active側の障害時には、Passive 側に切り替えが行われます。 Broker は一つしかありませんが、Broker のダウンは、Submariner に参加しているクラスターの通信に影響を与えません。新規に追加されたクラスターなどは検知できなくなりますが、Brokerが復活次第、情報の Update や同期が再開されます。 ClusterSet ClusterSet という概念も導入されています。ClusterSet は、2つ以上のクラスターで構成されるグループの事です。Submariner を有効化する時には、ACM上から複数のクラスターで構成されるClusterSet に対して、Submariner を add-on を有効化する事で、クラスター間のネットワークが構成されます。 Service の公開 他のクラスターに対して、Service を公開するには、 ServiceExport オブジェクトを作成 して、service を export します。 export された Service は、 [service].[namespace].svc.clusterset.local としてアクセス可能になります。 この時、クラスターをまたいで使用できるこの Service の名前解決は、Lighthouse DNS Server が行います。 Lighthouse DNS Server は、clusterset.local のドメイン名を所有する権威DNSとして振る舞います。Kubernetes の CoreDNS から clusterset.local の名前解決をフォワードされ、Lighthouse Agent が Broker 経由で取得してきた他のクラスターの Service のmetada を元に、Service 名を解決します。 分散環境でのKubernetes の今後 コンテナの小ささは、遠隔地にもアプリケーションを簡単に展開しやすくするため、地理的に離れた場所や、Edge でのアプリケーション展開に Kubernetes 利用したいという需要がでてきています。その場合、複数作成され、地理的に分散されたKubernetes クラスタを、もっとシンプルに透過的に使用したくなるのは当然で、Submariner もそうした背景を元に開発されてきたのだと思います。 また、距離がある場合はレイテンシーの問題はつきまといますが、Database のようなデータを扱うサービスは、そのまま一つのクラスタに偏在させておき、他のクラスターから(外部サービスとして公開せずに)内部サービスとして利用する。という事が Submariner の登場によって出来るようになりました。 一方で、データ自体も分散させてしまう、 Cockroach DB のような分散型のDatabaseもではじめています。 今後も新たな技術が登場し、熟成して行くと思いますが、コンテナの特性が新しい方向に技術をドライブ、発展させていくのは何とも楽しみです。 関連ドキュメント Submarinerドキュメントのサイト :: Submariner k8s project documentation website GitHubのプロジェクト GitHub - submariner-io/submariner: Connect all your Kubernetes clusters, no matter where they are in the world. GitHub - submariner-io/lighthouse: Controller to facilitate DNS discovery between clusters Red Hat の関連ブログ (英語) Multicluster Service Discovery in OpenShift (Part 1) Multicluster Service Discovery in OpenShift (Part 2)
2021/3/4 Paul Brown / Emily Murphy 共著 (本記事はOptaPlannerに投稿された記事の日本語訳になります。オリジナルはこちら) https://www.optaplanner.org/blog/2021/03/04/OptimizingCovid19VaccinationScheduling.html COVID-19の予防接種の予約は世界的な課題となっています。予防接種の対象となる人々は、何度も予約を試みているにもかかわらず予約を確保できていません。予防接種を受ける予定の人が予防接種センターに到着して初めて、予約がキャンセルされたことを知ることもあります。また、同じ時間帯に何百人もの人が並んでいて何時間も待たされることもあります。しかし、そのようなことにならないようにすることができます。OptaPlannerの予防接種予約スケジューラークイックスタートを使えば、効率的かつ公平なスケジュールを組むことができます。予防接種予約スケジューラーは人工知能(AI)を使用して、複数の制約や優先順位に基づいて人々に優先順位を付け、時間枠を割り当てます。これは、GitHubで公開されている OptaPlannerのクイックスタート・コレクション の一部です。 OptaPlannerの予防接種予約スケジューリングのビデオ もあります。続きをお読みください。 予約計画システムの自動化の利点 予約の計画には、大きく分けて2つのアプローチがあります。システムがユーザーに予約の枠を選択させる方法(ユーザーが選択)と、システムが枠を割り当て、ユーザーにいつどこに行けばいいかを伝える方法(システムが自動的に割り当てる)です。 この2つのアプローチを簡単に比較してみましょう。 ユーザーが選択する場合 この方法は、Ticketmaster™などのコンサートチケットサイトで採用されている方法と似ています。ほとんどのコンサートチケットは、この方法で販売されています。人々は、一定の数のチケットや予約をめぐって互いに競い合います。 このアプローチの特徴 先着順に受け付けます。 予約可能な時間帯と場所の中から希望のものを選択します。 このアプローチの課題 先着順では公平ではないかもしれません。 システムが過負荷になると、インターネットの速度が遅い人を何度もシャットアウトされてしまいます。 同じ時間に多くの人が予約をしようとすると、1人を除いて予約が取れないことがあり、ユーザーエクスペリエンスが低下します。予約を諦めてしまう人もいるかもしれません。一方で、望ましくない予約枠は埋まらないかもしれません。 優先順位、年齢、2回目の接種の有無などの基準に基づいて優先順位を決めるのは厄介です。 希望するワクチンの種類(Pfizer™、Moderna™、AstraZeneca™)がないかもしれません。 ユーザーが選択する方法は、予防接種のスケジュールを立てる上で最も効率的な方法ではないと言えるでしょう。人々は最も近い予防接種センターを選ぶことができますが、そのセンターが最大の収容力を持っているとは限りません。1人の人間にとって良いことが、集団全体にとって良いこととは限らないのです。個人のニーズに合った予防接種センターに誘導し、同時に人口全体にとってもキャパシティの関係で効率的な予防接種センターに誘導する方法が、このシステムにはありません。また、システムは簡単に過負荷になります。 システムが自動的にアサインする場合 このプッシュ型のアプローチでは、人々がシステムに情報を提供すると、システムが予約枠を割り当てます。 このアプローチの特徴 予約枠は優先順位に基づいて割り当てられます。 事前に設定された計画制約に基づいて、最適な予約時間と場所を割り当てます。 このアプローチの課題 割り当てられた時間帯は都合が悪いかもしれません。 人々は予定を変更する可能性が高いかもしれません。 システムが自動的に割り当てる方法は、ユーザーが選択する方法に比べて、人々にとって使いやすく、公平で、予防接種の予約スケジュールをより効率的に立てることができます。 2回目の接種に関する課題 ほとんどのCOVID-19ワクチンは、2回の接種が必要です。最適な効果を得るためには、同じ種類のワクチンを用いて、2回目の接種を1回目の接種に関連した特定の時間内に行う必要があります。それに加えて、ワクチンによって2回目の接種の時間枠が異なります。そして、その時間枠の中には、準備が整った日(2回目の接種が可能な最初の日)、理想的な日(2回目の接種に最適な日)、そして終了日(2回目の接種が有効であると考えられる最後の日)があります。例えば、ファイザー社の2回目の服用の理想的な日付は1回目の服用から21日後ですが、モデルナ社の2回目の服用の理想的な日付は1回目の服用から28日後です。 あなたが接種管理者であると仮定します。モデルナ社のワクチンの接種を開始したとします。4週間後、あなたはまだ1回目の接種を行っている間に、今度はすでに1回目の接種を受けた人が2回目の接種を受ける時期になります。あなたは、2回目の接種が必要な人に予約を入れるか、1回目の接種を受ける人に予約を入れるかを決めなければなりません。それは当然のことのように思えるかもしれませんが、このシナリオには潜在的な複雑さがあります。ワクチン接種の最初の週に、優先順位の高い人にワクチンを接種したものの、1日の終わりにワクチンが余っていることに気づき、それを無駄にしたくなかったため他の人にもワクチンを接種したとします。4週間後の今、あなたは1回目の接種の優先順位が高い人に予約を入れるか、2回目の接種が必要な優先順位の低い人に予約を入れるかを選択しなければなりません。 1回目と2回目の予約を均等にするという方法もありますが、そうすると2回目を必要としている人の予約が滞ってしまう可能性があります。2回目の接種が必要な人に優先順位をつけずに1回目の接種を続けると、最終的に2回目の接種が必要な人の滞留が雪だるま式に増えていきます。2回目の接種日は、理想的な接種日から非常に離れてしまい、予定日を超えてしまう可能性もあり、1回目のワクチン接種の効果が大幅に低下してしまいます。 したがって、初回接種者の優先順位にかかわらず、2回目の予約を初回接種者よりも優先する必要があるのです。 ワクチン接種予約スケジューリング問題の解決 ワクチン接種予約スケジューラーを構成できるOptaPlannerは、システム自動割り当て法を用いて、できるだけ多くの人にワクチンを接種するという問題を解決するために、計画制約を用いて各人のスコアを作成します。その人のスコアによって、いつ予約が取れるかが決まります。スコアが高ければ高いほど、早く予約が取れる可能性が高くなります。制約条件には、ハード、ミディアム、ソフトの3種類があります。 ハードな制約は必須条件です。いずれかのハード制約が破られた場合、そのプランは実現不可能であり、実行することはできません。 ワクチンの容量:どのような場所でも、いつでもワクチンの容量に対してオーバーブッキングしてはいけません。 ワクチンの最大年齢:ワクチンに最大年齢が設定されている場合、初回接種時にワクチンの最大年齢を超えている人には接種しません。年齢に適した種類のワクチンを確実に接種してください。例えば、最大年齢制限が65歳のワクチンの予約を、75歳の人に割り当てないようにします。 必要なワクチンの種類:必要なワクチンの種類を使用してください。例えば、2回目の接種には1回目と同じ種類のワクチンを使用しなければなりません。 準備完了日:指定された日以降にワクチンを接種します。例えば、2回目の接種を受ける人は、特定の種類のワクチンで推奨される最も早い接種可能日(1回目の接種から26日後など)より前に接種してはいけません。 期日:指定された期日までにワクチンを接種する。例えば、2回目の接種を受ける場合は、特定のワクチンの推奨接種最終期限(1回目の接種から3ヶ月後など)より前に接種する。 最大移動距離を制限:各人を最寄りの予防接種センターのグループの1つに割り当てます。これは通常、3つある接種センターのうちの1つです。この制限は距離ではなく移動時間によって計算されるため、都市部に住む人は農村部に住む人よりも最大移動距離が短くなるのが普通です。 ミディアム制約は、全員にアポイントメントを割り当てるだけの十分な容量がない場合に、誰がアポイントメントを取れないかを決めるものです。これを過制約計画といいます。 2回目のワクチン接種の予定:2回目のワクチン接種の予約は、理想的な日にちが計画の枠外になる場合を除き、割り当てられないままにしないでください。 優先度に基づいて人をスケジュール:各人には優先度が設定されています。これは通常は年齢ですが、例えば医療従事者の場合はもっと高くなる可能性があります。最も低い優先度の人だけを未割り当てにしておきます。それらは次の実行時に抽出されます。この制約は、前の制約よりもソフトです。というのも、2回目の接種は常に優先度の評価よりも優先されるからです。 ソフト制約はなるべく破らないようにします。 希望する予防接種センター:希望する予防接種センターがある場合は、そのセンターに予約を入れます。 距離:指定された接種会場までの移動距離をできるだけ短くする。 理想的な接種日:指定された接種日にできるだけ近い日に接種します。例えば、2回目の接種を受ける人は、そのワクチンの理想的な接種日(1回目の接種から28日後など)に接種します。この制約は理想的な日付に1日でも近づくために、人々を国の反対側に送ることを避けるために、距離の制約よりも緩やかなものになっています。 優先度評価:優先度の高い人を計画ウィンドウの早い段階でスケジュールします。この制約は、国の反対側に人を送ることを避けるために、距離の制約よりもソフトになっています。また、優先度よりも2回目の服用が優先されるため、この制約は理想日の制約よりもソフトです。 ハード制約は、他のハード制約に対して重み付けされます。ソフト制約は、他のソフト制約に対して重み付けされます。しかし、それぞれの重みにかかわらず、ハードな制約は常にミディアムとソフトな制約を上回ります。予約枠よりも多くの人がいるため、厳しい決断を下す必要があります。 2回目の予約は、後になって予約が殺到するのを避けるため、常に最初に割り当てられます。その後、優先度に基づいて予約を入れていきます。最初の優先順位は年齢で決められます。これにより、若い人よりも年配の人が優先されることになります。その後、特定の優先順位の人には、数百点の追加ポイントが与えられます。これは、そのグループの優先度に応じて異なります。例えば、看護師の場合、1000ポイントが追加されます。このようにして、年配の看護師は若い看護師よりも優先され、若い看護師は看護師ではない人よりも優先されます。 次の表は、この考え方を示したものです。 表1 優先順位テーブル Solver OptaPlannerの核となるのはソルバーであり、問題データセットを受け取り、計画の制約や構成を重ね合わせるエンジンです。問題データセットには、人、ワクチン、予防接種センターに関するすべての情報が含まれています。ソルバーは様々なデータの組み合わせを検討し、特定のセンターでの予防接種の予約に割り当てられた人々の最適な予約スケジュールを最終的に決定します。次の図は、ソルバーが作成したスケジュールを示しています。 継続的な計画 継続的な計画とは、1つまたは複数の次期計画期間を同時に管理し、そのプロセスを毎月、毎週、毎日、毎時、またはそれ以上の頻度で繰り返す手法です。計画ウィンドウは、指定された間隔で段階的に進みます。次の図は、毎日更新される2週間分の計画ウィンドウを示しています。 2週間の計画対象を半分に分けます。最初の1週間は公開された状態で、2週間目はドラフトの状態です。計画対象の公開された部分とドラフトの部分の両方で、人々は予約枠に割り当てられます。しかし、計画対象の公開された部分にいる人だけが、自分の予約について通知されます。それ以外の人の予定は、次回の実行時に簡単に変更できます。このようにすることで、計画が自らを窮地に追い込むことを防ぐことができます。例えば、2回目の接種が必要な人の準備ができている日が月曜日で、理想的な日が水曜日の場合、週の後半にドラフトの予定を入れることができることを証明できれば、月曜日に招待する必要はありません。 計画対象の大きさを決めることはできますが、問題空間の大きさには注意してください。問題空間とは、計画を作成するために必要な様々な要素のすべてです。つまり、先に計画する日数が多ければ多いほど、問題スペースは大きくなります。 プランニング・エンティティの固定 毎日継続して計画を立てていると、2週間の間にすでに割り当てられている予定が出てきます。予約枠がダブルブッキングにならないようにするためには、既存の予約をピン留めして、割り当て済みとしてマークする必要があります。ピン留めは、1つまたは複数の特定の割り当てを固定し、OptaPlannerにそれらの固定された割り当てを中心にスケジュールを組ませるために使用されます。ピン留めされたプランニング・エンティティ(予約など)は、解決中に変更されることはありません。 エンティティがピン留めされているかどうかは、アポイントメントの状態によって決まります。前の画像を見てみると、画像の左側の予約枠には5つの状態があることがわかります。「空き」、「招待済」、「承認済」、「拒否」、「再予約済」。 注意: OptaPlannerエンジンは予約が固定されているかどうかだけをチェックするので、クイックスタートデモコードでは実際にこれらの状態を直接見ることはできません。 画像からもわかるように、すでに予定されている予約を中心に計画を立てられるようにする必要があります。「招待済」「承認済」状態の予約枠は固定されています。「空き」「再予約済」「拒否」の状態の予約枠は固定されておらず、スケジュール可能な状態です。 この例では、ソルバーが実行されると、公開範囲とドラフト範囲の両方で、2週間の計画対象全体を検索します。ソルバーは、スケジュール外の入力データに加えて、ピン留めされていないエンティティ(空き、再予約済、拒否のいずれかの状態の予約枠)を考慮し、最適な解を見つけます。ソルバーが毎日実行される場合、上の真ん中の画像のように、ソルバーを実行する前にスケジュールに新しい日が追加されています。3つ目のスケジュールには、ソルバーの結果が表示されています。 新しい日の予定が割り当てられ、以前は計画対象のドラフト部分に予定されていたAmyとEdnaが、対象の公開部分に予定されていることに注目してください。これは、GusとHugoが予定変更を要求したために実現しました。AmyとEdnaにはドラフトの日付が通知されていなかったので、これで混乱は起こりません。現在、彼らは計画対象の公開されたセクションで予定を持っているので、通知され、予定を受け入れるか拒否するかを尋ねられ、彼らの予定は固定されるようになりました。 ご期待ください。Optaplannerの予防接種予約計画のクイックスタートについて、より深く、より技術的に見たフォローアップブログを掲載する予定です。 こちらもご覧ください Vaccination appointment scheduling video www.youtube.com Github appointment planner code github.com OptaPlanner User Guide docs.optaplanner.org 翻訳:Solution Architect 梅野
みなさんこんにちは。レッドハットの杉村です。Ansible のテクニカルサポートをしています。 今回は10月に書いた記事の続きとして、Python の venv での実行環境の話をします。もう Python 2.7 については触れず、Python 3 での実行環境のみを扱うことにします。 rheb.hatenablog.com 以前の Ansible での venv の利用シーンとしては、複数のバージョンの Ansible Engine を利用したいということがありました。いまもそれは変わらないのですが、Collections と組み合わせて使うために必要となることが増えてきました。例えば、AWS を扱うための amazon.aws collection であれば、boto などの Python ライブラリを利用する、などです。 github.com Azure のための collection についてもよくお問い合わせいただきます。 github.com 基本的な流れとしましてはこのようになります。 Python 3 をインストールする venv を作成する Ansible 2.9 をインストールする ビルドが必要なモジュールのために開発環境をインストールする pip でモジュールをインストールする RHEL や macOS で同じように試していただけますが、Windows はあまり詳しくないもので触れません。 なお、この方式でインストールした Ansible はサポート対象にはなりません。サポートを必要とされる場合には、Ansible Automation のサブスクリプションをご購入いただき、Ansible Tower をご利用ください。Ansible Tower に付属する venv では、AWS や Azure などに接続するために必要なモジュールはあらかじめインストールされているため、追加の作業なくご利用いただけます。ただ、新しい Collections を使いたい場合にはやはり新しいモジュールが必要となることがありますので、そのときにはここで説明する手順で新しく venv を作っていただくことになります。 RHEL 7.6 以前のとき Python 3 は RHSCL (Red Hat Software Collections) からインストールします。scl enable コマンドで環境を作って利用するのが少々面倒ではあります。 $ sudo subscription-manager repos --enable=rhel-server-rhscl-7-rpms リポジトリー 'rhel-server-rhscl-7-rpms' は、このシステムに対して有効になりました。 $ sudo yum install rh-python36-python rh-python36-python-devel … $ sudo yum install gcc openssl-devel … $ scl enable rh-python36 /bin/bash $ python --version Python 3.6.12 venv を作ってその中に pip でインストールしていきます。初めに使える pip コマンドは古いので、更新してからのほうが失敗しにくいです。 $ pwd /home/sugimura $ umask 0022 $ mkdir venv $ python -m venv venv/2.9 $ source venv/2.9/bin/activate (2.9) $ pip --version pip 9.0.1 from /home/sugimura/venv/2.9/lib64/python3.6/site-packages (python 3.6) (2.9) $ pip install --upgrade pip … (2.9) $ pip --version pip 21.1 from /home/sugimura/venv/2.9/lib64/python3.6/site-packages/pip (python 3.6) (2.9) $ pip install ansible==2.9.20 … (2.9) $ ansible --version ansible 2.9.20 config file = None configured module search path = ['/home/sugimura/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/sugimura/venv/2.9/lib64/python3.6/site-packages/ansible executable location = /home/sugimura/venv/2.9/bin/ansible python version = 3.6.12 (default, Sep 15 2020, 12:49:50) [GCC 4.8.5 20150623 (Red Hat 4.8.5-37)] 続いて、AWS と Azure に接続するためのモジュールをインストールしてみます。エラーが出ないことを確認してください。 (2.9) $ pip install -r https://raw.githubusercontent.com/ansible-collections/amazon.aws/main/requirements.txt (2.9) $ pip install -r https://raw.githubusercontent.com/ansible-collections/azure/dev/requirements-azure.txt あとは Collections をインストールして、playbook を書けば使えます。今回は実行環境についての説明までにしますので、実際に playbook を動かすところまでは行いません。 (2.9) $ ansible-galaxy collection install amazon.aws Process install dependency map Starting collection install process Installing 'amazon.aws:1.5.0' to '/home/sugimura/.ansible/collections/ansible_collections/amazon/aws' (2.9) $ ansible-galaxy collection install azure.azcollection Process install dependency map Starting collection install process Installing 'azure.azcollection:1.5.0' to '/home/sugimura/.ansible/collections/ansible_collections/azure/azcollection' RHEL 7.7 以降のとき RHEL 7.7 以降では、OS 標準のリポジトリからも Python 3 が提供されるようになりました。scl コマンドで一段入れることなく使えますので、使いやすくなったと思います。 python3-devel は rhel-7-server-optional-rpms から入れる必要があることに注意が必要です。 $ sudo subscription-manager repos --enable rhel-7-server-optional-rpms リポジトリー 'rhel-7-server-optional-rpms' は、このシステムに対して有効になりました。 $ sudo yum install python3 python3-devel gcc openssl-devel … $ python3 --version Python 3.6.8 あとは先ほどの RHEL 7.6 以前のときと同様に、venv を作って同じように進めることができます。python コマンドですと 2.7.5 を使いますので、python3 コマンドにすることがポイントです。 $ pwd /home/sugimura $ umask 0022 $ mkdir venv $ python3 -m venv venv/2.9 $ source venv/2.9/bin/activate (2.9) $ pip install --upgrade pip (2.9) $ pip install ansible==2.9.20 (2.9) $ ansible --version ansible 2.9.20 config file = None configured module search path = ['/home/sugimura/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/sugimura/venv/2.9/lib64/python3.6/site-packages/ansible executable location = /home/sugimura/venv/2.9/bin/ansible python version = 3.6.8 (default, Aug 13 2020, 07:46:32) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] Collections のためのモジュールのインストールは同じですので割愛します。 RHEL 8 のとき RHEL 8 では標準で有効になっている AppStream から Python 3.6 か 3.8 が利用できますが、今回は 3.6 を使ってみます。 新しいものですので当然ではありますが、もっとも簡単に構築することができます。 $ sudo dnf install python36 python36-devel gcc openssl-devel $ python3 --version Python 3.6.8 $ pwd /home/sugimura $ umask 0022 $ mkdir venv $ python3 -m venv venv/2.9 $ source venv/2.9/bin/activate (2.9) $ pip install --upgrade pip (2.9) $ pip install ansible==2.9.20 (2.9) $ ansible --version ansible 2.9.20 config file = None configured module search path = ['/home/sugimura/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/sugimura/venv/2.9/lib64/python3.6/site-packages/ansible executable location = /home/sugimura/venv/2.9/bin/ansible python version = 3.6.8 (default, Aug 18 2020, 08:33:21) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] おわりに RHEL のそれぞれのバージョンでの venv の作り方と利用方法についてまとめてみました。 ここでは Ansible は 2.9.20 をインストールしてみましたが、この方法でコミュニティから新しくリリースされている 2.11 などを試してみることもできます。 Ansible に限らず、例えば Django のアプリケーション開発を RHEL でやってみたいという方にも参考にしていただけましたらと思います。 Ansible Towerの評価ライセンスリクエストはこちらからご利用いただけます。 www.redhat.com Happy Automation!
レッドハットでISVパートナーを担当している三島です。 Red Hat OpenShift(以下、OpenShift) の導入にあたっては、セキュリティについての検討も欠かせません。 今回、コンテナ自体のセキュリティを高める製品の一つであるAquaをご紹介をいたします。 OpenShiftには管理画面上からコンテナパッケージをデプロイ可能な機能として「Operatorhub」があります。今回はこのOperatorhubを使い、コンテナセキュリティ製品であるAquaのインストールから初期の設定の方法をご紹介します。 本記事は、クリエーションライン様にご協力をいただき、作成しております。 終わりに同内容の動画もありますので、合わせて御覧ください。 Aquaによるコンテナセキュリティ AquaはAqua Security社( https://www.aquasec.com )が提供するコンテナセキュリティ製品です。国内ではクリエーションライン社( https://www.creationline.com/aqua )が総代理店となっています。 設計ポリシーとして、ホスト側に負担をかけないようデザインされています。Aquaは、リソースを逼迫させることなく軽快に動作します。 Aquaはコンテナイメージのスキャンを行い、脆弱性、マルウエアなどの検知や外部からの攻撃を検知し、コンテナを実行する際のセキュリティを向上します。機能の詳細は後述します。 OperatorHubを使用したAquaの構築 Aquaを使用するためには、Aquaとの契約が必要です。あらかじめAqua社と契約し、発行されたライセンスを入手しておく必要があります。 ※Aquaのライセンス取得方法については今回記載しておりませんが、こちらでご紹介されていますので、ご参照ください。 OperatorHubを使用してAquaを構築するのは簡単です。 以下の構築手順とAquaの簡単な紹介を、動画で公開されています。書き手順とあわせてご参照ください。 1. まずAqua用のプロジェクトを作成します。今回は「aqua」という名前にします。 2. OpenShiftの画面でOperatorHubを開き、Aquaを検索すると複数表示されます。 「Community」はGithub上に公開されている10.2です。「Marcketplace」は、ライセンスをサブスクリプションとする最新版の10.4です。無印のものがAquaのライセンスをBYOLで用意する10.4です。 今回は無印のBYOL版10.4を選択します。 INSTALLボタンを選択し、次の画面でSubscriptionを選択すると。AquaがOperatorHubにインストールされます。 3. これでOperatorHubから、AquaがOpenShift環境へインストールされました。 AquaのYAMLファイルを確認し、デフォルトのデータベースのパスワード(password)やAquaの管理者ユーザのパスワード(Password1)を変更しておきます。 4. AquaCSPをインストールします。 このとき、自動的にAquaDatabase/AquaServer/AquaEnforcer/AquaGatewayがインストールされます。 AquaServer 中央制御のコンポーネントで、ユーザがセキュリティに関する設定やステータスを確認できるようなWebベースのUIを提供します。 AquaDatabasease Aqua ServerおよびAqua Gatewayで使用されるPostgresデータベースです。 Aqua Enforcer(enforcer) Aqua Serverで設定されたポリシーに基づいて、仮想/物理ホスト上のContainerを保護します。Aqua Enforcerは保護を行うすべてのホスト上に配置が必要です Aqua Gateway Aqua Serverと各種Enforcer間の通信を処理します。管理対象Enforcer数が多数となる場合は複数配置することで負荷分散が可能です。 5. 次に、AquaScannerをデプロイします。 Aqua Scannerは、イメージの脆弱性をスキャンし、その結果をAqua Serverに送信します。Aqua Server内蔵のスキャン機能も同様の機能を持ちますが、独立して別ノード(ビルドサーバなど)に配置することが推奨されます。 これでAquaのインストールは完了です。 6.aquaプロジェクトの Network→Routerに、インストールしたAquaのWeb画面のURLが表示されているので、それをクリックします。 7.ユーザ「administrator」、YAMLファイルに設定したパスワードを設定してログインします。 8.初回のみ、Aquaとの契約時に発行されたライセンスを入力します。 9.Aquaの画面にログインできました。RiskExplolerを見ると、OpenShiftのすべてのプロジェクト(namespace)が監視対象に入っているのがわかります。 Aquaを含めOpenShiftで動作しているコンテナは、インストール直後ではAquaで検査されていません。そのため、PodのリスクがすべてMedium(オレンジ)の評価となっています。 10.OpenShiftのdefault プロジェクトに、デフォルトで用意されている「hello-openshift」という新しいPodを作成します。 新たに作成したPodはAquaでスキャンされた状態で起動されます。そのため、AquaのRiskExploler上でも安全なPodであることが表示されます。 Aqua を導入するメリット Aquaはコンテナセキュリティ製品です。設計ポリシーとして、ホスト側に負担をかけないようデザインされています。Aquaは、リソースを逼迫させることなく軽快に動作します。 AquaをOpenShiftなどのコンテナ環境に導入することで、以下の機能を実現します。 Imageの静的スキャン 指定したコンテナイメージについて、以下の項目を検知します。 NIST、ベンダースコアなどで登録された脆弱性 OSパッケージ(Red Hat Enterprise Linuxを始めとしたLinux/Windows Server)や、言語パッケージ(Java/Node.js/PHP/Python/Ruby)に含まれる脆弱性を検知します。 秘密鍵などのセンシティブデータ RSAキーやSSLのセッションパラメータなど、コンテナに含まれるべきではないデータを検知します。 マルウェア Virus Scanner によりマルウェアを検知します。 OSSライセンス イメージに含まれるOSSライセンスを検知します。 スキャンによって得られた情報は、脅威度( CVSS v2.0/CVSS v3.0)によって分類可能です。深刻な脆弱性があっても、OSベンダーによって回避されている脆弱性もあります。 このイメージスキャンはCI/CDシステムと連携可能で、作成したコンテナイメージの定期的なスキャンが可能です。 ランタイム保護 実行時のコンテナに対する攻撃から保護します。以下のようなポリシーを定義し設定することが可能です。 許可されない、もしくは(脆弱性など)特定の条件を満たさないイメージの実行禁止 プロセス・スレッド数の上限を制御 許可されないプロセス・システムコールの実行防止 コンテナ間ファイアウォールによる不正な通信の防止 機械学習による行動分析/ホワイトリスティング コンテナの挙動を学習して、ランタイム時に使用されているリソース/プロセスのホワイトリスト化、およびホワイトリスト以外の機能の実行防止 その他 CIS、NIST、PCI DSS、HIPPA等に対応した、初期定義ランタイムポリシーを用意しているほか、独自のポリシーをユーザが新たに作成することが可能です。 これらポリシーに準拠しない動作を検知したときに、コンテナを再起動することなくポリシー違反の動作のみを抑制可能です。またランタイムに対するポリシーを変更しても、再起動の必要なく実行中のコンテナに変更したポリシーが反映されます。 Drift Prevention Aqua独自の機能で、元イメージに無い実行ファイルの実行をブロックする機能です。これを有効にしておくだけでも攻撃を大半を防げるであろう、設定も容易で強力なランタイム保護機能です。 vShield 新たな脆弱性は日々発見されますが、その修正には時間がかかることがあります。vShield機能は、既知の脆弱性に対して仮想的なパッチを当てることで、その危険性を回避する機能です。vShieldによる仮想パッチは、脆弱性が発見されてから24時間以内に提供されます。 開発者が脆弱性に対応するまで、vShieldによって暫定的に脆弱性から保護することが可能です。 マルチアプリケーションRBAC アプリケーションのあらゆる要素へのアクセスを制御するための、RBAC機能を提供しています。ロールに対して、各種ポリシーやアセット・イベント種別・システムコンポーネントに、編集・読み取り権限を設定可能です。ロールは、Active DirectoryやLDAPとマッピングできます。ロールを割り当てるスコープとしてアーティファクト(イメージ、Function)、インフラ(クラスタ、ホスト)、Workloads(プロジェクト、コンテナなど)を指定できます。 また、柔軟なセキュリティ階層を定義可能です。例えば下位チームに読み取り専用ポリシーを割り当てたり、複数のロールをユーザに割り当てることで部門間チームを有効にできます。 Risk Explorer Risk Explolerは、コンテナ環境内のWorkloads(コンテナ)とそれに関連するセキュリティリスクを動的に表示します。RiskExplolerはすべてのプロジェクト(namespace)、Kubernets リソース(deployment、statefulset、job等)、コンテナに含まれる脆弱性などの脅威度、Pod間のネットワーク接続などを可視化できます。 視覚的に表示する際に脅威度ごとに選択してハイライトを行い、高い脅威度だけを表示することも可能です。Risk Explolerは、実行中のWorkloadsのみを表しています。デプロイされていないイメージは表示されません。 Dynamic Threat Analysis(DTA ) Aqua Dynamic Threat Analysis (DTA) は、コンテナイメージを実環境でコンテナとして実行する前に、コンテナイメージがもたらすリスクを動的に評価する業界初のコンテナサンドボックスソリューションです。DTAは、安全で隔離されたサンドボックス環境でコンテナイメージを実行し、悪意のある動作やネットワークアクティビティなどの動作パターンやIoC(Indicators of Compromise)を監視して、コンテナの権限昇格、マルウェア、クリプトマイナー、コードインジェクションのバックドア、その他の脅威を検出します。
皆様こんにちは、Ansibleのシニアテクニカルサポートエンジニアの八木澤( @hiyoko_taisa )です。日々Ansible Engine / Towerの問題と戦いながら、世界の平和を守っています。 適切にサービスを提供するためには、サービスが想定どおり動作しているか監視する必要があります。Ansible Towerを導入した場合も例外ではありません。 そこで今回は、Ansible Towerを監視する際のポイントについて、従来の監視手法の問題点とともに整理してみましょう。 1. 監視とは何か まず最初に、ここでとりあげる「監視」という言葉の定義について考えましょう。監視とは、「 サービスおよびシステムが正常に動作しているかを確認し、異常が発生した際にいち早く検知し対応する 」ための手段です。 エンタープライズのシステムと監視は切っても切り離せない関係にあります。常に使えることが前提とされるシステムで「気がついたら使えなくなっていた」という状況は避けたいものです。適切な対応を取るために、問題が発生していることをいち早く検知する必要があります。 巷にはさまざまな監視のソリューションやプロダクトが存在していますが、本記事では個別のソリューションについては取り上げません。そのような監視プロダクトなどを使ってAnsible Towerの監視を設計する場合の考え方についてフォーカスします。 2. どうやってAnsible Towerを監視するか 従来多くの組織で行われてきた監視手法は、 サーバーのログファイル出力 と、 プロセスの状態 をモニタリングするという方法です。 具体的には、サービスが出力するログファイルの特定メッセージの出力とプロセスの死活監視を定期的に行い、プロセスが停止していたり指定した重要度のエラーメッセージが出力されたらアラートを発報する、というやり方です。 しかし、現代のITシステムにおいて、この監視手法は 有効なアプローチではありません 。特にAnsible Towerにおいては、上記のような監視設計は問題が発生するケースが多く起こりえます。 ログ出力を網羅できない 「問題のあるログメッセージさえ網羅できればうまく動く」といっても、そのような ログメッセージの一覧は多くのプロダクトで提供されていません 。そのため、OSSの場合はコードを直接確認したり、検証環境にて起こり得るメッセージを確認するしかありませんが、 プロダクトのバージョンや関連するコンポーネントのバージョンの差異によってこのようなログメッセージは変更される可能性があります 。 たとえば、Ansible Tower 3.6まではRabbitMQを利用していたため、クラスタに問題が発生した場合は「/var/log/rabbitmq/」配下のログを確認する必要がありました。しかしながら、Ansible Tower 3.7以降ではRabbitMQクラスタは廃止されたため、監視するべきログを変更する必要が出てきます。 このように、アップグレードに伴う変更によって使用されるコンポーネントが変化したり、ログメッセージの扱いが変化する可能性は大いにあります。そのたびに出力されうるログをすべてリストアップし、監視すべきメッセージを決定するというのは非現実的です。 特定のログやプロセスを監視するだけでは不十分 Ansible Towerは、supervisord、nginxやrabbitmqなど、複数の関連サービスが密接に連携しながらサービスを提供しています。 コンポーネント単体では意味がなく、それぞれが正しく動作してはじめて正常にサービスを提供できます 。そのためあるプロセスでエラーメッセージが出力されていても、状況によってそのメッセージが出力される原因や及ぼす影響は異なります。 また、supervisordの管理下にあるプロセスは、仮に停止していた場合でも自動的にsupervisord側で復旧を試みます。これらの関連プロセスを人間が手動で死活監視することは現実的ではありません。 正確に問題を調査するためには、発生している問題を特定し、関連すると思われるログを全て調査する必要があります。ですので、「 このメッセージが出力されたらこの復旧操作をする 」という紐づけをすることは 事実上不可能 です。ですので、「supervisordの特定のプロセスを確認する」「ログファイルのエラーメッセージのリストを作り、問題のあるメッセージを検知する」というような従来の監視スタイルは、あまり効果的ではありません。 3. どのような監視を検討するべきか より実際のサービスの提供に即した監視手法を検討する 真に監視するべきは「プロセスの起動有無」ではなく、「 サービスが正常に提供できているかどうか 」です。そのためには、Ansible Towerが正しくジョブを実行できるかどうか、実際の利用に即した形で確認するのがよいでしょう。以下は、Ansible Towerの監視で実際に用いられるケースが多い手法です。 /api/v2/ping/の出力を確認する Ansible TowerのAPIには、各クラスタノードの状態を確認できる以下のAPIエンドポイントが存在します。 この出力の「 Capacity 」の値や「 Heartbeat 」の更新有無を確認することで、ジョブが実行できなくなっているノードを見つけ出すことができます。 { "ha": true, "version": "3.8.2", "active_node": "tower1", "install_uuid": "05176067-ce0a-42fb-900c-10572f3c53b4", "instances": [ { "node": "tower1", "uuid": "966df87e-531c-4b97-b862-17411b6d34bd", "heartbeat": "2021-04-21T00:49:38.065421Z", "capacity": 16, "version": "3.8.2" }, { "node": "tower2", "uuid": "619b4639-445d-40b8-8b20-adc400744a4d", "heartbeat": "2021-04-09T08:10:23.000914Z", "capacity": 0, "version": "3.8.2" }, { "node": "tower3", "uuid": "ffbdbe85-27d8-41ff-966a-db4f52e1c280", "heartbeat": "2021-04-09T08:10:20.774458Z", "capacity": 0, "version": "3.8.2" } ], "instance_groups": [ { "name": "tower", "capacity": 16, "instances": [ "tower1", "tower2", "tower3" ] } ] } 上記は、実際の検証環境の出力です。これを確認すると、「tower2」「tower3」はCapacityが0になっており、Heartbeatの値から4月9日から動作していないことが読み取れます。 このように、Ansible Tower側で用意しているAPI出力から、各ノードがサービスを提供できる状況にあるか確認するのもひとつの方法です。 テスト用のプレイブックを定期的に実行する また、実際の処理に影響がない範囲で、テスト用のジョブを実行するという手もあります。こちらはより実態に即した監視手法となります。 テスト用のプレイブックは、軽量で副作用が少ないシンプルなものがよいでしょう。実行頻度を増やしすぎると負荷が増大しますので、環境に応じて適切な頻度を検討しましょう。 一口に監視と言っても、環境によって求められる要件は千差万別です。実際の環境や要件にしたがってどのような監視を行なえばよいか検討してみましょう。
Red Hatのソリューションアーキテクトの森です。 Red Hat にはクラウドネイティブアプリの開発に役立つ、ソフトウェアのラインナップが充実していることをご存知ですか? ここでは、それらのソフトウェア [Red Hat Application Services]に関する注目ニュースを、各製品技術に特化したソリューションアーキテクトが、ご紹介します。 今回は 2021/5月号となります。 想定読者 エンタープライズアーキテクト アプリケーション開発者 システムの提案をするSIerの方 特集1: Red Hat Runtimesの最新アップデート:どこでも、誰でもQuarkus Red Hat Runtimes portfolioの最新アップデートとQuarkus 1.11.6の紹介になります。 また、今回、Red Hat Enterprise Linux(RHEL)のサブスクリプションにQuarkusのエンタイトルメントを追加することを発表しました。 Quarkus on RHELは、サーバーレス、マイクロサービス、コンテナ環境での活用やビジネスクリティカルなアプリケーションのエッジへの展開に弾みがつくと考えます。 www.redhat.com 特集2: APIのライフサイクルを体験できるハンズオンワークショップ "Day in the Life - Agile Integration"のご紹介 APIの設計から実装、管理まで、APIフルライフサイクルをハンズオン形式で体験できる「DIL Agile Integration ハンズオンワークショップ」を紹介しています。 Apicurio, Microcks, 3scale, Fuse, Code Ready Workspaces, Keycloak (RH-SSO), OpenShiftなど、オープンソースをベースとした製品を活用し、APIファーストのアプローチによるAPIのライフサイクルを体験できる無償のワークショップです。 興味のある方はRed Hatまでご連絡を。 speakerdeck.com 特集3: Process Automation 7.10 新機能!ビジネスプロセスからAMQ Streams(kafka)を送受信してみよう Red Hat Process Automation Manager と、Red Hat AMQ Streams (Apache Kafka) を統合することができるようになりました。 ビジネスプロセスは、メッセージイベントを使用して Kafka メッセージを送受信することができます。 KIE Server では、プロセス、ケース、またはタスクが完了したときに Kafka イベントを生成させることができます。 今回は、簡単なサンプルプロセスを作成して、Kafka メッセージ からプロセスを開始する方法と、プロセス終了時に Kafka メッセージ を送信する方法についてご紹介していきます。 rheb.hatenablog.com 好評開催中!クラウドネイティブアプリ開発関連のWebinar全6回 Cloud Nativeを見据えたアプリケーションアーキテクチャとレガシーモダナイゼーション コンテナ時代の開発ツールチェインと開発プロセスのベストプラクティス クラウド/コンテナを前提とした時代のアプリケーション実行環境の選択 マイクロサービス/サーバーレス実践入門 これからのシステム連携を実現するデジタル基盤とアプローチ Cloud Nativeなデータパイプラインの作り方とオープンハイブリッドクラウドへの展開 各回とも、オンデマンドで視聴出来ます。(お名前とメールアドレス等の登録のみで視聴可能です) 下記リンクよりぜひご登録ください。 www.redhat.com 直近GAになった製品群 最近リリースとなった Application Services 製品群のリストをご紹介します。 見逃している製品が無いか、是非一度ご確認ください。 Red Hat 3scale API Management 2.10 Red Hat AMQ 2021.Q2
レッドハットのソリューションアーキテクトの森です。 Red Hat Process Automation Manager と、Red Hat AMQ Streams (Apache Kafka) を統合することができるようになりました。 ビジネスプロセスは、メッセージイベントを使用して Kafka メッセージを送受信することができます。 KIE Server では、プロセス、ケース、またはタスクが完了したときに Kafka イベントを生成させることができます。 今回は、簡単なサンプルプロセスを作成して、Kafka メッセージ からプロセスを開始する方法と、プロセス終了時に Kafka メッセージ を送信する方法についてご紹介していきます。 サンプル実行環境 今回ご紹介するサンプルは、以下の環境で実施をしています。 Red Hat Process Automation Manager 7.10.0 (以下RHPAM) Apache Kafka Java 11 Maven Git Docker Kafka のセットアップ まずは、ローカル環境に Kafka サービス を構築しましょう。 下記のプロジェクトをクローンして、strimzi-all-in-one フォルダに移動し、docker-composeファイルを使って、 以下のコンテナサービスを起動します。 Zookeeper Kafka Broker Strimzi HTTP Bridge Apicurio Service Registry git clone https://github.com/hguerrero/amq-examples.git cd amq-examples/strimzi-all-in-one/ docker-compose up これで、localhostの port 9092 で Kafka サーバーが動作するようになります。 続いて、別のターミナルを立ち上げて、strimzi-all-in-one フォルダに移動します。 以下のコマンドを実行して、今回のサンプルで使用する3つのトピックを作成しておきます。 docker-compose exec kafka bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic new-request docker-compose exec kafka bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic request-approved docker-compose exec kafka bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic request-rejected RHPAM の設定とサンプルプロジェクトのインポート RHPAM のプロセスで Kafka メッセージ を送受信するには、EAPの設定ファイルに、システムプロパティ org.kie.kafka.server.ext.disabled を false の値で追加する必要があります。 RHPAM を起動する際の設定ファイル(/$EAP_HOME/standalone/configuration/standalone-full.xml 等)を開き、以下の設定を追加します。 ・・・ <system-properties> ・・・ <property name="org.kie.kafka.server.ext.disabled" value="false"/> </system-properties> ・・・ 次に、RHPAM を起動して Business Central にログインし、以下のサンプルプロジェクトをインポートします。 https://github.com/kamorisan/pam-kafka-sample.git サンプルのプロセスは、メッセージの情報をインプットとして、リクエストを承認するかどうかをルールで判断します。 自動承認のルールに該当しない場合は、手動で二次判断を行うヒューマンタスクを実施するという、シンプルなものです。 トピックに新しいイベントが発生すると、プロセスの新しいインスタンスが起動します。 リクエストの承認/却下の結果については各々のトピックに送信することで、 承認ステータスに基づいて異なるサービスで対応ができるようになります。 プロセスを開始するための Kafka メッセージを 受け取るイベントの作成 先ほどインポートしたプロジェクトの、ビジネスプロセスのアセット (kafka-process-sample) を開きます。 まずは、プロセスの開始イベントを、Kafka メッセージ を使用する開始メッセージイベントに変更をしてみましょう。 開始イベント(New Request)の緑色の丸をクリックし、左下の歯車アイコンを選択して開始メッセージイベントを選択します。 次に、この開始メッセージイベントが参照する、Kafka トピック を設定します。 右端の開始メッセージイベントのプロパティパネルから、先ほど作成した Kafka トピック の new-request を、実装/実行メニューの、メッセージの項目に設定をします。 次に、Kafka トピック から受け取るメッセージのデータ項目を追加します。 今回のサンプルプロジェクトでは、 RequestData というデータオブジェクトを既に作成してありますので、それを使用します。 開始メッセージイベントのプロパティパネルから、データ割り当てメニューの割当の項目をクリックし、以下のデータ出力と割り当てを追加してください。 Name: request データタイプ: RequestData ターゲット: request 開始イベントの変更と、プロパティへの設定の追加が完了したら、一度プロセスを保存し、プロジェクトをKIE Serverへデプロイをしましょう。 新しいターミナルを開き、Kafka サービスの strimzi-all-in-one フォルダへアクセスし、下記のコマンドを実行します。 $PROJECTS_DIR は、自分のフォルダパスの内容に置き換えてください。 cd $PROJECTS_DIR/amq-examples/strimzi-all-in-one docker-compose exec kafka bin/kafka-console-producer.sh --topic new-request --bootstrap-server localhost:9092 > Kafka の Producer サービスは、 new-request というトピックにイベントを発行できる状態となっています。 ターミナルに、以下のjsonデータを入力してみましょう。 > {"data" : {"id": 1, "status": "Gold", "score": 200}} Business Central の上部メニューから、 管理 → プロセスインスタンス を選択します。 左のフィルターパネルから Stateメニューの 完了 にチェックを入れます。 先ほど、 new-request で発行したイベントから実施され、完了したプロセスが表示されるはずです。 完了済のプロセスインスタンスを選択し、次にダイアグラムタブへ移動します。 メッセージイベントからのリクエストが、自動承認されたことが確認できます。 プロセスから Kafka メッセージを 送信するイベントの作成 続いて、プロセス内から Kafka メッセージ を送信するイベントを作成していきます。 事前の準備として、メッセージ送信イベントを作成する際に必要なワークアイテムハンドラーを追加しておきます。 プロジェクトのアセット一覧の画面より、 設定 → デプロイメント → ワークアイテムハンドラー タブを選択します。 ワークアイテムハンドラーの追加をクリックし、新しい空の行に以下の値を入力します。 Name: Send Task 値: new org.jbpm.bpmn2.handler.SendTaskHandler() リゾルバータイプ: MVEL 項目の追加後、保存をしてください。 次に、ビジネスプロセスのアセット (kafka-process-sample) を開きます。 プロセスの終了イベントを、Kafka メッセージ を送信する終了メッセージイベントに変更をしてみましょう。 終了イベント(Approved)の赤色の丸をクリックし、左下の歯車アイコンを選択して終了メッセージイベントを選択します。 次に、この終了メッセージイベントが参照する、Kafka トピック を設定します。 右端の終了メッセージイベントのプロパティパネルから、冒頭で作成した Kafka トピック の request-approved を、実装/実行メニューの、メッセージの項目に設定をします。 次に、Kafka トピック へ送信するメッセージのデータ項目を追加します。 今回は、承認/却下の理由をメッセージとして送信することにします。 終了メッセージイベントのプロパティパネルから、データ割り当てメニューの割当の項目をクリックし、以下のデータ入力と割り当てを追加してください。 Name: data データタイプ: String ターゲット: message 同様にして、もう一つの終了イベント(Rejected)についても、終了メッセージイベントへ変更をしておきます。 Kafka トピック は request-rejected を使用し、データ入力と割り当ては上記と同じものを入力してください。 終了イベントの変更と、プロパティへの設定の追加が完了したら、一度プロセスを保存し、プロジェクトをKIE Serverへデプロイをしましょう。 新しいターミナルを2つ開き、Kafka サービスの strimzi-all-in-one フォルダへアクセスし、下記のコマンドを実行します。 $PROJECTS_DIR は、自分のフォルダパスの内容に置き換えてください。 cd $PROJECTS_DIR/amq-examples/strimzi-all-in-one docker-compose exec kafka bin/kafka-console-consumer.sh --topic request-approved --bootstrap-server localhost:9092 cd $PROJECTS_DIR/amq-examples/strimzi-all-in-one docker-compose exec kafka bin/kafka-console-consumer.sh --topic request-rejected --bootstrap-server localhost:9092 これで、 request-approved と request-rejected の2つのトピックの Consumer サービス が準備できました。 new-request の Producer サービス のターミナルから、以下のjsonデータを入力してみましょう。 > {"data" : {"id": 2, "status": "Gold", "score": 150}} request-approved の Consumer サービス のターミナルに、終了イベントから送信されたメッセージが表示されるはずです。 { "specversion": "1.0", "time": "2021-04-19T11:32:25.710+0900", "id": "4d7356ad-606b-4768-bbab-41b749e48d86", "type": "java.lang.String", "source": "/process/pam-kafka-message.process-kafka-sample/2", "data": "自動承認します" } プロセス、ケース、またはタスクが完了したときに Kafka イベントを生成させる 開始・終了メッセージイベントを通してだけでなく、プロセス・ケースやタスクが完了した時に、イベントに関する Kafka メッセージを生成するように設定できます。 トランザクションをコミットすると、KIE Server はメッセージを送信します。 デフォルトでは、KIE Server は以下のトピックでメッセージを公開します。 完了したプロセスに関するメッセージ : jbpm-processes-events 完了したタスクに関するメッセージ : jbpm-tasks-events 完了したケースに関するメッセージ : jbpm-cases-events トランザクションのコミット時に、KIE Server からメッセージを送信するには、以下の手順を実行します。 (※ RHPAM 7.10.0 の場合) Red Hat カスタマーポータルの Software Downloads ページから製品配信可能ファイル rhpam-7.10.0-maven-repository.zip をダウンロードします。 ファイルの内容を展開します。 maven-repository/org/jbpm/jbpm-event-emitters-kafka/7.48.0.Final-redhat-00004/jbpm-event-emitters-kafka-7.48.0.Final-redhat-00004.jar ファイルをアプリケーションサーバーの deployments/kie-server.war/WEB-INF/lib サブディレクトリーにコピーします。 ファイルを指定のフォルダに格納後、EAPを再起動します。 ※ maven-repository.zipはファイルサイズが約1.7Gbと大きいため、一般提供版 (GA) リポジトリー: https://maven.repository.redhat.com/ga/ へアクセスし、 該当のファイル を直接ダウンロードして格納しても構いません。 新しいターミナルを2つ開き、Kafka サービスの strimzi-all-in-one フォルダへアクセスし、下記のコマンドを実行して、 jbpm-processes-events と jbpm-tasks-events の2つのトピックの Consumer サービス を準備しておきます。 $PROJECTS_DIR は、自分のフォルダパスの内容に置き換えてください。 cd $PROJECTS_DIR/amq-examples/strimzi-all-in-one docker-compose exec kafka bin/kafka-console-consumer.sh --topic jbpm-processes-events --bootstrap-server localhost:9092 cd $PROJECTS_DIR/amq-examples/strimzi-all-in-one docker-compose exec kafka bin/kafka-console-consumer.sh --topic jbpm-tasks-events --bootstrap-server localhost:9092 再び Business Central に戻ります。もしサンプルプロジェクトが KIE Server にデプロイされていない場合は、もう一度デプロイを実行してください。 new-request の Producer サービス のターミナルから、以下のjsonデータを入力してみましょう。 > {"data" : {"id": 3, "status": "Silver", "score": 150}} jbpm-tasks-events の Consumer サービス のターミナルに、KIE Serverから送信されたイベントメッセージが表示されるはずです。 { "specversion": "1.0", "time": "2021-04-19T13:48:38.045+0900", "id": "773d7b97-64cf-41d4-8b35-8090f279f41c", "type": "task", "source": "/process/pam-kafka-message.process-kafka-sample/2", "data": { "compositeId": "default-kieserver_1", "id": 1, "priority": 0, "name": "手動承認", "subject": "", "description": "", "taskType": null, "formName": "Task", "status": "Ready", "actualOwner": null, "createdBy": null, "createdOn": "2021-04-19T13:48:37.611+0900", "activationTime": "2021-04-19T13:48:37.611+0900", "expirationDate": null, "skipable": false, "workItemId": 2, "processInstanceId": 2, "parentId": -1, "processId": "pam-kafka-message.process-kafka-sample", "containerId": "pam-kafka-message_1.0.0-SNAPSHOT", "potentialOwners": [ "kie-server" ], "excludedOwners": [], "businessAdmins": [ "Administrator", "Administrators" ], "inputData": { "request": { "id": 3, "status": "Silver", "score": 150 }, "TaskName": "Task", "NodeName": "手動承認", "approval": false, "Skippable": "false", "message": "却下します", "GroupId": "kie-server" }, "outputData": null } } Business Central の上部メニューから、 管理 → プロセスインスタンス を選択します。 リストに、有効なインスタンスが表示されているので選択し、次にダイアグラムタブへ移動します。 メッセージイベントからのリクエストは自動承認されずに、手動承認のタスクが実行されているのが確認できます。 Business Central の上部メニューから、 トラック → タスク受信箱 を選択します。 リストの手動承認のタスクを選択し、遷移したタスク処理画面の、 クレーム → 開始 の青いボタンをクリックします。 Outputs欄に Approval のチェックボックスと、承認/却下理由の Message のテキストボックスがあるので、今回はそのまま却下(Approvalのチェックは入れない)とし、 Message のテキストボックスには何か適当に理由を入力して、 完了 の青いボタンをクリックします。 Business Central の上部メニューから、 管理 → プロセスインスタンス を選択します。 左のフィルターパネルから Stateメニューの 完了 にチェックを入れます。 手動承認のタスクを処理した結果、プロセスが完了しています。 このインスタンスを選択て、ダイアグラムタブを確認します。 手動承認の処理の結果、Rejected の終了メッセージイベントが実行され、プロセスが終了しています。 request-rejected の Consumer サービス のターミナルをみてみましょう。 終了イベントから送信されたメッセージが表示されているはずです。 { "specversion": "1.0", "time": "2021-04-19T14:04:15.790+0900", "id": "dfb359b4-8c1c-44f4-9344-450e6381e9ed", "type": "java.lang.String", "source": "/process/pam-kafka-message.process-kafka-sample/2", "data": "審査の結果、リクエストは却下とします。" } またタスクの処理後に jbpm-tasks-events の Consumer サービス のターミナルを確認すると、新しく、KIE Serverから送信されたイベントメッセージが表示されています。 タスク処理前と比べて、 state が 1→2(実行中→完了)になり、 variables の message が入力した理由に置き換わっています。 { "specversion": "1.0", "time": "2021-04-19T14:04:15.831+0900", "id": "499f344a-f9b6-4067-819b-2c4fb4afe3d4", "type": "process", "source": "/process/pam-kafka-message.process-kafka-sample/2", "data": { "compositeId": "default-kieserver_2", "id": 2, "processId": "pam-kafka-message.process-kafka-sample", "processName": "process-kafka-sample", "processVersion": "1.0", "state": 2, "containerId": "pam-kafka-message_1.0.0-SNAPSHOT", "initiator": "unknown", "date": "2021-04-19T14:04:15.829+0900", "processInstanceDescription": "process-kafka-sample", "correlationKey": "2", "parentId": -1, "variables": { "request": { "id": 3, "status": "Silver", "score": 150 }, "approval": false, "initiator": "unknown", "message": "審査の結果、リクエストは却下とします。" } } } jbpm-processes-events の Consumer サービス のターミナルにも、プロセスに関するメッセージが送信されていますので、確認をしてみてください。 おわりに いかがでしたでしょうか? RHPAM の開始・終了メッセージイベントを使用することで、Red Hat AMQ Streams (Apache Kafka) と統合し、イベント駆動型のマイクロサービスとして、ビジネスプロセスを運用することができるようになりました。 この機能についてのより詳細な情報については、以下のURLのドキュメントを参照して頂ければと思います。 Red Hat Process Automation Manager と Red Hat AMQ Streams の統合
こんにちは、RHEL のテクニカルサポートを担当している岡田です。 前回の パート1 では Performance Co-Pilot (PCP) で取得したパフォーマンスメトリクスを Grafana を使って可視化する方法をご紹介しました。パート1は1つのホストのパフォーマンスデータをリアルタイムに可視化する方法についてでしたが、今回のパート2では 複数のホスト のパフォーマンスデータを 過去のデータも含めて 可視化する方法をご紹介しています。「あの時のあのホストの負荷状況ってどうだったんだろう?」というような疑問をもったときに、それをあとから Grafana のダッシュボードで確認することができます。ぜひ試してみてください! www.redhat.com
Red Hatでソリューションアーキテクトをしている田中司恩です。RHEL 8.4 Betaが公開され、ようやくRHEL上でPodman v3が使用可能になりました。今回はRHEL 8.4 BetaとPodman v3の新機能についてご紹介します。 RHEL 8.4 Beta Red Hat Enterprise Linux(RHEL)の最新版 RHEL 8.4のベータ版が公開され利用可能になりました(↓ブログ記事)。 www.redhat.com RHEL 8.4 Betaを使用するには有効なサブスクリプションを保有している他にも方法があります。 Red Hat Developer Program への参加もその一つで、RHEL Betaが使用可能です。まだアカウントをお持ちでない場合はこの機会に登録してみてください。Red Hat Developer Programについては下記記事に解説があります。 rheb.hatenablog.com RHEL 8.4 Betaの入手 下記のページの「GET STARTED」を押すとRed Hat IDでのログイン画面に遷移します。 access.redhat.com ログインが完了すると下記のような表示が出て、Red Hat IDに紐づくメールアドレスにメールが届けば準備完了です。 RHEL Betaのリクエスト完了 あとはRed Hat Customer Portalのダウンロードページより、Red Hat Enterprise Linux for x86_64 Beta を選択してイメージを入手してください。 Red Hat Customer PortalよりRHEL Betaを入手 RHEL 8.4 Beta ドキュメント 8.4 Beta としてすでにドキュメントも公開されています(英語版のみ)。 Product Documentation for Red Hat Enterprise Linux 8 | Red Hat Customer Portal 追加機能や変更点はリリースノートにまとまっていますので、詳細はそちらをご確認ください。 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8-beta/html/8.4_release_notes/index container-tools:3.0 モジュールストリームの追加 いろいろ新機能の追加はあるのですが、個人的なイチオシはこれ、 container-tools:3.0 の追加です!これにより RHEL上でPodman v3 をパッケージで導入して使用可能になったことは大きいです。さらにリリースノートの一番最後にあるあたり、ラスボス感があってとても良いです。 リリースノート:container-tools:3.0 についての記載 RHEL 8.4 Betaに追加された container-tools:3.0 のSummary # cat /etc/redhat-release Red Hat Enterprise Linux release 8.4 Beta (Ootpa) # dnf module info container-tools:3.0 |grep Summary Summary : Stable versions of podman 3.0, buildah 1.19, skopeo 1.2, runc, conmon, etc as well as dependencies such as container-selinux built and tested together, and supported as documented on the Application Stream lifecycle page. container-toolsのモジュールリスト # dnf module list container-tools Red Hat Enterprise Linux 8 for x86_64 - AppStream Beta (RPMs) Name Stream Profiles Summary container-tools rhel8 [d][e] common [ Most recent (rolling) versions of podman, buildah, skopeo, runc, conmon, runc, conmon, CRIU, Udica, etc as well as dependencies such as container-selinux built and te d] sted together, and updated as frequently as every 12 weeks. container-tools 1.0 common [ Stable versions of podman 1.0, buildah 1.5, skopeo 0.1, runc, conmon, CRIU, Udica, etc as well as dependencies such as container-selinux built and tested together, an d] d supported for 24 months. container-tools 2.0 common [ Stable versions of podman 1.6, buildah 1.11, skopeo 0.1, runc, conmon, etc as well as dependencies such as container-selinux built and tested together, and supported d] as documented on the Application Stream lifecycle page. container-tools 3.0 common [ Stable versions of podman 3.0, buildah 1.19, skopeo 1.2, runc, conmon, etc as well as dependencies such as container-selinux built and tested together, and supported d] as documented on the Application Stream lifecycle page. なお、container-tools:1.0は非推奨となりますのでご注意ください( リリースノートの7.15 に記載があります)。 Podman v3 PodmanのOSSコミュニティでは先行して開発が進んでいて、CentOS StreamやFedoraではすでにPodman v3が使用可能でした。 github.com なお、最新版はv3.1.0となっておりGitHubで公開されています(2021/4/2、時点)。 Release v3.1.0 · containers/podman · GitHub RHEL 8.4 Beta、CentOS Stream 8、Fedora 33、それぞれの現時点でパッケージで導入できるPodmanのバージョンは下記の通りです。(2021/4/2、時点) RHEL 8.4 # podman version Version: 3.0.2-dev API Version: 3.0.0 Go Version: go1.15.7 Built: Wed Mar 3 00:10:06 2021 OS/Arch: linux/amd64 CentOS Stream 8 # podman version Version: 3.1.0-dev API Version: 3.1.0-dev Go Version: go1.16.1 Built: Sat Mar 27 03:32:03 2021 OS/Arch: linux/amd64 Fedora 33 # podman version Version: 3.0.1 API Version: 3.0.0 Go Version: go1.15.8 Built: Sat Feb 20 01:56:17 2021 OS/Arch: linux/amd64 なお、Fedoraについては updates-testing リポジトリを有効にすることによりv3.1.0の導入が可能です。 # dnf update --refresh --enablerepo=updates-testing podman # podman version Version: 3.1.0 API Version: 3.1.0 Go Version: go1.15.8 Built: Tue Mar 30 22:30:36 2021 OS/Arch: linux/amd64 開発版のバージョンのPodmanの導入方法ついてはPodmanの公式サイトで紹介されています。下記ページを参考にしてください。ソースからビルドする方法についても紹介されています。 Redirect to Podman Docs docker-composeのサポート Podman v3は多くの機能が追加され現在も開発が継続中ですが、個人的なイチオシ機能は doker-compose のサポートです。 これにより docker をインストールすることなく、Podmanとdocker-composeを組み合わせることが可能となりました。 www.redhat.com 「Podmanでdocker-composeが使えない」ということでPodmanの使用を見送っていた方にはぜひ試して頂きたい新機能です。なお、 podman-compose というPodmanを使用して docker-compose.yml を実行するスクリプトがありますが、podman-composeは3rdのプロジェクトであり、Podman v3におけるdocker-composeのサポートとは別物です。Podman v3におけるdocker-composのサポートはDocker互換のインターフェースとしてREST APIがサポートされたことにより実現しています。 この機能についてはまた別記事で詳細な解説をしたいと思います。 (参考:AWXをPodman + docker-composeで起動するテストは成功しています。 こちらを参照→ AWX on Podman ) cockpit-podman RHELのWeb管理コンソール cockpit を使ってPodmanをGUIで操作、管理することができます。RHEL 8.4の新機能というわけではないですが、Podman v3でも利用可能です。 cockpit のアドオン機能の cockpit-podman を有効にすることで使用可能となります(RHEL 8.1以降)。 cockpit-podmanの画面 GUI上ではコンテナーの起動停止だけでなく、コンテナーイメージの取得、削除もできます。 cockpit-podman上でコンテナーイメージの取得 cockpit-podmanは以前からあった機能ですが、個人的にもあまり使ってなかったのでCLIと併用して使っていきたいと思います。 まとめ RHEL 8.4 Betaが公開されましたので合わせて使用可能になったPodman v3についてご紹介しました。RHEL 8.4から正式にPodman v3が搭載されますのでこの機会にいち早くRHEL 8.4とPodman v3に触れてみてはいかがでしょうか。 さらに、記事内で紹介したdocker-composeのサポートは実は奥が深い可能性を秘めています。PodmanはPodman Podとして実行するためのKubernetes YAMLファイルに書き出しに対応しているので、docker-composeのコンテナをPodman Pod、Kubernetes/OpenShiftへと移行するパスが出来上がります。 このように単なるコンテナー実行ツールではないPodmanは要注目です。docker-composeサポートの詳細についてはまた別記事にて紹介いたしますのでお楽しみに。
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 Red Hat OpenStack Platformのライフサイクルについて何度か取り上げていますが、今回は、OpenStack環境のマイグレーションを取り上げます。「新規にRHOSP環境を構築し、ワークロードをマイグレーションする」という考え方です。既存環境をアップグレードするin-placeアップグレードについては過去の記事とRed Hatのカスタマーポータルサイトに掲載されている 公式ドキュメント を参照してください。 OS-Migrate OS-MigrateはふたつのOpenStackクラウド間でリソースとワークロードをエクスポートおよびインポートするためのフレームワークを提供するオープンソースプロジェクトです。Red Hat OpenStack Platformの一部として提供されている訳ではなく、Red Hatが公式にサポートしている訳でもありません。あくまで オープンソース であり、このような取り組みがされていますというご紹介になります。 OS-Migrateとは Ansible Playbookコレクション ユースケースにあわせて、用意されているrolesやmodulesを利用してPlaybookをカスタマイズすることが前提です インポート・エクスポートにはOpenStack APIを使用します。データベースを直接操作することはありません マイグレーションのおおまかな流れ Destination Cloud(新規環境)作成(これはOS-Migrateの範疇外) Pre-workload("control plane") Migration Source Cloud(既存環境)からリソースをエクスポートしてDestination Cloud(新規環境)にインポート Workload Migration Source Cloud(既存環境)からVMとアタッチされているボリュームをエクスポートしてDestination Cloud(新規環境)にインポート これらのエクスポート・インポートの操作はMigratorと呼ぶホストで実施します。OpenStack管理者権限ではなくテナント毎に実施することを前提としています。エクスポート・インポートの情報はyamlファイルに記載されるため、移行に不要な情報を削除したり移行先で名前を変更したい場合など、必要に応じて編集することも可能です。 Pre-workload Migrationの対象となるリソース VMやボリュームなどのワークロードをマイグレーションする前に、Pre-workloadということでOpenStackリソースをマイグレーションします。マイグレーションできるリソースは以下になります。現在の制限としてFloting ipについては、そのまま(=同じIPアドレス)移行はできません。Source CloudとDestination CloudでFloting ipレンジが異なっていると考えられるからです。移行先の新規環境において、新しいFloting ipのレンジから自動的に新しくアサインすることは可能です。同様の観点で、プロバイダーネットワークを使用している環境の移行ではSource CloudとDestination CloudでIPアドレスレンジの重複をどうするか考慮する必要がありますが、これはOS-Migrateの範疇外です。 ユーザー プロジェクト ネットワーク サブネット ルーター ルーターのインターフェース セキュリティグループ セキュリティグループのルール glanceイメージ novaフレーバー keyペア Workload Migration ワークロード、すなわちVMとアタッチされているボリュームをマイグレーションします。 ワークロードを停止して移行するコールドマイグレーションです 。移行の際に、boot diskをコピーするかしないかを指定できます。boot diskのコピーを有効にすると、移行先でのインスタンスはboot-from-volumeになります。 Pre-workload Migration Migrator 必要なパッケージ Ansible 2.9 OpenStack Client OpenStack SDK この環境にOS-Migrateをインストールします ansible-galaxy collection install os_migrate.os_migrate インストールで作成されるファイルの一例 ├── collections │   └── ansible_collections │   ├── community │   │   ├── crypto │   │   │   ├── changelogs │   │   │   ├── meta │   │   │   ├── plugins │   │   │   └── tests │   │   └── general │   │   ├── changelogs │   │   ├── meta │   │   ├── plugins │   │   ├── scripts │   │   └── tests │   ├── openstack │   │   └── cloud │   │   ├── docs │   │   ├── meta │   │   ├── plugins │   │   └── scripts │   └── os_migrate │   └── os_migrate │   ├── playbooks │   ├── plugins │   ├── roles │   └── tests └── tmp # os_migrate以下 └── os_migrate ├── FILES.json ├── MANIFEST.json ├── README.md ├── localhost_inventory.yml ├── playbooks │   ├── delete_conversion_hosts.yml │   ├── deploy_conversion_hosts.yml │   ├── export_flavors.yml │   ├── export_images.yml │   ├── export_keypairs.yml │   ├── export_networks.yml │   ├── export_projects.yml │   ├── export_router_interfaces.yml │   ├── export_routers.yml │   ├── export_security_group_rules.yml │   ├── export_security_groups.yml │   ├── export_subnets.yml (略) MigratorはOpenStack APIを利用するので、認証のための情報をyamlファイルを作成し設定します。リソースが管理者に所属している場合を除いて、プロジェクト/テナント毎にcredentialを利用してOS-migrateを使用することを推奨してます。 必要な認証情報 Source project Destination project Source admin Destination admin 設定例:os-migrate-vars.yml os_migrate_src_auth: auth_url: http://192.168.0.13.199/v3 password: srcpassword project_domain_name: Default project_name: src user_domain_name: Default username: src os_migrate_src_region_name: regionOne os_migrate_dst_auth: auth_url: http://192.167.0.16:5000/v3 password: dstpassword project_domain_name: Default project_name: dst user_domain_name: Default username: dst os_migrate_dst_region_name: regionOne os_migrate_data_dir: /home/migrator/os-migrate-data Migratorの準備ができたところで、各種リソースをエクスポート・インポートします。コマンドでよく利用する値は環境変数で設定しておきます。 例として、ネットワークをエクスポートして、それをインポートするためにはMigratorで下記のコマンドを実行します。なお、Migrator はSource CloudとDestination Cloud両方に対してアクセス可能である必要があります。 OSM_COL=/home/migrator/.ansible/collections/ansible_collections/os_migrate/os_migrate ansible-playbook -v \   -i $OSM_COL/localhost_inventory.yml \   -e @os-migrate-vars.yml \   $OSM_COL/playbooks/export_networks.yml ansible-playbook -v \   -i $OSM_COL/localhost_inventory.yml \   -e @os-migrate-vars.yml \   $OSM_COL/playbooks/import_networks.yml Workload Migration Conversion Host ワークロードのマイグレーションではConversion Hostというものを利用します。これは、Source CloudとDestination Cloud両方で稼働する仮想マシンで、バイナリーボリュームデータをSource CloudからDestination Cloudに転送する処理を行います。Conversion Hostはv2v-conversion-host-appliance-devel.qc2というイメージで提供されており、このイメージをSource CloudとDestination Cloudにアップロードしておき、Source CloudとDestination Cloudの移行対象のテナントでインスタンスを起動します。 Source Cloudでの処理 移行対象の仮想サーバからボリュームをデタッチします Source CloudのConversion Hostにボリュームをアタッチします ボリュームをブロックデバイスとしてエクスポートして、Destination CloudのConversion Hostからの接続を待ちます Destination Cloudでの処理 Destination CloudのConversion Host上に新しいボリュームを作成します Source CloudのConversion Hostによってエクスポートされたブロックに接続し、新しくアタッチされたボリュームにデータをコピーします Destination CloudのConversion Hostからボリュームをデタッチします 新しいボリュームから新しい仮想サーバを作成します Workloadについてもエクスポート・インポートのコマンドはPre-workloadと同様にMigratorで実行します。 ansible-playbook -v \   -i $OSM_COL/localhost_inventory.yml \   -e @os-migrate-vars.yml \   $OSM_COL/playbooks/export_workloads.yml ansible-playbook -v \   -i $OSM_COL/localhost_inventory.yml \   -e @os-migrate-vars.yml \   $OSM_COL/playbooks/import_workloads.yml これらの処理をテナント毎にひたすら実行します。リソースはネットワーク、サブネット、ルーター、ルーターインターフェース等々たくさんありますが、クラウドが稼働中でもエクスポート・インポート処理はできるので問題ないと思います。ワークロードについては停止を伴うため、移行タイミングに考慮が必要です。そのため、実際にマイグレーションするとなると、テナントの数やVMの数、使用しているボリュームのサイズ等考慮すべき点は多数ありますので、このOS-Migrateというツールが即使えるという訳ではありませんが、マイグレーションの方法の一例として紹介させていただきました。 ドキュメント  https://os-migrate.github.io/os-migrate/ ソースコード  https://github.com/os-migrate/os-migrate ↓OS-Migrateを開発している方々の記事 www.redhat.com
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 「Red Hat OpenStack Platform 13と16の機能差分」という記事で、RHOSP 16から従来どおりのTelemetryがデフォルトでdisableになりService Telemetry Frameworkが推奨されていることを記載しました。今回はこのService Telemetry Frameworkについて説明いたします。 Service Telemetry Framework Service Telemetry FrameworkはRed Hat OpenShift Container Platform(以降OCP)上で稼働します。このOCPは、Telemetryの対象となるRHOSPとは独立している必要があります。 RHOSPのTelemetryの話なのに、いきなりOCPなのか?とツッコミたくなるかもしれませんが、将来的にはService Telemetry Frameworkを利用して複数のクラウド環境を集中管理したいという考えがあり、OCPではスケーラブルなモニタリング環境を稼働させることが可能なため、これを利用する方向になっています。OCPとRHOSPの環境は弊社のラボ環境を使用しています。宣伝になりますが、OpenShiftのコンセプトと基本的なクラスタ管理方法を学べる「Containers and Cloud-Native Roadshow 2021」が5月末頃に開催されますので、興味があればご利用ください(ただしSTFは含まれません)。今回はOCPの環境が既にある前提でSTF導入・設定を行います。 環境および導入するコンポーネント RHOSPとOCP環境と導入するコンポーネントは以下です。Service Telemetry Frameworkのデータ収集コンポーネントであるcollectd・Ceilometer、トランスポート用コンポーネント AMQ InterconnectとSmart GatewayはRed Hatがサポートします。PrometheusとElasticSearch、可視化コンポーネントGrafanaはコミュニティでサポートされているものを使用します。データ収集にcollectdとCeilometer両方利用するのは、collectdだけではOpenStackのメトリックを収集できないためです。 Red Hat OpenShift Container Platform 4.6 AMQ Certificate Manager Operator Elastic Cloud on Kubernetes Operator Service Telemetry Operator(Service Telemetry Framework 1.2) Grafana operator Red Hat OpenStack Platform 16.1 AMQ Interconnect Ceilometer Collectd 公式ドキュメント: Service Telemetry Framework 1.2 実施する内容 OCP環境にService Telemetry Frameworkをデプロイ OCP内にServiceTelemetry objectを作成 RHOSPをService Telemetry Frameworkを利用するように構成 動作確認 OCP環境にService Telemetry Frameworkをデプロイ まずservice-telemetryのnamespaceを作成します。 $ oc new-project service-telemetry OperatorGroupを作成します。 $ oc apply -f - <<EOF apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: service-telemetry-operator-group namespace: service-telemetry spec: targetNamespaces: - service-telemetry EOF ElasticSearchやGrafanaなどコミュニティのOperatorを利用するため、OperatorHub.io Community Catalog Sourceを有効にします。 $ oc apply -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: CatalogSource metadata: name: operatorhubio-operators namespace: openshift-marketplace spec: sourceType: grpc image: quay.io/operator-framework/upstream-community-operators:latest displayName: OperatorHub.io Operators publisher: OperatorHub.io EOF Service Telemetry Frameworkを利用するためにRed Hat STF Operators CatalogSourceを有効にします。 $ oc apply -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: CatalogSource metadata: name: redhat-operators-stf namespace: openshift-marketplace spec: displayName: Red Hat STF Operators image: quay.io/redhat-operators-stf/stf-catalog:v4.6 publisher: Red Hat sourceType: grpc updateStrategy: registryPoll: interval: 30m EOF AMQ Certificate Manager Operatorをデプロイします。 $ oc apply -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: amq7-cert-manager-operator namespace: openshift-operators spec: channel: alpha installPlanApproval: Automatic name: amq7-cert-manager-operator source: redhat-operators-stf sourceNamespace: openshift-marketplace targetNamespaces: global EOF ClusterServiceVersionを確認して「Succeeded」になっていることを確認します。 $ oc get --namespace openshift-operators csv NAME DISPLAY VERSION REPLACES PHASE amq7-cert-manager.v1.0.0 Red Hat Integration - AMQ Certificate Manager 1.0.0 Succeeded Kubernetes OperatorのElastic Cloudをデプロイします。 $ oc apply -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: elastic-cloud-eck namespace: service-telemetry spec: channel: stable installPlanApproval: Automatic name: elastic-cloud-eck source: operatorhubio-operators sourceNamespace: openshift-marketplace EOF Service Telemetry Operatorをデプロイします。 $ oc apply -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: service-telemetry-operator namespace: service-telemetry spec: channel: stable-1.2 installPlanApproval: Automatic name: service-telemetry-operator source: redhat-operators sourceNamespace: openshift-marketplace EOF 公式ドキュメントの中では後のステップで行っていますが、Dashboradを利用するためにGrafana Operatorをデプロイします。 $ oc apply -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: grafana-operator namespace: service-telemetry spec: channel: alpha installPlanApproval: Automatic name: grafana-operator source: operatorhubio-operators sourceNamespace: openshift-marketplace EOF 必要なコンポーネントがすべて正常にデプロイされているか確認します。 $ oc get csv --namespace service-telemetry NAME DISPLAY VERSION REPLACES PHASE amq7-cert-manager.v1.0.0 Red Hat Integration - AMQ Certificate Manager 1.0.0 Succeeded amq7-interconnect-operator.v1.2.3 Red Hat Integration - AMQ Interconnect 1.2.3 amq7-interconnect-operator.v1.2.2 Succeeded elastic-cloud-eck.v1.4.0 Elasticsearch (ECK) Operator 1.4.0 elastic-cloud-eck.v1.3.1 Succeeded grafana-operator.v3.9.0 Grafana Operator 3.9.0 grafana-operator.v3.8.1 Succeeded prometheusoperator.0.37.0 Prometheus Operator 0.37.0 prometheusoperator.0.32.0 Succeeded service-telemetry-operator.v1.2.1 Service Telemetry Operator 1.2.1 Succeeded smart-gateway-operator.v2.2.1 Smart Gateway Operator 2.2.1 Succeeded CLIで操作を行ってきましたが、OpenShift コンソールで見るとProject: service-telemetryの「Installed Operators」に表示されています。 OCP内にServiceTelemetry objectを作成 ServiceTelemetry objectの主要なパラメーターは以下になります。 alerting Prometheusにアラートのルールを作成し、Alertmanagerにアラートを送信します。 backends メトリックとイベントを保存するためのストレージの有効化とストレージの指定を行います。現時点ではメトリックのバックエンドはPrometheus、イベントのバックエンドはElasticSearchです。 clouds STFに接続するクラウドを定義し、メトリックとイベントのcollectorを指定します。 graphing collectdで収集されたメトリックをGrafanaを使って可視化する設定を行います。 highAvailability STFのコンポーネントの冗長設定を行います。現状ではSTFは完全なfault tolerant systemではなく、リカバー中のメトリックやイベントは保証されません。 transports STFのメッセージバスの有効化と設定を行います。現状ではAMQ Interconnectのみがサポートされます。 alertingやgraphingなど使いたいサービスをenabled:trueに設定してServiceTelemetry objectを作成します。OpenStackのメトリックやイベント収集のためにclouds parameter を指定します。(以下の内容は一例です、必要に応じて編集してください) apiVersion: infra.watch/v1beta1 kind: ServiceTelemetry metadata: name: default spec: alerting: enabled: true alertmanager: storage: strategy: persistent persistent: storageSelector: {} pvcStorageRequest: 20G backends: metrics: prometheus: enabled: true scrapeInterval: 10s storage: strategy: persistent retention: 24h persistent: storageSelector: {} pvcStorageRequest: 20G events: elasticsearch: enabled: true storage: strategy: persistent persistent: pvcStorageRequest: 20Gi graphing: enabled: true grafana: ingressEnabled: false adminPassword: secret adminUser: root disableSignoutMenu: false transports: qdr: enabled: true web: enabled: false highAvailability: enabled: false clouds: - name: cloud1 metrics: collectors: - collectorType: collectd subscriptionAddress: collectd/telemetry - collectorType: ceilometer subscriptionAddress: anycast/ceilometer/metering.sample events: collectors: - collectorType: collectd subscriptionAddress: collectd/notify - collectorType: ceilometer subscriptionAddress: anycast/ceilometer/event.sample ServiceTelemetry objectが作成されると、設定された内容に従ってPodが稼働します。 $ oc get pods NAME READY STATUS RESTARTS AGE alertmanager-default-0 2/2 Running 0 2d5h default-cloud1-ceil-event-smartgateway-5f8ff46bfb-bdbzd 1/1 Running 3 2d4h default-cloud1-ceil-meter-smartgateway-5ff6cd4bbb-gl6kf 1/1 Running 0 2d5h default-cloud1-coll-event-smartgateway-54fc6cd9b4-zlb8f 1/1 Running 3 2d4h default-cloud1-coll-meter-smartgateway-8446fc88d9-wwvzr 2/2 Running 0 2d5h default-interconnect-668d5bbcd6-dtxd4 1/1 Running 0 2d5h elastic-operator-6dd57fb74b-746pw 1/1 Running 0 2d9h elasticsearch-es-default-0 1/1 Running 0 2d4h grafana-deployment-76dccbcfcd-r45d6 1/1 Running 0 43h grafana-operator-7456f8c54f-zfrzd 1/1 Running 0 2d9h interconnect-operator-69df6b9cb6-j7868 1/1 Running 0 2d9h prometheus-default-0 3/3 Running 1 2d5h prometheus-operator-7fcbb6dbc9-qlxt7 1/1 Running 0 2d9h service-telemetry-operator-86764c5c44-874qt 2/2 Running 0 2d9h smart-gateway-operator-5c44c5947b-wr9bf 2/2 Running 0 2d9h CLIだけでなく、OpenShift コンソールの[Developer]→[Toplogy]でも確認できます。 RHOSPをService Telemetry Frameworkを利用するように構成 OCP側の準備ができたところでRHOSPのデプロイを行います。既にundercloudのインストール、overcloudのデプロイの準備、STF以外のTemplateの準備は済んでる前提です。 OCP環境のCLIでservice-telemetryのAMQ Interconnect route addressを調べます。この環境では「default-interconnect-5671-service-telemetry.apps.cluster-5224.5224.sandbox605.opentlc.com」が結果として表示されています。 $ oc get routes -ogo-template='{{ range .items }}{{printf "%s\n" .spec.host }}{{ end }}' | grep "\-5671" default-interconnect-5671-service-telemetry.apps.cluster-5224.5224.sandbox605.opentlc.com RHOSPでAMQ Interconnect route addressを指定するstf-connectors.yamlを作成し、STFを有効化するyamlファイルを指定してovercloudをデプロイします。 stf-connectors.yaml作成 環境ファイルceilometer-write-qdr.yamlを指定 環境ファイルenable-stf.yaml stf-connectors.yaml [stack@undercloud ~]$ source ./stackrc (undercloud) [stack@undercloud ~]$ cat templates/stf-connectors.yaml parameter_defaults: EventPipelinePublishers: [] MetricPipelinePublishers: [] CeilometerQdrPublishEvents: true CeilometerQdrPublishMetrics: true MetricsQdrConnectors: - host: default-interconnect-5671-service-telemetry.apps.cluster-5224.5224.sandbox605.opentlc.com ←ここに先程の結果を記載 port: 443 role: edge sslProfile: sslProfile verifyHostname: false ExtraConfig: ceilometer::agent::polling::polling_interval: 5 ceilometer-write-qdr.yaml (undercloud) [stack@undercloud environments]$ cat metrics/ceilometer-write-qdr.yaml ## This environment serves the purpose of enabling ceilometer to send telemetry and notification data ## through QPID dispatch routers. resource_registry: OS::TripleO::Services::CeilometerAgentCentral: ../../deployment/ceilometer/ceilometer-agent-central-container-puppet.yaml OS::TripleO::Services::CeilometerAgentNotification: ../../deployment/ceilometer/ceilometer-agent-notification-container-puppet.yaml OS::TripleO::Services::CeilometerAgentIpmi: ../../deployment/ceilometer/ceilometer-agent-ipmi-container-puppet.yaml OS::TripleO::Services::ComputeCeilometerAgent: ../../deployment/ceilometer/ceilometer-agent-compute-container-puppet.yaml OS::TripleO::Services::Redis: ../../deployment/database/redis-pacemaker-puppet.yaml parameter_defaults: CeilometerEnablePanko: false CeilometerQdrPublish: true (undercloud) [stack@undercloud environments]$ enable-stf.yaml (undercloud) [stack@undercloud environments]$ cat enable-stf.yaml # This heat environment can be used to enable STF client side resource_registry: OS::TripleO::Services::Collectd: ../deployment/metrics/collectd-container-puppet.yaml OS::TripleO::Services::MetricsQdr: ../deployment/metrics/qdr-container-puppet.yaml OS::TripleO::Services::Redis: ../deployment/database/redis-pacemaker-puppet.yaml # We want these when smartgateway is able to process ceilometer messages # OS::TripleO::Services::CeilometerAgentCentral: ../deployment/ceilometer/ceilometer-agent-central-container-puppet.yaml # OS::TripleO::Services::CeilometerAgentNotification: ../deployment/ceilometer/ceilometer-agent-notification-container-puppet.yaml # OS::TripleO::Services::ComputeCeilometerAgent: ../deployment/ceilometer/ceilometer-agent-compute-container-puppet.yaml parameter_defaults: # Uncomment when smartgateway can handle ceilometer messages # CeilometerQdrPublish: true EnableSTF: true CollectdConnectionType: amqp1 CollectdAmqpInterval: 5 CollectdDefaultPollingInterval: 5 CollectdAmqpInstances: notify: notify: true format: JSON presettle: false telemetry: format: JSON presettle: true MetricsQdrAddresses: - prefix: collectd distribution: multicast MetricsQdrSSLProfiles: - name: sslProfile # The snippet below should be added to a separate yaml file, edited, and # passed in at deploy time. #MetricsQdrConnectors: # - host: qdr-normal-sa-telemetry.apps.remote.tld # port: 443 # role: edge # sslProfile: sslProfile # verifyHostname: false (undercloud) [stack@undercloud environments]$ 上記3ファイルを指定してデプロイするshを作ってデプロイします。 #!/bin/bash THT=/usr/share/openstack-tripleo-heat-templates/ CNF=/home/stack/templates/ openstack overcloud deploy --templates $THT \ -r $CNF/roles_data.yaml \ -n $CNF/network_data.yaml \ -e ~/containers-prepare-parameter.yaml \ -e $CNF/environments/node-info.yaml \ -e $THT/environments/network-isolation.yaml \ -e $CNF/environments/network-environment.yaml \ -e $CNF/environments/ips-from-pool-all.yaml \ -e $CNF/scheduler-hints.yaml \ -e $CNF/environments/fix-nova-reserved-host-memory.yaml \ -e $THT/environments/metrics/ceilometer-write-qdr.yaml \ -e $THT/environments/enable-stf.yaml \ -e $CNF/stf-connectors.yaml 動作確認 RHOSP側 デプロイされたovercloudのノードで該当するコンテナのAMQの設定内容を確認することができます。 (undercloud) [stack@undercloud ~]$ openstack server list +--------------------------------------+-------------------------+--------+---------------------+----------------+-----------+ | ID | Name | Status | Networks | Image | Flavor | +--------------------------------------+-------------------------+--------+---------------------+----------------+-----------+ | 19247b16-d920-411a-8885-67949b85e4d6 | overcloud-controller-2 | ACTIVE | ctlplane=192.0.2.12 | overcloud-full | baremetal | | 08a228bb-6190-46ce-b4c4-81b594c99667 | overcloud-controller-0 | ACTIVE | ctlplane=192.0.2.20 | overcloud-full | baremetal | | 2c45ccd4-3777-478d-9a6c-918e25853415 | overcloud-controller-1 | ACTIVE | ctlplane=192.0.2.16 | overcloud-full | baremetal | | a402a393-61b7-4036-a865-728c0984ffa3 | overcloud-novacompute-1 | ACTIVE | ctlplane=192.0.2.23 | overcloud-full | baremetal | | b83d7e27-fbc3-4a8e-8f27-d35c01cb3490 | overcloud-novacompute-0 | ACTIVE | ctlplane=192.0.2.11 | overcloud-full | baremetal | +--------------------------------------+-------------------------+--------+---------------------+----------------+-----------+ (undercloud) [stack@undercloud ~]$ ssh heat-admin@192.0.2.20 [heat-admin@overcloud-controller-0 ~]$ sudo podman container inspect --format '{{.State.Status}}' metrics_qdr running [heat-admin@overcloud-controller-0 ~]$ sudo podman exec -it metrics_qdr cat /etc/qpid-dispatch/qdrouterd.conf router { mode: edge id: Router.overcloud-controller-0.localdomain workerThreads: 2 debugDump: /var/log/qdrouterd saslConfigPath: /etc/sasl2 saslConfigName: qdrouterd } sslProfile { name: sslProfile } listener { host: 172.17.0.201 port: 5666 authenticatePeer: no saslMechanisms: ANONYMOUS } connector { host: default-interconnect-5671-service-telemetry.apps.cluster-5224.5224.sandbox605.opentlc.com port: 443 role: edge sslProfile: sslProfile verifyHostname: false } (略) address { distribution: multicast prefix: collectd } コネクションの確認。以下の4つのコネクションがあることがわかります。 Outbound connection to STF Inbound connection from ceilometer Inbound connection from collectd Inbound connection from our qdstat client [heat-admin@overcloud-controller-0 ~]$ sudo podman exec -it metrics_qdr qdstat --bus=172.17.0.201:5666 --connections Connections id host container role dir security authentication tenant ================================================================================================================================================================================================================================================================================================== 2 172.17.0.201:44718 metrics normal in no-security anonymous-user 3 172.17.0.201:53288 openstack.org/om/container/overcloud-controller-0/ceilometer-agent-notification/23/164c3ee60fe54e0e85afcf7ba3f52166 normal in no-security no-auth 273 default-interconnect-5671-service-telemetry.apps.cluster-5224.5224.sandbox605.opentlc.com:443 default-interconnect-668d5bbcd6-dtxd4 edge out TLSv1.2(DHE-RSA-AES256-GCM-SHA384) anonymous-user 309 172.17.0.201:49654 10931bbe-0af8-448e-b92b-cacc9b8de4c7 normal in no-security no-auth OCP側 AMQ Interconnect podの名前を元にしてコネクションの確認ができます。 $ oc get pods -l application=default-interconnect NAME READY STATUS RESTARTS AGE default-interconnect-668d5bbcd6-dtxd4 1/1 Running 0 2d6h $ oc exec -it default-interconnect-668d5bbcd6-dtxd4 -- qdstat --connections 2021-03-19 10:36:10.872461 UTC default-interconnect-668d5bbcd6-dtxd4 Connections id host container role dir security authentication tenant last dlv uptime ============================================================================================================================================================================================== 1 10.128.2.99:40234 bridge-36d edge in no-security anonymous-user 000:00:00:01 002:06:03:50 2 10.131.1.182:47508 rcv[default-cloud1-ceil-meter-smartgateway-5ff6cd4bbb-gl6kf] edge in no-security anonymous-user - 002:06:03:28 3 10.129.2.49:33336 rcv[default-cloud1-coll-event-smartgateway-54fc6cd9b4-zlb8f] normal in no-security anonymous-user - 002:05:32:19 4 10.129.2.50:47392 rcv[default-cloud1-ceil-event-smartgateway-5f8ff46bfb-bdbzd] normal in no-security anonymous-user 000:09:48:02 002:05:32:15 94 10.129.2.11:55704 Router.overcloud-controller-1.localdomain edge in TLSv1/SSLv3(DHE-RSA-AES256-GCM-SHA384) anonymous-user 000:00:00:01 000:03:16:02 95 10.128.2.6:53364 Router.overcloud-controller-2.localdomain edge in TLSv1/SSLv3(DHE-RSA-AES256-GCM-SHA384) anonymous-user 000:00:00:02 000:03:16:02 96 10.129.2.11:55762 Router.overcloud-controller-0.localdomain edge in TLSv1/SSLv3(DHE-RSA-AES256-GCM-SHA384) anonymous-user 000:00:00:01 000:03:15:59 98 127.0.0.1:57040 62680fcf-e316-4d03-8ddb-5a34010ed2e3 normal in no-security no-auth 000:00:00:00 000:00:00:00 $ oc exec -it default-interconnect-668d5bbcd6-dtxd4 -- qdstat --address 2021-03-19 10:39:13.304383 UTC default-interconnect-668d5bbcd6-dtxd4 Router Addresses class addr phs distrib pri local remote in out thru fallback ============================================================================================================================= mobile anycast/ceilometer/event.sample 0 balanced - 1 0 107 107 0 0 mobile anycast/ceilometer/metering.sample 0 balanced - 1 0 0 0 0 0 mobile collectd/notify 0 multicast - 1 0 0 0 0 0 mobile collectd/telemetry 0 multicast - 1 0 7,824,586 7,824,586 0 0 Dashboard Service Telemetry Framework objectを作成する際にgraphingを有効化してあるので、OpenStackのノードのcollectdで収集されたメトリックをGrafanaで確認することができます。 Service Telemetry Frameworkは、日々機能改善が行われています。collectdのpluginも機能改善が行われ、より使いやすくなると思われます。機会があれば、またご紹介いたします。
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 このブログで何度か取り上げておりますが、2021年3月の時点でRed Hat OpenStack Platform(以降RHOSP)の最新版は16.1になります。Long Life ReleaseであるRHOSP 13もメンテナンスサポート期間ではありますが、 RHOSP 13のメンテナンスサポートは2021年6月27日 までです。それ以降でサポートを受けるためにはExtended life cycle support (ELS) add-onが必要になります。 ELSを適用した場合、サポート期限は2023年6月27日となります 。RHOSPのサポートを継続して受けたい場合は、RHOSP 13のELSを導入いただくか、RHOSP 16にバージョンアップしていただく必要があります。 access.redhat.com RHOSP 13とRHOSP 16.1の差分 RHOSP 16では機能拡張やバグフィックスが行われています。拡張されている機能に関してはリリースノートの「機能拡張」をご覧いただくか、詳細については弊社までお問い合わせをいただければと思います。現在既にRHOSPをご使用中で、バージョンアップを検討する場合は、RHOSP 13では使用できていたが、RHOSP 16ではサポートされない機能があるか考慮する必要があります。以下は、RHOSPのリリースノートから抜粋した非推奨・廃止された機能です。非推奨の機能とは、現在はサポートされてはいるが今後サポート外になる予定のものです。 コンポーネント 内容 OpenDaylight 13で初めて導入されましたが、14では非推奨になりました。OSP14のサイクル期間中、OpenDaylightのサポートは継続されバグ修正のリクエストは受け付けられますが、OSP13のライフサイクル終了の時点でサポートは完全に廃止される予定です。 gnocchi (openstack-ceilometer) 15でTelemetryサービスの一部であるgnocchi は非推奨になりました。RHOSPの今後のバージョンでは、gnocchiおよび残りのTelemetryサービスが廃止され、Red Hat Service Assurance Framework(Service Telemetry Framework ) に置き換えられる予定です。 aodh (openstack-ceilometer) 15でTelemetryサービスの一部であるAlarm サービス(aodh)は非推奨になりました。RHOSPの今後のバージョンでは、Alarmサービスが廃止される予定です。 ceilometer client 16.0 ではTelemetryサービスの一部であるceilometer clientがサポートされなくなり、廃止されています。廃止されたのはクライアントとAPIにであり、ceilometer agentは引き続き RHOSPの一部です。 - 15でモニタリングエージェントSensuクライアントサービスは非推奨になりました。 RHOSPの今後のバージョンでは、Sensuクライアントサービスが廃止される予定です。 openstack-tripleo-heat-templates 15でOpenStack Elastic Compute Cloud(EC2)API は非推奨になり、16.0でサポートされなくなりました。directorでは EC2 API のサポートは非推奨になり、今後の RHOSP リリースで廃止される計画です。 openstack-sahara 15でData Processingサービス (sahara)は非推奨になり、16.0で廃止されました。13および15でData Processingサービスのサポートを継続して提供します。 TripleO Red Hat OpenStack director (TripleO)は、OpenShiftインストールの Playbook (openshift-ansible パッケージで提供される) および Orchestrationサービス (heat))テンプレートを使用した、ベアメタルノードへの Red Hat OpenShift Container Platform 3.11 クラスターのデプロイをサポートしなくなりました。ベアメタルノードに OpenShift 3.11 をデプロイするには、Orchestrationサービスのテンプレートを使用せずに、OpenShift インストールのPlaybook だけを使用します。 openstack-tripleo-heat-templates 15 では、controller-v6.yamlファイルは必要なくなりました。controller-v6.yaml で定義されていたルートはcontroller.yaml で定義されるようになりました。 - 15ではNova vCenterプラグインは非推奨になりました。このプラグインは16 で廃止される予定です - 16.0で環境ファイル /usr/share/openstack-tripleo-heat-templates/environments/deployed-server-bootstrap-environment-rhel.yaml が廃止されています。この環境ファイルは、事前にプロビジョニングされたノードを使用する場合に使用されていました。 - 16.1でRed Hat Ceph Storage クラスターの管理者キーリングシークレットをカスタマイズできなくなりました。その代わりに、初期のデプロイメント時に管理者キーリングシークレットが無作為に生成されます。 Red Hat OpenStack Platform Telemetry RHOSPのTelemetryについて、16以前はCeilometer・gnocchi・aodhを利用してTelemetryサービスを提供していました。データの保存場所やポーリングの間隔などをデフォルトで構成した場合OpenStack Controllerに負荷がかかるため、RHOSP 16では従来のTelemetryサービスはデフォルトではdisableになっています。代わりにService Telemetry Frameworkという仕組みを推奨しています。従来のTelemetryサービスは非推奨にはなっていますがRHOSP 13と同様にenableにすることは可能で、サポートもされますが、今後はService Telemetry Frameworkの利用をお薦めしています。Service Telemetry Frameworkの仕組みについては別記事でご紹介します。 従来のRed Hat OpenStack Platform Telemetryの仕組み RHOSP 16において、RHOSP 13と同様のTelemetryサービスを使う場合は、従来どおりのTelemetryを有効にするためのyamlファイルが用意されているので、OpenStack Directorを用いてOpenStack環境をデプロイする際に、そのファイルを指定してデプロイします。詳細は「 Deployment Recommendations for Specific Red Hat OpenStack Platform Services 」を参照してください。