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

TECH PLAY

Red Hat  - Open Innovation Labs

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

全900件

こんにちは小杉です。 今回は OpenShift 上で Knative Serving アプリケーションをサンプルプログラムを使って実際に動作させるまでをまとめました。 OpenShift Serverless Operator のインストールと Knative Serving のインストール サーバーレスアプリケーションのデプロイ トラフィック分割 medium.com 今回は Knative Serving のみのご紹介ですが、いずれ Apache Kafka や Camel K(Quarkus) を利用した Knative Eventing についてもご紹介したいと思います。
Red Hatの小島です。 Red Hatが提供するAnsible関連製品は「Red Hat Ansible Automation Platform」という型番1つにまとまっており、この型番を購入することでAnsible Engine、Ansible Tower、 Automation Analystics 、 Automation Hub といった製品/サービスを利用できるようになります。なお、Red Hat Ansible Automation Platformの60日セルフサポート評価版(Red Hatサポートチームによる問い合わせ対応は無し)をWebから簡単に発行できるようになっていますので、これを使ってAnsible TowerをAzure上で利用する方法を紹介していきます。 (1). https://www.redhat.com/en/technologies/management/ansible/try-it にアクセスし、「Download」ボタンをクリックします。すると、Red Hat アカウントのログインまたは作成画面が開きますので、適宜ログインまたはアカウントを作成します。これは Red Hat Customer Portal のアカウントになります。 ログインまたはアカウントを作成すると、自分のRed Hat アカウントに下記のような評価版サブスクリプションが紐付けられます。これはRed Hat Customer Portalの サブスクリプション情報 から確認できます。これで評価版サブスクリプションの入手完了です。 また、Ansible TowerはAzure Marketplaceで提供されているため、テンプレートから簡単にデプロイできるようになっています。これを利用してAnsible TowerをAzureにデプロイします。 azuremarketplace.microsoft.com (2). Microsoft Azure Portalにログイン、またはアカウントを作成します。 azure.microsoft.com そしてAzure MarkeplaceからAnsible Towerを選択し、作成をクリックします。 (3). Ansible Towerのテンプレートから仮想マシンを作成するのに必要なパラメータを入力します。必要なパラメータを入力して最後に利用規約に同意したら「作成」をクリックします。下記の例では「ansibletowervm」という名前のAnsible Tower仮想マシンを作成しています。 各パラメータ: VM Admin User Name: 仮想マシンにSSHログインするときに利用するユーザ名。sudo でroot権限を利用可能。 SSH Public Key for VM Admin User: SSHログインするときに利用するSSH公開鍵。 サブスクリプション: Azure Portalのアカウントに紐付けられているサブスクリプション。 リソースグループ: Ansible Tower仮想マシンを配置するリソースグループ。下記の例では、「ansible-rg」を新規作成。 場所: Ansible Tower仮想マシンを起動するリージョン。 Ansible Tower VM Name/size: Ansible Tower仮想マシンの名前と、CPU/メモリリソース割当のサイズを指定。 Password for Ansible Tower Console Admin: Ansible Towerの管理権限を持つ「admin」ユーザのパスワード。 Password for Ansible Tower Database: Ansible Towerが内部で利用しているPostgreSQLのパスワード。 ※ 参考: ssh-keygenコマンドを利用した、SSH公開鍵/秘密鍵の作り方 $ mkdir ~/tmp $ ssh-keygen -f ~/tmp/id_rsa -N '' $ ls -a ~/tmp . .. id_rsa id_rsa.pub $ cat ~/tmp/id_rsa.pub <- SSH公開鍵の中身を表示 ssh-rsa AAAAB3NzaC1yc2E... 作成完了したら、Azure Portalの仮想マシン一覧の画面からAnsible Tower仮想マシンを選択して、接続するために必要な情報を確認できます。下記の場合だと、「hkojima」ユーザとAnsible Towerのパブリックなホスト名を利用してSSHログインするコマンド例を表示しています。 (4). Ansible TowerのWebコンソールにログインします。 https://<SSHログイン時に指定するパブリックなホスト名> にアクセスすると、Ansible Towerのログイン画面が表示されますので、 ユーザ名: admin パスワード: (3). のPassword for Ansible Tower Console Admin で指定したパスワード でログイン TOWER LICENSEのユーザ/パスワードの入力フィールドに、(1).の手順で利用したRed Hat アカウント情報を入力して「ライセンスの取得」をクリック Automation Platform評価版サブスクリプションを選択 「使用許諾契約書に同意します」にチェックを入れて「送信」 すると、Ansible Towerの機能が使えるようになります。これ以降は、 Ansible Towerのユーザーガイドや管理ガイド を随時参照しながら利用してみてください。 (5). Ansible Tower仮想マシンを削除する場合は、(3). の手順で作成したリソースグループを丸ごと削除します。下記の例では、「ansible-rg」という名前のリソースグループを削除することで、Ansible Towerの仮想マシンやIPアドレスなどのリソースを一括削除しています。 ※ 評価期間が終了した後もAnsible Towerをご利用される場合は、Red Hat Ansible Automation Platform サブスクリプションをご購入ください。執筆時点では、Azureの利用料金の中にAnsible Automation Platformサブスクリプションの利用料金は 含まれていませんので、Azuerの利用料金とは別料金 になります。ご注意ください。
こんにちは Red Hat 小杉です。 Red Hat Integration 2020-04 がリリースされ、Debezium もリリースとなりました。 Tech Preview のときに紹介した内容も含めて再度ユースケースをご紹介します。 medium.com Developer Channel で Webinar も開催していますので興味があれば参加してみてください。 www.redhat.com
この記事は、Quarkus.io のブログ記事、 Quarkus 1.3 and Eclipse MicroProfile 3.3 の翻訳記事です。 Quarkus 1.3が利用可能になったという発表とともに、私たちはQuarkus 1.3がEclipse MicroProfile 3.3の全仕様のTCKに合格したことを追加で発表します。 MicroProfile 3.3には次の仕様アップデートが含まれます。 Config 1.4 Fault Tolerance 2.1 Health 2.2 Metrics 2.3 REST Client 1.4 Config Configの更新には、ConfigProviderResolverの不正なキャッシュを防ぐための修正と、それに関連するクラスローダの問題も含まれます。 また、暗黙的コンバータの優先度を調整し、byte,short,char用のコンバータを追加しました。優先度の変更は、暗黙的な変換がコンストラクタを使用する前に静的メソッドを使用することを意味します。 Fault Tolerance CircuitBreakerとFallbackはどちらもskipOnプロパティを追加し、FallbackはapplyOnプロパティを追加して、呼び出し側への動作または通過をきかっけとする例外を定義できるようにしました。なぜこれが重要なのでしょうか? 実際の使用例では、特定の例外に対する高可用性戦略を起動する必要があり、また、戦略が適用されないようにするために、他の例外を通常として扱うことができます。 Health すべての修飾子にAnnotationリテラルを追加してプログラムによる検索を容易にし、HealthCheckResponseを具象クラスに切り替えて利用側で使用できるようにするなど、いくつかの小さな更新が含まれています。 Metrics 平均および分布計算を実行しない@SimplyTimedが追加されました。メソッドに費やされたヒット数と時間のみを計算します。@SimplyTimedは、Prometheusが@SimplyTimedの生データを使用して計算を実行できるため、計算時間を短縮する@Timedの「単純な」バージョンです。 仕様では、JAX-RS呼び出しに固有のオプションのメトリックも定義しています。JAX-RSメソッドごとにSimple Timerがあるので、リクエストの合計数とそのメソッドにかかった合計時間を測定します。 この仕様では、JVMが占有するCPU時間を追跡する、もう1つのオプションの基本メトリックProcessCpuTimeも追加されています。この値はJDKインタフェースからは使用できず、Sunの内部インタフェースからのみ使用できるため、オプションです。 REST Client 今回のリリースでは、ClientHeadersFactoryへのCDI注入をサポートすることが仕様の要件であると定義しています。これにより、以前は@Injectをクラスに挿入できなかった隔たりが解消されます。 インジェクションポイントの@RestClient修飾子に@Targetが指定され、Kotlinでの使用が可能になりました。以前のリリースでこの問題に悩まされたQuarkusユーザの多くはKotlinを使っています。 Standalone MicroProfileプラットフォーム内の仕様に加えて、QuarkusはReactive Streams Operators、Reactive Messaging、Context Propagationの実装も含んでいます。ImperativeでもReactiveでも、Quarkusには必要なものが揃っています。 近い将来、Quarkusは長時間実行アクションとGraphQLのための新しいスタンドアロン仕様の実装も開始するでしょう。 要約 Quarkus 1.3のリリースは、SmallRyeにMicroProfile仕様を実装し、それをQuarkusで利用するという私たちの約束を継続するものです。開発者が必要としているものを提供できるように、MicroProfileの機能に関するフィードバックを提供してください。主要な機能が不足している場合は、お知らせください!
Red Hatのもえわきです。Red Hatローカライゼーションチーム(各国の言語への翻訳を担当する部署)でRHELの翻訳プロジェクトコーディネーター兼トランスレーターをしています。 Red Hatは、製品の拡充とともに、各国へのローカライゼーションに迅速に対応できないという課題がありました(マイナーバージョンごとにドキュメントが更新されるため、「製品の拡充 x リリースされるバージョン」とドキュメントの数は膨大)。その中で、新たな試みとして、機械翻訳を積極的に活用するプロジェクトが立ち上がりました。今回、ローカライゼーションのRHELチームが機械翻訳の適用にあたって取り組んできた裏話をご紹介したいと思います。 もくじ RHEL 8から始まった「機械翻訳」プロジェクト: 目標は、日本語版の「全冊公開」 機械翻訳を活用してRHELの日本語翻訳版を定期更新できるようになるまでの軌跡 まずは、機械翻訳を活用してRHEL 8を全冊公開 RHEL 7.7への対応と、人の手によるRHEL 8の再翻訳 RHEL 8.1のGA公開と、可能になった「定期更新」 活動の幅を広げる そして、新たな試み: Red Hat Insightsでの「機械翻訳+α」 最後に RHEL 8から始まった「機械翻訳」プロジェクト: 目標は、日本語版の「全冊公開」 RHELはRed Hatのコア製品であり、多くのお客様にご利用頂いております。昨年、メジャーバージョンであるRHEL 8がリリースされ、今月2つ目のマイナーバージョンであるRHEL 8.2がリリースされます。それにあわせて、RHELの英語ドキュメントを制作するライティングチームが増員され、毎月かなりの量が追加公開されています。 一方で、RHEL翻訳チームは少人数で対応しています。このため、これまでは一般公開日(GA)に一部のドキュメントを公開し、その後残りを少しずつ公開するという方法を選択しており、「読みたいのに日本語がない(古い)」というご指摘をいただくことも少なくありませんでした。 このようなご指摘に対応するため、昨年メジャーバージョンであるRHEL 8のGAにあわせ、多くの日本語ドキュメントを公開するプロジェクトを立ち上げました(その軌跡は以下のページ)。 rheb.hatenablog.com この取り組みは成功しましたが、いくつかの課題が残りました。 RHEL 8ドキュメントのうち1/3が翻訳されていない RHEL 8の英語ドキュメントの更新速度に追いつかない RHEL 8を準備している間RHEL 7の日本語ドキュメントが更新されず古くなっていた これを解消するため、私たちは機械翻訳を積極的に活用することを模索し始めました。 機械翻訳を活用してRHELの日本語翻訳版を定期更新できるようになるまでの軌跡 まずは、機械翻訳を活用してRHEL 8を全冊公開 最初に取り組んだのが「機械翻訳+簡単なポストエディット」で残りのRHEL 8を翻訳して公開。ポストエディットというのは、機械翻訳で作成された訳文を人間の手で修正する作業のことで、昨今、翻訳業界でその手法や問題点が活発に議論されています。RHELチームは、RHEL 8のGAに向けて日本オフィスから吸い上げた意見をもとに、「最低限の修正だけ行い最短期間で公開」という形をとり、本来人間の手だけでは数か月かかる量を数日で公開しました。これによりGA後2ヶ月以内にRHEL 8全冊公開となりました。初めての試みで、しかも待望のメジャーバージョン。公開にあたっては多少の心配もありましたが、想像していた以上に温かいお言葉をたくさんいただきました。 RHEL 7.7への対応と、人の手によるRHEL 8の再翻訳 この頃の機械翻訳の品質は、以前と比べると飛躍的に良くなっていましたが決して十分とはいえず、翻訳者による再翻訳が必須となっていました。さらには、目の前に迫ってきたRHEL 7.7のGA。RHEL翻訳チームも念願の増員を果たし、RHEL 7.7でのGA公開と、RHEL 8の再翻訳を同時にすすめていきました。 RHEL 8.1のGA公開と、可能になった「定期更新」 RHEL 7が終わると、今度はRHEL 8.1に向けて、RHEL 8のGAで公開したドキュメントの更新、そして翻訳者が再翻訳したドキュメントの更新が目の前に立ちはだかりました。さらに、この頃には、社内でも私たちの取り組みが知られるようになり、「RHEL 7のドキュメントが古いので更新してほしい」としたリクエストも徐々に増えてきました。そのため、お客様と弊社社員、また弊社社員とRHEL翻訳チームのやりとりを円滑にすすめるために、翻訳周期をGAより短い「RHEL 8を毎月更新、RHEL 7を毎四半期(弱)更新」に設定して社内へ周知。RHEL 8だけでなくRHEL 7も、更新頻度は高くなってきました。これは、機械翻訳自体の品質が改善されたのに加え、翻訳者の「機械翻訳+十分なポストエディット」ノウハウも蓄積されてきて非常に効率的に作業できるようになったことで可能になりました。 活動の幅を広げる 並行して、昨年力をいれたのが「業界からの情報収集」と「社内外への情報発信」です。翻訳関連のイベントに参加して、機械翻訳に取り組んでいる企業と積極的に情報交換を行い、また弊社の社内外向け各種イベントにも参加し、また時には登壇して自分たちの取り組みを紹介し、さまざまな意見を集め、今後の方向性を模索していきました。同時に、翻訳作業もRHELを超えて対応できるようになりました。少しずつではありますが、ご提供できる量は確実に増えています。私自身も翻訳プロジェクトコーディネーターとして対応する製品が増え、今年はAnsible(TowerとEngine)の強化に尽力することになりました。 そして、新たな試み: Red Hat Insightsでの「機械翻訳+α」 昨年皆様から承ったさまざまなご意見により、今年私たちは大きな節目を迎えます。その先駆けとして、先日、RHELの関連製品であるRed Hat Insightsで以下の試みが行われました。 「機械翻訳+システマティックな後修正+簡単なポストエディット」による迅速な公開 RHEL 8のときと何が違うのか。まず、スクリプト等を多用して、翻訳者が作業しやすい環境を作り効率化を目指す。機械翻訳の「くせ」を自動修正または検出し、検出されたものを翻訳者が修正する。最後に大きな間違いが残っていないかを自動検出して確認する。これにより、RHEL 8のときと比べ、短時間の「+簡単なポストエディット」でも品質が飛躍的に向上しました。今後は、エンジンを効果的に学習させ、複数のエンジンを使い分けることも視野にいれています。 さらには、このようにして培ってきたノウハウを、Insightsだけでなく、RHELやAnsibleにも無理のない形で積極的に取り入れていくことで、「定期更新」よりも短い「即時対応」も可能になってくるでしょう。 最後に RHEL翻訳チームは、「読みたいのに日本語がない、こんな経験が少しでもなくなれば」を合言葉に、機械翻訳という非常に強力なツールを賢く取り入れるさまざまな取り組みを行ってきました。「+簡単なポストエディット」は「100%機械翻訳」ではありません。しかし、通常の翻訳作業(および「+十分なポストエディット」)とも異なります。多少言い回しが気になる訳文も見つかるでしょう。それでも、私たちは、日本のお客様、パートナー様にいち早く日本語版を届け、早期にフィードバックを得るという点を重視し、これからもより良い方法を模索し続けます。翻訳に問題がある場合はお気軽にご相談ください。 引き続き、より多くの方にRHELおよび関連製品をご利用いただければと思います。 なお、Red Hatの製品ドキュメントは購入前からすべて閲覧できます。ぜひ導入前からご参照ください。 access.redhat.com
Podmanがどのようにしてユーザ名前空間を利用してルートレスモードで動作するのかを説明します。 この記事は How does rootless Podman work? | opensource.com を翻訳したものです。 RHEL 7.8以降およびRHEL 8.1以降ではこの記事で紹介されているユーザ名前空間を活用した rootless container がフルサポートとなっていて、利用できます。 :::11 Feb 2019 Daniel J Walsh ::: Image by: Opensource.com   前回 のユーザ名前空間と Podman についての記事では、Podmanコマンドを使って異なるユーザ名前空間で異なるコンテナを起動し、コンテナ間の分離を改善する方法について説明しました。Podmanはまた、ユーザ名前空間を利用してルートレスモードで実行できるようにしています。基本的に、非特権ユーザがPodmanを実行すると、ユーザ名前空間を設定してそこへ参加します。Podmanがユーザ名前空間内でrootになった後、Podmanは特定のファイルシステムをマウントし、コンテナをセットアップすることができます。ここでは、以下で説明するユーザが利用可能なUIDを追加する以外には、特権のエスカレーションはありません。 Podmanはどのようにしてユーザ名前空間を作成するのですか? shadow-utils 現在のほとんどの Linux ディストリビューションには、 /etc/subuid と /etc/subgid ファイルを使用して、ユーザ名前空間内のユーザが利用できる UID と GID を決定する shadow-utils の実装が含まれています。 $ cat /etc/subuid dwalsh:100000:65536 test:165536:65536 $ cat /etc/subgid dwalsh:100000:65536 test:165536:65536 useraddプログラムは、システムに追加されたユーザごとに65536個の UIDを自動的に割り当てます。システムに既存のユーザがいる場合は、自分でUIDを割り当てる必要があります。これらのファイルの形式は、 username:STARTUID:TOTALUIDS です。つまり、私の場合、dwalshにはUID 100000から165535までのUIDが割り当てられ、それに加えて私のデフォルトUIDが/etc/passwdで定義されている3265になります。これらのUID範囲を割り当てる際には、システム上の 実際の UIDと重ならないように注意する必要があります。UID 100001 としてリストアップされたユーザがいた場合、私 (dwalsh) はこの UID になり、潜在的に UID が所有するファイルを読み書きしたり実行したりすることができます。 Shadow-utils はまた、2つの setuid(または setfilecap) プログラムを追加します。Fedora では、このようになります。 $ getcap /usr/bin/newuidmap /usr/bin/newuidmap = cap_setuid+ep $ getcap /usr/bin/newgidmap /usr/bin/newgidmap = cap_setgid+ep Podmanはこれらのファイルを実行してユーザ名前空間を設定します。ルートレスコンテナの中から /proc/self/uid_map と /proc/self/gid_map を調べることでマッピングを見ることができます。 $ podman run alpine cat /proc/self/uid_map /proc/self/gid_map         0       3267         1         1       100000         65536         0       3267         1         1       100000         65536 上で見たように、Podmanはコンテナ内のルートを現在のUID (3267)にマッピングするのがデフォルトで、その後、/etc/subuidと/etc/subgidに割り当てられたUID/GIDの範囲を1からマップします。 つまり、私の例では、コンテナ内のUID=1はUID 100000で、UID=2はUID 100001で、同様に65536は165535に対応するまで続きます。 ユーザ名前空間の外から、ユーザ名前空間にマッピングされていない UID や GID が所有するアイテムは、 kernel.overflowuid sysctl で設定されたユーザに属しているように見えますが、これはデフォルトでは 65534 で、私の /etc/passwd ファイルでは nobody という名前が付いています。あなたのプロセスはマッピングされていない ID として実行できないので、所有者とグループのパーミッションは適用されず、「その他」のパーミッションに基づいてしかファイルにしかアクセスできません。rootはユーザ名前空間にマッピングされていませんから、これには、コンテナを実行しているシステム上で 実際の root が所有するすべてのファイルが含まれます。 Buildah コマンドには buildah unshare というクールな機能があります。これにより、Podmanが実行しているのと同じユーザ名前空間に入ることができますが、コンテナのファイルシステムには入らないので、ホームディレクトリの内容を一覧表示することができます。 $ ls -ild /home/dwalsh 8193 drwx--x--x. 290 dwalsh dwalsh 20480 Jan 29 07:58 /home/dwalsh $ buildah unshare ls -ld /home/dwalsh drwx--x--x. 290 root root 20480 Jan 29 07:58 /home/dwalsh ユーザ名前空間の外でホームディレクトリの属性をリストアップすると、カーネルは所有権を dwalsh として報告しますが、ユーザ名前空間内ではディレクトリを root が所有していると報告することに注意してください。これは、ホームディレクトリが3267によって所有されており、ユーザ名前空間内ではそのUIDをrootとして扱っているからです。   ユーザ名前空間を設定した後、Podmanでは次に何が起こるのでしょうか? Podmanはコンテナイメージを引き出すために containers/storage を使用します。containers/storageは賢いので、イメージ内のrootが所有するすべてのファイルをユーザ名前空間のrootにマップし、異なるUIDが所有するその他のファイルをユーザ名前空間のUIDにマップします。デフォルトでは、この内容は ~/.local/share/containers/storage に書き込まれます。コンテナストレージは、ルートレスモードで vfs モードまたはオーバーレイで動作します。Note: Overlay は fuse-overlayfs 実行ファイルがインストールされている場合にのみサポートされます。 カーネルはユーザ名前空間のrootには特定のタイプのファイルシステムをマウントすることだけを許可しています。現時点では以下が利用できます: procfs, sysfs, tmpfs, fusefs, bind mount (ソースとデスティネーションの両方を Podman を実行しているユーザが所有している場合のみ。OverlayFSはまだサポートされていませんが、カーネルチームが許可できるように取り組んでいます。) 。 fuse-overlayfsを利用している場合、Podmanはコンテナのストレージをマウントします。ストレージドライバがvfsを使用している場合はマウントの必要はありません。しかし、vfs上でPodmanを使用すると、各コンテナは基盤となるファイルシステム全体をコピーするため、多くのスペースを必要とします。 Podmanは/procと/sysをいくつかのtmpfsと共にマウントし、コンテナ内のデバイスを作成します。 ホストネットワーク以外のネットワークを使用するために、Podmanは slirp4netns プログラムを使用して、 特権のないネットワーク名前空間用のユーザモードネットワーク を設定します。slirp4netnsを使用すると、Podmanはコンテナ内のポートをホストに公開することができます。ただし、カーネルは1024以下のポートに非特権プロセスをバインドすることを許可しません。ポートへのバインドにはPodman-1.1以降が必要です。 Rootless Podmanはコンテナの分離にユーザ名前空間を使用することができますが、/etc/subuidファイルで定義されたUIDにしかアクセスできません。 結論 Podmanツールは、システムのセキュリティを犠牲にすることなくコンテナを構築して使用することを可能にします。開発者にroot権限を与えずに必要とするアクセスを可能にできます。   また、コンテナを本番環境に投入する際には、ユーザ名前空間によって提供される追加のセキュリティを利用して、ワークロードを互いに分離しておくことができます。   この 記事 は クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンス の下に提供されています。
この記事は Podman and user namespaces: A marriage made in heaven | Opensource.com を翻訳したものです。RHEL 7.8以降およびRHEL 8.1以降ではこの記事で紹介されているユーザ名前空間を活用した rootless container がフルサポートとなっていて、利用できます。 Podmanを使用して別のユーザ名前空間でコンテナを実行する方法を学びます :::2018年12月13日 Daniel J Walsh (Red Hat) ::: 画像: opensource.com   libpod ライブラリの一部であるPodmanを使うことで、ユーザはポッドやコンテナ、コンテナイメージを管理することができます。前回の記事では、 コンテナをより安全に実行する方法としてPodmanについて書きました 。ここでは、Podmanを使ってコンテナを別々のユーザ名前空間で実行する方法を説明します。 私は、主にRed HatのEric Biederman氏が開発したユーザ名前空間を、コンテナを分離するための素晴らしい機能だと常々考えていました。ユーザ名前空間では、ユーザ識別子(UID)とグループ識別子(GID)のマッピングを指定してコンテナを実行することができます。つまり、コンテナ内ではUID 0、コンテナ外ではUID 100000として実行できます。コンテナプロセスがコンテナを脱出した場合、カーネルはUID 100000として扱います。それだけでなく、ユーザ名前空間にマッピングされていないUIDが所有するファイルオブジェクトは「nobody」(65534、kernel.overflowuid)が所有するものとして扱われ、そのオブジェクトが「other」(world readable/writable)でアクセス可能でない限り、コンテナプロセスはアクセスを許可されません。 "本物の" root が所有するファイルをパーミッション 660 で持っていて、ユーザ名前空間のコンテナプロセスがそれを読もうとした場合、そのファイルへのアクセスは阻止され、そのファイルは nobody が所有するものとして表示されます。 例 これがどのように機能するかを示します。まず、rootが所有するシステムにファイルを作成します。 $ sudo bash -c "echo Test > /tmp/test" $ sudo chmod 600 /tmp/test $ sudo ls -l /tmp/test -rw-------. 1 root root 5 Dec 17 16:40 /tmp/test 次に、ユーザ名前空間マップ0:100000:5000で実行されているコンテナにファイルをボリュームマウントします。 $ sudo podman run -ti -v /tmp/test:/tmp/test:Z --uidmap 0:100000:5000 fedora sh # id uid=0(root) gid=0(root) groups=0(root) # ls -l /tmp/test -rw-rw----. 1 nobody nobody 8 Nov 30 12:40 /tmp/test # cat /tmp/test cat: /tmp/test: Permission denied 上の --uidmap 設定は、コンテナの外側のUID 100000から始まるコンテナ内の5000のUIDの範囲(つまり範囲は100000-104999)からコンテナ内のUID 0から始まる範囲(つまり範囲は0-4999)までをマップするようにPodmanに指示します。コンテナ内では、私のプロセスがUID 1として実行されている場合、ホスト上では100001です。 本物の UID=0 がコンテナ内にマッピングされていないため、root が所有するファイルは誰も所有していないものとして扱われます。コンテナ内のプロセスが CAP_DAC_OVERRIDE を持っていても、この保護を上書きすることはできません。 DAC_OVERRIDE を使用すると、ルートプロセスが所有していなくても、システム上の任意のファイルを読み書きできるようになりますし、そのプロセスがルートが所有していなくても、ワールドが読み書きできるようになっていなくても、読み書きできるようになります。 ユーザ名前空間でのケーパビリティは、ホスト上でのケーパビリティとは異なります。それらは名前空間内でのケーパビリティです。つまり、私のコンテナのルートは、コンテナ内でのみ、つまりユーザ名前空間にマップされた UID の範囲内でのみ能力を持っています。コンテナプロセスがコンテナから脱出した場合、UID=0 を含め、ユーザ名前空間にマップされていない UID に対しては何の能力も持ちません。 プロセスが何らかの方法で別のコンテナに入ることができたとしても、コンテナが異なる範囲の UID を使用している場合は、それらの能力を持つことはできません。 注意: SELinux や他の技術でも、コンテナプロセスがコンテナから抜け出した場合にできることを制限しています。 `podman top`を使用してユーザ名前空間を表示 コンテナ内で実行しているプロセスのユーザ名を調べて、ホスト上の本当の UID を識別できるように、 podman top に機能を追加しました。 まず、UIDマッピングを使ってスリープコンテナを実行してみましょう。 $ sudo podman run --uidmap 0:100000:5000 -d fedora sleep 1000 次に podman top を実行します。 $ sudo podman top --latest user huser USER HUSER root 100000 $ ps -ef | grep sleep 100000   21821 21809  0 08:04 ?     00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000 podman top のレポートによると、ユーザプロセスはコンテナ内では root として実行されているが、ホスト (HUSER) では UID 100000 として実行されていることに注意してください。また、psコマンドでスリーププロセスがUID 100000で実行されていることを確認しています。 ここで、2つ目のコンテナを実行してみますが、今回は200000から始まる個別のUIDマップを選択します。 $ sudo podman run --uidmap 0:200000:5000 -d fedora sleep 1000 $ sudo podman top --latest user huser USER   HUSER root   200000 $ ps -ef | grep sleep 100000   21821 21809  0 08:04 ?     00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000 200000   23644 23632  1 08:08 ?     00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000 podman top のレポートでは、2 つ目のコンテナはコンテナ内では root として実行されていますが、ホスト上では UID=200000 として実行されていることに注意してください。 また、 ps コマンドを見てみると、それぞれのsleepプロセスについてひとつは 100000で、もう一つは 200000 で動作していることがわかります。 これは、別々のユーザ名前空間内でコンテナを実行することで、伝統的なプロセス間の UID 分離が可能になることを意味しています。 ユーザ名前空間の問題 私は数年前から、誰もが欲しがるセキュリティツールとしてユーザ名前空間を提唱してきましたが、ほとんど誰も使っていませんでした。理由は、ファイルシステムのサポートやシフトファイルシステムがなかったからです。 コンテナでは、多くのコンテナ間でベースイメージを共有したいです。上の例では、それぞれの例でFedoraのベースイメージを使用しています。Fedora イメージ内のほとんどのファイルは実在の UID=0 で所有されています。 このイメージ上でユーザ名前空間 0:100000:5000 でコンテナを実行した場合、デフォルトではこれらのファイルはすべて誰も所有していないとみなされるので、ユーザ名前空間に合わせてこれらの UID をすべてシフトする必要があります。私は何年も前から、カーネルにこれらのファイル UID をユーザ名前空間に一致するようにリマップするように指示するマウントオプションが欲しいと思っていました。アップストリームカーネルストレージの開発者は、この機能について調査を続け、進歩を遂げていますが、難しい問題です。 Podman は、Nalin Dahyabhai が率いるチームによって containers/storage に組み込まれた自動 chowning により、同じイメージ上で異なるユーザ名前空間を使用することができます。Podmanはcontainers/storageを使用しますが、Podmanが初めてコンテナイメージを新しいユーザ名前空間で使用すると、containers/storageはイメージ内のすべてのファイルをユーザ名前空間にマッピングされたUIDに「chowning」(つまり所有権を変更)し、新しいイメージを作成します。これを fedora:0:100000:5000 イメージと考えてください。 Podmanが同じUIDマッピングを持つイメージ上で別のコンテナを実行すると、"pre-chowned "イメージを使用します。2つ目のコンテナを0:200000:5000で実行すると、containers/storageは2つ目のイメージを作成します。 podman build や podman commit を行っていて、新しく作成されたイメージをコンテナレジストリにプッシュすると、Podman は containers/storage を使ってシフトを逆にして、すべてのファイルが chowned されたイメージを実際の UID=0 に戻してプッシュすることに注意してください。 これは、イメージ内のファイル数に応じて chown が遅くなる可能性があるため、新しい UID マッピングでのコンテナ作成が本当に遅くなる可能性があります。また、通常の OverlayFS では、イメージ内の全てのファイルがコピーされます。通常の Fedora イメージでは、chown を終了してコンテナを起動するのに 30 秒かかることがあります。 幸いなことに、Vivek Goyal と Miklos Szeredi を中心とした Red Hat カーネルストレージチームは、カーネル 4.19 で OverlayFS に新機能を追加しました。この機能は、 metadata only copy-up と呼ばれるものです。マウントオプションとして metacopy=on を指定してオーバーレイファイルシステムをマウントした場合、ファイル属性を変更しても下位レイヤのコンテンツはコピーアップされません; カーネルは下位レイヤのデータを指す参照を含む属性を含む新しい inode を作成します。カーネルは下位レベルのデータを指す参照を含む属性を含む新しい inode を作成します。コンテンツが変更されれば、コンテンツはコピーアップされます。この機能は Red Hat Enterprise Linux 8 Beta で利用可能です。 これは、コンテナのchowningが数秒でできることを意味し、各コンテナのストレージ容量が2倍になることはありません。 これにより、Podman のようなツールでコンテナを別のユーザ名前空間で実行することが可能になり、システムのセキュリティが大幅に向上します。 今後 Podmanに --userns=auto のような新しいフラグを追加して、実行するコンテナごとにユニークなユーザ名前空間を自動的に選択するように指示したいのですが、これはSELinuxがマルチカテゴリセキュリティ(MCS)ラベルを分離して動作する方法に似ています。これは、SELinuxがマルチカテゴリセキュリティ(MCS)ラベルを個別に設定して動作する方法に似ています。環境変数 PODMAN_USERNS=auto を設定すれば、フラグを設定する必要すらありません。 Podmanはついに、ユーザが別々のユーザ名前空間でコンテナを実行できるようになりました。 Buildah や CRI-O のようなツールも、ユーザ名前空間を活用できるようになるでしょう。ただし、CRI-Oについては、Kubernetesがどのユーザ名前空間でコンテナエンジンを実行するのかを理解する必要があり、上流ではそれに取り組んでいます。 次回の記事では、ユーザ名前空間で非rootとしてPodmanを実行する方法を説明します。   この 記事 は クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンス の下に提供されています。
この記事は、Quarkus.io のブログ記事、 Quarkus 1.3.1.Final released - Bugfixes, JDK 11 by default の翻訳記事です。 今日、1.3 .0.Finalのバグフィックス版である1.3 .1.Finalがリリースされました。このバージョンにはバグ修正とドキュメントの改善が含まれており、Java11を新たに生成されるプロジェクトのデフォルトターゲットにしています。 これは1.3 .0を使っているすべての人にとって安全なアップグレードです。 何が新しいの? Java 11 がデフォルトに これは1.3.0.Final での見落としであり、1.4 を待たずに今すぐ修正しました。 これ以降、新しく生成されるプロジェクトは、デフォルトでJava11をターゲットとし、 https://code.quarkus.io/ によって生成されるものも含まれます。これは、デフォルトのコンテナイメージがすべてJava11にアップグレードされたことも意味します。 ただし、Java8を使用してローカルにプロジェクトを作成する場合、そのプロジェクトのターゲットはJava8のままです。 1.4 ではJava 8のサポートを非推奨にする予定です。Java 8をQuarkusとともに使用している場合は、警告が表示されます。私たちはJava 8のサポートをいくつかのリリース、おそらく1.6 頃に廃止する予定です。 MongoDBクライアントのsocket-timeoutがread-timeoutに変更 quarkus.mongodb.socket-timeout設定プロパティーは以前は無視されていました。これを修正して、より正確にするためにquarkus.mongodb.read-timeoutに名前を変更しました。 これを使用すると、プロパティが適用されていないという警告が表示されますが、動作は以前と同じで、プロパティは適用されません。設定したい場合は、古い名前を新しい名前に置き換えてください。 バグ修正とドキュメントの改善 1.3.1.Final の完全な変更ログはGitHubで入手できます。 参加しよう 私たちはあなたのフィードバックをとても大切にしていますので、バグを報告し、改善を依頼してください...一緒に何か素晴らしいものを作りましょう! Quarkusのユーザーや好奇心の強い人は、恥ずかしがらずに歓迎コミュニティに参加してください。 GitHub にフィードバックを提供する; コードを作成して PRを行う ; Zulip や メーリングリスト で議論する; なにか質問があれば Stack Overflow で投稿してください。
この記事は Red Hat Developer の Support lifecycle for Clang/LLVM, Go, and Rust in Red Hat Enterprise Linux 8 を、許可をうけて翻訳したものです。 :::Tom Stellard 2019年11月7日:::   Red Hat Enterprise Linux(RHEL)8.1.0に は、 コンパイラツールチェーン の新しいバージョンを開発者に提供するアプリケーションストリーム、llvm-toolset、 go-toolset 、rust-toolsetが含まれています。これらのアップストリームプロジェクトは、LLVMとGoの場合は6か月ごと、Rustの場合は6週間ごと(!)の新機能リリースで非常に迅速に変化しています。これらのツールチェーンを取り巻くコミュニティーでは、ユーザーが常に最新のリリースを最新の状態に保つことを奨励しています。この状況をふまえて、私たちは可能なかぎり早くRed Hat Enterprise Linuxに新しいバージョンを導入しようとしています。 サポートの観点では、私たちはこれらのアプリケーションストリームを RHEL 8 のライフサイクル中維持します。定期的に新しいアップストリームリリースに更新することにより、ストリーム内に新機能とバグ修正を提供します。 llvm-toolsetとgo-toolsetの場合、ストリームの更新は6か月ごとに期待でき、rust-toolsetの場合は3か月ごとの更新が期待できます。 GoおよびRust言語は進化し続け、コンパイラーの更新ごとに新しい機能を追加しています。そのため、多くのユーザーがコンパイラーの最新バージョンを入手したがっています。同時に、これらのコンパイラは古いコードとの互換性を維持するように設計されています。したがって、RHEL 8アプリケーションストリーム内でGoとRustの新しいバージョンに進んでも、コンパイル可能にするためにコードベースを修正する必要はありません。 GoまたはRustアプリケーションストリームを使用して有効なコードをコンパイルしたら、RHEL 8の全期間にわたってそのストリームを使用してコンパイルできると想定できます。 最新かつ最高の新しいコンパイラテクノロジーを継続的に提供できることを嬉しく思います。 LLVM、Go、Rustを使用して何ができるかについては、Red Hat Developerブログをお楽しみに。  
Red Hat 小杉です。 本日はドメイン駆動設計(DDD)と Red Hat について書いてみました。 medium.com ドメイン駆動設計を考慮して設計したいと思われている方は是非 Red Hat にお声がけください。
この記事は、Quarkus.io のブログ記事、 Quarkus 1.3.0.Final released - New class loader infrastructure, GraalVM 20 support and much much more の翻訳記事です。 お気づきでないかもしれませんが、新しいクラスローダーインフラストラクチャを検証するために、いくつかの大規模なテストフェーズを実施しており、前回のQuarkusのメジャーリリースから2ヶ月弱が経過しています。 我々のAlphas/CRをテストし、フィードバックを提供してくれた全ての人に感謝します。 2ヶ月?Quarkusの世界ではそれが多いので、新しいことを期待しよう。 はじめに、1.3が世界にもたらすものを見てみましょう。 移行ガイド 既存のアプリケーションを移行したいとお考えですか?ここに 1.3.0.Finalの移行ガイドがあります 。 何が新しいの? 新しいクラスローダーインフラストラクチャ Quarkusの革新的な性質(特にテスト・インフラストラクチャーと開発モードでは)のために、クラス読み込みの問題が何度か発生しました。 Quarkus 1.3には全く新しいクラスのローディング・インフラが付属しており、私たちが抱えていた構造上の問題を解決してくれます。新しいクラス読み込みインフラストラクチャについては、『 クラス読み込みリファレンスガイド 』で詳しく説明しています。 この新しいインフラストラクチャは、AlphaとCRフェーズで調整したので、現在はかなり安定しています。クラスの読み込みで奇妙な問題が発生した場合は、リプロデューサーに報告してください。これらの修正は、今後の1.3 .1にすべて含まれます。 すべてを支配する1つのVert.x Quarkus内のすべてを処理するために、Vert.xインスタンスを2つではなく1つにすることにかなりの労力が費やされました。この作業の背後にある考え方は、できれば何も変更せずに、リソースの消費を減らすことです。 バナー デフォルトでは、Quarkusの起動時にASCIIアートのバナーが表示されるようになりました。 もちろん、次のことが可能です。 それをカスタマイズする。 特定のプロジェクトに対して無効にします。 すべてのあなたのプロジェクトで全体的に無効にします。 詳細については、 ドキュメント を参照してください。 Mutiny の発生 新しいリアクティブプログラミングAPIが導入されました。この Mutiny というAPIは、AxleモデルとReactive Streams Operatorsモデル(リアクティブストリームとCompletionStage)を置き換えるものです。以前のモデルはまだ機能していますが、廃止され、将来削除される予定です。 詳細については、『 Reactive入門ガイド 』を参照してください。 KubernetesやOpenShiftへの簡単なデプロイ Kubernetesのエクステンションは大幅に改良されて、QuarkusアプリケーションをKubernetesやOpenShiftにデプロイする作業がほとんど不要になりました。基本的には、コンテナイメージ(詳細については、コンテナイメージを参照してください。)の生成と、生成されたKubernetesマニフェストのターゲットクラスタへの適用も、コンテナイメージが生成された後に行うようになりました。 詳細については、 ドキュメント を参照してください。 Eclipse MicroProfile 3.3仕様 SmallRye拡張機能は、Eclipse MicroProfile 3.3を実装するために更新されました。 詳細なブログ記事は近日公開予定。 デフォルトのHTTP読み取りタイムアウト HTTP読み取りタイムアウト(quarkus.http.read-timeoutを使って)を設定する機能が追加されました。デフォルト値は1分です。 新しい拡張機能 コンテナイメージ Quarkusではコンテナイメージの構築に多大な努力が払われています。 これで、Quarkusビルドの一部として、Jib、Docker、S2Iのいずれかを使って、Quarkus構成に基づいてイメージをビルドする一連の拡張機能ができました。 詳細については、『 コンテナイメージガイド 』を参照してください。 OptaPlanner OptaPlannerはAI制約解決です。計画とスケジューリングの問題を最適化します。 OptaPlanner Quarkus拡張機能は、ネイティブの実行形式であっても、OptaPlannerのすべての機能をQuarkusに提供します。OptaPlannerがどのように役立つかについては、 OptaPlannerガイド をお読みください。 セキュリティJPA データベースのユーザーをHibernate ORMで管理したいとお考えですか?いくつかのアノテーションを追加するだけで、 Security JPA拡張機能 がカバーしてくれます。 Spring Cloud Config Client Springの互換性レイヤをSpring Cloud Config Clientで拡張しました。 Spring Cloud Configサーバから設定を取得 できるようになりました。 AWS X-Ray AWS X-Rayのサポートが追加されたので、JVMモードとネイティブモードでAWSラムダとともに使用することができます。 Qpid JMS Artemis JMS拡張ではなく、Qpid JMS拡張を使用することをお勧めします。機能は同じですが、柔軟性が増すだけです。 Artemis JMS拡張はまだ存在します。 詳細については、 JMSガイド を参照してください。 Liquibase 以前はFlywayの拡張機能を使っていましたが、データベーススキーマの移行にもLiquibaseを使うことができるようになりました。 詳しくは Liquibaseのガイド を参照してください。 Reactive MongoDB と Panache リアクティブが好きですか?Mongo DBが好きですか?シンプルなコードが好きですか? Panache拡張を持つReactive MongoDBが登場した。詳細はMongoDBとPanacheのドキュメントを参照のこと。 GraalVM 20.0 support 1.3.0.Finalは4種類のGraalVMをサポートしています。 GraalVM 19.3.1 - JDK 8 GraalVM 19.3.1 - JDK 11 GraalVM 20.0.0 - JDK 8 GraalVM 20.0.0 - JDK 11 要約すると、Quarkusでは次のように使用できます。 JVMモードでJDK 8, 11, 12, 13 or 14 ネイティブ実行形式をビルドするためJDK 8 もしくは 11 と GraalVM 19.3.1 か 20.0.0 GraalVMのJDK11サポートは、まだ技術プレビュー段階です。私たちの側では、コンパイルが20%遅くなること以外、特に問題はありませんでした。 Hibernate ORM バイトコード拡張による自動関連付け管理は、今後無効になります。 quarkus.hibernate-orm.second-level-caching-enabled設定プロパティーをfalseに設定すると、セカンドレベルのキャッシュを無効にできます。 Spring 互換層 Spring互換レイヤは、完全なSpring.jarではなく、必要なAPIとアノテーションだけを含む切り落とされたアーティファクトに基づいています。 依存性が少なく、コードも少なく、サポートされている機能だけがあります。 さらに…​ -GradleとKotlinのサポートに関するいくつかの改善しました。 -ネイティブ実行可能ビルドの<有効Jni>オプションは非推奨になり、JNIは常にGraalVM 19.3+で有効になっているため、削除対象としてマークされました。 -Flyway拡張は、順が狂っている設定プロパティをサポートするようになりました。 -私たちのQuteテンプレートエンジンは成熟しつつあり、バグ修正と改善が行われています。 ・Keycloak9をサポートします。 -Hibernate Search+Elasticsearchが6.0 .0.Beta5にアップグレードされました。 -Quartz拡張モジュールのベースとなるQuartzスケジューラを注入して、より柔軟性を持たせることが可能になりました。 完全な変更ログ 1.3.0.Alpha1 、 1.3.0.Alpha2 、 1.3.0.CR1 、 1.3.0.CR2 と 1.3.0.Final の完全な変更ログはGitHubで入手できます。 ADOPTERS.md Quarkusの使用に関する情報を共有するために、リポジトリのルートに ADOPTERS.mdファイル を追加しました。 Quarkusを使用していて、私たちのブログでインタビューを受けたい場合、または単にこのファイルに追加したい場合は、私たちにご連絡ください。 貢献者 Quarkusには現在 246人の貢献者 がいます。皆様、本当にありがとうございました。 特に1.3.0リリースについてはみなさんのおかげです。 Akito Kidani, Alex Soto, Alexey Loubyansky, Alvaro Serrano, Andreas Eberle, Andrej Petras, Andrew Guibert, Andy Damevin, Aurea Munoz, Bill Burke, Clement Escoffier, cstdev, Darran Lofthouse, David M. Lloyd, Emmanuel Bernard, Erik Mattheis, Erin Schnabel, Felix Wong, Geoffrey De Smet, George Gastaldi, Georgios Andrianakis, Grzegorz Piwowarek, Guillaume Smet, Gunnar Morling, Gwenneg Lepage, Harald Reinmueller, Harold Sun, Ioannis Canellos, Irena Kezic, Jaikiran Pai, Jakubo96, Jan Martiska, Jason T. Greene, Jesper Skov, Joachim Segala, Johannes, John O’Hara, Jonas Scholz, Jordi Sola, Josejulio Martínez, Justin Lee, Kamesh Sampath, Katia Aresti, Kaxil Naik, Ken Finnigan, Kuzuha Shinoda, Ladislav Thon, Loïc Mathieu, Luca Burgazzoli, Luis F Munoz, Luram Archanjo, Maciej Swiderski, Manyanda Chitimbo, Marc Häbich, Martin Kouba, Martin Panzer, Matej Novotny, Max Rydahl Andersen, Michal Karm Babacek, Michał Szynkiewicz, Miroslav Stary, Nicolas Martignole, Olivier Dufour, Ondrej Machala, Paulo Casaes, Pavol Loffay, Pedro Igor, Peter Palaga, Phillip Kruger, Pierre PLR, Raffael Hertle, Ramakrishna Pattnaik, Rinaldo Pitzer Júnior, Robbie Gemmell, Roberto Cortez, Rohan Maity, Rostislav Svoboda, Sanne Grinovero, Sebastian Wastl, Sergey Beryozkin, Stefnotch, Stuart Douglas, Stéphane Épardaud, testfixer, Thomas Segismont, Timothy Power, Tobias Liese, Tomaz Cerar, Vincent Sevel, Vincent Sourin, Vinícius Ferraz Campos Florentino and Yoann Rodière. 参加しよう 私たちはあなたのフィードバックをとても大切にしていますので、バグを報告し、改善を依頼してください...一緒に何か素晴らしいものを作りましょう! Quarkusのユーザーや好奇心の強い人は、恥ずかしがらずに歓迎コミュニティに参加してください。 GitHub にフィードバックを提供する; コードを作成して PRを行う ; Zulip や メーリングリスト で議論する; なにか質問があれば Stack Overflow で投稿してください。
お久しぶりです。コンサルタントの森 ( @mosuke5 )です。 コロナで自宅勤務の人も多いかと思いますが、みなさんどう過ごしていますか? ずっと家にいると辛いので、定期的に息抜きで家の散歩をしています。桜もちょうどきれいでいい花見?になります。 さて、ここ最近は、OpenShift上でのCI/CDパイプラインの構築をたくさん行ってきたのですが、 よくある質問に「どうやってカスタムのJenkins agentを作ったらいいか」がありました。 まとまった情報もインターネットになかったので今回書いてみました。 デフォルトのJenkins agentイメージ OpenShiftのインストール後のデフォルトでもmaven環境とnodejs環境のagentのイメージがあります。(OCP 4.3環境) openshift プロジェクト内にあるimage streamを確認してみます。 $ oc get is -n openshift | grep jenkins-agent jenkins-agent-maven image-registry.openshift-image-registry.svc:5000/openshift/jenkins-agent-maven latest,v4.0 2 days ago jenkins-agent-nodejs image-registry.openshift-image-registry.svc:5000/openshift/jenkins-agent-nodejs latest,v4.0 2 days ago こちらのイメージの技術情報についてRed Hat Container Catalogから参照することが可能です。 こちらのイメージでことが足りるようであればもうこのブログは閉じてしまって問題ないです(笑) Jenkins Agent nodejs Jenkins Agent maven Red Hat Container Catalogueでは、コンテナイメージの取得や技術情報の閲覧、ビルドしたDockerfileがみることができるので非常に便利です。 とくにイメージをビルドしたDockerfileを確認できるので、イメージの中身を理解するのに役立ちます。 たとえば、Jenkins Agent nodejsのDockerfileは ここから 確認できます。 カスタマイズ しかし、実際の運用環境では、デフォルトのJenkins Agentでは事足りなくカスタマイズしたい、自作したいことが多くあるはずです。 例えば、PostgreSQLをデータベースに使っていて、テスト時にアプリケーションから接続できるようにクライアントソフトウェアをインストールしておきたい、 そもそもRubyやPythonなどのデフォルトで提供されている以外の言語を扱いたいなどさまざまかと思います。 ベースイメージ カスタマイズしたJenkins agent イメージを作成するためのベースイメージを紹介します。 Jenkins agentとして動作させるPodにはJenkins agentのソフトウェアのインストールが必要です。 この段階から自作するのは少し面倒なので、すでにJenkins agentが導入済みのベースイメージを利用すると便利です。 Jenkins Agent Base というイメージを用意しているのでこちらをぜひ利用しましょう。 もし、デフォルトで用意されているjenkins-agent-mavenかjenkins-agent-nodejsに手を入れたいというのであれば、それをベースイメージにしてももちろん構いません。 Jenkins Agent Baseは、Container CatalogueかQuayからダウンロードできます。 Container Catalogue (Jenkins Agent Base) Quay (Jenkins Agent Base) ベースイメージが決まれば、Dockerfileを書いてカスタムのJenkins agentのイメージを簡単に作成できます。 FROM quay.io/openshift/origin-jenkins-agent-base:4.6.0 USER root RUN yum install -y xxxxx ... USER 1001 Container Quickstarts Container QuickstartsというGithubのレポジトリでは、Jenkins agentのサンプル(イメージのビルドサンプル)をいくつか公開しています。 RubyやPythonの環境のイメージを作成するためのテンプレートもありますので参考にしてみるといいです。 このレポジトリのものをそのまま利用しないにしても、Jenkins slaveの作り方について参考になるので、みなさんのアプリケーションにあったSlaveの作成に活用しましょう。 github.com 例えば、Ruby2.5のバージョンのJenkins slaveのイメージ作成したければ、こちらのリポジトリのBuildConfigを利用することで簡単に作成することができます。(Rubyのバージョンもう古いですね。。) $ git clone https://github.com/redhat-cop/containers-quickstarts $ cd containers-quickstarts/ $ oc process -f .openshift/templates/jenkins-slave-generic-template.yml \ -p NAME=jenkins-slave-ruby \ -p SOURCE_CONTEXT_DIR=jenkins-slaves/jenkins-slave-ruby \ | oc create -f - 手元のDockerで動作確認する カスタマイズしたJenkins agentのイメージも、最終的にはBuildConfigを用いてビルドできるようにすることが運用上は望ましいです。 しかし、いきなりBuildConfigを設定してビルドするには、デバッグが大変なことがあります。 なので、まずは手元のPC上のDockerなどで必要なソフトウェアのインストールができるかどうかなどを確認するといいでしょう。 例えば、 origin-jenkins-agent-base は下記のようにDocker上で動かして検証できます。 確認した結果を、最終的にDockerfileに記述できればBuildConfigでの生成もできるようになります。 $ docker run -it --entrypoint="/bin/bash" quay.io/openshift/origin-jenkins-agent-base:4.5 container # container # useradd xxxx container # yum install xxxx 注意点として、 origin-jenkins-agent-base はENTRYPOINTに ["/usr/bin/go-init", "-main", "/usr/local/bin/run-jnlp-client"] が指定されているので、 docker run -it quay.io/openshift/origin-jenkins-agent-base:4.5 /bin/bash として起動しようとしても、エラーで落ちます。 (DockerのCMDとENTRYPOINTの違いは復習) Jenkins上での作成したイメージの指定方法 カスタマイズ したJenkins agentのイメージを利用するにはJenkinsfileから指定できます。 JenkinsのGUIから利用するイメージの登録もできるのですが、Jenkinsfileに設定を記述することをおすすめします。 理由は、Jenkins内で起動するPodについてもGit管理の対象とすることができるからです。 なるべくJenkins本体への設定を減らし、コード化してGit管理の対象を増やすことは自動化を進めていく上で便利になります。 Jenkinsの Kubernetesプラグイン を利用して、agentとして起動するPodのマニフェストを指定できます。 pipeline { // pipelineを実行するagentの設定。yamlファイルで設定を渡せる // 可能な限りJenkinsfileにagentの設定をもたせたほうが自動化とGit管理が進むためおすすめ。 agent { kubernetes { cloud 'openshift' yamlFile 'jenkins-slave-pod.yaml' } } ... } Podのマニフェストの例は以下です。 # jenkins-slave-pod.yaml apiVersion : v1 kind : Pod spec : serviceAccountName : jenkins containers : - name : jnlp image : image-registry.openshift-image-registry.svc:5000/your-project/custom-jenkins-agent args : [ '$(JENKINS_SECRET)' , '$(JENKINS_NAME)' ] tty : false env : - name : POSTGRESQL_USER value : "postgres" jenkins-agent-mavenのJavaバージョンについて jenkins-agent-maven のイメージを利用する際にJavaのバージョンについて注意があります。 OCP 4.3以降のイメージではJava8と11の両方がインストールされるようになり切り替えできるようになりました。 コンテナイメージ内でJavaのバージョンを切り替えるスマートな方法がいまのところあまり用意されていないのですが、 Jenkinsパイプライン内で、 JAVA_HOME の指定やalternativesコマンドを使って alternatives --set java xxxx 設定することで切り替えできます。 $ alternatives --list ld auto /usr/bin/ld.bfd libnssckbi.so.x86_64 auto /usr/lib64/pkcs11/p11-kit-trust.so java_sdk_11_openjdk auto /usr/lib/jvm/java-11-openjdk-11.0.6.10-1.el7_7.x86_64 java_sdk_1.8.0_openjdk auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64 java_sdk_openjdk auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64 javadocdir auto /usr/share/javadoc/java-11-openjdk-11.0.6.10-1.el7_7.x86_64/api java_sdk_1.8.0 auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64 java_sdk_11 auto /usr/lib/jvm/java-11-openjdk-11.0.6.10-1.el7_7.x86_64 javac auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/bin/javac jre_11 auto /usr/lib/jvm/java-11-openjdk-11.0.6.10-1.el7_7.x86_64 jre_openjdk auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/jre jre_11_openjdk auto /usr/lib/jvm/jre-11-openjdk-11.0.6.10-1.el7_7.x86_64 jre_1.8.0_openjdk auto /usr/lib/jvm/jre-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64 java auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/jre/bin/java jre_1.8.0 auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64/jre 例えばJenkinsfileないの環境変数の指定で下記のようにコマンドの結果を設定するといいかもしれません。 environment { JAVA_HOME = """${sh( returnStdout: true, script: 'alternatives --list | grep "java_sdk_1.8.0\\s" | awk \'{print $3}\' | tr -d \'\\n\'' )}""" } さいごに ひさびさの投稿は、華やかな新しいプロダクトの内容とかでない地味な内容でしたが(笑)、 OpenShift上でCI/CDを行っていくのに欠かせないJenkins agentの作り方についてみてきました。 CI環境は、その後の運用環境で動くアプリケーションのビルドなどをする重要な環境です。 利用するソフトウェアのバージョンやテストを妥協すると、いいCI/CDは実現できません。 OpenShift上でCI/CDパイプラインを整備していきたいみなさんのご参考になればと思っています。 最後に個人的に最近書いたCI/CDに関するブログがまあまあ反響がよかったので、関連ブログとして参考にしてもらえればと思います。 blog.mosuke.tech
Red Hatエンジニアリングの佐藤匡剛です。 Camel 3マイグレーションガイド 紹介記事の後編です。前編のcamel-core編はこちらです。 rheb.hatenablog.com 前編ではcamel-coreを含むCamelアプリケーション全般に影響する変更をまとめましたが、後編は個別のコンポーネント毎の細かな変更を説明します。こちらは、主に利用しているコンポーネントのセクションだけをチェックすればいいでしょう。 削除されたコンポーネント 名前変更されたコンポーネント コンポーネントのマイグレーション ActiveMQコンポーネント AWSコンポーネント CDIコンポーネント Cryptoコンポーネント FHIRコンポーネント JMXコンポーネント Kafkaコンポーネント Mockコンポーネント Propertiesコンポーネント Scriptコンポーネント Shiroコンポーネント Telegramコンポーネント XML Securityコンポーネント XSLTコンポーネント データフォーマットのマイグレーション Cryptoデータフォーマット JSONデータフォーマット XML Securityデータフォーマット Zip / Gzipデータフォーマット 最後に 削除されたコンポーネント camel-core編 でも触れた通り、Camel 2.xで非推奨だったAPIやコンポーネントはすべて削除されました。 以下のコンポーネントは、同じコンポーネントのより新しいバージョンがあるために削除されました。(例:camel-http → camel-http4) camel-http camel-hdfs camel-mina camel-mongodb camel-netty camel-netty-http camel-quartz camel-rx 以下のコンポーネントは、JDK 8で動作しないため削除されました。 camel-jibx 以下のデータフォーマットは、JDK 9以降で動作しないため削除されました。 camel-boon 以下のコンポーネントは、Linkedin API 1.0のサポートが終了したために削除されました。新しい2.0 APIを使ったコンポーネントの開発は CAMEL-13813 でトラックされています。 camel-linkedin また、以下のコンポーネントからは部分的に機能が削除されました。 camel-zookeeper ― ルートポリシーの機能が削除されました。代わりに ZooKeeperClusterService クラスを使うか、camel-zookeeper-masterコンポーネントを使います。 camel-jetty ― プロデューサー( to() )の機能が削除されました。代わりにcamel-httpを使います。 camel-twitter ― twitter-streamingサブコンポーネントが削除されました。Twitter Streaming APIが非推奨となり動作しなくなったためです。 名前変更されたコンポーネント 大きな変更ポイントとして、これまでCamel 2.xで同じライブラリ/フレームワークの複数バージョンをサポートするために別々の名前になっていたコンポーネント(例:camel-httpとcamel-http4、camel-jettyとcamel-jetty9、など)を、古いバージョンを削除することで整理し、最新バージョンがシンプルなコンポーネント/スキーマ名になるようにしました(例:camel-http4 → camel-http)。 コンポーネント/スキーマ名、パッケージ、JARに変更のあったコンポーネントを表にまとめます。 コンポーネント パッケージ/JAR サポートするスキーマ hdfs2 → hdfs org.apache.camel.component.hdfs2 → org.apache.camel.component.hdfs hdfs http4 → http org.apache.camel.component.http4 → org.apache.camel.component.http http , https jetty9 → jetty jetty mina2 → mina org.apache.camel.component.mina2 → org.apache.camel.component.mina mina mongodb3 → mongodb org.apache.camel.component.mongodb3 → org.apache.camel.component.mongodb mongodb netty4 → netty org.apache.camel.component.netty4 → org.apache.camel.component.netty netty netty4-http → netty-http org.apache.camel.component.netty4.http → org.apache.camel.component.netty.http netty-http quartz2 → quartz org.apache.camel.component.quartz2 → org.apache.camel.component.quartz quartz rxjava2 → rxjava org.apache.camel.component.rxjava2 → org.apache.camel.component.rxjava test → dataset-test (JAR) camel-core → camel-dataset コンポーネントのマイグレーション ActiveMQコンポーネント ActiveMQが提供していたactivemq-camelコンポーネントは、今後はCamelからcamel-activemqコンポーネントとして提供されます。コンポーネントのクラス名も org.apache.activemq.camel.component.ActiveMQComponent から org.apache.camel.component.activemq.ActiveMQComponent に変更されます。 AWSコンポーネント AWSコンポーネントは、複数のコンポーネントに分割されました。 camel-aws-cw camel-aws-ddb(ddbとddbstreamsの両方のコンポーネントを含む) camel-aws-ec2 camel-aws-ecs camel-aws-eks camel-aws-iam camel-aws-kinesis(kinesisとkinesis-firehoseの両方のコンポーネントを含む) camel-aws-kms camel-aws-lambda camel-aws-mq camel-aws-s3 camel-aws-sdb camel-aws-ses camel-aws-sns camel-aws-sqs camel-aws-swf これらのAWSのコンポーネントを使用するには、AWSの必要な機能をもったコンポーネントを個別にdependencyに追加する必要があります。ただし、OSGi/Karafについては、 camel-aws Karaf featureが引き続き利用可能で、1つですべてのコンポーネントを利用できます。 CDIコンポーネント camel-core編 で触れたように複数CamelContextのサポートが削除されました。それに伴い、 @ContextName アノテーションも削除されました。代わりに、標準のCDIアノテーション @Named や @ApplicationScoped を使います。 Cryptoコンポーネント Crypto(JCE)コンポーネントのデフォルト署名アルゴリズムが、SHA1WithDSAからSHA256withRSAに変更されました。 FHIRコンポーネント FHIRコンポーネントはdependencyのhapi-fhirを4.1.0にアップグレードしました。 hapi-fhir Karaf featureに問題があったため、それが解決してリリースされるまでKarafは非サポートになっています。デフォルトのFHIRバージョンはR4に変更されました。したがって、DSTU3が必要な場合、明示的にセットする必要があります。 JMXコンポーネント camel-coreだけをdependencyとしてCamelアプリケーションをスタンドアロンで実行している場合、JMXを有効化したければ、さらにcamel-managementをdependencyに追加する必要があります。 ManagedCamelContext クラスを使いたい場合、 CamelContext から拡張として次のように取得します。 ManagedCamelContext managed = camelContext.getExtension(ManagedCamelContext. class ); Kafkaコンポーネント Kafkaコンポーネントでは、 bridgeEndpoint と circularTopicDetection の2つのオプションが削除されました。コンポーネントが標準でブリッジとして動作するようになり、必要なくなったためです。言い換えれば、camel-kafkaではメッセージはエンドポイントURIからトピックへ送信されます。これをオーバーライドするには、 KafkaConstants.OVERRIDE_TOPIC ヘッダに新しいトピック名を指定します。詳細は、 camel-kafkaコンポーネントのドキュメント を参照してください。 Mockコンポーネント Mockコンポーネントはcamel-coreからcamel-mockに移動しました。また、ほとんど使われていなかったアサーション句ビルダーのメソッドもごっそりと削除されました。 また camel-core編 で触れたようにOUT Messageの概念が削除されたのに伴い、以下のような関連するアサーションメソッドも削除されました。 mock.message( 0 ).outBody() ... Propertiesコンポーネント Propertiesコンポーネントで、カスタムのプレフィクス/サフィックストークンを設定できた機能は削除されました。Simple言語や他のところで潜在的に衝突を起こす可能性があったからです。 また、Propertiesコンポーネントから高度なオプション propertyPrefix 、 propertySuffix 、 fallbackToUnaugmented が削除されました。エンドユーザにとって実際に使えるものではなかったためです。同じく、 propertiesResolver オプションも削除されました。代わりに、 PropertiesSource クラスを使います。 Propertiesコンポーネントでは、OS環境変数が最も優先される値になりました。つまり、OS環境変数を使ってプロパティファイルやJVMシステムプロパティなどで定義されたプロパティ値を上書きできるようになります。この振る舞いは、 environmentVariableMode オプションで制御できます。 Propertiesコンポーネントでは、今後、以下のようなエンドポイントとしての使い方はサポートされません。 properties :myKey Propertiesコンポーネントの役割は、CamelContextに対するプロパティのプレースホルダーサービスになります。したがって、 camelContext.getComponent("properties") の形でコンポーネントにアクセスすることはできません。代わりに camelContext.getPropertiesComponent() を使います。この戻り値も org.apache.camel.spi.PropertiesComponent インタフェースになります。実装クラスは引き続き org.apache.camel.component.properties.PropertiesComponent ですが、こちらの実装クラスを直接参照するのは非推奨です。 Scriptコンポーネント Scriptコンポーネント(camel-script)は削除されました。 javax.script がすでに非推奨であり、Java 11以降削除されるためです。 Shiroコンポーネント Shiroコンポーネントのデフォルト暗号化キーが削除されました。したがって、今後はキー/パスフレーズの提供が必須になります。 Telegramコンポーネント Telegramコンポーネント(camel-telegram)では、認証トークンがURIパスでの指定からクエリパラメータでの指定に変更されました。 telegram :bots/myTokenHere の代わりに、 telegram :bots?authorizationToken=myTokenHere と書き換える必要があります。 XML Securityコンポーネント XML Securityコンポーネントのデフォルト署名アルゴリズムが、RSA-SHA1からRSA-SHA256に変更されました。 XSLTコンポーネント XSLTコンポーネントは、camel-coreからcamel-xsltとcamel-xslt-saxonに移動しました。 came-xslt ― JDKのXSLTエンジン(Xalan)ベースのコンポーネント camel-xslt-saxon ― Saxonベースのコンポーネント コンポーネントのエンドポイントURIも、それぞれ xslt 、 xslt-saxon と別々のものを使う必要があります。 XSLTのアグリゲーションストラテジーを使っている場合、Saxonサポートを有効にするには org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy を使います。XSLTビルダーを使っている場合、Saxonサポートを有効にするには org.apache.camel.component.xslt.saxon.XsltSaxonBuilder を使います。また、 allowStax のサポートはcamel-xslt-saxonを使う場合のみになります。JDK XSLTでStaxはサポートされないためです。 データフォーマットのマイグレーション Cryptoデータフォーマット Crypto(JCE)データフォーマットのデフォルト暗号化アルゴリズムに変更があり、デフォルトは null で明示的な値の設定が必要になりました。以前は "DES/CBC/PKCS5Padding" でした。 JSONデータフォーマット JSONデータフォーマットのデフォルトJSONライブラリが、XStreamからJacksonに変更されました。 XML Securityデータフォーマット XML Securityデータフォーマットのデフォルト暗号化キーが削除されました。したがって、今後は対称暗号を利用する際はキー(文字列 or バイト)の提供が必須になります。つまり、キーを渡さずに XMLSecurityDataFormat クラスを使っていたメソッドは削除されたことを意味します。 さらに、デフォルトの対称暗号アルゴリズムがTriple DESからAES-256(GCMモード)に変更されました。 Zip / Gzipデータフォーマット zip / gzip データフォーマットはそれぞれ zipdeflater / gzipdeflater に名前変更されました。これは、これらのデータフォーマットがzip / gzipアルゴリズムでデータ圧縮を行うためのもので、zip / gzipファイルを直接扱うものではなかったためです。zipファイルを扱うには、camel-zipfileデータフォーマットを使います。 また、これらのデータフォーマットはcamel-coreからcamel-zip-deflaterに移されました。使用には、camel-zip-deflaterの明示的なdependency追加が必要です。Java/XML DSLの名前も変更されたので、そちらもマイグレーションが必要になります。 最後に Camel 3マイグレーションガイドの日本語記事が無事完成しました。原文ガイドの構成がカオスな分、日本のCamelユーザの皆さんの方がマイグレーションしやすい環境が整ったと自負しています(笑)。 Camel 3を採用した製品版のRed Hat Fuse 8もいずれリリース(2020年内?)されると思いますが、一足先に是非新しいCamel 3ライフをお楽しみください!
みなさんこんにちは。レッドハットの杉村です。Ansible のテクニカルサポートをしています。 今回は Ansible から Windows Active Directory を操作してみようということで、簡単な Windows の扱い方や、変数のパラメータ化、Tower での実行例について軽く説明したいと思います。 対象としては Windows 2019 を用意しました。Ansible から接続できるように、初期設定をしておきました。詳細はこちらのサイトをご覧ください。 https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html インベントリファイルを書きます。最近は ini 形式ではなく yaml で書くのが好みです。 --- windows: hosts: 192.168.0.158: ansible_connection: winrm ansible_password: your_password_as_you_like1! ansible_user: Administrator ansible_winrm_server_cert_validation: ignore ansible_winrm_transport: basic Ad hoc コマンドの win_ping を使って、Ansible から接続できることを確認します。 $ ansible -i inventory.yml -m win_ping windows 192.168.0.158 | SUCCESS => { "changed": false, "ping": "pong" } これであとはプレイブックを書けば操作できます。 Windows 2019 には Active Directory を設定してみました。ドメインはここでは ANSIBLE.JP.REDHAT.COM としています。 この Active Directory を Ansible から操作してみようというのが今回の目的です。ユーザを作ったり消したりしてみようと思います。 モジュールを検索しますと、win_domain_user モジュールが使えそうです。 https://docs.ansible.com/ansible/latest/modules/win_domain_user_module.html 試しにプレイブックを書いてみます。 --- - hosts: windows gather_facts: false tasks: - win_domain_user: name: ansibleuser firstname: Ansible surname: User groups: - Domain Users password: p@ssw0rd state: present 実行してみました。 $ ansible-playbook -i inventory.yml playbook.yml PLAY [windows] ******************************************************************************************** TASK [win_domain_user] ******************************************************************************************** changed: [192.168.0.158] PLAY RECAP *************************************************************************** 192.168.0.158 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 Windows でも確認してみます。正しくユーザが作られていました。簡単ですね。 逆に、ユーザを削除することもできます。 --- - hosts: windows gather_facts: false tasks: - win_domain_user: name: ansibleuser state: absent 次に、ユーザ作成のプレイブックをパラメータ化してみます。 --- - hosts: windows gather_facts: false tasks: - win_domain_user: name: "{{ username }}" firstname: "{{ firstname }}" surname: "{{ surname }}" groups: - Domain Users password: "{{ password }}" state: present このままでは実行できません。 TASK [win_domain_user] ******************************************************************************************************************* fatal: [192.168.0.158]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'username' is undefined\n\nThe error appears to be in '/home/ec2-user/blog20200318/playbook_user_create.yml': line 5, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - win_domain_user:\n ^ here\n"} extra vars として外から渡す必要があります。JSON 形式で書いて渡してみます。 { "username": "user1", "firstname": "Ansible", "surname": "User", "password": "a_passw0rd_for_ans1ble_user!" } $ ansible-playbook -i inventory.yml playbook_user_create.yml --extra-vars "@param.json" PLAY [windows] ***************************************************************************** TASK [win_domain_user] ************************************************************************************************ changed: [192.168.0.158] PLAY RECAP ************************************************************************************************ 192.168.0.158 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 パラメータ化しておくことで、再利用性がとても高まります。 ここまででも便利に使えるとは思いますが、Ansible Tower からも動かせるようにしてみました。ジョブテンプレートを作成するときに survey を設定することで、extra vars としてのパラメータ渡しができるようになります。 なお、Tower でプレイブックを動かすときには、 hosts: all として対象をインベントリから選択するようにする必要があります。 こちらは実行してみたときの例です。 Windows に構築した AD を Ansible から設定してみる例を取り上げまして、パラメータ化してTower に載せてみるところまでやってみました。他の設定や操作にも応用が効くと思いますので、これをヒントにしてあれこれ試してみてください。 Ansible Towerの評価ライセンスリクエストはこちらからご利用いただけます。 www.ansible.com Happy Automation!
Red Hatエンジニアリングの佐藤匡剛です。昨年12月の赤帽エンジニアAdvent Calendarの 記事 で、Camel 3へのマイグレーションガイドの紹介記事を年明けに書くと宣言していましたが、ようやく書きました。 今回紹介する本家のガイドは、こちらです。 Apache Camel 2.x to 3.0 Migration Guide - Apache Camel このガイドは長いので、このブログでは2つの記事(camel-core編、コンポーネント編)に分けてお送りします。コンポーネント編はこちらです。 rheb.hatenablog.com 今回は、camel-core編です。 Javaのバージョン JAXB ランタイム/プラットフォーム Spring Boot StarterのGroup ID変更 Mainクラス camel-coreのモジュール化 camel-core コアコンポーネント CamelContext 複数CamelContextの非サポート Mainクラスの複数CamelContext非サポート CamelContextのグローバルオプション ExtendedCamelContext ModelCamelContext CatalogCamelContext CamelContextによるルートの制御 Message API MessageのgetOut() MessageのFault API MessageのAttachments API ルート/エンドポイント consumer.プレフィクスの付いたエンドポイントオプションの削除 POJOアノテーション 複数インプットのあるルート ルートポリシー XML DSLのマイグレーション その他の変更 その他のAPI 非推奨API、コンポーネントの削除 検査例外 vs 非検査例外 HelperとSupport 冪等リポジトリ アグリゲーション JSSE フォールバック型コンバータ レジストリ アノテーション その他の変更 EIP XML DSLの<setHeader>、<setProperty> XML DSLの<aggregate> Hystrix EIP テスト camel-test adviceWith 管理/監視 トレーシング JMXイベント EIP、コンポーネント等の参照用JMX APIの削除 カスタムコンポーネント/言語 カスタムコンポーネント カスタム言語 言語 Simple言語からのOUT Messageの削除 Simple言語の開始/終了トークン Simple言語のproperty Terser言語 → HL7 Terser言語 アノテーション Camel Mavenプラグイン 既知の問題 最後に Javaのバージョン Camel 3が正式にサポートするのはJava 11です。当面はJava 8もベストエフォートでサポートを続けますが、いずれどこかの段階でドロップされます。 JAXB Java 11でJAXBを使うには、Maven dependencyの明示的な追加が必要です。XML DSLでJAXBを使っていたり、camel-jaxbコンポーネントを使っている場合は、これらの dependency を pom.xml に追加します。 <dependency> <groupId> javax.xml.bind </groupId> <artifactId> jaxb-api </artifactId> <version> 2.3.1 </version> </dependency> <dependency> <groupId> com.sun.xml.bind </groupId> <artifactId> jaxb-core </artifactId> <version> 2.3.0.1 </version> </dependency> <dependency> <groupId> com.sun.xml.bind </groupId> <artifactId> jaxb-impl </artifactId> <version> 2.3.2 </version> </dependency> ランタイム/プラットフォーム Spring Boot StarterのGroup ID変更 Spring Boot StarterのMaven groupId が org.apache.camel から org.apache.camel.springboot に変更されました。 Camel 2.x: <dependency> <groupId> org.apache.camel </groupId> <artifactId> camel-component-starter </artifactId> </dependency> Camel 3.0: <dependency> <groupId> org.apache.camel.springboot </groupId> <artifactId> camel-component-starter </artifactId> </dependency> Mainクラス Camelの Main クラス(Camelアプリケーションをスタンドアロンで実行するためのユーティリティクラス)が含まれるJARが、 camel-core から camel-main に変わりました。 Main クラスを使っている方は、 camel-main の pom.xml への追加が必要です。 camel-coreのモジュール化 camel-core Camel 3の大きな変更の1つがcamel-coreのモジュール化です。camel-coreは、以下のJARに細分化されました。後方互換性のために、これらを1つにまとめたcamel-coreは引き続き提供されていますが、マイクロサービス化のためにアプリケーションをスリムダウンしたい方は必要なdependencyだけをピックアップして使えます。 camel-api camel-base camel-caffeine-lrucache camel-cloud camel-core camel-jaxp camel-main camel-management-api camel-management camel-support camel-util camel-util-json コアコンポーネント さらに、camel-coreに含まれていた下記のコアコンポーネントも、通常のコンポーネントと同様に外だしされました。それぞれ、使いたいコンポーネントをピックアップして使う形になります。 camel-attachments camel-bean camel-browse camel-controlbus camel-dataformat camel-dataset camel-direct camel-directvm camel-file camel-language camel-log camel-mock camel-ref camel-rest camel-saga camel-scheduler camel-seda camel-stub camel-timer camel-validator camel-vm camel-xpath camel-xslt camel-xslt-saxon camel-zip-deflater CamelContext 複数CamelContextの非サポート 元々アプリケーションのデプロイメント毎に複数のCamelContextを定義する方法は、推奨されてもおらず100%完全な実装でもなかったのですが、Camel 3ではデプロイメント毎に1つのCamelContextのみサポート、ということが明示化されました。 それに伴い、複数のCamelContextを扱うために提供されていたAPIはごっそり削除されました。 @EndpointInject 、 @Produce 、 @Consume などのCamelアノテーションにあった context 属性は削除されました。 Mainクラスの複数CamelContext非サポート camel-core、camel-spring、camel-cdiの Main クラスでも、同様に1つのCamelContextのみ対応するための変更が加えられています。具体的には、 getCamelContextMap() メソッドが削除され、 getCamelContext() メソッドだけになりました。 CamelContextのグローバルオプション Camel 2.xでdeprecatedだった CamelContext の getProperties() は削除されました。代わりに、 getGlobalOptions() を使います。 Java: context.getGlobalOptions().put( "CamelJacksonEnableTypeConverter" , "true" ); context.getGlobalOptions().put( "CamelJacksonTypeConverterToPojo" , "true" ); XML: <globalOptions> <globalOption key = "CamelJacksonEnableTypeConverter" value = "true" /> <globalOption key = "CamelJacksonTypeConverterToPojo" value = "true" /> </globalOptions> ExtendedCamelContext CamelContext のAPIが一般ユーザ向けに整理され、高度なユースケース向けのAPIやSPIは ExtendedCamelContext に移されました。 ExtendedCamelContext には以下のようにしてアクセスします。 ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext. class ); ModelCamelContext ModelCamelContext にあった loadRouteDefinitions() と loadRestDefinitions() のメソッドは、他のメソッドと名前を揃えるために addRouteDefinitions() と addRestDefinitions() になりました。ローダ関連のメソッドは ModelHelper ユーティリティクラスに見つかります。 ModelCamelContext にアクセスしたいときは、以下のようにします。 ModelCamelContext mcc = camelContext.adapt(ModelCamelContext. class ); CatalogCamelContext CamelContext に定義されていたカタログ関連のメソッドは、 CatalogCamelContext インタフェースに移動しました。以下のようにして使います。 CatalogCamelContext ccc = context.adapt(CatalogCamelContext. class ); CamelContextによるルートの制御 CamelContext にあった startRoute() 、 stopRoute() 、 suspendRoute() 、 resumeRoute() 、 getRouteStatus() とその他関連するメソッドは RouteController クラスに移されました。以下のようにアクセスします。 context.getRouteController().startRoute( "myRoute" ); Message API MessageのgetOut() Message クラスの hasOut() 、 getOut() メソッドはdeprecateになりました。代わりにシンプルに getMessage() を使います。メッセージのINとOUTというコンセプトは廃止になりました。これらは、JBIやSOAPといった古い仕様から採用されたものですが、実際はそれほど有用でなかったためです。 それに伴い、他の部分でもIN、OUTのコンセプトに基づいた要素は削除されています。Beanパラメータバインディングの @OutHeaders アノテーションは削除され、代わりに @Headers を使います。 MessageのFault API Message クラスのFault APIも削除されました。SOAPのFaultメッセージにしか使われていなかったためです。 handleFault オプションも削除されています。 SOAPを扱うcamel-cxf、camel-spring-wsコンポーネントでは、それぞれ独自にFaultメッセージを実装していて、 handleFault の有効化をコンポーネント/エンドポイントのオプションとして設定する必要があります。 MessageのAttachments API javax.activation のAttachments APIは、 Message クラスからcamel-attachmentsの org.apache.camel.attachment.AttachmentMessage クラスに移動しました。 使い方は、以下のとおりです。 AttachmentMessage am = exchange.getMessage(AttachmentMessage. class ); am.addAttachment( "myAtt" , new DataHandler( ... )); ルート/エンドポイント consumer. プレフィクスの付いたエンドポイントオプションの削除 consumer. プレフィクスの付いたエンドポイントオプションは廃止されました。今後は、 consumer. プレフィクスを付けずにそのままオプションを指定します。 例) consumer.delay=5000 → delay=5000 POJOアノテーション @Consume 、 @Produce 、 @EndpointInject の ref 属性は削除されました。代わりに、 value 属性にrefコンポーネントを使い、以下のようにします( value は省略可能なことに注意)。 @Consume( "ref:myName" ) 上記に uri 属性を使うこともできますが、 uri 属性自体もdeprecatedになっていて、代わりに value 属性を使う必要があります。そのため、全般に、 @Consume(uri = "jms:cheese") ではなく @Consume("jms:cheese") を使います。 複数インプットのあるルート Camel 2.xでは、実はルートは2つ以上のインプットを持つことが(部分的に)できたのですが、ほとんど使われていませんでした。Camel 3では、この機能を削除し、明示的に1つのルートで1つのインプットしか受け付けないようにしました。 ルートポリシー org.apache.camel.support.RoutePolicySupport クラスはcamel-supportに移りました。メソッド startConsumer() 、 stopConsumer() の戻り値は boolean から void に変更されました(元々 true しか返していなかったため)。 org.apache.camel.impl.ThrottlingInflightRoutePolicy クラスは org.apache.camel.throttling.ThrottlingInflightRoutePolicy にパッケージが変わりました。 XML DSLのマイグレーション XML DSLのタグに細かな修正が入っています。 カスタムロードバランサーEIPのタグが <custom> から <customLoadBalancer> に変更された XML Securityデータフォーマットで <secureXML> タグの keyOrTrustStoreParametersId 属性が keyOrTrustStoreParametersRef に名前変更された <zipFile> データフォーマットが <zipfile> に名前変更された その他の変更 RestEndpoint クラスの bindingMode 向けのgetter/setterメソッドは、camel-apiの org.apache.camel.spi.RestConfiguration.RestBindingMode 型を使う形に変更されました。setterメソッドに関しては、String型を使うバージョンも残されてます。 RouteBuilder クラスの includeRoutes() メソッドは削除されました。このメソッドはCamel 2.xの頃からdeprecatedでした。 その他のAPI 非推奨API、コンポーネントの削除 Camel 2.xで既にdeprecatedになっていたAPIやコンポーネントは、Camel 3で全部削除されました。 検査例外 vs 非検査例外 Camelのほとんどの例外クラスは非検査例外( RuntimeException のサブクラス)になりました。 また、 Service および SuspendableService のライフサイクルメソッド start() 、 stop() 、 suspend() 、 resume() も検査例外を投げないようになりました。 FactoryFinder クラスのAPIは、検査例外 FactoryNotFoundException や ClassNotFoundException 等をスローする代わりに、 Optional 型を返すように変更されました。 HelperとSupport HelperおよびSupportのクラスの変更は以下の通りです。 org.apache.camel.util.AsyncProcessorHelper (camel-core) → org.apache.camel.support.AsyncProcessorHelper (camel-support) org.apache.camel.util.AsyncProcessorConverterHelper (camel-core) → org.apache.camel.support.AsyncProcessorConverterHelper (camel-support) org.apache.camel.util.CamelContextHelper (camel-core) → org.apache.camel.support.CamelContextHelper (camel-support) org.apache.camel.util.EndpointHelper (camel-core) → org.apache.camel.support.EndpointHelper (camel-support) org.apache.camel.util.EventHelper (camel-core) → org.apache.camel.support.EventHelper (camel-support) org.apache.camel.util.ExchangeHelper (camel-core) → org.apache.camel.support.ExchangeHelper (camel-support) org.apache.camel.util.GZIPHelper (camel-core) → org.apache.camel.support.GZIPHelper (camel-support) org.apache.camel.util.JsonSchemaHelper (camel-core) → org.apache.camel.support.JsonSchemaHelper (camel-support) org.apache.camel.util.MessageHelper (camel-core) → org.apache.camel.support.MessageHelper (camel-support) org.apache.camel.util.ObjectHelper (camel-core) → org.apache.camel.support.ObjectHelper (camel-support) & org.apache.camel.util.ObjectHelper (camel-util) camel-apiに依存したメソッドはcamel-supportに、それ以外はcamel-utilに移動 org.apache.camel.util.PlatformHelper (camel-core) → org.apache.camel.support.PlatformHelper (camel-support) org.apache.camel.util.PredicateAssertHelper (camel-core) → org.apache.camel.support.PredicateAssertHelper (camel-support) org.apache.camel.util.ResolverHelper (camel-core) → org.apache.camel.support.ResolverHelper (camel-support) org.apache.camel.util.ResourceHelper (camel-core) → org.apache.camel.support.ResourceHelper (camel-support) org.apache.camel.spi.RestProducerFactoryHelper (camel-core) → org.apache.camel.support.RestProducerFactoryHelper (camel-support) org.apache.camel.util.ServiceHelper (camel-core) → org.apache.camel.support.service.ServiceHelper (camel-api) org.apache.camel.util.UnitOfWorkHelper (camel-core) → org.apache.camel.support.UnitOfWorkHelper (camel-support) org.apache.camel.processor.loadbalancer.SimpleLoadBalancerSupport は削除されました。代わりに org.apache.camel.processor.loadbalancer.LoadBalancerSupport を使います。 冪等リポジトリ 冪等リポジトリ( IdempotentRepository )クラスも以下のように場所が移動しています。 org.apache.camel.processor.idempotent.FileIdempotentRepository (camel-core) → org.apache.camel.support.processor.idempotent.FileIdempotentRepository (camel-support) org.apache.camel.processor.idempotent.MemoryIdempotentRepository (camel-core) → org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository (camel-support) アグリゲーション XsltAggregationStrategy クラスは以下のように場所が移動しています。 org.apache.camel.builder.XsltAggregationStrategy (camel-core) → org.apache.camel.component.xslt.XsltAggregationStrategy (camel-xslt) org.apache.camel.builder.AggregationStrategies クラスの xslt() メソッドは削除されました。代わりにcamel-xsltの XsltAggregationStrategy を直接使います。 Aggregate EIPの groupExchanges() オプションを使った場合でも、アウトプットが Exchange.GROUPED_EXCHANGE に格納されることはなくなりました。これは、既にCamel 2.13以降deprecatedになっていた挙動でした。 JSSE org.apache.camel.util.jsse パッケージのクラスは、 org.apache.camel.support.jsse パッケージに移りました。 フォールバック型コンバータ @FallbackConverter は削除されました。代わりに @Converter(fallback = true) を使います。さらに、 @Converter(generateLoader = true) とすることでCamelが型コンバータをより高速にロードするためのコードを自動生成できるようになりました。 レジストリ SimpleRegistry クラスが org.apache.camel.impl パッケージから org.apache.camel.support パッケージに移動しました。ただし、今後は org.apache.camel.support.DefaultRegistry を代わりに使うべきです。さらに、 SimpleRegistry または DefaultRegistry にエントリを追加するのに、 put() メソッドでなく bind() メソッドを使ってください。 CompositeRegistry 、 PropertyPlaceholderDelegateRegistry クラスは共に削除されました。代わりに DefaultRegistry を使います。 アノテーション アノテーション関連の細かな変更は以下のとおりです。 org.apache.camel.Constant アノテーションは削除されました。代わりに @Simple を使います。 org.apache.camel.InvokeOnHeader / org.apache.camel.InvokeOnHeaders → org.apache.camel.spi.InvokeOnHeader / org.apache.camel.spi.InvokeOnHeaders その他の変更 その他、細かな修正を列挙します。(まだ未分類な変更項目が多いので、後で別のセクションに振り分けるかもしれません。) breadcrumbの使用はデフォルトで true から false に変更されました。 CamelContext がまだ起動していない段階で、 ProducerTemplate や ConsumerTemplate を使おうとすると失敗するようになりました。 org.apache.camel.impl パッケージにあったクラスの大部分は、camel-baseの org.apache.camel.impl.engine パッケージに移されました。 org.apache.camel.util.jndi.JNDIContext (camel-core) → org.apache.camel.support.jndi.JNDIContext (camel-support) org.apache.camel.ThreadPoolRejectedPolicy → org.apache.camel.util.concurrent.ThreadPoolRejectedPolicy org.apache.camel.processor.validation.PredicateValidationException → org.apache.camel.support.processor.validation.PredicateValidationException org.apache.camel.util.toolbox.AggregationStrategies → org.apache.camel.builder.AggregationStrategies org.apache.camel.processor.aggregate.AggregationStrategy → org.apache.camel.AggregationStrategy org.apache.camel.management.JmxSystemPropertyKeys → org.apache.camel.api.management.JmxSystemPropertyKeys org.apache.camel.builder.xml.XPathBuilder → org.apache.camel.language.xpath.XPathBuilder (camel-xpath) org.apache.camel.builder.xml.InvalidXPathExpression → org.apache.camel.language.xpath.InvalidXPathException (camel-xpath) org.apache.camel.converter.stream.OutputStreamBuilder → org.apache.camel.support.builder.OutputStreamBuilder camel-coreのAPI全般にわたって次のtypoを直しました: chiper → cipher ReloadStrategySupport 、 FileWatcherReloadStrategy クラスは削除されました。 MessageHistoryFactory インタフェースにメッセージをフィルタまたはコピーするオプションが追加され、APIに細かな変更がありました。 TypeConverterAware インタフェースは削除されました。代わりに、型コンバータメソッドへのパラメータとして Exchange を使います。 Component 、 DataFormat インタフェースは、 Service インタフェースを継承するようになりました。コンポーネントやデータフォーマットにもそれらのライフサイクルを管理するサービスコントラクトがあるためです。デフォルトのベースクラスは既にそれらのインタフェースを実装しています。 コンポーネント共通の resolvePropertyPlaceholders オプションは削除されました。プロパティプレースホルダーの機能はCamel Main、Camel Spring Boot等で既にサポートされています。 EIP XML DSLの <setHeader> 、 <setProperty> <setHeader> の headerName 属性、 <setProperty> の propertyName 属性は、単に name に名前変更しました。 Camel 2.x: <setHeader headerName = "foo" ><simple> Hello ${body} </simple></setHeader> Camel 3.0: <setHeader name = "foo" ><simple> Hello ${body} </simple></setHeader> XML DSLの <aggregate> Aggregate EIPで、相関サイズ/タイムアウト(correlation size/timeout)を表現する条件式(expression)のタグ名が変更されました。XML上の名前衝突を避けるための措置です。 Camel 2.x: <completionSize> <header> mySize </header> </completionSize> Camel 3.0: <completionSizeExpression> <header> mySize </header> </completionSizeExpression> <completionTimeout> も同様に <completionTimeoutExpression> となります。 Hystrix EIP 元々あったHystrix EIPは、より一般的なCircuit Breaker EIPに変更され、他の実装をプラグインできるようになりました。 Java DSL、XML DSLでそれぞれ以下のように書き換える必要があります。 .hysterix() → .circuitBreaker() <hystrix> → <circuitBreaker> テスト camel-test camel-testを使っていて、これまでテスト用のBeanを登録するために createRegistry() メソッドをオーバーライドして JndiRegistry クラスをインスタンス生成していた場合、このテクニックはもう必要なくなりました。代わりに、 CamelContext から Registry APIを取得して bind() メソッドを使うのが推奨の方法になります。 context.getRegistry().bind( "myId" , myBean); adviceWith adviceWith を使ったテストは以下のように書き換える必要があります。 Camel 2.x: context.getRouteDefinition( "start" ).adviceWith(camelContext, new AdviceWithRouteBuilder() { ... } Camel 3.0: ModelCamelContext mcc = camelContext.adapt(ModelCamelContext. class ); RouteReifier.adviceWith(mcc.getRouteDefinition( "start" ), mcc, new AdviceWithRouteBuilder() { ... } AdviceWithRouteBuilder とラムダを使うともっと簡単に書けます。 AdviceWithRouteBuilder.adviceWith(context, "myRoute" , a -> { a.replaceFromWith( "direct:start" ); } 管理/監視 トレーシング Camelルーティングの詳細なログを出力するTracer機能の実装が、書き換えられました。新しいTracerでは、ログは org.apache.camel.Tracing ロガー名で出力されます。 JMXでは、 BacklogTracer はデフォルトで無効になりました。有効にするには、 CamelContext に backlogTracing=true をセットします。 JMXイベント org.apache.camel.management.event パッケージにあったすべてのイベントクラスは、 org.apache.camel.spi.CamelEvent クラス内にサブクラスとして定義されるようになりました。例えば、 CamelContext の開始イベントは CamelEvent.CamelContextStartedEvent になります。 EIP、コンポーネント等の参照用JMX APIの削除 EIPやコンポーネント、エンドポイント等を検索し、そのメタ情報を得るためのJMX APIは削除されました。これらのAPIはアプリケーション実行時にはあまり意味がなく、同じ情報は開発時にはcamel-catalogから得られるためです。関連するCamelのKarafコマンドも同様に削除されました。 カスタムコンポーネント/言語 カスタムコンポーネント カスタムコンポーネントは、今後は camel-core ではなく camel-support のみに依存するように実装すべきです。 DefaultComponent 、 DefaultEndpoint など、camel-coreにあったカスタムコンポーネントの開発に必要なクラスは、 org.apache.camel.impl パッケージのからcamel-supportの org.apache.camel.support パッケージに移されました。 同様に、camel-coreの org.apache.camel.util.component パッケージにあった全てのクラスもcamel-supportの org.apache.camel.support.component パッケージに移されました。 カスタム言語 @LaunguageAnnotation アノテーションは、 org.apache.camel.language パッケージから org.apache.camel.support.language パッケージへ移されました。 言語 Simple言語からのOUT Messageの削除 OUT Messageのコンセプトが廃止されたのに伴い、Simple言語からも ${out.body} といった用法が削除されました。 Simple言語の開始/終了トークン これまでSimple言語の開始/終了を表すトークンを変更できたのですが、誰も使っていなかったので最適化のために廃止されました。今後は、デフォルトの ${xxx} または $simple{xxx} のみが使用可能です。 Simple言語のproperty Camel 2.xでSimple言語の property はdeprecatedになっていましたが、Camel 3では削除されました。代わりに exchangeProperty を使います。 Terser言語 → HL7 Terser言語 Terser言語は、 terser → hl7terser に名前変更されました。 アノテーション 言語関連のアノテーションの変更は以下のとおりです。 org.apache.camel.language.XPath → org.apache.camel.language.xpath.XPath (camel-xpath) org.apache.camel.language.Bean → org.apache.camel.language.bean.Bean (camel-bean) org.apache.camel.language.Simple → org.apache.camel.language.simple.Simple org.apache.camel.language.SpEL → org.apache.camel.language.spel.SpEL (camel-spring) Camel Mavenプラグイン camel-maven-pluginが2つに分割されました。 camel-maven-plugin camel-report-maven-plugin 1つめのcamel-maven-pluginが run ゴールを持っていて、Camelアプリケーションを素早くスタンドアロン実行できるためのものです。 2つめのcamel-report-maven-pluginは valudate 、 route-coverage ゴールを持っていて、Camelプロジェクトのバリデーションやカバレッジのレポートを出力するためのものです。 既知の問題 内部のルーティングエンジンをリファクタリングした影響で、MDCロギングとbreadcrumb IDの扱いに一定の状況下で問題が見つかっています。この問題は、camel-zipkinコンポーネントにも影響しています。 最後に 本家のガイドは構成がカオスなので、意味のある構成を見つけ出して再構成するのに一番苦労しました。(その分、本家ガイドよりもこちらの方が参照しやすくなっているはず!)もし気が向いたら、本家ガイドにもこの記事の構成を反映させるかもしれません。 次回は、マイグレーションガイドのコンポーネント編を書く予定です。
※ 2020-04-27補足、CMS for RHELはRed Hat Insightsに統合されました。そのためRed Hat Smart Managementを購入しなくても、Red Hat Enterprise Linuxだけを購入すれば以下に紹介している機能を利用することができます。 Red Hatの森若です。 https://cloud.redhat.com/ をご存知の方はどのくらいいるでしょうか。2019年5月に公開されたRed HatのSaaSを提供する窓口となるドメインで、現在のところ以下の4つのサービスを提供しています。 Red Hat Insights Cloud Management Services for Red Hat Enterprise Linux Red Hat OpenShift Cluster Manager Red Hat Ansible Automation Platform この中にひとつだけまだ赤帽エンジニアブログで紹介されていないものがあります。ということで今回はCloud Management Services for Red Hat Enterprise Linux (以下 CMSforRHEL) をご紹介します。 CMSforRHELとは? CMSforRHELは、2019年5月にリリースされたRHELを管理するためのSaaS製品です。 特徴を簡単に以下にまとめます。 Red Hat Insightsのクライアント(insights-client)が送る情報を利用します。Red Hat Insightsが「ナレッジベースを基としてエンジニアが作り込んだルールで処理を行う」のに対して、CMSforRHELは「全errataや収集した情報について機械的に処理を行う」という点が大きく異なります。 Red Hat Smart Management の一部として提供されています。Red Hat Smart Managementは以前から存在するRed Hat SatelliteとCMSforRHELをあわせて提供しています。これらは同時に両方を使っても、どちらか片方だけを利用しても費用はおなじです。 クラウドプロバイダから提供される、Red Hat Satelliteから管理できないRHELも管理できます。 CMSforRHELの機能 管理対象のRHELについて、以下の機能を提供します。 既知の脆弱性に対応するerrataが適用されていない場合のレポートと、Ansible playbook生成 OpenSCAPのログ収集によるコンプライアンス管理 システム同士のプロファイル比較 それぞれを見ていきましょう。 既知の脆弱性に対応するerrataが適用されていない場合のレポートと、Ansible playbook生成 以下のスクリーンショットのように、各システムに影響する既知の脆弱性とその重大度を一覧し、条件によりフィルタします。さらにこれらの脆弱性にに対応する修正を適用するための Ansible Playbookを生成します。 脆弱性の一覧とフィルタ この項目を見て「この機能はRed Hat Insightsのものでは?」と思った方もいるかもしれません。Red Hat Insightsには脆弱性についてのルールも存在しますが、全ての脆弱性を対象とはしていません。これに対して、CMSforRHELでは、既存の脆弱性に関連するerrata全てを対象としている点が異なります。 Red Hat InsightsとCMSforRHELの比較 OpenSCAPのログ収集によるコンプライアンス管理 RHELにはOpenSCAPおよび SCAP Security Guide という、(主に)設定が企業内のポリシーや基準に沿っているかを自動で確認するためのツール、チェックリスト、プロファイルが同梱されています。CMSforRHELは、OpenSCAPの出力をinsights-client経由でアップロードすることでWeb上で閲覧できます。 OpenSCAPスキャン結果の閲覧 SCAP Security Guideで対応している一部のチェック項目については、Ansible Playbookを生成して問題を修正することもできます。(パーティション分割の方法など対応できないものもあります。) 基準にあわない点をAnsibleで修正する システム同士のプロファイル比較 Red Hat Insightsのクライアントが取得したしたシステム情報を比較します。名前での絞り込みの他、比較対象間で同じもの、異なるもの、片方が未定義のものを指定してフィルタできます。あるシステムで発生するが別のシステムでは発生しない問題の切り分けなどで活躍します。 プロファイル比較 まとめ CMSforRHELは比較的最近登場した、新しいRHELの管理製品です。Red Hat Insightsが人手によるルールを充実させる一方で、ルールではカバーしきれない多数の脆弱性や、OpenSCAPの検査結果収集、システム同士の比較機能を提供します。 関連リンク ドキュメント 製品ページ
Red Hat の小林俊哉です。オープンソースのルールエンジン Drools のブログです。開発&プロジェクト管理GUIである Business Central と、ルールエンジン実行サーバーである Kie Server の2本立てです。 tokobayashi.hatenablog.com tokobayashi.hatenablog.com
皆さんこんにちは、Red Hat ソリューションアーキテクトの岡野です。 前回 Ansible Tower の可用性の一つということでクラスターについて書かせていただきました。 今回は、よりお手軽に利用可能なバックアップリストアについてご説明したいと思います。 #前回同様この記事は Ansible Tower 3.6をベースに動作確認を行っています。  将来のバージョンでは異なる動きとなる可能性もありますのであらかじめご了承ください。 Ansible Tower の可用性の担保を考えた場合、バックアップリストアは凄くお手軽に実装・運用できる手段です。 Ansible Tower インストールの際に使うコマンド、setup.sh の引数を "-b" とすればバックアップ、"-r" とすればリストアとなります。 手順は以下の通り簡単です。 1. バイナリの入手と解凍  インストール用のバイナリと同じものを使用します。入手先は以下参照。   https://releases.ansible.com/ansible-tower/setup/  ※入手するバイナリはバックアップホストと同じバージョンかつ最新のマイナーバージョンのものを入手します   例えば、3.4.0 や 3.4.2 を使っている場合は、3.4.5 (ansible-tower-setup-3.4.5-1.tar.gz) を入手してください 2. バックアップを取得  解凍した inventory ファイルを環境に合わせて編集し、以下のコマンドを実行します # ./setup.sh -b  バックアップデータは 1 つのファイルとなります 3. リストア先にバックアップファイルを転送 4. inventory ファイルの編集  手順 1 で取得したバイナリファイルから今度はリストア先の環境に合わせて inventory ファイルを編集します 5. リストア  バックアップファイルを指定してコマンドを実行します。 # ./setup.sh -e 'restore_backup_file=/path/to/nondefault/backup-data.tar.gz' -r これだけです。先日ご説明したクラスター環境も同様にバックアップリストア可能です。 なお、バックアップリストアに関しては、以下の様な条件があります。 ・リストア先はバックアップ元と同じバージョンとする ・リストアに利用するバイナリは最新のマイナーバージョンを利用(上記の通り) 手順3で作成されたバックアップデータは日付、時間を含む、 "tower-backup-YYYY-MM-DD-HH:MM:SS.tar.gz" という圧縮ファイルとなります。このファイルさえ保存しておけば、万が一の Ansible Tower 障害の際、PostgreSQLのデータ含め、一部の例外を除き丸ごと復旧することが可能です。 リストアに関しては、 ・既存の Ansible Tower 上にリストア ・新規ホストへのリストア というケースが考えられますが共に可能です。 但し、リストアは、Ansible Tower の新規インストールは行いません。このため、特に、新規ホストへのリストアの際は、あらかじめリストア先に Ansible Tower をインストールしておく必要があります。この際、バックアップ元とリストア先は、同じ Ansible Tower のバージョンで準備するようお願いします。 留意点 基本的には丸ごとリストアでほぼ同じ環境となるのですが、以下はリストアの際に失われる可能性があります。 ・インスタンスグループ ・/var/lib/awx/projects/ 配下の Playbook (Ansible Tower をクラスター構成している場合のみの制限) ・/var/log/tower/ 配下のログファイル  ※リストア先が既存ホストか、新規ホストかによって異なりますが、無くなる可能性があるということでご理解ください。 PostgreSQLのバックアップは pg_dump を利用。このため、バックアップ取得開始時点のスナップショットであり、DBとして内部的に整合性のとれたデータとなっています。ただ、Ansible Tower にはジョブ実行時のキューの情報などもあります。これがリストア時にどうなるのか実機で試してみました。 テスト内容 ジョブテンプレートを実行しながらバックアップを取得し他のホストにリストア 結果 バックアップジョブが失敗としてリストアされる。 右がバックアップ元の Ansible Tower のジョブの結果、左がリストアした Ansible Tower のジョブ結果です。このジョブは成功したのですが、リストアしたホストでは失敗ジョブとして記録されています。 エラー内容を見てみると・・・、 稼働中のジョブとして記述されているが、該当するキューがないとのこと。なるほど、という感じですね。 この結果から、リストアした時には実際には成功している直前のジョブが失敗として表記される可能性があります。 ま、それほどクリティカルな問題だとは思いませんが、もし気になる場合は、実行されているジョブがない時にバックアップを取得ください。 まとめ Ansible Tower のバックアップリストアは追加のソフトウェアも必要なく、かつ、オペレーションは極めて簡単です。あらかじめスタンバイホストとして Ansible Tower を新規で準備しておけば RTO も非常に短くなります。Ansible Tower の可用性の向上をお考えの方は是非ご検討ください。 Ansible Tower のバイナリーと評価ライセンスは以下から取得可能です。是非使ってみてください!! ・Ansible Tower バイナリーダウンロードは こちら から ・Ansible Towerの評価ライセンスリクエストは こちら から
皆さんこんにちは、Red Hat ソリューションアーキテクトの岡野です。 これから何回かに分けて、Ansible Tower について書いていきたいと思います。 第1回目は、 Tower を提案する際に良く聞かれる可用性、特に Ansible Tower クラスターについてご紹介したいと思います。 ※なお、この記事は、現時点で最新の、Ansible Tower 3.6.3 をベースに記載しています。  将来のバージョンでは異なる動きとなる可能性もありますのであらかじめご了承ください。 Ansible Tower では可用性を担保する仕組みとして、以下の様な選択肢があります。 クラスター(Active / Active) バックアップリストア Tower オブジェクト自体のコード化 どの仕組みを採用するかは災害発生時に許容される RPO/RTO に依存しますし、そもそも Ansible Tower が落ちても対象ノードのサービスが停止するわけではないのでそのあたりは可用性の要否をしっかり見極めた上で選択する必要がありますが、今回はその議論は置いておいて、まず、Ansible Tower のクラスターについてご紹介したいと思います。 1. Ansible Tower クラスター Ansible Tower の主な構成要素は以下の通りです。 ・Webサービス ・メッセージキュー ・データベース 上記コンポーネントを All in One で構成することも可能ですし、PostgreSQL の Database 部分のみ外出しにすることも可能ですが、クラスターを組む場合はデータベースを外出しにした上でそれ以外の部分を Active / Active で構成する形となります。クラスターのインストールは非クラスター構成と同様で、インストール用の構成ファイル(inventory)を編集するのみで極めて簡単です。ただし、残念ながら Ansible Tower のインストーラーでは PostgreSQL 部分の冗長化構成を作ることはできません。データベースの冗長化の部分に関しては別途ご検討いただく必要があります。この点はご注意ください 。 ・Active / Active の部分は3台~最大20台で構成する事が出来ます。  奇数台数を基本とします。(台数が多くなると奇数である必要性は少なくなってきます) ・各クラスターノードが UI 及び API のエントリーポイントとして機能するため、ロードバランサーは必須ではありません。 3台の Active / Active クラスターと外部 PostgreSQL を利用した場合の inventory ファイルの例は以下の通りです。 [tower] clusternode1.example.com clusternode2.example.com clusternode3.example.com [database] [all:vars] ansible_become=true admin_password='password' pg_host='dbnode.example.com' pg_port='5432' pg_database='tower' pg_username='tower' pg_password='password' rabbitmq_port=5672 rabbitmq_vhost=tower rabbitmq_username=tower rabbitmq_password='password' rabbitmq_cookie=rabbitmqcookie # Needs to be true for fqdns and ip addresses rabbitmq_use_long_name=true なお、インストールには root 権限が必要です。inventory ファイルの変数定義欄に、ユーザー、パスワード (または ssh 認証キー)など必要な情報を追記ください。 ansible_user=root ansible_ssh_password=”your_password_here” クラスターは Active / Active で動作します。複数のジョブテンプレートの並列実行はもちろんですが、1つのジョブテンプレートの並列実行も可能です。例えば以下の例では、1つのジョブテンプレートの実行の際、クラスターを構成する3台の Ansible Tower ホストが並列で 10台ずつ、計 30 台のホストに対して Playbook を実行する様子を示しています。この様な動作をジョブスライスと呼んでいます。 ジョブスライスを実行するには、ジョブテンプレートに対し以下の2点の設定を行う必要があります。 ・Job Slicing を 1 → 3 などスライス数に合わせて上げる ・同時実行ジョブの有効化にチェックを入れる ・実行ホストを絞りたい場合は、対象ホストを絞ったインスタンスグループを別途作成してジョブ実行することも可能(オプション) 上記設定を行うと、自動的にワークフロージョブとして同一の3つのジョブが同時実行されます。 なお、クラスター構成の場合主に管理面で少しばかり注意が必要です。 1つは、ローカルで作成した Playbook です。 Ansible Tower の場合、/var/lib/awx/projects/ 配下に Playbook を配置します。シングル構成の Ansible Tower であれば、そのホストにsshで接続して Playbook を作成、Ansible Tower のプロジェクトに登録してジョブテンプレートで利用、ということが可能ですが、クラスターの場合、1台ホストに記載するだけではそのホストがダウンした際にジョブテンプレートが実行できないことになります。このため、手動で、全ホストに対して Playbook を配置する必要があります。 これは、ホストダウンの時だけではなく、先ほどのジョブスライスでも同様で、並列実行対象の全ホストの/var/lib/awx/projects/ に Playbook を配置しておかないと Playbook が配置されてないホストで実行されたジョブが失敗します。 また、クラスター構成の場合、バックアップリストアの際も、このローカルに保存された Playbook は、リストア対象ではありません。このため、バックアップファイルをリストアした際には Playbook を個別に移動する必要があります。 ※クラスター構成ではなく単独ホストの場合は /var/lib/awx/projects/ 配下の Playbook はバックアップリストア対象となっています。 勿論、上記制限は、全ホストからアクセス可能な、Git等のSCMを使って Playbook を管理している場合は全く問題ありません。 Ansible Tower を利用した場合は、Git 等の SCM を使って Playbook のバージョンと品質を管理することを推奨していますが、クラスターの場合は管理面でもこちらがお勧めということになりそうですね。♬ Ansible Tower のバックアップリストアと、 オブジェクト自体のコード化については次回以降にご紹介したいと思います。 Ansible Tower のバイナリーと評価ライセンスは以下から取得可能です。是非使ってみてください!! ・Ansible Tower バイナリーダウンロードは こちら から ・Ansible Towerの評価ライセンスリクエストは こちら から  
インテグレーションのためのミドルウェア製品のテクニカルサポートを担当している山下です。 今回は レッドハットのシニアアーキテクトである Eric Murphy さんによる「マイクロサービスのための分散データ 〜 イベントソーシング vs チェンジデータキャプチャ(CDC)」の翻訳記事です。この記事では、イベントソーシング、CDC、CDC + Outboxパターン、CQRSをそれぞれ簡単に説明しながら、それらの特性の違いを比較します。また、イベントソーシングとCQRSの簡易な説明がなされている他、あまり明確に語られることが少ないもののソフトウェアの設計に大きな影響をおよぼすドメインイベントとチェンジイベントの違いにも触れられています。 [原文] Distributed Data for Microservices — Event Sourcing vs. Change Data Capture by Eric Murphy あんまり翻訳がうまくないのは許してください (^^; この記事では、イベントソーシング、コマンドクエリの責任分離(CQRS)、チェンジデータキャプチャ(CDC)、およびOutboxパターンの領域をみていきます。 これらのソリューションの価値が明らかになるでしょう。 そして異なるこれらの設計について、それぞれの長所/短所を用いて説明します。 そもそも、なぜこれらのソリューションが重要なのでしょうか? それは多くのチームがマイクロサービスを構築し、データを複数のデータストアに分散しているためです。 マイクロサービスのシステムでは、リレーショナルデータベース、オブジェクトストア、メモリ内キャッシュ、さらには検索インデックスが含まれている場合があります。 データはすぐさま失われたり、同期がとれなくなったり、破損するため、ミッションクリティカルなシステムには悲惨な結果をもたらすことがあります。 これらの深刻な問題を回避するソリューションは、多くの組織にとってとても重要です。しかし 残念ながら、こうした不可欠のソリューションを理解するのは困難でもあります。これはイベントソーシング、CQRS、CDC、およびOutboxでも例外ではありません。これらのソリューションを特定のユースケースにどのように適用できるかを学びそして理解する機会として捉えてください。 この記事の最後でわかるように、これら4つのソリューションのうち、3つは高い価値がありますが、残りの1つは稀な状況を除いては推奨されません。この記事でのアドバイスは、あなたの特有のユースケースに対して評価されるべきです。これら4つのソリューションのどれもが適切ではないこともあるでしょう。 リアクティブシステム 軽く振り返るなら、イベントソーシングとチェンジデータキャプチャ(CDC)は、リアクティブな分散システム(つまりマイクロサービス)の構築に使用できるソリューションです。 マイクロサービスは、レジリエント(回復力)とエラスティック(弾力性)を備えていることにより、絶えず変化する環境(つまりクラウド)に対応する必要があります。 これらの能力の背後にあるマジックは、メッセージとイベント駆動です。 詳細は Reactive Manifesto を読むことをお勧めします。 Figure 1. Attributes of a Reactive System, per the Reactive Manifesto イベントソーシングとチェンジデータキャプチャ(CDC)の共有のゴール この記事で紹介する2つのコアソリューションは、イベントソーシングとチェンジデータキャプチャです。 これらのソリューションを紹介する前に、これらが次の共通の目標を達成していることがわかるでしょう: 1つのデータストアを、特定のデータセットのためのグローバルな真実の情報源(source of truth)として指定する 過去や現在のアプリケーションの状態を、ジャーナルまたはトランザクションログとも呼ばれる一連のイベントとして表現する 必要に応じて状態を再構築または最新化するための、イベントを再生することができるジャーナルを提供する イベントソーシングは独自のジャーナルを情報源(source of truth)として使用し、一方でチェンジデータキャプチャは基礎となるデータベーストランザクションログを情報源(source of truth)として使用します。この違いは、この記事の後半で説明するソフトウェアの設計と実装に大きな影響を及ぼします。 ドメインイベント vs チェンジイベント 深く掘り下げる前に、イベントソーシングとチェンジデータキャプチャに関して、それぞれの関心事となるイベントのタイプを区別することは重要です。 ドメインイベント — アプリケーションによって生成される、ビジネスドメインの一部である明示的なイベント。 これらのイベントは通常、OrderPlacedやItemShippedなど、過去形で表される。ドメインイベントはイベントソーシングの主要な関心事。 チェンジイベント — データベーストランザクションログから生成されるイベント。発生した状態遷移を示す。 チェンジイベントはチェンジデータキャプチャにとっての関心事。 ドメインイベントとチェンジイベントは、チェンジイベントにドメインイベントが含まれている場合を除くなら関係ありません。チェンジイベントにドメインイベントが含まれているというのは、この記事の後半で紹介するOutboxパターンの領域です。 それでは、イベントソーシングとチェンジデータキャプチャに関するいくつかの共通点を確立したので、深く掘り下げましょう。 イベントソーシング イベントソーシングは、ソフトウェアがドメインイベントのジャーナルとしての状態を維持できるようにするソリューションです。 そうしてジャーナル全体でアプリケーションの現在の状態を表現します。 また、このジャーナルを使用すると、履歴を簡単に監査したり、以前の状態を再現してタイムトラベルしたりエラーを再現したりすることができます。 一般的にイベントソーシングの実装には次のような特徴があります: アプリケーションのビジネスロジックから生成されたドメインイベントが、アプリケーションに対する新しい状態を追加する アプリケーションの状態は、追記のみのイミュータブルなイベントログ(ジャーナル)を介して更新される ジャーナルは、アプリケーションの存続期間中、真実の情報源(source of truth)と見なされる ジャーナルは、どのような時点のアプリケーションの状態でも再構築できるようリプレイ可能である ジャーナルは、オブジェクト(DDD用語でいうところの集約)の現在の状態を補足するために、ドメインイベントをIDでグループ化する Figure 2. Representation of Event Sourcing Materializing an Object また加えて、イベントソーシングの実装には次の特徴があることもあります: アプリケーションの状態の再作成を高速化するためのジャーナルのスナップショットメカニズム 必要に応じてジャーナルからイベントを削除するメカニズム(通常はコンプライアンス上の理由から) アプリケーションの状態を配布するために使用できるイベントディスパッチのためのAPI 一般的なシステムでは存在するような強い一貫性のあるトランザクション保証は提供されない ジャーナル内のイベント形式の変更に対処するための下位互換性メカニズム アプリケーションの真実の情報源(source of truth)であるジャーナルをバックアップおよび復元するメカニズム イベントソースはデータベースの動作を模倣しますが、しかしそれはアプリケーションレベルにて行われます。 図2をみれば、データベースとほとんど同様の仕組み(図3)で更新されていることがわかるでしょう。 Figure 3. Representation of Database Transaction Materializing a Table この図2と図3の比較は、イベントソーシングとチェンジデータキャプチャを比較するにつれてより重要になります。 チェンジデータキャプチャ チェンジデータキャプチャ(CDC)は、データベーストランザクションログ(または同等のメカニズム)からチェンジイベントをキャプチャし、それらのイベントを下流コンシューマに転送するソリューションです。 CDCは、最終的にアプリケーションの状態を外部化し、データの外部ストアと同期することを可能にします。 通常、チェンジデータキャプチャの実装には次の特徴があります: トランザクションからチェンジイベントをマテリアライズ化する目的のために、データベースのトランザクションログを読み取る外部プロセスである チェンジイベントは、メッセージとして下流コンシューマーに転送される ご覧のとおり、CDCは非常に狭い範囲での比較的単純な概念です。それは単にデータベースのトランザクションログを、関心のあるコンシューマに対してイベントストリームとして、外部化するだけです。 Figure 4. Change Data Capture Implementation Options CDCは、イベントの消費方法に柔軟性与えます。 図4のように: オプション 1 は、トランザクションログからメッセージブローカーにイベントをキャプチャして転送するスタンドアロンCDCプロセス(ソースコネクタ) オプション 2 は、イベントをアプリケーションに直接送信する組み込みCDCクライアント オプション A は、CDCイベントをデータストアに直接永続化する別のコネクタ(シンクコネクタ) オプション B は、メッセージブローカーを介してアプリケーションにイベントを転送 最後に、CDC実装には度々次のような特徴があることもあります: 少なくとも1回の配信(at-least-once)保証で、イベントをすべてのコンシューマに転送するために、デュラブルなメッセージブローカーが利用される イベントが保持されている限り、データストアのトランザクションログまたはメッセージブローカーからイベントをリプレイする能力がある CDCは非常に柔軟で、複数のユースケースに適応できます。 アーリーアダプターのCDCの採用者はオプション 1 や A を選択していましたが、CDCが勢いを増すにつれて、オプション1 や B、そしてオプション 2 の人気が高まっています。 Outboxパターンを実装するためにCDCを利用する Outboxパターンの主な目的は、(テーブルに格納されている)アプリケーションの状態の更新とドメインイベントの発行を、単一のトランザクション内で行うことを保証することです。これには、データベース内にOutboxテーブルを作成して、トランザクションの一部としてそれらのドメインイベントを収集することを含みます。ドメインイベントとそのOutboxでの転送にまつわるトランザクションの保証は、システム全体のデータ一貫性にとって重要です。 トランザクションが完了すると、CDCコネクタによってドメインイベントが取得され、信頼できるメッセージブローカーを利用して関心のあるコンシューマーに転送されます(図5を参照)。 これらのコンシューマーは、このドメインイベントを使用して、彼ら自身の集約を具体化するかもしれません(上記のイベントソーシングを参照)。 Figure 5. Outbox Pattern implemented with CDC (2 Options) Outboxは、送信するイベントデータの一時的なストアにすぎず、読み取りやクエリは意図されていないため、アプリケーションからは抽象化されることもあります。実際、Outboxにあるドメインイベントは、挿入後にすぐに削除される可能性があります! イベントソーシングジャーナル vs Outbox これで、イベントソーシングジャーナルと、Outboxを用いたCDC の設計のオーバーラップを詳しく見ることができます。ジャーナルの属性をOutboxテーブルと比較することにより、類似性が明らかになります。 DDDでいうところの集約は、イベントソーシングとOutboxの双方にとって、データがどのように保存され消費されるかの中心にあります。 イベントソーシングジャーナルとOutbox間に存在する一般的な属性は次のとおりです: イベントID — イベントそれ自体の一意の識別子。べき等のコンシューマの重複排除にも使用できる 集約ID — イベントに関連したパーティションで利用される一意の識別子。 これらのイベントは集約の状態を構成 集約タイプ — 関心のあるコンシューマーのみにイベントをルーティングするために使用できる集約のタイプ シーケンス/タイムスタンプ — イベントをソートして順序を保証する方法 メッセージペイロード — 下流コンシューマーが読み取り可能な形式で交換されるイベントデータを含む Outboxテーブルとイベントソーシングジャーナルは基本的に同じデータ形式を持ちます。主な違いは、イベントソーシングジャーナルは永続的で不変のドメインイベントのストアであるのに対し、Outboxは非常に短命であり、ドメインイベントがチェンジイベント内に記録され、下流コンシューマに転送されるただの降着場であることです。 コマンドクエリの責任分離(CQRS) コマンドクエリの責任分離パターン(略してCQRS)は、一般的にイベントソーシングと共に利用されます。ただし、CQRSを使用するためにイベントソーシングは必要ありません。たとえば、代わりにOutboxパターンで実装できます。 CQRSとは何でしょうか?これは、いくらかのまとまったデータをクエリ可能な読み取り専用のビューにすることを主な目的として、プロジェクション(投影)と呼ばれるデータの代替表現を作成するパターンです。さまざまなクライアントが関心のある同じデータセットに対して、複数のプロジェクションがある場合があります。 CQRSのコマンド面では、アクション(コマンド)を処理し、そして最終的にプロジェクションされる状態を作成するために利用できるドメインイベントを生成する、アプリケーションに当てはまります。これが、CQRSがイベントソーシングに頻繁に関連付けられる1つの理由です。 CQRSがイベントソーシングと組合わされるもう1つの理由は、ジャーナルはアプリケーションによってクエリできないためです。 イベントソースシステムでデータをクエリする唯一の方法は、プロジェクションを使用することです。 これらのプロジェクションは結果整合性であることに留意してください。これにより柔軟性がもたらされますが、強い一貫性のあるビューからの逸脱と複雑さをも引き起こします。 Figure 6. Representation of Event Sourcing with CQRS Figure 7. Representation of Event Sourcing with CQRS using a Message Broker 図6と図7から分かるように、これらはイベントソーシングに基づくCQRSパターンの2つの異なる解釈ですが、最終結果は同じで、イベントからのみ生じるデータのクエリ可能なプロジェクションになります。 前述しましたが、CQRSは図8のようにOutboxパターンと組み合わせることもできます。この設計の利点はアプリケーションデータベース内で依然として強力な一貫性があることですが、しかしCQRSプロジェクションを用いた結果整合性となります。 Figure 8. Representation of the Outbox Pattern with CQRS ドメインイベントをアプリケーション内部で処理する この記事の中では、システム全体にデータを配布することに重点を置いていますが、アプリケーション内部でドメインイベントを使用することも重要です。 ドメインイベントを内部で処理することは、イベントの発生元と同じマイクロサービスコンテキスト内でのビジネスロジックの実行などの、さまざまな理由で必要となります。 これはイベント駆動アプリケーションを構築する一般的な方法です。 イベントソーシングまたはCDCのいずれかを用いて、ドメインイベントを内部的に処理するには、イベントをメモリで渡すディスパッチャメカニズムが必要で、これには Vert.x EventBus、Akka Actor System、あるいはSpring Application Events といった例があります。 しかしながらOutboxパターンの場合には、イベントはOutboxトランザクションが正常に完了した後にのみディスパッチされます。 特性の比較 この記事はたくさんの事を説明したので、要約した表が有益かもしれませんね: 特性 イベントソーシング CDC CDC + Outbox CQRS 目的 ドメインイベントを含むジャーナルの状態をキャプチャ トランザクションログからチェンジイベントをエクスポート CDCを介してOutboxからドメインイベントをエクスポート ドメインイベントを使用して、データのプロジェクションを生成 イベントタイプ ドメインイベント チェンジイベント チェンジイベントに組み込まれたドメインイベント ドメインイベント 真の情報源(Source of Truth) ジャーナル トランザクションログ トランザクションログ (実装に依存する) 境界(Boundary) アプリケーション システム システム (CDC) アプリケーション (Outbox) アプリケーションもしくはシステム 一貫性モデル N/A (ジャーナルにのみ書き込み) 強い一貫性 (テーブル)、結果整合性 (Change Event capture) 強い一貫性 (Outbox)、結果整合性 (Change Event capture) 結果整合性 リプレイ可能 Yes Yes Yes (実装に依存する) イベントソーシング + CQRS の 長所と短所 イベントソーシングとCQRSを理解したので、イベントソーシングとCQRSを組み合わせた場合の長所と短所を確認しましょう。これらの長所と短所は、利用可能な現在の実装を考慮し、分散システムを構築する私自身や他のエキスパート両方からの経験をもとに文書化しました。 イベントソーシング + CQRS の 長所 監査を目的としてジャーナルに簡単にアクセスできる 一般的にジャーナルへの大量の書き込み操作に対するパフォーマンスが高い 大量データに対してジャーナルをシャードできる可能性がある(ただしデータストア依存) イベントソーシング + CQRS の 短所 すべては結果整合性のデータです。 強い一貫性データの要件はイベントソーシングとCQRSには適合しません ジャーナルへの書き込みは読み取ることができません(クエリ観点から) ジャーナルおよびイベントソースアーキテクチャ周りの長期メンテナンスの考慮 エラーケースための補正アクションのための多くのコードを書く必要がある デュアル書き込みの欠陥を解決するためのトランザクション保証がない(後で説明します) イベントの形式が変化するために、レガシーデータの下位互換性または移行を検討する必要がある ジャーナルのスナップショットとそれに関連する影響を考慮する必要がある イベントソーシングとCQRSを使用した経験のある開発者は事実上存在しません イベントソーシングのユースケースが不足しているため適用が制限される イベントソーシングとCQRSのデュアル書き込みのリスク イベントソーシングの1つの問題は、アプリケーションにエラーがある場合、CQRSプロジェクションを更新することに失敗する可能性があることです。 これによりデータが失われる可能性があります。残念ながら、アプリケーション自体に適切な補正アクションを組み込まなければ、そのデータを回復することは困難かもしれません。 追加コードと複雑さは開発者に委ねられエラーが発生しやすくなります。 たとえば1つの回避策は、イベントソースジャーナルに相関する読み取りオフセット番号を追跡し、エラー時にドメインイベントを再処理してCQRSプロジェクションを更新できる、リプレイの能力を与えることです。 このエラーが発生する根本的な理由は、ジャーナルとCQRSプロジェクションの両方に書き込むためのトランザクションを欠いていることです。これは「デュアル書き込み」と呼ばれるものであり、エラーのリスクが大幅に増加します。 このデュアル書き込みの欠陥を図9に示します。 Figure 9. Lack of Transactional Integrity with Event Sourcing and CQRS 図7に示すように、メッセージブローカーを追加しても、デュアル書き込みの問題は解決しません。この設計では、メッセージブローカーにメッセージを書き出しているため、エラーが発生する可能性があります。 デュアル書き込みの欠陥は、CQRSでイベントソーシングを使用する際の課題のほんの一例です。 さらに、ジャーナルを真実の源泉(source of truth)として持つことによる長期的なメンテナンスとDay 2の影響により、時間の経過とともにアプリケーションのリスクが高まります。 また、イベントソーシングは、ほとんどのエンジニアには馴染みのないパラダイムであり、システムを再設計することにつながる誤った憶測や設計上の選択をしやすくなります。 イベントソーシングの長所と短所をCQRSと組み合わせて考えると、この設計に着手する前に代替案を探すことをお勧めします。 あなたのユースケースはイベントソーシングに適合するかもしれませんんが、CDCが適合する場合もあります。 CDCとOutbox のためのDebezium Debeziumは、Red HatがサポートするオープンソースCDCプロジェクトであり、過去数年間で徐々に人気を集めています。最近、Debeziumは、Quarkus Javaマイクロサービスランタイムの拡張機能を備えたOutboxパターンの完全なサポートを追加しました。Debezium、Quarkus、およびOutboxは、デュアル書き込みの欠陥を回避する包括的なソリューションを提供し、一般的にイベントソースソリューションと比較して、平均的な開発者チームにとってより実用的なソリューションです。 Figure 10. Error Handling of the Outbox Pattern with CQRS CDC + Outbox with Debezium の長所 真実の源泉(Source of truth)は、アプリケーションデータベースのテーブルとトランザクションログ内にとどまります トランザクションの保証と信頼できるメッセージングにより、データの損失または破損の可能性が大幅に減少します プロトタイピカルなマイクロサービスアーキテクチャに適合する柔軟なソリューション シンプルな設計は、長期にわたって維持しやすい 自身の書き込みを読み取りとクエリが可能 アプリケーションデータベース内の強力な一貫性の機会がある。 残りのシステム全体にまたがる結果整合性 CDC + Outbox with Debezium の短所 トランザクションログを読み取り、メッセージブローカーを通過することにより、追加のレイテンシが発生する場合があります。 レイテンシーを最小化するためにチューニングが必要な場合があります。 Quarkusは優れていますが、既製された Outbox API の現在の唯一のオプションです。しかし 必要に応じて独自の実装をロールすることもできます。 まとめ マイクロサービスを使用した分散システムの構築は、非常に困難な場合があります。 それが、イベントソーシングのような斬新なソリューションを検討する上で魅力的な理由です。 ただし、通常、Debeziumを使用するCDCおよびOutboxは、イベントソーシングのより優れた代替手段であり、さらにはCQRSパターンと互換性があります。 一部のユースケースではイベントソーシングに価値がある場合がありますが、まずDebeziumとOutboxを試してみることをお勧めします。 さらに先へ進むためのリソース ドキュメント Debezium Tutorial Debezium Outbox Event Router Debezium Outbox Pattern Sample Application (Quarkus) Quarkus Getting Started ブログと記事 Reliable Microservices Data Exchange With the Outbox Pattern Transactional Outbox Pattern Outbox Event Router goes Supersonic! Introducing Event Sourcing Exploring CQRS and Event Sourcing What they don’t tell you about event sourcing Day Two Problems When Using CQRS and Event Sourcing Introducing Derivative Event Sourcing Domain Events versus Change Data Capture Reactive Manifesto ビデオとポッドキャスト Gunnar Morling on Change Data Capture and Debezium Microservices & Data: Implementing the Outbox Pattern with Debezium Eric Murphy Ericha はレッドハットのシニアアーキテクトです。彼はアプリケーション開発とOpenShiftのコンサルティングプロジェクトをリードしています。 Eric はシアトルのそばに住んでいます。 [ twitter ] [ github ]