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

TECH PLAY

Red Hat  - Open Innovation Labs

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

全900件

  クラウドインフラ全般を担当しているソリューションアーキテクトの伊藤です。   このRed Hat Engineers Blogでは何度かROSAについてご紹介する記事が投稿されていますが、 ROSAはマネージドサービスなのでWeb公開前提のサービスだとお考えではありませんか? ROSAではデプロイ時のコンフィグレーション次第で、プライベートなOpenShiftをマネージドサービスとして構築して利用することができます。   過去のROSA記事 rheb.hatenablog.com rheb.hatenablog.com   本投稿のコンテンツは以下の通りです    ROSAでデプロイできる2種類の構成 パブリッククラスタ プライベートクラスタ 従来から存在しているプライベートクラスタ AWS PrivateLinkを用いたプライベートクラスタ 既存のVPC、サブネットを用いたROSAクラスタの構築 プライベートクラスタの使い方 まとめ     ROSAでデプロイできる2種類の構成 細かく分類するともっとバリエーションが存在しますが、ROSAは大きく分けて2種類の構成があります。 パブリッククラスタ 最も基本的なROSAクラスタの構成です 作成されるエンドポイント(OpenShiftのWebコンソール、API、アプリケーションの公開URL)はインターネットに向けて露出されています。パスワードやSSOを用いた認証を行いますがWebコンソール、APIエンドポイントを必要な人以外にはアクセスさせないという要件がある場合は別の対応が必要になります。       パブリッククラスタ プライベートクラスタ デフォルトでは作成されるエンドポイント(OpenShiftのWebコンソール、API、アプリケーションの公開URL)がインターネットに向けて公開されていないクラスタになります。 ROSAが一般提供開始になった最初のタイミングでは、ROSAクラスタの運用を支えているレッドハットのSREチームがクラスタにアクセスする経路を確保するため、 IPアドレス制限が掛かったセキュリティグループを適用したELBがインターネットに向けて存在していました。 6月中旬よりAWS Private Linkを用いてNLB経由でセキュアに運用するためのアクセス経路が利用可能になり、ROSAを構成する全てのコンポーネントがインターネットに露出されない様にすることできます。   プライベートクラスタにおいてはデフォルトの状態はレッドハットのSREチームしかアクセス経路が存在しません。後述する何らかの方法でWebコンソール、OpenShift API、Ingressルートへのアクセス経路を確保する必要があります。   従来から存在しているプライベートクラスタ このプライベートクラスタは現在も利用可能な構成です。以下のような構成でクラスタがデプロイされます。       AWS PrivateLinkを用いたプライベートクラスタ AWS PrivateLink を使う場合は、ROSAクラスタをデプロイする前にVPCやサブネットなどのネットワークコンポーネントを先に手動でデプロイしておく必要があります。既存のサブネットを使う事も可能です。 AWS PrivateLinkを使用するにはエンドポイントサービスを作成する必要がありますが、これはROSAのインストーラが自動で作成しますので、利用者はPrivateLinkを使用するためのオプション指定をするだけで利用可能になります。 なお、AWS PrivateLinkを用いたプライベートクラスタを使うには新規でROSAクラスタを作成する必要があり、既に存在しているROSAクラスタの構成変更では実現することはできません。       Privatelink       既存のVPC、サブネットを用いたROSAクラスタの構築 ROSAクラスタをデプロイするときにVPCやサブネットを同時にデプロイするのが既定の動作になります。 しかし既存のVPC、サブネットにデプロイしたいユースケースも存在しています。 パブリッククラスタ、プライベートクラスタどちらの構成においても、既存VPC、サブネットにROSAクラスタをデプロイすることは可能です。 この場合、以下のURLを参考に以下のAWSコンポーネントをROSAクラスタをデプロイするより前にデプロイします。 4.8. AWS のクラスターの既存 VPC へのインストール 4.7 | Red Hat Customer Portal インターネットゲートウェイ NAT ゲートウェイ サブネット ルートテーブル VPC VPC DHCP オプション VPC エンドポイント     プライベートクラスタの使い方 プライベートクラスタですが、デフォルトではプライベートなクラスタとして存在しているため限られた空間で使用されるOpenShiftというユースケースもありますが、 AWSのいくつかのサービスと連携することで、既にAWS上で構築したシステムとの連携、一部機能の外部公開といったユースケースに対応します。 ・他リソースとの接続したい ・特定のアプリケーションだけを外部公開したい   まず、プライベートクラスタにおいては、Webコンソール、OpenShift API、Ingressルートに対してのアクセス経路を確保する必要があります。 以下のURLにあるように、プライベートなアクセス経路を確立します。 access.redhat.com   次にすべてのアプリケーションをプライベートな環境で利用する場合においては不要ですが、特定のアプリケーションを外部公開したい要件が発生した場合には以下のような対応を取ることができます。   access.redhat.com このコマンドでIngressを追加することができます。ルートセレクターを使う事でRouteオブジェクトを作成するときにどのIngressで公開するか選択させることができます。 プライベートクラスタであっても、この追加のIngress作成コマンドでプライベートオプションを付けなければ、インターネットに露出されたサブネットに追加のIngressを作成させることが可能です。   まとめ  今回の構成はシンプルに表現するためすべてシングルアベイラビリティゾーンで構成しました。 ROSAはマネージドサービスでありながら、オプションでインターネットに露出されないセキュアなプライベートクラスタを構成することができます。 AWSのVPC PeeringやVPC VPN、DXを用いた企業内ネットワークとの繋ぎこみを行う事で、OpenShiftの大部分の運用はレッドハットが行い、アプリケーション開発に専念する環境を手に入れることができます。    
