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

TECH PLAY

Red Hat  - Open Innovation Labs

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

全900件

Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Checkpointing Java from outside of Java | Red Hat Developer の翻訳記事です。 OpenJDKのJava仮想マシン(JVM)がJavaアプリケーションを実行する際、メインクラスを起動する前に十数個のクラスをロードします。また、あるメソッドを数百回実行してから、そのメソッドの最適化コンパイラを起動します。このような準備は、「write once, run anywhere(一度書けばどこでも実行できる)」というJavaのパワーを支える重要な要素ですが、その代償として起動時間が長くなってしまいます。 私たちは、新しいアプローチに取り組んできました。これにより、クラスをロードし、ジャストインタイム(JIT)コンパイラをウォームアップしてから、アプリケーションにチェックポイントを設けられます。その後、アプリケーションをリストアすることで、素早く実行できます。この変更により、起動に数秒かかっていたアプリケーションが、ミリ秒でウォームアップするようになりました。 この記事では、Linuxのコマンドラインからチェックポイントを設ける方法および実行中のJavaプログラムをリストアする方法をご紹介します。近日中に別の記事で、Javaコードの内部からJavaプログラムのチェックポイントを設けてリストアを可能にするJava Native Interface(JNI)ライブラリを紹介します。 Javaコードでのチェックポイントの使用 JNIの Checkpoint Restore library は、 Linux Checkpoint/Restore in Userspace (CRIU)をベースにしています。この記事の例では、これを使用します。 CRIUは起動時間を短縮できますが、それ以上の可能性を秘めています。 長時間動作するプログラムがある場合、定期的にチェックポイントを設定できます。障害が発生した場合、最後のチェックポイントからアプリケーションを再起動できます。もし、障害の原因がバグであれば、すぐに再現できます。また、外部要因による障害であれば、作業を中断することなく、前回の続きを行えます。 別の例として、プログラムのいくつかのポイントでヒープダンプを取りたいが、ヒープ内を走査するために停止するとプログラムの実行が妨害されます。チェックポイントを挿入することで、プログラムを完了まで実行した後、戻ってヒープダンプを行うために再起動できます。これにより、元のプログラムと非常によく似たプログラムの実行順序で、興味のある時点でのメモリレイアウトを見れます。 いい感じでしょうか?例を見てみましょう。 Java以外からのチェックポイントを設ける処理 この例では、実行中のJavaプログラムをコマンドラインからチェックポイントを設け、リストアする方法を学びます。まず始めに、ScoobyというJavaプログラムを実行しているとします。 ターミナル1から、以下を入力します。 % setsid java -XX:-UsePerfData -XX:+UseSerialGC Scooby 別のターミナルの別のディレクトリから、以下を入力します。 % sudo criu dump -t <pid> --shell-job -o dump.log これで ps を実行して、自分の Java プログラムがもはや実行されていないことを確認できます。ディレクトリを見ると、いくつかのイメージファイルを見られます。また、 dump.log を見ると、CRIU がコードにチェックポイントを設けるために行ったことをすべて確認できます。 では、イメージをダンプしたディレクトリから、以下のようにしてください。 % sudo criu restore --shell-job -d -vvv -o restore.log Javaプログラムが再び実行されているのが見えるはずです。 restore.log をチェックして、リストアがどのように行われたかを確認できます。デフォルトでは、CRIUはJVMを同じプロセスID(PID)にリストアしていることに気づくでしょう。同じイメージを複数回リストアしたい場合は、仮想PIDを使用できます。 % sudo unshare -p -m -f bash # mount -t proc none /proc/ # criu restore --shell-job 別のウィンドウで、同じディレクトリを使って、次のようにします。 % sudo unshare -p -m -f bash # mount -t proc none /proc/ # criu restore --shell-job まとめ チェックポイントを設けることにはいくつかの問題があります。今のところ、チェックポイントを使用する際には perf と並列ガベージコレクションをオフにする必要があります。また、 /var/lib/sss/pipes/nss というファイルがある場合は、それを削除しなければなりません。また、 restore 操作を実行するには root 権限が必要になります。なぜなら、特定の PID を選択できるようにする必要があるためです。現在、CRIUチームがこの問題に取り組んでいます。 次回は、JNI Checkpoint Restoreライブラリを使って、Javaの中からJavaにチェックポイントを設ける方法をご紹介しますので、お楽しみに。
Red Hatのソリューションアーキテクトの伊藤ちひろです。 Red Hat にはクラウドネイティブアプリの開発に役立つ、ソフトウェアのラインナップが充実していることをご存知ですか? ここでは、それらのソフトウェア [Red Hat Application Services] に関する注目ニュースを、各製品技術に特化したソリューションアーキテクトが、ご紹介します。 今回は 2021/8月号となります。 想定読者 エンタープライズアーキテクト アプリケーション開発者 システムの提案をするSIerの方 特集1: CodeReady Workspacesをカスタマイズして便利に開発してみよう その3 CodeReady WorkspacesはEclipse CheをベースとしたクラウドIDEです。 3回目となる今回はプラグインレジストリのカスタマイズの仕方を紹介いたします。今回GAしているKogitoをQuakurs便利に扱うためのプラグインを題材にしています。 rheb.hatenablog.com 特集2: Red HatによるManaged Kafka, RHOSAKのトライアルを試してみる! Red Hat OpenShift Streams for Apache Kafka(RHOSAKと略され、「ロサック」と発音しています)はRed Hatが提供するManaged Kafkaのサービスです。Kafkaの環境を自分で構築・運用することなく、ストリーム処理のアプリケーションの開発やリリースを簡単に行うことができるようになります。概要については、以前の赤帽ブログの Application Services Newsletter 7月号 や Speakersdeck内のスライド でも紹介していますので、そちらも併せて読んで頂ければと思います。 今回は、RHOSAKを使うことでKafkaをすぐに利用できるところまでを実際に試す方法について説明していきます。 rheb.hatenablog.com 特集3: Kogitoがついに来た!ルールエンジン開発が更に手軽に 先日(2021/6)リリースされた、Red Hat Decision Managerのv7.11で、Kogito(コジト)の一部機能が、製品として正式にサポート対象になりました。 Kogitoによって、業務ルールのマイクロサービス開発が更に手軽になります。 Kogitoの詳細については、ぜひこちらの記事を見てください。 qiita.com 好評開催中!クラウドネイティブアプリ開発関連のWebinar全6回 Cloud Nativeを見据えたアプリケーションアーキテクチャとレガシーモダナイゼーション コンテナ時代の開発ツールチェインと開発プロセスのベストプラクティス クラウド/コンテナを前提とした時代のアプリケーション実行環境の選択 マイクロサービス/サーバーレス実践入門 これからのシステム連携を実現するデジタル基盤とアプローチ Cloud Nativeなデータパイプラインの作り方とオープンハイブリッドクラウドへの展開 各回とも、オンデマンドで視聴出来ます。(お名前とメールアドレス等の登録のみで視聴可能です) 下記リンクよりぜひご登録ください。 www.redhat.com 直近GAになった製品群 最近リリースとなった Application Services 製品群のリストをご紹介します。 見逃している製品が無いか、是非一度ご確認ください。 Red Hat build of Quarkus 1.11 Red Hat JBoss Web Server 5.5 Red Hat support for Spring Boot 2.3 Red Hat build of Eclipse Vert.x 4.1
Red Hatの森若です。 今日はRHEL小技ということで、実際にアップデートせずにアップデートに必要なパッケージを確認・ダウンロードする方法をご紹介します。 パッケージの確認 # yum update --assumeno <パッケージ名> --assumeno は、よく使われる -y と逆の意味で、あらゆる質問に自動的にNoと答えます。yumは必要に応じてキャッシュのアップデート、依存関係の解決をして、リクエストされたアップデートに必要なパッケージ一覧を表示して終了します。 パッケージのダウンロード # yum update --downloadonly <パッケージ名> --downloadonlyは、パッケージのダウンロードだけを行い、インストールをしません。 ダウンロードされたパッケージは、/var/cache/yum または /var/cache/dnf 以下に保存されています。リポジトリ等によりダウンロード先は異なりますが、以下のようなコマンドでみつけられます。 # find /var/cache/yum -type f -name "*rpm" yum を使わずにできるか? さて、依存関係の解決をyumでおこなわずに、「○○をアップデートするために必要なrpmの一覧が欲しい」と仰るお客様が時折いらっしゃいます。 おそらくシステムをインターネット接続できなくて、かつRed Hat Satellite等を利用できないような、制限が厳しい状況なのだと思います。 残念ながらそのような一覧をyumのようなツールを使わずに作ることは非常に困難です。 依存関係の解決 rpmの依存関係はパッケージそれぞれで見ると単純なものに見えますが、複数のパッケージが互いに依存関係やバージョンの制約を宣言しているため、実際に依存や制約を守りつつアップデートを行うには制約充足問題と呼ばれる複雑な処理が必要で、yumはこれを実装しています。どのような処理が必要か、例で見てみましょう。 例A 説明のために非常にシンプルな世界Aを想定します。 rsyslog-1.rpm, を rsyslog-2.rpm にアップデートしようとしたときに何が必要かを見てみましょう。 rsyslogには複数のバージョン rsyslog-1 と rsyslog-2 があります rsyslog-1, rsyslog-2 はそれぞれ libc に依存しています 現在システムにインストールされているパッケージはrsyslog-1, libcの2つだけです この場合は簡単で、rsyslog-2.rpmだけを入手すると依存関係が満たされます。 次にシンプルな世界A-2を想像します。基本的に世界Aと同じですが、以下が異なります。 libcにもバージョンがあり、 libc-1.rpm と libc-2.rpm があります 現在インストールされているパッケージはrsyslog-1, libc-1の2つだけです rpmは、パッケージ対パッケージだけでなく、抽象化した仮のパッケージを扱うことができます。libc-1, libc-2ともに、libc という抽象化された名前を提供して、rsyslog-1, rsyslog-2ともに抽象化された"libc" への依存を宣言します。 シンプルな例 A やはり rsyslogのアップデートには rsyslog-2パッケージだけをダウンロードすれば十分です。 例B シンプルな世界Bを想定します。世界A-2とほぼ同じですが、今度はサードパーティのパッケージ foo を導入します。 fooは非常に厳密に、検証された組み合わせでのパッケージを依存関係で定義します。 foo-1 は rsyslog-1 と libc-1 に依存しています foo-2 は rsyslog-2 と libc-2 に依存しています システムには foo-1, rsyslog-1, libc-1 がインストールされています シンプルな例 B この場合、rsyslog-2だけをインストールしようとすると foo-1 の依存関係が満たせなくなります。 foo-2 にアップデートが必要となり、libc-2 のアップデートも必要になります。 つまりrsyslogをアップデートするための最低限必要なパッケージは rsyslog-2, foo-2, libc-2 の3つになります。 まとめ ややこしい所はyumがやってくれるので、yumを使いましょう :D
こんにちは。Red Hatでソリューションアーキテクトをしている杉本です。今回のブログ記事では、Red Hatが提供しているManaged Kafkaをトライアルで実際に試してみる方法について書いていきます。 Red Hat OpenShift Streams for Apache Kafkaとは Red Hat OpenShift Streams for Apache Kafka(RHOSAKと略され、「ロサック」と発音されることが多いようです)はRed Hatが提供するManaged Kafkaのサービスです。Kafkaの環境を自分で構築・運用することなく、ストリーム処理のアプリケーションの開発やリリースを簡単に行うことができるようになります。概要については、以前の 赤帽ブログのApplication Services Newsletter 7月号 や Speakersdeck内のスライド でも紹介していますので、そちらも併せて読んで頂ければと思います。 今回のブログでは、RHOSAKを使うことでKafkaを利用できるところまでを実際に試す方法について説明していきます。なお、2021年7月現在、Red Hat OpenShift Streams for Apache Kafkaはベータ版としてのリリースとなっており、トライアルで作成したKafkaインスタンスは48時間で削除されます。 Red Hat Application Servicesのページ まず、 cloud.redhat.com にアクセスしてRed Hat アカウントでログインします。もしまだRed Hat アカウントをお持ちでなければアカウント作成のリンクからアカウントを作ってください。ログインできたらcloud.redhat.comのランディングページで、左のメニューからApplication Servicesを選択します。 図1: cloud.redhat.comのランディングページ Application Servicesのランディングページが表示されたら、左のメニューでStreams for Apache Kafka → Kafka Instancesを選択します。ベータ環境であることを確認するメッセージが表示されたら、[Use feature in beta] をクリックします。 図2- Application Servicesのランディングページ Kafkaインスタンスの作成 Kafka Instancesのページで[Create Kafka Instance]をクリックしてKafkaインスタンスを作成していきます。Instacne名のフィールドに名前を入力し(ここでは "my-kafka-instance")、[Create Instance]をクリックするとOpenShift上にKafkaクラスタの構築が開始されます。なお、ベータの時点で利用可能なクラウドはAWSのみでリージョンもUSのみですが、GA後は拡充される予定です。 図3: Kafkaインスタンスの作成画面 数分でKafkaクラスターのインスタンスの作成が完了し、以下のような画面が表示されます。 図4- Kafka Instancesのページ 作成されたKafkaインスタンスはOpenShift上にデプロイされており、KafkaのクライアントアプリケーションからKafkaインスタンスにアクセスするにはサービスアカウントが必要です。Kafka Instancesページに表示されている先ほど作成したmy-kafka-instanceのオプションのアイコン(3つのドット)をクリックし、View connection informationを選択します。 図5: Kafkaインスタンスのオプション Kafkaインスタンスの接続情報が以下のように表示されます。 図6: Kafkaインスタンスの接続情報画面 Kafkaインスタンスの接続情報画面に表示される接続情報からBootstrap serverのエンドポイントをどこか安全な場所にコピーします。 次に[Create service account]ボタンをクリックし、サービスアカウント名を入力して[Create]をクリックします(ここでは "my-service-account")。 図7: サービスアカウントの作成画面 以下のようにClient IDとClient Secretが生成されるので、その値をどこか安全な場所にコピーし、チェックボックスにチェックを入れてクレデンシャルのウィンドウを閉じます。 図8: サービスアカウントの作成後のクレデンシャル表示画面 Kafkaトピックの作成 Kafkaのインスタンスとそれにアクセスするためのサービスアカウントができたら、次にトピックを作成してみましょう。Kafka Instancesのページで、先ほど作成したKafkaインスタンスの名前をクリックします。Topicsタブで、[Create topic]をクリックし、ガイドに従ってトピックに関する情報を設定していきます。 トピック名(ここでは "my-first-kafka-topic") パーティション数(デフォルトは1) メッセージのリテンションポリシー(ここではリテンション期間は1週間、リテンションサイズはUnlimitedを指定) レプリカ数(現在のRHOSAKでは事前に設定された値を変更することはできません) 図9: Kafkaトピック一覧画面 Kafkaトピックにメッセージを送信 (produce) 以上でKafkaを使う用意が整いましたので、トピックにメッセージを送信したり、トピックからメッセージを取り出すことができるようになります。ここでは、Kafkaとのメッセージの送受信をコマンドラインで行うことのできるkafkacatを使用してみます。kafkacatは https://github.com/edenhill/kafkacat からダウンロードできますので、手順に従ってインストールしてみてください。Macの場合には以下のようにbrewを使ってもインストール可能です。 $ brew install kafkacat kafkacatがKafkaインスタンスにアクセスできるようにするためには、先ほど保存したKafkaインスタンスのBootstrap serverのエンドポイントとサービスアカウントのクレデンシャルが必要となります。以下のコマンドで環境変数として設定しておきましょう。それぞれの値は実際の値に置き換えてください。 $ export BOOTSTRAP_SERVER=<bootstrap_server> $ export USER=<client_id> $ export PASSWORD=<client_secret> ターミナルで以下のコマンドを実行することでkafkacatをProducerモードで開始することができます。以下のコマンド例で接続するKafkaトピックは、先に作成したmy-first-kafka-topicを使用していますので必要に応じて書き換えてください。またこの例では、先ほど設定したBootstrap serverとサービスアカウントのクレデンシャルを使用してSASL/PLAINの認証を行っています。 $ kafkacat -t my-first-kafka-topic -b "$BOOTSTRAP_SERVER" \ -X security.protocol=SASL_SSL -X sasl.mechanisms=PLAIN \ -X sasl.username="$USER" \ -X sasl.password="$PASSWORD" -P kafkacatをProducerモードで起動すると、ターミナルの標準入力 (stdin) から直接Kafkaトピックにメッセージを送信することができます。以下のように標準入力で入力してメッセージを送信してみましょう。一行ごとにトピックにメッセージが送信されます。 First message Second message Third message このメッセージのproducerは後ほどまた使用しますのでターミナルはこのままにしておきましょう。 Kafkaトピックからメッセージを受信 (consume) 次にKafkaトピックからメッセージを取得するために、ターミナルをもう一つ立ち上げて、Producerの時と同様に環境変数をしたら、以下のコマンドを実行してkafkacatをConsumerモードで開始しましょう。Consumerモードで起動してトピックに接続したら(ここでは"my-first-kafka-topic")、先ほどProducerとして送信したメッセージを受信して、標準出力にメッセージが出力されます。 $ kafkacat -t my-first-kafka-topic -b "$BOOTSTRAP_SERVER" \ -X security.protocol=SASL_SSL -X sasl.mechanisms=PLAIN \ -X sasl.username="$USER" \ -X sasl.password="$PASSWORD" -C First message Second message Third message % Reached end of topic my-first-kafka-topic [0] at offset 3 Producerモードのkafkacatのターミナルからメッセージを送信すると、Consumerモードのkafkacatのターミナルにメッセージが表示され、Kafkaのトピックでメッセージの送受信が行われているのを確認することができます。 まとめ このようにRHOSAKを使用すると、Kafkaのクラスタ環境を簡単に構築し、利用することができるようになります。 cloud.redhat.com にアクセスすればトライアルはすぐにできますので、ぜひRed HatによるManaged Kafka, RHOSAKを試してみていただければと思います。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 OpenJDK 8 and 11: Still in safe hands | Red Hat Developer の翻訳記事です。 2018年、オラクルは商用ユーザー向けにJava SE 8の無料公開アップデートと自動更新を2019年1月末までしか提供しないと発表しました。Java 8は非常に重要なプラットフォームで、何百万人ものプログラマーが利用しています。そのため、これは大きな問題でした。Javaコミュニティは、このギャップを埋める必要がありました。 2019年の2月、私はOpenJDK 8 アップデートリリースプロジェクトの新しいリーダに任命されました。その数週間後、私はOpenJDK 11 アップデートプロジェクトの新しいリーダに任命されました。これはOpenJDKとJava SEの歴史において重要な節目となります。なぜなら、Oracle社以外の社員が現在の長期的なOpenJDKリリースプロジェクトを率いるのは初めてのことです。JDK 8は現在も業界で多く使用されているJavaリリースであり、JDK 11は現在の長期メンテナンス・リリースです。 私の目の前でJDK8uとJDK11uの最初のリリースが行われてから2週間が経ちました。このプロセスは非常にうまくいったと思います。しかし、開発者にとっては全くの順風満帆ではありませんでした。とは言っても、予定通りの日にリリースを行い、今のところ大きな問題はありません。 Oracle社が商用ユーザーにJDKの長期アップデート用バイナリを無料で提供しなくなるという話がかなり出ていました。中にはパニックになりそうなものもありました。当時、私はその心配は見当違いだと思っていました。今回のリリースで、それが証明されたと思います。 Red Hatの役割 もちろん、私一人でやっているわけではありません。Red HatにはOpenJDK開発者の大規模なチームがありますし、Red Hat以外の多くの人たちもリリースに取り組んでいます。また、非常に機密性の高いセキュリティ作業を行っている人もいますが、これは準備が整うまで見ることができません。 この中でのRed Hatの役割を明確にすることは重要です。Red Hatは、OpenJDKの最大の貢献者の1つであり、何年も前からそうでしたし、これからもそうであり続けるでしょう。しかし、私たちはOpenJDKのアップデートプロジェクトを「引き継いだ」わけではありませんし、そうしたいとも思っていません。OpenJDKにおける私たちの役割は、他の多くのプロジェクトと同様、顧客、貢献者、パートナーのコミュニティの触媒となることです。これは、プロジェクトの利益のために、他社(中には競合他社もある)と協力することを意味します。Red HatがOpenJDKのアップデートに加える変更は、多くのソースからのパッチに基づいています。もちろん、その多くは私たち自身で作成したものですが、OpenJDKのすべての貢献者からもパッチを受け取っています。 プロジェクトリーダとしての私の役割は、これらの貴重な宝石であるOpenJDKのアップデートを守るための最善の方法を監督し、奨励し、時には決定を下すことです。私はどのベンダにも有利にならないようにそうしなければなりません。私は公平でなければならないだけでなく、誰からもそう見られていなければなりません。このように行動することは、Red Hatにとって最善の利益となります。皆にとってより良いOpenJDKは、より多くのユーザとより多くの貢献者を促します。最終的には、Red Hatにとっての最良の結果は、誰にとっても最良の結果なのです。
みなさんこんにちは、レッドハットでソリューションアーキテクトをしている暮林といいます。 CodeReady Workspacesの便利なカスタマイズ方法の第三回目のご紹介です。 第一回目と第二回目はこちら。 rheb.hatenablog.com rheb.hatenablog.com 今回のテーマはカスタムプラグインレジストリの作成です。 CodeReadyWorkspacesのレジストリについて理解する devfileレジストリー プラグインレジストリー 前提 node.jsとnpmのセットアップ STEP2 プラグインレジストリのビルド準備 STEP3 デフォルトのままビルド STEP4 カスタマイズ STEP5 CodeReadyWorkspacesへの反映 STEP6 動作確認 まとめ 前回のおさらいになりますが、CodeReadyWorkspacesの2つのレジストリについて説明いたします。今回は後者のプラグインレジストリが対象です。 プラグインとしてはVSCODE用の日本語プラグインとルール開発用のプラグインを導入してみます。このエントリーで紹介しているプラグインです。 rheb.hatenablog.com 先に言ってしまうと日本語プラグインは導入はできても動作はしません。理由は後ほど解説いたします。 CodeReadyWorkspacesのレジストリについて理解する CodeReadyWorkspacesには2つのレジストリがありそれぞれ役割が異なります。 devfileレジストリー ワークスペースのテンプレートを保管しておくレジストリーです。 第一回では自分用のdevfileを修正してコンテナを追加しましたが、修正済みのdevfileをレジストリーに登録しておくことでほかのユーザーも同じスタック(設定のようなもの)でワークスペースを起動できるようになります。下記の画像はデフォルトのスタック一覧ですが、devfileレジストリーを変更することでここの一覧を変更できます。 デフォルトのスタック一覧 プラグインレジストリー デスクトップ版のVSCodeは自由にエクステンションをダウンロードして追加することができますが、CodeReadyWorkspacesでは利用したいプラグインをプラグインレジストリーに保管しておいて、これをdevfile経由で指定することで利用することができるようになります。2.8ではUIが変更されて、下記のようにワークスペース内のUIからプラグインを指定できるようになりました。プラグインレジストリーを変更することで、下記の画像の左側にあるプラグイン一覧に表示されるプラグインを変更することができます。 プラグイン一覧 前提 プラグインレジストリの構築は少々厄介で、第二回の条件に加えてnode.jsのパッケージ管理システムであるnpmが必要になります。またビルド自体に少々メモリを多めにつかうため、AWSでいうところのmicroレベルのインスタンスではビルドがKillされてしまいます。smallの環境であれば問題なさそうです。 openshiftプロジェクトへの変更権限 CodeReadyWorkspacesのインスタンスへの変更権限 OpenShift ImageRegistry Operatorの変更権限 podman(またはdockerかbuildah)が実行可能なラップトップ(またはサーバーなど) node.jsとnpm 1GByte以上のメモリを搭載したマシン 公式なマニュアルは下記のURLから参照できますが、 ワークアラウンド が必要になります。 node.jsとnpmのセットアップ 普通にインストールしてください。嘘です、すみません。 筆者はRHEL8を用いてビルドをしていますが、何も考えずにnodejsを入れると10系がインストールされます。 $ node --version v10.24.0 なぜかというとこういう事情があります。 rheb.hatenablog.com つまり正解はこうです。 # yum install @nodejs:12 npm ... $ node --version v12.21.0 実際はnode.jsの10系でもビルドはできましたが、サポートにトラブルの問い合わせをしたくなった場合に指摘されてしまう点なので、条件は揃えておくのが吉です。 あとyarnも必要になるので、npmを通してインストールしていまいましょう。グローバルインストールをしないと、ビルド時にややこしいことになるので、よほどの事情がなければこのコマンドの通りがおすすめです。 $ npm install -g yarn $ yarn --version 1.22.10 STEP2 プラグインレジストリのビルド準備 この辺りは公式手順のままですが、cloneのプロトコルgit(ssh)のままだと困る方が多いと思うので、httpに変えた手順をのせておきます。 前回はCodeReadyが2.8だったため、2.8に対応したブランチに切り替えていましたが、今回は新しい2.9にあわせます。 $ git clone https://github.com/redhat-developer/codeready-workspaces.git $ cd codeready-workspaces $ git checkout crw-2.9-rhel-8 STEP3 デフォルトのままビルド プラグインレジストリはビルドがやや不安定で、ビルドが通らない原因が追加した設定なのか環境依存なのかの切り分けに苦労します。なので一旦はデフォルトのままでビルドを通すことを推奨します。 公式の手順では下記のとおりですが、このままではビルドは成功しません。原因は2種類ありそうです。 $ cd dependencies/che-plugin-registry $ ./build.sh --organization <my-org> \ --registry <my-registry> \ --tag <my-tag> 1つ目はテストが不安定なことです。リポジトリにはビルドツールのテストが同梱されていますが、これが不安定でなかなか実際のビルドにたどり着かないことが多かったです。 2つ目は少々込み入っています。プラグインの中には皆さんの想像するVSCODEのプラグイン以外に、サイドカーコンテナを用いるタイプのプラグインがあります。デフォルトではビルド時にコンテナイメージのダイジェストを参照し行くようなのですが、サイドカーのコンテナイメージが registry.redhat.io にあると認証ができなくてビルドが失敗します。 なので下記のコマンドでこの2つの原因を回避します。 $ export SKIP_TEST=true $ cd dependencies/che-plugin-registry $ ./build.sh --organization <my-org> \ --registry <my-registry> \ --tag <my-tag> \ --skip-digest-generation 第二回と同じ環境をつかっているとすると、このようなコマンドになります。 $ export SKIP_TEST=true $ ./build.sh --organization openshift-workspaces \ --registry $HOST \ --tag 1.0 \ --skip-digest-generation ビルドが通らない場合はエラーメッセージとのにらめっこになります。(なかなか難しいです) STEP4 カスタマイズ ビルドが成功したらカスタマイズを行いましょう。今回行うカスタマイズは che-theia-plugins.yaml というファイルを更新することで行います。 che-theia-plugin.yamlの一番上の方の plugins: の下に、このように追記してください。 version: 1.0.0 plugins: - id: redhat/vscode-extension-dmn-editor repository: url: 'https://github.com/kiegroup/kie-tooling-store.git' revision: 0.11.0 extension: https://open-vsx.org/api/redhat/vscode-extension-dmn-editor/0.11.0/file/redhat.vscode-extension-dmn-editor-0.11.0.vsix - id: redhat/vscode-extension-bpmn-editor repository: url: 'https://github.com/kiegroup/kie-tooling-store' revision: 0.11.0 extension: https://open-vsx.org/api/redhat/vscode-extension-bpmn-editor/0.11.0/file/redhat.vscode-extension-bpmn-editor-0.11.0.vsix - id: redhat/vscode-extension-red-hat-business-automation-bundle repository: url: 'https://github.com/kiegroup/kie-tooling-store' revision: 0.11.0 extension: https://open-vsx.org/api/redhat/vscode-extension-red-hat-business-automation-bundle/0.11.0/file/redhat.vscode-extension-red-hat-business-automation-bundle-0.11.0.vsix - id: open-vsx/vscode-language-pack-ja repository: url: 'https://github.com/Microsoft/vscode-loc' revision: 1.59.0 extension: https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ja/1.59.0/file/MS-CEINTL.vscode-language-pack-ja-1.59.0.vsix 各項目の意味はここで解説されています。 access.redhat.com が、extensionsを使うと必須項目がないとして怒られてしまいます・・・。 今回は、vscode-extension-red-hat-business-automation-bundleはdmn-editorとbpmn-editorに依存関係をもつので、IDをきちんと指定しておかないとビルドが失敗します。 この例ではVSCode Pluginの本体をOpen VSX RegistryというEclipse Foundationがホストしているレジストリーから取得することにします。オープンであることに加えて、vsixファイルのURLがわかりやすいというおまけがあります。 open-vsx.org 変更が完了したら、STEP3と同じコマンドでビルドしてください。 $ export SKIP_TEST=true $ ./build.sh --organization openshift-workspaces \ --registry $HOST \ --tag 1.0 \ --skip-digest-generation ... STEP 39: COMMIT default-route-openshift-image-registry.apps..xxxxxxxxxxx/openshift-workspaces/pluginregistry-rhel8:1.0 --> bded7730d30 ビルドが成功したらPushしてください。pushするイメージ名はビルドの最後のSTEP39で出力されています。(podman imagesで探してもよいです) oc login ~~~~ podman login -u $(oc whoami) -p $(oc whoami -t) --tls-verify=false $HOST podman push default-route-openshift-image-registry.apps.xxxxxxxxxxx/openshift-workspaces/pluginregistry-rhel8:1.0 STEP5 CodeReadyWorkspacesへの反映 いよいよCodeReadyWorkspacesへの反映です。 devfile registryのカスタマイズの際はデフォルトのレジストリとは別立てして、参照先のURLを変えるということをしましたが、今回はもっと簡単にデフォルトのレジストリの参照イメージを変更する手段を使います。(実は前回もこの手法が使えました) 前回の「STEP5 CodeReadyWorkspacesのインスタンスの設定変更」を参考に設定までたどり着いてください。 今回は、serverセクションに追記を行います。 server: pluginRegistryImage: image-registry.openshift-image-registry.svc:5000/openshift-workspaces/pluginregistry-rhel8:1.0 セーブして完了です。別立てするより簡単ですね! STEP6 動作確認 では動作確認をしていきましょう。 まずはプラグインをワークスペースに組み込みます。 適当なワークスペースを開いて、上部のメニューから view→Pluginと開いてください。 左に開いたプラグインリストをスクロールしていくと追加したプラグインが見えてきます。(ここでは見えていませんがもっと上に日本語パックもあります) 雷のマークのアイコンが今回追加したルール開発周りのプラグインです。3つともチェックを入れてください。チェックを入れるとリスタートを促すメッセージが入った帯がでてくるので、クリックしてワークスペースをリスタートしましょう。 実はリスタートと言いつつシャットダウンしかしてくれないので、ワークスペースを選んで起動してください。 (Application is not availableという画面が出たときはブラウザ側をリロードしてください) 起動が完了したら、エクスプローラのペインからディレクトリ適当に選んで test.bpmn というファイルを作成してみてください。 bpmnのエディターが起動すれば成功です! すっかり忘れ気味でしたが、日本語プラグインをいれたのに日本語されていないな?と思いませんでしたか? 実はCodeReadyWorkspacesは表示言語の国際化への対応が未完了です。IDE部分のUpstreamにあたるeclipse-theiaの対応は下記のIssueとして現在進行形で進んでいます。 ということでUIの日本語化は乞うご期待といったところです。 github.com まとめ プラグインの追加の手順はここまででしたがいかがだったでしょうか。準備段階はVSCodeの簡単さに比べてしまうと雲泥の差ではありますが、利用者の立場ではほとんどおなじになる事がわかっていただけたかと思います。 今回ルール開発用のプラグインを取り上げたのは、KogitoというKubernetesのマイクロサービス向けのルールエンジンがついにGAしたことのアピールも兼ねていますが、実はQuarkusからKogitoを使うためにはこのエディタがあると便利という点が最大の動機です。 QuarkusからKogitoをどう使うかは下記のGuideに日本語情報があります。私自身はまだためせていませんが、CodeReadyWorkspacesのQuarkusのDevfileに今回紹介したプラグインを追加することで、このガイド通りにできるのではと考えています。(ただし、このGuideはCommunityの情報ということをお忘れなく) ja.quarkus.io 次回以降は、CodeReadyWorkspaces単体の話から、こういったツールを用いてどうやってDeveloper Experienceを上げていくのがよいか、という話にシフトしていこうと思います。
こんにちは、Red Hatでソリューションアーキテクトをしている石川です。 OpenShiftではクラウドネイティブなCI/CDを実現する手段として、OpenShift Pipelines という機能を提供しています。 以前はTech Previewだったのですが、 今年の5月にGAとなった ため、今回から2回に分けてOpenShift Pipelinesを使ってCI/CDパイプラインを構築する方法についてご紹介していきたいと思います。 OpenShift Pipelinesの概要 OpenShift Pipelinesは Tekton というOSSがベースになっています。 TektonはLinux Foundationが母体となるContinuous Delivery Foundation(CDF)にて開発が進められているプロジェクトです。元々はKubernetes上でサーバーレスを提供するKnativeの一部として開発されていましたが、現在は独立したプロジェクトとなっており、Kuberenetes上でCI/CDを提供するための様々な機能を提供しています。 Tektonは複数のコンポーネントで構成されており、CI/CDを実施する際に主に利用されるTekton PipelinesやTekton Triggersといったメインのコンポーネントに加え、CLIを提供するTekton CLI、後述するTaskのカタログを提供するTekton Catalogなどがあります。 Tekton Pipelines、Tekton TriggersはそれぞれKubernetesのCRD、Custom Controllerとして実装されています。OpenShiftではOpenShift Pipelines Operatorをインストールすることで簡単にTektonを使い始めることが可能となります。 ユースケース 今回の記事ではTekton Pipelinesについて説明をしていきますが、その前にCI/CDパイプラインのユースケースについて考えてみましょう。 例えば、以下のように開発者が自身の作業用ブランチからメインブランチに対しプルリクエストを行い、それが承認されたタイミング(merge commitが作成されたタイミング)で、アプリケーションの静的診断、コンテナイメージの作成、レジストリへのプッシュなどを自動的に実施するパターンを考えてみます。 本記事ではこのパイプライン作成部分をTekton Pipelinesにて実施したいと思います。 Tekton Pipelinesで登場する概念 Tekton PipelinesではCI/CDで実行したいアクションをTask、Taskの組み合わせや実行順序などをPipelineという形で表現します。 ユースケースの図の例だと、"Git Clone"や"SAST"などが一つ一つのTaskとなり、PipelineではそれらのTaskを参照し、実行順序を定義します。これらのTaskやPipelineはKubernetesのカスタムリソースとして作成します。 Pipelineは、PipelineRunという別のカスタムリソースを作成することにより実行されます。 PipelineRunが作成されると、内部的にはPipelineに含まれる一つ一つのTaskに対しTaskRunというカスタムリソースが作成され、それにより個々のTaskが実行されます。PipelineRunを使う場合は指定した順序でTaskRunが自動で作成されますが、Pipelineの構築時など、ある特定のTaskの動作を確認したい場合などでは、TaskRunを手動で作成し、一つのTaskだけを実行することも可能です。TaskRunが作成されるとTask実行のためのPodが作成され、Taskの中で指定されたコンテナイメージを使って処理を実施していきます。 Pipelineを実行するにはこれらのカスタムリソースを作成する必要があるわけですが、Gitリポジトリからのソースコードのクローンや、コンテナイメージのビルド、など一般的によく使われるようなTaskについては、 Tekton Catalog というTaskがまとめられたカタログ集や、 Tekton Hub というページで公開されているTaskを使用することが出来ます。 OpenShift Pipelinesではインストールの際にTekton Catalogの一部がClusterTask(クラスタ全体で共通利用可能なTask)として登録されるためそれらをすぐに利用することが出来ます。 Pipelineの作成と実行 本記事ではOpenShiftに登録済みのCluster Taskと、Tekton Catalogで公開されているTaskを使いPipelineを作成していきたいと思います。 Tekton CatalogからTaskをインストールするには利用したいyamlをダウンロードし、CICDを実行するNameSpace上で実行します。今回はアプリケーションの静的診断を行うため、SonarQubeのTaskをインストールします。それ以外はデフォルトのClusterTaskを使用します。 # SonarQube実行のためのyamlの取得 curl https://raw.githubusercontent.com/tektoncd/catalog/main/task/sonarqube-scanner/0.1/sonarqube-scanner.yaml -o sonarqube-scanner.yaml # Taskインストール oc apply -f sonarqube-scanner.yaml # 確認 oc get task --- NAME AGE sonarqube-scanner 4s 続いてPipelineのためのマニフェストファイルを作成していきます。 Pipelineに含むTaskはspec.tasks以下にリスト形式で記述します。 apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: test-pipeline spec:  # Task間のデータの受け渡しはworkspaceにて実施 workspaces: - name: shared-workspace - name: sonar-settings  # 各Taskで利用されるパラメータを定義 params: - name: url type: string - name: SONAR_HOST_URL type: string - name: SONAR_PROJECT_KEY type: string - name: IMAGE type: string tasks: - name: git-clone  # Pipelineで実行するTaskの参照先 taskRef: kind: ClusterTask name: git-clone params: - name: url value: $(params.url) - name: subdirectory value: "" - name: deleteExisting value: "true" workspaces: - name: output workspace: shared-workspace - name: sonarqube-scanner taskRef: name: sonarqube-scanner  # あるTaskが実行された後に本Taskが実行されるよう順番を制御 runAfter: - git-clone params: - name: SONAR_HOST_URL value: $(params.SONAR_HOST_URL) - name: SONAR_PROJECT_KEY value: $(params.SONAR_PROJECT_KEY) workspaces: - name: source-dir workspace: shared-workspace - name: sonar-settings workspace: sonar-settings - name: buildah taskRef: kind: ClusterTask name: buildah runAfter: - sonarqube-scanner params: - name: IMAGE value: $(params.IMAGE) workspaces: - name: source workspace: shared-workspace このマニフェストを oc apply -f test-pipeline.yaml で適用するとPipelineが作成されます。 OpenShiftのコンソールでは以下のような形で作成したPipelineを確認することが出来ます。 Pipelineを作成することが出来たので、このPipelineを実行してみたいと思います。Pipeline実行に必要なPipelineRunを以下の通り作成します。PipelineRunでは、Pipelineに渡すパラメータの値や、Task間のデータの受け渡しで使用されるWorkspaceのPVC情報などを記載します。 apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: generateName: test-run- spec: pipelineRef: name: test-pipeline params: - name: url value: 'https://[git cloneしたいリポジトリのURL]' - name: SONAR_HOST_URL value: 'http://sonarqube:9000' - name: SONAR_PROJECT_KEY value: 'test-project' - name: IMAGE value: '[作成するコンテナイメージ名:タグ名]' workspaces: - name: shared-workspace volumeClaimTemplate: spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi - name: sonar-settings emptyDir: {} PipelineRunを作成し適用するとPipelineが実行されます。 コンソールからはPipelineの実行状況や、Taskごとのログ情報をリアルタイムに確認することが出来ます。 無事Pipelineが実行され、各Taskが成功していることを確認することが出来ました。 まとめ 本記事ではOpenShift Pipelinesの概要と、Tekton Pipelinesの仕組み、実行方法についてご紹介させて頂きました。 もしOpenShift Pipelinesを自分で触ってみたいという方は、 こちらのサイト から簡単にハンズオンを実施することが可能ですので是非やってみて下さい。 さて、実際に開発におけるCI/CDのパイプラインとしてこれらを利用するには、Gitのイベント(pushやPRなど)を契機として、PipelineRunの作成を自動化していく必要があります。この部分を実施するTektonのもう一つのコンポーネント、Tekton Triggersについては次回の記事でご紹介していきたいと思います。
みなさんこんにちは。レッドハットの杉村です。Ansible のテクニカルサポートをしています。 本日は Red Hat Ansible Automates 2021 Japan Day 1 が開催されています。多数の方にご参加いただいているとお聞きしています。ありがとうございます。 www.redhat.com 今回は最近よくお問合せをいただく Collections の使い方について紹介します。 Collections とは Ansible では多くのモジュールがありましてリリースを重ねるごとにどんどん数も増えてきまして 3000を超えてしまい、一緒に配布することにさまざまな限界が出てきてしまいました。 2.8 〜 2.9 頃から本体と分けて Collections として切り出すことにより、開発ベンダーやコミュニティは独自に開発や配布を進めることができ、品質の向上や利用者の利便性を高めることができるようになりました。 Collections にはモジュールだけでなく、さまざまなものが含まれています。再利用な形で十分なテストがされているものであれば、取ってきて変数を設定するだけで簡単に自動化を実現できるというものも多数開発されています。 playbooks roles modules plugins Collections は Red Hat の SaaS サイトでも配布しています。 cloud.redhat.com こちらはコミュニティの配布サイトです。 galaxy.ansible.com インターネットへの接続がない閉じた環境でも同じように Collections を配布できるプロダクトも用意しています。以前この赤帽エンジニアブログでも紹介しましたので、ご興味あればご覧ください。 rheb.hatenablog.com requirements.yml を書いて使う Collections のインストールは ansible-galaxy コマンドから実行できます。一つだけであればコマンドラインに直接指定してもできるのですが、もし複数インストールしたいことがあれば、requirements.yml ファイルを書いてまとめることもできます。 --- collections: - community.vmware - vmware.vmware_rest ansible-galaxy collection install コマンドから実行します。依存する collection があれば、自動的に取得して同時にインストールします。 $ ansible-galaxy collection install -r requirements.yml より詳しくはこちらのドキュメントをご覧ください。 docs.ansible.com Ansible Tower から使う Ansible Tower では、SCM プロジェクトに collections/requirements.yml ファイルを含めておくことで、SCM (git など) からプロジェクトディレクトリを同期したときに ansible-galaxy collections install コマンドを呼び出してインストールすることができます。 docs.ansible.com SCM で管理していないときは、あらかじめ Tower にインストールしておくことで利用することができます。 こちらのドキュメントに沿って設定いただけます。 access.redhat.com この例と同じように、インストールディレクトリを /opt/collections/ として説明します。 ディレクトリを作成して、権限を設定します。 # rm -rf /opt/collections # mkdir /opt/collections # chown awx:awx /opt/collections Tower は awx ユーザでコマンドを実行しますので、awx ユーザで作業します。 # su - awx $ whoami awx ここでは community.vmware をインストールする例で紹介します。別途ダウンロードしたものを scp 等で持ち込んでも構いません。ダウンロードしたら、ansible-galaxy コマンドでインストールします。 オンラインで ansible-galaxy collection install community.vmware -p /opt/collections/ コマンドをお使いいただくこともできます。 $ curl -LO https://galaxy.ansible.com/download/community-vmware-1.12.0.tar.gz $ ansible-galaxy collection install community-vmware-1.12.0.tar.gz -p /opt/collections/ [WARNING]: The specified collections path '/opt/collections' is not part of the configured Ansible collections paths '/var/lib/awx/.ansible/collections:/usr/share/ansible/collections'. The installed collection won't be picked up in an Ansible run. Process install dependency map Starting collection install process Installing 'community.vmware:1.12.0' to '/opt/collections/ansible_collections/community/vmware' ここに warning が表示されているように、collections の path を指定する必要があります。ansible.cfg で指定しないときには、Tower の Web UI から「設定」→「ジョブ」→「追加の環境変数」にこのように設定します。 { "ANSIBLE_COLLECTIONS_PATHS": "/opt/collections/" } /etc/ansible/ansible.cfg で設定していただくこともできますが、ここでは上記の方法を取ることにします。 [defaults] collections_paths = /opt/collections/ プロジェクトを作り、collection を使うプレイブックを記述します。 $ mkdir /var/lib/awx/projects/test_vmware $ cat /var/lib/awx/projects/test_vmware/playbook.yml --- - hosts: localhost gather_facts: false vars: vcenter_hostname: '192.168.0.XXX' vcenter_username: 'administrator@vsphere.local' vcenter_password: 'XXXXXXXX' tasks: - name: Provide information about vCenter community.vmware.vmware_about_info: hostname: '{{ vcenter_hostname }}' username: '{{ vcenter_username }}' password: '{{ vcenter_password }}' validate_certs: false register: vcenter_about_info - name: debug debug: var: vcenter_about_info もし /opt/collections/ 以外のディレクトリをご利用の場合には、ディレクトリによっては Web UI での追加の設定が必要になることがあります。「設定」→「ジョブ」を開いていただき、「ジョブの分離の有効化」が有効のときには、「分離されたジョブに公開するパス」にディレクトリを設定してください。「ジョブの分離の有効化」が無効であれば、awx ユーザで読み取り可能なディレクトリであれば動作します。 ここまで設定いただけましたら、Tower でプロジェクトとジョブテンプレートを作成して実行してください。 また、コマンドラインからでも動作させたい場合には、awx ユーザで次のように実行していただけます。 $ source /var/lib/awx/venv/ansible/bin/activate (ansible) $ ANSIBLE_COLLECTIONS_PATHS=/opt/collections/ ansible-playbook /var/lib/awx/projects/test_vmware/playbook.yml -e "ansible_python_interpreter=/var/lib/awx/venv/ansible/bin/python" おわりに Ansible 2.9 同梱のモジュールが古くなってしまい、いまどきの自動化に対応しない局面も増えてきました。対象の機器のベンダーやコミュニティから Collections として対応するものが出ていることも多いですので、今回の記事で検討していただけるとうれしく思います。 Ansible Towerの評価ライセンスリクエストはこちらからご利用いただけますのでご検討ください。 www.redhat.com Happy Automation!
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 How Red Hat ported OpenJDK to 64-bit Arm: A community history | Red Hat Developer の翻訳記事です。 今年はArm社にとって大変な1年でした。Arm社はコンピュータ・プロセッサのRISC(Reduced Instruction Set Computing)アーキテクチャを設計している会社です。Armベースのコンピュータが当分の間重要になるというニュースは、 主流メディア にまで届きました。2019年末には、Amazon Web ServicesがArmベースのGraviton2サーバーを発表しました。2020年6月には、AppleがMacintoshコンピュータをApple siliconに移行させる計画を発表しました。これはつまりArmです。 長年、Armサーバに携わってきた者にとって、この変化は長い間待ち望んでいたものです。 はじめに 2011年のある日のことです。私は、Red HatのリードArmアーキテクトであるJon Masters氏と共にThe Wrestlers(英国ケンブリッジの技術者コミュニティのお気に入りのタイ料理店)で昼食をとっていました。彼はエキサイティングなニュースを話していました。Armが64ビットアーキテクチャを開発し、Red HatがRed Hat Enterprise Linux(RHEL)をそれに移植するというのです。これを実現するためには、いくつかの問題を解決する必要がありますが、その中でも特に難しい問題がありました。新しい64ビットアーキテクチャ用のソフトウェアには、Javaが含まれていませんでした。Javaは多くの企業向けソフトウェアの重要なコンポーネントですから、このニュースはかなり大きなものでした。 誰かが移植版を書かなければならなりません。2人の専門家が約1年でOpenJDKの素朴な移植版を書けると聞いていましたが、私はそれしか知りませんでした。私のチームがやろうとすると、現場で学ばなければなりません。 私は、このような大きな仕事に携われることに興奮していました。しかし、成功の保証もないのに、このような大きなプロジェクトを始めることをRed Hatはどうやって正当化するのでしょうか?私は、自分たちがやらなければ、誰かにお金を払わなければならないと主張しました。それには莫大な費用がかかる。ならば、自分たちでやったほうがお金の節約になるのではないか。宣伝にもなるし、仲間もつくれる。しかし、社内でやることには、もうひとつ深い理由がありました。私たちは、OpenJDKのサポートチームを立ち上げていました。移植版をすべて作成することで、他では得られない経験を積むことができます。Red Hatの経営陣も同意してくれたので(それ以来、一貫してプロジェクトをサポートしてくれています)、私たちは実行に移すことができました。 私はこのプロジェクトのエンジニアの一人になることを決意しましたが、一人ではできませんでした。幸いなことに、Andrew DinnがJavaチームに加わることになりました。彼は長い間Javaに携わってきており、Lispマシンや論理言語のコンパイラを書いた経験もある。彼とならうまくやっていけるでしょう。 ただ、ひとつ心配なことがありました。他の人が先に移植してしまったらどうしよう。もし、他の人が先に移植してしまったら、せっかくの努力が無駄になってしまうかもしれません。そんなことにならないためには、先手必勝で人前で仕事をするしかありません。早くやって、うまくやって、無料にする。そうすれば、みんなが来てくれます。 プロジェクトを開始 ただ、問題が1つ、いや2つありました。まず、AArch64プロセッサが存在しなかったこと。また、Arm社を説得して、必要な情報を詳細に提供してもらうことも容易ではありませんでした。ドキュメントの問題は、Arm社のPhilippe Robin氏の協力と粘り強さで解決しましたが、ハードウェアの不足の方が問題でした。OpenJDKのすべてをシミュレーションで動かすことは可能ですが、当時のシミュレータは非常に遅かったのです。さらに悪いことに、OpenJDKはOSを呼び出さなければなりません。Javaを起動する前に、シミュレータ上ですべてのLinuxをブートストラップさせる必要があります。 Andrew Dinnは、あるカンファレンスの朝食時に、私がシャワーを浴びている間に何をすべきかを見つけたと興奮気味に話したことを覚えています。シンプルで機能的な命令セット・シミュレータを使用しますが、それは自分たちで生成したAArch64コードのためだけです。OpenJDKのJVMの残りの部分はC++です。C++はIntel x86ベースのPCでネイティブにフルスピードで実行できます。C++ から Java への呼び出しはすべてシミュレータに入り、Java から C++ への呼び出しはすべてシミュレータを出て x86 コードに戻ります。でも、AArch64のシミュレータ・ライブラリはどこで手に入るのでしょう?私は「書きましょう」と言った。「RISCなんだから。難しいことはないだろう」。 スタートしたのは2012年の6月。Andrew Dinnがシミュレータを書くのに少し時間がかかり、私はアセンブラと初期起動コードの作成に取り掛かりました。数ヵ月後には、Javaのバイトコードを実行できるようになりました。自分たちでシミュレータを書いてみようと思い立ったのです。複雑なブレークポイント条件を設定したり、命令のトレースを記録して、JVMがクラッシュしたときの命令の履歴を確認できました。その結果、最初の移植作業はすぐに終わりました。ログを見返してみると、2012年10月4日に「Enough for Hello, World! 」のエントリが見えます。この日は大事な日でした。コンソールに "Hello, World!"と出力するまでに、Javaは約25万バイトコードをクラッシュせずに実行し、仮想マシンの多くを動かさなければなりません。 そして3人になった 2013年の夏には、3人でプロジェクトを進めていました。Linaro社からは、元Arm社のJavaエキスパートであるEdward Nevillがプロジェクトに参加しました。彼は実際のハードウェアを手に入れた最初の人物です。私は、自分たちが作った小さなAArch64シミュレータにとても満足していたので、誰かが実機でデバッグしてくれるのはとても嬉しかったですね。苦労するだろうと思っていました。しかし、命令キャッシュのフラッシュに関する小さな問題と、浮動小数点フラグの問題を除けば、すべてうまくいったのです。これには驚きました。私たちは、Arm社のドキュメントをもとに、自分たちでシミュレータ、コンパイラ、アセンブラを書いたのです。独立した検証を受けたわけではありませんが、私たちはそれを正しく理解していました。 Edward は非常に大きな助けとなり、2014年の初めには動作する移植版が完成しました。 Red Hatはパートナー企業への早期リリースの出荷を開始し、私たちや他の企業はバグの修正やパフォーマンスの向上を続け、2015年3月2日にAArch64ポートはOpenJDKプロジェクトのメインの一部となりました。Oracle は素晴らしく、厄介な統合プロセスを助け、励ましてくれました。 統合と(超)ロングテール 動くJVMと本当に優れたJVMの間にはかなりの違いがあります。Intel/x86のOpenJDKにどれだけの時間が費やされたのかはわかりませんが、エンジニアとしては何十年もかかっているはずです。AArch64の移植版を競争力のあるものにするのは本当に大変なことでしたが、私たちには助けがありました。AArch64のシリコンメーカーやその他の企業からも参加してもらい、今では世界中の人たちが移植に取り組んでいます。 これこそが、Red Hatのオープンで協力的なアプローチが真価を発揮するところです。他者とパートナーシップを結ぶことで、純粋な自社ソフトウェア開発に比べて大きな相乗効果を得られます。 しかし、それだけではありません。Oracle社が64ビットのArm上でJavaを動かしているという話を聞いていたので、それが我々のポートなのかと思っていました。しかし、その移植版は、Oracle社がすでに持っている(32ビット)Armの移植版をベースにした独自のものでした。 Javaの本家が我々よりもはるかに良い成果を得ているのではないかと心配になりました。最終的には、Oracle社の移植版を使ったことのある人が親切にも「心配することはない」と言ってくれました。しかし、Oracle社が自分で移植版を書いたのは不思議でした。Oracle社は、最初から我々のコードをすべて使用する許可を得ていたのです。それなのに、なぜまた書くのでしょうか? 最終的にOracle社は、Armの32ビットと64ビットの両方の移植版を解放しました。その結果、OpenJDKには2つのAArch64移植版が残ることになりました。そして2020年11月12日、Oracleは今後のリソースを64ビットのArm移植版の1つに集中させることを決定したと発表しました。それはRed Hatで始めたAArch64移植版です。OracleのメンテナンスリリースであるJDK 8の64ビットArmサポートも、私たちの移植版をベースにしています。 最近、Appleは大騒ぎしながら、AArch64を実装したApple M1チップを発表しました。OpenJDKはそのプロセッサに対応しており、5年前から対応していました。しかし、OpenJDKには、OSとCPUの組み合わせごとに固有のレイヤーがあります。誰かがその作業をしなければなりませんでしたが、すぐに2人のボランティアが現れました。Microsoft社とAzul社の2社が協力してくれました。Microsoft社は、OS-CPUのレイヤーをWindows/AArch64にも移植しました。 まとめ では、なぜこのようなことが起こったのでしょうか?それは、OpenJDKの開発者コミュニティが決定したからです。それは、私たちの小さなチームが早期に実用的な移植版を提供し、それをOpenJDKのメインラインに導入し、参加したいと思うすべての人を歓迎したからだと思っています。可能な限り多くの議論をオープンにしました。人々はボランティアで参加し、私たちはコミュニティになりました。私たちは、このコミュニティとともに、自分たちだけでは考えられないほどの成果を上げることができました。しかし、2014年の初めに作業用の移植版をリリースしていなければ、これらのことは起こらなかったでしょう。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Creating and deploying a Java 8 runtime container image | Red Hat Developer の翻訳記事です。 Javaの実行環境はコンパイルされたソースコードを実行できるものでなければならないが、例えばOpenJDKのような開発キットには、ソースコードをコンパイルして実行するためのライブラリ/バイナリがすべて含まれている。基本的に、後者は実行環境の上位集合です。OpenJDKのサポートとライフサイクルに関する詳細は こちら をご覧ください。 Red Hat は、Java 8 と 11 の両方の OpenJDK を搭載したコンテナイメージを出荷し、サポートしています。詳細は こちら を参照してください。Red Hat Middleware を使用している場合、出荷された s2i イメージは、Red Hat Openshift Container Platform などにデプロイするのにも便利です。 Red HatはOpenJDKベースのJava 8と11のイメージしか提供していないことに注意してください。とはいえ、開発者が独自のJavaランタイムイメージを作成したい場合もあるでしょう。例えば、ランタイムイメージを実行するためにストレージを最小化するといった理由が考えられます。その一方で、JolokioやHawkularなどのライブラリや、セキュリティパラメータの設定など、多くの手作業が必要になります。そういった細かい作業をしたくない場合は、Red Hatが出荷しているOpenJDK用のコンテナイメージを使うことをお勧めします。 この記事では、以下のことを行います。 DockerとBuildahでイメージを構築します。 DockerとPodmanを使って、イメージをlocalhostで実行します。 イメージをQuayにプッシュします。 最後に、OpenShiftにストリームをインポートしてアプリを実行します。 この記事は、OpenShift 3.11と4.0のベータ版の両方で書かれています。早速ですが、ご紹介します。 設定方法 私たちのイメージを使用し、その動作を確認するために、バンドルの一部としてWebアプリを使用します。最近、Microprofile.ioは、 MicroProfile Starter beta を発表しました。これは、ダウンロード可能なパッケージを作成することで、MicroProfileの使用を開始するのに役立ちます。 Microprofile.io にアクセスして、MicroProfile with Thorntail V2のパッケージを入手してください。 ダウンロードボタンをクリックしてアーカイブファイルを取得します。 Red Hat Enterprise Linux(RHEL)のマシンでは、まず、 demoapp などの一時ディレクトリを作成し、ダウンロードした成果物をそこに解凍します。 tempディレクトリで、次のように実行します: $ mvn clean compile package これで、ビルドされたデモアプリができあがり、fat jarができました。このjarを呼び出して、Thorntailを実行できます。 target/demo-thorntail.jar`をtempディレクトリにコピーしましょう。 ここでは、各レイヤーにコメントをつけた Dockerfile を紹介します。このファイルのソースコードは、こちらの GitHub でもご覧いただけます。 # Java 8 ランタイムの例 # Red Hatの公式レジストリとベースイメージ FROM registry.access.redhat.com/rhel7-minimal USER root # Javaランタイムのインストール RUN microdnf --enablerepo=rhel-7-server-rpms \ install java-1.8.0-openjdk --nodocs ;\ microdnf clean all # Javaがどこにあるかを明確にするためにJAVA_HOME変数を設定する ENV JAVA_HOME /etc/alternatives/jre # 自分のアプリのためのディレクトリ RUN mkdir -p /app # リッスンするポートを公開する EXPOSE 8080 # MicroProfile starter appをコピーする COPY demo-thorntail.jar /app/ # スクリプトをソースからコピー: run-java.shは、コンテナ内でコマンドラインからThorntailアプリを実行するための特定のパラメータを持っています。スクリプトの詳細は https://github.com/sshaaf/rhel7-jre-image/blob/master/run-java.sh にあります。 COPY run-java.sh /app/ # スクリプトを実行するためのパーミッションの設定 RUN chmod 755 /app/run-java.sh # 最後に、スクリプトを実行する CMD [ "/app/run-java.sh" ] さて、 Dockerfile の詳細がわかったところで、イメージの構築を進めていきましょう。 重要な点として、OpenJDKのJavaランタイムは「java-1.8.0-openjdk」としてパッケージされています。これには、 -devel パッケージに含まれているコンパイラやその他の開発ライブラリは含まれていません。 上記の Dockerfile はRHELでビルドされています。つまり、ホストにはすでにサブスクリプションが添付されているので、 subscription-manager に登録する必要はありません。 以下に、これを構築する2つの方法を紹介します。私のように RHEL を使用している場合は、2 つのバイナリのいずれかを選択してデプロイできます。両方とも rhel7-server-extras-rpms にあるはずです。 次のようにして extras リポジトリを有効にします。 # subscription-manager repos --enable rhel-7-server-extras-rpms ローカルでイメージをビルドと実行 docker でイメージを構築します。 $ docker build -t quay.io/sshaaf/rhel7-jre8-mpdemo:latest . イメージを docker で実行し、localhost:8080 をコンテナのポート 8080 に指定します。 $ docker run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest また、buildahコマンドも使用できます。これは、作業中のコンテナから、Dockerfileから、またはスクラッチからコンテナイメージを作成するのに役立ちます。作成されたイメージはOCIに準拠しているので、 OCIランタイム仕様 を満たしたランタイム(DockerやCRI-Oなど)で動作します。 buildah でビルドします: $ buildah bud -t rhel7-jre8-mpdemo . buildah でコンテナを作ります: $ buildah from rhel7-jre8-mpdemo また、Podmanを使ってもコンテナを実行できます。これは Buildah や Skopeo を補完するもので、Dockerのコマンドラインに似た体験を提供するものです。これにより、ユーザーはスタンドアロンの(オーケストレーションされていない)コンテナを実行できるようになります。また、Podmanはコンテナやポッドを実行するためのデーモンを必要としません。Podmanは extras チャンネルの一部でもあり、以下のコマンドでコンテナを実行できます。 $ podman run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest Podmanの詳細については、 Containers without daemons: Podman and Buildah available in RHEL 7.6 and RHEL 8 Beta および Podman and Buildah for Docker users をご覧ください。 イメージができたので、それを OpenShift にデプロイしてアプリをテストしたいと思います。そのためには、 oc クライアントライブラリが必要です。私は自分のクラスタを設定していますが、Red Hat Container Development Kit (CDK)/minishift、Red Hat OpenShift Online、または自分のクラスタも使用できます。手順は同じになるはずです。 OpenShiftにデプロイ OpenShiftにデプロイするためには、以下のような構成が必要です。 新しく作成したコンテナイメージのイメージストリーム OpenShift用のデプロイメント構成 サービスとルーティングの設定 イメージストリーム イメージストリームを作成するために、私のOpenShiftクラスタはどこかからコンテナイメージを引き出せるようにしなければなりません。これまで、イメージは私自身のマシンに存在していました。これを Quay にプッシュしてみましょう。Red Hat Quayのコンテナとアプリケーションのレジストリは、あらゆるインフラ上でコンテナの安全な保管、配布、デプロイを提供します。スタンドアロンのコンポーネントとしても、OpenShiftと組み合わせても利用可能です。 まずQuayにログインする必要がありますが、これは以下のように行います。 $ docker login -u="sshaaf" -p="XXXX" quay.io そして、新しく作ったイメージをQuayにプッシュします: $ docker push quay.io/sshaaf/rhel7-jre8-mpdemo ここでは、デプロイする前の構成を見てみましょう。気になる方は、デプロイテンプレートの詳細を読み飛ばして、プロジェクトの作成に進んでください。 イメージができたので、ストリームを定義します。 - apiVersion : v1 kind : ImageStream metadata : name : rhel7-jre8-mpdemo spec : dockerImageRepository : quay.io/sshaaf/rhel7-jre8-mpdemo 上の例では、Quay.ioのイメージリポジトリに直接アクセスしています。 デプロイメントコンフィグ 次は、デプロイメント設定です。ここでは、ポッドやトリガーを設定し、新しく作成したストリームを指定するなどします。 コンテナやOpenShiftのデプロイメントに慣れていない方は、こちらの便利な ebook をご覧になるとよいでしょう。 - apiVersion : v1 kind : DeploymentConfig metadata : name : rhel7-jre8-mpdemo spec : template : metadata : labels : name : rhel7-jre8-mpdemo spec : containers : - image : quay.io/sshaaf/rhel7-jre8-mpdemo:latest name : rhel7-jre8-mpdemo ports : - containerPort : 8080 protocol : TCP replicas : 1 triggers : - type : ConfigChange - imageChangeParams : automatic : true containerNames : - rhel7-jre8-mpdemo from : kind : ImageStreamTag name : rhel7-jre8-mpdemo:latest type : ImageChange サービス これでデプロイメントができたので、内部のロードバランシングやポッドのIPアドレスなどを確保するサービスも定義したいと思います。 サービスは、新しく作成したアプリを最終的に外部のトラフィックに公開したい場合に重要です。 - apiVersion : v1 kind : Service metadata : name : rhel7-jre8-mpdemo spec : ports : - name : 8080-tcp port : 8080 protocol : TCP targetPort : 8080 selector : deploymentconfig : rhel7-jre8-mpdemo ルート そして、デプロイメントの最後の部品は、ルートです。ルートを使ってアプリを外部に公開する時が来ました。このルートがどの内部サービスを指すのか、どのポートをターゲットにするのかを定義できます。OpenShift はルートにフレンドリーな URL を与えます。この URL を指定することで、新しく作成した Java 8 ランタイムベースのデプロイメント上で MicroProfile アプリが実行されるのを確認できます。 - apiVersion : v1 kind : Route metadata : name : rhel7-jre8-mpdemo spec : port : targetPort : 8080-tcp to : kind : Service name : rhel7-jre8-mpdemo weight : 100 上記の完全なテンプレートは GitHubのここ にあります。 また、このようにOpenShiftでプロジェクトを作成してみましょう。 $ oc new-project jredemos そして、テンプレートを処理して、OpenShift上でJava 8ランタイムを使ったデモを取得します。そのためには、以下のコマンドを実行します。 $ oc process -f deployment.yaml | oc create -f - これでデプロイメント全体が作成され、以下のように表示されるはずです。 ここで、次のコマンドを実行します。 $ oc get routes これにより、以下のようなルートが表示されます。 このルートをブラウザにコピーすると、RHEL 7上でJava 8ランタイムが動作するWebアプリがデプロイされていることが確認できます。(以下のアドレスは、クラスタのテスト専用であり、クラスタごとに異なります) http://rhel7-jre8-mpdemo-jredemos.apps.cluster-1fda.1fda.openshiftworkshop.com/ まとめ DockerまたはBuildahを使って、Java 8ランタイムのコンテナイメージを構築・作成することに成功しました。以下の点に注意してください。 この画像は、どのようにして実現するかを示すためのものであることに注意してください。JolokioやHawkularのような、デプロイに必要なものは含まれていません。 さらに、コンテナ内でJavaアプリを実行するために必要なパラメータは考慮されていません。これについては、Rafael Benevides氏の 記事 で非常によく説明されています。 さらに、独自のコンテナイメージをデプロイする際には、Red Hat の OpenJDK ビルドを実行している場合、サポートおよびライフサイクルポリシー こちら を確認することを常に忘れないでください。 その後、 MicroProfile Starter beta から基本的なMicroProfileのデモアプリを使ってOpenShiftにデプロイしました。 より包括的なデモアプリの作成を検討されている方は、以下の資料をご参照ください。 Deploying MicroProfile apps on Microsoft Azure using the Azure Open Service Broker The MicroProfile ebook こちら 本記事の全資料は こちら からご覧いただけます。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Build lean Java containers with the new Red Hat Universal Base Images OpenJDK runtime images | Red Hat Developer の翻訳記事です。 Red Hat Universal Base Images (UBI) には、OpenJDK の完全な Red Hat ビルドが含まれています。Universal Base Images は UBI のエンドユーザライセンス契約の下で誰でも利用でき、Red Hat の顧客には完全にサポートされています。これらの「ビルダ」イメージは、特に Red Hat OpenShift 環境で使用する場合に、広範な Java ベースのアプリケーションの構築と実行に適しているように設計されています。これらのイメージには、開発ツール、Java コンパイラ、Maven、および関連するビルドツールを含む完全な Java Development Kit(JDK)が含まれています。 OpenShiftのS2I(source-to-image)プロセスでは、アプリケーションのソースコードをOpenShiftクラスタ内で簡単に構築・更新できます。また、基盤となるイメージやアプリケーションのソースが更新されるたびに、デプロイメントが更新されます。このワークフローでは、アプリケーションはビルダイメージの上に重ねられているため、デプロイメントには完全なJDKとMavenツールが含まれています。開発者の中には、よりスリムなベースイメージに基づいてデプロイメントを行いたいと考える人もいます。その場合、Maven を使用しないか、JDK ツールを完全に使用しないか、またはその両方を使用します。 このニーズに対応するため、Red Hat は新しい OpenJDK ランタイム・コンテナ・イメージをリリースしました。 このイメージには、完全なJDKやその他のビルドツールは含まれていません。この記事では、S2Iワークフローを使用してアプリケーションを自動的にデプロイするために、OpenShift環境内でこれらの新しいイメージを使用する方法を説明します。ここでは、Quarkusのクイックスタートをアプリケーションソースとして使用します。 S2IとQuarkusのクイックスタートでビルダイメージを使う Quarkusのクイックスタートを開始するには、OpenShiftインスタンスにログインしていることを確認し、以下のコマンドを実行します。 # OpenShiftでのイメージ構築 $ oc new-app --context-dir=getting-started --name=quarkus-quickstart \ ' registry.access.redhat.com/ubi8/openjdk-11~https://github.com/quarkusio/quarkus-quickstarts.git#1.13.3.Final ' # ビルドの完成を見守る $ oc logs -f bc/quarkus-quickstart # ルートを作成 $ oc expose svc/quarkus-quickstart # ルートのURIを取得 $ export URI= " http:// $( oc get route | grep quarkus-quickstart | awk ' {print $2} ' ) " # アプリをテスト! $ curl $URI /hello/greeting/quarkus 最初のコマンドである oc new-app は、クイックスタートアプリケーションの構築とデプロイに必要なすべての OpenShift コンポーネントを作成します。すなわち、 BuildConfig 、 ubi8/openjdk-11 ベースイメージと結果のアプリケーションイメージの両方の ImageStreams 、 DeploymentConfig と Service です。また,このコマンドはビルドとデプロイメントのインスタンスを作成します。 oc expose コマンドは、デプロイメントへの Route を作成し、実行中のWebアプリケーションをテストできます。 この設定の優れた点は、アプリケーションソースがGitリポジトリで更新されたときや、基盤となるビルダイメージが更新されたときに、新しいビルドを起動できることです。 ランタイムイメージ さて、新しい部分です。ここでは、無駄のないランタイムイメージのために、新しい ImageStream を定義します。このイメージの一部として、前のステップで作成されたアプリケーションの ImageStream からアプリケーションの成果物をコピーします。また、初期のクイックスタートで自動的に行われたように、アプリケーションを稼働させるための他のOpenShiftの部品を定義する必要があります。それは"DeploymentConfig"、"Service"、"Route "の3つです。図1は私たちのプロセスを示しています。 DIYランタイムイメージを生成するためのOpenShiftのプロセス まず、無駄のないベースイメージが必要です。ここではRed Hat UBI8 minimal base imageを使用します。これを ImageStream として OpenShift にインポートする必要があります。それは以下のコマンドで簡単にできます。 $ oc create -n openshift -f https://raw.githubusercontent.com/jboss-container-images/openjdk/release/templates/runtime-image-streams.json ここからは、無駄のないアプリケーション用のOpenShiftコンポーネントを定義していきます。まず、無駄のないランタイムアプリケーションのイメージを公開するための ImageStream を作成します。 $ oc create imagestream quarkus-quickstart-runtime 次に、イメージを構築するための BuildConfig が必要です。これはより複雑なので、コマンドラインではなくYAMLファイルで定義します。この記事の次のすべてのYAMLの断片については、その断片をファイルに保存して、OpenShiftに次のように読み込みます。 $ oc create -f snippet.yaml BuildConfigは以下の通りです。 apiVersion : v1 kind : BuildConfig metadata : name : quarkus-quickstart-runtime spec : output : to : kind : ImageStreamTag name : quarkus-quickstart-runtime:latest source : images : - from : kind : ImageStreamTag name : quarkus-quickstart:latest paths : - sourcePath : /deployments destinationDir : ./deployments dockerfile : |- FROM - COPY deployments / CMD java -jar /deployments/quarkus-run.jar strategy : type : Docker dockerStrategy : from : kind : ImageStreamTag name : ubi8-openjdk-11-runtime:latest triggers : - type : ConfigChange - type : ImageChange imageChange : automatic : true from : kind : ImageStreamTag name : quarkus-quickstart:latest - type : ImageChange imageChange : automatic : true from : kind : ImageStreamTag name : ubi8-openjdk-11-runtime:latest Note: イメージのDockerfileはYAMLの中にインラインで記述されています。ここでは"-"を代理の FROM イメージとして使用しています。YAMLの dockerStrategy セクションは、 FROM 行を ubi8-openjdk-11-runtime イメージストリームの最新イメージを表す値でオーバーライドするようOpenShiftに指示します。 Quarkus のクイックスタートイメージから /deployments ディレクトリを新しい無駄のないイメージにコピーします。Quarkusのクイックスタートアプリケーション全体がこのディレクトリに存在することがわかっているので、コピーする必要があるのはこれだけです。特定のアプリケーションに応じて、さらなるステップが必要になるかもしれません。 最後に、無駄のないコンテナの CMD が java を直接呼び出すように設定します。そして、これはアプリケーションのJARをコマンドラインで渡しています。 この構成では、基盤となる quarkus-quickstart イメージ、またはベースの ubi8-openjdk-11-runtime イメージに変更があった場合は、このイメージの再構築が行われます。 この断片を一時ファイルに保存し、前述のようにOpenShiftに読み込みます。これで、OpenShift はイメージの構築をスケジュールして開始するはずです。先ほどと同様に、ログを見て進行状況を確認できます。 $ oc logs -f bc/quarkus-quickstart-runtime イメージサイズ ビルドが完了したら、結果を確認してそのサイズをチェックできます。まず、ビルダイメージの上に重ねられた、通常のクイックスタート ImageStream のサイズを取得します。 $ oc get istag quarkus-quickstart:latest -o json | jq .image.dockerImageMetadata.Size 308976772 => 295 MiB 比較のために、新しいランタイムイメージを入手してください: $ oc get istag quarkus-quickstart-runtime:latest -o json | jq .image.dockerImageMetadata.Size 135747392 => 129 MiB この新しいランタイム・イメージは、UBI8 OpenJDKの完全なビルダイメージの半分以下のサイズです。完全なビルダイメージには、完全なOpenJDKとMavenが含まれています。 最後の仕上げ 次に必要なのは、 DeploymentConfig 、 Service 、 Route の定義です。これらについては特に説明することがないので、1つのYAMLスニペットにまとめました。これを保存しておけば、先ほどのように oc create -f で一度に読み込めます。 apiVersion : v1 kind : DeploymentConfig metadata : name : quarkus-quickstart-runtime spec : replicas : 1 selector : app : quarkus-quickstart-runtime template : metadata : labels : app : quarkus-quickstart-runtime spec : containers : - image : ' ' name : quarkus-quickstart-runtime ports : - containerPort : 8080 protocol : TCP triggers : - type : ConfigChange - imageChangeParams : automatic : true containerNames : - quarkus-quickstart-runtime from : kind : ImageStreamTag name : quarkus-quickstart-runtime:latest type : ImageChange --- apiVersion : v1 kind : Service metadata : name : quarkus-quickstart-runtime spec : selector : app : quarkus-quickstart-runtime ports : - port : 8080 protocol : TCP targetPort : 8080 --- apiVersion : v1 kind : Route metadata : name : quarkus-quickstart-runtime spec : to : kind : Service name : quarkus-quickstart-runtime これらが読み込まれたら、同じ手法でルートを取得し、「Hello world」のURIを取得して、すべてが順調に進んでいることを確認します。 $ export URI= " http:// $( oc get route | awk ' /quarkus-quickstart-runtime/ {print $2} ' ) " curl $URI /hello/greeting/quarkus まとめ Universal Base ImagesのOpenJDK ビルダイメージは、OpenShift上でソフトウェアを構築してデプロイしたいと考えている様々なお客様のニーズに応えるために設計されました。しかし、このイメージの柔軟性は、イメージのサイズを犠牲にしています。開発者の中には、より小さなイメージや、ビルドツールのないイメージを望む人もいます。Red Hat は、このニーズに対応するために、新しい UBI OpenJDK ランタイムイメージを導入しました。この記事で紹介する方法では、新しいランタイムイメージに基づいてOpenShift内でDIY(do-it-yourself)アプリケーションイメージをカスタマイズして構築できます。また、この方法では、構成部品が変更されたときにイメージが再構築されるようになっています。 今後の課題 新しいランタイムイメージの主な目的は、可能な限り構成要素を少なくすることでした。既存のビルダイメージには、ランタイムイメージにはない多くの機能が含まれています。 その既存のビルダイメージは、機能的なランスクリプト(ただし、これに限定されません)、 メトリクス収集のための Prometheus エージェント、OpenShift の準備のためのプローブ、デフォルトのJVMおよびガベージコレクションのパラメータ、イメージを調整するための豊富な環境変数などを含んでいます。これらの機能を必要とする場合は、完全なビルダイメージが適しているかもしれません。逆に、できるだけ小さなランタイムイメージで、可動部が少なく、多少のDIYは気にしないという方には、ランタイムイメージの方が適しているかもしれません。 Red Hatでは、最新の技術を活用するためにコンテナを継続的に進化させています。多くの開発者にとって、イメージのサイズとデプロイに必要なサイズが重要な問題であることは承知しています。私たちは、リリースごとにOpenJDKビルダとランタイムイメージの両方のサイズを小さくするために継続的に取り組んでいます。現在、いくつかの有望な開発を進めています。どうぞご期待ください。
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 今更ですが、ちょっと初心に戻ってRed Hat OpenShift 製品を改めてご紹介します。当ブログでも既に紹介済で重複する内容もある点はご容赦ください。 ご存知ない方のが多数だと思いますが OpenShift YouTube Channel というものが存在しております。英語ではありますが頻繁にコンテンツがアップロードされており「OpenShiftとKubernetesの違い」「Hands-on demo」「GitOps Guide」などが公開されております。紹介ネタは数分程度のものが多いのでお時間の有る時に覗いてみてください。 Red Hat OpenShift 利用形態 「Red Hat OpenShift Everywhere」と謳うように、Red Hat OpenShiftは物理サーバー、仮想サーバー、プライベートクラウド、パブリッククラウド問わずにあらゆるクラウドで実行可能です。利用形態として、利用者自身が一から作り上げるものから、パブリッククラウドの一サービスとして提供されているものがあります。費用面を抜きにして手軽にお試しいただけるのは、パブリッククラウドに自分でクラスターを作成できるARO、ROKS、ROSAです。 名称 管理 内容 Red Hat OpenShift Container Platform Self-Managed 利用者自身がOpenShiftをインストールして運用管理を行います Red Hat OpenShift Dedicated Managed Red Hatが管理運営するOpenShift クラスターです。コンテナアプリケーションの開発および管理を実施できる環境を提供します。利用者は Red Hat と協業しながら要件や統合するツールを決定し、Red Hat が環境の実装とすべての管理を行います。AWSおよびGCPで利用可能です Microsoft Azure Red Hat OpenShift (ARO) Managed Microsoftが提供し、Red Hat と Microsoftが共同でサポートするマネージドサービスで、Microsoft Azureで実行されます Red Hat OpenShift on IBM Cloud (ROKS) Managed IBMがサポートするマネージドサービスで、IBM Cloudで実行されます Red Hat OpenShift on AWS (ROSA) Managed Red Hat と AWS が 共同で管理し、共同でサポートするマネージドサービスで、AWSで実行されます OpenShiftをユーザー自身が導入運用してアプリを公開するに至るまでには、サーバやストレージ、ネットワークだけでなくDNSやロードバランサーなど考慮する必要があります。図で表してみると青の部分がユーザーの責任範囲になります。フルマネージドの場合と比較すると構成要素とカバーする範囲が大きいことがわかると思います。 ▼ユーザー自身がOpenShiftを導入運用する場合 ▼フルマネージドOpenShiftの場合 Managed Red Hat OpenShift Platform 比較項目 そんなフルマネージドなサービスを比較してみようと思うのですが、Container RegistryやCI/CDツールなどのOpenShiftが提供する機能に差はなく、サポートや可用性も大きな差はありません。このブログで「AWS PrivateLink」の話もありましたが、AROでもROKSでも同様のプライベートクラスター構成は可能です。コントロールプレーンの構成はクラウドプロバイダー毎に特徴があります。 ほぼ差がない項目 使用するアカウント:ユーザ自身のクラウドアカウント 運用サポート:クラウドプロバイダーとRed Hatが共同で管理とサポートを行う サポート時間:24x7 可用性:複数の地域とゾーンの利用可能 SLA:99.95%(高可用性の構成の場合) OpenShiftが提供する機能 クラウドプロバイダーで異なる項目 提供されるOpenShiftのバージョン サポートされる標準構成 提供可能なPersistent Storage CLI バージョンアップのポリシー クラスターのロギング・メトリクス IdentityとAuth セキュリティ/コンプライアンス Managed Red Hat OpenShift Platform 費用と構成 各Managed Red Hat OpenShift Platformの費用感と構成について以下にまとめます。この他にストレージやネットワークなども従量課金されます。 Microsoft Azure Red Hat OpenShift (ARO) 最小構成 マスターノード×3 ワーカーノード×3 ・最小構成の費用(時間) ノード インスタンスタイプ 台数 インスタンス料金 OpenShift料金 マスターノード D8s v3 3 $0.44/hour × 3 - - ワーカーノード D4s v3 3 $0.22/hour × 3 $0.171/hour ×3 - 1時間あたりの使用料金 $1.98$/hour $0.513/hour $2.493/hour ▼マルチゾーン構成 Red Hat OpenShift on IBM Cloud (ROKS) 最小構成 ワーカーノード×2 ・最小構成の費用(時間) ノード インスタンスタイプ 台数 インスタンス料金 OpenShift料金 ワーカーノード 4 vCPU 16GB RAM 仮想 - 共有 2 $0.44/hour ×2 - 1時間あたりの使用料金 $0.88/hour $0.88/hour ※「IBM Cloud Pak」を所持している場合はOCP license entitlementを含んでいるので、それを適用することが可能で、料金体系が変わります。 ▼シングルゾーン構成 ▼マルチゾーン構成 Red Hat OpenShift on AWS (ROSA) 最小構成 マスターノード×3 インフラノード×2 ワーカーノード×2 ・最小構成の費用(時間) ノード インスタンスタイプ 台数 インスタンス料金 OpenShift料金 コントロールプレーン $0.03/hour - マスターノード m5.xlarge 3 $0.248/hour × 3 - - インフラーノード r5.xlarge 2 $0.304/hour × 2 - - ワーカーノード m5.xlarge 2 $0.248/hour × 2 $0.171/hour ×2 - 1時間あたりの使用料金 $1.848/hour $0.372/hour $2.22/hour ▼シングルゾーン構成 ▼マルチゾーン構成
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Introducing the Red Hat build of the OpenJDK Universal Base Images—now in Red Hat Enterprise Linux 8.2 | Red Hat Developer の翻訳記事です。 最近リリースされたRed Hat Enterprise Linux 8.2では、OpenJDK Universal Base Imagesの最初のRed Hatビルドも追加されました。OpenJDK 8およびOpenJDK 11用のこれらのGA(General Availability)イメージは、コンテナ内で実行されるJavaアプリケーションを安全かつ安定的にテストされた方法で開発したいと考えている人にとって、新たな開始地点となります。 この記事では、新しいOpenJDK Universal Base Imagesを紹介し、Java開発者にとってのメリットを説明します。その前に、一般的なUBIについて知っていることを簡単におさらいしましょう。 Universal Base Imagesについて Red Hat Universal Base Images (UBIs) は: OCI に準拠したコンテナベースのオペレーティングシステムイメージで、自由に再配布可能な補完的なランタイム言語とパッケージを備えています。これまでのベースイメージと同様に、Red Hat Enterprise Linux (RHEL)の一部から構築されています。UBI イメージは Red Hat コンテナカタログから入手でき、どこでもビルドしてデプロイできます。 言い換えれば、UBIは、アプリケーション開発者が、安全で安定した移植しやすいコンテナの世界に到達するのを助けるものです。これらのイメージは、Podman/BuildahやDockerなどのよく知られたツールを使ってアクセスできます。また、Red Hat Universal Base Imagesでは、Red Hat OpenShiftやRed Hat Enterprise Linuxでサポートされているエンタープライズ品質の小さな基盤の上に、ユーザが独自のアプリケーションを構築して配布できます。 Red HatがビルドしたOpenJDK OpenJDKのRed Hatビルドは、アップストリームのOpenJDK 8uとOpenJDK 11uのコミュニティ主導のプロジェクトをベースにしています。Red Hatは、両プロジェクトに重要な貢献者を提供し、Red Hatのビルドに新しい機能を追加しています。 このバージョンには 超低停止時間のガベージ・コレクタ「Shenandoah」を搭載。 RPM、MSIインストーラ、およびZIPバージョンを含む、いくつかのインストールオプション。 Java Web Startのサポート(Windowsのみ、Linuxの場合はRed Hat Enterprise LinuxのRPMを使用してください)。 Red HatビルドのOpenJDKは、セキュリティやその他のバグフィックスの強化のため、少なくとも四半期に一度は更新されます。Red Hat は、OpenJDK の主要バージョンに対して、規定の期間のサポートとメンテナンスを提供しています。今回のケースでは、バージョン8は2026年6月まで、バージョン11は2024年10月までの長期サポート(LTS)バージョンを提供しています。(OpenJDK ライフサイクルとサポートポリシーもご参照ください。) 詳細については、Red Hat Ecosystem Catalog の新しいイメージをご覧ください。 OpenJDK 8 UBI8 イメージ OpenJDK 11 UBI8 イメージ OpenJDK UBIイメージ入門 OpenJDK UBIイメージには、アプリケーションのJARを自動的に検出してJavaを起動するデフォルトの起動スクリプトがあります。このスクリプトの動作は、環境変数を使ってカスタマイズできます。詳しくは、コンテナ内の/help.mdをご覧ください。 一方で、OpenJDK 11 UBI8 Imageにtestubi.jarというアプリケーションを追加するDockerfileの例を簡単に紹介します。 FROM registry.access.redhat.com/ubi8/openjdk-11 COPY target/testubi.jar /deployments/testubi.jar Universal Base ImageのEULAを拡張 2019年5月にユニバーサルベースイメージを導入した際、エンドユーザー使用許諾契約書(EULA)を盛り込みました。これにより、Red Hat パートナーは相当数の RHEL パッケージを自由に使用し、再配布できるようになりました。これは、Red Hat と非 Red Hat の両方のプラットフォームに展開できます。この契約により、開発者は安全でセキュア、かつ移植が容易なコンテナベースのソフトウェアを構築し、どこにでも展開できるようになりました。いただいたご意見は圧倒的にポジティブなものばかりで、感謝しています。また、より多くのものを必要とされていることも分かりましたので、お客様向けのパッケージセットを拡充しました。 Red Hat Partner Connect プログラムのアプリケーション開発者は、Red Hat Enterprise Linux (RHEL) のユーザスペースパッケージ (非カーネル) のフルセットからコンテナアプリを構築し、選択したコンテナレジストリを通じて再配布できるようになりました。この拡張機能により、UBI のみの場合と比べて利用可能なパッケージの数が約 3 倍になります。 こちらもご覧下さい: Red Hat simplifies container development and redistribution of Red Hat Enterprise Linux packages. 結論 コンテナでJavaアプリケーションを開発したいと考えており、さらにセキュリティ、信頼性、安定性の面で基盤となるベースを信頼できるようにしたいと考えているなら、OpenJDK UBI8イメージは、あなたが求めているソリューションになるかもしれません。ハイブリッドクラウドでコンテナ型のJavaアプリケーションを構築するために、新しいOpenJDK Universal Base Imagesを試してみてください。 今後数週間は、このアップデートを継続し、OpenJDK UBIでの作業についてより詳細に紹介していきます。それには、OpenJDK UBI8のコンテナ・イメージを扱う方法についてのより多くの例が含まれます。ご期待ください。
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 Red Hat OpenShift Platform on AWS、略称ROSA、 Red Hat OpenShiftのyoutube に上がっているハンズオン動画を見ると「ローザ」と言ってる気がします。 www.youtube.com 今までもAWS上でOpenShiftが動いてのでは?と思われるかもしれませんが、今まではSelf-managedで利用者自身がAWS上にOpenShift Container Platformインストールするか、クラスターの作成・運用はRed Hatが行うOpenShift Dedicatedの2択でした。利用者がAWSマネージメントコンソールやCLIコマンド(rosaコマンド)を用いて自由にクラスター作成できるのがROSAです。 ROSAのリリースにあたって「ROSA無料トライアル可能ですか?」「OpenShift Container Platformのサブスクリプションを既に持っていますがROSAで使えますか?」といったFAQがありますが、回答は以下です。 ROSAの無料トライアルはない OpenShift Dedicatedは60日間無料トライアル有り(OpenShiftのトライアルであり、AWSのインスタンス料金は必要) Self-managedで利用していたOpenShift Container PlatformのサブスクリプションをROSAに転用することはできない このブログでも既に複数の人がROSAの記事を書いていて、今さら書くことがあるのかと言われそうですが、今回は「初めてAWSを使う」という前提で「それはROSAの使い方というよりもはやAWSの使い方じゃないか」的なことを書いてみます。 アカウントのクォータ ROSAクラスターを作成する際に、事前チェックとして $ rosa verify quota --region=リージョン名 を実行します。作ったばかりで何もしていないアカウントで実行すると「クォータが足りません」とメッセージが出ます。 $ rosa verify quota --region=ap-northeast-1 I: Validating AWS quota... E: Insufficient AWS quotas E: Service ec2 quota code L-1216C47A Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances not valid, expected quota of at least 100, but got 64 少なくともOn-Demand Standard instancesが100必要とのことで、AWSマネージメントコンソールで「クォータの引き上げのリクエスト」を実施してクォータの上限を上げておきます。リクエストを出して数分〜数十分で引き上げられます。 ROSAのドキュメント「 Red Hat OpenShift Service on AWS Documentation 」の中の「 Required AWS service quotas 」という章にROSAでOpehshiftを使う場合の必要な「Quota name / Service code / Quota code / Minimum required value / Recommended value」が記載されています。クラスター作成時だけでなく、利用してゆくうちにクォータにひっかかる場合もあるかと思いますので、必要に応じて設定してください。 Red Hat OpenShift Platform on AWS コスト 利用料金に関しては Red Hat OpenShift Service on AWS に「Red Hat OpenShift Service on AWS pricing」の記載があります。マスターノードとインフラノードの費用はコントロールプレーンのcluster feeになってます。料金設定としては時間単位以外に1年・3年があり契約期間が長いほどディスカウントされます。デフォルトで作成すると以下のインスタンスのマスターノード×3,インフラノード×2、ワーカーノード×2が作成されます。他にストレージやロードバランサーの費用なども従量課金されるのは他のクラウドと同様です。 ノード インスタンス vCPU RAM DISK インスタンス料金 OpenShift料金 マスターノード m5.xlarge minimum 4 16GB - $0.248/hour $0.03/hour インフラノード r5.xlarge minimum 4 32GB - $0.304/hour ↑に含む ワーカーノード m5.xlarge minimum 4 16GB - $0.248/hour $0.171/hour ※マスターノードとインフラノードのOpenShift料金は1クラスターあたりの費用でマスター3台とインフラ2台分を含む費用 インフラノードはOpenShift DedicadeやROSAでは標準構成に入っており、以下のようなユーザーのワークロード以外の以下のような機能を集約しています。 Red Hat OpenShift に含まれるレジストリ ルーター OpenShift クラスタモニタリング OpenShift ログ集約 Red Hat Quay Red Hat OpenShift Container Storage Red Hat Advanced Cluster Manager ちなみに利用料金明細を見ると m5.large ($0.124/hour)がちょっとだけ使われていますが、これはOpenShiftをデプロイする際に一時的に使用されるbootstrapノードです。クラスター作成後は削除されますので、以降は費用はかかりません。 ▼利用料金明細
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 Red Hat OpenShift on IBM Cloud (ROKS)については以前にHands on Lab環境と使ってみるという記事を書きましたが、半年くらい経過しているのでRed Hat OpenShift on IBM Cloud (ROKS)を再度チラッと見てみます。 rheb.hatenablog.com rheb.hatenablog.com 今回のお題 Red Hat OpenShift on IBM Cloud CLI Red Hat OpenShift on IBM Cloud コンソールの利用 クラスター作成 クラスターアップデート ノード追加 クラスターの中を覗いてみる Red Hat OpenShift on IBM Cloud コスト Red Hat OpenShift on IBM Cloud CLI 前回はCLIはまったく使用せず、Red Hat OpenShift on IBM Cloud コンソールを利用してクラスターを作成しました。他のクラウドではCLIを利用するケースが多いので、IBM CloudのCLIも確認してみます。 OpenShift CLI のインストール 手順にしたがって導入します。 IBM Cloud CLI (ibmcloud) Red Hat OpenShift on IBM Cloud プラグイン (OpenShift クラスターの ibmcloud oc) IBM Cloud Container Registry プラグイン (ibmcloud cr) IBM Cloud Kubernetes Service 可観測性プラグイン (ibmcloud ob) IBM Cloud CLIをインストールした後の作業は、コマンドラインでibmcloudにログインしておく必要があります。以下のうように入力を求められるので、Webにログインする際に利用しているメールアドレスをパスワードを入力します。初回のみリージョンの選択肢が表示されるので適切なものを選んでください。 $ ibmcloud login API エンドポイント: https://cloud.ibm.com Email> xxxxxx@redhat.com(IBM Cloudに登録したメールアドレス) Password>(IBM Cloudに登録したパスワード) 認証中です... OK リージョンを選択します (または Enter キーを押してスキップします): 1. au-syd 2. in-che 3. jp-osa 4. jp-tok 5. kr-seo 6. eu-de 7. eu-gb 8. ca-tor 9. us-south 10. us-east 11. br-sao 数値を入力してください> 4 ターゲットのリージョン jp-tok API エンドポイント: https://cloud.ibm.com リージョン: jp-tok ユーザー: xxxxxx@redhat.com アカウント: xxxxxx's Account (xxxxxx) <-> xxxxxx ▼手順に従ってCLIをインストール $ ibmcloud plugin install container-service リポジトリー 'IBM Cloud' から 'container-service' を検索しています... プラグイン 'container-service/kubernetes-service 1.0.295' がリポジトリー 'IBM Cloud' 内で見つかりました プラグイン 'container-service/kubernetes-service 1.0.208' は既にインストールされていました。 'container-service/kubernetes-service 1.0.295' で更新しますか? [y/N] > y バイナリー・ファイルをダウンロードしようとしています... 29.09 MiB / 29.09 MiB [============================================] 100.00% 5s 30501488 バイトがダウンロードされました バイナリーをインストールしています... OK プラグイン 'container-service 1.0.295' は ~/.bluemix/plugins/container-service に正常にインストールされました。 'ibmcloud plugin show container-service' を使用して詳細を表示してください。 $ ibmcloud plugin install container-registry リポジトリー 'IBM Cloud' から 'container-registry' を検索しています... プラグイン 'container-registry 0.1.536' がリポジトリー 'IBM Cloud' 内で見つかりました プラグイン 'container-registry 0.1.497' は既にインストールされていました。 'container-registry 0.1.536' で更新しますか? [y/N] > y バイナリー・ファイルをダウンロードしようとしています... 26.27 MiB / 26.27 MiB [============================================] 100.00% 3s 27547088 バイトがダウンロードされました バイナリーをインストールしています... OK プラグイン 'container-registry 0.1.536' は ~/.bluemix/plugins/container-registry に正常にインストールされました。 'ibmcloud plugin show container-registry' を使用して詳細を表示してください。 $ ibmcloud plugin install observe-service リポジトリー 'IBM Cloud' から 'observe-service' を検索しています... プラグイン 'observe-service 1.0.61' がリポジトリー 'IBM Cloud' 内で見つかりました バイナリー・ファイルをダウンロードしようとしています... 17.70 MiB / 17.70 MiB [============================================] 100.00% 2s 18561888 バイトがダウンロードされました バイナリーをインストールしています... OK プラグイン 'observe-service 1.0.61' は ~/.bluemix/plugins/observe-service に正常にインストールされました。 'ibmcloud plugin show observe-service' を使用して詳細を表示してください。 $ ibmcloud plugin list インストール済みプラグインをリストしています... プラグイン名 バージョン 状況 サポートされるプライベート・エンドポイント cloud-functions/wsk/functions/fn 1.0.49 更新が使用可能です false cloud-object-storage 1.2.1 更新が使用可能です false container-registry 0.1.536 true container-service/kubernetes-service 1.0.295 false observe-service/ob 1.0.61 false Red Hat OpenShift on IBM Cloud リソースを作成および管理には「ibmcloud oc」を利用します。AWSのrosaコマンド、AROのazコマンドと同じような使用感です。 これはあくまで個人的な感覚ですが、Red Hat OpenShift on IBM Cloudに関しては、Red Hat OpenShift on IBM Cloud コンソールが直感的にわかりやすく、クラスターの作成やノードの追加はRed Hat OpenShift on IBM Cloud コンソールで実施した方が簡単です。すべてのコマンドを対比した訳はないのですが、ibmcloud ocコマンドで出来ることはほぼRed Hat OpenShift on IBM Cloud コンソールから実施できると思います。 クラスター作成 Red Hat OpenShift on IBM Cloud コンソールから「Create Cluster」を選びクラスターを作成します。シングルゾーンまたはマルチゾーン、使用するワーカーのvCPUやメモリ、台数を指定できます。昨年末に作成した際はバージョンが4.5でしたが、現在はデフォルトが4.6になっています。また、4.7へのアップデートも可能です。 ▼シングルゾーン構成 ▼マルチゾーン構成 クラスター作成後のクラスター管理画面が以前より使い勝手がよくなっている印象です。Add-onの導入状況の表示(インストールもそこから可)や右側に「IBM Cloud Shell」や「Oauth token request」へのリンクを出すことができたりします。 クラスターアップデート Red Hat OpenShift on IBM Cloudでは以下の2通りの方法があります。 OpenShiftのWebコンソールからアップデート Red Hat OpenShift on IBM Cloud コンソールのクラスター管理画面(もしくはコマンド)でアップデート 作成したクラスター(デフォルトで作成すると4.6)をクラスター管理画面から4.6から4.7にアップデートしてみます。後述しますが、クラスター管理画面でのアップデートは「ibmcloud oc cluster master update」に該当するようで、マスターの更新を行います。ワーカーノードは別途アップデートを行う必要があります。 ▼クラスター管理画面 ▼Webコンソールでの進捗確認ができる ノードの追加 作成したクラスターへの新しいワーカーノードを追加もクラスター管理画面から実施できます。同じworker poolにノードを追加する場合は[Resize]になります。追加と思って[Add]を選ぶと新規のworker poolを作ってしまいます。 ▼同一worker poolへのノードの追加 ▼新規worker poolの追加 クラスターの中を覗いてみる AROクラスターでも実施したように、中身をちょっと見てみましょうといくつかコマンドを試してみました。Red Hat OpenShift on IBM Cloudではマスターノードは利用者からは認識できない状況になっています。「oc get nodes」コマンドで確認できるのはワーカーのみです。ROLESに「master,worker」と出ますがマスターノードを兼ねている訳ではありません。この点が他のマネージドOpenShiftと異なる点で、マスターに関してはIBM様にお任せとなってます。 $ oc get nodes NAME STATUS ROLES AGE VERSION 10.212.234.207 Ready master,worker 160m v1.20.0+2817867 10.212.234.217 Ready master,worker 160m v1.20.0+2817867 10.212.234.220 Ready master,worker 160m v1.20.0+2817867 10.212.234.223 Ready master,worker 6h9m v1.19.0+c3e2e69 10.212.234.233 Ready master,worker 160m v1.20.0+2817867 10.212.234.234 Ready master,worker 6h8m v1.19.0+c3e2e69 10.212.234.243 Ready master,worker 6h8m v1.19.0+c3e2e69 10.212.234.245 Ready master,worker 141m v1.20.0+2817867 $ oc whoami IAM#mkoshimi@redhat.com $ oc get machineset -A error: the server doesn't have a resource type "machineset" ibmcloud ocコマンドでクラスターの中身をチラ見してみます。 ▼クラスター一覧 $ ibmcloud oc cluster ls OK Name ID State Created Workers Location Version Resource Group Name Provider mycluster-osa22-b3c.4x16 c3ci566o0ios9ivro38g normal 2 hours ago 9 Osaka 4.6.28_1543_openshift Default classic mycluster-tok02-b3c.4x16 c3chubft05l5kt4orku0 normal 3 hours ago 3 Tokyo 4.7.12_1520_openshift Default classic ▼特定のクラスターのリソース状況 $ ibmcloud oc cluster get --cluster c3chubft05l5kt4orku0 --show-resources Retrieving cluster c3chubft05l5kt4orku0 and all its resources... OK Name: mycluster-tok02-b3c.4x16 ID: c3chubft05l5kt4orku0 State: normal Status: All Workers Normal Created: 2021-06-28T01:00:51+0000 Location: tok02 Pod Subnet: 172.30.0.0/16 Service Subnet: 172.21.0.0/16 Master URL: https://c100-e.jp-tok.containers.cloud.ibm.com:30608 Public Service Endpoint URL: https://c100-e.jp-tok.containers.cloud.ibm.com:30608 Private Service Endpoint URL: - Master Location: Tokyo Master Status: Ready (5 hours ago) Master State: deployed Master Health: normal Ingress Subdomain: mycluster-tok02-b-490845-162f4dd9d7174cb8b0ffbc223c7b2a54-0000.jp-tok.containers.appdomain.cloud Ingress Secret: mycluster-tok02-b-490845-162f4dd9d7174cb8b0ffbc223c7b2a54-0000 Ingress Status: healthy Ingress Message: All Ingress components are healthy Workers: 8 Worker Zones: tok02 Version: 4.7.12_1520_openshift Creator: - Monitoring Dashboard: - Resource Group ID: 461c4fdfb3aa498eb230ce340f6023fa Resource Group Name: Default Addons Name Enabled openshift-container-storage true Subnet VLANs VLAN ID Subnet CIDR Public User-managed 3108638 10.212.77.216/29 false false 3108636 162.133.94.40/29 true false クラスターのアップデートをクラスター管理画面から実施できると書きましたが、クラスターに属しているワーカーノードの状態を確認すると、アップデート前に作成したワーカーノードについては「* To update to 4.7.16_1522_openshift version, run 'ibmcloud ks worker update'. Review and make any required version changes」という記載があり、ワーカーノードは手動でアップデートする必要があります。 $ ibmcloud oc worker ls --cluster c3chubft05l5kt4orku0 OK ID Public IP Private IP Flavor State Status Zone Version kube-c3chubft05l5kt4orku0-myclusterto-default-000001c2 162.133.80.21 10.212.234.234 b3c.4x16.encrypted normal Ready tok02 4.6.34_1546_openshift* kube-c3chubft05l5kt4orku0-myclusterto-default-000002de 162.133.80.25 10.212.234.243 b3c.4x16.encrypted normal Ready tok02 4.6.34_1546_openshift* kube-c3chubft05l5kt4orku0-myclusterto-default-000003c8 162.133.80.24 10.212.234.223 b3c.4x16.encrypted normal Ready tok02 4.6.34_1546_openshift* ↑最初に作成したワーカー kube-c3chubft05l5kt4orku0-myclusterto-default-000008a7 162.133.80.23 10.212.234.245 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift ↑クラスターを4.6から4.7にアップデートした後に、Resizeで追加されたワーカー kube-c3chubft05l5kt4orku0-myclusterto-myworke-00000445 162.133.80.19 10.212.234.233 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-000005d9 162.133.80.26 10.212.234.207 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-00000675 162.133.80.22 10.212.234.217 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-0000078b 162.133.80.30 10.212.234.220 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift ↑クラスターを4.6から4.7にアップデートした後に、新しいワーカープールを追加して出来たワーカー * To update to 4.7.16_1522_openshift version, run 'ibmcloud ks worker update'. Review and make any required version changes ここ、さりげにksコマンドになってますが、特定のワーカーのアップデートしている間はそのワーカーで稼働していたpodは他のワーカーに退避されるようにしておく必要があります。 $ ibmcloud ks worker update --cluster c3chubft05l5kt4orku0 --worker kube-c3chubft05l5kt4orku0-myclusterto-default-000001c2 Updating the worker node version can cause downtime for your apps and services. During the update, all pods might be rescheduled onto other worker nodes and data is deleted if not stored outside the pod. To avoid downtime, ensure that you have enough worker nodes to handle your workload while the selected worker nodes are updating. You might need to change your YAML files for deployments before updating. Review the docs for details: 'https://ibm.biz/upworker' Are you sure you want to update your worker node [kube-c3chubft05l5kt4orku0-myclusterto-default-000001c2] to 4.7.16_1522_openshift? [y/N]> y Processing kube-c3chubft05l5kt4orku0-myclusterto-default-000001c2... Processing on kube-c3chubft05l5kt4orku0-myclusterto-default-000001c2 complete. 最初にコマンド実行したワーカーがアップデートされたことを確認してから、順次このコマンドを実施します。 $ ibmcloud oc worker ls --cluster c3chubft05l5kt4orku0 OK ID Public IP Private IP Flavor State Status Zone Version kube-c3chubft05l5kt4orku0-myclusterto-default-000001c2 162.133.80.21 10.212.234.234 b3c.4x16.encrypted normal Ready tok02 4.6.34_1546_openshift --> 4.7.16_1522_openshift (pending) kube-c3chubft05l5kt4orku0-myclusterto-default-000002de 162.133.80.25 10.212.234.243 b3c.4x16.encrypted normal Ready tok02 4.6.34_1546_openshift --> 4.7.16_1522_openshift (pending) kube-c3chubft05l5kt4orku0-myclusterto-default-000003c8 162.133.80.24 10.212.234.223 b3c.4x16.encrypted normal Ready tok02 4.6.34_1546_openshift --> 4.7.16_1522_openshift (pending) kube-c3chubft05l5kt4orku0-myclusterto-default-000008a7 162.133.80.23 10.212.234.245 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-00000445 162.133.80.19 10.212.234.233 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-000005d9 162.133.80.26 10.212.234.207 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-00000675 162.133.80.22 10.212.234.217 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-0000078b 162.133.80.30 10.212.234.220 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift $ ibmcloud oc worker ls --cluster c3chubft05l5kt4orku0 OK ID Public IP Private IP Flavor State Status Zone Version kube-c3chubft05l5kt4orku0-myclusterto-default-000001c2 162.133.80.21 10.212.234.234 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-default-000002de 162.133.80.25 10.212.234.243 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-default-000003c8 162.133.80.24 10.212.234.223 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-default-000008a7 162.133.80.23 10.212.234.245 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-00000445 162.133.80.19 10.212.234.233 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-000005d9 162.133.80.26 10.212.234.207 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-00000675 162.133.80.22 10.212.234.217 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift kube-c3chubft05l5kt4orku0-myclusterto-myworke-0000078b 162.133.80.30 10.212.234.220 b3c.4x16.encrypted normal Ready tok02 4.7.16_1522_openshift Red Hat OpenShift on IBM Cloud コスト Red Hat OpenShift on IBM Cloudではマスター部分は見えない状態で、料金表にはワーカーノードの記載のみがあります。 ノード インスタンスタイプ vCPU RAM DISK インスタンス料金 OpenShift料金 マスターノード - - - - - ワーカーノード 4 vCPU 16GB RAM 仮想 - 共有 4 16GB 25GB SSD - $0.44/hour マルチゾーンの場合はMultizone load balancerも必要になります。その他、ストレージやネットワーク利用分も従量課金するのは他のクラウド製品と同様です。 参照: OpenShift料金表 (参照にはIBM Cloudのアカウントでログインが必要) ▼以下はコンソールから確認できる費用 初期設定で円を選んでしまいドルに変える方法がわからず。
Red Hatでソリューションアーキテクトをしている杉本です。 モバイルアプリとバックエンドシステムあるいはマイクロサービスを連携するためのテクノロジーとしてAPIを利用されている企業は多いかと思います。もちろんAPIはそういった用途で使われるものでもありますが、APIの価値はそれにとどまりません。イノベーションの促進、生産性の向上、顧客体験の向上など、APIからビジネス的な価値を抽出するには、APIがどのように利用されるのか、その利用シナリオを設計しておくことが必要となってきます。そのためにはAPIの提供者はAPIを提供していくためのプランを考えておくことも重要です。 この記事は Red Hat Developer Blog の Packaging APIs for consumers with Red Hat 3scale API Management の日本語訳したもので、Red HatのAPI管理製品である 3scale API Management (Red Hat Integrationに含まれます) を使ってAPIの提供プランを設計していくための方法について解説しています。 API管理プラットフォームの主な機能の1つとして、APIのエンドポイントの保護、ビジネス観点での流量制御、価格設定のルールなどに関するポリシーを定義、適用することがあげられます。場合によっては、APIプロバイダーは、同じAPIであっても異なるユーザセグメントに応じた形で、APIを利用できるようにすることが必要になってきます。この記事では、 Red Hat 3scale API Management を使用して、社内外の開発者やパートナー企業など、様々なAPIの利用者に応じて API をパッケージ化する方法について説明します。この記事の最後では 3scale API Management の使い方に関するビデオチュートリアルも紹介しており、この記事で紹介する API パッケージの作成および構成方法を学ぶことができます。 Red Hat 3scale API Management について 3scale API Managementはスケーラブルでハイブリッドクラウドに対応したAPI管理の仕組みで、 Red Hat Integration という製品ポートフォリオの一部となっています。図1は、 3scale API Management の概要図です。 図1: 3scale API Management の概要図 API Manager は、3scale におけるコントロールプレーンです。API Managerは、APIプロバイダーがユーザ、アカウント、ポリシー、サービスを作成するためのインタフェースを提供しています。API Gateway (APIcast)は、データプレーンとしてAPIに対してポリシーを適用します。 APIアクセスに関するポリシー 3scale API Management を使用することで、同じ API に対して異なるポリシーが適用されるようにAPIコンシューマーのセグメントを作成することができます。例えば、1つのAPIエンドポイントを、社内の開発者 (Internal developers)、社外の開発者 (External developers)、パートナー企業 (Strategic partners)という3つの異なるAPIコンシューマーに公開する必要があるとします。表1は、対象となるAPIコンシューマーごとに作成できるパッケージの例を示しています。 表 1: 3種類のAPIコンシューマーに応じた基本的なアプリケーションプラン パッケージ 流量制御 価格設定ルール フィーチャー (Features) Internal developers None Free Internal External developers 10 calls per minute $0.01 per call Basic Strategic partners 1 million calls per day $100 per month Premium 注:社内の開発者の場合、流量制御は「なし」に設定されていますが、DDoS(Distributed Denial of Service)攻撃を防ぐためには、高いレート制限を設定したほうがよいでしょう。また、パートナー企業の流量制御は1日単位で表示されていますが、1分単位で設定した方がよい場合もあります。そうすることで短時間で大きな負荷がシステムにかかることを防ぐことができます。 図2は表1に従ってAPIをパッケージ化したものを示しています。 図2: 社内の開発者、社外の開発者、パートナー企業ごとのAPIをパッケージ化 図2にある流量制御のポリシーにより、APIの呼び出し回数に上限を設けることができます。流量制御はAPIエンドポイントとなるメソッドごとに定義されるので、同一パッケージに含まれるAPIのメソッドごとに異なる制御を適用することが可能になります。また、価格設定のルールを使用することで、APIの呼び出し回数を計測し、それに応じて課金をすることができます。価格設定のルールはAPIメソッドごとに定義され、同一パッケージに含まれるAPIメソッドごとに異なる価格設定のルールを適用することが可能になります。最後に、フィーチャー (Features) ポリシーでは、各パッケージに複数のフィーチャー (Features)を定義することができます。これにより各パッケージにメタデータのタグが追加され、利用可能なフィーチャー (Features)を一意に識別してマッピングできるようになります。 3scale API Managementのパッケージングの考え方は一般的なもので、ほとんどのAPI管理プラットフォームが同様のものをサポートしています。以下のセクションでは、3scale API Managementが提供する様々な種類のプランについて見ていきます。 アプリケーションプラン アプリケーションプランは、APIを利用するためのルール(流量制御、価格、フィーチャー (Features))を定めたものになります。APIに対するアプリケーションからのリクエストはすべてにおいて、アプリケーションプランの制約が適用されます。3scale API Managementで管理されるAPIはすべて、少なくとも1つのアプリケーションプランに紐づけられます。また、同一のAPIを、異なるユーザーグループを対象として複数のプランを定義することも一般的に行われています。図3は、APIとアプリケーションプラン、対象となるAPI利用者 (Audience)、ポリシーとの関係を示しています。 図 3: 1つのAPIに対して複数のアプリケーションプランを定義し、異なるユーザ層に応じて異なるポリシーを適用 APIを呼び出す各アプリケーションは、1つのアプリケーションプランに一意にマッピングされます。アプリケーションからAPIにリクエストが送信されると、3scale API Managementはそのアプリケーションに対して流量制御と価格設定ルールを適用し、APIの使用統計情報を更新します。アプリケーションプランは、3scale API Managementで適用することのできる最も細かい粒度の制御になります。APIごとに1つ以上のアプリケーションプランを使用すれば、APIをパッケージングする上で出てくる要件はほとんど満たすことができます。 アプリケーションプラン以外のプラン 場合によっては、APIや開発者アカウント用に複数のアプリケーションプランのポリシーを定義するために特別なプランを使用する必要があります。デフォルトのプランはすべてのAPIプロバイダーが利用できますが、特別なプランはサービス、アプリケーション、アカウント間の複雑な関係を定義するものであり、明示的に有効にする必要があります。1つまたは複数の特別なプランを使用するかどうかはAPIの設計フェーズの段階で検討すべきであり、予期せぬ結果を避けるためにもその詳細はドキュメント化しておくべきでしょう。次のセクションでは、特別なプランとしてサービスプランとアカウントプランについて紹介します。 訳注:サービスプランとアカウントプランのメニューを有効にするには、3scale の管理コンソールで Audience メニューを選択し、Settings > Usage Rulesを選択した時に表示される ADVANCED PLANS のセクションで、Account Plans と Service Plans のチェックボックスにチェックを入れます。 サービスプラン API利用者がAPIプロダクト (サービス) にサブスクライブして利用の登録をする際に、サービスプランを使用することができます。3scale API ManagementではAPIプロダクトへのサブスクリプションはデフォルトで有効になっており、各サービスへのサブスクリプションでは1つのサービスプランのみが有効になります。サービスプランを利用すると、そのプランの下でサービスを利用するすべてのアプリケーションに対してサービス全体に関わるフィーチャー (Features) とプランを提供することができるようになります。 例えば表2に記載されているサービスプランでは、前節で定義したアプリケーションプランに新しいフィーチャー (Features) が追加されています。 表2: 3つのベースとなるアプリケーションプランに新規フィーチャー (Features) を追加 パッケージ 流量制御 価格設定ルール フィーチャー (Features) Internal developers None Free Internal, developers External developers 10 calls per minute $0.01 per call Basic, developers Strategic partners 1 million calls per day $100 per month Premium, partners アプリケーションプランごとに個別にフィーチャー (Features) を設定していくことも可能ではありますが、それよりはサービスプランで「デフォルト」のフィーチャー (Features) を定義し、アプリケーションプランでは必要に応じてアプリケーションプランで定義したフィーチャー (Features) を有効にする方がよいでしょう。 表3の例はより複雑なシナリオになりますが、APIプロバイダーがパートナー企業向けに2つ以上のアプリケーションプランを提供する必要がある場合の例になります。 表3: 複数のアプリケーションプラン パッケージ 流量制御 価格設定ルール フィーチャー (Features) Strategic Partners Bronze Plan 100,000 calls per day $30 per month Premium, partners, bronze, developers Strategic Partners Silver Plan 500,000 calls per day $60 per month Premium, partners, silver, testing Strategic Partners Gold Plan 1 million calls per day $100 per month Premium, partners, gold, production このアプリケーションプランの設定例では、1つのパートナーアカウントが複数のプランにサインアップできるようにAPIプロバイダーがプランを設定していることになります。例えば、あるパートナー企業は、開発中のアプリケーションにはブロンズプランを利用し、QA段階のアプリケーションにはシルバープランを利用し、そして本番用のアプリケーションにはゴールドプランを利用することができるようになります。そのパートナー企業に対してすべてのアプリケーションプランで標準となる価格を提供するために、表4に示すようなサービスプランを利用することが可能です。 表 4: サービスプラン パッケージ 流量制御 価格設定ルール フィーチャー (Features) Strategic Partners Premium Plan $50 $100 per month Premium, partners, customers 図4は、サービスプランとアプリケーションプランを併用する典型的なシナリオを示しています。 図 4: 3scale API Managementでのサービスプランとアプリケーションプランの組み合わせ例 要約すると、以下のようなユースケースにおいては、カスタムのサービスプランの利用を検討するといいでしょう。 複数のアプリケーションプランが継承して利用可能なカスタムのフィーチャー (Features) が存在するケース 複数のアプリケーションプランで適用可能なカスタムのトライアル期間が同一のAPIサービスに存在するケース 複数のアプリケーションプランで適用可能なセットアップ料金または固定料金が同一のAPIサービスに存在するケース アカウントプラン アカウントプランは、APIに対するサブスクリプションの条件をAPIコンシューマーのアカウントに適用するケースにおいて使用するものになります。アプリケーションプランやサービスプランのようにAPIへのアクセスを管理するのではなく、このプランではアカウントをパッケージ化し、特定のアカウントがアクセスするすべてのAPIに対してアカウントプランを適用します。アカウントプランを作成すると、開発者ポータル内に利用の「階層」が作成され、それぞれのレベルに応じてパートナーが受けるサポート、コンテンツ、その他のサービスのグレードを区別することができるようになります。 例えば、APIプロバイダーが3つの異なるパートナーレベルに応じて、それぞれに表5のようなポリシーを設定したいとします。 表 5: 3つのパートナーレベルに対応したアカウントプランの例 パッケージ 流量制御 価格設定ルール フィーチャー (Features) Strategic Partners Bronze Plan Free $30 per month Premium, partners, bronze, no support Strategic Partners Silver Plan $50 $60 per month Premium, partners, silver, standard support Strategic Partners Gold Plan $100 $100 per month Premium, partners, gold, 24/7 support, dedicated account この例では、APIプロバイダーはアプリケーションプランやサービスプランで課金をするのではなく、固定の月額費用とセットアップのための費用を課金することになります。その場合、アカウントレベルでプランを運用し、そのアカウントに関連するすべてのAPIやアプリケーションに同じポリシーが適用されるようにするのが合理的です。APIプロバイダーは、API利用者のアカウントごとに異なるセットアップ費用やサポートプランを作成することも可能です。図5は、そのようなアカウントプランとAPIの関係を示しています。 図 5: アカウントプランを利用したアカウントに関連するすべてのAPIやアプリケーションへの同じポリシーの適用 3scale API Managementでは、すべてのAPI利用者のアカウントに対してデフォルトのアカウントプランが提供されています。このデフォルトプランにより、APIへのアクセスは個別のサービスプランとアプリケーションプランによって制御されます。アプリケーションの数に関係なく、複数のAPI利用者のアカウントに対してフィーチャー (Features) を定義する必要がある場合には、アカウントプランの導入を検討するとよいでしょう。また、アカウントプランは、サブスクライブされているAPIの数にかかわらず、セットアップ料金、利用料金、あるいはトライアル期間の長さがそのアカウントにおいて固定である場合にも有効です。 動画による解説 3scale API Managementを使用して、さまざまなAPI利用者向けにAPIの提供プランをパッケージ化して組み合わせる方法については、以下の動画もご覧ください。 結論 これまで紹介してきましたように、3scale API Management の機能であるアプリケーションプラン、サービスプラン、アカウントプランを適切に組み合わせて使用することで、APIをパッケージングする上での多くの複雑なシナリオにも対応することが可能になります。この記事では、1つのAPIバックエンドエンドポイントをパッケージングするための戦略について説明しました。また、3scale API Management は APIプロダクト の機能をサポートしており、それを利用して複数のバックエンドAPIをパッケージングして同じポリシーとプランを使用することも可能となっています。今後の記事では、APIプロダクトの機能とユースケースを紹介していく予定です。
みなさんこんにちは。レッドハットの杉村です。Ansible のテクニカルサポートをしています。 今回は HAR (HTTP Archive) について紹介したいと思います。 Ansible Tower は Web アプリケーションなのですが、少々手の込み入った部分がありまして、Web ブラウザとの間でさまざまな通信をおこないます。この2つが代表的なややこしいところです。 Websocket を使った画面のリアルタイム更新 (ジョブテンプレートを実行したときにプレイブックの実行結果を順次画面に表示) 外部認証が設定されている場合の認証シーケンス (Azure AD や SAML など) 何かこの Web UI の動作に問題があるという問い合わせを受けたときには、Web ブラウザと Tower の間でどのような通信をおこなっているのかを詳しく知りたくなることがあります。 近年の Web ブラウザでは HAR (HTTP Archive) を出力できる機能が標準で備わるようになってきまして、通信内容を取得してアーカイブとして保存できるようになっています。 Ansible Tower では Google Chrome と Firefox に対応しています。HAR の取得方法はこちらをご覧ください。Firefox では少々面倒な設定が必要です。 access.redhat.com access.redhat.com 実際にジョブテンプレートを動かしてみたときにキャプチャしてみた例です。 例えば Websocket の設定に問題がある場合には、画面の更新がされなかったり、いつまでも緑色の丸いアイコンが点滅したままだったりということがあります。時系列を追って通信があるのかないのか、通信はエラーとなっているかどうかなど、さまざまな情報が読み取れます。 このキャプチャした後には右クリックして「Save all as HAR with content」を選ぶと、HAR ファイルとしてダウンロードできるようになります。ブラウザの言語を日本語にしている場合には日本語で表示されるかもしれません。 HAR ファイルの実体は JSON ファイルです。ブラウザでのやりとりをすべて記録しますので、パスワードなどを入力した場合でもそのまま記録されます。他の人に渡す場合には注意してください。 { "log": { "version": "1.2", "creator": { "name": "WebInspector", "version": "537.36" }, "pages": [ { "startedDateTime": "2021-06-30T06:52:35.277Z", "id": "page_1", "title": "https://192.168.0.100/", "pageTimings": { "onContentLoad": 748.5830001533031, "onLoad": 925.3330000210553 } } ], "entries": [ { "_initiator": { "type": "script", "stack": { "callFrames": [ { "functionName": "", "scriptId": "6", "url": "https://192.168.0.100/static/js/vendor.3009e31cf8589a0d65a9.js", "lineNumber": 200, "columnNumber": 111758 }, { ... この HAR ファイルを受け取った側では、ブラウザに持ってきて内容を解析します。単にデベロッパーツールにドロップするだけで読むことができます。 どの処理のときにどのような通信をしているのかを製品サポートとしては把握していますので、お問い合わせいただいた状況と通信の流れを比較して、問題箇所のあたりをつけていきます。 リクエストのヘッダやレスポンスコード、レスポンスの内容などを細かく見ていきます。 ここでは正常な例になってしまいましたが、問題があるときには何らかの理由で 404 が返っていたり、500 などのサーバ側のエラーになっていたりすることもあります。 SAML での認証のように複数のサイトにまたがって通信をおこなうようなものでも同様に HAR を取ることができまして、同じように通信の内容を見ることができます。このように認証に関わるものである場合には HAR をいただいても問題の再現をすることは一般に困難ですので、異常な通信が発生しているかどうか、想定する通信の流れになっているかどうかなどの観点で見ることが多いです。 HAR は手元のブラウザだけではなく、分析できるサイトもあります。このようなサービスを使う際には、試すデータについては注意するようにしてください。 toolbox.googleapps.com www.softwareishard.com おわりに 通信内容をキャプチャするためには tcpdump や wireshark などを使うこともあるとは思いますが、Web ブラウザでのやりとりに特化したものとして HAR について紹介してみました。 動きのあるサイトにアクセスしながらこのようなキャプチャを取りますと、現代の Web アプリケーションはさまざまな技術が組み合わさって複雑に構成されていることがよくわかります。 みなさんも試してみてください。 今回の記事は Ansible にはあまり関係はありませんでしたが、Ansible Towerの評価ライセンスリクエストはこちらからご利用いただけますのでご検討ください。 www.redhat.com Happy Automation!
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 前回、デフォルトのAROクラスターを作成してコンソールにログインできるところまで実施しました。OpenShift Container Platform のコマンドラインインターフェースを用いて中身をちょっと確認してみましょう。 OpenShift Container Platform のコマンドラインインターフェース AROクラスター Azure Red Hat OpenShift のネットワークアーキテクチャー Azure Red Hat OpenShift コスト OpenShift Container Platform のコマンドラインインターフェースを利用してのログイン OpenShift上での操作はこのコンソールで行えますが、クラスターの中身を覗いてみるにはOpenShift Container Platform のコマンドラインインターフェース (CLI) であるocコマンドが適しています。ocコマンドは、コンソールにログインした際の右上にある「?」をクリックすると、ocコマンドのダウンロード画面が表示されるので、ご自身の環境にあわせてダウンロードして展開してください。ocコマンド自体はAROでもROSAでもROKSでも共通です。 作成したクラスターにocコマンドでログインするためにはtokenが必要で、コンソールから必要な情報を入手できます。 $ oc login --token=sha256~1n4d1cZh6rtlanz-jE1Mx7gDmBPQ7Q7eS1wUtf1dRgI --server=https://api.csm8323l.eastus.aroapp.io:6443 Logged into "https://api.csm8323l.eastus.aroapp.io:6443" as "kube:admin" using the token provided. You have access to 61 projects, the list has been suppressed. You can list all projects with 'oc projects' Using project "default". AROクラスター az createコマンドで特にパラメーターを指定せずデフォルトでAROクラスターを作成するとマスターノード3台、ワーカーノード3台の構成で作成されます。ARO(4.Xの場合)ではインフラノードは利用できません。 ノード 台数 インスタンスタイプ vCPU RAM DISK マスターノード 3 D8s v3 8 32GB - ワーカーノード 3 D4s v3 4 16GB 128GB クラスターの上限 クラスターあたりのワーカーノード上限:100ノード ノードあたりポッド上限:250 ひとつのクラスターでサポートされるポッドの最大数: 250×100 = 25000 ノードに関してaz create時にパラメーター指定できるのは以下の項目になります。 マスターノードのVMサイズ( Standard_D8s_v3 / Standard_D16s_v3 / Standard_D32s_v3 ) ワーカーノードのVMサイズ ワーカーノードの台数 ワーカーノードのディスクサイズ (GB) VMサイズの詳細については「 Azure Red Hat OpenShift のサポートポリシー 」の「サポートされる仮想マシンのサイズ」に記載があります。 ocコマンドで作成されたクラスターのノードの数やmachinesetを確認してみます。ワーカーノードは米国東部 eastusリージョンの中の3つのAvailability Zone(可用性ゾーン)に1台ずつ配置されていることがわかります。以下のコマンドでは確認できませんが、マスターノードも同様の配置になります。 $ oc whoami kube:admin $ oc get nodes NAME STATUS ROLES AGE VERSION cluster-t6x9s-master-0 Ready master 17h v1.19.0+a5a0987 cluster-t6x9s-master-1 Ready master 17h v1.19.0+a5a0987 cluster-t6x9s-master-2 Ready master 17h v1.19.0+a5a0987 cluster-t6x9s-worker-eastus1-gchqq Ready worker 17h v1.19.0+a5a0987 cluster-t6x9s-worker-eastus2-hvn9r Ready worker 17h v1.19.0+a5a0987 cluster-t6x9s-worker-eastus3-xbbth Ready worker 17h v1.19.0+a5a0987 $ oc get machineset -A NAMESPACE NAME DESIRED CURRENT READY AVAILABLE AGE openshift-machine-api cluster-t6x9s-worker-eastus1 1 1 1 1 17h openshift-machine-api cluster-t6x9s-worker-eastus2 1 1 1 1 17h openshift-machine-api cluster-t6x9s-worker-eastus3 1 1 1 1 17h ノード配置イメージ 更にmachineset cluster-t6x9s-worker-eastus1の内容を見るとレプリカ数やVMの種類やメモリ・使用しているディスクとサイズなどのワーカーノード情報が確認できます。 $ oc get machineset cluster-t6x9s-worker-eastus1 -n openshift-machine-api -o yaml apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: annotations: machine.openshift.io/GPU: "0" machine.openshift.io/memoryMb: "16384" machine.openshift.io/vCPU: "4" creationTimestamp: "2021-06-17T09:09:22Z" generation: 1 labels: machine.openshift.io/cluster-api-cluster: cluster-t6x9s machine.openshift.io/cluster-api-machine-role: worker machine.openshift.io/cluster-api-machine-type: worker 〜〜〜(略)〜〜〜 spec: metadata: {} providerSpec: value: apiVersion: azureproviderconfig.openshift.io/v1beta1 credentialsSecret: name: azure-cloud-credentials namespace: openshift-machine-api image: offer: aro4 publisher: azureopenshift resourceID: "" sku: aro_46 version: 46.82.20201126 kind: AzureMachineProviderSpec location: eastus metadata: creationTimestamp: null networkResourceGroup: aro-rg osDisk: diskSizeGB: 128 managedDisk: storageAccountType: Premium_LRS osType: Linux publicIP: false publicLoadBalancer: cluster-t6x9s resourceGroup: aro-csm8323l subnet: worker-subnet userDataSecret: name: worker-user-data vmSize: Standard_D4s_v3 vnet: aro-vnet zone: "1" status: availableReplicas: 1 fullyLabeledReplicas: 1 observedGeneration: 1 readyReplicas: 1 replicas: 1 Azure Red Hat OpenShift のネットワークアーキテクチャー 以下の図は「 Azure Red Hat OpenShift (ARO) のネットワークの概念 」に掲載されているネットワーク概念図を引用してます。図では4.5とありますが、現在のAROで使用しているOpenShiftのバージョンは4.6です。「Microsoft Azure Red Hat OpenShift (ARO) 其の1」の仮想ネットワーク作成時に「マスターサブネットの サブネットプライベートエンドポイントポリシー無効化 」という設定をしましたが、図の上部にあるAzure Red Hat OpenShift serviceがプライベートリンクを介してマスターノードに対して接続する必要があるためです。 ネットワークアーキテクチャを見ると、AROクラスターではマスターノードやワーカーノードの他にロードバランサーやDNSを利用していることがわかります。AROはフルマネージなのでこれらの構成を自動的にセットアップしてくれますが、セルフマネージで例えばオンプレミス環境に構築するには、様々な考慮点があることがわかると思います。 Azure Red Hat OpenShift コスト AROの利用料金についてです。マスターノードはインスタンス料金のみ、ワーカーノードはインスタンス料金とOpenShift料金がかかります。以下は時間単位の料金ですが1年・3年単位での契約も可能でその場合は時間単位に比べてディスカウントされます。 ノード インスタンスタイプ vCPU RAM DISK インスタンス料金 OpenShift料金 マスターノード D8s v3 8 32GB - $0.44/hour - ワーカーノード D4s v3 4 16GB 128GB $0.22/hour $0.171/hour azure.microsoft.com 本記事を書くために、とりあえずデフォルトのAROクラスターを作ってみた訳ですが、半日くらい使ってこれくらいの料金でした。 内訳をみるとVMやOpenShiftの料金以外に使用したストレージやロードバランサーの費用なども従量課金されるので利用コストを算出する場合は使用するデータ容量なども考慮する必要があります。 余談ですが、Azureを初めて利用する場合、今現在「USD200* のクレジット」が付いてくるので、今回試した内容はまかなえるかもしれません。現時点で今月分の請求書は見れないようなので、来月請求書が来たら結果をお伝えします。 クラスターの削除 半日くらいで上記の料金なので、テストなどが終了したら、クラスター削除をお忘れなく。 クラスターを作成したときの環境変数 LOCATION=eastus # クラスターのロケーション(この例では米国東部) RESOURCEGROUP=aro-rg # クラスターを作成する場所のリソースグループ名。任意の名称でOK。 CLUSTER=cluster # クラスター名。任意の名称でOK。 $ az aro delete --resource-group $RESOURCEGROUP --name $CLUSTER Are you sure you want to perform this operation? (y/n): y
OpenStackやOpenShiftなどのCloud製品を担当しているソリューションアーキテクトの輿水です。 Microsoft Azure Red Hat OpenShiftは Microsoft Azure上で提供されるフルマネージドのRed Hat OpenShiftサービスであり、2019年にリリースされ、2020年4月にOpenShift 4に対応するようになりました。 www.openshift.com 既にAzureをバリバリお使いの方には今更な内容も多いかもしれませんが、今回は初めてAzureを使う前提ですすめます。「 Azure Red Hat OpenShift のドキュメント 」が用意されておりますので、この「チュートリアル」に従って作業を行います。チュートリアルは「既にAzureを使っている」観点で書かれておりAzureの細かい操作にはあまり触れておりません。 私自身はAzureには不慣れのため事前準備でかなりの時間を要しました。 Microsoft Azure Red Hat OpenShiftを使うまでのおおまかな手順は以下の通りです。 事前準備 Azureアカウントの作成 Microsoftアカウントの作成 Microsoft Azureサブスクリプションの購入 クォータ確認と制限引き上げ Red Hat アカウントの作成とプルシークレット取得 Azure CLI(バージョン 2.6.0 以降)のインストール リソースプロバイダー登録 Microsoft.RedHatOpenShift リソース プロバイダー Microsoft.Compute リソース プロバイダー Microsoft.Storage リソース プロバイダー Microsoft.Authorization リソース プロバイダー 仮想ネットワークを作成 リソースグループ作成 仮想ネットワークを作成 マスターノード用の空のサブネットを追加 ワーカーノード用の空のサブネットを追加 マスターサブネットの サブネットプライベートエンドポイントポリシー無効化 クラスターを作成 クラスターに接続 Azureアカウントの作成 licensecounter.jp 提供されている案内にしたがって「Microsoft アカウント」と「Microsoft Azure サブスクリプション」を作成します。とりあえず無料サービスを使えるアカウントを作成してみましたが、サブスクリプションは従量課金制のものが必要でした。 クォータ確認と制限引き上げ OpenShiftを利用するためには、それなりのリソースが必要で、チュートリアルにも「少なくとも 40 コアが必要です」と記載があります。サブスクリプションを購入した時点のデフォルトのリソースではクォータの上限にひっかかってAROクラスターの作成に失敗します。クラスター作成の前にクォータの上限を上げておく必要があります。[サブスクリプション]のページから使用したいサブスクリプションを選択し[設定]の中にある[使用量+クォータ」のページの[引き上げを依頼する]をクリックしてサポートリクエストを作成します。 概要:適当に入力 問題の種類:サービスとサブスクリプションの制限(クォータ) サブスクリプション:サブスクリプション名(ID) クォータの種類:コンピューティング-VM(コア-vCPU)のサブスクリプション上限の増加 詳細を入力をクリックするとクォータの詳細の入力を求められます。 デプロイモデル:リソースマネージャー 場所:リソースを増やしたいリージョンを選択(複数選択可能) ここでどのVMを選べばよいのかしばし迷いました。作成時のエラーメッセージを良く見ると「standardDSv3Family」とあるので「DSv3 Series」にチェックを入れて「新しいvCPUの制限」を50にしてみました。「次へ:確認および作成」をクリックするとサポートリクエストが行われ、しばらくすると(数分〜数十分)クォータが増えているのを確認できます。 ▼クラスター作成時のエラー。standardDSv3Familyが10しかないので、追加で36必要。 $ az aro create --resource-group $RESOURCEGROUP --name $CLUSTER --vnet aro-vnet --master-subnet master-subnet --worker-subnet worker-subnet --pull-secret @/Users/mayumi/Downloads/pull-secret Deployment failed. Correlation ID: 95eacfcc-6802-4653-80b1-8ae18adfb6cd. Resource quota of standardDSv3Family exceeded. Maximum allowed: 10, Current in use: 0, Additional requested: 36. ちなみに日本語ドキュメントには記載がなかったのですが 英文ドキュメント にはクォータチェックコマンドがありました。 ▼クォータチェックコマンド(場所として「eastus」を指定) LOCATION=eastus az vm list-usage -l $LOCATION \ --query "[?contains(name.value, 'standardDSv3Family')]" \ -o table ▼確認結果 CurrentValue Limit LocalName -------------- ------- -------------------------- 0 50 Standard DSv3 Family vCPUs クラスター作成後に、作成時のログを見るとわかりますがマスターノードとワーカーノードはそれぞれ次のインスタンスを使用しています。マスター用に8コア×3台=24コア、ワーカー用に4コア×3台=12コア必要なので「Additional requested: 36」ということですね。 マスターノード:Standard_D8s_v3 ワーカーノード:Standard_D4s_v3 ▼クラスター作成時のログの一部 "masterProfile": { "subnetId": "/subscriptions/f6fd6eb1-0bdf-4f39-b9ec-60c30c1b533a/resourceGroups/aro-rg/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master-subnet", "vmSize": "Standard_D8s_v3" } 〜〜〜(略)〜〜〜 "workerProfiles": [ { "count": 1, "diskSizeGb": 128, "name": "cluster-t6x9s-worker-eastus1", "subnetId": "/subscriptions/f6fd6eb1-0bdf-4f39-b9ec-60c30c1b533a/resourceGroups/aro-rg/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/worker-subnet", "vmSize": "Standard_D4s_v3" Red Hat アカウントの作成とプルシークレット取得 AROクラスター作成時にOpenShift Container Platform の内部レジストリーを利用するためのプルシークレットを指定します。プルシークレットはカスタマーポータルのアカウントと紐付くので、Red Hat アカウントを持っていない場合は作成します。Red Hatアカウントで Red Hat OpenShift Cluster Manager にログインしてプルシークレットを任意のファイル名で作業している端末にダウンロードします。今回は「pull-secret」というファイル名で保存してます。 Azure CLI(バージョン 2.6.0 以降)のインストール Azure CLIをインストールする環境にあわせて Install the Azure CLI | Microsoft Docs に従ってインストールします。Azure CLIインストール後はloginコマンドを実行します。 az login コマンドを実行するとデフォルトブラウザが開いてAzureへのsign inページが表示されるので、Azureアカウント(Microsoftアカウント)でサインインします。 リソースプロバイダー登録 Azureサブスクリプションを複数有している場合は、適切なサブスクリプションIDを指定します。サブスクリプションIDはazure portalの[サブスクリプション]で確認することができます。リソースグループを作成するために、必要なリソースプロバイダーを登録します。 Microsoft.RedHatOpenShift リソース プロバイダー Microsoft.Compute リソース プロバイダー Microsoft.Storage リソース プロバイダー Microsoft.Authorization リソース プロバイダー az account set --subscription <SUBSCRIPTION ID> az provider register -n Microsoft.RedHatOpenShift --wait az provider register -n Microsoft.Compute --wait az provider register -n Microsoft.Storage --wait az provider register -n Microsoft.Authorization --wait 仮想ネットワークを作成 2つの空のサブネットを含む仮想ネットワークを作成します。マスターとワーカーの仮想ネットワーク サブネットは、最小でも /27 にする必要があります。後々の作成コマンドの中で使うパラメーターを環境変数で設定しておきます。「サブネットプライベートエンドポイントポリシー無効化」ってなんだろう?と思いつつとりあえず進みます。 リソースグループ作成 仮想ネットワークを作成:仮想ネットワーク名「aro-vnet」アドレス「10.0.0.0/22」 マスターノード用の空のサブネットを追加:サブネット名「master-subnet」アドレス「10.0.0.0/23」 ワーカーノード用の空のサブネットを追加:サブネット名「worker-subnet」アドレス「10.0.2.0/23」 マスターサブネットのサブネットプライベートエンドポイントポリシー無効化 ▼コマンド LOCATION=eastus # クラスターのロケーション(この例では米国東部) RESOURCEGROUP=aro-rg # クラスターを作成する場所のリソースグループ名。任意の名称でOK。 CLUSTER=cluster # クラスター名。任意の名称でOK。 az group create \ --name $RESOURCEGROUP \ --location $LOCATION az network vnet create \ --resource-group $RESOURCEGROUP \ --name aro-vnet \ --address-prefixes 10.0.0.0/22 az network vnet subnet create \ --resource-group $RESOURCEGROUP \ --vnet-name aro-vnet \ --name master-subnet \ --address-prefixes 10.0.0.0/23 \ --service-endpoints Microsoft.ContainerRegistry az network vnet subnet create \ --resource-group $RESOURCEGROUP \ --vnet-name aro-vnet \ --name worker-subnet \ --address-prefixes 10.0.2.0/23 \ --service-endpoints Microsoft.ContainerRegistry az network vnet subnet update \ --name master-subnet \ --resource-group $RESOURCEGROUP \ --vnet-name aro-vnet \ --disable-private-link-service-network-policies true クラスターを作成 作成したリソースグループや仮想ネットワーク、プルシークレットを指定してAROクラスターを作成します。作成時にワーカーノードの数やマスターノードのVMサイズなど細かい設定も可能なのですが、今回はチュートリアルに従ってデフォルトのまま作成します。作成時間は数十分程度で、事前にクォータの引き上げが終わっていれば問題なく作成されるはずです。 $ az aro create \ --resource-group $RESOURCEGROUP \ --name $CLUSTER \ --vnet aro-vnet \ --master-subnet master-subnet \ --worker-subnet worker-subnet \ --pull-secret @/Users/mayumi/Downloads/pull-secret クラスターに接続 作成されたクラスターの「kubeadmin ユーザー」と「パスワード」を調べます。 $ az aro list-credentials \ > --name $CLUSTER \ > --resource-group $RESOURCEGROUP { "kubeadminPassword": "tug3L-6GUSf-5StUk-PswKh", "kubeadminUsername": "kubeadmin" } 作成されたクラスターのコンソールの URLを調べます。 $ az aro show \ > --name $CLUSTER \ > --resource-group $RESOURCEGROUP \ > --query "consoleProfile.url" -o tsv https://console-openshift-console.apps.csm8323l.eastus.aroapp.io/ 「 https://console-openshift-console.apps.csm8323l.eastus.aroapp.io/ 」にアクセスするとOpenShiftクラスターのコンソール画面が開くので「kubeadmin」とパスワードでログインします。見慣れたいつものOpenShiftコンソールが開けば無事ログイン完了です。 次の回で作成されたAROクラスターの中身を確認してゆきます。ひとまずお疲れさまでした。 APPENDIX ▼ OpenShift YouTube Channel の「Hands-on demo of Azure Red Hat OpenShift」(9分ちょっとの動画です) www.youtube.com ▼仮想ネットワークを作成コマンドと実行結果のログ $ LOCATION=eastus # the location of your cluster $ RESOURCEGROUP=aro-rg # the name of the resource group where you want to create your cluster $ CLUSTER=cluster # the name of you r cluster $ az group create \ > --name $RESOURCEGROUP \ > --location $LOCATION { "id": "/subscriptions/f6fd6eb1-0bdf-4f39-b9ec-60c30c1b533a/resourceGroups/aro-rg", "location": "eastus", "managedBy": null, "name": "aro-rg", "properties": { "provisioningState": "Succeeded" }, "tags": null, "type": "Microsoft.Resources/resourceGroups" } $ az network vnet create \ > --resource-group $RESOURCEGROUP \ > --name aro-vnet \ > --address-prefixes 10.0.0.0/22 { "newVNet": { "addressSpace": { "addressPrefixes": [ "10.0.0.0/22" ] }, "bgpCommunities": null, "ddosProtectionPlan": null, "dhcpOptions": { "dnsServers": [] }, "enableDdosProtection": false, "enableVmProtection": null, "etag": "W/\"9a085cba-2693-4aff-ac38-b1f34df69355\"", "extendedLocation": null, "flowTimeoutInMinutes": null, "id": "/subscriptions/f6fd6eb1-0bdf-4f39-b9ec-60c30c1b533a/resourceGroups/aro-rg/providers/Microsoft.Network/virtualNetworks/aro-vnet", "ipAllocations": null, "location": "eastus", "name": "aro-vnet", "provisioningState": "Succeeded", "resourceGroup": "aro-rg", "resourceGuid": "9c98ffb4-7edb-4abf-856f-7ec6621f7026", "subnets": [], "tags": {}, "type": "Microsoft.Network/virtualNetworks", "virtualNetworkPeerings": [] } } $ az network vnet subnet create \ > --resource-group $RESOURCEGROUP \ > --vnet-name aro-vnet \ > --name master-subnet \ > --address-prefixes 10.0.0.0/23 \ > --service-endpoints Microsoft.ContainerRegistry { "addressPrefix": "10.0.0.0/23", "addressPrefixes": null, "applicationGatewayIpConfigurations": null, "delegations": [], "etag": "W/\"c171d195-7852-45fd-aee2-cb61863010f2\"", "id": "/subscriptions/f6fd6eb1-0bdf-4f39-b9ec-60c30c1b533a/resourceGroups/aro-rg/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master-subnet", "ipAllocations": null, "ipConfigurationProfiles": null, "ipConfigurations": null, "name": "master-subnet", "natGateway": null, "networkSecurityGroup": null, "privateEndpointNetworkPolicies": "Enabled", "privateEndpoints": null, "privateLinkServiceNetworkPolicies": "Enabled", "provisioningState": "Succeeded", "purpose": null, "resourceGroup": "aro-rg", "resourceNavigationLinks": null, "routeTable": null, "serviceAssociationLinks": null, "serviceEndpointPolicies": null, "serviceEndpoints": [ { "locations": [ "*" ], "provisioningState": "Succeeded", "service": "Microsoft.ContainerRegistry" } ], "type": "Microsoft.Network/virtualNetworks/subnets" } $ az network vnet subnet create \ > --resource-group $RESOURCEGROUP \ > --vnet-name aro-vnet \ > --name worker-subnet \ > --address-prefixes 10.0.2.0/23 \ > --service-endpoints Microsoft.ContainerRegistry { "addressPrefix": "10.0.2.0/23", "addressPrefixes": null, "applicationGatewayIpConfigurations": null, "delegations": [], "etag": "W/\"cc544642-0bb6-4d44-b16b-776c4a2a737e\"", "id": "/subscriptions/f6fd6eb1-0bdf-4f39-b9ec-60c30c1b533a/resourceGroups/aro-rg/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/worker-subnet", "ipAllocations": null, "ipConfigurationProfiles": null, "ipConfigurations": null, "name": "worker-subnet", "natGateway": null, "networkSecurityGroup": null, "privateEndpointNetworkPolicies": "Enabled", "privateEndpoints": null, "privateLinkServiceNetworkPolicies": "Enabled", "provisioningState": "Succeeded", "purpose": null, "resourceGroup": "aro-rg", "resourceNavigationLinks": null, "routeTable": null, "serviceAssociationLinks": null, "serviceEndpointPolicies": null, "serviceEndpoints": [ { "locations": [ "*" ], "provisioningState": "Succeeded", "service": "Microsoft.ContainerRegistry" } ], "type": "Microsoft.Network/virtualNetworks/subnets" } $ az network vnet subnet update \ > --name master-subnet \ > --resource-group $RESOURCEGROUP \ > --vnet-name aro-vnet \ > --disable-private-link-service-network-policies true { "addressPrefix": "10.0.0.0/23", "addressPrefixes": null, "applicationGatewayIpConfigurations": null, "delegations": [], "etag": "W/\"350d8005-0e04-4bfb-89f8-9b1dc37ecce2\"", "id": "/subscriptions/f6fd6eb1-0bdf-4f39-b9ec-60c30c1b533a/resourceGroups/aro-rg/providers/Microsoft.Network/virtualNetworks/aro-vnet/subnets/master-subnet", "ipAllocations": null, "ipConfigurationProfiles": null, "ipConfigurations": null, "name": "master-subnet", "natGateway": null, "networkSecurityGroup": null, "privateEndpointNetworkPolicies": "Enabled", "privateEndpoints": null, "privateLinkServiceNetworkPolicies": "Disabled", "provisioningState": "Succeeded", "purpose": null, "resourceGroup": "aro-rg", "resourceNavigationLinks": null, "routeTable": null, "serviceAssociationLinks": null, "serviceEndpointPolicies": null, "serviceEndpoints": [ { "locations": [ "*" ], "provisioningState": "Succeeded", "service": "Microsoft.ContainerRegistry" } ], "type": "Microsoft.Network/virtualNetworks/subnets"
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Shenandoah garbage collection in OpenJDK 16: Concurrent reference processing | Red Hat Developer の翻訳記事です。 OpenJDKにおける Shenandoahガベージコレクション (GC) プロジェクト の主の動機は、ガベージコレクションの停止時間を短縮することでした。参照処理は、伝統的にGCの停止の主な原因の1つでした。この関係はほぼ一次式です。つまり、アプリケーションがより多くの参照を処理すればするほど、ガベージコレクションの停止と遅延への影響は大きくなります。ここで重要なのは「処理」、つまりGCサイクルごとにどれだけの参照を処理する必要があるかということです。決して死なない参照を持つ参照や、参照自体と一緒に死滅する参照は問題ではありません。 私自身、過去に「遅延を気にするなら、ソフト、弱、ファントムの参照やファイナライズを量産しない方がいい」と勧めたことがあります。今回の記事では、過去に参照処理がJavaのガベージコレクションの停止の原因となった理由と、JDK16で参照処理を並行にすることでどのようにその問題を解決したかを紹介したいと思います。 TL;DR: もしあなたのアプリケーションがソフト、弱、ファントムの参照やファイナライズを処理しているなら、Shenandoah GCの並行参照処理を備えたJDK 16は、あなたのアプリケーションの遅延を大幅に改善するかもしれません。 参照の要約 ここでいう参照とは、Javaのオブジェクトである java.lang.ref.Reference 型と、そのサブタイプである SoftReference , WeakReference , PhantomReference , FinalReference を指します(最後の型については後述します)。オブジェクト間の通常の参照は強参照とも呼ばれます。各参照は1つの参照を指します。さまざまな種類の参照の目的は、オブジェクトを参照できるようにすることですが、そのオブジェクトが参照によって再利用されないようにすることはできません。再利用は到達可能性のルールに従っており、大まかに以下のように規定されています(到達可能性が低い順)。 SoftReference : 強参照によって到達できなくなった時点で、その参照を回収されます。回収はさらに他の発見的手法に従います。例えば、通常、ソフト参照は、メモリ圧が高くない限り、回収されないと考えられています。このため、ソフト参照は、メモリに敏感な(キャッシュ)実装に適しています。どちらかというと悪い選択ですが、とはいえ選択です。GCは、メモリが逼迫しているときにソフト参照をクリアします。 WeakReference : この参照は、強参照やソフト参照によって到達できなくなった時点で、回収されます。回収されていない限り、その参照はまだアクセスでき、その時点で再び強く到達可能になります。 FinalReference : これはJDK内部の参照型なので、知らない人も多いでしょう。これは、 Object.finalize() を実装するために使用されます。 finalize() を実装したオブジェクトはすべて FinalReference の参照先となり、対応する ReferenceQueue に登録されます。そのオブジェクトが強、ソフト、または弱参照によって到達できなくなるとすぐに、そのオブジェクトは処理され、その finalize() メソッドが呼び出されます。 PhantomReference : 参照は、強参照、ソフト参照、弱参照、ファイナル参照のいずれによっても到達できなくなった時点で、言い換えれば、適切に到達できなくなった時点で、回収できます。参照元には決してアクセスできません。これは、到達不可能と判断された後に、参照元が誤って復活しないようにするためです。参照元の到達可能性が決定されるとすぐに、到達不可能な参照元はクリア(nullに設定)され、対応する参照オブジェクトは、アプリケーションによる更なる処理のために、それぞれの ReferenceQueue にエンキューされます。ファントム参照は通常、ネイティブメモリやオペレーティングシステムのファイルハンドルなど、GCで処理できないようなリソースを管理するために使用されます。 伝統的な参照の処理方法 JDK16以前のバージョンでは、Shenandoahは前節の到達可能性ルールに忠実な方法で参照を発見し、処理します。 最初に、並行マーキング中のすべての強く到達可能なオブジェクトの到達可能性を決定します。マーキングの波面が、まだマークされた参照先を持たない参照オブジェクトに到達すると(つまり、どこか他の場所から強く到達できないオブジェクト)、すぐにそこで停止し、後の処理のために4つの発見キューの1つに参照をエンキューします。参照タイプごとに1つの発見キューがあります。特殊なケースとして、ソフト参照があります。GCは、発見的手法(例えば、メモリ圧やオブジェクトの年齢)に基づいて、ソフト参照を強参照のように扱うかどうかを決定できます。 次に、並行(強い)マーキングが完了すると同時に、JVMはアプリケーションを停止し、発見キューの処理を開始します: すべての SoftReference オブジェクトが検査されます。参照先が強く到達可能でなければ(つまり、並行マーキングでマークされていれば)、それはクリアされ、その SoftReference は処理キューに入れられます。 すべての WeakReference オブジェクトが検査されます。参照元が強く到達可能でなければ,それはクリアされ,その WeakReference は処理キューに入れられます. すべての FinalReference オブジェクトが検査されます。参照元が強く到達可能でない場合, FinalReference は処理キューに入れられますが,GC が finalize() メソッドを呼び出すことができるように,後でまだ必要とされるので,参照元はまだクリアされません.また,ここで何か特別なことが起こります:他の方法では到達できない参照元から始まって,マーキングが再開され,参照元から見つかったオブジェクトの部分的なグラフがマークされます.これは次のステップで重要なことで、ファイナライズから到達可能な PhantomReference オブジェクトの回収を避けるためです。この追加のマーキングパスは問題となります。なぜなら、JVMが停止している間に行われ、理論的には参照のあるデータセットのサイズによってのみ制限されるためです。言い換えれば、部分的なグラフをファイナライズからマーキングするのに多くの時間を費やす可能性があります。 すべての PhantomReference オブジェクトが検査されます。参照先に到達できない場合(強くもなくファイナライズ対象からも到達できない場合)、参照先はクリアされ、 PhantomReference は処理キューに入れられます。 最後に、処理キューはJavaのLinked Listに追加され、さらに ReferenceQueue の処理が行われます。 これらのステップから、GCの停止時間に対する参照処理の貢献度は、基本的に「処理された参照の数」+「新しくマークされた部分的なグラフのサイズ」に比例することがわかります。 参照処理の停止時間の問題に対処するためには、GCがそれを並行して行う必要があります。参照処理のタスクは,2つのサブタスクに分けられます。すなわち,それぞれの部分的なグラフを含む参照の並行マーキングと、参照とクリアの並行処理です。従来の実装ではこの2つのサブタスクが絡み合っているので、どのようにして解きほぐすかを考えてみましょう。 並行参照マーキング 従来の実装をよく見てみると、到達可能性モデルを単純化できることがわかります。到達可能性のレベルは実際には5つ(強、 ソフト、弱、ファイナル、ファントム)ではなく、2つだけです。参照を分類する基準を別の角度から見てみましょう。 SoftReference オブジェクトは、参照先に強く到達できず、ある発見的手法な条件を満たすと、クリアされたり、エンキューされます。要するに、並行マーキングの前または途中で、 SoftReference を強参照と弱参照のどちらとして扱うかを決めるべきです。 WeakReference オブジェクトは、参照先に強く到達できない場合にクリアされ、エンキューされます。 FinalReference オブジェクトは、参照先に強く到達できない場合にエンキューされます。 PhantomReference は、参照元に強く到達できず、どの FinalReference からも到達できない場合にクリアされ、エンキューされます。 言い換えれば、我々の2つの関連する到達可能性レベルは、強い到達可能性とファイナルな到達可能性です。 従来の実装では、以下のような手順でマーキングにより到達可能性を決定していました。 並行マーキング時に、すべての強く到達可能なオブジェクトのセットを確立する。 ソフト、弱、ファイナルの到達可能性レベルのみを必要とするすべての参照を処理する。 ファイナルになったものからのマーキングを継続する。 この新しい情報を必要とする残りのファントム参照を処理する。 強い到達可能性とファイナルな到達可能性を同時に判定できますか?もちろんできます。しかし、マーキングのビットマップを少し拡張する必要があります。オブジェクトごとに1つのビット(マークされているかどうか)を使う代わりに、2つのビットですべての可能な状態(強い到達可能性、ファイナルな到達可能性、不到達)を表します。この情報があれば、すべてのライブオブジェクトを並行にマークして、強い到達可能性とfinalizable 到達可能性の両方を決定できます。 通常の強い波面でルートからマーキングを開始する。 強い波面が「ソフト参照」に遭遇すると、それを強参照として扱うべきか、弱参照として扱うべきかを(発見的手法に基づいて)決定する。もしソフト参照が強参照として扱われるべきであれば、通常は参照を介してマークし(その部分グラフを強いものとしてマークする)、そうでなければそこで波面を止め、ソフト参照を発見キューにエンキューする。 強い波面が WeakReference や PhantomReference に遭遇した場合、そこで波面を停止し、発見キューに参照をエンキューする。 強い波面が FinalReference に遭遇するとすぐに、その FinalReference を強参照としてマークし、その参照をマークするためにファイナルな波面に切り替えます。そこから到達可能なすべてのオブジェクトは、ファイナルにマークされます。 強い波面が、すでにファイナルとマークされたオブジェクトに遭遇した場合、そのオブジェクトとその部分グラフを強参照にアップグレードします。 これで、すべての到達可能なオブジェクトを並行にマークし、それらが強い到達可能性かファイナルな到達可能性かを判断しました。また、すべての参照オブジェクトを発見キューに入れて、さらに処理を行えました。これで問題の前半は解決しました。私たちは到達できない参照先を消去し、参照オブジェクトをエンキューする必要がまだあります。 並行参照処理 マーキング中に並行に到達可能性を確立しました。これはファイナルマークの停止期間に終了し、その停止期間中に退避のための準備も行います。並行参照処理は、並行退避フェーズの最初に行われます。私たちは2つのことをする必要があります。 発見キューをスキャンし、到達できない参照をすべてクリアする。 ”到達できない”参照オブジェクトを、Java側でのさらなる処理のために、処理キューにエンキューする。 タスクは、ほとんどが見た目通りの単純なものです。発見キューを並行にスキャンし、各参照オブジェクトを検査して、その参照先が到達可能かどうかを確認します。 前述の到達可能性のルールに従います。到達可能であるためには、ソフト参照、弱参照、ファイナル参照は強く到達可能でなければならず、ファントム参照は強く到達可能であるか、またはファイナルに到達可能でなければなりません。参照が到達不可能な場合は、参照元をクリアして、参照を処理キューに入れます。 でも、もしJavaプログラムが、私たちがクリアする前に参照元にアクセスしようとしたらどうでしょう?Javaプログラムは,他の方法では到達できないと判断された参照をまだ見ており,それを復活させてしまいます。これは仕様違反であり,JVMのクラッシュに至るまで様々な問題を引き起こすでしょう。なぜなら、GCはその後、そのオブジェクトを取り戻したり、上書きしたりするからです。そして、Javaプログラムは、開放済のメモリ領域を指しているポインタで終わってしまいます。 この問題を解決するには、 Reference.get() に挿入する特別なバリアが必要です。参照の読み込みであるため、そこにはすでにLRBがあります。 // Reference.get()組込みの疑似コード T Reference_get() { T ref = this.referent; return lrb(ref); } // 参照元に到達できない場合はnullを返しましょう。 // 並行参照処理のためのReference.get()の疑似コード T Reference_get() { T ref = this.referent; if (isUnreachable(ref) { return null; } return lrb(ref); } ほらね。到達できない参照にアクセスしようとすると、常に null を返すようになりました。また、Javaアプリケーションが誤ってオブジェクトを復活させることもありません。 理屈はいいから数字を見せてくれ 並列ガベージコレクションは、実際にはどのくらい悪いのでしょうか? JDK 11で動作する、参照とファイナライズを適度に使用する負荷を見てみましょう。 -Xlog:gc+stats オプションで、いくつかの統計情報を得れます。 Pause Final Mark (N) = 0,278 s (a = 3812 us) (n = 73) (lvls, us = 893, 2891, 3535, 4414, 7707) Finish Queues = 0,020 s (a = 273 us) (n = 73) (lvls, us = 94, 123, 137, 227, 4426) Weak References = 0,214 s (a = 2929 us) (n = 73) (lvls, us = 158, 2109, 2695, 3555, 6072) Process = 0,213 s (a = 2924 us) (n = 73) (lvls, us = 154, 2109, 2695, 3555, 6067) これにより、平均的なファイナルマークの停止時間3.8msのうち、GCは弱参照処理に2.9msを費やし、最悪の場合は7.7msのうち4.4msを費やしていることがわかります。 同じコードをJDK16で見てみましょう。 Pause Final Mark (G) = 0,208 s (a = 2044 us) (n = 102) (lvls, us = 688, 820, 914, 1562, 36975) Pause Final Mark (N) = 0,089 s (a = 870 us) (n = 102) (lvls, us = 500, 625, 705, 764, 4489) Finish Queues = 0,034 s (a = 329 us) (n = 102) (lvls, us = 107, 125, 174, 246, 4072) Update Region States = 0,004 s (a = 38 us) (n = 102) (lvls, us = 26, 34, 38, 41, 52) Manage GC/TLABs = 0,001 s (a = 13 us) (n = 102) (lvls, us = 9, 13, 13, 14, 22) Choose Collection Set = 0,019 s (a = 183 us) (n = 102) (lvls, us = 97, 156, 188, 203, 323) Rebuild Free Set = 0,002 s (a = 23 us) (n = 102) (lvls, us = 13, 20, 23, 25, 29) Initial Evacuation = 0,028 s (a = 274 us) (n = 102) (lvls, us = 133, 207, 227, 260, 3264) E: = 0,247 s (a = 2422 us) (n = 102) (lvls, us = 799, 1875, 2031, 2090, 39583) E: Thread Roots = 0,247 s (a = 2422 us) (n = 102) (lvls, us = 799, 1875, 2031, 2090, 39583) Concurrent Weak References = 0,967 s (a = 9479 us) (n = 102) (lvls, us = 152, 4824, 9473, 11914, 39231) Process = 0,966 s (a = 9470 us) (n = 102) (lvls, us = 148, 4805, 9453, 11914, 39215) [ ファイナルマークの停止期間から参照処理が完全になくなり、停止期間は0.9msに短縮されています。参照処理は現在、「Concurrent Weak References」で個別に表示され、平均で9.5msかかります。しかし、アプリケーションの実行を妨げるものではないので、それほど気にしていません。 この数字は、比較的小規模なワークロードでのものです。文字通り何百万もの弱参照やファイナライザの対象があるお客様の負荷を扱ったことがありますが、当然のことながら、そこでは効果がより劇的に現れています。 まとめ リソースのクリーンアップに弱参照、ソフト参照キャッシュ、ファイナライズ、ファントム参照を使用していて、ガベージコレクションの一時停止や遅延を気にしている場合は、JDK16にアップグレードして、Shenandoah GCを試してみてはいかがでしょうか。