Red Hatのソリューションアーキテクトの井上たかひろです。 Red Hat にはクラウドネイティブアプリの開発に役立つ、ソフトウェアのラインナップが充実していることをご存知ですか? ここでは、それらのソフトウェア [Red Hat Application Services] に関する注目ニュースを、各製品技術に特化したソリューションアーキテクトが、ご紹介します。 今回は 2021/7月号となります。 想定読者 エンタープライズアーキテクト アプリケーション開発者 システムの提案をするSIerの方 特集1: Red Hat OpenShift Platform 4 ハンズオンワークショップ紹介 〜Dev Track編〜 Red Hat では「 Container and Cloud Native Roadshow 」というイベントを四半期単位で開催しています。 Red Hat OpenShift 4のハンズオンワークショップを通して、コンテナを利用したクラウドネイティブなアプリケーションの開発やインフラストラクチャの運用管理に関する基礎知識やプラクティスを学ぶイベントです。 内容は開発者向けトラックと運用管理者向けトラックに分かれており、今回は開発者者向けトラック全4つについてご紹介いたします。 rheb.hatenablog.com rheb.hatenablog.com rheb.hatenablog.com rheb.hatenablog.com 特集2: Red Hatによる Managed Kafka のサービス 〜 OpenShiftベースでハイブリッドクラウド環境に対応したイベントストリーミングプラットフォーム 〜 をご紹介! 今年のRed Hat Summitでは新しいマネージド・クラウドサービスとしてRed Hat OpenShift Streams for Apache Kafkaがアナウンスされました。これは、フルマネージドおよびホステッド型の Kafkaサービスとして提供され、開発者はKafkaの環境構築・運用に関する煩わしさを気にすることなく、ストリーム処理をするアプリケーションを迅速に作り上げることに集中できるサービスになります。 以下の紹介資料では、その概要と無料でできるトライアルの始め方についても紹介しています。 speakerdeck.com 特集3: 業務ルールをビジュアル化してそのまま実装!DMNをVSCodeで作成してみよう Red Hat Decision Manager / Process Automation Manager は、VSCode 拡張機能のサポートが提供され、Visual Studio Code (VSCode) で BPMN モデル、 DMN モデル、及びテストシナリオを可視化し、設計できるようになりました。 今回は、VSCode で DMNモデルを用いて簡単なルールを作成して動かしてみたいと思います。 rheb.hatenablog.com 好評開催中!クラウドネイティブアプリ開発関連のWebinar全6回 Cloud Nativeを見据えたアプリケーションアーキテクチャとレガシーモダナイゼーション コンテナ時代の開発ツールチェインと開発プロセスのベストプラクティス クラウド/コンテナを前提とした時代のアプリケーション実行環境の選択 マイクロサービス/サーバーレス実践入門 これからのシステム連携を実現するデジタル基盤とアプローチ Cloud Nativeなデータパイプラインの作り方とオープンハイブリッドクラウドへの展開 各回とも、オンデマンドで視聴出来ます。(お名前とメールアドレス等の登録のみで視聴可能です) 下記リンクよりぜひご登録ください。 www.redhat.com 直近GAになった製品群 最近リリースとなった Application Services 製品群のリストをご紹介します。 見逃している製品が無いか、是非一度ご確認ください。 Red Hat Data Grid 8.2 Red Hat Process Automation Manager 7.11 Red Hat Decision Manager 7.11
Red Hatのソリューションアーキテクトの井上たかひろです。 「Module3:サービスメッシュによるアプリの制御とセキュリティ」に続いて「Dev Module4:イベント駆動型サーバーレス編」についてざっくり紹介いたします。 Cloud Native アプリケーションの作成し、Kafkaクラスターを作成し、イベントドリブンサービスに改修し、さらにはサーバレス化します。最後はTekton を使った CI/CD Pipelines の作成を実践します。 使うソフトウェア:Red Hat AMQ Streams(Apache Kafka ),Red Hat Runtimes(Quarkus, Spring BootNode.js), Red Hat Data Grid, Knative, Tektonなど Module3:イベント駆動型サーバーレス編 ハンズオンで実施する項目 Cloud Native アプリケーションの作成 イベントドリブンサービスの作成(Kafkaクラスターの作成) サーバレスの作成 Tekton を使った CI/CD Pipelines の作成 Cloud Native アプリケーションの作成 5 つのマイクロサービスを OpenShift上で開発します。 これらの アプリケーションは PostgreSQL や MongoDB 等の複数のデータソースとのトランザクションを持ちます。 特に、 Quarkus Extensions を使ってデータソースを簡単に設定する方法を学びます。 最終的には、エンドユーザー(顧客)の満足度を高めるために、 Cache(Data Grid)サーバー と統合することで、 ショッピングカートサービスの データトランザクションパフォーマンス を最適化します。 作ろうとしているアプリのアーキテクチャは以下になります。 ガイドを見ながら、やっていきます。 利用したことないプログラミング言語やフレームワークでも、ガイドに詳細に手順があるので、大丈夫です。 3つのアプリケーションができた状態です。赤枠の部分は、QuarkusとCache(Data Grid)のアプリの部分になります。 5つのアプリケーションができた状態です。 次では、一部をAMQ Streams(Apache Kafka ベース)を使って、イベントドリブンな処理を追加していきます。 イベントドリブンサービスの作成(Kafkaクラスターの作成) ここでは、ショッピングカートと注文の実装を変更し、イベントドリブン/リアクティブアプリケーションとして決済サービスを追加します。 これらの アプリケーションでは、メッセージング/ストリーミングのバックボーンとして、AMQ Streams(Apache Kafka ベース)を使用します。 AMQ Streams は、OpenShift 上で Apache Kafka を簡単に構築できます Kafka クラスターを作成します。 カタログからKafka クラスターを選びます。 Kafka クラスタを定義するYAMLエディタが表示されます。デフォルトのままCreateボタンを押すと、クラスターが作成できます。 次に、Kafka Topicを作成します。 カタログからKafka Topicを選びます。 KafkaTopicを定義する YAML エディタに入ります。 Topic名を orders に変更し、下部にあるCreateボタンを押すと、Topicが作成できます。 出来上がるとこのようになります。KafkaTopicはもう1つ追加しています。 簡単にKafkaが構築できてしまいます。 あとはガイドを見ながら、アプリケーションの修正や追加をやっていきます。 サーバレスの作成 ここでは、さきほど作成した決済サービスをサーバレスにします。 まずは、さきほど作成した決済サービスをネイティブ実行ファイルにして、高速起動、低メモリ消費にします。 これは GraalVM を使って実現しています。先行コンパイル、積極的なデッドコードの排除、起動ロジックの多くをビルド時に移動させるネイティブバイナリとしての最適なパッケージ化などにより、起動時間と必要なメモリリソースを大幅に削減します。 起動してみると、0.012secで12ミリ秒で起動していることがわかります。 __ ____ __ _____ ___ __ ____ ______ --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ INFO [io.quarkus] (main) getting-started 1.0-SNAPSHOT native (powered by Quarkus xx.xx.xx) started in 0.012s. <xxx> INFO [io.quarkus] (main) Profile prod activated. INFO [io.quarkus] (main) Installed features: [cdi, resteasy] ガイドを見ながら、Kafkaのメッセージからネイティブ実行ファイルにしたアプリをサーバレスで起動する設定をやっていきます。 以下が完成した状態です。 Kafkaのメッセージを入れると、サーバレスでアプリが実行されます。また、 一定期間経過するとPodが停止します。 Tekton を使った CI/CD Pipelines の作成 サーバレスをやって結構満足になるのですが、まだ終わっていません。 最後に、 CI/CD Pipelines の作成をやります。 OpenShift Pipelines は、Cloud Native なCI/CDソリューションで、Tekton をベースにしたスタンダードな CI/CD パイプラインの定義ができ、 複数のプラットフォーム(Kubernetes、サーバーレス、VM など)におけるデプロイの自動化を可能にします。 ガイドを見ながら、パイプランを作っていきます。 実際にパイプランを実行した様子は以下になります。 手順の類はだいぶ端折っているので、短く感じるかもしれませんが、実際にハンズオンを行うとかなりのボリュームです。このモジュールが一番ボリュームがあります ガイドに従って進めればAMQ Strems(Apache Kafka)の構築、Java(Quarkus)からのネイテイブアプリケーションの作成、Knativeでのサーバレースアプリ、Tekton を使った CI/CD Pipelinesの作成の流れが体験できます。 ワークショップにご興味があればご連絡ください。
Red Hatのソリューションアーキテクトの井上たかひろです。 「Module2:デバッグ、モニタリング、継続的デリバリー」に続いて「Module3:サービスメッシュによるアプリの制御とセキュリティ」についてざっくり紹介いたします。 OpenShift Service Meshにアプリをデプロイして可視化したり、A/Bテスト、フォルトインジェクション、サーキットブレーカーを試したり、サービスメッシュでのシングルサインオンを実践します。 使うソフトウェア:Service Mesh(istio), Kiali, Jaeger, Prometheus, Grafana, Red Hat Single -Sign on(Keycloak)など Module3:サービスメッシュによるアプリの制御とセキュリティ ハンズオンで実施する項目 サービスメッシュを使ってみて、可視化してみる サービスメッシュの色々な機能を使ってみる(A/Bテスト、フォルトインジェクション、サーキットブレーカー) サービスメッシュでシングルサインオンをやってみる サービスメッシュを使ってみて、可視化してみる サービスメッシュはオープンソースプロジェクトの Istio をベースにしています。 これにより、サービスメッシュ全体のモニタリングと運用制御が可能になります。サービスのネットワーク全体で統一されたトラフィック管理 、可視化、ポリシー運用、セキュリティなどを提供します。 Kiali, Jaeger, Prometheus, Grafanaを使って、色々可視化していきます。 ガイドを見ながら、サンプルアプリケーションをインストールと、サービスメッシュの設定をやっていきます。 アプリはIstioのサンプル・​アプリケーションのBookinfoを使用します。 OpenShift上にデプロイした後のトポロジービューは以下のようになっています。 Kialiを試してみます。サービスメッシュの設定の表示、トラフィックの流れと健全性の監視、トレースの分析を行うことができます。 サービスグラフでは、各マイクロサービスが、それらを通過するリクエストによって接続されたグラフが見れます。 アプリケーションのメトリクスも確認できます。インバウンドのリクエストについて表示しています。 分散トレースを確認してみます。Kiali は Jaeger との統合機能も備えています。 詳細なトレースとスパン(1つのサービス内の処理時間)のデータが確認できます。 この情報を使用して、アプリケーションの問題を迅速に発見することができます。 Prometheus によるメトリクスのクエリーも試してみます。 Prometheus は定期的にアプリケーションをスクレイプしてメトリクスを取得します 。 Istio 用の Prometheus アドオンは、Istio Mixer エンドポイントに対して、メトリクスを収集するように予め設定されています。 アプリケーションの各サービスが何回アクセスされたかのカウントとともに一覧表示しています。 また、 Graph タブをクリックすることで、結果を時間経過とともにグラフ化することもできます。 必要なデータを抽出するために実行できるクエリは、非常に多くものがありますので、詳細は Prometheusドキュメント を参照してください。 とはいえ、アプリケーションでサービスや数が増えてくると、このスタイルのメトリクスには少し大変かもしれません。 Grafana は、Istio データプレーンから抽出された多くの利用可能な Prometheus メトリクスを視覚的に表現し、問題を迅速に発見するために便利です。 ここでは、Istio Service メトリクスからbookinfoアプリのproductpage サービスの詳細なメトリクスを表示しています。 サービスメッシュの色々な機能を使ってみる(A/Bテスト、フォルトインジェクション、サーキットブレーカー) サービスメッシュでは、A/Bテスト、カナリアロールアウト、パーセンテージベーストなどを実現することができます。 ここでは、サーキットブレーカー、タイムアウトやリトライなどの障害系も試していきます。 ガイドを見ながら、A/Bテストを試していきます。 jasonさんでログインするとreviewsサービスのv2 に、それ以外は reviewsサービスのv3にリクエストを送信するようにします。 yamlの該当箇所の抜粋です。 - match: - headers: end-user: exact: jason route: - destination: host: reviews subset: v2 - route: - destination: host: reviews subset: v3 ハンズオンで、実際にアプリを動かしてみると、jasonさんでログインするとreviewsサービスのv2に、それ以外は reviewsサービスのv3にリクエストが送信されます。 このルーティング機能で、テスト、ブルー/グリーンデプロイメント、ダークローンチなどにおいて、異なるサービスインスタンスにトラフィックを選択的に送信することができます。 ガイドを見ながら、フォルトインジェクションを試していきます。 inventoryサービスへのリクエストの 50% にフォルト( HTTPのステータスコード500)を注入しています。 http: - fault: abort: httpStatus: 500 percentage: value: 50 route: - destination: host: inventory port: number: 8080 リクエストを何度か送信し、kialiで確認すると、リクエストの50%がエラーになっていることがわかります。 ガイドを見ながら、サーキットブレーカーを試していきます。 inventoryサービスへのリクエストを最大接続数を 1 に、最大保留中のリクエストを 1 を注入しています。 spec: host: inventory trafficPolicy: connectionPool: tcp: maxConnections: 1 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 1 リクエストを纏めて送信し、kialiで確認すると、サーキットブレーカーが HTTP 503 エラーを発生させているのがわかります。 このような流れでサービスメッシュのA/Bテスト、フォルトインジェクション、サーキットブレーカーを試してみました。 アプリ側に手を入れずに、出来るのが大きな魅力です。 サービスメッシュでシングルサインオンをやってみる 認証を有効します。ここでは、Red Hat Runtimesの一部であるRed Hat Single Sign On(keycloakベース)を利用してJSON Web Tokens (JWT)でやっていきます。 Red Hat Single Sign Onを簡単に試せるカタログがあるので、そこからインストールしていきます。 1〜2分で、Red Hat Single Sign Onが利用できるようなります。 ガイドを見ながら、Single Sign Onの設定を実施していきます。 JWTと OIDC 認証フローを使って、認証ポリシーを作成します。 apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: calalog-req-auth namespace: user1-catalog spec: selector: matchLabels: deploymentconfig: catalog-springboot jwtRules: - issuer: http://sso-user1-rhsso.apps.cluster-xxxxx.opentlc.com/auth/realms/istio jwksUri: http://sso-user1-rhsso.apps.cluster-xxxxopentlc.com/auth/realms/istio/protocol/openid-connect/certs --- apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: catalog-auth-policy namespace: user1-catalog spec: selector: matchLabels: deploymentconfig: catalog-springboot rules: - from: - source: requestPrincipals: ["*"] curlを使って、RH-SSOから出力されたAuthorizationトークンを取得し、そのトークンでアプリにアクセスできることを確認します。 このような流れでシングルサインを試すことができます。 手順の類はだいぶ端折っているので、短く感じるかもしれませんが、実際にハンズオンを行うとそこそこのボリュームです。 ガイドに従って進めればサービスメッシュの可視化、リクエストルーティング、サービスメッシュでの認証の流れが理解できると思います。 ワークショップにご興味があればご連絡ください。
Red Hatのソリューションアーキテクトの井上たかひろです。 「Module1:既存アプリケーションの最適化」に続いて「Module2:デバッグ、モニタリング、継続的デリバリー」についてざっくり紹介いたします。 Module2では、OpenShift上でCodeReady Workspacesを使用したJavaアプリのデバッグやアプリのパフォーマンスモニタリング、 Jenkinsを使用したCI/CDパイプラインの作成を行います。 使うソフトウェア:JBoss, Jenkins, Prometheus, Grafanaなど Module2:デバッグ、モニタリング、継続的デリバリー ハンズオンで実施する項目 Jenkinsを使用してCI/CDパイプラインを作成し、マイクロサービスアプリケーションへのアップデートのデプロイを自動化 CodeReady Workspacesを使用したJavaアプリのデバッグ(ライブコーディング) Jaegarm, Prometheus, Grafanaなどを使用してアプリケーションのパフォーマンスを計測し、モニタリング Jenkinsを使用してCI/CDパイプラインを作成し、マイクロサービスアプリケーションへのアップデートのデプロイを自動化 OpenShift上で開発環境と本番環境のプロジェクトを作成し、OpenShiftのパイプラインビルドを使って、開発環境から本番環境にデプロイします。 下図が構成になります。開発環境がcoolstore-devで、本番環境がcoolstore-podになります。 ガイドを見ながら、CodeReady Workspacesのターミナルウィンドウから「oc project coolstore-dev」等を叩いたりしながら、開発環境と本番環境を作っていきます。 開発環境は以下のようになります。 次に、Jenkinsを入れます。これはカタログからおじさんを選べば入ります。 ここから、Jenkins自動化エンジンで実行するための Jenkins pipelineを作っていきます。 OpenShiftではJenkins pipelines をプラットフォームに統合することでCI/CD Pipelinesの構築を簡素化してます。 また、OpenShift 4からはKubernetes向けのCI/CDの進化形である Tekton Pipelines も導入されています(Module4で実施します) パイプラインを使って、開発環境イメージを本番環境へデプロイしてみます。 2分ぐらいで終わります。下図のようにパイプラインの進行状況を見ることができます。 アプリケーションがデプロイされて実行できることも確認できます。 次に、パイプラインへ承認ステップを追加してみます。(yamlを編集しています) ガイドを見ながら、Webアプリをちょこっと修正して、もう一度パイプラインを実行します。 黄色でパイプランが承認待ちになっているのがわかります。 上記の「Input Required 」のリンクを押すとJenkisの画面に移動します。 ログインすると、承認画面になり、承認すると本番環境へのデプロイが開始されます。 このような流れでOpenShift上でCI/CDを体験できます。 JenkinsやTektonのパイプランがOpenShiftに統合されているので構築が容易です。 CodeReady Workspacesを使用したJavaアプリのデバッグ(ライブコーディング) 開発モードのQuarkusでは、バックグラウンドコンパイルで「ライブコーディング」ができます。 Javaファイルやリソースファイルを変更して更新すると、変更が自動で反映されます。(pom.xmlなども) この機能を使うことで、デバックしながら修正をかけたりすることで、開発効率が向上します。 これは、体験して頂くのが一番いいかなと思います。 ここでは、CodeReady Workspacesのデバック画面をご紹介します。 ブラウザ上のIDEでも、デスクトップアプリと遜色がありません。 CodeReady Workspacesは、ブラウザベースの利用なので、開発者メンバへの配布が容易です。 ある程度の規模のプロジェクトでは、開発環境の準備、プロジェクトの共有設定などの手間がかかり、さらには環境差異でハマることもあるかと思います。 CodeReady Workspacesでは、そのような問題の解決策についても活用できます。 Jaegarm, Prometheus, Grafanaなどを使用してアプリケーションのパフォーマンスを計測し、モニタリング クラウドネイティブ・アプリケーションもしくはマイクロサービスが増えてくると、アプリの数が増えるので、モニタリングが複雑になりがちです。 ここでは、JaegarやPrometheusなどを使って、アプリケーションの監視を実践します。 なお、Module3では、Service Meshを使っての可視化や監視を実践します。 ガイドを見ながら、Jaegarのデプロイ、Quarkusアプリにトレース拡張の設定などをやっていきます。 アプリを実行した際のトレースを見ていきます。 アプリが1つなので、効果があまり感じられないかも知れないですが、アプリが増えてくると、応答性能のボトルネックなどの把握が容易になります。 ガイドを見ながら、PrometheusとGrafanaのデプロイ、Quarkusアプリに quarkus-micrometer(メトリクス)の設定などをやっていきます。 Prometheusで何回アプリが実行されたかを表示しています。 Grafanaで何回アプリが実行されたかとJavaVMのメモリを表示するダッシュボードになります。 このような流れでアプリケーションのパフォーマンスを計測し、モニタリングを体験できます。 Module3では、Service Meshでサイドカーを使うことで、アプリに手を入れずにモニタリングを実現します。 手順の類はだいぶ端折っているので、短く感じるかもしれませんが、実際にハンズオンを行うとそこそこのボリュームです。 ガイドに従って進めればプロジェクト作成、ビルド&デプロイなどの一連の流れとOpenShiftでのアプリ開発やマイクロサービスのモニタリングの体験・理解ができると思います。 ワークショップにご興味があればご連絡ください。
Red Hatのソリューションアーキテクトの井上たかひろです。 Red Hat では「 Container and Cloud Native Roadshow 」というイベントを四半期単位で開催しています。 Red Hat OpenShift 4のハンズオンワークショップを通して、コンテナを利用したクラウドネイティブなアプリケーションの開発やインフラストラクチャの運用管理に関する基礎知識やプラクティスを学ぶイベントです。 内容は開発者向けトラックと運用管理者向けトラックに分かれており、今回は開発者者向けトラックについてご紹介いたします。 運用管理者向けトラックについては、下記の記事をご参照ください。 Red Hat OpenShift Platform 4 ハンズオンワークショップ紹介 〜Ops基礎編〜 - 赤帽エンジニアブログ Red Hat OpenShift Platform 4 ハンズオンワークショップ紹介 〜オプション編〜 - 赤帽エンジニアブログ Red Hat OpenShift Platform 4 ハンズオンワークショップ紹介 〜オプション編〜 - 赤帽エンジニアブログ 開発者者向けトラックのポイント 参加者はブラウザが使える環境のみでOK!!(WebブラウザベースのIDE CodeReady Workspacesで実施) ガイドに従って自分のペースで実施 オンライン・ワークショップ(お家からのご参加も可能です) Etherpadなどの共有ツールでインストラクターと質疑応答可能 ラボの環境は以下のようになります。(左側がガイド、右側がCodeReady Workspaces) 開発者向けトラックは、以下の4つのモジュールで構成されており、好きなものから始めることができます。 Module1:既存アプリケーションの最適化 Red Hat Application Migration Toolkit を使用して、とあるJ2EEサーバのアプリをJBossに移行し、モノリスからマイクロサービスにします。 使うソフトウェア:Red Hat Application Migration Toolkit, JBoss Enterprise Application Server, Red Hat Runtimes(Spring Boot, Node.js, Quarkus)など Module2:デバッグ、モニタリング、継続的デリバリー CodeReady Workspacesを使用したJavaアプリのデバッグやアプリのパフォーマンスモニタリング、Jenkinsを使用したCI/CDパイプラインの作成 使うソフトウェア:Jenkins, Prometheus, Grafanaなど Module3:サービスメッシュによるアプリの制御とセキュリティ OpenShift Service Mesh(istio)にアプリをデプロイして可視化したり、A/Bテスト、サーキットブレーキングや分散トレースの実践、Service MeshとSSOを統合します。 使うソフトウェア:Service Mesh(istio), Kiali, Jaeger, Prometheus, Grafana, Red Hat Single -Sign on(Keycloak)など Module4:イベント駆動型サーバーレス編 アプリをイベント駆動型アーキテクチャに移行します。また、分散キャッシュ(Data Grid)や
サーバーレス(Knative)も使います。 使うソフトウェア:Red Hat AMQ Streams(Apache Kafka ),Red Hat Runtimes(Quarkus, Spring BootNode.js), Red Hat Data Grid, Knative, Tektonなど Module1:既存アプリケーションの最適化のざっくり紹介 ハンズオンで実施する項目 Red Hat Application Migration Toolkit を使用して、他のJ2EEサーバのアプリをJBossに移行します。 JBossに移行したアプリをOpenShiftにデプロイします。 モノリス(JBossに移行したアプリ)を分解してQuarkusとSpring Bootを使用してマイクロサービスに分割し、Cloud Nativeアプリケーションにします。 Red Hat Application Migration Toolkit を使用して、J2EEサーバのアプリをJBossに移行 Migration Toolkit for Applications (MTA) は、拡張可能でカスタマイズ可能なルールベースのツールで、Java アプリケーションの移行を簡素化します。 MTAはハンズオンで使うCodeReady Workspacesに組み込まれています。 それを使って、他のJ2EEサーバのアプリをMTAの分析します。 操作イメージは、以下になります。 分析が終わると以下のようなレポートが出力されます。ここでは22箇所でJavaのソースファイルや定義ファイルで修正が必要と出ています。 ダッシュボードでの確認や問題箇所の詳細も見れます。 ガイドを見ながら、JBoss(標準のJ2EE)にアプリを修正していきます。 MTAは、適宜レポートを出すことで、移行の進捗具合がわかるのもいいところです。 JBossに移行したアプリをOpenShiftにデプロイ アプリの修正が終わったら、OpenShift上でデプロイします。 JBossやPostgreSQLのインストールはテンプレートからサクッと出来ます。 下図は、テンプレートを選択している画面になります。 ガイドを見ながら、postgresqlとの接続やアプリのデプロイを行っていきます。 下図は、OpenShift上にデプロイした直後の状態です。デプロイの状態などがOpenShift上で見ながらできるので楽しいです。 アプリをWebブラウザで見るとこんな感じです。 ここまできて、ショッピングアプリをイジっていたのがわかります。 モノリス(JBossに移行したアプリ)を分解してQuarkusとSpring Bootを使用してマイクロサービスに分割 Quarkusを使って、在庫アプリを追加します。 下図の左側がJBossアプリで、右下がQuarkusで作る在庫アプリです。 ガイドを見ながら、DB含めて作っていきます。 何気にMicroProfile Healthを使って、ヘルスチェック機能も入れて、障害を発生させたりもやります。 ヘルスチェックのプローブで一定回数失敗した場合、OpenShift がポッドとコンテナを入れ替えて復旧してくれます。 下図は、障害を発生させた状態です。 次に、Spring Bootを使って、カタログアプリを追加します。 なお、Spring Bootは、Red Hat Runtimesに含まれています。 下図の右上がSpring Bootで作るカタログアプリです。 これまたガイドを見ながら、DB含めて作っていきます。 Quarkus(在庫アプリ)-> Spring Boot(カタログアプリ)間でのオリジン間リソース共有 (CORS) ベースも作ります。 最後はできあがった、アプリを色々叩いてみます。 手順の類はだいぶ端折っているので、短く感じるかもしれませんが、実際にハンズオンを行うとそこそこのボリュームです。 ガイドに従って進めればプロジェクト作成、ビルド&デプロイなどの一連の流れとOpenShiftでのアプリ開発を体験・理解ができると思います。 ワークショップにご興味があればご連絡ください。
レッドハットのソリューションアーキテクトの森です。 Red Hat Decision Manager / Process Automation Manager は、VSCode 拡張機能のサポートが提供され、 Visual Studio Code (VSCode) で BPMN モデル、 DMN モデル、及びテストシナリオを可視化し、設計できるようになりました。 今回は、VSCode で DMNモデルを用いて簡単なルールを作成して動かしてみたいと思います。 必要なセット VSCode Red Hat Business Automation Bundle (VSCode拡張機能) KIE Server (RHDM/PAM に 含まれている、REST API でルールを実行できるサーバアプリ) Java 11 Maven Git DMN について DMN (Decision Model and Notation) は、業務的意思決定を説明してモデル化するための表記法です。OMG (Object Management Group)によって定義されています。 業務ルールを整理し定義する際に、DMNを使うことで、要件定義・設計・実装における認識の齟齬を低減し、開発効率と品質を向上することが期待されます。 DMNの基本については、こちらも合わせてご覧いただければと思います。 qiita.com ルールの要件 今回は、ドライバーが交通違反をした時の罰則の判断(罰金・減点)と、免許停止の判断をサンプルとして作ってみます。 違反の内容が 速度超過 で、超過速度が 10km/h 以上、30km/h 未満の場合、違反点数 3、罰金 500 違反の内容が 速度超過 で、超過速度が 30km/h 以上の場合、違反点数 7、罰金 1000 違反の内容が 駐車違反の場合、違反点数 1、罰金 100 違反の内容が 飲酒運転の場合、違反点数 5、罰金 1000 違反点数が 累計 20 以上の場合、免許停止となる プロジェクトの作成 まずは Maven アーキタイプを使用して、新しいプロジェクトを作成します。 mvn archetype:generate \ -DarchetypeGroupId=org.kie \ -DarchetypeArtifactId=kie-kjar-archetype \ -DarchetypeVersion=7.48.0.Final-redhat-00004 ※ Red Hat Maven Repository( https://maven.repository.redhat.com/ga/ ) を ~/.m2/settings.xml に設定しておく必要があります。 設定例: 1) 以下の XML を settings.xml ファイルの <profiles> 要素へコピーします。 <!-- Configure the JBoss Enterprise Maven repository --> <profile> <id>jboss-enterprise-maven-repository</id> <repositories> <repository> <id>jboss-enterprise-maven-repository</id> <url>https://maven.repository.redhat.com/ga/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>jboss-enterprise-maven-repository</id> <url>https://maven.repository.redhat.com/ga/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> 2) 以下の XML を settings.xml ファイルの <activeProfiles> 要素へコピーします。 <activeProfile>jboss-enterprise-maven-repository</activeProfile> ※ 7.48.0.Final-redhat-00004 は RHDM 7.10 に対応しています。 デフォルトのGAV(group:artifact:version)を使用してプロジェクトを作成するかを聞かれますので、一旦そのままとしておきます。 DNM ファイルの作成 次に、 src/main/resource 配下のフォルダに、 traffic-violation.dmn というファイルを作成します。 ファイルを作成すると、以下のような DMN エディタが開きます。 DMN エディタが開いたら、入力データノードを2つキャンバスに配置し、それぞれ、 ドライバー情報 , 違反情報 と名前を変更します。 (名前の変更はノードをダブルクリックするか、右側のプロパティパネルの Name を変更します) 続いて、罰則の内容を判断するデシジョンと、免許停止かどうかを判断するデシジョンを作成します。 デシジョンノードを2つキャンバスに配置し、それぞれ、 罰則 , 免許停止 と名前を変更します。 入力データノード 違反情報 から、デシジョンノード 罰則 へ、情報要件を用いて接続をします。 以下のように各ノードを接続して下さい。 データ構造の定義 次に、DMN で使用するデータ構造について定義をします。 エディタの上部メニューからデータタイプを選択し、中央の Add a custom Data Type をクリックして下さい。 Name: ドライバー情報 タイプ: Structure と入力し、右側のチェックマークをクリックすると、 ドライバー情報 という名前の Structure型 のデータが定義されます。 以下の表に従って、3つの Structure型 を含むデータを定義して下さい。 Name タイプ ドライバー情報 Structure 点数 number Name タイプ 違反情報 Structure タイプ string 制限速度 number 違反時速度 number Name タイプ 罰則情報 Structure 罰金 number 点数 number 下記のように定義ができていればOKです。 エディターに戻り、各ノードのデータタイプを定義していきます。 入力データノード ドライバー情報 をクリックし、右側のプロパティパネルの情報アイテムで、データタイプを ドライバー情報 に設定して下さい。 他のノードも、下記の表に従って設定をします。 ノード データタイプ ドライバー情報 ドライバー情報 違反情報 違反情報 罰則 罰則情報 免許停止 string デシジョンの作成 2つのデシジョン、 罰則 , 免許停止 について、ルールの定義を行っていきます。 デシジョンノード 罰則 を選択し、 編集 をクリックしてデシジョンエディタを開きます。 式の選択をクリックし、デシジョンテーブルを選択します。 条件列として、情報要件で接続した入力データノードの内容が、またアクション列として、デシジョンのデータタイプの内容が既に設定されています。 違反情報.違反時速度 の列を、 違反情報.違反時速度 - 違反情報.制限速度 に修正をして、 違反情報.制限速度 の列を削除します。 次に、罰則のルールの要件に従って条件とアクションを作成していきます。 下記の表のように各行を設定をして下さい。 [10..30) は、10以上、30未満(10 ≦ x < 30)という意味になります。 続いて、デシジョンノード 免許停止 を選択し、 編集 をクリックしてデシジョンエディタを開きます。 式の選択をクリックし、コンテキストを選択します。 ContextEntry-1 をクリックして、Name に 累計点数 、データタイプ に number と入力します。 累計点数 の右の式の選択をクリックして文字式を選択し、 ドライバー情報.点数 + 罰則.点数 と入力します。 次に、 <result> の右の式の選択をクリックして文字式を選択し、 if 累計点数 >= 20 then "はい" else "いいえ" と入力します。 こちらの記述式については、FEEL(Friendly Enough Expression Language) という言語で、簡単に計算等のロジックを記述できます。 DMN における FEEL の詳細は OMG の Decision Model and Notation specification を参照してみてください。 以上で、DMN の作成については完了です! シナリオテスト VSCode拡張機能を使って、DMN のテストシナリオを作成することができます。 テストシナリオを使用するには、プロジェクトに以下の依存関係を追加する必要があります。 junit:junit org.drools:drools-scenario-simulation-backend org.drools:drools-scenario-simulation-api org.drools については、 org.kie と バージョンを合わせる必要があります。 今回のサンプルでは、RHDM 7.10 を使用しており、 7.48.0.Final-redhat-00004 となります。 プロジェクトの pom.xml を開き、次の依存関係を追加して下さい。 <dependencies> <dependency> <groupId>org.drools</groupId> <artifactId>drools-scenario-simulation-api</artifactId> <version>${version.org.kie}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-scenario-simulation-backend</artifactId> <version>${version.org.kie}</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> 次に、 src/test/java 配下のフォルダに、 testscenario というフォルダを作成します。 そのフォルダの中に、下記の内容で ScenarioJunitActivatorTest.java というファイルを作成しておくことで、Junit と一緒にテストシナリオを実行できるようになります。 package testscenario; @org.junit.runner.RunWith(org.drools.scenariosimulation.backend.runner.ScenarioJunitActivator.class) public class ScenarioJunitActivatorTest { } それでは、テストシナリオを作成していきます。 src/test/resources 配下のフォルダに、 org/kie/businessapp というフォルダを作成し、その中に Violation_Scenarios.scesim というファイルを作成します。 テストシナリオのエディタが開きますので、下記を指定します。 Source type: DMN Choose a valid DMN asset from the list: traffic-violation.dmn 入力と期待値については、列が既に設定されています。 いくつかのパターンで、シナリオを作成してみて下さい。 テストを実行するには、ターミナルから mvn test を実行するか、 ScenarioJunitActivatorTest.java ファイルを右クリックして、 Run java を選択します。 テストの結果が問題なければ、 mvn clean install を実行して、プロジェクトがコンパイルできることを確認します。 KIE Server の準備 ルールを実行するための KIE Server を準備します。 Red Hat Customer Portal にログインして、下記ファイルをダウンロードします。 jboss-eap-7.3.0.zip rhdm-7.10.0-kie-server-ee8.zip 1) jboss-eap-7.3.0.zip を解凍します。解凍したファイルを格納したフォルダを、仮に $EAP_HOME としておきます。 2) rhdm-7.10.0-kie-server-ee8.zip を $EAP_HOME フォルダ内に解凍します。 3) $EAP_HOME/SecurityPolicy フォルダ配下のファイルを、 $EAP_HOME/bin/ に移動します。 mv SecurityPolicy/* $EAP_HOME/jboss-eap-7.3/bin/ 4) $EAP_HOME/kie-server.war フォルダを、 $EAP_HOME/standalone/deployments/ に移動します。 mv kie-server.war/ $EAP_HOME/jboss-eap-7.3/standalone/deployments/ 5) kie-server.war を自動デプロイするための .dodeploy ファイルを作成します。 touch $EAP_HOME/jboss-eap-7.3/standalone/deployments/kie-server.war.dodeploy 6) KIE Server REST 機能にアクセス可能なユーザを追加します。パスワードは 8 文字以上で、数字と、英数字以外の文字をそれぞれ 1 文字以上使用する必要があります。ただし & の文字は使用できません。 <USERNAME> と <PASSWORD> 書き換えて実行してください。 $EAP_HOME/jboss-eap-7.3/bin/add-user.sh -a --user <USERNAME> --password <PASSWORD> --role kie-server,admin 7) EAP を起動します。 $EAP_HOME/jboss-eap-7.3/bin/standalone.sh -c standalone-full.xml 8) 設定したユーザとパスワードを使用して、ブラウザから http://localhost:8080/kie-server/services/rest/server にアクセスできればOKです。 デプロイ 今回は、KIE Server REST API を使用して、DMN を含むプロジェクトをデプロイしていきます。 まず、ブラウザで KIE Server REST API を開きます。(デフォルトの設定でローカル上に起動している場合は、 http://localhost:8080/kie-server/docs ) KIE Server and KIE containers のメニューから、 [PUT] /server/containers/{containerId} を開き、 Try it out をクリックします。 下記の内容を入力します。 containerId: mybusinessapp body: { "container-id": "mybusinessapp", "release-id": { "group-id": "org.kie.businessapp", "artifact-id": "mybusinessapp", "version": "1.0" } } Parameter content type: application/json Execute をクリックし、下記のような実行結果が出力されればOKです。 それでは、KIEServer へデプロイした DMN を実行してみましょう。 DMN models のメニューから、 [POST] /server/containers/{containerId}/dmn を開き、 Try it out をクリックします。 containerId: mybusinessapp body: { "dmn-context": { "ドライバー情報": { "点数": 17 }, "違反情報": { "タイプ": "速度超過", "制限速度": 100, "違反時速度": 120 } } } Parameter content type: application/json Response content type: application/json 正しく実行できていれば、下記のような出力が帰ってくるはずです。 いかがでしたでしょうか? VSCode拡張機能 を使うことで、BPMN モデル、DMN モデル の開発がしやすくなっていると思います。 ぜひ試してみて下さい。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Shenandoah GC in JDK 14, Part 2: Concurrent roots and class unloading | Red Hat Developer の翻訳記事です。 JDK 14のShenandoah GCに関するこのミニシリーズの第1部では、 自己修復バリア を取り上げました。この記事では、並行ルート処理と並行クラスアンロードについて説明しています。これらは、GC作業を停止フェーズから並行フェーズに移行することで、GCの停止時間を短縮することを目的としています。 並行ルート処理 いったん並行マーキングが行われると、Shenandoahはマーキングを完了し、退避の準備をする必要があります。 これらは論理的に独立した2つの作業ですが、"Final Mark "という紛らわしい名前の1つの停止期間の下で実行されます。 Shenandoahでは退避自体は並行ですが、停止しなければならないことがいくつかあります。これらは以下の通りです。 弱くないルート(例えば、スレッドスタックや強力なJNIハンドルなど)の事前退避と更新。 弱いルート(例えば、文字列テーブルや弱いJNIハンドル)の事前退避とクリーンアップ。 クラスのアンロード。 この作業は停止しながら行われるため、停止時間に影響します。この停止時間を最小限にするために、これらのタスクのほとんどを並行に実行したいと考えています。この方法は、サイズが制限されていないGCルートの場合に特に重要です。 停止中にすべてのGCルートを事前に退避させて更新する必要があるのは、強い不変性を確保するためです。読み出されたり、保存されたりするオブジェクトは、必ずto-spaceにある必要があります。 ここで、重要な注意点があります。GCルートからオブジェクトをロードする際には、ロードリファレンスバリアを採用していません。そのため、アプリケーションはオブジェクトの正しいコピーを見る必要があります。そして、停止期間からアンブロックする前に、退避と更新を実行しなければなりません。この問題には、比較的簡単な解決策があります。それは、関連するGCルートからのロードが「ネイティブLRB」と呼ばれるロードリファレンスバリア(LRB)によって保護されるようにし、それらのルートの実際の更新を並行フェーズに移すことです。 しかし、いわゆる「弱い」ルートは特別です。マーキング中に、あるGCルートにはもう到達できないと判断することがあります。この問題の例として、弱いJNIハンドルがあります。弱いJNIハンドルが(final mark中に)死んだと宣言されたら、それを誤って復活させてはいけません。例えば、死んだと思われるオブジェクトへの参照をヒープに挿入して戻してはいけません。 したがって、(他のすべてのルートと同様に)到達可能な弱いルートを事前に退避させて更新するだけでなく、到達不可能な弱いルートをクリーンアップして、アプリケーションがそれらに触れて復活することができないようにしなければなりません。 このクリーンアップを並行フェーズに移行するには、ネイティブLRBに余分な作業が必要となります。ネイティブLRBは、弱いルートが到達可能かどうかを(マーキングビットマップの指示に従って)確認します。弱いルートに到達できない場合、ネイティブLRBは単にNULLを返します。このようにして、JVMの他の部分に対して、ハンドルがすでにクリーンになっていることを装います。このプロセスにより、既に到達不可能なオブジェクトを誤って再び到達可能にしてしまうことがありません。 擬似的に、ネイティブのLRBは次のようになります。 T native_LRB(T* addr) { T obj = *addr; // GCルートからロード if (is_reachable(obj)) { return LRB(obj); } else { return NULL ; } } 並行クラスアンローディング final markの停止時のもう一つの大きな項目はクラスアンロードでした。クラスのアンロードはかつてはクラスローダを多用するアプリケーションにとって重要でした。この状況は通常、アプリケーションサーバやその他の大規模なアプリケーション(IDEなど)に当てはまります。しかし、クラスのアンローディングは、無名クラス(それぞれが独自のクラスローダーを持つ)やラムダ(無名クラスに似ている)を使用する場合にも関係してきます。 クラスのアンロードは複雑な手順を必要とします。クラス(というかクラスローダ)が到達可能かどうかをコードが判断する必要があります。このチェックは並行マーキングの際にすでに行われています。すべてのオブジェクト(クラスローダを含む)の到達可能性が確立されると、すべての到達不可能なクラスローダとそのクラス、および補助データ構造がリンク解除され、クリーンアップされる必要があります。それらのクラスに属するコンパイルされたコードもクリーンにする必要があります。 ほとんどの部分で、Shenandoahの実装は、JDK 13でZGC開発者が行った作業に基づいています。この実装では、上述のネイティブバリアが必要です。それに加えて、いわゆる "nmethod entry barrier "も必要です。 通常、停止期間中には、コンパイル済みのすべてのメソッドに埋め込まれているすべての参照を事前に退避させ、更新する必要があります。理想的には、現在実行されている(つまり、スタック上のフレームで到達可能な)メソッドの参照のみを事前退避/更新し、他のメソッドは並行して処理することです。この方法を実現するためには、スレッドがメソッドの実行を開始するというシナリオを処理する必要があります。 nmethod バリアの考え方は、メソッドが呼び出されるたびに実行されるというものです。実行がメソッドに引き渡される前に、GCバリアは特定のことを行うために呼び出されます。Shenandoahでは、メソッドのコードをスキャンして埋め込みオブジェクト(定数)を探し、それらを退避させて更新することを意味します。これは、上記の強力な不変性を確保するためです。生きているnmethodは、最後のマークの停止ですぐ使えるようにされ、並行フェーズ中のGCスレッドか、nmethodが実行されようとしているときにJavaスレッドによって解除されます。 並行のルート処理と並行のクラスアンロードの正味の利点は、final markの停止が短くなることです。そのため、アプリケーションがクラスローダーやJNIハンドルを多用している場合でも、全体的な遅延が改善されます。
※ 2024年11月27日: 2024年10月下旬から11月上旬にかけて行われたSimple Content Accessの強制を踏まえて更新しました Red Hatの森若です。今日は Simple Content Accessについてご紹介します。 Simple Content Accessとは Red Hat Enterprise Linuxではシステムを利用する際に、subscription-managerコマンドで、システムの登録と、所有しているサブスクリプションとの対応づけを行う必要がありました。 2024年10月に廃止された今までの仕組みでは、サブスクリプションで提供される「pool」とシステムを対応づける(attach)必要があり、複数種類の製品を持っている場合には必要なpoolがわかりにくいため手間がかかるなどの難点がありました。 Simple Content Accessはこのattachを廃止して「アカウントが対応する製品を1つ以上保有しているか」だけを考慮するように動作を変更するものです。利用の簡単さと引き換えに、サブスクリプションの必要本数を管理・強制する機能が失われます。利用する側からみると「システムの登録だけでyumが使えるようになるが、利用本数や台数は別途管理する必要がある」ものです。 2024年10月下旬から、全てのアカウントに対してSimple Content Accessが強制され、従来の手順を使う方法がなくなりました。現在システムとサブスクリプションを対応づける方法は存在しません。 従来のしくみ(enforcing mode)とSimple Content Accessの比較 Subscription Watch (Subscription Service) 利用本数や台数を別途管理する必要があると書きましたが、これを補完するための仕組みが Subscription Watch(Subscription Service) です。アカウントについて、Red Hat Subscription ManagementやRed Hat Satellite、Red Hat Insightsへ登録されたシステム情報を基に、システム数を報告します。 Subscription WatchはRed Hatが推奨するサブスクリプション本数の管理方法ですが、少なくとも現状ではHigh AvailabilityやELSなどのアドオン製品は管理できません。さらにRed Hat直接の製品とOEM製品の区別もできません。これらの管理が必要な場合は、別途何らかの方法で管理をおこなう必要があります。 Subscription Watch は、RHELシステムが定期的にRed Hatのサーバへ接続することを前提としています。一定期間(1ヶ月)以上接続がない場合は利用数から除外されます。インターネットへの接続が不可能なシステムについては、Red Hat Satelliteを利用するか、Subscription Watchでの管理をあきらめ別途台帳などで管理する必要があります。 使いはじめる 2024年10月末に全アカウントでSimple Content Accessの利用が強制されているため、特に有効化などの作業は不要です。 無効にする方法はありません。 RHEL側での操作は簡単です。 subscription-manager register としてシステムを登録するだけで yum install zsh のようにyumが利用できるようになります。 既に登録されているシステムについてSCA移行後にはじめてyumなどを利用する場合、 subscription-manager refresh として証明書を更新します。 必要なリポジトリが有効になっていない場合は、 subscription-manager repos --available でリポジトリ名一覧を確認し、 subscription-manager repos --enable=ansible-2.9-for-rhel-8-x86_64-rpms のようにして有効化します。 今持っているサブスクリプションの一覧はHybrid Cloud Console内の Subscription Services >> Subscriptions Inventory で確認します。 サブスクリプションの利用状況を確認するためには、Hybrid Cloud Console内の Subscription Services >> Subscriptions Usage >> RHEL を表示します。 過去30日分の利用状況と過去30日以内にアクセスがあったシステムの一覧が表示されます。 subscription-manager register で登録したあと反映までに最大24時間かかります。 すぐに一覧へ反映させたい場合には insights-client --register のようにしてRed Hat Insightsへ登録します。Red Hat Insightsへの登録はすぐに反映されます。 subscription watch 各システムで subscription-manager syspurpose を使って SLA(Premium, Standard)や用途(Production, Development/Test, Disaster Recovery)を指定しておくと分類毎の表示がおこなわれます。 FAQ Q: Simple Content Accessの利用は必須ですか? A: はい、必須です。2024年10月下旬に全ユーザに強制的に適用されています。 Q: Simple Content Accessを無効化して従来の仕組みを利用することはできますか? A: いいえ、できません。2024年10月で従来の仕組みは提供が終了し、廃止されています。 Q: Simple Content Access以前の手順そのままでエラーが出ないよう抑止することはできますか? A: いいえ、できません。サブスクリプションの割り当ては失敗します。RHEL 10では関連する subscription-manager のサブコマンド(attachなど)が削除される予定です。 Q: Simple Content Accessの環境で、サブスクリプションを明示的にシステムに対応づけることはできますか? A: いいえ、できません。サブスクリプションとシステムの対応づけは自動的に行われないだけでなく、指定することができません。アカウント全体での数量管理のみが行われます。 Q: 本数をチェックしないということは使い放題なのですか? A: いいえ、Simple Content Accessを利用しても 契約は全く変わりません ので、利用しているシステムの構成や数に従って適切な数のサブスクリプションを購入する必要があります。超過利用についてお問いあわせを行う場合がございます。 Q: Simple Content Accessではvirt-whoは不要になりますか? A: いいえ。Red Hat Enterprise Linux for Virtual Datacenterなどのゲスト数無制限のサブスクリプションを利用する場合、virt-whoが必要であることは変わりません。 Subscription Watchの表示に反映されるほか、システムインベントリにHypervisorのエントリが表示されるようになります。 Q: どうやってサブスクリプション本数を管理しますか? Subscription Watchの利用は必須ですか? A: Red HatではSubscription Watch を利用することを推奨していますが、利用は必須ではありません。台帳や運用管理ツールの機能などで管理しても問題ありません。 Q: 登録したシステムがSubscription Watchに表示されません A1: 30日以上Red Hatへの通信をおこなっていないシステムは表示されません。 rhsmcertd が動作していないシステムやインターネット接続ができないシステムは、この条件により表示されず、グラフにも反映されない場合があります。 A2: subscription-manager で登録したシステムが Subscription Watchに表示されるまで最大24時間ほどかかります。 A3: A1, A2にあてはまらないが表示されない場合、Red Hat側の移行作業での問題の可能性があります。 テクニカルサポートへお問いあわせください。 Q: 利用手順は変わりますか? A: はい。Simple Content Accessを有効にすると subscription-manager attach の操作が不要になり、行うと失敗するようになるため、関連する手順が変わります。 具体的には以下が失敗します。 subscription-manager attach のような直接アタッチする操作 subscription-manager register --auto-attach のような登録と同時に自動アタッチする操作 サブスクリプションの割当てを含むアクティベーションキーによるシステム登録 Q: Subscription Watchを利用するときに、システムをRed Hat InsightsとRed Hat Subscription Managementの両方に登録するとサブスクリプションを2倍消費しますか? A: いいえ。システムの重複は適切に排除されます。 Q: アタッチが不要なのはわかりましたがアタッチしようとするとどうなりますか A: 以下のようなエラーメッセージが出力されます。 英語: # subscription-manager attach --auto Ignoring request to auto-attach. It is disabled for org "6062722" because of the content access mode setting. 日本語: # subscription-manager attach --auto 自動割り当ての要求を無視します。これは、コンテンツアクセスモードの設定により、組織 "6062722" に対して無効となっています。 参考リンク access.redhat.com access.redhat.com access.redhat.com
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Shenandoah GC in JDK 14, Part 1: Self-fixing barriers | Red Hat Developer の翻訳記事です。 次期 JDK 14 に搭載される Shenandoahガベージコレクタ (以下GC)の開発では、大幅な改良が行われています。ここで取り上げている最初のもの(自己修正バリア)は、局所的な遅延を減らすことを目的としています。これらはバリアの中間のパスとスローパスに費やされます。2つ目は、並行ルート処理と並行クラスアンロードを取り上げます。 自己修正バリア 自己修正バリアの改善は、JDK 13に搭載された ロードリファレンスバリア をベースにしています。ロードリファレンスバリアは、参照フィールドや配列要素からのロード後、ロードされたオブジェクトがアプリケーションコードの残りの部分に与えられる前に用いられます。疑似コードでは、バリアは次のようになります。 T load_reference_barrier(T* addr) { T obj = *addr; // Fast-path: スレッドローカルフラグへのアクセス if (!is_gc_active()) return obj; // Mid-path 1: 小さなビットマップへのアクセス(領域ごとのバイト、数KB程度?) if (!is_in_collection_set(obj)) return obj; // Mid-path 2: オブジェクト(ヒープ全体?)内の転送ポインタにアクセスします。 T fwd = resolve_forwardee(obj); if (obj != fwd) return fwd; // Slow-path: ランタイムへの呼び出し、転送されていないオブジェクトのロケーションごとに1回 return load_reference_barrier_slowpath(obj); } その結果、GCがアクティブなときにオブジェクトをロードすると、そのオブジェクトがコレクションセットへの参照である場合、オブジェクトの解決に突入し、実際の避難を行うためにランタイムの遅い部分に突入する可能性があります。可能性としては、オブジェクトはGC自体によって退避され、バリアはMid-path 2のチェックでこれを発見し、そこでこのメソッドから戻るでしょう。最悪の場合、バリアはランタイムを呼び出して全ての作業を行います。 この話のパフォーマンスに敏感な部分は、GCサイクルが終わってGCが関心のある参照を更新するまでの間、再配置されたオブジェクトをMid-path 2でずっとチェックしてしまうことです。ホットループでアクセスを行うと、GCが実行されている間、常にバリアの奥まで達することになります。また、Mid-path 2チェックは幅広く遠くまで届くため、コストがかかります。 自己修正バリアの考え方は、オブジェクトを解決し、転送されたコピーを発見したときに、その場で位置を更新できるというものです。コレクションセットにないオブジェクトのコピーへの参照を更新しているので、次のバリアの呼び出しでは、Mid-path 1でこのメソッドから戻ることになります。 このような変更を加えたバリアは、このようになっています。 T load_reference_barrier(T* addr) { T obj = *addr; // Fast-path: スレッドローカルフラグへのアクセス if (!is_gc_active()) return obj; // Mid-path 1: 小さなビットマップへのアクセス(領域ごとのバイト、数KB程度?) if (!is_in_collection_set(obj)) return obj; // Mid-path 2: オブジェクト(ヒープ全体?)内の転送ポインタにアクセスします。 T fwd = resolve_forwardee(obj); if (obj != fwd) { // ここでアップデートが可能 CAS(addr, fwd, obj); return fwd; } // Slow-path: ランタイムへの呼び出し、転送されていないオブジェクトのロケーションごとに1回 fwd = load_reference_barrier_slowpath(obj); // ここでアップデートが可能 CAS(addr, fwd, obj); return fwd; } 言い換えれば、 転送されるもの を取得したらすぐにスローパスに入り、新しいコピーへの参照を元のアドレスに置き換えて戻せるのです。これは、上書きしてはいけない別のJavaスレッドによる同じフィールドの更新が競合する可能性を避けるために、比較とセットの操作を使って行います。 ここで、Mid-path 2のチェックに失敗するのは、更新されていない場所ごとに1回だけであることに注意してください。このチェックに失敗しても、それを修正すれば、二度とバリアのダークな部分を訪れることはありません。このことを念頭に置いて、更新全体をスローパス自体に移動させることで、バリアを単純化できます。 T load_reference_barrier(T* addr) { T obj = *addr; // Fast-path: スレッドローカルフラグへのアクセス if (!is_gc_active()) return obj; // Mid-path 1: 小さなビットマップへのアクセス(領域ごとのバイト、数KB程度?) if (!is_in_collection_set(obj)) return obj; // Slow-path: ランタイムへの呼び出し、更新されていないロケーションごとに1回 return load_reference_barrier_slowpath(obj, addr); // アップデートは実際にここで } これで、よりシンプルなミューテータ側のバリアができました。 複雑なのは、スローパスにaddrを渡すことで、インタプリタ、C1、C2をいじらなければなりません。それが、最初からこの方法で行われない理由です。また、注意点にも注目してください。更新されていないロケーションの場合、以前はMid-path 2のチェックから早めに終了していました。現在は、それらのためにランタイムに入ります。この動作はコード上では悪く見えますが、ホットオブジェクトに対して多くのMid-path 2チェックを行っています。これらのオブジェクトはコレクションセットに含まれていますが、ロケーションごとに1回、修正のためのランタイムに入るよりもはるかにコストがかかります。 また、これらの仕組みにより、後に行われる参照の更新フェーズにおいて、GCワーカーが行うべき作業が少なくなります。 まとめ JDK 14のShenandoah GCリリースに搭載されている自己修正バリアが、バリアの中間のパスとスローパスの局所的な遅延の低減にどのように役立つか、お分かりいただけたかと思います。 次回の記事 では、並行ルート処理と並行クラスアンロードを取り上げます。これらの機能を合わせると、GC作業を停止フェーズから並行フェーズに移行することで、GCの一時停止時間を短縮し、その結果、全体的な遅延を削減できます。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Shenandoah GC in JDK 13, Part 3: Architectures and operating systems | Red Hat Developer の翻訳記事です。 このシリーズでは、 JDK 13 で登場する Shenandoah GC の新展開を取り上げてきました。 パート1 では、ロードリファレンスバリアに変更されたことを見て、 パート2 では、オブジェクトごとに余分なワードをなくす計画を見てきました。今回は、Shenandoah GCが扱うことになる新しいアーキテクチャと新しいOSについて見ていきます。 Solaris BellSoft は 最近変更を加えました 。これにより、ShenandoahはSolaris上でビルド・実行できるようになりました。Shenandoah自体には、オペレーティングシステム固有のコードはありません。したがって、新しいオペレーティングシステムへの移植は比較的簡単です。今回のケースでは、Solarisコンパイラを満足させるために、列挙型の末尾のカンマを削除するなど、一連の修正を行っただけです。 特に問題となったのは、Solaris 10です。Solaris 10は、Solarisの後続バージョンや他のすべての関連オペレーティングシステムが行っているのとは逆に、ユーザーメモリを上位のアドレス範囲にマッピングします(たとえば、0x7fではなく0xff...で始まるアドレス)。他のOSでは、アドレス空間の上半分をカーネルメモリに割り当てています。 このアプローチは、Shenandoahのタスクキューの最適化と相反するものでした。これは、上位アドレス範囲に予備のスペースがあると仮定してポインタをエンコードします。これはビルド時のフラグで無効にするのに十分なほど簡単で、 Aleksey Shipilevがそれを行いました 。 その修正 は、Shenandoah GCの完全に内部的なものであり、ヒープ内のJava参照の表現には影響しません。この変更により、ShenandoahはSolaris 10以降でビルド・実行できるようになりました(もっと古い可能性もありますが、試していません)。これは、Solaris上でShenandoahを走らせたい人たちにとって興味深いだけでなく、私たちにとっても興味深いことです。なぜなら、非メインラインのツール群を満足させるためには、余分なクリーンさが必要だからです。 Solarisサポートのための変更点は、すでにJDK 13の開発用リポジトリに含まれており、ShenandoahのJDK 11およびJDK 8のバックポート用リポジトリにもバックポートされています。 x86_32 Shenandoahはずいぶん前に"passive"モードでx86_32をサポートしていました。このモードでは、バリアの実装を避けるためにstop-the-world GCのみに依存します(基本的には、Degenerated GCを常に実行します)。このモードは、本当に小さなマイクロサービスサイズのVMで、アンコミットとスリムなネイティブポインタで得られるフットプリントの数値を見るのに興味深いモードでした。このモードはアップストリームに統合する前に削除されました。なぜなら、多くのShenandoahのテストは、すべてのヒューリスティック/モードが適切に動作することを期待しており、初歩的なx86_32サポートがあると、Tier1テストを壊してしまうからです。 そのため、これを無効にしました。 今日では、 ロードリファレンスバリア と 個別の転送ポインタスロットの排除 のおかげで、ランタイムインターフェースが大幅に簡素化されました。そして、その上に完全にコンカレントなx86_32を構築できます。このアプローチにより、Shenandoahのコードで32ビットのクリーンさを維持することができます(この変更の前に5つ以上のバグを修正しました!)。また、Shenandoahが32ビットプラットフォームで実装できるという概念の証明にもなります。 これは、コンテナや組み込みシステムなど、余分なフットプリントの削減が重要なシナリオで興味深いものです。 LRB + 転送ポインタしない + 32-bitサポートの組み合わせにより、現在のフットプリントの最低限度を実現しています。これは、Shenandoahでも可能でしょう。 x86_32ビットサポートのための変更は完了しており、JDK 13に統合する準備ができています。しかし、現在は転送ポインタの変更の排除を待っており、それに伴いC2の厄介なバグフィックスを待っています。計画では、ロードリファレンスバリアと転送ポインタの廃止の変更がバックポートされた後、後にShenandoah JDK 11とJDK 8のバックポートにバックポートする予定です。 その他のアーキテクチャやOS OSとアーキテクチャのサポートにこの2つが追加されたことで、Shenandoahはまもなく4つのOSで利用できるようになります(例えば、ビルドして実行できることがわかっている)。 Linux、Windows、MacOS、Solarisの4つのOSと、x86_64、arm64、x86_32の3つのアーキテクチャに対応します。これは、OS固有のコードを一切使用せず、過度に複雑なアーキテクチャ固有のコードも使用しないというShenandoahの設計によるものです。将来のリリースでは、より多くのOSやアーキテクチャを仲間に加えることを検討するかもしれません(誰かが実装するほど面白いと思えば)。 いつものように、リリースを待ちたくない方は、すでにすべてを手に入れ、問題の解決に協力することができます: Shenandoah GC Wiki をチェックしてみてください。 もっと読む JDK 13のShenandoah GC パート1:ロードリファレンスバリア JDK 13のShenandoah GC パート2:転送ポインタワードの廃止
こんにちは、 Red Hat 版の Kubernetes である、 OpenShift を担当しています。花田です。 前回は、 OpenShift の AWS上のマネージドサービスである ROSA の cluster を作成する。 独自の概念である Machinepool という概念を使って、 Worker Node を使いしてみて、その周りの制限を探ってみる。という事をやってみました。 今回は、 ROSA で作成される構成がどういうものになのか、 AWS コンソール上から見ていこうと思います。 EC2 インスタンスの構成を観察してみる 初期状態の ROSA の EC2 の構成を観察してみます。今回は rosa create cluster --cluster-name rosa-cluster --multi-az で Multi AZ の最小構成で ROSA クラスターを作成した時の AWS Console からの EC2の眺めてみます。 Single AZ 構成の時の EC2 インスタンスについては、マニュアルの「 1.5. プロビジョニングされる AWS インフラストラクチャー 」に書いているのですが、同じかどうかの確認です。 作成されたEC2インスタンス インスタンスの名前から役割が想像できるようになっています。 Master Node m5.xlarge x 3 Infra Node r5.xlarge x 3 Worker Node m5.xlarge x 3 で構成されている事が見て取れます。 Single AZ 構成と同じインスタンスタイプが使われていて、本数だけが増えています。 こちら のページによると m5.xlarge = 4 vCPU 16GB :コンピューティング最低化ノード r5.xlarge = 4 vCPU 32GB :メモリ最適化ノード なので、 Infra Node にメモリが多めのインスタンスを使用している事がわかります。 ロードバランサーの構成を観察してみる さて、次は ELB (Elastic Loadbalancer)の構成を見て行きます。 作成されたロードバランサー なにやら5つ程、 ELB ( NLB x 2, CLB x 3) が作成されています。このままだと良く分からないので、構成を確認しながら図に起こしてみた所、以下のようになりました。 ロードバランサー構成の書き起こし OpenShift (Kubernetes) で API Server のアクセスを受け付けるポートは 6443 ですが、それを受け付ける ELB が Red Hat SRE 用と、ユーザー用で分かれている事がわかります。入り口のトラフィックの経路を分割しておこう。という思想が見て取れます。 Red Hat SRE 用とされる 6443 の Load Balancer は、 CLB が使われており、対象も Master Node だけではなく Woker Node にも分散されています。この部分は標準的なオンプレの OpenShift と異なる部分で気になる所です。 が、ここは Red Hat の SRE チームが使用する部分なので、追求は一旦、脇に置いておきましょう。(気になる方は、フォワード先の Port をどんな Service が構成されているか確認してみると面白いかもしれません) 他にも Red Hat SRE 用の CLB には、ソースセキュリティグループが設定されており、 Red Hat が使用する特定の IPアドレスレンジのみのインバウンドが許可されているのが見て取れました。 ユーザーHTTP アプリ用の ELB(CLB) ユーザーが作成した Web アプリケーションは、図の上部の CLB が受け取り、 Infra Node 上にある Router ( OpenShift の Ingress 実装) にフォワードされます。 NLB のフォワード先の構成は、 以下のように全ての Node が対象になっています。が、実際に InService となっているのは2つの Infra Node だけです。 80/443 用のCLB (Classic Load Balancer)の構成 OpenShift では、 Router と呼ばれる Infra Node 上の Pod が (配置はどこでも良いのですが、通常 Infra Node に Label や Taint を使って配置します)、一旦、クラスター外部から来た 80/443 の受け口となり、 Worker Node 上で稼働するユーザーのコンテナに対してリクエストをフォワードします。 OpenShift で使用される Router Pod の実体は、 Load Balancer アプリとして良く使用される HA Proxy です。クラスター内の HA Proxy が一旦トラフィックを受け止めて、そこからさらにクラスター内のどこかの Worker Nodde 上に存在する Pod にフォワードする。と考えれば、動きが理解しやすいかもしれません。 この Router Pod の配置を確認してみます。 # Router Pod は、openshift-ingress という namespace に所属しています。 $ oc get pods -n openshift-ingress -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES router-default-f998c67f9-mtkcx 1/1 Running 0 6h31m 10.130.2.21 ip-10-0-135-141.ap-northeast-1.compute.internal <none> <none> router-default-f998c67f9-snxw4 1/1 Running 0 6h31m 10.131.2.21 ip-10-0-189-232.ap-northeast-1.compute.internal <none> <none> $ Router Pod (router-default-xxxxxx-xxxxxx) は、2つだけデプロイされているのがわかります。(紙面の都合上、確認ログは省きますが、上記の InService の Infra Node の上にこれら Pod がデプロイされていました) ですので、 NLB は、 Router Pod のある所にだけ、リクエストをフォワードしている事がわかります。 Router Pod を増やしてみる せっかく Infra Node が 3本あるので、 Router の Pod も3つにしたい所です。2→3 に Router Pod の数を増やしてみます。 # Router Pod をコントロールする、Ingress Controller (名前は default) の設定を編集します。 $ oc edit ingresscontroller/default -n openshift-ingress-operator <省略> spec: defaultCertificate: name: rosa-cluster-primary-cert-bundle-secret domain: apps.rosa-cluster.btpl.p1.openshiftapps.com nodePlacement: nodeSelector: matchLabels: node-role.kubernetes.io/infra: "" tolerations: - effect: NoSchedule key: node-role.kubernetes.io/infra operator: Exists replicas: 3 # ここを 2→ 3に編集して保存 routeSelector: {} <省略> $ $ oc get pods -n openshift-ingress NAME READY STATUS RESTARTS AGE router-default-f998c67f9-b2pvl 1/1 Running 0 17s router-default-f998c67f9-mtkcx 1/1 Running 0 6h39m router-default-f998c67f9-snxw4 1/1 Running 0 6h39m $ 無事 Router が 3つに増えました。 ロードバランサー側のステータスを確認してみます。 Router Pod を 3つに増やした時のステータス ロードバランサー側も Infora Node 全てが InService としてフォワード先になりました。 ストレージボリュームを観察してみる EC2 、 ELB と来て、次はストレージの初期構成を観察してみます。 まずは EBS の状態です。 作成されたボリューム Name カラムから推測ができる通りに Master Node 350GiB io1 1000 IOPS Infra Node 300GiB gp2 900 IOPS Worker Node 300GiB gp2 ​900 IOPS がアタッチされています。 etcd のある Master Node にやや大きめの領域と、若干高めの IOPS をプロビジョニングしている事がわかります。 その他に、 Name カラムからは何のボリュームか良く分からない 100 GiB x 2 と10GiB x 3 のボリュームが見えます。これらは、確認した所 Infra Node にアタッチされていました。 恐らく、 OpenShift Monitoring 用のボリュームではないか。と当たりを付けて、 OpenShift Monitoring がデプロイされる namespace である、 openshift-monitoring に所属する PVC (Persistent Volume Claim)を確認してみます。 $ oc get pvc -n openshift-monitoring NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE alertmanager-data-alertmanager-main-0 Bound pvc-4d3f789e-69a2-4018-a1e2-203c4d11c02e 10Gi RWO gp2 7h55m alertmanager-data-alertmanager-main-1 Bound pvc-3575ba46-984e-434b-9137-165d9aebcd77 10Gi RWO gp2 7h55m alertmanager-data-alertmanager-main-2 Bound pvc-242a40fe-3610-4b7a-b309-b394a19a3e6c 10Gi RWO gp2 7h55m prometheus-data-prometheus-k8s-0 Bound pvc-b358791e-5665-4cf1-9dcd-17e8ca0d5ec4 100Gi RWO gp2 7h55m prometheus-data-prometheus-k8s-1 Bound pvc-b152847b-5b80-45fd-a19a-a08f1e0ca455 100Gi RWO gp2 7h55m $ ビンゴ!です。10 GiB x 3 は、 Alert Manager 用、100 GIB x 2 は、 Prometheus のデータ保管用のボリュームのようです。 これらの Alert Manger と、 Prometheus は、 OpenShift Monitoring と呼ばれる OpenShift の監視用のサブコンポーネントを構成するモジュールです。 次に S3 を見て行きます。バックアップの保管先と思われる S3 のバケットが作成されています。 作成された S3バケット 名前 のカラムから、上の2つは backup 用、下の1つは registry 用だと思われます。 一応、 xxxxx-image-registry-xxxxx の方だけでも確認してみます。 Image Registry の構成の中身を、バケット名の一部を使って grep してみると… $ oc get configs.imageregistry.operator.openshift.io -o yaml | grep "rosa-cluster-" bucket: rosa-cluster-sl69n-image-registry-ap-northeast-1-ktnkgfriwbfla bucket: rosa-cluster-sl69n-image-registry-ap-northeast-1-ktnkgfriwbfla $ S3 のバケット名が指定されていました。 ちなみにこの OpenShift に標準でバンドルされている Image Registry ですが、一番長い呼ばれ方だと Integrated OpenShift Container Platform Registry と呼ばれます。 Red Hat SRE チームの AWSインフラへのアクセス ここまで、見て回った Master Node や、 Infra Node や周辺の AWS オブジェクトは、 Red Hat SRE チームが管理する部分なので、 基本的にユーザーが触らなくて良い(触ってはいけない)部分になります 。 ROSA はマネージドの OpenShift 環境なので、ユーザーの関心範囲は Worker Node とその上にデプロイするユーザーのアプリケーションであり、 Manster Node や、 Worker Node 等は、 Red Hat SRE チームが管理します。 とは言え Worker Node を追加したり、新しい PV を追加したり。と AWS 上のオブジェクトに変更をもたらすはずのユーザーの操作というものがあります。 それらの作業は rosaコマンド や、 OpenShift の CLI である oc コマンド、後述する OCM (OpenShift Cluster Manager) を通して行う事になります。 また反対に、 Red Hat SRE チームも通常は、 AWS アカウントにアクセスはしません。緊急時にのみ「明確に定義された監査可能な手段」でアクセスする場合があります。詳細については、マニュアルの「 3.3. アイデンティティーおよびアクセス管理 」を参照下さい。 また、 Red Hat SRE チームとユーザーの責任範囲については、「 第2章 責任分担マトリクス 」のようなドキュメントも用意されています。 ROSA クラスターの管理 (OCM : OpenShift Cluster Manager) ROSA をインストールするためには、 cloud.redhat.com でアカウントを作成する必要があります。 作成したアカウントで cloud.redhat.com にログインした後、インストールするモジュールを AWS 上に引っ張ってくるための token を取得します。 この cloud.redhat.com には、インストール用の token を取得する以外にも Red Hat 製品の統合管理ツールとしての機能を持っています。 cloud.redhat.com にログインし、左側のペインの OpenShift というメニューをクリックします。 rosa-cluster として名前を付けた ROSA の OpenShift クラスターが表示されています。これは、 OCM (OpenShift Cluster Manager) と呼ばれるクラウド・サービスの画面で、 OpenShift クラスターを管理するためのツールです。 OCM (OpenShift Cluster Manager) 画面 ここに表示される OpenShift クラスターは、 ROSA で作成された OpenShift クラスターだけでなく、同じ cloud.redhat.com ユーザーアカウントを使用して、 token を取得した全ての OpenShift クラスターが表示されます。 つまり Azure の上に作成しても IBM Cloud の上に作成しても GCP の上に作成しても オンプレミスの VMware の上に作成したものも、同じユーザーアカウントを使って token を取得して構築した OpenShift クラスターであれば、全てこちらに表示され、現在のステータス等が確認できるようになっています。 さらに ROSA では、幾つかの Cluster 管理機能をここからも行えるようになっています。 例えば、 ROSA で作成した OpenShift クラスターを選択すると以下のような Network 構成の画面があります。 OCM 上の ROSA Cluster Networking 設定 この画面では、デフォルトではインターネットに公開する設定になっている、 API Server や、ユーザーアプリケーションの Router の設定を Private に切り替える事ができるようになっています。 他にも、 こちらの記事 で rosa コマンドを使って行われている Machinepool の作成と Macinepool への Worker Node の追加等もこの OCM からできるようになっています。 ROSA クラスターのアップグレードの設定 (自動、手動) や、 Support ケースの起票など、 ROSA クラスターの管理に必要な事が、ここからできるようになっています。 サポートケースの管理画面 今回は、 ROSA によって作成されるデフォルトの AWS 上のオブジェクトをざっと見て周ったのと、 ROSA を含めた OpenShift クラスターを統合管理するツールである OCM (OpenShift Cluster Manager) をご紹介しました。 ROSA は今後もアップデートが予定されており、今後も使いやすさに磨きがかかっていく予定ですが、随時情報をアップデートしていきたいと思います。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Shenandoah GC in JDK 13, Part 2: Eliminating the forward pointer word | Red Hat Developer の翻訳記事です。 この連載では、 JDK 13 で登場する Shenandoah GC の新展開についてご紹介します。 パート1 では、Shenandoahのバリアモデルがロードリファレンスバリアに変更されたことと、その意味について見てきました。 ここでお話ししたい変更点は、Shenandoah GCに関するもう1つのよくある(おそらく最もよくある)懸念に対処するものです。それは、オブジェクトごとに余分なワードが必要なことです。多くの人は、これがShenandoahのコア要件であると信じていますが、以下で見るように、実際にはそうではありません。 まず、Hotspot JVMでの通常のオブジェクトレイアウトを見てみましょう。 0: [mark-word ] 8: [class-word ] 16: [field 1 ] 24: [field 2 ] 32: [field 3 ] ここでの各セクションは、ヒープのワードを示しています。それは、64ビットアーキテクチャでは64ビット、32ビットアーキテクチャでは32ビットになります。 最初のワードは、いわゆるマークワード、つまりオブジェクトのヘッダです。これは様々な目的で使用されます。例えば、オブジェクトのハッシュコードを保持できます。3つのビットがあり、様々なロック状態に使用されます。GCの中には、オブジェクトの年齢やマーキングの状態を追跡するために使用するものもあります。また、"displaced "マークへのポインタ、"inflated "ロックへのポインタ、あるいはGC時には転送ポインタを "オーバーレイ "できます。 2番目のワードはklassポインタ用に予約されています。これは単に、オブジェクトのクラスを表すHotspot内部のデータ構造へのポインタです。 配列の場合は、配列長を格納するために次のワードが追加されます。その後に続くのは、オブジェクトの実際のペイロード、つまりフィールドと配列の要素です。 Shenandoahを有効にして実行した場合、レイアウトは代わりに以下のようになります。 -8: [fwd pointer] 0: [mark-word ] 8: [class-word ] 16: [field 1 ] 24: [field 2 ] 32: [field 3 ] フォワードポインタは、Shenandoahの同時退避プロトコルに使用されます。 通常、それは自分自身を指しています -> そのオブジェクトはまだ退避していません。 (GCまたはライトバリアを介して)退避するときは、まずオブジェクトをコピーし、そのコピーにアトミックな比較とスワップを使用して新しいフォワードポインタをインストールします。その際、問題のあるコピーへのポインタを渡す可能性があります。勝つのは1つのコピーだけです。 これで、この転送ポインタを読むだけで、読み書きする正規のコピーを簡単に見つけられます。 このプロトコルの利点は、単純で安価であることです。安価であるという点がここでは重要です。というのも、Shenandoahはプリミティブなものも含めて、すべての読み書きに対してフォワーダを解決する必要があるからです。そして、このプロトコルを使用すると、このための読み取りバリアは1つの命令になります。 mov %rax, (%rax, -8) それくらいシンプルなものです。 デメリットとしては、当然ながらメモリが多く必要になります。最悪の場合、ペイロードを持たないオブジェクトの場合、2ワードのオブジェクトのために1ワード増えることになります。つまり、50%増です。より現実的なオブジェクトサイズの分布であれば、5%~10%のオーバーヘッドが増えることになりますが、効果は人によって異なります。。これはパフォーマンスの低下にもつながります。これは、同じ数のオブジェクトを割り当てると、オーバーヘッドがない場合よりも早く上限に達し、GCがより頻繁に促されるため、スループットが低下するということです。 ここまで注意深く読んでくださった方は、マークワードがいくつかのGCで転送ポインタを運ぶためにも使われている/オーバーレイされることにお気づきでしょう。では、なぜShenandoahでも同じようにしないのでしょうか?その答えは(かつては)、転送ポインタを読み取るにはもう少し作業が必要だったからです。真のマークワードと転送ポインタをどうにかして区別する必要があります。そのためには、マークワードの最下位2ビットを設定しました。これらのビットは通常、ロックビットとして使用されますが、0b11という組み合わせは、ロックビットの合法的な組み合わせではありません。つまり、これらのビットが設定されると、最下位ビットが0にマスクされたマークワードは、転送ポインタとして解釈されることになります。このマークワードのデコードは、上記の単純な転送ポインタの読み取りよりもかなり複雑です。私は実際に 少し前にプロトタイプを作った のですが、リードバリアの追加コストは法外なものであり、節約分を正当化するものではありませんでした。 そんな状況を一変させたのが、最近登場したロード リファレンスバリア です: 特に(非常に頻繁な)プリミティブリードでは、リードバリアを必要としなくなりました。 ロードリファレンスバリアは条件付きです。これは、GCがアクティブで、問題のオブジェクトがコレクションセットにある場合にのみ、スローパス(実際の解決)が有効になることを意味します。これはかなり稀なことです。これを以前のリードバリアと比較してみましょう。これは常にオンになっています。 from-spaceコピーへのアクセスはもはや許されません。強力な不変性により、我々は常にto-spaceコピーからの読み取りとto-spaceコピーへの書き込みのみを行うことが保証されています。 2つの結果は以下の通りです。from-spaceコピーは実際には何にも使われていないので、転送ポインタのために余分なワードを確保する代わりに、そのスペースを使えます。基本的に、from-spaceコピーの内容全体を消去して、転送ポインタをどこにでも置けます。「転送されていない」(他の内容は気にしない)と「転送されている」(残りは転送ポインタ)を区別することができればよいのです。 また、ロードリファレンスバリアの実際の中間のパスとスローパスはそれほどホットではないので、そこに少しのデコードをする余裕があるということです。それは次のようなものになります(擬似コードで)。 oop decode_forwarding(oop obj) { mark m = obj->load_mark(); if ((m & 0b11) == 0b11) { return (oop) (m & ~0b11); } else { return obj; } } これは、転送ポインタの単純なロードよりも明らかに複雑に見えますが、それでも基本的には無料でもらえるモノです。なぜなら、これはロードリファレンスバリアのあまりホットではない中間のパスでのみ実行されるからです。これにより、新しいオブジェクトのレイアウトは次のようになります。 0: [mark word (or fwd pointer)] 8: [class word] 16: [field 1] 24: [field 2] 32: [field 3] この方法にはいくつかの利点があります。 明らかに、余分なワードを排除することで、Shenandoahのメモリフットプリントを削減します。 それほど明らかではありませんが、結果的にスループットが向上します。GCトリガーを起動する前に、より多くのオブジェクトを割り当てることができるようになりました。これにより、実際のGCに費やされるサイクル数が減少します。 オブジェクトはよりキツく詰め込まれます。これにより、CPUのキャッシュ圧力が改善されます。 ここでも、必要なGCインタフェースがよりシンプルになりました。これまでは,(余分なワードを確保して初期化するために)アロケーションパスの特別な実装が必要でした。他のGCと同じアロケーションコードを使用できるようになりました。 スループットの向上の一例として、私が試したGCに敏感なベンチマークでは、すべて10%から15%の向上が見られました。他のベンチマークでは、それ以下か、まったく効果がありませんでした。しかし、これはGCをまったく行わないベンチマークでは驚くべきことではありません。しかし、余分なデコードコストは実際にはどこにも現れないことに注意する必要があります。基本的には無視できるレベルです。ただし、退避が激しいワークロードでは、おそらく表示されるでしょう。しかし、ほとんどのアプリケーションはそれほど退避しませんし、ほとんどの作業はGCスレッドで行われます。これにより、中間のパスデコーディングが十分に安価になっています。 この実装は、 Shenandoah/JDK のリポジトリに 最近プッシュ されました。現在、最後の既知のバグを排除しており、その後、JDK 13 リポジトリにアップストリームする準備が整います。計画では、最終的にShenandoahのJDK 11およびJDK 8バックポートリポジトリにバックポートし、そこからRPMに移行する予定です。もし待ちたくないのであれば、すでに手に入れることができます: the Shenandoah GC Wiki をチェックしてください。 続きを読む JDK 13のShenandoah GC パート1:ロードリファレンスバリア JDK 13のShenandoah GC パート3:アーキテクチャとオペレーティングシステム
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Shenandoah GC in JDK 13, Part 1: Load reference barriers | Red Hat Developer の翻訳記事です。 この連載では、 JDK 13 で登場する Shenandoah GC の新しい進歩を紹介します。おそらく最も重要な変更は、ユーザには直接見えないものの、Shenandoahのバリアモデルをロードリファレンスバリアに切り替えたことです。この変更により、Shenandoahに対する批判の主要なポイントの1つである、高価なプリミティブリードバリアが解決されました。ここでは、この変更の意味について詳しく説明します。 Shenandoah(他のコレクターと同様)は、ヒープの一貫性を確保するためにバリアを採用しています。より具体的には、Shenandoah GCは「to-space-invariant」と呼ぶものを保証するためにバリアを採用しています。これは、ShenandoahがGCしているときに、オブジェクトをいわゆる「from-space」から「to-space」にコピーしていることを意味し、Javaスレッドが実行されている間(同時)にそれを行います。 そのため、JVM内には2つのオブジェクトのコピーが存在する可能性があります。ヒープの一貫性を保つためには、次のいずれかを保証する必要があります。 書き込みはto-spaceのコピーに発生し、読み込みは両方のコピーから発生します。メモリモデルの制約を受ける=弱いto-space invariant、または 書き込みと読み込みが常にto-spaceコピーに発生する=強いto-space invariant。 これを保証する方法は、読み取りと書き込みが起こるたびに、対応するタイプのバリアを採用することです。以下の疑似コードを考えてみましょう。 void example(Foo foo) { Bar b1 = foo.bar; // 読み込み while ( .. ) { Baz baz = b1.baz; // 読み込み b1.x = makeSomeValue(baz); // 書き込み } Shenandoahのバリアを採用すると、次のようになります(JVM+GCが内部で行う)。 void example(Foo foo) { Bar b1 = readBarrier(foo).bar; // 読み込み while ( .. ) { Baz baz = readBarrier(b1).baz; // 読み込み X value = makeSomeValue(baz); writeBarrier(b1).x = readBarrier(value); // 書き込み } 言い換えれば、オブジェクトから読み取る場合には、まずリードバリアを介してオブジェクトを解決し、オブジェクトに書き込む場合には、おそらくオブジェクトをto-spaceにコピーすることになります。ここでは詳細を説明しませんが、どちらの操作も多少のコストがかかることだけは覚えておいてください。 また、ヒープ参照が更新されている間、to-space参照のみをフィールドに書き込むことを保証するために、ここでの書き込みの値にリードバリアが必要であることにも注意してください(Shenandoahの古いバリアモデルのもう一つの厄介な点)。 バリアはコストのかかるものなので、最適化にはかなり力を入れました。重要な最適化は、バリアをループの外に出すことです。この例では、b1はループの外で定義されていますが、ループの中でのみ使用されています。ループの中で何度もバリアを実行するのではなく、ループの外で一度だけバリアを実行すればいいのです。 void example(Foo foo) { Bar b1 = readBarrier(foo).bar; // 読み込み Bar b1' = readBarrier(b1); Bar b1 '' = writeBarrier(b1); while ( .. ) { Baz baz = b1'.baz; // 読み込み X value = makeSomeValue(baz); b1 '' .x = readBarrier(value); // 書き込み } そして、ライトバリアはリードバリアよりも強いので、この2つを畳みこむことができるのです。 void example(Foo foo) { Bar b1 = readBarrier(foo).bar; // 読み込み Bar b1' = writeBarrier(b1); while ( .. ) { Baz baz = b1'.baz; // 読み込み X value = makeSomeValue(baz); b1'.x = readBarrier(value); // 書き込み } これは素晴らしいことで、かなりうまく機能していますが、このための最適化パスが非常に複雑であるという点で、厄介でもあります。あらゆるオブジェクトのfrom-spaceと2つのspaceコピーがいつでもJVMの中を浮遊しているという事実は、頭痛と複雑さの大きな原因です。例えば、あるオブジェクトを別のコピーと比較する場合に備えて、オブジェクトを比較するための余分なバリアが必要です。リードバリアとライトバリアは、非常に頻繁に行われるプリミティブな読み書きを含め、 あらゆる 読み書きに対して挿入する必要があります。 では、これを最適化して、オブジェクトがメモリからロードされた時点で、to-space-invarianceを強く保証すればいいのではないでしょうか。そこで登場するのが、ロードリファレンスバリアです。ロードリファレンスバリアは、これまでのライトバリアとほぼ同様に機能しますが、使用時点(オブジェクトからの読み込み時やオブジェクトへの保存時)では採用されません。その代わりに、オブジェクトがロードされたときのもっと早い段階(定義時点)で使用されます。 void example(Foo foo) { Bar b1' = loadReferenceBarrier(foo.bar); while ( .. ) { Baz baz = loadReferenceBarrier(b1'.baz); // 読み込み X value = makeSomeValue(baz); b1'.x = value; // 書き込み } このコードは基本的には最適化後のものですが、まだ何も最適化する必要がなかったことがわかります。また、格納した値のリードバリアがなくなっています。なぜなら、makeSomeValue()が何をしたとしても、(強いto-space-invariantのおかげで)今は分かっているからです。これは、必要であれば、すでにロードリファレンスバリアを採用しているからです。この新しいロードリファレンスバリアは、以前のライトバリアとほぼ100%同じです。 このバリアモデルの利点はたくさんあります(私たちGC開発者にとって)。 強力なinvariantにより、GCやオブジェクトの状態についての推論が非常に容易になります。 ずっとシンプルなバリア・インタフェースです。実際、JDK11以降にGCのバリアインタフェースに追加した多くのものは、今では使われなくなっています:プリミティブ上のバリアは必要ありませんし、オブジェクトのイコールバリアも必要ありません。 最適化が非常に容易になります(上記参照)。バリアは、最もホットな場所(使用時点)ではなく、最もホットでない場所(定義時点)に自然に配置され、そこから離れたところで最適化を試みます(常に成功するとは限りません)。 オブジェクト・イコール・バリアが不要になります。 "resolve "バリアが不要になりました。(主にintrinsicsで使用される、少々特殊な種類のバリアで、リードのようなライトのような操作を行う場所で使用されます) すべてのバリアが条件付きになったことで、後の最適化の機会が増えました。 高速な JNI ゲッタは、from-spaceの参照をうまく処理できないため、以前は無効にする必要がありましたが、このような最適化を再び有効にできます。 ユーザにとって、この変更はほとんど目に見えませんが、要はShenandoahの全体的なパフォーマンスが向上したということです。また、転送ポインタの廃止など、さらなる改善への道も開かれていますが、これについては次の記事でご紹介します。 ロードリファレンスバリアは、2019年4月に JDK 13開発リポジトリに統合 されました。近々、ShenandoahのJDK 11とJDK 8のバックポートにも着手する予定です。待ちたくない方は、すでに手に入れられます:詳細は Shenandoah GC Wiki をご覧ください。 もっと読む JDK 13のShenandoah GC パート2:転送ポインタワードの廃止 JDK 13のShenandoah GC パート3:アーキテクチャとオペレーティングシステム
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Not all OpenJDK 12 builds include Shenandoah: Here's why | Red Hat Developer の翻訳記事です。 OpenJDK 12がリリースされました 。それには新しい機能が追加されています。これらは以下を含みます。 189: Shenandoah: 低休止時間のガーベジコレクタ (実験) 230: マイクロベンチマークスイート 325: Switch式(プレビュー) 334: JVM Constants API 340: 2つではなく1つのAAR64移植 341: デフォルトCDSアーカイブ 344: G1の中止可能な混合コレクション 346: 未使用のコミットされたメモリーをG1から速やかに返還 OpenJDK 12プロジェクトページから オープンソースビルドページ へのリンクをたどると、ダウンロード可能なバイナリが表示されます。Linuxバイナリをダウンロードしてインストールし、機能リストの最初の項目である「Shenandoah」が動作するかどうかを確認します。 $ ./jdk-12/bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -cp ~ Hello Error occurred during initialization of VM Option -XX:+UseShenandoahGC not supported おや、どうしたのでしょう? ちょっとした歴史です。高性能で低休止時間のガベージコレクタである Shenandoah は、Red Hatが主導するプロジェクトです。我々が最初にShenandoahをOpenJDKに貢献することを提案したとき、Oracle社は サポートしたくない と明言しました。それは妥当なことです。OpenJDKはフリーソフトウェアですから、不要なものをサポートする必要はありません。私たちはOracle社に、誰もが簡単にガベージコレクタを選択してビルドに含めることができる、非常にクリーンでプラグイン可能なガベージコレクタのインターフェースを設計するために協力することを伝えました。私たちはそれを一緒に行い、ShenandoahはJDK 12に入りました。 明らかにOracleはShenandoahをビルドしないことにしたようです。除外することで厳密に間違ったことをしているわけではありませんが、私には何かしっくりこないのです。これらのビルドはOracleによってサポートされていません。サポートを受けるにはOracleの商用バイナリが必要ですが、なぜShenandoahを除外するのでしょうか?単に、オープンソースのバイナリをビルドするために標準のビルドスクリプトを使用していただけかもしれません。しかし、かなり機能の少ないOpenJDKのリリースにおいて、オープンソースのビルドが最も重要な貢献の1つを除外するのは奇妙なことだと思います。Oracle社がGPLライセンスのOpenJDKビルドを提供してくれたことには本当に感謝していますが、そのすべてをビルドしてくれることを望みます。 しかし、すべてが失われたわけではありません。Red Hat Enterprise LinuxやFedoraでShenandoahを試したい場合は、JDK 8以降のすべてのビルドでサポートされていますので、ソフトウェアインストールツールを使用するか、例えば以下のように実行します。 $ yum install java-11-openjdk-devel JDK 12を試してみたい方は、FedoraとRed Hat Enterprise Linux用のパッケージ( EPEL 経由)がまもなく利用可能になります。その他のシステムでは、 AdoptOpenJDK がJDK 12バイナリを提供し、そのすべてがShenandoahをサポートしています。
こんにちは、 OpenShift を担当しています、花田です。 2021/3/31 より、 Red Hat 版の Kubernetes である OpenShift のマネージドサービスである ROSA (ろさ/ろーさ: R ed Hat O penShift S ervice on A WS ) の提供が、 AWS 上で開始されています。 OpenShift は、オンプレの ベアメタルサーバー の上でも、 VMware の上でも OpenStack の上でも RHV (Red Hat Virtualization)の上でも、 AWS の上でも、 Azure の上でも、 GCP の上でも テスト済み なので、場所を選ばず、どこでも同じ知識で運用を回す事ができるというのが大きな特徴です。 もともと OSD ( OpenShift Dedicated ) という AWS / GCP 上で提供する OpenShift のマネージドサービスが存在しています。 OSD も引き続きサービスを提供していますが、契約は AWS と Red Hat の両方と行う必要がありました。 ROSA は、AWSのサービスとして、AWSコンソールからの作業だけで契約が完了するため、マネージドサービスとしての敷居がぐっと下がった形になります。(細かい違いはあるのですが、ここではとりあえず置いておきます) ROSA の マニュアルはこちらに公開 されていますが、これを読んでいくのは細かくて大変なので、今回はざっくりと使い方を見て行きたいと思います。 1. AWS 周りの準備 AWS の CLI環境を準備する もしまだ AWS の CLI を使える環境を整えてない場合は、次の手順に従って AWS の CLI コマンドをセットアップします。 AWS CLI バージョン 2 のインストール、更新、アンインストール AWSコンソール上で ROSAを有効にする AWS のコンソール にログインして、画面上の検索ボックスで「ROSA」を検索すると以下のような画面が出てくるので、クリックして有効にします。 この作業は最初の一回だけ必要です。 ROSA有効化画面 以上で、AWS周りのセットアップは完了です。30秒程度で以下のように画面が変化するはずです。 有効化の完了 ROSA CLI をダウンロードする (過去に ROSA / OpenShift を使った事があり、ROSA / OpenShift の CLI ツールが手元に残っていても CLI のバージョンが古いとインストールが上手く行かない事があります。常に最新のものを使う事をおすすめします。) ROSAを有効化した時に現れた「CLIをダウンロード」のリンクをクリックすると、以下の rosa コマンドのダウンロードページ に飛ぶはずです。 CLI で操作できるように rosa というコマンドが用意されています。実行ファイル一つです。 ダウンロードしてパスを通しておきます。(後ほど、手順のまとまり具合的な観点で、もう一回同じダウンロード手順が出てきますがここでダウンロードした人は無視して下さい。) ブラウザの copy link のような機能で、ダウンロードボタンを右クリックしてリンクをコピーし、以下のように CLIでダウンロードする事も可能です。 $ curl -LO https://mirror.openshift.com/pub/openshift-v4/clients/rosa/latest/rosa-linux.tar.gz $ tar -zxf rosa-linux.tar.gz $ sudo mv ./rosa /usr/local/bin/ (Download の URLはサンプルですので、ご自身のブラウザで取得できたURLを使用して下さい) 2. RedHat 周りの準備 契約面では、AWS上のコンソールで全て完結するのですが、 OpenShift のサブスクリプション管理の観点で Red Hat のクラウドサービスにもアカウントを作る必用があります。 アカウントを作るのは完全に無料で、後から何かが請求されたりクレジットカードを登録するなどの必要もありません。 cloud.redhat.com からユーザーアカウントを作成します。 この cloud.redhat.com は、 OpenShift 以外にも Red Hat 製品のサブスクリプションの管理(だけではないのですが)を管理できるクラウドサービスになっています。 後で ROSA クラスターを作成する時に、このサイト経由で発行される API token が必要になります。 この API token が無いと ROSA のインストールをすすめる事ができません。 とりあえずは、ユーザーを作って、 cloud.redhat.com に、ログインできる事が確認できればOKです。 3. CLI 周りの準備 ROSA では、2種類のコマンド・ライン・ツールを使用します。一つは rosa コマンドと、もう一つは oc コマンドです。 rosa のコマンドのダウンロードと初期化 ROSA CLI Downloads | Red Hat OpenShift Service on AWS より、 rosa コマンドをダウンロードしてパスを通しておきます。 バイナリー一個の単純なものです。 AWS の CLI がセットアップされた環境で動作するように作られているので AWS の CLI を事前にセットアップしておく必要があります。 rosa version でコマンドがセットアップできてる事を確認します。 $ rosa version 1.0.9 $ rosa init を実行する $ rosa init と実行すると $ rosa init To login to your Red Hat account, get an offline access token at https://cloud.redhat.com/openshift/token/rosa ? Copy the token and paste it here と出てくるはずです。 上記のメッセージの中に出てくる https://cloud.redhat.com/openshift/token/rosa  の部分をクリックして API token を取りに行きます。 Red Hat のサイトへのログインを求められるので、ここで手順の2番目で作成した、 Red Hat Hybrid Cloud のアカウントが必要になります。 Terms & Condition 等の画面がでてきますが、 Terms and Conditions 最終的に以下の画面にたどり着きます。ここに見えている文字列 (token) をコピーして CLI に貼り付けます。 token 画面 token を貼り付けて enter を押すと、初期化が終わります。 $ rosa init To login to your Red Hat account, get an offline access token at https://cloud.redhat.com/openshift/token/rosa ? Copy the token and paste it here: **************************************************************************************************** ***************************************************************************************************************************************** ***************************************************************************************************************************************** ***************************************************************************************************************************************** ***************************************************************************************************************************************** <略> Run `rosa download oc` to downlaod the latest version, then add it to your PATH $ この時点で AWS上に osdCcsAdmin という IAM ユーザーが作成されているはずです。 oc コマンドのダウンロードと解凍 rosa init の最後の出力に rosa downlad oc を実行して oc コマンドをダウンロードしなさい。とあるのでダウンロードします。 oc コマンドは kubectl を拡張した OpenShift のコマンドです。 kubectl と同じように使える + α の機能が使えるようになります。 $ rosa download oc $ tar -xzf openshift-client-linux.tar.gz 解凍されてでてきた oc コマンドと kubectl コマンドを /usr/loca/bin に移動しておきます。 $ sudo mv ./oc /usr/local/bin $ sudo mv ./kubectl /usr/local/bin oc コマンドは kubectl の拡張コマンドです。クラスターにアクセスするコマンドで、クラスターができてないこの時点では使えませんので、パスが通っている事だけ確認できたら次に進みます。 AWSサービスの Quota を確認する AWS では、各サービス毎に サービスクォータ と呼ばれる使う事ができるリソースの上限が設定されています。 マニュアルの「 Required AWS service quotas 」の項目に、 ROSA を実行するための サービスクォーター についてかかれていますが、 rosa コマンドを導入した後は、 rosa init した後 rosa verify quota コマンドでこの条件が満たされているか確認できます。 以下は EBS の Quota に引っかかっている例です。 $ rosa verify quota --region=ap-northeast-1 I: Validating AWS quota... E: Insufficient AWS quotas E: Service ebs quota code L-D18FCD1D General Purpose SSD (gp2) volume storage not valid, expected quota of at least 300, but got 50 $ もし、 Quota 上限にひっかかっている場合は、 1. AWS 周りの準備 の AWSサービスの Quota を確認する に戻って、AWSの Quota 設定の上限を上げる申請をしてください。 このブログでは最低限の記述にとどめていますが、他にも AWSの必要な権限が設定されているか確認できる rosa verify permissions 等のコマンドがあります。詳しく知りたい方は マニュアルのこの辺り を卸参照下さい。 私の環境の場合は、EBSがマニュアル上は、最小 300 必要となっているのですが、 50 が 設定されてました。 AWS の Quota 画面 ここでは、 クォータの引き上げをリクエスト をクリックして、上限を 300 にするリクエストをします。 リクエストの処理状況も AWS コンソールから確認できます。 Quota リクエストの状態 自分の使っている会社のアカウントのサービス契約形態がわかってないのですが、処理が終わるまで平日で1~2時間、日曜で 6時間くらいかかりました。 4. ROSA クラスターの作成 いよいよ ROSA クラスターの作成に入ります。 その前にクラスターを作ったら一日どのくらいの費用がかかるか気になる方もいると思います。 以下の記事によると、Multi AZ 構成の ROSAクラスターの場合 $120/日 程度かかるようです。個人でちょっと試すにはちょっと厳しいと思うのでご注意下さい。 rheb.hatenablog.com ここでは rosa-cluster という名前を付けたクラスターを作成します。この部分は好みに応じて置き換えて下さい。 Worker Node 2本の最小構成のクラスターを作成する場合 ( Master Node を含め、全てが単一AZに作成されます) Single AZ 最小構成 $ rosa create cluster --cluster-name rosa-cluster ※ このコマンド例では、Master/Infra/Worker = 3 x m5.xlarge / 2 x r5.xlarge /2 x m5.xlarge の EC2 構成でクラスターが作成 されます。 Worker Node 3本の Multi AZ構成 のクラスターを作成する場合 ( --multi-az を指定。 Master Node と Infra Node も3つの AZに分散されて配置されます) Multi AZ 最小構成 $ rosa create cluster --cluster-name rosa-cluster --multi-az ※ このコマンド例では、Master/Infra/Worker = 3 x m5.xlarge / 3 x r5.xlarge /3 x m5.xlarge の EC2 構成でクラスターが作成されます。 クラスターの作成完了待ち クラスター作成完了までは、40分ほど時間がかかります。完了を Watch するには、以下のコマンドでログを確認する事ができます。 $ rosa logs install --cluster=rosa-cluster --watch 完了のメッセージ time="2021-05-24T05:46:58Z" level=debug msg=" API: 1s" time="2021-05-24T05:46:58Z" level=debug msg=" Bootstrap Destroy: 1m32s" time="2021-05-24T05:46:58Z" level=debug msg=" Cluster Operators: 17m12s" time="2021-05-24T05:46:58Z" level=debug msg=" Console: 1s" time="2021-05-24T05:46:58Z" level=info msg="Time elapsed: 37m38s" I: Cluster 'rosa-cluster' is now ready time="2021-05-24T05:46:59Z" level=info msg="command completed successfully" installID=g7qz882d time="2021-05-24T05:46:59Z" level=info msg="saving installer output" installID=g7qz882d time="2021-05-24T05:46:59Z" level=debug msg="installer console log: level=info msg=Credentials loaded from default AWS environment variables\nlevel=info msg=Consuming Install Config from target directory\nlevel=info msg=Manifests created in: manifests and openshift\nlevel=warning msg=Found override for release image. Please be warned, this is not advised\nlevel=info msg=Consuming Openshift Manifests from target directory\nlevel=info msg=Consuming Worker Machines from target directory\nlevel=info msg=Consuming OpenShift Install (Manifests) from target directory\nlevel=info msg=Consuming Master Machines from target directory\nlevel=info msg=Consuming Common Manifests from target directory\nlevel=info msg=Ignition-Configs created in: . and auth\nlevel=info msg=Consuming Bootstrap Ignition Config from target directory\nlevel=info msg=Consuming Worker Ignition Config from target directory\nlevel=info msg=Consuming Master Ignition Config from target directory\nlevel=info msg=Credentials loaded from default AWS environment variables\nlevel=info msg=Creating infrastructure resources...\nlevel=info msg=Waiting up to 20m0s for the Kubernetes API at https://api.rosa-cluster.3fof.p1.openshiftapps.com:6443...\nlevel=info msg=API v1.20.0+75370d3 up\nlevel=info msg=Waiting up to 30m0s for bootstrapping to complete...\nlevel=info msg=Destroying the bootstrap resources...\nlevel=info msg=Waiting up to 40m0s for the cluster at https://api.rosa-cluster.3fof.p1.openshiftapps.com:6443 to initialize...\nlevel=info msg=Waiting up to 10m0s for the openshift-console route to be created...\nlevel=info msg=Install complete!\nlevel=info msg=To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/output/auth/kubeconfig'\nlevel=info msg=Access the OpenShift web-console here: https://console-openshift-console.apps.rosa-cluster.3fof.p1.openshiftapps.com\nREDACTED LINE OF OUTPUT\nlevel=info msg=Time elapsed: 37m38s\n" installID=g7qz882d time="2021-05-24T05:46:59Z" level=info msg="install completed successfully" installID=g7qz882d vscode ➜ /workspaces/rosa $ ./rosa logs install --cluster=rosa-cluster --watch 念のため状態を確認したい場合は、以下のような状態と構成の確認コマンドもあります。 $ rosa describe cluster --cluster=rosa-cluster 管理ユーザーの作成 クラスターができたら、以下のコマンドで管理ユーザー( cluster-admin ) を作成してみます。 $ rosa create admin --cluster=rosa-cluster W: It is recommended to add an identity provider to login to this cluster. See 'rosa create idp --help' for more information. I: Admin account has been added to cluster 'rosa-cluster'. I: Please securely store this generated password. If you lose this password you can delete and recreate the cluster admin user. I: To login, run the following command: oc login https://api.rosa-cluster.3fof.p1.openshiftapps.com:6443 --username cluster-admin --password amya9-7pass8-sS9HF-DDQdeg I: It may take up to a minute for the account to become active. コマンド出力にログイン用のURLや、 cluster-admin のパスワードが表示されているので、メモしておきます。 本番環境では作法としてよろしくないのですが、私は実験用の環境しか作成しないので、コピペしてローカルにテキストで保管してしまっています。 echo "oc login https://api.rosa-cluster.3ogw.p1.openshiftapps.com:6443 --username cluster-admin --passwordamya9-7pass8-sS9HF-DDQdeg" > login-memo.txt ログイン 管理ユーザーを作成した時に出力された管理ユーザー名 ( cluster-admin ) とパスワードが表示されるので、それでログインしてみます。(管理ユーザーを作った直後だと Login failed (401 Unauthorized) が出る事があります。その場合は少し待ってみましょう) $ oc login https://api.rosa-cluster.3fof.p1.openshiftapps.com:6443 --username cluster-admin --password aqja9-7atm8-sS9HF-QeSBB oc get nodes コマンドで、作成されている node を確認します。ここでは、 --multi-az オプションを付けてクラスターを作成したので Worker Node が3本あります。 $ oc get nodes NAME STATUS ROLES AGE VERSION ip-10-0-132-255.ap-northeast-1.compute.internal Ready worker 6h36m v1.20.0+75370d3 ip-10-0-136-188.ap-northeast-1.compute.internal Ready infra,worker 6h17m v1.20.0+75370d3 ip-10-0-158-164.ap-northeast-1.compute.internal Ready master 6h47m v1.20.0+75370d3 ip-10-0-165-17.ap-northeast-1.compute.internal Ready master 6h47m v1.20.0+75370d3 ip-10-0-171-207.ap-northeast-1.compute.internal Ready infra,worker 6h17m v1.20.0+75370d3 ip-10-0-181-41.ap-northeast-1.compute.internal Ready worker 6h39m v1.20.0+75370d3 ip-10-0-200-141.ap-northeast-1.compute.internal Ready infra,worker 6h16m v1.20.0+75370d3 ip-10-0-206-1.ap-northeast-1.compute.internal Ready worker 6h37m v1.20.0+75370d3 ip-10-0-222-207.ap-northeast-1.compute.internal Ready master 6h47m v1.20.0+75370d3 Multi AZ 構成では、Master Node 3本、Infra Node 3本、Worker Node 3本が作成されている事がわかります。 Master Node と Infra Node は、Red Hat 社が Managed として管理します。 Infra Node とは、 OpenShift 独自の概念で、ものは Worker Node と同じものです。実際の運用管理環境では、Monitoring や Log 収集などを統合的に行うアプリ(コンテナ)が必要で、 OpenShift では運用管理用のコンテナを、ユーザーワークロードと分割して配置するために、 Worker Node に Infra Node と分かるラベルを付けて、そこに配置する形で別途管理しています。いづれにしても ROSA では、 Red Hat がマネージする対象の Node なのでユーザーが気にする必要はありません。 ログアウト ログアウトは以下の通りです。 $ oc logout 5. Worker Node の追加 (Machineset と Machinepool) ROSA では、 Machiepool という概念が導入されています。 Machinepool は、同じインスタンス・タイプをグループ化した概念です。 ROSA で Worker Node を増やすには、 Machinepool 内の Worker Node を追加する。という形を取ります。 既存の Worker Node と同じインスタンスタイプを増やしたい場合は、既存 ( Default ) の Machinepool 内の replica の数を増やします。この Default の Machinepool は、初期の本数以下にしたり消す事はできませんが、増やす事は可能です。 別のインスタンスタイプを追加したい場合は、新しい Machiepool を追加します。 一方で、 OpenShift に詳しい方であれば、 OpenShift では、 Machineset というインスタンスのグループ化の概念があるのをご存じだと思います。 これらはどう違うのか確認してみます。 Machineset の確認 ますは、 MachineSet を確認してみます。 $ oc get machineset -A NAMESPACE NAME DESIRED CURRENT READY AVAILABLE AGE openshift-machine-api rosa-cluster-wchgs-infra-ap-northeast-1a 1 1 1 1 6h24m openshift-machine-api rosa-cluster-wchgs-infra-ap-northeast-1c 1 1 1 1 6h24m openshift-machine-api rosa-cluster-wchgs-infra-ap-northeast-1d 1 1 1 1 6h24m openshift-machine-api rosa-cluster-wchgs-worker-ap-northeast-1a 1 1 1 1 6h55m openshift-machine-api rosa-cluster-wchgs-worker-ap-northeast-1c 1 1 1 1 6h55m openshift-machine-api rosa-cluster-wchgs-worker-ap-northeast-1d 1 1 1 1 6h55m 名前から、 Worker Node 用に各 AZ毎 に3つ、 Infra Mode 用に各 AZ毎 に3つ、 Machineset が作成されているのがわかります。 図で表すとこんな感じです。 machineset OpenShift では、 Machineset に含まれる Node の数を、UIやコマンドで簡単に増減させる事ができるようになっています。 補則1: ROSA cluster 作成時に  --multi-az オプションを付けなかった場合は、 MachineSet は以下のように作成されました。 $ oc get machineset -A NAMESPACE NAME DESIRED CURRENT READY AVAILABLE AGE openshift-machine-api rosa-cluster-247vl-infra-ap-northeast-1a 2 2 2 2 16m openshift-machine-api rosa-cluster-247vl-worker-ap-northeast-1a 2 2 2 2 47m $ コマンド出力には現れていませんが、 Master Node を含め、単一の AZ に全ての Node が作成されています。 補則2: MachineSet の操作は、 Red Hat の管理している Infra Node も変更できてしまうし、 Machinepool の概念が導入されているのでユーザーとしては直接触る必要がないのではないだろうか。と思い、 MachineSet が変更できるか試して見ました。 $ oc whoami cluster-admin $ oc scale machineset rosa-cluster-247vl-mypool-1-ap-northeast-1a --replicas=2 -n openshift-machine-api Error from server (Prevented from accessing Red Hat managed resources. This is in an effort to prevent harmful actions that may cause unintended consequences or affect the stability of the cluster. If you have any questions about this, please reach out to Red Hat support at https://access.redhat.com/support): admission webhook "regular-user-validation.managed.openshift.io" denied the request: Prevented from accessing Red Hat managed resources. This is in an effort to prevent harmful actions that may cause unintended consequences or affect the stability of the cluster. If you have any questions about this, please reach out to Red Hat support at https://access.redhat.com/support $ と、例え cluster-admin でも MachineSet は、変更できないようになっていました。ユーザーが Worker Node を増やしたい場合は、 Machinepool を使用して変更する。という事のようです。 Machinepool の確認 前述したように ROSA では Machiepool とうい概念が定義されています。 Machinepool は、oc コマンドではなく rosa コマンドで確認する事ができます。まずここが、 Machineset と大きく違います。 では Machinepool を確認してみます。 $ rosa list machinepools --cluster=rosa-cluster ID AUTOSCALING REPLICAS INSTANCE TYPE LABELS TAINTS AVAILABILITY ZONES Default No   3 m5.xlarge ap-northeast-1a, ap-northeast-1c, ap-northeast-1d Machiepool では、 Worker Node のみが表示され、また AWS 独自の概念である m5.xlarge のような INSTNANCE TYPE や、AZ の名前が表示されています。 Machineset は、環境に依存しない OpenShift の概念であるため特定のベンダーに依存した部分が隠ぺいされている一方、 rosa コマンドで取得できる Machinepool では、AWSの独自の概念をそのままコマンド出力に含めています。 また、 ROSA でユーザーの管理対象外である Infra Node は、 Machinepool の対象に含まれてない事がわかります。その他にも AZ をまたいで一つの プール が構成されており、 Machinepool は、ユーザーが自分の関心対象である Worker Node だけにフォーカスした管理作業ができるように作られた、新しい概念である事が見て取れます。 default の Machinepool ちなみに出力のカラムに AUTOSCALING のカラムがある事からもわかるように、 Machinepool 内での Worker Node の Autoscaling も可能 です。 Machinepool の追加 ROSA では、別のインスタンスタイプを追加する場合、 Machinepool を作成し、新しい Worker Node インスタンスを追加します。 Single AZ の場合は本数は1本から追加できますが、 Multi AZ 環境の場合は、3の倍数で Worker Node を追加する必要があります。追加本数の制約については、ROSA マニュアルの 「Service Definition」の章の Compute のセクション に記載があります。 Machinepool の追加は以下のように行います。 $ rosa create machinepool --cluster=rosa-cluster ? Machine pool name: mypool-1 # 追加する Machinepool に付ける名前 ? Enable autoscaling (optional): No # AutoScaleの有効、無効を選択できる。 ? Replicas: 3 # Multi AZ (--mluti-az オプションを付けて cluster を作成した場合は 2を入れるとエラーになった。3の倍数の必要あり) ? Instance type: [Use arrows to move, type to filter, ? for more help] m5.4xlarge c5.4xlarge r5.4xlarge > r5.8xlarge p3.8xlarge m5.8xlarge c5.9xlarge <もっとある> Labels: env=dev ? Taints (optional): INFO: Machine pool 'mypool-1' created successfully on cluster 'rosa-cluster'INFO: To view all machine pools, run 'rosa list machinepools -c rosa-cluster' $ 追加するインスタンスタイプはリストから選択する事ができます。このブログの作成時点でサポートされているインスタンスタイプは、マニュアルによると こちら になります。 追加した MachinePool を確認してみます。 $ rosa list machinepools --cluster=rosa-cluster ID AUTOSCALING REPLICAS INSTANCE TYPE LABELS TAINTS AVAILABILITY ZONES Default No 3 m5.xlarge ap-northeast-1a, ap-northeast-1c, ap-northeast-1d mypool-1 No 3 m5.xlarge env=dev ap-northeast-1a, ap-northeast-1c, ap-northeast-1d $ 新しい Machinepool 、 mypool-1 ができています。 図で表すとこんな感じです。 追加された Machinepool mypool-1 ここでは出力は省略しますが、 Machinepool が作成された裏では、 MachineSet が、AZ 毎にそれぞれ作られていました。 同じインスタンスサイズで MachinPool を作ってしまったので、 Default の MachinePool がいらないな…と思ったので、数を 0 にできるか確認してみます。 $ rosa edit machinepool --cluster=rosa-cluster --replicas=0 Default ERR: Default machine pool for AZ cluster requires at least 3 compute nodes $ Default の Machinepool の最低で 3 本という数は変更できないようです。 別のサイズのインスタンスを追加する場合は、 Machinepool が2つ以上できる事になりますが、その際は、 Machinepool に Taint や Label を付ける事で、 Pod を振り分ける事になりそうです。 補則: ROSA cluster 作成時に  --multi-az オプションを付けなかった場合は、 Machinepool に作成する Node の本数は 1 でも大丈夫でした。 $ rosa list machinepools -c rosa-cluster ID AUTOSCALING REPLICAS INSTANCE TYPE LABELS TAINTS AVAILABILITY ZONES Default No 2 m5.xlarge ap-northeast-1a mypool-1 No 1 r5.xlarge env=test ap-northeast-1a 6. Cluster の削除 マニュアルの「 第11章 ROSA クラスターの削除 」に従って、クラスターを削除します。 クラスターの削除は、作成時と同じで rosa コマンドで行います。 $ rosa delete cluster --cluster=rosa-cluster --watch Cloud Formation のスタックが残っているので、それも消すには以下のコマンドを実行します。( 消す前に確認した所、 Cloud Formation の残骸は無いように見えたのですが… 少なくても作成された IAM User が消されます) $ rosa init --delete-stack 次回は ROSA の構造の内部をもう少し深掘りしてみます。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Mandrel: A specialized distribution of GraalVM for Quarkus | Red Hat Developer の翻訳記事です。 最初に Mandrel を発表したとき、なぜRed Hatが GraalVMのダウンストリーム・ディストリビューション を必要としているのかを説明しました。私たちは、GraalVMの ネイティブイメージ機能 、特に Quarkus の文脈で最も興味を持ちました。この記事では、Mandrelとは何か、何ではないかを説明します。また、Mandrelの技術的な特徴を紹介し、QuarkusでMandrelを使用する短いデモンストレーションを行います。 Mandrelとは? Mandrelは、GraalVMの native-image コンポーネントに焦点を当て、Quarkusユーザーが自分のアプリケーションにネイティブイメージを生成するための簡単な方法を提供します。Quarkusを使用している開発者は、 Java のソースコードから、 Linux 上で動作する無駄のないネイティブなプラットフォーム依存のアプリケーションに至るまで、すべての作業を行えるはずです。この機能は、クラウド・ネイティブアプリケーションの開発モデルにおける コンテナへのデプロイ に不可欠です。 私たちは、Mandrel内でのGraalVMの他の用途については、意図的に約束していません。GraalVMのフルディストリビューションは、 ネイティブイメージ以上のもの です。 多言語サポート 、効率的なインタプリタ実装をサポートするTruffleフレームワーク、 native-image のための LLVMコンパイラバックエンド 、HotSpotのC2サーバコンパイラの代替となるlibgraal JITコンパイラ、その他多くの機能を備えています。Mandrelは、GraalVMの機能の小さなサブセットです。私たちは、Quarkusのようなプロジェクトで、 native-image というユースケースをサポートしています。 なぜMandrelなのか? Mandrelは、GraalVMの不要な部分を取り除き、 native-image に集中できます。メンテナンスやテストのためのコードベースを減らせます。Mandrelは、 Labs OpenJDK 11 ではなく、アップストリームのOpenJDK 11を使用できます。これは GraalVM CE の基本的なJava開発キットです。Red Hatには OpenJDK for Red Hat customers をサポートするチームがあるので、アップストリームのOpenJDKを使うことはMandrelにとって自然なことでした。また、Red HatはOpenJDKのアップストリームに関わってきた歴史があり、現在は jdk-updates OpenJDK プロジェクト のOpenJDK 11uストリームをリードしています。 これらのプロジェクトにおける私たちのリーダーシップにより、私たちはGraalVM、ひいてはMandrelを改善する安定した変更を行いました。Red Hatはアップストリーム・ファーストの会社なので、最初からパッチをアップストリームに出すようにしています。今のところ、私たちは GraalVM CEとデバッグ能力 を増強しました。(-g フラグを使用して)Linux と Windows の両方に対応しています。また、Oracle Labsと協力して、 native-image に JDK Flight Recorderサポートの追加 を積極的に行っています。統合されれば、開発者は JDK Flight Recorder を使用して、アプリケーションがJVMモードまたはネイティブで実行されているかどうかに関わらず、アプリケーションの動作やパフォーマンス上の課題を観察・追跡できるようになります。 MandrelでのGraalVMコンポーネント GraalVMの native-image 機能をMandrelで提供するために、 Substrate VM フレームワーク とその依存関係のみをビルドしています。これには、 GraalVM SDK と GraalVMコンパイラ が含まれます。 Truffle や Sulong など、その他のGraalVMコンポーネントはMandrelの一部ではなく、我々はそれらをビルドしません。 GraalVMのSDKとコンパイラ以外に、Substrate VMはベースとなるJDKとネイティブ・コンパイラのツール群にも依存しています。MandrelはアップストリームのOpenJDK 11のビルドとGNU Compiler Collection(GCC)を使用してこれらの依存関係を満たしていますが、GraalVMは Labs OpenJDK 11 を使用し、GCCとLLVMの両方のツール群をサポートしています。 私たちは、MandrelをOpenJDKの拡張機能と考える傾向があります。ほとんどがJARファイルで、ネイティブなバイナリはほとんどありません。実際、私たちの 製品化されたMandrelイメージ は、RHELベースの通常の java-11-openjdk-static-libs インストールに加えて、2つのRPMを追加するだけです。 Mandrelのビルド GraalVMは、Pythonで書かれたツールである mx を使ってビルドされています。異なるGraalVMコンポーネント間のすべての依存関係はmxスイートによって定義され、ビルドプロセスの一部はmxエクステンションとして定義されています。そのため、 mx はMandrelのビルドプロセスにも不可欠な要素となっています。GraalVMとMandrelの両方のビルドをサポートするために mx スイートを拡張することは、 難しいことがわかりました 。特に、ビルドするコンポーネントの数を減らしたり、ビルドの手順を分割したりして、異なるビルドシステム上で異なるパーツをビルドすることをサポートするために行った作業を組み合わせることが難しかったです。 現在の解決策は、 mandrel-packaging を使用して、Mandrelをビルドしています。このツールは、必要な mx スイートから不要な依存関係を削除し、必要なコマンドを正しい順序で起動します。また、 mandrel-packaging ツールは、Mandrelを3つのステップでビルドできます。まず、Javaの部品(JARファイルとMavenアーティファクト)を生成し、次にネイティブの部品(GraalVMのスタティックライブラリ)を生成し、最後にOpenJDK 11で組み立て、 native image に対応したランタイムを生成します。 ここでは、OpenJDK 11をベースに、Mandrelの現行バージョンをソースからビルドするための基本的な手順を紹介します。 $ curl -sL https://github.com/AdoptOpenJDK/openjdk11-upstream-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_11.0.10_9.tar.gz -o jdk.tar.gz $ curl -sL https://github.com/AdoptOpenJDK/openjdk11-upstream-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-static-libs_x64_linux_11.0.10_9.tar.gz -o jdk-static-libs.tar.gz $ export JAVA_HOME=$(pwd)/openjdk-11 $ mkdir ${JAVA_HOME} $ tar xf jdk.tar.gz -C ${JAVA_HOME} --strip-components=1 $ tar xf jdk-static-libs.tar.gz -C ${JAVA_HOME} --strip-components=1 $ git clone --depth 1 --branch 5.279.1 https://github.com/graalvm/mx $ git clone --depth 1 --branch mandrel-21.0.0.0-Final \ https://github.com/graalvm/mandrel $ git clone --depth 1 --branch mandrel-21.0.0.0-Final \ https://github.com/graalvm/mandrel-packaging$ $JAVA_HOME/bin/java -ea ./mandrel-packaging/build.java --mx-home $(pwd)/mx $ ./mandrel-java11-21.0.0.0-Final/bin/native-image --version GraalVM Version 21.0.0.0-Final (Mandrel Distribution) (Java Version 11.0.10+9) Oracle Labsとの協力 GraalVM CE 11は、アップストリームのOpenJDK 11をフォークした Labs OpenJDK 11 をベースにしています。これは、libgraalとGraalVM CEをサポートするベースJDKを構築するために使用されています。Labs OpenJDK 11は、 GraalVM CE をビルドしているのと同じグループによってメンテナンスされています。 Graal VM CEはLabs OpenJDK 11をベースにしているため、Graal VMチームは、Java 11の最新の Java-level JVM Compiler Interface (JVMCI)の機能強化を利用して、改善できます。この2つのプロジェクトは非常に密接な関係にあるため、開始当初はビルドするJDKとして、 Labs OpenJDK 11をアップストリームのOpenJDK 11に置き換えることは不可能 でした。我々はOracle Labsと協力してMandrelを実現しました。 私たちは無地のOpenJDK 11で構築したかったし、Oracle Labsはダウンストリームで保守するパッチの数を減らしたかったのです。この作業の結果、一連のパッチがGraalVMのコードベースと上流のOpenJDK 11に統合されました。これは、今後の協力のための素晴らしい基盤となりました。最も重要なことは、OpenJDKのライブラリを静的な亜種としてビルドすることをOpenJDK 11でサポートする必要がありました。Mandrelは、通常のOpenJDKディストリビューションに含まれる共有ライブラリではなく、OpenJDKのスタティック・ライブラリを使用します。これにより、ネイティブなJavaアプリケーションをネイティブなイメージにリンクできます。これらはOpenJDKのライブラリに依存しています。 QuarkusでMandrelを使う この記事を書いている時点では、QuarkusがMandrelの主な使用者です。ここでは、Javaで書かれたシンプルなRESTEasy Quarkusアプリケーションのネイティブ実行ファイルを生成するためにMandrelを使用する簡単なデモンストレーションを紹介します。 $ echo | mvn io.quarkus:quarkus-maven-plugin:1.12.2.Final:create $ cd code-with-quarkus $ ./mvnw -Dnative verify \ -Dquarkus.native.container-build=true \ -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel:20.3-java11 $ ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner __ ____ __ _____ ___ __ ____ ______ --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 2021-03-08 17:57:40,084 INFO [io.quarkus] (main) code-with-quarkus 1.0.0-SNAPSHOT native (powered by Quarkus 1.12.2.Final) started in 0.014s. Listening on: http://0.0.0.0:8080 2021-03-08 17:57:40,084 INFO [io.quarkus] (main) Profile prod activated. 2021-03-08 17:57:40,084 INFO [io.quarkus] (main) Installed features: [cdi, resteasy] $ curl -w "\n" http://localhost:8080/hello-resteasy Hello RESTEasy まず、シンプルなRESTEasy Quarkusアプリケーションを、 code-with-quarkus というディレクトリに作成します。そして、Mavenのラッパー( mvnw )を使ってJavaのソースコードをコンパイルし、定義済みのコンテナイメージを使ってJavaのクラスファイルからネイティブの実行ファイルをビルドします。 -Dnative パラメータはMavenにネイティブの実行ファイルを生成するように指示し、 -Dquarkus.native.container-build=true はQuarkusにビルダーイメージを使用してネイティブの実行ファイルをビルドするように指示し、 -Dquarkus.native.builder-image=... は どのビルダーイメージ を使用するかを指示します。この例についての詳細は、 Quarkus ガイド を参照してください。 生成されたバイナリ ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner は、 最小のUBI 8イメージ のような、基本的なLinuxディストリビューション上で動作するのに適したネイティブELFバイナリです。 $ file target/code-with-quarkus-1.0.0-SNAPSHOT-runner target/code-with-quarkus-1.0.0-SNAPSHOT-runner: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=b43068dce7c114a0e8d018370a9d47e1e257de44, not stripped 図1は、Mandrelのネイティブイメージ実行ファイルを使ってQuarkusアプリケーションをコンテナ化するためのワークフローを示しています。 図1:MandrelによるQuarkusアプリケーションのコンテナ化 まとめ Mandrel は GraalVM のダウンストリームリリースであり、Red Hat が支援するプロジェクトにおける Java アプリケーションのネイティブイメージコンパイルに焦点を当てています。そのため、すべてのユーザーにとってGraalVMの ネイティブイメージ を置き換えるものではありません。例えば、MandrelはpolyglotやLLVMツール群をサポートしていませんが、これはいくつかのユースケースで必要とされるかもしれません。しかし、Red HatのエンジニアはアップストリームのGraalVMに貢献しており、アップストリームのGraalVMコードを最新の状態に保つよう努力しています。 MandrelはGraalVMのGitHub組織の一部であり、その組織の一部としてメンテナンスされています。それはGraalVMのエコシステムの一部であり、私たちはそれを変えるつもりはありません。とはいえ、MandrelはQuarkusのようなプロジェクトの持続可能性のニーズを満たすことを目的としています。私たちの主な目標は、Quarkusのエコシステムの一部であるMandrelのバージョンを安定的に保ち、そのエコシステムのライフサイクルを通してサポートすることです。そのため、特定のMandrelバージョンは、通常のアップストリームGraalVM CEビルドよりも長く更新されることになるでしょう。また、MandrelはOpenJDK 11に依存しているため、OpenJDKの四半期ごとのセキュリティ修正に合わせて最新の状態を維持する必要があります。 私たちのGitHubページの Mandrel releases を定期的にチェックしてください。現在、LinuxとWindows用のダウンロードがあります。私たちは通常、UBI 8ベースのLinuxコンテナイメージを quay.io に、GitHubのリリースと同時に、あるいはその後すぐに公開しています。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Debugging GraalVM-native images using gdb | Red Hat Developer の翻訳記事です。 GraalVMプロジェクト には、他の機能に加えて、 GraalVMネイティブイメージ と呼ばれるコンポーネントが含まれています。GraalVMネイティブイメージは、 Java アプリケーションをパッケージした自己完結型のスタンドアロン実行ファイルとして提供することをサポートしており、一般的にJavaネイティブイメージと呼ばれています。ネイティブイメージは、同じアプリケーションを従来の方法でJVM上で実行するのに比べて、フットプリントが小さく、起動時間が早いことが多いです。これは、短時間で実行されるアプリケーションや、小規模な コンテナ ベースのサービスには有利です。トレードオフとして、長時間動作するプログラムではピーク時の パフォーマンス が低下し、大量の生存データを持つプログラムではガベージコレクションのオーバーヘッドと遅延が高くなります。 特に、 Quarkus をベースにしたアプリケーションの代わりのバックエンドへ届ける選択肢として、GraalVMネイティブイメージに興味があります。Javaチームは、 Quarkus がGraalVMネイティブイメージとうまく統合されるように努力してきました。その過程で、配信されたネイティブイメージをデバッグできるかどうかが、重要な使い勝手の問題であることがわかりました。 もちろん、これは主に開発上の問題ではありません。アプリケーションをデバッグするための大変な作業のほとんどは、開発やテストの際にJVM上で行えます。しかし、デプロイされたネイティブイメージの動作が異なる場合、どうすればよいかという問題が常にあります。このようなことはあってはならないことですが、アプリケーションのエラーやビルドの設定に問題があるために起こることもあります。まれに、アプリケーション・コードやJDKランタイム・コードをネイティブ・マシン・コードにコンパイルする際に、ネイティブ・コンパイル・プロセスによってもたらされた不一致が原因で、デプロイされたネイティブ・イメージの動作が異なる場合があります。 デバッグを難しくしているのは、生成されたネイティブ・イメージが、最小限のシンボル情報で高度に最適化されたコードであることです。オリジナルのJavaメソッドのコードの多くはインライン化されているため、特定の命令を元のJavaメソッドに関連付けることは非常に困難であり、Javaソースファイル内の特定のコード行に関連付けることはできません。最高の最適化レベルでコンパイルされ、シンボル情報を持たないCやC++のプログラムと同じくらい、デバッグが困難です。 もちろん、C/C++コンパイラは、バイナリにdebuginfoを埋め込むことで、この問題を解決しています。この情報は、デバッガに対して、生成されたコードをどのように解釈し、元のソースと関連付けるかを正確に伝えます。そこで私は最近、LinuxイメージにDWARFデバッグ情報を追加することで、GraalVMネイティブイメージの問題を解決することにしました。これで、Linuxの標準的なデバッガであるgdbを使って、効果的にソースレベルのデバッグができるようになりました。Windowsバイナリをデバッグするための同等のソリューションは、現在開発中です。 デバッガは、イメージにコンパイルされた Java クラスとメソッドを知ることができます。ブレークポイントは、メソッドの入口やメソッド内の特定の行に置けます。デバッガは、ネイティブ・イメージ内のマシン命令と、Javaファイル内の特定のソース行を関連付けられます。メソッドのコードを一行ごとに停止してステップ実行し、コールスタックを表示できます。命令がインライン化されたメソッドに属するかどうかも把握しており、コードを読み進める際には、外側のコンパイルされたメソッドのソース行とインライン化されたソースコードの間を行き来します。 このデバッグ機能は、 最新のGraalVMリリース に搭載されました。最近、私は Quarkusチャンネル に ビデオプレゼンテーション をアップロードし、実装された内容をより正確に説明しています。このビデオには、小さなJavaプログラムをベースにしたデモが含まれており、デバッグ情報を含むネイティブイメージを構築し、それをgdbで実行/デバッグする方法を示しています。デモを楽しんでいただければ幸いです。また、使い勝手やデバッグ時に発生したエラーについてのフィードバックもお待ちしております。
Red Hat で Solution Architect として OpenJDK を担当している伊藤ちひろ( @chiroito )です。 この記事は、Red Hat Developerのブログ記事、 Set up JDK Mission Control with Red Hat Build of OpenJDK | Red Hat Developer の翻訳記事です。 JDK Mission Controlは、 Red Hat Software Collections (RHSCL)の最新メンバーとなりました。 JDK Mission Control は、HotSpotのJava仮想マシン(JVM)用の強力なプロファイラで、高度なツール群を備えています。これにより、JDK Flight Recorderが収集した広範なデータを効率的かつ詳細に分析できます。このツール群により、開発者や管理者は、OpenJDK 11を使用して本番稼働環境でローカルで実行されている、またはデプロイされている Javaアプリケーション からデータを収集・分析できます。 この記事では、JDK Mission Controlをセットアップする主な例を紹介します。 Linux では、JDK Mission ControlはRHSCLの一部であり、Windowsでは、 Red Hat Customer Portal の OpenJDK のzip配布物の一部として提供されています。 Linuxの場合、この手順ではRed Hat Build of OpenJDK 11がすでにインストールされていることを前提としています。ここでは、RHSCLからソフトウェアをインストールするためのシステムの設定方法を紹介します。これは Red Hat Enterprise Linux の最新の開発技術を提供するものです。そして、JDK Mission Controlをインストールし、簡単なサンプルアプリケーションを実行します。チュートリアル全体の所要時間は10分以内となっています。 Mission Controlのインストール Microsoft Windows の場合 Microsoft Windows では、Red Hat カスタマーポータルで入手できる OpenJDK の zip に JDK Mission Control と JDK Flight Recorder が含まれるようになりました。アーカイブを解凍すると、JMC バイナリは bin ディレクトリに格納されます。 Red Hat Enterprise Linux の場合 root ユーザとして subscription-manager ツールを使用して、コマンドラインからソフトウェアリポジトリを追加または削除できます。利用可能なソフトウェアリポジトリを表示するには、 --list オプションを使用します。また、RHSCL へのアクセス権があることを確認してください。 $ su - # subscription-manager repos --list | egrep rhscl どの種類を使用するか(サーバかワークステーションかなど)によって異なります。以下のコマンドでリポジトリを有効にできます。 # subscription-manager repos --enable rhel-variant-rhscl-7-rpms 以下のコマンドでJMCをインストールします。 $ yum install rh-jmc JMCをインストールしました。JMCと入力するか、アプリケーションメニューから起動できます。 私のように、複数のバージョンのJavaを実行していて、コマンドラインからJMCを起動したい場合は、以下のオプションを使用して、OpenJDKのRed Hat BuildへのパスでJMCを起動します。 $ scl enable rh-jmc bash $ jmc -vm /usr/lib/jvm/java-11-openjdk-11.0.2.7-0.el7_6.i386/bin リアルタイムモニタリング JMCでは、JVMのリアルタイムモニタリングを行えます。これを行うには、ファイルメニューから新しい接続を作成し、JVMを選択して、JMXコンソールを起動します。その結果、プロセッサ、メモリ消費量、Javaヒープ使用量、JVM CPU使用量などの概要ページが表示されるはずです。 さて、JMCの設定ができましたので、例題を実行して動作を確認してみましょう。 以下は、いくつかのファイルを読み込む簡単な例です。確かに、考慮していない問題があるかもしれません。以下の例では、2つのファイルがあります。シンプルなHTMLファイルと、約1GBのテキストファイルです。 import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; public class TextFileReader { private File textFilePath = null ; public TextFileReader(String textFilePath) { if (textFilePath == null ) throw new IllegalArgumentException(); this .textFilePath = new File(textFilePath); } public void readFile() throws IOException { FileReader fileReader = new FileReader(textFilePath); BufferedReader bufferedreader = new BufferedReader(fileReader); StringBuffer sb = new StringBuffer(); String strLine; while ((strLine = bufferedreader.readLine()) != null ) { sb.append(strLine); sb.append( " \n " ); } fileReader.close(); System.out.println(sb.toString()); } public static void main(String[] args) throws IOException{ new TextFileReader( "index.html" ).readFile(); new TextFileReader( "test.txt" ).readFile(); } } 以下のコマンドを実行して、このサンプルをコンパイルして実行してみましょう。 $ javac TextFileReader.java $ java -XX:+FlightRecorder -XX:StartFlightRecording=dumponexit=true,filename=filereader.jfr TextFileReader 上記のJavaコマンドでは,パラメータ -XX:StartFlightRecording で,結果を filereader.jfr にダンプします. このファイルをJMCで開いて、結果を見てみましょう。 JMCは、実行全体に関する掘り下げた詳細な情報を報告します。例えば、JVM内部では、GCが失速していることを示しています。さらに、メモリがあまりない上に大きなファイルでは、それは問題なので、 -XX:InitiatingHeapOccupancyPercent の値を下げるか、さらには、十分なメモリを確保する(例:Xms1024m -Xmx4096m)ことで、問題を解決できます。 また、Red HatのソフトウェアエンジニアであるJie Kang氏による こちら では、メソッドのプロファイリングがどのように機能し、元のコードの最適化に役立っているかが紹介されています。 JMCは、メモリリークやデッドロックなど、アプリケーションの動作を理解するのに非常に役立ちます。Red Hat Build of OpenJDK 11 で試してみてください。
レッドハットで RHEL のテクニカルサポートをしている岡田です。 前回の パート2 では、Performance Co-Pilot (PCP) で取得した複数のホストのパフォーマンスデータを過去のデータも含めて Grafana で可視化する方法をご案内しました。パート3では、BPF を利用したトレーシングツールである bpftrace を PCP と Grafana と組み合わせることによって、これまでのツールでは可視化することが難しかったデータ (例えば1秒あたりに fork されたプロセス数や、ランキューの待ち時間) を可視化する方法をご紹介しています。ぜひご覧ください! www.redhat.com ※ なお上の記事は執筆された時点で最新だった RHEL 8.3 で動作確認が行われています。現在最新の RHEL 8.4 では Grafana の部分の操作方法が若干異なります。RHEL 8.4 でお試しになる場合には併せて以下のドキュメントもご覧ください。 access.redhat.com