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

TECH PLAY

Red Hat  - Open Innovation Labs

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

全900件

Red Hat のソリューションアーキテクトの瀬戸です。 これは Jakarta EE / Java EE Advent Calendar 2025 の8日目の記事です。 トップに前後記事へのリンクを張るのが面倒くさくなってきたので、今回から端折ります。 QuarkusはMicroPrifleを基にしたアプリケーションフレームワークです。 MicroProfileは旧Java EEのAPIを使いながらJava Alternativeとして生まれた仕様で、マイクロサービスアーキテクチャ向けにエンタープライズ Java を最適化することを目的としています。 Java EEがOracle社からEclipse Foundationsに移管され、Jakarta EEとなってからはJakarta EEとMicroProfileの融和が図られています。Jakarta EE 10ではCoreProfileが定義され、Jakarta EEとMicroProfileは密接に結合しています。 Jakarta EEとMicroProfileの関係 実は、QuarkusはQuarkus 3.Xの時点だとおおよそMicroProfile 6.0~7.0に対応していますが、完全に準拠しているわけではなく、MicroProfile の互換製品の一覧には載っていません。 *1 *2 ただ、実務上は問題がない程度で、多くの人はMicroProfileに準拠した製品だという認識を持っていると思います。 その中で、MicroProfileに含まれていないJakarta EEの仕様(機能)はどうなってるの?(使えるの?)という質問を受けました。 (ここまで前説が長かった!) QuarkusではMicroProfileに含まれていないがJakarta EEに含まれている仕様でもサポートされている場合があります と、いうのが回答となります。 オフィシャル(コミュニティ版の記述ですが)では3.20時点ではJakarta EEの次の仕様が実装されています。 Jakarta Core 10 Jakarta Contexts and Dependency Injection 4.1 (Lite) Jakarta Bean Validation 3.0 Jakarta Persistence 3.1 Jakarta Transactions 2.0 Jakarta RESTful Web Services 3.1 Jakarta JSON Processing 2.1 Jakarta JSON Binding 2.1 Jakarta Batch 2.1 ja.quarkus.io ただ、完全に仕様に準拠しているのか?といわれると微妙なところで、例えばJakarta Persistenceではpersistence.xml の使用時に制限があります。 ja.quarkus.io ただ、多くの実装はJBoss EAP/Wildflyと同じライブラリが使用されているため、いくつか制限はあるもののJakarta EEサーバー(JBoss EAP/Wildfly)と同じように使えるはずです。 また、仕様を実装するとは書いてないものの、使用できる機能もあります。 例えば、Servletなども使用できます。 ja.quarkus.io なお、Red Hatではサポートしていませんが、JSFも使用する事ができます。 quarkus.io 公式のサポートがある、無いにかかわらず、Quarkusに登録されているエクステンションはスターターのページで検索することができます。 MicroProfileに含まれてないから自前でOSSのjarを入れようという前にエクステンションが提供されているかを確認するとよいでしょう。 code.quarkus.io ということで、QuarkusではMicroProfileに含まれていない機能についても使用ができるよという話でした。 Red HatではMicroProfileに含まれていない機能でもサポートしている場合があります。 詳細については次のページをご確認ください。 access.redhat.com また、Jakarta EEをお使いのお客様はJakarta EEが標準仕様で他ベンダーとの互換性を期待されていることも多いと思いますが、当然ながらMicroProfile外の機能はJakarta EE標準機能であっても他ベンダーのMicroProfile実装では使用できない可能性がある点については注意が必要です。この記事についてはMicroProfile準拠の場合の一般的な話ではなく、現状のQuarkusについて説明した記事であることをご留意ください。 12/9: 文章の表現を直しました。 *1 : https://microprofile.io/compatible/7-0/ *2 : https://microprofile.io/compatible/6-1/
Apache Camel Advent Calendar 8日目の記事は、サポート担当古市が担当します。テーマは、「Camel File コンポーネント」 Apache Camel 1.0 から提供されている古参のコンポーネントであり、クラウドや AIなどで賑わっている昨今においても、サポート業務で度々お問い合わせを受ける人気コンポーネントの1つです。 こんな作業を検討されている方は、ぜひ camel-file コンポーネントのご利用をご検討ください。 特定ディレクトリーからファイルを定期的に読み込む 特定ディレクトリーへファイルを出力する よく聞く話では、 メインフレームとの連携にファイルを使用 工作機器やガジェットとの連携にファイルを使用 ファイルデータ転送 といった用途で使用されているようです。 camel ftp コンポーネントもありますので、FTP環境をお持ちの方は、こちらを検討しても良いかもしれません。 また、ファイルデータ転送については、本当に必要なデータのみを必要なタイミングで転送しているか再考してみると気付きがあるはずです。camel route はあらゆるプロトコルと連動し柔軟にインテグレーションを実装できますので、「夜間バッチで特定ディレクトリ配下のファイルを全て別環境へコピーする」といった運用では勿体無く感じます。(もちろん、メリットもありますので否定はしません。) camel を使えばシンプルな運用ができそうだけれど、どう実装すれば良いかわからない。 camel ルートを作ってみたけれど、もっと良い方法があるか気になる。 こういった方は、ぜひ Red Hat セールスチームへご相談いただければと思います。コンサルティングサービスやトレーニングサービスのご提案が可能です。もちろん、Apache Camel コミュニティーが運用する SNS で相談も可能です。 camel.apache.org それでは、簡単なデモで試してみます。 camel-file に関するブログ記事などが散見されますが、ご利用するにあたり、製品ドキュメントもしくはコミュニティードキュメントを確認していただく方法を強くお勧めします。 ここでは、コミュニティードキュメントを見ていきます。 camel.apache.org 圧倒的な query parameter の量に驚かれるかもしれません。この豊富なオプションが、camel を使う理由の1つでしょう。 "Usage"セクションには、多数サンプルが記述されています。きっとイメージしている使用例が見つかるはずですので、一通り見ていただくと良いです。 よくあるケースとして、CSVファイルを読み込んでみます。まずは、ファイル内容を出力してみます。 % tree . ├── data │   └── sample.csv └── Hello.java 2 directories, 2 files % cat data/sample.csv 1,Bob,23 2,Nancy,30 3,David,18 % cat Hello.java import org.apache.camel.builder.RouteBuilder; public class Hello extends RouteBuilder { @Override public void configure() throws Exception { from("file:data?charset=utf-8") .log("${body}") .log("${headers}"); } } % % camel run Hello.java ~割愛~ 2025-08-20 10:11:59.245 INFO 6442 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.13.0 (Hello) started in 93ms (build:0ms init:0ms start:93ms boot:2s138ms) 2025-08-20 10:12:00.217 INFO 6442 --- [5 - file://data] Hello.java:8 : 1,Bob,23 2,Nancy,30 3,David,18 2025-08-20 10:12:00.220 INFO 6442 --- [5 - file://data] Hello.java:9 : {CamelFileAbsolute=false, CamelFileAbsolutePath=/Users/hfuruich/training/camel/data/sample.csv, CamelFileInitialOffset=org.apache.camel.support.resume.Resumables$AnonymousResumable@7102b6dc, CamelFileLastModified=1755651928676, CamelFileLength=30, CamelFileName=sample.csv, CamelFileNameConsumed=sample.csv, CamelFileNameOnly=sample.csv, CamelFileParent=data, CamelFilePath=data/sample.csv, CamelFileRelativePath=sample.csv, CamelMessageTimestamp=1755651928676} camel-file consumer endpoint が実行された時点で exchange.body には Fileのラップオブジェクトがセットされますが、.log("{$body}") 実行時に自動的にファイルを読み込み文字列をターミナルへ出力しています。 大量のヘッダー値も出力されています。個々のヘッダー値についてはコミュニティードキュメントの "MESSAGE HEADERS"セクションに解説がありますので、そちらをご覧ください。 data ディレクトリーには .camel ディレクトリーが作成され、sample.csv ファイルはそちらへ移動しています。 挙動確認のために .log("${headers}") をわざわざ記載せず、前回ご紹介した trace を使ってモニターしても良いです。 その場合、"initialDelay" オプションをセットし、consumer endpoint のポーリングが開始される前に trace を開始します。 % cat Hello.java import org.apache.camel.builder.RouteBuilder; public class Hello extends RouteBuilder { @Override public void configure() throws Exception { from("file:data?charset=utf-8&initialDelay=30000") .log("${body}"); } } % % camel run Hello.java --background Running integration with the following configuration: --camel-version=4.13.0 Running Camel Main: Hello in background with PID: 8717 (waiting to startup) Camel Main: Hello (state: Running) % camel trace PID NAME AGE STATUS TOTAL QUEUE FILTER PATTERN 8717 Hello 6s Standby 0 0 % camel trace Hello --action=start % % ls data sample.csv % ls data % % camel trace Hello --action=dump 2025-08-20 10:29:51.711 8717 --- [) thread #5 - file://data] route1/*--> : 1 - Created Endpoint file://data?charset=utf-8&initialDelay=30000 Exchange (DefaultExchange) InOnly FD18A47B92D4549-0000000000000000 Message (GenericFileMessage) Header (Boolean) CamelFileAbsolute false Header (String) CamelFileAbsolutePath /Users/hfuruich/training/camel/data/sample.csv Header (resume.Resumables.AnonymousResumable) CamelFileInitialOffset org.apache.camel.support.resume.Resumables$AnonymousResumable@43068e59 Header (Long) CamelFileLastModified 1755651928676 Header (Long) CamelFileLength 30 Header (String) CamelFileName sample.csv Header (String) CamelFileNameConsumed sample.csv Header (String) CamelFileNameOnly sample.csv Header (String) CamelFileParent data Header (String) CamelFilePath data/sample.csv Header (String) CamelFileRelativePath sample.csv Header (Long) CamelMessageTimestamp 1755651928676 (2025-08-20 10:05:28 / 24m47s ago) Body (org.apache.camel.component.file.GenericFile) (size: 30 bytes: 32) 1,Bob,23\n2,Nancy,30\n3,David,18 2025-08-20 10:29:51.718 8717 --- [) thread #5 - file://data] route1/log1 : 2 - Processed (1ms) Exchange (DefaultExchange) InOnly FD18A47B92D4549-0000000000000000 Message (GenericFileMessage) Header (Boolean) CamelFileAbsolute false Header (String) CamelFileAbsolutePath /Users/hfuruich/training/camel/data/sample.csv Header (resume.Resumables.AnonymousResumable) CamelFileInitialOffset org.apache.camel.support.resume.Resumables$AnonymousResumable@43068e59 Header (Long) CamelFileLastModified 1755651928676 Header (Long) CamelFileLength 30 Header (String) CamelFileName sample.csv Header (String) CamelFileNameConsumed sample.csv Header (String) CamelFileNameOnly sample.csv Header (String) CamelFileParent data Header (String) CamelFilePath data/sample.csv Header (String) CamelFileRelativePath sample.csv Header (Long) CamelMessageTimestamp 1755651928676 (2025-08-20 10:05:28 / 24m47s ago) Body (org.apache.camel.component.file.GenericFile) (size: 30 bytes: 32) 1,Bob,23\n2,Nancy,30\n3,David,18 2025-08-20 10:29:51.711 8717 --- [) thread #5 - file://data] route1/*<-- : 3 - Completed (success) (1ms) Endpoint file://data?charset=utf-8&initialDelay=30000 Exchange (DefaultExchange) InOnly FD18A47B92D4549-0000000000000000 Message (GenericFileMessage) Header (Boolean) CamelFileAbsolute false Header (String) CamelFileAbsolutePath /Users/hfuruich/training/camel/data/sample.csv Header (resume.Resumables.AnonymousResumable) CamelFileInitialOffset org.apache.camel.support.resume.Resumables$AnonymousResumable@43068e59 Header (Long) CamelFileLastModified 1755651928676 Header (Long) CamelFileLength 30 Header (String) CamelFileName sample.csv Header (String) CamelFileNameConsumed sample.csv Header (String) CamelFileNameOnly sample.csv Header (String) CamelFileParent data Header (String) CamelFilePath data/sample.csv Header (String) CamelFileRelativePath sample.csv Header (Long) CamelMessageTimestamp 1755651928676 (2025-08-20 10:05:28 / 24m47s ago) Body (org.apache.camel.component.file.GenericFile) (size: 30 bytes: 32) 1,Bob,23\n2,Nancy,30\n3,David,18 traceログからも、各Header値を確認できました。body には org.apache.camel.component.file.GenericFileオブジェクトがセットされていることも読み解けます。 ある程度動作確認をしたあとは、traceデータの消去や実行中のインテグレーションの停止もお忘れなく。 % camel trace Hello --action=stop % camel trace Hello --action=clear % camel stop Hello Shutting down Camel integration (PID: 8717) % camel-jbang で簡単に動作確認をできるので、コミュニティードキュメントを参考にしつつ、まずは気になるオプションを試してみてください。 読み込んだ csvファイルを分割してデータ変換することもできます。 hfuruich@hfuruich-mac camel % cat Hello.java import org.apache.camel.builder.RouteBuilder; import org.apache.camel.model.dataformat.JsonLibrary; public class Hello extends RouteBuilder { @Override public void configure() throws Exception { from("file:data?charset=utf-8") .split(body().tokenize("\n")) .unmarshal().csv() .marshal().json(JsonLibrary.Jackson) .log("${body}"); } } % camel run Hello.java ~割愛~ 2025-08-20 10:59:24.418 INFO 12558 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.13.0 (Hello) started in 99ms (build:0ms init:0ms start:99ms boot:1s960ms) 2025-08-20 10:59:25.403 INFO 12558 --- [5 - file://data] Hello.java:12 : [["1","Bob","23"]] 2025-08-20 10:59:25.404 INFO 12558 --- [5 - file://data] Hello.java:12 : [["2","Nancy","30"]] 2025-08-20 10:59:25.404 INFO 12558 --- [5 - file://data] Hello.java:12 : [["3","David","18"]] 条件式も camel は提供しているので、アイディア次第で柔軟なルーティングか可能です。 スモールスタートでまずはファイルの入出力を試していただき、そこから少しずつルーティングの規模を広げてアイディアを形にしていってください。 明日の advent calendar 9日目では、「Camel kafka コンポーネント」についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com
はじめに APIリクエストはどこで止められるのか? 各コンポーネントの役割と守備範囲 RBAC (Role-Based Access Control) Validating Admission Policy (VAP) Gatekeeper Operator (OPA) 使い分けのディシジョンツリー 【実機検証】振る舞いの違いを確認する シナリオA:RBACによる「認可」の壁 シナリオB:Gatekeeperによる「ポリシー」の壁 シナリオC:VAPによる「ネイティブ・ガードレール」の壁 Gatekeeperにしかできないこと:他のリソースとの突き合わせ シナリオD:Ingressホスト名の重複禁止(Gatekeeper独自の強み) 堅牢なクラスターのために 最終的な使い分けまとめ 補足:OpenShiftにおけるGatekeeperの導入とRHACMの関係 導入形態の違い 操作感(インターフェース)の違い はじめに OpenShift Advent Calendar 2025の7日目のエントリーを担当します、金子です。さっそく見ていきましょう。 qiita.com KubernetesやOpenShiftの運用において、「誰に何の権限を与えるか」という議論と、「リソースの設定ミスをどう防ぐか」という議論は混同されがちです。セキュリティとガバナンスを強固にするためには、RBAC(認可)、Validating Admission Policy(VAP)、そしてGatekeeperという3つの異なるメカニズムを理解し、適切に組み合わせる多層防御のアプローチが不可欠です。本記事では、これら3つの機能の守備範囲を整理し、実際のコマンド操作を通じて、それぞれの挙動の違いを体感的に理解することを目指します。 APIリクエストはどこで止められるのか? まず、ユーザーが oc や kubectl コマンドを実行した際、リクエストが処理されるまでのフローを整理します。 認証 (Authentication): あなたは誰ですか? (User, Group, SA) 認可 (Authorization / RBAC): その操作をする権利はありますか? (Verbに対する制御) アドミッション制御 (Admission Control / VAP, Gatekeeper): そのリソースの内容はルールに適合していますか? (Payloadに対する制御) 各コンポーネントの役割と守備範囲 ここでは3つの主要コンポーネントの特徴を比較します。 RBAC (Role-Based Access Control) 役割: 「誰が」「何を」できるかの認可。 特徴: APIに対する「動詞(Create, Get, Deleteなど)」を制御。 できないこと: 「レプリカ数は3以下に制限する」「特定のラベルを必須にする」といったリソースの中身(設定値)の検証。 Validating Admission Policy (VAP) 役割: Kubernetesネイティブなアドミッション制御。 特徴: K8s v1.30で安定版となった新機能。外部Webフック不要でプロセス内で完結。 ポリシー言語に CEL (Common Expression Language) を使用。シンプルで高速。 Gatekeeper Operator (OPA) 役割: OPA (Open Policy Agent) を利用した高度なアドミッション制御。 特徴: ポリシー言語に Rego を使用。複雑なロジックや外部データとの結合が可能。 OpenShiftでは RHACM (Red Hat Advanced Cluster Management for Kubernetes) と連携し、マルチクラスターへのポリシー配布や監査レポートの一元管理に強みを持つ。 使い分けのディシジョンツリー 結局、どれをいつ使うべきなのでしょうか? 判断基準 推奨コンポーネント 理由 アクセス権の制御 RBAC (必須) 全ての基本。Namespaceの分離や特権の制限に使用。 シンプルな設定値チェック VAP K8sネイティブ機能で完結させたい場合。外部依存を排除し、高速に動作させたい場合。 複雑なルール・マルチクラスター Gatekeeper RHACMを利用している、またはRegoによる高度な記述(データの結合など)が必要な場合。 【実機検証】振る舞いの違いを確認する ここからは実際にOpenShift/Kubernetes環境での挙動を確認します。「RBACで弾かれる場合」と「アドミッション制御(Gatekeeper/VAP)で弾かれる場合」のエラーメッセージの違いに注目してください。 シナリオA:RBACによる「認可」の壁 前提: ユーザー user1 は rbac-sample Namespaceの view 権限(Namespace 内部の参照権限) しか持っていません。 # ユーザー user1 に参照権限のみ付与する $ oc adm policy add-role-to-user view user1 -n rbac-sample 読み取り操作 (成功) # ユーザー user1 で実行 $ oc get pod -n rbac-sample NAME READY STATUS RESTARTS AGE httpd-6dd6796d4d-znbmj 1/1 Running 0 7m33s 解説: Roleに get 動詞が許可されているため、アクセス可能です。 作成操作 (失敗) # ユーザー jane で実行 $ oc create deployment nginx --image=nginx -n rbac-sample error: failed to create deployment: deployments.apps is forbidden: User "user1" cannot create resource "deployments" in API group "apps" in the namespace "rbac-sample" 解説: これは RBACによる拒否 です。リソースの中身を見る以前に、そもそも「Deploymentを作成する」というアクション自体が許可されていません。 シナリオB:Gatekeeperによる「ポリシー」の壁 前提: ユーザー admin (強い権限 cluster-admin) で操作します。ただし、クラスターには以下のポリシーが適用されています。 ポリシー: 全てのNamespace作成時に gatekeeper: required ラベルが必須。 モード: Enforce (強制ブロック) 詳細は割愛しますが、まずGatekeeperを利用して、ラベルがないとエラーとする定義を作成します。 前半は ConstraintTemplate の定義であり、これを適用することで独自のCRD(カスタムリソース定義)が作成されます。 apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8suserrequiredlabels spec: crd: spec: names: kind: K8sUserRequiredLabels validation: openAPIV3Schema: type: object properties: username: type: string labels: type: object additionalProperties: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8suserrequiredlabels violation[{"msg": msg}] { # 1. 操作しているユーザー名を取得 user := input.review.userInfo.username # 2. パラメータで指定されたターゲットユーザーと一致するか確認 # 一致しない場合、このルールは適用されない(何もしない) user == input.parameters.username # 3. ラベルの検証ロジック # パラメータで要求されたラベル(key/value)のリストを取得 required_key := input.parameters.key required_value := input.parameters.value # リクエスト内のラベルを取得 (存在しない場合は空オブジェクト) provided_labels := object.get(input.review.object.metadata, "labels", {}) # 実際に設定されている値を取得 (存在しない場合は空文字) actual_value := object.get(provided_labels, required_key, "") # 要求された値と一致しない場合に違反とする actual_value != required_value msg := sprintf("User '%v' must provide label '%v: %v' when creating this resource.", [user, required_key, required_value]) } 実体を作ります。今回のルールは、admin ユーザーがラベル gatekeeper=requiredを付与しないと、Namespaceを作成できないようにします。 apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sUserRequiredLabels metadata: name: admin1-must-label-namespaces spec: match: kinds: - apiGroups: [""] kinds: ["Namespace"] parameters: username: "admin" # 対象とするユーザー名 key: "gatekeeper" # 必須ラベルのキー value: "required" # 必須ラベルの値 ポリシー違反のリソース作成 (失敗) # ユーザー admin で実行(ラベルなしで作成) $ oc create namespace new-project Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: [admin1-must-label-namespaces] User 'admin' must provide label 'gatekeeper: required' when creating this resource. 解説: これは アドミッション制御による拒否 です。Adminユーザーなので「作成する権限」自体は持っています(RBACは通過)。しかし、リクエストされた「リソースの中身(ラベル不足)」がポリシーに違反しているため、永続化の直前でブロックされました。 ポリシー準拠のリソース作成 (成功) # ユーザー admin で実行(ラベルありで作成) $ cat <<EOF | oc apply -f - apiVersion: v1 kind: Namespace metadata: name: labeled-project labels: gatekeeper: required EOF namespace/labeled-project created 解説 : リソースの中身がポリシー(必須ラベルの付与)を満たしているため、無事に作成されました。 シナリオC:VAPによる「ネイティブ・ガードレール」の壁 目的: VAPがどのようにリソースの設定値(Payload)を検証するかを確認します。Gatekeeperよりも軽量で、Kubernetesのコア機能として動作する点がポイントです。 前提: ユーザー admin で操作します。VAPポリシーにより、Deploymentのレプリカ数は「5以下」に制限されています。 以下が上記の前提を vap-sample Namespace に適用するためのサンプルです。 apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: limit-deployment-replicas spec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: ["apps"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["deployments"] validations: - expression: "!has(object.spec.replicas) || object.spec.replicas <= 5" message: "Deployment replicas must be less than or equal to 5." --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: limit-deployment-replicas-binding spec: policyName: limit-deployment-replicas validationActions: [Deny] matchResources: namespaceSelector: matchExpressions: # 変更点: key が "vap-sample" に一致する(In)場合のみ適用する - key: kubernetes.io/metadata.name operator: In values: ["vap-sample"] ルール違反のリソース作成 (失敗) # ユーザー admin で実行(レプリカ数を10に設定) $ oc create deployment heavy-app --image=nginx --replicas=10 -n vap-sample error: failed to create deployment: deployments.apps "heavy-app" is forbidden: ValidatingAdmissionPolicy 'limit-deployment-replicas' with binding 'limit-deployment-replicas-binding' denied request: Deployment replicas must be less than or equal to 5. 解説 : これが VAPによる拒否 です。 APIサーバー自体がCEL式 object.spec.replicas <= 5 を評価し、即座にエラーを返しています。外部Webフックとの通信が発生しないため、レスポンスが高速で、エラーメッセージも標準的なAPI検証エラーの一部として返されます。 ルール準拠のリソース作成 (成功) # ユーザー admin で実行(レプリカ数を3に設定) $ oc create deployment light-app --image=nginx --replicas=3 -n vap-sample deployment.apps/light-app created Gatekeeperにしかできないこと:他のリソースとの突き合わせ VAPとGatekeeperの最大の違いは、 「自分以外のリソースが見えているか」 です。 例えば、「クラスター全体でIngressのホスト名が重複しないようにする」という要件を考えてみましょう。 VAPの場合 : 「リクエストされたIngressのホスト名が example.com か?」は判定できますが、「example.com が他のNamespaceですでに使われているか?」を知るすべがありません。 Gatekeeperの場合 : OPAがクラスターの状態(Inventory)をキャッシュしているため、「全NamespaceのIngressを検索し、同じホスト名があれば拒否する」というロジックが書けます。 シナリオD:Ingressホスト名の重複禁止(Gatekeeper独自の強み) 目的: 異なるNamespace間でのIngressホスト名の衝突(ハイジャック)を防ぎます。これはマルチテナント環境では必須級のセキュリティ要件です。 ポリシー設定 (YAML) Gatekeeperで「クラスター内の全Ingress」を参照する設定です。 # 4. gatekeeper-unique-ingress.yaml apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8suniqueingresshost spec: crd: spec: names: kind: K8sUniqueIngressHost targets: - target: admission.k8s.gatekeeper.sh rego: | package k8suniqueingresshost # クラスター内の他のIngressとホスト名が被っていないかチェック violation[{"msg": msg}] { input.review.kind.kind == "Ingress" # リクエスト内のホスト名を取得 host := input.review.object.spec.rules[_].host # インベントリ(既存リソース)から他のIngressを検索 other := data.inventory.namespace[other_ns][_]["Ingress"][other_name] # 自分自身との比較は除外 not (other_ns == input.review.object.metadata.namespace) # 他のIngressも同じホスト名を持っていたら違反 other.spec.rules[_].host == host msg := sprintf("Ingress host '%v' is already used in namespace '%v'", [host, other_ns]) } --- apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sUniqueIngressHost metadata: name: unique-ingress-host spec: match: kinds: - apiGroups: ["networking.k8s.io"] kinds: ["Ingress"] 実機検証 Step 1: ユーザーJaneが正常にIngressを作成 # namespace: project-a で作成 $ oc create ingress app-a --rule="myapp.example.com/*=service-a:80" -n project-a ingress.networking.k8s.io/app-a created これは最初の作成なので成功します。 Step 2: 別のユーザーが同じホスト名でIngressを作成(衝突) # namespace: project-b で作成(攻撃や設定ミスのシミュレーション) $ oc create ingress app-b --rule="myapp.example.com/*=service-b:80" -n project-b error: failed to create ingress: admission webhook "validation.gatekeeper.sh" denied the request: [unique-ingress-host] Ingress host 'myapp.example.com' is already used in namespace 'project-a' 解説 : Gatekeeperが拒否しました。 Gatekeeperは「今作成しようとしているリソース」だけでなく、「project-a にある既存のIngress」の情報も持っているため、この重複を検知できます。これはVAP(現時点の標準機能)では実現できません。 堅牢なクラスターのために 権限管理は「鍵」と「ルール」の関係に似ています。 - RBAC は「鍵」です。誰が部屋(API)に入れるかを管理します。 - VAP / Gatekeeper は「入室ルール」です。「泥だらけの靴で入ってはいけない(不適切な設定のリソース)」をチェックします。 鍵を持っているからといって、部屋を散らかして良いわけではありません。OpenShift環境においては、基本としてRBACを設計し、設定のガバナンスにはVAP(シンプル・ネイティブ志向)やGatekeeper(RHACM連携・エンタープライズ志向)を要件に応じて適切に組み合わせることで、セキュアで管理しやすい基盤を構築しましょう。 最終的な使い分けまとめ 機能 RBAC VAP (CEL) Gatekeeper (Rego) 主な役割 アクセス権の認可 (Who can do What) 自己完結型の検証 (Is this resource valid?) コンテキスト認識型の検証 (Is this resource valid in this cluster?) 判定材料 ユーザー、動詞、リソースの種類 リクエストされたリソースの中身(Payload) リソースの中身 + 他のリソースの状態 + 外部データ 得意なこと ユーザーごとの権限分離 書式チェック、値の範囲制限、Immutabilityの強制 ユニーク制約、外部DBとの照合、複雑なビジネスロジック 導入推奨 必須 推奨 (Default)シンプルで高速。まずはこちらを検討。 必要に応じて (Advanced)VAPで表現できない「他のリソースとの関係性」を見る必要がある場合。 補足:OpenShiftにおけるGatekeeperの導入とRHACMの関係 本記事ではGatekeeperのネイティブなリソース(ConstraintTemplate/Constraint)を直接操作して解説しましたが、OpenShift環境における導入・運用には2つのパターンがあります。 導入形態の違い RHACMの一部として : Red Hat Advanced Cluster Management (RHACM) を導入すると、そのガバナンス機能のエンジンとしてGatekeeperが統合されています(推奨)。 単体利用として : RHACMを使用しない場合でも、「Gatekeeper Operator」をOperatorHubからインストールして単体利用が可能です(利用には適切なサブスクリプションが必要です)。 操作感(インターフェース)の違い RHACMを経由する場合、管理者が作成するのはGatekeeperのCRD(Constraint)ではありません。RHACM固有の Policy リソースを作成し、その中にGatekeeperの設定を埋め込む形になります。 単体利用: Constraint を直接作成 → そのクラスターに即適用。 RHACM利用: Policy を作成 → RHACMが複数の管理対象クラスターへ配布 → 各クラスター内で Constraint として実体化。 RHACMを利用することで、マルチクラスターに対する「ポリシーの一括配布」や「違反状況の中央集権的なレポート機能」が提供されます。 そのため、「ポリシー運用の可視化」や「環境間の設定統一」を効率的に行いたい場合は、Gatekeeper単体ではなくRHACM(Policy Controller)経由での利用が推奨されます。
※本記事は OpenShift Virtualization アドベントカレンダーの 7 日目の記事です。 qiita.com 皆さんこんにちは、OpenShift Virtualization とストレージを生業にしている Red Hat のうつぼ(宇都宮)です。 現場猫をご存知でしょうか?あの安全帽を被って指差し確認しながら「ヨシ!」とやってる例の猫のイラスト、みなさんも一度は見たことがあると思います。 この指差し確認というのは IT の世界でも馬鹿にならないもので、なぜならヒューマンエラーの原因の多くは確認不足によるものだからです。指差し確認とは体を動かすことで脳を刺激して、きちんと意識的に確認をするという偉大な行為なのです。CRUD 操作のコマンドを打つ時は、必ず「ヨシ!」とやりたいものですね。 ということで今日のテーマは確認ダイアログです。 OpenShift Virtualization の GUI VM Tree View 確認ダイアログの実装 まとめ OpenShift Virtualization の GUI Red Hat OpenShift Virtualization(以下、Virt)は、既存の仮想化基盤からの移行先として多くのお客様やパートナー様にご検討いただいています。これは大変ありがたいことです。 ですが Virt の操作に違和感を覚えるかたも少なくないと思います。OpenShift は Kubernetes をベースにしているため、手続き型ではなく宣言型の操作を行います。 例えば VM にディスクを1つ追加する処理も、「VM にディスクを1つ追加する」という変更作業自身を記述するのではなく、「VM のディスクが2つになった」という変更後の姿を記述します。 こうすることで、宣言したあるべき姿になるまで自動で操作をやり直してくれるため非常に便利なのですが、これがやはり既存の仮想化基盤の操作に慣れている方からすると最初は結構違和感を抱くことがあるでしょう。 しかしこれは YAML の話。Virt には Virt 専用の洗練された(多分洗練されてると思う、洗練されてるんじゃないかな)という GUI が存在し、まるで手続き型のような操作を可能としています。 VM Tree View OpenShift の GUI(Web console)は基本的に Project(Namespace)を選択して、その中のリソースを表示し、色々な操作をできるようにします。ノードだとか PV だとか Storage Class だとか、Project 関係なくクラスタ全体で定義されるリソース(cluster-scoped resource)以外は大抵は Project 単位で見ることになります。 VM も例に漏れず Project 内で定義されるリソースなので、Project を選択して見ることになります。しかし、管理者の立場としてはどの Project に何の VM があるのか、わかりやすく一覧で見たいですよね。 そういうわけで Virt 4.19 から GA になったのが Tree View です。左側に Project ごとに VM を Tree View で一覧できるようになっています。Project 内でフォルダを作って分類することも可能です。結構 vSphere Client っぽい見た目なので、とっつきやすいのではないかなと思います。 VM の Tree View 確認ダイアログの実装 さて本題はここから。さっきの View で VM を選択すると下のような感じで表示されます。この右上の方に四角とかぐるりと回った矢印とかがありますが、これを押して VM を停止したり再起動したりすることがあります。 VM の詳細画面 これ便利と言えば便利ですが、剥き身でちょっと危ないと思いませんか?ちょっとした操作ミスでうっかり押してしまいそうな感じがします。 ですが、Virt GUI はもし押してしまってもきちんと確認のダイアログが表示されるようになっています。 確認ダイアログ それがどうしたんだよそんなの当たり前でしょ?って思われるかもしれないんですが、驚くなかれ なんとこれは 4.19 で GA になった新機能なのです。 Virt の設定画面で「VirtualMachine のアクションの確認」という項目があって、これを On にしていると、確認ダイアログが表示されます。 Virt の設定画面に燦然と輝く New の文字 逆に言えば、それまではこの確認ダイアログはなかったんです。日本だけではなく世界中から、これ危険だよねぇという声を非常に多くのお客様やパートナー様からいただいてきました。 そういったことから、また一つ GUI が洗練されたということをここでお知らせしたかったという次第です。 まとめ vSphere Client / vCenter Server は非常に洗練された GUI を提供されているので、どうしても Virt の GUI はまだ不足していると思われるかもしれません。 それは Red Hat としてもしっかり認識済みで、こういった確認ダイアログを始め、お客様が受け入れやすいユーザーインターフェースを日々実装を続けております。少しずつ少しずつ、花魁の歩みのような速度かもしれませんが、日々洗練し続けていると思っていただけると嬉しいです。 ということで今日はここまで。
Apache Camel Advent Calendar 7日目の記事は、サポート担当古市が担当します。 テーマは、「Debugging Camel」 基本的には、以下の流れで camel route のデバッグをすすめていくことをお勧めします。 Camel trace を使い、ルーティングの状況を把握 ログレベルを変更し、より詳細な情報を把握 デバッガーを使い、ソースコードレベルの調査 Camel trace 想定通りにルーティングされない場合、exchange の状態と、どの経路でルーティングされたかを把握する必要があります。 実際、製品サポートの現場でかなり大掛かりな camelルートに関する調査をする場合も、traceログからピンポイントで調査が必要な箇所を絞り混みます。 CamelContext の trace アトリビュートを有効にすることで、これらルーティング情報の詳細がログ出力されます。 (どのエンドポイントで処理されるかが、exchange の内容とセットで把握できます。) camel.apache.org 実は、camel-jbang にも trace 機能が提供されており、手元でサクッと検証する場合には便利です。 camel-jbang をご存知ない方は、まずこちらの記事をご覧ください。 rheb.hatenablog.com camel-jbang は稼働中のインテグレーション(camel ルート)の統計を取得することも可能です。まずは、バックグラウンドでインテグレーションを実行します。 camel init Hello.java camel run Hello.java --background 稼働中のインテグレーションの trace status は "Standby" になっています。この状態ではまだトレースが開始されていません。 action オプションを使い、trace status を "started" に変更します。 % camel trace PID NAME AGE STATUS TOTAL QUEUE FILTER PATTERN 4795 Hello 6s Standby 0 0 % camel trace --action=start % camel trace PID NAME AGE STATUS TOTAL QUEUE FILTER PATTERN 4795 Hello 2m15s Started 12 8 % トレーシングが開始されました。actoinオプションを使い、トレース情報を出力します。 % camel trace --action=dump 2025-08-15 09:35:43.895 4795 --- [ thread #5 - timer://java] route1/*--> : 1 - Created Endpoint timer://java?period=1000 Exchange (DefaultExchange) InOnly 97F301CDA23540D-0000000000000081 Message (DefaultMessage) Body (null) 2025-08-15 09:35:43.895 4795 --- [ thread #5 - timer://java] route1/setBody1 : 2 - Processed (0ms) Exchange (DefaultExchange) InOnly 97F301CDA23540D-0000000000000081 Message (DefaultMessage) Body (null) 2025-08-15 09:35:43.899 4795 --- [ thread #5 - timer://java] route1/log1 : 3 - Processed (0ms) Exchange (DefaultExchange) InOnly 97F301CDA23540D-0000000000000081 Message (DefaultMessage) Body (String) (bytes: 23) Hello Camel from route1 2025-08-15 09:35:43.895 4795 --- [ thread #5 - timer://java] route1/*<-- : 4 - Completed (success) (1ms) Endpoint timer://java?period=1000 Exchange (DefaultExchange) InOnly 97F301CDA23540D-0000000000000081 Message (DefaultMessage) Body (String) (bytes: 23) Hello Camel from route1 ~~省略~~ トレース情報は収集され続けるので、収集を止める場合は "Standby"ステータスへ変更します。 camel trace --action=stop 収集したトレース情報は、保持され続けています。消去することも可能です。 camel trace --action=clear 出力されたトレース情報を確認すると、どのように exchangeがルーティングされているか把握できるかと思います。 exchange id (先ほど掲示した例では、 97F301CDA23540D-0000000000000081)も重要な情報です。後述するログを確認する際、camel trace で特定した exchange id を使いログの絞り込みが可能だからです。 トレース情報にはエンドポイント情報(例: route1/setBody1)も出力されますが、ファイルの行番号で出力することも可能です。 camel trace --source -action=dump exchange の property や variable も合わせて出力させることも可能です。 camel trace --show-exchange-properties --show-exchange-variables --action=dump 他にも色々とオプションがありますので、詳細は --help でご確認ください。 camel trace --help いきなりアプリケーションログの解析やデバッガーによるデバッグをせず、一旦 camel trace を使ったルーティング状況の把握を強くお勧めします。 ログレベルの変更 アプリケーションログレベルの変更はデバッグをする上で一般的だと思います。camel trace で問題箇所を調べることができれば、ルートログレベルの変更ではなく、パッケージを指定したログレベルの変更をお勧めします。 camel-jbang を使い、camel全般のログレベルを変更する方法はこちらです。 camel run Hello.java --logging-category=org.apache.camel=DEBUG camel のログを読み解くにはソースコードレベルの読解が必要となります。無理に DEBUG/TRACE レベルログの解析に時間を使わず、製品サポートへ問い合わせる方法をお勧めします。調査の過程でログレベルの変更をお願いすることもありますので、ご留意ください。 breakpoint を使って止める camel-jbang は、camel engine レベルでのデバッガーも提供しています。例えば、特定の endpoint にブレイクポイントをセットし、ステップ実行ができます。 exchange の内容も出力されるので、traceログ出力して後から読むのではなく、こちらの方法で調査しても良いかもしれません。 camel debug Hello.java --brakpoint=setBody このコマンドでは、setBody() 実行箇所にブレイクポイントをセットし実行しています。camel ルートの実行後、自動でデバッグメニューが出力されます。 Source: Hello.java History -------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------ 4: ---> route1/from1 7: from("timer:java?period=1000") 5: @Override 6: public void configure() throws Exception { 7: *--> from("timer:java?period=1000") 8: .setBody() 9: .simple("Hello Camel from ${routeId}") 10: .log("${body}"); 11: } 12: } 2025-08-19 09:09:27.979 4135 --- [ thread #6 - timer://java] route1/*--> : 1 - Created Exchange (DefaultExchange) InOnly 1296773E4359222-0000000000000000 Message (DefaultMessage) Body (null) Breakpoint suspended (i = step into (default), o = step over). Press ENTER to continue. 豊富なオプションが用意されていますので、最新バージョンの camel-jbang を用意し、ヘルプコマンドでオプション内容を確認することを推奨します。 camel debug --help camel は vscode extensionも用意しており、VSCode が提供する GUI を使いデバッグすることも可能です。 marketplace.visualstudio.com marketplace.visualstudio.com camel engine レベルではなく Javaレベルでのデバッグももちろん可能ですが、traceログなど各種リソースを取得した時点で一旦製品サポート窓口へお問い合わせいただき、camelのデバッグではなくビジネスロジックの開発にリソースを集中していただければと思います。 明日の advent calendar 8日目では、「Camel File コンポーネント」 についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com
※本記事は OpenShift Virtualization アドベントカレンダーの 6日目の記事です。 qiita.com 皆さんこんにちは、OpenShift Virtualization とストレージを生業にしている Red Hat のうつぼ(宇都宮)です。 万物は有限です。数字や時間のような概念的な一部の例外を除けば、大抵のものには限りがあります。石油だってお金だって、ミミズやオケラやうつぼの命だって限りがあります。 そんな限りある資源をうまく使うことが私たち生を受けている者に与えられた使命なのです。 ということで今日のテーマはオーバーコミットです。 オーバーコミットの概念とリスク そもそもオーバーコミットとは requests と limits がやっていること CPUのオーバーコミット CPU オーバーコミットの特徴 クラスターレベルでのオーバーコミット率の設定:vmiCPUAllocationRatio limits.cpu の設定には注意 メモリのオーバーコミット 安定運用のためのメモリ設定 それでも密度を上げたいとき:メモリオーバーコミットと swap キャパシティプランニングで気をつけること まとめ オーバーコミットの概念とリスク Red Hat OpenShift Virtualization の環境を最大限に活用し、安定性、パフォーマンス、そしてリソース効率のバランスを取るためには、リソースのオーバーコミットの理解が不可欠です。 本稿では特に CPU とメモリという二大リソースに焦点を当てて、それぞれのオーバーコミットに対する推奨、技術的な背景、および具体的な設定方法について詳細に解説します。 そもそもオーバーコミットとは オーバーコミット(Overcommit)とは、物理サーバー(=Compute ノード)が持つ実際のハードウェアリソース量(CPUコア数、物理メモリ容量など)よりも、そのノード上で稼働する全てのワークロード(VMやコンテナ)に割り当てられたリソースの要求総量が上回っている状態を指します。 メリット: リソース利用効率の向上: ワークロードが常にリソースを全開で使うわけではないという前提に基づき、浮いている状態のリソースを他のワークロードに再割り当てすることで、物理ハードウェアの稼働率を高めます。 コスト削減: 少ない物理サーバーでより多くのワークロードを稼働できるため、インフラコスト(ハードウェア、電力、設置場所)を削減できます。 リスク: パフォーマンスの低下: すべてのワークロードが同時に割り当てられたリソースを要求した場合、リソースの取り合いが発生し、処理の遅延やスループットの低下を招きます(競合)。 システム不安定化: 特にメモリのオーバーコミットが過度になると、最悪の場合ノード全体の不安定化やサービス停止に繋がります。 requests と limits がやっていること ※ 2026/08/04 加筆 具体的な話に入る前に、ここを押さえておくと以降がスッキリします。コンテナにしろ VM にしろ、CPU とメモリのリソース管理は Kubernetes の requests と limits が使われます。ただこの2つ、名前から受ける印象より役割が限定的です。 requests : スケジューラが「このノードに載せてよいか」を判断するための申告値。加えて、CPU の場合は、競合が起きたときの取り分の重み(cpu.shares)を意味する。VMware の "Reservation" のように 物理リソースを保証するものではないので注意。 limits : シンプルに実際の使用量の最大値。 大事なのは、 requests は上限ではない ということ。limits を設けない限り、コンテナや VM ワークロードは requests を大きく超えてリソースを使えます。そして CPU と メモリで、limits に当たったときの挙動がまったく違います。 requests limits CPU 配置判断 + 競合時の取り分の重み 超えるとスロットリング( 遅くなる ) メモリ 配置判断 + OOM 時の生存優先度 超えると OOM Kill(停止) 「CPU はオーバーコミットしてよくて、メモリはダメ」と言われる技術的な根拠は、要するにこの右の列の違いです。 ただ、コンテナでは limits に当たることは時折あっても、VM の場合は limits に当たることはほぼありません。 CPU: VM の vCPU はホストから見ると 1 vCPU = 1 スレッドなので、割り当てた vCPU 数を大幅に超えて消費されることはありません。逆に言えば、limits を vCPU 数より小さく設定した時だけスロットリングが起きます。 メモリ:ゲスト OS は自分に見えているメモリ量の中でやりくりを完結させます。足りなくなればゲスト内でページキャッシュを解放し、それでもダメならゲスト内の OOM Killer が動く。ホスト側の limits に到達する前に、ゲストが自分で始末をつけてしまいます。 こういったことから、VM 単体で見ると、適切に設定すれば limits にあたって嫌なことになる可能性はかなり小さい。 しかしノード全体でリソースが足りなくなったら話は別です。メモリが足りなくなったら容赦なく OOM Kill されます。ゆえに、後にも書きますが、メモリに関しては requests と limits を同じ値にするのがよいです。こうすると requests がその VM の実際の使用量の上限と一致します。スケジューラは requests の合計が物理容量を超えないよう配置するので、結果としてノードが枯渇しない、という理屈です。 いきなりドカッと書きましたが、次からは CPU とメモリを順番に見ていきます。 CPUのオーバーコミット CPU のオーバーコミットは、OpenShift Virtualization 環境において 一般的に推奨・使われることが多い プラクティスです。その理由は、仮想マシンに割り当てられる仮想 CPU(vCPU)の性質にあります。 CPU オーバーコミットの特徴 多くの VM ワークロード、特に Web サーバー、開発・テスト環境、一部のデータベースなどでは、割り当てられた vCPU を常に 100% 使い切ることはまずありません。 つまり vCPU はアイドル状態にある時間が多いため、物理コアに対して複数の vCPUを「多重化」して割り当てることで、物理ハードウェアのアイドル時間を最小限に抑え、リソース効率を飛躍的に向上させることができます。 最悪、タイミング悪くワークロードが高騰して CPU の競合が起きても、パフォーマンスの低下で済みます。サービスが止まるまでの影響はないことが多いでしょう。 クラスターレベルでのオーバーコミット率の設定: vmiCPUAllocationRatio ※ 2026/08/03 加筆修正 OpenShift Virtualizationでは、クラスター全体に対するデフォルトの CPU オーバーコミット比率を、 HyperConverged カスタムリソース(CR)で定義できます。 パラメータ 説明 デフォルト値 vmiCPUAllocationRatio vCPU 数から POD の CPU requests を算出する際の除数(整数のみ) 10 これ、名前から「vCPU の割り当て上限を決める設定」と読んでしまいがちなんですが、実際は requests の計算式を決めているだけ です。 POD の CPU requests = vCPU 数 × 1 / vmiCPUAllocationRatio デフォルトの 10 なら、1 vCPU あたり 100m(物理スレッドの 10%)が requests として計上されます。4 vCPU の VM なら 400m ですね。 10:1 になるのは「requests ベースで見たときの結果」であって、「11個目の vCPU は載せられない」というハードな上限が効いているわけではありません。なお dedicatedCpuPlacement: true の VM には、この設定は適用されません。 このデフォルト値の "10" という値は、VMware をご存知の方は「高すぎるのでは?」と思うでしょう。何を隠そう私もそう思います。 しかしデフォルトがこうなっているということは、「一般的な VM ワークロードって普通 CPU 使用率は 10% くらいでしょ?だったらこの値で OK じゃないの?」という KubeVirt コミュニティからのメッセージを感じますね。 ただ、requests が上限ではないという話を踏まえると、これはなかなか大胆な設定です。たとえば 8 vCPU の VM を ratio=10 で払い出すと requests は 800m 。この VM がフルロードすると 8000m 超を消費します。要求値の 10倍です。 requests をあてにして容量計画したノードに、こういう VM が何台か載って同時に負荷が上がったらあっという間にパンク寸前、という話になります。 だから個人的にはリソース効率の追求より安全をみて、 少なくとも設計段階では 1:1 ~ 4:1 くらいで見ておくのが手堅い んじゃないかと思います。 limits.cpu の設定には注意 ※ 2026/08/03 加筆 「じゃあ暴走を防ぐために limits を付ければいいのでは」と思うところですが、ここは慎重に判断したいところです。実は OpenShift Virtualization はデフォルトで VM に CPU limits を付けません 。これは意図的にそうしています。 limits.cpu は vSphere の CPU Limit に相当するのですが、Linux の cgroup での実装が少し独特で、100ms ごとの期間中にプロセスが使用できる CPU 時間を配る方式になっています。このため、CPU がバーストした時にスロットリング(強制停止)が発生することがあります。 1つ例に挙げて考えてみましょう。4vCPU を割り当てた VM を作成し、オーバーコミットするぜと言って手で requests.cpu: 1 , limits.cpu: 2 を設定します。この時、100ms のウィンドウで使える合計の最大 CPU 時間は 100ms x 2(=limits.cpu) = 200ms となります。 普段は穏やかなのに、ある時 VM 内で急激に負荷が上がって CPU バーストが発生しました。このバースト中は、割り当てられている 4 vCPU = 4 スレッド全開で並列処理しようとします。 しかし、limits.cpu を設定しているので、最大 CPU 時間は 200ms で制限されています。ゆえに、4 スレッドで並列処理するとなると、200 / 4 = 50ms で全部使い切ってしまいます。 この時、100ms のウィンドウ開始と共に 4 スレッドで 50ms を使い切ると、即座にスロットリングが発生し、残りの 50ms は何もできず待ち状態になります。そして次の 100ms のウィンドウでまた 50ms 処理して、50ms 待って、が繰り返されることになります。 ゲストからすると、vCPU が 50ms 止まったことになるので、割り込みが遅延したりネットワークのレイテンシがスパイクしたり、ということが現れることになります。 OpenShift Monitoring 等見ると CPU 使用率のグラフは涼しい顔をしているのになぜか応答時間は悪化している、という追いづらいトラブルになりがちです。 (なお、スロットリングが起きているかどうかは container_cpu_cfs_throttled_periods_total を見れば分かります。) 「4 vCPU の VM に limits.cpu: 2 なんて設定するわけないじゃん」と思われるかもしれませんが、namespace の LimitRange や ResourceQuota によって、書いていないのに limits が付くことがあります。特にマルチテナント環境やコンテナ向けに整備された namespace にそのまま VM を載せるとこれを踏む可能性があるのでご注意下さい。limits がセットされてるかどうかは virt-launcher Pod を見るのが確実です。 「じゃあ VM に割り当てた vCPU 数と全く同じ数を limits.cpu に設定すればいいんじゃないの?」確かにこの場合は vCPU の処理だけを見れば釣り合っています。 しかし、この最大 CPU 時間は vCPU だけでなく、デバイスのエミュレーションやディスク I/O といった裏方の処理とも共有されます。なので limits.cpu を vCPU 数ぴったりにしても、裏方処理のスレッド分だけ超えてしまうので、高負荷時に軽いスロットリングが起きる可能性はあります。 よって、 基本的には limits 無しで VM を走らせるのがお勧め です。limits が無くても、前述の通り VM の vCPU はホストから見ると 1vCPU = 1スレッドなので、割り当てた vCPU 数を大幅に超えて消費されることはありません。(裏方処理の分だけ上乗せされる程度です) なお、特定の VM に物理コアを確実に割り当てたいなら、limits ではなく dedicatedCpuPlacement: true (ノードで CPU Manager の static policy が必要)で固定することができます。 メモリのオーバーコミット ※ 2026/08/03 加筆修正 さてメモリです。CPU と違って、こちらは 既定では保証(オーバーコミットしない)を推奨 します。理由は先の表のとおり、limits を超えたときに「遅くなる」ではなく「死ぬ」からです。 非圧縮性 : CPU 時間は分割して共有できますが、メモリは一度 VM が使い始めると、ホスト側から取り上げることが困難です。(virtio-balloon の free page reporting や KSM といった緩和策はあり、KubeVirt では前者はデフォルトで有効になっています) 競合時のインパクト : ノード上のメモリが足りなくなると、OOM Killer が QEMU プロセスを強制終了し、VM が停止します。なお OpenShift のノードはデフォルトで swap が無効なので、後述の設定をしない限り、スワップして粘ることなく OOM に至ります。 安定運用のためのメモリ設定 安定したパフォーマンスと信頼性の高い運用を確保するためには、メモリの割り当てには以下の原則に則ることを推奨します。 requests.memory = limits.memory :メモリの requests と limits を同じ値に設定し、VM が宣言量を超えてメモリを使わないようにします(メモリ使用量の保証)。なお、Pod 全体としては CPU の requests/limits も揃えないと Kubernetes の Guaranteed QoS クラスにはなりません。 物理容量の管理 :ノードに割り当てられる全ての VM(および、ノード上で稼働するコンテナや OpenShift コンポーネント)の requests.memory の合計が、そのノードの物理メモリ容量を超えないように容量計画とスケジューリング管理を行います。 spec : domain : memory : guest : 4Gi # VMが認識するメモリ量 resources : requests : memory : 4Gi # スケジューリング時に 4GiB 分の空きがあるノードに配置される limits : memory : 4Gi # 上限も同値にし、宣言量を超えて使わないようにする requests と limits を同じ値にすることで、「配置の時点で物理容量を超えない」ことと「その VM が宣言量以上を使わない」ことの両方が成立します。requests が物理メモリを予約するわけではありませんが、超過を禁止することで結果的にノードの破綻を防ぐ、という理屈です。 そのうえで、ノード上の全 VM(および他のコンテナや OpenShift コンポーネント)の requests.memory の合計が、ノードの割り当て可能なメモリを超えないように容量計画します。 とはいえ requests 合計 ≤ Allocatable はスケジューラが必ず守るので、ここは自動的に担保されます。 それでも密度を上げたいとき:メモリオーバーコミットと swap ※ 2026/08/03 加筆 とはいえ「メモリオーバーコミット禁止」と言い切ってしまうのも、今となっては考えが古いのかも知れませんね。OpenShift Virtualization 4.16 以降、 メモリオーバーコミットは正式機能として提供されています 。 HyperConverged CR の higherWorkloadDensity.memoryOvercommitPercentage を 100 より大きい値に設定すると、Compute ノードに swap が割り当てられ、requests を実メモリより小さく計上できるようになります。150 に設定すれば「VM のメモリの最大 1/3 はディスクに swap out されうる」という前提です。 $ oc -n openshift-cnv patch HyperConverged/kubevirt-hyperconverged --type='json' \ -p='[{"op": "replace", "path": "/spec/higherWorkloadDensity/memoryOvercommitPercentage", "value": 150}]' swap の管理を担う内部コンポーネントはバージョンで異なります。 バージョン swap 管理 備考 4.16 〜 4.21 wasp-agent memoryOvercommitPercentage > 100 で自動デプロイ。swap 割り当てに加え、swap I/O 過大時の Pod 退避も担う 4.22 〜 OpenShift swap(ネイティブ) wasp-agent に代わり OpenShift 標準の swap 機構がデフォルトに。設定が簡素化された 4.21以前 → 4.22 へのアップグレード時の注意: 旧環境では KubeletConfig に failSwapOn: false を手動設定していましたが、4.22 ではこのキーを削除する必要があります。 Red Hat の検証記事では、ワークロードにもよるものの 25% 程度のオーバーサブスクリプションは十分に実用的、という結果が報告されています。 developers.redhat.com 使う場合の注意点を2つだけ。 swap 先は専用の高速デバイスを用意する。 レイテンシがそのまま VM の性能に跳ね返ります swap が使えるのは Burstable QoS クラスの VM Pod だけ。 Guaranteed クラスの Pod は swap の対象外です 2つ目が地味に重要で、「性能を保証したい VM は Guaranteed にする=密度の恩恵は受けない」「密度を稼ぎたい VM は Burstable にする」という切り分けが、QoS クラスによって自然に表現されることになります。VDI や開発環境のように、平均使用率が低くピークがずれているワークロードには相性がよい機能です。 ちなみに、Kubernetes の QoS クラスは requests/limits の書き方から自動的に決まるもので、 Guaranteed になるには Pod 内の全コンテナが CPU・メモリ両方で requests = limits である必要があります。 メモリだけ揃えても Burstable です。前述のとおり CPU に limits を付けると副作用があるので、多くの場合は「メモリだけ requests = limits の Burstable」で運用することになります。 キャパシティプランニングで気をつけること ※ 2026/08/03 加筆 最後に、設計時に見落としがちな点を2つ挙げておきます。 物理搭載量 ≠ 割り当て可能量 kube-reserved / system-reserved / eviction threshold が差し引かれるので、VM に配れるのは物理搭載メモリより数 GiB 少なくなります。加えて VM のメモリ requests には QEMU 自体のオーバーヘッドが上乗せされるので、 4Gi と書いた VM の Pod は 4Gi + 数百 Mi を要求します。物理搭載量ベースで机上計算すると必ずズレます。実際の値は oc describe node の Allocatable と、Pod の requests を見比べるのが早いです。 N+1 のヘッドルーム ノード障害やメンテナンス時に VM を live migration させる先が必要なので、全ノードを requests で埋め切ることはできません。3ノードなら1ノード分は空けておく、といった設計は「requests 合計 ≤ Allocatable」だけでは担保されないので、明示的に見込んでおく必要があります。 まとめ ※ 2026/08/03 加筆修正 OpenShift Virtualization のオーバーコミット戦略は、以下の表に集約されます。 リソース オーバーコミット 制御パラメータ 推奨される戦略 CPU 推奨 vmiCPUAllocationRatio limits は無し(または requests < limits )とし、余裕があるときのバースト利用を許す。ratio は設計時 1:1 ~ 4:1 から メモリ 既定では非推奨 (密度が必要なら swap を有効化) VM ごとの requests / limits 、 memoryOvercommitPercentage requests = limits を基本とする。VDI 等で密度が要るなら swap 前提で計画的に CPU は競合しても遅くなるだけ、メモリは競合すると止まる。この非対称性が、両者で戦略を変える理由の全てです。そしてメモリ側を固く倒しておくと、悩む対象が CPU 一本に絞れるので、運用負荷の面でも見通しがよくなります。 ワークロードの特性(I/O 集中型か、CPU 集中型か、レイテンシ要求レベルなど)を踏まえて、適切に設計・設定していきましょう。 あと、しばしば「どれくらいのオーバーコミット率がいいか?」という旨の質問をいただきます。気持ちはわかります。最近はハードウェアが高騰してますし、可能な限りリソースの効率を高めたいという思いがあると考えています。 しかしながら、身も蓋もない話、適正なオーバーコミット率はワークロード次第なので事前に分かりません。しかもその実使用率は動かしてみないと分からない。なので一発で当てにいくより、保守的に始めて後から調整できる構造にしておくほうが手堅いと思います。 ということで今日はここまで。
コンサルタントの織です。OpenShift Advent Calendar 2025の5日目、OVN-Kubernetesで今後実装されそうな機能(2025年度版)というタイトルの記事を書きました。OVN-KubernetesのOKEP (KubernetesにおけるKEPと同じもの) を眺めて、今後実装されるかもしれない機能をチラ見する、という内容です。 具体的には、 トラブルシュート用MCPサーバ no-overlay ClusterNetworkConnect OVS-DPDK関連 EVPN について簡単に紹介しています。詳細については以下をご覧ください。 zenn.dev
Apache Camel Advent Calendar 6日目の記事は、サポート担当古市が担当します。(鎌田さん、アドバイスありがとうございます。) テーマは、「Testing Camel」 Camel は、JUnit extension ライブラリーを提供しており、従来のテストコードと同等に Camelルート用テストコードを記述可能です。 camel.apache.org テストの粒度をこのように分けることで、テスト設計がし易くなるでしょう。 processor/Beans単位 Camelルート単位 Processor/Beans単位 例えばこのような Processor を実装したいとします。 public class CustomProcessor implements Processor { @SuppressWarnings("unchecked") @Override public void process(Exchange exchange) throws Exception { exchange.getMessage().setBody("${body} from ${header.username}"); } camel route単位でのテストでは無いので、mockitoが提供する @InjectMocks を使い、テスト対象の Processorのみ用意します。 site.mockito.org @InjectMocks CustomProcessor processor; テストでは、org.apache.camel.builder.ExchangeBuilderクラスを使い、意図した exchangeオブジェクトを作成し、Processor/Bean へ投入することが可能です。 org.apache.camel.CamelContextcamelContext = new org.apache.camel.impl.DefaultCamelContext(); org.apache.camel.Exchange exchange = ExchangeBuilder.anExchange(camelContext) .withBody("Hello World!") .withHeader("username", "Bob") .build(); processor.process(exchange); assertEquals("Hello World! from Bob", exchange.getMessage().getBody()); Camelルート単位 camelルート単位のテストをしたい場合、endpointをモックへ置き換える方法が有用です。 テスト用に別途モックへ置き換えた camel routeを用意するのは手間なので、adviceWith を使い、特定 endpointをモックに置き換えます。 具体的には、RouteBuilder を拡張した AdviceWithRouteBuilder の .configure()メソッド内にて、ID指定により特定エンドポイントをモックに置き換えたり、モックエンドポイントを追加することも可能です。 camel.apache.org コミュニティーページで紹介されているコードに注目します。 AdviceWith.adviceWith(context, "myRoute", new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { weaveAddLast().to("mock:result"); } }); ウィーブ(織り込む)したい対象ルートID "myRoute" を指定し、ルート末尾にモックエンドポイント mock:result を追加しています。 ラムダ形式で記述も可能です。 AdviceWith.adviceWith(context, "myRoute", a -> a.weaveAddLast().to("mock:result") ); テストでは、モックエンドポイントの状態を捕捉しテスト判定に使用することができます。 getMockEndpoint("mock:result").expectedMessageCount(3); MockEndpoint.assertIsSatisfied(context); モックに指定できる判定方法は多岐にわたります。常に最新バージョンの javadoc をウォッチすることをお勧めします。 javadoc.io よく使うであろうメソッドをもう1つ紹介します。 expectedMessagesMatches(org.apache.camel.Predicate... predicates) 期待する exchangeの状態を判定することが可能です。以下のように実装します。 getMockEndpoint("mock:result").expectedMessagesMatches( exchange -> { Object body = exchange.getMessage().getBody(); return (body instanceof String s) && s.equals("Hello World")); }); Fileオブジェクトなど、想定するオブジェクトに置き換えて評価式の実装をご検討ください。 Quarkus runtime をご利用予定の場合、CamelQuarkusTestSupport が提供されておりますので、こちらも要チェックです。 camel.apache.org サンプルコードにあるよう、既に用意された ProducerTemplateを使い、メッセージを投入することができます。 @QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Test void testGreeting() { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:start", "World"); mockEndpoint.assertIsSatisfied(); } もちろん CamelSpringTestSupport も、SpringBoot runtime向けに用意されています。 camel.apache.org 明日の advent calendar 7日目では、「Debugging Camel」 についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com
※本記事は OpenShift Virtualization アドベントカレンダーの 5日目の記事です。 qiita.com 目次 はじめに 【積極採用中!】Red Hat 採用に関するお知らせ この記事のゴール Q. Red Hat OpenShiftって何?そもそもそこがわからない。 Q. Red Hat OpenShift環境では、従来のブロックストレージやNASは使用可能なのか? Storage Class - どんな特徴のストレージかを定義するリソース Persistent Volume Claim - 希望するボリューム構成を定義する Persistent Volume - StorageClassとPVCの内容に基づき生成された永続ストレージ Q. ブロックストレージの場合は上記の解説で分かったが、NASの場合の動きが知りたい。 Q. (上記の動画では)PVCを作成した際に、なぜPowerStoreに保存域が作成されたのか? Q. つまりPVとは、VMwareのvmdk/Hyper-Vのvhdx/Nutanixのvdiskのような存在か? あとがき はじめに 皆さんこんにちわ、Red Hat Global Learning ServicesでLearning Solution Architectを担当している坂井 大和( @lab8010 )です。 主に X.com 上でRed Hat製品やサービスについて配信をしているので、もしよければフォローくださると幸いです。 この記事では、 『Red Hat OpenShift Virtualization環境では、ストレージ製品ってどう使われるの?』 という疑問に対して解説します。 なお、本記事で想定するストレージ=基本的に物理ストレージ製品を想定します。 私は前職でストレージを取り扱うベンダーに居たこともあり、ある程度はストレージ製品について心得があるので、忘れないうちにそうした知見を残しておきたいという個人的な狙いもあります。 【積極採用中!】Red Hat 採用に関するお知らせ Red Hatでは事業拡大に伴い人材を募集しています。 本記事でご紹介している『OpenShift Virtualization』に関するコンサルタントを募集しています。もし少しでも興味がある方は、ご応募または本記事を執筆している私坂井までお気軽にDMをください。( X / Linkedin ) redhat.wd5.myworkdayjobs.com この記事のゴール この記事を読み終わった頃には、読者様が次のことが出来る状態になって頂きたいと考えています。 Red Hat OpenShift Virtualizationにおけるストレージ基礎 具体的なストレージ製品の管理画面から、構成の様子を読み取る力を身につける なお、この記事はRed Hat OpenShift Virtualizationを対象として書きますが、ほとんどの内容は仮想マシンだけでなくコンテナワークロードにも対応する話となります。 それでは、早速本編に入っていきましょう。 Q. Red Hat OpenShiftって何?そもそもそこがわからない。 A. Red Hatによってカスタムされた商用環境向けKubernetesです。 https://kubernetes.io/ja/ Kubernetesには、Linuxカーネルを使用するOSのように色々なディストリビューションがあり、Red Hat OpenShiftはそのうちの1つと考えてください。 詳細はこちらの記事をお読みください。 rheb.hatenablog.com Q. Red Hat OpenShift環境では、従来のブロックストレージやNASは使用可能なのか? A. はい、使用が可能です。 Kubernetesは CSI(Container Storage Interface) と呼ばれるインターフェースを通じてストレージ製品と連携します。 CSIはネイティブなKubernetesが持つ仕組みであるため、Red Hat OpenShift固有の概念や規格ではありません。 kubernetes.io CSIを通じて物理的なストレージに対して操作を行うには ストレージメーカーが提供するCSIドライバー *1 を入手およびOpenShiftにインストールする必要があります。 このCSIドライバーを使用することで、OpenShift経由で物理ストレージに対してデータ保存域の作成リクエストや削除などの管理操作が可能となります。 この際、OpenShiftは Kubernetesの世界で登場する リソース *2 という概念 を通じて使用したいストレージの機能や構成を定義し、CSIドライバーを通じて物理ストレージが解釈可能な命令に変換して転送するという一連の処理を行います。 これを図解してみたものが次の図です。 OpenShiftやKubernetesのレイヤーからストレージ領域を使用するための流れ 以下のページに掲示のあるアイコンで示される要素1つ1つがKubernetesの世界におけるリソースです。 github.com この中でも特にストレージに関係するリソースとして次のようなものが挙げられます。 Storage Class - どんな特徴のストレージかを定義するリソース kubernetes.io 通称SC、SCを複数持つことでシーンごとに使いたいストレージの種別を管理できます。例えば、1台のストレージ製品がiSCSIブロックアクセスとNFSによるNASアクセスに対応している場合、そのストレージ製品に対して2種類のストレージクラスを準備し、それを使い分けることで利用したいストレージを指定可能となります。 例えばDell TechnologiesのUnityというストレージにおけるStorage Classを定義するマニフェストファイルの様子がこちらです。 引用元  https://dell.github.io/csm-docs/docs/concepts/csidriver/features/unity/   parameters配下を読むと、どのようなストレージ特性かが読める このSCを使ってストレージ領域をリクエストすると arrayIdが一致するDell Unityが指定され、その中のpool_7という領域内に NFSによる保存域を作成するような構成が宣言されています また、別のストレージメーカーの例として、PureStorage社のPortworxのStorageClassは以下のようになっています。 引用元  helm/charts/portworx-daemonSet/templates/portworx-storageclasses.yaml at master · portworx/helm · GitHub 1つのマニフェストファイルに3つのStorage Classが定義されています ここでお伝えしたいポイントは、『StorageClassに含まれる内容はベンダーや機器によって大きく異なる』ということです。 特に、StorageClassにはストレージによる暗号化やレプリケーションなども含むことができるので、KubernetesやOpenShift環境でストレージ固有の機能を使用する場合はその機能を含むStorageClassの作成と使用が必要となってきます。 クラスによって提供されるサービスが異なるというのは、エコノミークラス、ビジネスクラス、ファーストクラスで提供されるサービスが違う航空機のようですね✈️ Persistent Volume Claim - 希望するボリューム構成を定義する 通称PVC、Kubernetes環境において使用したい永続ストレージのリクエスト内容を定義するものであり、この中に次の要素を含めます。 どのストレージクラスに、 どのくらいの容量が必要で、 どのようなアクセスモードが必要で どのようなボリュームモードが必要か 次の例は、Dell Unityに対し2GiBの永続ストレージをリクエストするためのPVCです。 上記で確認したStorageClassであるunity-nfs(下図一番下の行) 引用元  https://dell.github.io/csm-docs/docs/concepts/csidriver/features/unity/ Persistent Volume - StorageClassとPVCの内容に基づき生成された永続ストレージ kubernetes.io 通称PV、永続的にデータを保存する箇所であり、物理ストレージ上のLUNやNFS共有域に関連づく論理的なオブジェクトです。 PVCの作成により、対応するPVがKubernetesやOpenShiftのレイヤーで作成されるが、 物理ストレージのレイヤーではこのPVに対応するLUNやNFSの作成が作成されます。 このため、物理ストレージ上の管理ソフトウェア上ではKubernetesやOpenShift上で作成命令されたPVC/PVに対応する新たな記憶域の様子が次のように確認できます。 Dell Technologies PowerStore上のBlock StorageをリクエストするPVC VOLUME名のcsivol-239a9c2dc4に注目 Dell PowerStore Manager上のBlockストレージの様子 上記のVOLUME名と同じ値でストレージのVolume(LUN)が作成されている HPEのNimble Storageでも同様の状況が確認できます。 HPE Nimble Storage上に永続ストレージを作成するためのPVCとPV HPE Nimble Storageの管理ツール上のBlockストレージの様子 上記のkubectl get pv, pvc -o nameで取得した名前と同じ値で ストレージのVolume(LUN)が作成されている 今回参考にした2つのストレージの操作の動画は次の2つの動画です。 www.youtube.com www.youtube.com   ここでいう、命令の変換や転送などを受け付ける存在こそが CSIドライバー です。 CSIドライバーはストレージソリューションを提供する各ベンダーが提供します。 ストレージ利用者はこれをストレージベンダーから入手、セットアップをすることでストレージが利用可能となります。 Q. ブロックストレージの場合は上記の解説で分かったが、NASの場合の動きが知りたい。 A. 以下の解説をご覧ください。 次の動画では、実際にその様子をデモンストレーションしています。 www.youtube.com この動画では、Red Hat OpenShiftとDell TechnologiesのPowerStoreと呼ばれるユニファイドストレージ *3 を使用して、上述しているPVを作成するとてもシンプルなデモを実施しています。 上記のデモでは、PVC(Persistent Volume)を通して 『こんなストレージが欲しい』というリクエスト をOpenShift Web Console上で作成をしたことで、そのリクエストがDell Technologies PowerStoreに転送され、リクエストを受け付けたPowerStoreが要望に応じたストレージ領域をNFS共有域として準備したという結果を確認しています。 Q. (上記の動画では)PVCを作成した際に、なぜPowerStoreに保存域が作成されたのか? A. これもやはりStorageClassによる指定内容に基づいているから。(上記ブロックストレージの箇所ですでに解説済み) 上記の動画の1:34あたりをご覧頂くと、SC(Storage Class)の紹介をしています。 このSCは、PVCで定義したストレージ要件をどのストレージで叶えたいかを含む定義です。以下の図は動画内で表示されたSCのマニフェストを拡大表示したものです。 動画内で登場したStorage Classのマニフェストファイルの内容 行番号25では、csi-powerstore.dellemc.comとあるため、このストレージクラスを使用するとDell PowerStoreに対してストレージ保存域が作成されます。 行番号 27では、nfsの記載があるため、このストレージクラスを使用するとNFS保存域常にデータが保存される領域が確保されます。 行番号29では、ストレージが持つ一意のIDが記載されていおり、このIDと一致するDell PowerStoreに対する命令として処理されます。 上記のSCを利用し、実際にストレージ領域をPVCを通じてリクエストした結果が次の図です。 SCでは『どのストレージで、どんな特性を持つ保存域を使用するか』を定義し、 PVCでは『どれくらいの容量で、どんなアクセスモードにするかなど』を定義します。 どちらもストレージに対する設定/構成といえばそうかもしれませんが役割が違います。 結果として、上記の2つのリソースが定義した構成を持つPVが払い出されます。 Kubernetesのレイヤーと物理ストレージのレイヤーの俯瞰図 なお、本記事の本題であるOpenShift Virtualizationにおける仮想マシンにおいても、ここで登場するPVC/PV/SCの概念は使用します。 Q. つまりPVとは、VMwareのvmdk/Hyper-Vのvhdx/Nutanixのvdiskのような存在か? データを保存する媒体という性質で言えば、その解釈は非常に近いと言えます。 PV自体はKubernetesやOpenShiftのレイヤーに存在する論理的な存在であり、データ実体を収納しているのはあくまでもブロックストレージのLUNやNASの共有保存域です。 上記の形式に近い仕組みとしては、VMwareのVirtual Volumes(VVOL) *4   はかなり近い考えだと言えます。 blogs.vmware.com あとがき みなさんお気づきでしょうか。 OpenShift Virtualizationとストレージの連携について書こうと思っていた所が、どちらかというとOpenShiftや物理ストレージの内容にかなりよった記事であることに... しかし、 この記事の読者層の多くはおそらく『OpenShift Virtualizationをこれから使っていこうと考えている現役仮想化エンジニア』 だと考えています。 ストレージ製品への適切な理解は、仮想化基盤において欠かせない知識です。 仮想マシンのデータを預かるストレージ製品、もしクリティカルな障害が起きた場合仮想マシンの全停止など業務停止クラスの影響が予想されます。 KubernetesをベースとしたRed Hat OpenShiftでは、vSphereやHyper-V、Nutanixなどの仮想化基盤とは全く異なる仕組みでストレージを制御するため、まずはこの記事を通じて、どのような差分学習をすればいいのかを掴んでいただくことで、将来のトラブルを少しでも回避できるようになると言えます。 余談ではありますが、私自身もKubernetesのリソースを通じたストレージの利用の仕組みへの理解は最初は苦戦しました。 SANやNASなどの共有ストレージから入った人からすると、Kubernetes環境におけるPVCの存在が最初『?』ってなる人は一定数いると思う 従来型インフラだと、ストレージスペースの提供は、 1. ドライブをまとめ上げてプール化 2.… pic.twitter.com/BLoQozEKSf — Yamato@Red Hat/Learning Solution Architect (@lab8010) March 27, 2025 この記事を通じて、少しでもKubernetesやOpenShiftにおけるストレージの連携の仕組みを理解できた!という人が増えてくれると嬉しいです。 また、OpenShift Virtualizationに向けたストレージ関連記事はこの後も掲載予定です。 以上の内容をもち、本記事の締めとしたいと思います。 この記事の内容が、少しでもRed Hat OpenShift Virtualizationを活用した組織づくりのお役に立てば幸いです。 *1 : CSIドライバーのサポートは、それを提供するストレージメーカーにより提供されます *2 : ここでいうリソースとは、CPUやメモリ、ディスク容量などの物理リソースではなく、Kubernetesの世界で登場する論理的な管理単位の総称です。 *3 : ブロックアクセスやファイルアクセスなどの複数のデータアクセス手法に対応したストレージ *4 : VVOLはvSphere 9にてリタイアが決定しています。 https://knowledge.broadcom.com/external/article?articleId=401070
Apache Camel Advent Calendar 5日目の記事は、サポート担当古市が担当します。 テーマは、「Camel Route から Hello World」 雛形作成と実行までを紹介しますが、ここでは 0から10まで文法やオブジェクト構造を説明しません。 0からしっかりと時間をかけて学びたいという素晴らしい志を持たれた方は、こちらのリソースをご覧ください: 初日に紹介した Japan Camel User Group(JCUG)の記事 jcug-oss.github.io Community Document camel.apache.org 書籍: Camel in Action 2nd edition www.manning.com それでは、雛形の作成です。一番簡単に始めるのであれば、やはり camel-jbang です。 camel init コマンドで、サンプル camel route が自動生成されます。 % camel init Hello.java % % cat Hello.java import org.apache.camel.builder.RouteBuilder; public class Hello extends RouteBuilder { @Override public void configure() throws Exception { from("timer:java?period=1000") .setBody() .simple("Hello Camel from ${routeId}") .log("${body}"); } } 拡張子を変更することで、ご利用されたい camel DSLのサンプルを生成します。( java , xml-io , yaml ) % camel init hello.yaml % % cat hello.yaml - route: from: uri: timer:yaml parameters: period: "1000" steps: - setBody: simple: Hello Camel from ${routeId} - log: ${body} % % camel init hello.xml % cat hello.xml <?xml version="1.0" encoding="UTF-8"?> <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://camel.apache.org/schema/spring" xsi:schemaLocation=" http://camel.apache.org/schema/spring https://camel.apache.org/schema/spring/camel-spring.xsd"> <route> <from uri="timer:xml?period=1000"/> <setBody> <simple>Hello Camel from ${routeId}</simple> </setBody> <log message="${body}"/> </route> </routes> どの Camel DSL を推奨するかご質問をいただくことがありますが、これといった正解はございません。 後日ご紹介する visual camel editor kaoto は執筆時点で yaml と xml-io をサポートしています。kaoto のご利用をご検討される場合、この2つから選択していただく必要があります。 kaoto は ドキュメント生成機能 があるので、こちらを利用するためには yaml もしくは xml-io の選択が必要となります。 visual editor を使わず、普段から Javaのコーディングをされている場合、 java DSL をラクに感じるかもしれません。 ( camel transform route コマンドを使い、他DSLへ変換することも可能です。) ここでは、 Java DSL を使っていきます。生成した camel route は、 camel run コマンドで実行可能です。 % camel run Hello.java Running integration with the following configuration: --camel-version=4.10.3.redhat-00025 Running integration with the following configuration: --camel-version=4.10.3.redhat-00025 2025-07-17 09:53:18.394 INFO 2807 --- [ main] org.apache.camel.main.MainSupport : Apache Camel (JBang) 4.10.3.redhat-00025 is starting 2025-07-17 09:53:18.495 INFO 2807 --- [ main] org.apache.camel.main.MainSupport : Running Mac OS X 15.5 (aarch64) 2025-07-17 09:53:18.495 INFO 2807 --- [ main] org.apache.camel.main.MainSupport : Using Java 21.0.7 (Java HotSpot(TM) 64-Bit Server VM) with PID 2807 2025-07-17 09:53:18.495 INFO 2807 --- [ main] org.apache.camel.main.MainSupport : Started by hfuruich in /Users/hfuruich/sandbox 2025-07-17 09:53:18.557 INFO 2807 --- [ main] org.apache.camel.main.ProfileConfigurer : The application is starting with profile: dev 2025-07-17 09:53:19.036 INFO 2807 --- [ main] he.camel.cli.connector.LocalCliConnector : Camel JBang CLI enabled 2025-07-17 09:53:19.067 INFO 2807 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.10.3.redhat-00025 (Hello) is starting 2025-07-17 09:53:19.159 INFO 2807 --- [ main] e.camel.impl.engine.AbstractCamelContext : Routes startup (total:1) 2025-07-17 09:53:19.159 INFO 2807 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route1 (timer://java) 2025-07-17 09:53:19.159 INFO 2807 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.10.3.redhat-00025 (Hello) started in 92ms (build:0ms init:0ms start:92ms boot:670ms) 2025-07-17 09:53:20.119 INFO 2807 --- [ - timer://java] Hello.java:10 : Hello Camel from route1 2025-07-17 09:53:21.111 INFO 2807 --- [ - timer://java] Hello.java:10 : Hello Camel from route1 お手元で試された実行結果とこちらの実行結果で、使用された camel ライブラリーのバージョンが異なるかもしれません。 camel-jbang は、実行時に利用する camel ライブラリーのバージョンを指定できます。Red Hat Build of Apache Camel(RHBAC)で使われるバージョンも指定できますので、必要の際にはご活用ください。 % camel version set 4.10.3.redhat-00025 % % camel version JBang version: 0.127.18 Camel JBang version: 4.10.3.redhat-00020 User configuration: camel-version = 4.10.3.redhat-00025 次に、既存のひな形コードを多少修正してみます。 camel-jbang はデフォルトで、 コマンド実行ディレクトリにある application.properties を読み取ります 。プロパティ値を読みとるようにコード修正してみます。 % cat application.properties location="Tokyo" % % cat Hello.java import org.apache.camel.builder.RouteBuilder; public class Hello extends RouteBuilder { @Override public void configure() throws Exception { from("timer:java?period=1000") .setBody() .simple("Hello Camel from {{location}}!") .log("${body}"); } } % 実行結果はこのようになります。 % camel run Hello.java application.properties Running integration with the following configuration: --camel-version=4.10.3.redhat-00025 Running integration with the following configuration: --camel-version=4.10.3.redhat-00025 2025-07-17 14:57:01.394 INFO 7918 --- [ main] org.apache.camel.main.MainSupport : Apache Camel (JBang) 4.10.3.redhat-00025 is starting 2025-07-17 14:57:01.483 INFO 7918 --- [ main] org.apache.camel.main.MainSupport : Running Mac OS X 15.5 (aarch64) 2025-07-17 14:57:01.483 INFO 7918 --- [ main] org.apache.camel.main.MainSupport : Using Java 21.0.7 (Java HotSpot(TM) 64-Bit Server VM) with PID 7918 2025-07-17 14:57:01.484 INFO 7918 --- [ main] org.apache.camel.main.MainSupport : Started by hfuruich in /Users/hfuruich/sandbox 2025-07-17 14:57:01.513 INFO 7918 --- [ main] org.apache.camel.main.BaseMainSupport : Properties location: file:application.properties 2025-07-17 14:57:01.532 INFO 7918 --- [ main] org.apache.camel.main.ProfileConfigurer : The application is starting with profile: dev 2025-07-17 14:57:01.948 INFO 7918 --- [ main] he.camel.cli.connector.LocalCliConnector : Camel JBang CLI enabled 2025-07-17 14:57:01.974 INFO 7918 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.10.3.redhat-00025 (Hello) is starting 2025-07-17 14:57:02.013 INFO 7918 --- [ main] org.apache.camel.main.BaseMainSupport : Property-placeholders summary 2025-07-17 14:57:02.013 INFO 7918 --- [ main] org.apache.camel.main.BaseMainSupport : [application.properties] location = "Tokyo" 2025-07-17 14:57:02.063 INFO 7918 --- [ main] e.camel.impl.engine.AbstractCamelContext : Routes startup (total:1) 2025-07-17 14:57:02.064 INFO 7918 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route1 (timer://java) 2025-07-17 14:57:02.064 INFO 7918 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.10.3.redhat-00025 (Hello) started in 89ms (build:0ms init:0ms start:89ms boot:578ms) 2025-07-17 14:57:03.026 INFO 7918 --- [ - timer://java] Hello.java:10 : Hello Camel from "Tokyo"! 2025-07-17 14:57:04.019 INFO 7918 --- [ - timer://java] Hello.java:10 : Hello Camel from "Tokyo"! プロファイル毎に専用の application- .properties ファイルを作り、" --profile= " オプションを指定しファイルを使いわける事も可能です。手元の検証用やデモ用など、環境に合わせて使い分けても良いでしょう。 Timer で camel route を始めるのではなく、 http request を受け付けるよう修正してみます。 % cat application.properties location="Tokyo" % % cat Hello.java import org.apache.camel.builder.RouteBuilder; public class Hello extends RouteBuilder { @Override public void configure() throws Exception { from("netty-http:http://0.0.0.0:8080/foo") .setBody() .simple("Hello Camel from {{location}}!"); } } 実行結果はこのようになります。 % camel run Hello.java application.properties Running integration with the following configuration: --camel-version=4.10.3.redhat-00025 Running integration with the following configuration: --camel-version=4.10.3.redhat-00025 2025-07-17 15:17:14.152 INFO 9949 --- [ main] org.apache.camel.main.MainSupport : Apache Camel (JBang) 4.10.3.redhat-00025 is starting 2025-07-17 15:17:14.240 INFO 9949 --- [ main] org.apache.camel.main.MainSupport : Running Mac OS X 15.5 (aarch64) 2025-07-17 15:17:14.240 INFO 9949 --- [ main] org.apache.camel.main.MainSupport : Using Java 21.0.7 (Java HotSpot(TM) 64-Bit Server VM) with PID 9949 2025-07-17 15:17:14.240 INFO 9949 --- [ main] org.apache.camel.main.MainSupport : Started by hfuruich in /Users/hfuruich/sandbox 2025-07-17 15:17:14.270 INFO 9949 --- [ main] org.apache.camel.main.BaseMainSupport : Properties location: file:application.properties 2025-07-17 15:17:14.289 INFO 9949 --- [ main] org.apache.camel.main.ProfileConfigurer : The application is starting with profile: dev 2025-07-17 15:17:14.706 INFO 9949 --- [ main] he.camel.cli.connector.LocalCliConnector : Camel JBang CLI enabled 2025-07-17 15:17:14.805 INFO 9949 --- [ main] nt.netty.http.HttpServerBootstrapFactory : BootstrapFactory on port 8080 is using bootstrap configuration: [NettyServerBootstrapConfiguration{protocol='http', host='0.0.0.0', port=8080, broadcast=false, sendBufferSize=65536, receiveBufferSize=65536, receiveBufferSizePredictor=0, workerCount=0, bossCount=1, keepAlive=true, tcpNoDelay=true, reuseAddress=true, connectTimeout=10000, backlog=0, serverInitializerFactory=org.apache.camel.component.netty.http.HttpServerInitializerFactory@60b1ff3b, nettyServerBootstrapFactory=null, options=null, ssl=false, sslHandler=null, sslContextParameters='null', needClientAuth=false, enabledProtocols='TLSv1.2,TLSv1.3, keyStoreFile=null, trustStoreFile=null, keyStoreResource='null', trustStoreResource='null', keyStoreFormat='JKS', securityProvider='SunX509', passphrase='null', bossGroup=null, workerGroup=null, networkInterface='null', reconnect='true', reconnectInterval='10000', unixDomainSocketPath='null'}] 2025-07-17 15:17:14.807 INFO 9949 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.10.3.redhat-00025 (Hello) is starting 2025-07-17 15:17:14.841 INFO 9949 --- [ main] che.camel.component.netty.NettyComponent : Creating shared NettyConsumerExecutorGroup with 29 threads 2025-07-17 15:17:14.870 INFO 9949 --- [ main] tty.SingleTCPNettyServerBootstrapFactory : ServerBootstrap binding to 0.0.0.0:8080 2025-07-17 15:17:14.894 INFO 9949 --- [ main] ache.camel.component.netty.NettyConsumer : Netty consumer bound to: 0.0.0.0:8080 2025-07-17 15:17:14.895 INFO 9949 --- [ main] org.apache.camel.main.BaseMainSupport : Property-placeholders summary 2025-07-17 15:17:14.896 INFO 9949 --- [ main] org.apache.camel.main.BaseMainSupport : [application.properties] location = "Tokyo" 2025-07-17 15:17:14.946 INFO 9949 --- [ main] e.camel.impl.engine.AbstractCamelContext : Routes startup (total:1) 2025-07-17 15:17:14.946 INFO 9949 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route1 (http://0.0.0.0:8080/foo) 2025-07-17 15:17:14.946 INFO 9949 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.10.3.redhat-00025 (Hello) started in 139ms (build:0ms init:0ms start:139ms boot:652ms) 別ターミナルから httpリクエストを送信します。 % curl http://0.0.0.0:8080/foo Hello Camel from "Tokyo"!% % 最後に、ちょっとしたネタを。 stream:in,out を使いつつ、スクリプト実行に対応するため、先頭行にコメントを追記しています。 % cat application.properties location="Tokyo" % cat Hello.java ///usr/bin/env jbang --quiet camel@apache/camel script "$0" --properties=application.properties "$@" ; exit $? import org.apache.camel.builder.RouteBuilder; public class Hello extends RouteBuilder { @Override public void configure() throws Exception { from("stream:in") .setBody() .simple("Hello ${body.toUpperCase()} from {{location}}!") .to("stream:out"); } } Hello.java に実行権限を付与し、実行してみます。echoコマンドを使い、スクリプトに文字列を渡しています。 % chmod +x Hello.java % % echo "Camel" | ./Hello.java Hello CAMEL from "Tokyo"! % 普段何気なく作業している雑務を、camel routeを使ったスクリプトで効率化しても面白いかもしれません。 ぜひ、楽しみながら camel tool box を色々と試してみてください。 今回紹介した camel jbang の類似サンプルは、コミュニティーページでも紹介されています。他にも沢山の機能がありますので、ぜひこちらもご覧ください。 camel.apache.org Quarkus runtime や Spring Boot runtime 用ひな形プロジェクトを使い試されたい方は、それぞれオフィシャルドキュメントに生成方法が記載されています。こちらをご覧ください。(camel-jbang を使い、maven project を生成する機能もあります。) docs.redhat.com docs.redhat.com 明日の advent calendar 6日目では、「Testing Camel」 についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com
Red Hat のソリューションアーキテクトの瀬戸です。 これは Jakarta EE / Java EE Advent Calendar 2025 の4日目の記事です。 昨日は @TTakakiyo による Open LibertyでJakarta EEをフレームワークとして使う #Java - Qiita です。 明日は @megascus による Jakarta Persistence 3.2(Jakarta EE 11)で増えたJPQLの構文 - 水まんじゅう2 です。 JBoss EAP 8から環境変数の扱いが変わりました。 具体的にはstandalone.xmlなどの設定ファイルで積極的に環境変数を参照しに行くようになりました。 以前は環境変数を参照したい場合はenvと明示的にパラメーター名に付ける必要がありました。 さて、実際に見てみましょう。 JBoss EAPではデフォルトでHTTPポートのリスニングについては次のような設定がされています。 <socket-binding name="http" port="${jboss.http.port:8080}"/> これはjboss.http.portというパラメーターが渡された時はその値、渡されていない場合は8080がデフォルト値として使用されるという意味です。 何も設定しない場合、JBoss EAPは8080をリスニングポートとして起動します。 16:21:47,052 INFO [org.wildfly.extension.undertow] (MSC service thread 1-4) WFLYUT0006: Undertow HTTP リスナー default が 127.0.0.1:8080 でリッスンしています パラメーター名を全部大文字に変換し、英数字以外のすべての文字をアンダースコアにしたものを環境変数として設定します。 jboss.http.port -> JBOSS_HTTP_PORT 例) set JBOSS_HTTP_PORT=18080 設定するとJBoss EAPは18080をリスニングポートとして起動します。 16:27:38,769 INFO [org.wildfly.extension.undertow] (MSC service thread 1-3) WFLYUT0006: Undertow HTTP リスナー default が 127.0.0.1:18080 でリッスンしています また、システムプロパティが設定されている場合はそちらが優先され、環境変数は読み込まれませんのでご注意ください。 ということで、JBoss EAPの環境変数を読み込むルールが変更されたという話でした。JBOSSもしくはWILDFLYという環境変数が定義されている場合、環境変数から値が読み込まれ、予期しない挙動を生む場合があるのでご注意ください。また、standalone.xmlなどの設定ファイル内で独自の変数を定義している場合も、予期せず環境変数から値を読み込んでしまう場合もありますので、ご注意ください。 参考: 4.2. 管理モデル式を解決するための環境変数 | OpenShift Container Platform での JBoss EAP の使用 | Red Hat JBoss Enterprise Application Platform | 8.1 | Red Hat Documentation
※本記事は OpenShift Virtualization アドベントカレンダーの 4日目の記事です。 qiita.com 皆さんこんにちは、OpenShift Virtualization とストレージを生業にしている Red Hat のうつぼ(宇都宮)です。お久しぶりです。 OpenShift Virtualization の特命係として活動を始めてはや2年経ちますが、おかげさまで現在は過去最高の注目と期待を浴びていると感じております。誠にありがとうございます。 一方で、実案件やプロモーションなどにかまけて技術情報の発信を怠っていたなと痛感する毎日でございます。 そんなこんなでアドベントカレンダーの形ではありますが、OpenShift Virtualization の情報をお出ししていきたいと思います。 今日のテーマは Live migration です。 ターゲットノードを指定する VM Live migration 実際にやってみる Storage class live migration 実際にやってみる 注意点 さいごに ターゲットノードを指定する VM Live migration Live migration は VM を停止せずにノードからノードへ移動する機能です。 VMware でいう vMotion なわけですが、基本的な説明は以前の記事↓で紹介されていますので、こちらをご覧ください。 ゼロからはじめるOpenShift Virtualization(4)OpenShift Virtualizationのインストールと実行 - 赤帽エンジニアブログ 今回紹介したいことは、 ノードを指定して Live migration できるようになったよ ということです。 OpenShift Virtualization 4.20 で、指定したノードをターゲットとする Live migration が GA になりました。 これによって、ノードのメンテナンスなどで意図的に VM を特定のノードに移動させたい時に、 nodeSelector などを使わなくても簡単に行えるようになりました。 実際にやってみる やり方も極めて簡単です。ちょっとやってみましょう。 VM の Action メニューから Migration > コンピュート と選ぶと、下図のようにウィザードが出てきます。 ここで "特定のノード" を選択すると移動先のノードの候補が自動で表示されてきます。ノードを選んで [VirtualMachine の移行] ボタンを押せば実行されます。 VM Live migration のウィザード画面 これは結構昔からずーっと求められていた機能なので、喜ぶ方は結構多いのではないでしょうか。 ※[12/04 09:30 追記] 今朝時点でリリースされている最新の OpenShift Virtualization 4.20.1 (stable channel), および 4.20.2 (candidate channel) において、GUI で指定したノードに移動しないというバグが確認されております。 https://issues.redhat.com/browse/CNV-71548 このバグは上記のように GUI で設定した場合のみ発生するもので、YAML で作成した場合には発生しません。 早々に修正される見込みですが、現時点で特定のノードに VM を Live migration したい場合は YAML で実行するようにして下さい。 YAML の例、 spec.addedNodeSelector でノードを指定する。 apiVersion: kubevirt.io/v1 kind: VirtualMachineInstanceMigration metadata: name: migration-job namespace: vms labels: kubevirt.io/vmi-name: rhel9 spec: vmiName: rhel9 addedNodeSelector: kubernetes.io/hostname: wk-01 GUIでYAMLを書いてもOK Storage class live migration お次は仮想ディスクを無停止で別のストレージに移動する、VMware でいう Storage vMotion 的な機能です。 実はドキュメントによって名称はマチマチで、正式な機能名称がなさそうに思えるので、 Storage live migration でも、 Storage class live migration でも、 Storage class migration でも好きな名前で呼んでもらって大丈夫だと思います。だいたいは伝わるはずです。 さて、この機能はちょっと前から Technology Preview として提供されていて、実は昨年の OpenShift Advent Calendar の記事にも書いています。 詳細は大きく変わらないので、こちらの記事を読んでいただければ機能自体はおわかりいただけると思います。 OpenShift の Storage Class Migration - 赤帽エンジニアブログ 今回紹介したいことは、これが ついに GA になったよ ということと、 Migration Toolkit for Container (MTC) ではなくて VM のメニューからできるようになったよ ということです。 移行のエンジン自体は MTC を使っているので MTC のセットアップは必要になりますが、通常の Live migration と同じ感覚で Storage live migration も扱えます。 実際にやってみる ちょっとやってみましょう。 まず MTC のセットアップをします。 MTC Operator をデフォルトの openshift-migration namespace にインストールし、 MigrationController カスタムリソースを作成します。 細かいパラメータは一旦省略して、デフォルトのままで作ります。 MTC のセットアップ Pod を見ると知らないうちに OADP (OpenShift API for Data Protection) 関連の Pod が作られていますが、OADP は MTC と一緒に自動でインストールされるのでこれで正しいです。 [ root@bastion ~ ] # oc get pod -n openshift-migration NAME READY STATUS RESTARTS AGE migration-controller-bcf6fd9df-vc6dm 2 / 2 Running 0 2m38s migration-log-reader-d45f7fb6c-w9jkb 2 / 2 Running 0 2m37s migration-operator-55c8dbd7c9-hdjfh 1 / 1 Running 0 4m44s migration-ui-5c8c745679-555nn 1 / 1 Running 0 2m33s node-agent-6hkck 1 / 1 Running 0 2m54s node-agent-jncdz 1 / 1 Running 0 2m54s node-agent-lrvb9 1 / 1 Running 0 2m54s openshift-adp-controller-manager-5f6cd4bd9-4plrn 1 / 1 Running 0 4m31s velero-58986884ff-p82zs 1 / 1 Running 0 2m54s ここまででしておけばOKです。VM のメニューから Migration を選ぶと、グレーアウトされていた "ストレージ" が選択できるようになっているはずです。 ストレージ Live migration メニュー *Migration > ストレージ** を選ぶと、図のようなウィザードが表示されます。このウィザードに沿って移動させるディスクや移行先の Storage class を選択します。 最後に [VirtualMachine ストレージの移行] ボタンを押せば実行されます。 Storage class live migration のウィザード画面 ストレージの移行は、左メニューの "Migration for Virtualization" の下にある、"Storage migrations" から状況を見ることができます。 マイグレーションの設定をすると、 MigPlan というカスタムリソースが作成されます。 ※MTV は MigrationPlan なので少しややこしいですね(汗 Storage class live migration のプラン (MigPlan) 注意点 Storage class live migration は次のような注意点があります。 同一の Namespace 内でのみ移行できる 異なる Namespace への移行は対応していません。 同時に VM の Live migration も起きる PVC が移行先に切り替わるタイミングで、VM 自身も Live migration するため、別の Compute ノードに移動します。   以前は DataVolume (DV) は同じで PVC だけが置き換わる動きだったのですが、現在は DV 自体も新しいものに作り変えられるようです。VirtualMachine カスタムリソースで DV ごと変更されて、Live migration でその変更を適用するという流れになります。 移行元のディスクは残る Storage class live migration では移行した後も移行元の PVC と DV が残ります。このまま放っておくと容量を重複して消費することになるので、必要に応じて移行元の PVC と DV を削除して下さい。 同じ namespace では同時に 1つだけ migration できる。 1つの namespace で作成できる MigPlan は1つだけという制約があるためです。 さいごに VM の Live migration もストレージの Live migration も運用保守においては欠かせないものかと思いますが、OpenShift Virtualization でも対応しています。 Storage class live migration については現在は MTC に依存していますが、将来的にはこれがなくなって OpenShift Virtualization 自身に持たせていくプランもあります。 仮想化基盤の移行の際にはぜひ OpenShift Virtualization をご贔屓によろしくおねがいします。 それでは、今日はここまで。
Apache Camel Advent Calendar 4日目の記事は、サポート担当古市が担当します。 テーマは、「componentとの付き合い方」 普段の開発をラクにできるツールボックス Apache Camel を使いこなす上で、「どんなツールがあるのか」「どのツールはいつ使うのが効果的か」といった悩みをお持ちではないでしょうか。 既にご存知の方もいらっしゃるかと思いますが、ツールを使わずとも機能実装は可能です。 Camel では、 カスタムプロセッサー や Java Bean の実行をサポートしているため、過去にはこんな使い方を見たことがあります。 タイマーを使い定期実行 Java Bean 内で、ファイルシステムにアクセスし、ファイルが存在したら別ディレクトリへ移動するコードを独自に実装 上記コードは、テストもパスしているでしょうし、おそらく本番環境でも問題なく動作するはずです。 しかし、この例では、Java Bean内で独自にロジック実装する必要はありません。 せっかく Camel を使われているのだから、豊富なオプションを用意した File component を使えば良いのです。 File component (consumer, producer)を使い、ファイルを移動 両方とも最終的には同じビジネスロジックを実装したことにはなりますが、コードの見通しやチューニングのし易さで言えば後者に軍配が上がります。 Camel を導入する際には、各ツール(component)を効果的に使いこなしたいものです。[1] [1] 「componentにオプションが無かった」「バグがあった」という理由で暫定的に Java Beanをご利用されるコーナーケースもあります。 しかし、あくまでも特例であり、デフォルトで Java Beanを使う考え方は、お勧めできません。 Apache Camel コミュニティーサイトでは、執筆時点(2025/7/10)でこれだけのツールが提供されています。 core component: 27 component: 332 (5 deprecated) 工具セットを購入してみたけれど、ツールの多さに戸惑い途方に暮れながらとりあえずプラスドライバーだけで頑張るなんて、残念ですよね。 今回は、ツールセットとの付き合い方についてご紹介します。 まずはざっと見る 気になる component のページで詳細を読む サンプルを探す まずはざっと見る コミュニティー版では、こちらに component一覧があります。 camel.apache.org 製品版では、runtime毎に component一覧があります。[2] docs.redhat.com docs.redhat.com 後日ご紹介する VScode extension の kaoto でも、component一覧を表示できます。 [2]コミュニティー版にあり製品版にはない component があった場合、 Red Hatサポート窓口 までお問い合わせください。 サポート可否/代替え案/製品対応申請 といったサポートをご提供しております。 まずは、component一覧をぼんやりと一通り見てみましょう。 component名からなんとなく動作がわかるかと思いますし、descriptionに簡単な説明もあります。内部で使用しているライブラリーが component名になっていることも多いので、混乱はしにくいかと思います。 これから実装しようとしている機能がある場合、キーワード検索をしても良いかもしれません。前述した例ではファイル移動なので、"file"と検索すれば File component がヒットします。 ただ、この方法では検索しずらいものもあります。例えば、Artemis Brokerとのインテグレーション用 component を探す場合、"artemis" ではヒットしません。コミュニティーサイトにてキーワード "JMS"と探すと、これだけの component が見つかるはずです。 camel-activemq camel-activemq6 came-jms camel-sjms camel-sjms2 説明を読めばなんとなくそれぞれの違いがわかり、 camel-jms をご利用されるかもしれません。 ですが、 artemis broker を使われているのであれば、 camel-amqp component をお勧めします。(汗) artemis broker が client とのやりとりで使用する amqpプロトコル に対応した component であり、 camel-jms よりも最適化されているためです。 キーワード検索も有効ですが、component一覧を一通り見ておくことで、camel-amqp component を見落とす状況も回避できるかもしれません。 ぜひ通勤中などの片手間で良いので、定期的にご確認ください。 Red Hatサポート窓口では、お客様のニーズに合った componentをご紹介することも可能です。 「時間をかけずに最適な componentを探したい」という方は、ぜひサポート窓口のご利用をご検討ください。[3] [3] Red Hat コンサルティングサービスでは、お客様のプロジェクトに参画し、camelの導入に対し包括的なアドバイスや技術トレーニングのご提供も可能です。 気になる component のページで詳細を読む 一覧をざっと見ることで、気になる component が見つかったかと思います。次に、各component ページの読み方についてご案内します。 ここでは、 camel-file component を例にします。 もちろん component紹介ページの内容はすべて読むことをお勧めしますが、いくつかチェックポイントがあります。 まず気にすべきは、 dependency の追加定義 が pom.xml に必要かどうかです。 製品ドキュメントであれば、それぞれの runtime 用の定義が記載されているはずです。 Quarkus <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-file</artifactId> </dependency> Spring Boot <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-file-starter</artifactId> <version>x.x.x</version> </dependency> 次に、" URI Format "と各種オプションをチェックすることで、どういった制御が可能か把握できます。 camel-file component の "URI Format"はこちら。 file:directoryName[?options] ディレクトリー名とオプションが設定できることがわかります。 オプションですが、2種類あることに気づきます。 component レベル endpoint レベル camel routeを実装する際、CamelContext 内に複数 camel route を定義することが可能です。 component レベルは、CamelContext 内で使われる camel-file component 全てに適応されるオプションです。 endpoint レベルは、camel route 内で定義する エンドポイント(例えば "from("file://inbox"))にのみ適応されるオプションです。 クエリーオプション と言われたりもします。 簡単に動作確認されるのであれば、まずは endpointレベルのオプションを設定するのが簡単かと思います。 ” Message Headers " も重要です。動作の制御に使える header や、実行結果が格納される header が紹介されています。 オプションや message header に共通する内容ですが、 producer/consumer のどちらかにのみ適応されるものがありますので、ご注意ください。 consumer endpoint は、メッセージを受け取る endpoint です。 endpointは、" from "で定義を始めます。 producer endpoint は、インテグレーション先にメッセージを送信する endpointです。endoint は、" to "で定義を始めます。 「メッセージを受け取るのか送信するのか」、どちらの endpoint を使うか頭に入れつつ、各種オプション設定や message header をご確認ください。 サンプルを探す 各紹介ページには、必ずといって良いほどサンプルコードがセットになっています。まずはそちらをご確認ください。 他にも見てみたいという方には、サンプル集が公開されています。 github.com github.com サンプルにコンポーネントオプションが使われていないかもしれません。その場合、camelライブラリーのソースコードに同梱されているテストコードが有用な場合もあります。(Red Hat カスタマーポータルからも、製品ソースコードがダウンロード可能です。) access.redhat.com それでもオプションの使用方法がわからない場合などあるかと思います。 その場合は、camel コミュニティーが運営している SNS や メーリングリスト をご利用いただく方法があります。 camel.apache.org もちろん、 Red Hat サポート窓口 でご質問いただくことも可能です。 ざっとではありますが、componentとの付き合い方についてご紹介しました。 よくサポートケースで散見する component の使い方については、後日改めていくつか投稿する予定です。ぜひお楽しみにしてください。 明日の advent calendar 5日目では、「Camel route から Hello world」 についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com
はじめまして、Red HatでOCPとかAnsibleのコンサルタントをやっているワタナベです。 この記事では自分が作成したOpenShift Container Platform (OCP) の環境構築練習ツール ocp_create_vm を紹介します。 これはOpenShiftインストールを練習するための「OpenShift Node(Cluster VM/ISOマウントして起動)」と「周辺環境(Bastion VM/デフォルトはCentOS Stream9が起動)」をお手軽に払い出すAnsible Roleとそれを便利に使うスニペットをまとめたリポジトリです。 gitlab.com なぜ作成したのか OpenShift構築の学習や検証において、一番のハードルは「OpenShiftそのもの」よりも、「インストールを試すための土台(マシンの払い出し)の準備」 にあると感じたことはないでしょうか? 例えば、あなたはオンプレミス OCP構築担当としてプロジェクトにアサインされた新人メンバだとします。そうすると、自ずとこんなことになってしまうでしょう。 検証用にサーバー1台もらったからOpenShift入れてみようかな……あーでも、とりあえずSNO(シングルノードOpenShift)で組んだとしても、ノード落ちた時のテストとかできないか。本番インストール方法とも違うし、インストールの練習にもならないしなぁ。 じゃあマルチノードで練習するなら、サーバーにVM環境立てなきゃいけないってことか。いやでも、OpenShift入れたいだけなのに、わざわざその下の仮想基盤の構築から勉強してる時間なんてないって。 結局、本番はぶっつけでやるしかなさそうだから、それまではドキュメントベースの机上検証にしとくか。。。 ごめんね! アプリチーム!作った基盤でアプリのnodeダウンテストをしたいっていったけどOpenShift localとかで我慢して! とかとか。いや、OpenShift localが良くないわけじゃないんですけど、複数nodeで動作したときの挙動とかnode障害テストをしたいってときにちょっと物足りなさはあったりします。 このツールは、そんな問題 「複数nodeを前提としたオンプレミスOpenShiftのインストール手順(Agent-based Installer や Assisted Installer)を何度も練習したい。ついでにいうなら失敗して壊れてもささっと作り直しをして検証したい」 というニーズに特化した、環境構築・破棄の自動化ツールです。 何ができるツールなのか? 一言で言うと、 OpenShiftインストールを練習するための「OpenShift Node(VMスペック定義/ISOマウントして起動)」と「周辺環境(Bastion VM)」を一本で払い出すAnsible Roleとそれを便利に使うスニペットをまとめたリポジトリ です。 裏側ではTerraformが動いていますが、Ansibleでラッピングしているため、ユーザーがTerraform(HCL)を記述する必要はありません。AnsibleのPlaybookを実行するだけで、以下のサイクルを高速に回すことができます。 環境構築(Bastion VM) Bastionインストール OpenShiftインストール→ISO作成 環境構築(Cluster VMs) OpenShift設定/Operator検証 環境破棄(Destroy) → 1に戻る 使い方のイメージ まず、RHEL9系のLinuxマシンを用意します。その後、AnsibleとかTerraformとかKVMのセットアップをして・・・ってめんどくせー! curl -fsSL https://gitlab.com/tawatana/ocp_create_vm/-/raw/main/setup-host.sh | sh これでできます。とりあえずクリーンインストールしたRHEL9にrootアカウントでこれを実行したらおまかせで全部入ります。 なに?物理マシンも持ってない?そんな人には これ ! お手元のmacとかWSLにansibleをインストールしてこのplaybookを実行してください。AWSにAnsibleとかTerraformとかKVMがいい感じにセットアップされたベアメタルインスタンスがご飯食べてる間に払い出されます。もちろんAWS環境丸ごと削除するplaybookも入ってるのでお片付けも簡単です。 (※AWSのベアメタルインスタンスは料金が高めなので、検証が終わったら必ず削除Playbookを実行してください!) さてさて、これでKVMホストは用意できましたね。じゃあ「Step 1: Bastion(踏み台)の作成」を実施します。 これより後ろはAgent-based方式をサンプルに使い方を案内します。 Step 1: Bastion(踏み台)の作成 KVMホストで次のPlaybookをrootで実行します。 # create_bastion.yml --- - name: Create bastion hosts: localhost tasks: - name: Create bastion ansible.builtin.import_role: name: ocp_create_vm vars: ocp_create_vm_create_bastion: true ocp_create_vm_ocp_network_mode: "nat" 実行方法 ansible-playbook create_bastion.yml 実行後、KVMホスト上に以下の構成でネットワークとVMが作成されます。 default (192.168.122.0/24)(デフォルトゲートウェイ経由でインターネット接続可) │ bastion01 ├── NIC 1: default (192.168.122.10) └── NIC 2: openshift_network │ openshift_network (192.168.10.0/24)(デフォルトゲートウェイ経由でインターネット接続可) │ もし、ProxyやDisconnectedの練習がしたかったら「ocp_create_vm_ocp_network_mode: "nat"」を削るとデフォルト値の「ocp_create_vm_ocp_network_mode: "none"」が適用され、OCP VMがデプロイされるネットワークは疎通ができない構成になります。 bastionのログイン情報はplaybookに記載されます(Ansibleの変数変えてなかったらこれがデフォルトです。) TASK [ocp_create_vm : Display login info] ok: [localhost] => { "msg": [ "VM Connection Information", "IP Address : 192.168.122.10", "User : rhel", "Password : redhat" ] } これで、bastionサーバの構築は完了です。対象サーバにログインしていろいろインストール&設定しましょう! # ssh rhel@192.168.122.10 rhel@192.168.122.10's password: Activate the web console with: systemctl enable --now cockpit.socket Last login: Mon Dec 1 03:42:06 2025 from 192.168.122.1 [rhel@bastion0 ~]$ sudo -i [root@bastion0 ~]# dnf install xxx Step2: Bastionインストール BastionサーバにはOpenShiftインストールに必要なコンポーネントやCLIを設定します。 何をインストールするかは環境ごとに一概には言えませんが、4.20のAgent-based installerなら以下ドキュメントを見ることになります。 docs.redhat.com DNSとかロードバランサーとかProxyでのクラスタ構築とかとか・・・え、めんどい・・・? じゃあ、これで一発構築できます。Bastionサーバのrootで実行してください。 curl -fsSL https://gitlab.com/tawatana/ocp_create_vm/-/raw/main/examples/helper_node.sh | sh 詳細はスクリプトの中身をみてもらうとして、 いろんな構成に対応するためproxyとかntpも入っていますがOCP側で参照するように設定しなければ悪さはしません。 openshift-installのstable最新も入ってるのでAgent-based方式のISO作成もできます。 Step 3,4: ISOの準備とCluster VMの作成 4.20のAgent-based installerなら以下ドキュメントをみてISOファイルを生成するためのYAMLを作ってください。 docs.redhat.com これも面倒・・・?はい。これも自動化のスクリプトを作ってます。Bastionサーバのrootで実行してください。 3 Control plane, 3 workerのサンプルyamlをベースにしたISOが作成されます。 (インストールの練習のためにも スクリプトの中身 はぜひ読んでください!) curl -fsSL https://gitlab.com/tawatana/ocp_create_vm/-/raw/main/examples/create_ocp4_iso.sh | sh ISO作成後、KVMホストの /terraform/agent.x86_64.iso にISOをコピーして、以下playbookを実行してください。 # create_cluster.yml --- - name: Create cluster hosts: localhost tasks: - name: Create cluster ansible.builtin.import_role: name: ocp_create_vm vars: ocp_create_vm_create_cluster: true ocp_create_vm_cluster_os_image_path: "/terraform" ocp_create_vm_cluster_os_image_name: "agent.x86_64.iso" ocp_create_vm_cluster_master_count: 3 ocp_create_vm_cluster_worker_count: 3 実行方法 ansible-playbook create_cluster.yml 実行後、KVMホスト上に追加でOpenShift VMが作成されます。 default (192.168.122.0/24)(デフォルトゲートウェイ経由でインターネット接続可) │ bastion01 ├── NIC 1: default (192.168.122.10) └── NIC 2: openshift_network │ openshift_network (192.168.10.0/24)(デフォルトゲートウェイ経由でインターネット接続可) │ ├── master0 ├── master1 ├── master2 │ ├── worker0 ├── worker1 ├── worker2 Step 5: OpenShift設定/Operator検証 ここまで来たら普通のOpenShiftのインストールと同じです。 bastionサーバーで openshift-install --dir <install_directory> agent wait-for install-complete とか眺めてログイン情報が出力するまで待ちましょう。 Step 6: 環境破棄(Destroy) 検証が終わったり、インストールに失敗してやり直したい場合は以下Playbookを実行すればきれいに削除されます。 # destroy_all.yml --- - name: Destroy Cluster and bastion hosts: localhost tasks: - name: Destroy all ansible.builtin.import_role: name: ocp_create_vm vars: ocp_create_vm_destroy_all: true 実行方法 ansible-playbook destroy_all.yml 以上がベーシックな使い方です。 ちょっとひねった構成のOpenShiftを作りたい場合 bondingとかmultusを試したい場合 例えば、OCPをbondingでnic2つ構成にして、Virtのためにもう1本、合計3本のnicを接続したOCPを構築したいとします。 もちろんその構成のデプロイも対応してます。create_cluster.ymlの隣にocp_create_vm roleディレクトリをおいてdefaults/main.ymlを編集してみましょう。 . ├── create_cluster.yml └── ocp_create_vm/ └── defaults/ └── main.yml 54行目あたりからこんなふうに編集 # クラスタ構成情報 ocp_create_vm_cluster_master: - name: master0 cpu: "{{ ocp_create_vm_cluster_master_vcpu }}" memory: "{{ ocp_create_vm_cluster_master_memory }}" disk: - "{{ ocp_create_vm_cluster_disk_size }}" mac_address: - "52:54:00:26:a1:10" - "52:54:00:26:a2:10" - "52:54:00:26:a3:10" # - "52:54:00:26:a4:10" これで、OCP VMに3本結線され、openshift_networkに接続されるようになりました。簡単ですね。 OpenShift Virtualizationを試したい場合 これはサポートされない構成になってしまうのですが、セットアップスクリプトでKVMホストを構築した場合、Nested KVMが有効になっています。 これで多段VMが可能になるので、KVM上で作ったOCPの上でOpenShift Virtualizationが動作するようになります。とりあえず試してみる程度なら十分利用できます。 こんな人におすすめ このツールは、特に以下のような方に刺さると思います。 OpenShiftのインストールを練習したい人: Agent-based Installer や Assisted Installer の挙動を何度も確認したい方。 インストールの仕組みを深く理解したい人: どのタイミングで何が必要なのか、試行錯誤しながら学びたい方。 インストール手順書を作りたい人: 何度も「更地」に戻せるため、再現性のある手順作成に最適です。 OpenShift上のアプリ/設定手順を作りたい人: クラスター自体を使い捨てにできるため、常にクリーンな環境で検証できます。 Virtをとりあえず試したい人: Nested KVM環境で動作確認が可能です。 詳細なセットアップ方法やコードはGitLabで公開しています。 ぜひ試してみてください。 最後に当たり前のことになるんですが、このコードは個人開発で書かれたものですのでRed Hatがサポートすることはできません。あしからず。 おまけ とりあえず動くOCPが自動でできてほしいというわがままな方! 実は私がRoleのテスト用に書いたスクリプトがあります。 ansible-galaxy role install git+https://gitlab.com/tawatana/ocp_create_vm.git --force git clone --depth 1 https://gitlab.com/tawatana/ocp_create_vm.git cd ocp_create_vm/examples # Copy from https://cloud.redhat.com/openshift/install/pull-secret vi $HOME/openshift-pull-secret sh provision-openshift.sh これで先程の手順のstep4まで自動でやってくれます。楽ちんですね。中でどんなことをやってるか読み解けばいろいろカスタムとかインストールの自動化の理解ができるかと思います。
Red Hat OpenShift Virtualizationの認定資格デジタルバッジ ※本記事は OpenShift Virtualization アドベントカレンダーの 3日目の記事です。 qiita.com 目次 はじめに 【積極採用中!】Red Hat 採用に関するお知らせ この記事のゴール Q. (おさらい)Red Hat OpenShift Virtualizationとは? Q. 他社の仮想化製品経験があれば割とすぐ使えるものか? 筆者が考える、他社仮想化製品の経験者が(OpenShift Virtualizationのために)身につけるべき要素 1. YAML(ヤムル)ファイルを用いた宣言型形式によるインフラの定義 YAMLの編集は何を使って行うの? 2. OpenShiftやKubernetesにおける数々のリソース OpenShiftでサーバの仮想化をしたい場合は、どのようなリソースを覚えておく必要があるのか? 3. ストレージとネットワークに対する追加学習 ストレージ - CSIを通じたストレージの活用とPVCとPVを通じた仮想ディスク 4. 使い慣れた機能が同等の機能として存在するかの確認 OpenShift Virtualizationに向けた情報収集テクニック あとがき 最短プランは1ヶ月以内コース (実質1週間程度) 標準的なプランは3ヶ月以内コース はじめに 皆さんこんにちわ、Red Hat Global Learning ServicesでLearning Solution Architectを担当している坂井 大和( @lab8010 )です。 主に X.com 上でRed Hat製品やサービスについて配信をしているので、もしよければフォローくださると幸いです。 この記事では、 『Red Hat OpenShift Virtualizationを使いこなせるエンジニアになる』ために何を学べば良いか、そしてそれにどれぐらいの時間がかかるか を解説します。 また、この記事は2025年10月に東京赤坂で実施された当社の年次イベントRed Hat Summit Connectにおける私の登壇セッションをカスタムした内容としてお届けします。 多くの方から『このセッションのWeb配信はないんですか?』『資料の配布はないのですか?』という嬉しいお声をいただきましたが、私のセッションはWeb配信対象ではなかったので、この記事を持って皆さまの要望にお応えしたいと思います。 ※サミコネ担当の方、来年は...配信してくれると嬉しいです。配信を希望されるようなコンテンツ提供を頑張ります。 皆様のお越しをお待ちしております! 私はこちらのテーマで登壇させて頂きます。(残席数も後10席弱です、少しでもご興味のある方は早めのご登録をお勧めします!) ご登録はこちらのリンクから!(要Red Hatアカウント登録) #RHSummitConnectTokyo #サミコネ東京 https://t.co/FDtVTgIlw4 https://t.co/7A5huwuAje pic.twitter.com/8sbAn1Vlrn — Yamato@Red Hat/Learning Solution Architect (@lab8010) September 25, 2025 【積極採用中!】Red Hat 採用に関するお知らせ Red Hatでは事業拡大に伴い人材を募集しています。 本記事でご紹介している『OpenShift Virtualization』に関するコンサルタントを募集しています。もし少しでも興味がある方は、ご応募または本記事を執筆している私坂井までお気軽にDMをください。( X / Linkedin ) redhat.wd5.myworkdayjobs.com この記事のゴール この記事を読み終わった頃には、読者様が次のことが出来る状態になって頂きたいと考えています。 Red Hat OpenShift Virtualizationを管理運用するために必要な知識が必要かわかる 同製品の管理運用のために、どのような学習をすれば良いかがわかる 上記の学習が、概ねどの程度の時間がかかるのかを理解できる それでは、早速本編に入っていきましょう。 Q. (おさらい)Red Hat OpenShift Virtualizationとは? A. 次の記事を参照ください。 rheb.hatenablog.com   本赤帽ブログにて、前回私が投稿した記事にてまとめていますので、まだご覧いただいていない方はそちらを一度参照ください。 Q. 他社の仮想化製品経験があれば割とすぐ使えるものか? A. アーキテクチャそのものが異なるため、これは少し難しいと思います。 この問は、おそらく多くのユーザーが持つメジャーな疑問です。 私自身、これまで次の製品と関わってきました。 VMware vSphere (vSphere 4からvSphere 8まで、2009年から2024年頃まで) Microsoft Hyper-V (Windows Server 2008から2019頃まで) 特に、VMware vSphereとの付き合いは長く前職では VMware認定インストラクターとして8年ほど活動 していました。 ある年には、 グローバルレベルで最高成績のインストラクターとしても表彰 を受けました。 そのため、それなりに サーバ仮想化にはそれなりの自信がありました。 そんな私がRed Hat OpenShift Virtualizationと出会ったのは、Red Hatに入社して間も無い頃...『OpenShift Virtualizationできますか?』と日本のトレーニングチームのメンバーから言われ、 『仮想化製品はそれなりにやってきたから余裕だろう』 と思っていたのですが、根本的にアーキテクチャが異なるため、知れば知るほど既存の知識だけでは対応が難しいことに直ぐに気がつきました。 具体的に私が感じた技術的な差分は次の要素でした。 筆者が考える、他社仮想化製品の経験者が(OpenShift Virtualizationのために)身につけるべき要素 YAML(ヤムル)ファイルを用いた宣言型形式によるインフラの定義 OpenShiftやKubernetesにおける数々のリソース ストレージとネットワークにおける追加学習 使い慣れた機能が同等の機能として存在するかの確認 OpenShift Virtualizationに向けた情報収集テクニック これだけを見せられると 『なんだか学習コストが高いんじゃないの?』 という感想がすぐ浮かんでくると想像できます。 ここで最初に強調しておきたいのは 『Red Hat OpenShiftはKubernetesをコアとする次世代のITインフラストラクチャクラスター *1 』 だということです。 Kubernetesは元来、大量のコンテナ群を商用基盤として実行できるように設計された機能です。 一方で従来の仮想化基盤ではVMware環境ならvCenter Server、Microsoft環境ならHyper-V マネージャー、 Windows Admin Center 、 System Center Virtual Machine Manager などを通じて管理をしてきました。 これらはいずれも『仮想マシンを中心とした管理機能を提供するソリューション』です。 そもそも管理対象自体がの想定が違うため、アーキテクチャも違い必要とされてきた機能も異なります。 これは、世の中にサーバ仮想化が登場したばかりの時期にも同じようなことが言えたでしょう。 『サーバを仮想化?物理ベースの方が慣れているし、アーキテクチャを変える必要があるの?』と。 時代は繰り返すとよくいったものですが、今私たちが直面しているアーキテクチャの刷新による再学習は、以前にも起きていたことであり、転換期にはほぼ必然的に起きるものです。 この転換期をRed Hatは公式トレーニングやコンサルティングサービス、TAMなどのサービスなどでお客様を支援しているわけです。 なお、本記事では特に公式トレーニングについて解説をしていきます。   さてここから先は、これらを1つ1つ要素分解しその知識の必要性と学習方法を紹介します。 1. YAML(ヤムル)ファイルを用いた宣言型形式によるインフラの定義 VMware vSphere Client、Microsoft Hyper-V マネージャー、Nutanix Prismなど、多くの仮想化製品では優れたGUIを通じて、最も簡単に仮想化基盤に対してスマートに操作を行うことができます。 先にお伝えすると、Red Hat OpenShift VirtualizationにもWeb UIは存在します。 以下の動画では、そのデモンストレーションの様子が伺えます。 www.youtube.com GUIの変化は、これまで運用管理でそれらを多用してきた方からすれば大きなチャレンジになると言えます。 より使いやすくなるのであればWelcomeだと思いますが、そうでない場合は『前の方が良かった』と思う方が多数派となるでしょう。 実際の私の最初の感想としては、仮想マシンの台数の確認、それらのステータスの状態、どのホスト上にいるかなどを識別するのに数回のクリックを経てアクセスすることが多かったので、やや苦労したというのが正直な感想でした。 また、本題に入りますが『 YAMLファイルを通じたインフラストラクチャの定義 』がOpenShift(Kubernetes)では必要となります。 私自身のこれまでの経験上ではこのYAMLファイルを使用する画面がなかったため、OpenShiftがその初舞台となりました。 www.redhat.com YAMLそのものはRed Hat固有のものではなく、様々なベンダーの製品にて使用される有名なデータフォーマットです。 YAMLの利点は、ストレージやネットワーク、仮想マシンなど種類を超えた要素の定義をこの1種類のフォーマットで表現できることにあります。 OpenShiftをはじめとするKubernetes環境では、クラスターの制御層がこのファイルの中身で指定された状態を常に再現するように振る舞います。 例えば、上記の図の右側では 『常に、nginxのイメージが実行されるコンテナを持つPodを3つ実行するように』 努めます。 管理者は『こうあるべきである』という理想の状態をYAMLファイルに記述し、それをOpenShiftに提出(宣言)することでクラスター上に設定を施していくイメージです。 なお、Red Hat OpenShiftでは上述しているブラウザを使用するWeb UIを通じてGUIベースで上記相当の指示を出すことができるようにはなっています。 しかし、OpenShiftを使う以上はこのYAMLの記述を読んだり、編集したりする作業はどこかで行うことにはなるため、徐々に慣れていく必要があります。 YAMLの編集は何を使って行うの? YAMLは一般的なテキストファイルであるため、特別なソフトウェアがなくともOS標準のテキストエディタがあれば開いたり、編集することは可能です。 しかし、効率よく作業を行いたい場合はVisual Studio Codeなどのアプリ開発者向けのエディターなどを使うことで、改行やインデント(スペースを行頭に用いて頭を揃えること)を行いやすくすることができます。 Red Hatでは、MicrosoftのVisual Studio Codeに対してYAMLファイルに向けた編集や読解がしやすくなるプラグインを提供しています。 marketplace.visualstudio.com YAMLは、Red Hatが提供するAnsibleと呼ばれる構成管理ソリューション(IaC/Infrastructure as Code)でも使用されます。   ansible.builtin.dnf module – Manages packages with the dnf package manager — Ansible Community Documentation これは、dnfコマンドでhttpdをインストールするという命令を記述したAnsible用のYAML記述です。 このように、YAMLはOpenShiftだけでなく他の製品でも使われることが多いので、一度覚えておくと応用できる場面も増えるので、覚えることをお勧めします。 2. OpenShiftやKubernetesにおける数々のリソース リソースという単語は、それ自体が場面や文脈ごとに異なる意味を持ちます。 OpenShiftやKubernetesにおけるリソースは、次の図に掲載されたものを示します。 Kubernetesに登場する主要なタイプのリソースたち。ここに掲載したものはごく一部です。 Kubernetesをコアとするコンテナオーケストレーション環境では、これらのリソースをうまく組み合わせることでコンテナや仮想マシンのためのインフラストラクチャを構成していきます。 Kubernetesリソースを複数活用した場合の一例 サーバ仮想化系エンジニア向けの言い方をすると、次のようなものはKubernetesにおけるリソースとして登場します。 仮想マシン 仮想ハードディスク 仮想スイッチ 仮想スイッチのポートグループ 仮想マシンをまとめるリソースプール 管理画面にログインするためのユーザー そのユーザーを集約するグループ ユーザーに対して権限を割り当てるために作成するロール そして、これらリソースの設定は全てYAML形式で取り扱われます。 再掲しますが、YAMLで記述してOpenShiftクラスターに設定をしても良いですし、OpenShiftが持つWeb UIから設定をしても良いです。 OpenShiftでサーバの仮想化をしたい場合は、どのようなリソースを覚えておく必要があるのか? あらゆる構成を想定した記述はできないため、主要なものに限定して列挙します。 仮想マシンを実行するためのベースとなる VirtualMachine (カスタムリソース) Podをネットワークに繋ぐために使用する Service(標準リソース) 上記サービスをクラスター外のネットワークに公開する Route(カスタムリソース) Podに対し接続したストレージの要件を定義する PVC(標準リソース) 仮想ハードディスクのようにデータを保持する PV(標準リソース) ここに列挙したものはほんのごく一部であり、これら以外のリソースも実際のインフラでは登場します。 なお、説明に含まれる標準リソースはKubernetesがデフォルトで持っている基本的なリソースであり、カスタムリソースはKubernetesが標準的に持っていない追加されたリソースです。RouteはRed Hatが独自に用意したリソースであり、VirtualMachineはKubeVirtと呼ばれるオープンソースプロジェクトが定義したリソースです。 github.com 3.  ストレージとネットワークに対する追加学習 ITインフラストラクチャにおいて、ストレージとネットワークは非常に重要な要素であることはよく知られています。 特にサーバ仮想化インフラにおいて、ストレージと言えばFCやiSCSIなどを使用したブロックストレージやNFSなどをホストにマウントし、仮想マシンのデータを保存する仮想ハードディスク(VMware vSphereならvmdk/Microsoft Hyper-Vならvhdxなど)をその中に保存します。 ネットワークにおいては、各種ハイパーバイザーにおいてそれぞれで機能面が異なるものの仮想スイッチを用いて仮想マシンの通信を成立させます。 では、Red Hat OpenShift Virtualizationではここにどのような変化が起きるのか? ストレージ - CSIを通じたストレージの活用とPVCとPVを通じた仮想ディスク 結論から申し上げると、Kubernetesをベースとする環境においても従来利用してきた物理的なストレージ製品などを使用することはできます。 この際、Kubernetesがこうしたストレージ製品と連携をするためにContainer Storage Interface(通称CSI)という仕組み活用する必要があります。 github.com 具体的には各ストレージソリューションベンダーは自社のストレージとKubernetes環境を接続するためのCSIドライバーと呼ばれるソフトウェアを提供しているため、それを入手、セットアップをする事でストレージ製品がKubernetes環境で活用可能となります。 この点については、別の記事にて触れていく予定です。 ネットワーク - Podネットワークを使うのか?それとも従来のようなネットワークを使うのか? Kubernetesは、その発祥のきっかけとしてコンテナワークロードのためのオーケストレーションという歴史があります。 このため、Kubernetesが持つ標準的なネットワークの仕組みはコンテナに向けて用意されており、次のような特性があります。(これらの特性ともつネットワークををPodネットワークと呼ぶ) Podは原則1つのネットワークアダプタしか保有できない Pod *2 は、動的にIPアドレスを受け取り、Podが再起動される度に変化する Podが固定的なアクセスポイントを得るためには、Serviceというリソースを構成し、それが持つ固定的なIPアドレスや名前にアクセスをさせるよう構成を組む このように、Kubernetesにおけるネットワークの実装はサーバ仮想化の環境と比較するとかなり違いがあります。 また、ストレージにはCSIという考え方がありますがネットワークにはContainer Network Interface(通称CNI)が存在し、このCNIに対応するCNIプラグインと呼ばれるものの中からどれを使用するかで提供される機能が変わります。 ちなみにRed Hat OpenShift Virtualizationでは本記事投稿時点の最新版の4.20ではOVN-Kubernetesと呼ばれるCNIプラグインがデフォルトで使用されます。 第1章 OVN-Kubernetes ネットワークプラグインについて | OVN-Kubernetes ネットワークプラグイン | OpenShift Container Platform | 4.20 | Red Hat Documentation 上述のIPアドレスの動的な割り当てについても以下の記事内で言及があります。 Creates pod networking including IP Address Management (IPAM) allocation and virtual ethernet (veth) interface for the pod. www.redhat.com さて、ここまでで話が終わると『現在のサーバ仮想化環境向けに構築したネットワーク構成を抜本的に変える必要があるのか?』という疑問が残ります。 これに関しては、実は手段があります。それが 『Multus』と呼ばれるCNIプラグイン を活用する手法です。 このMultusを使用することで、上記で紹介した以下の構造を変えます。 Podは原則1つのネットワークアダプタしか保有できない 端的にいえば、Podに対して2つ目以降の仮想ネットワーク *3 アダプタを割り当て可能とし、その2つ目以降のネットワークは従来の仮想スイッチネットワークのようにVLANベースの通信に接続が可能となるという解決手法です。 www.redhat.com このMultusは、特にサーバ仮想化だけに使える特別なものではなくコンテナベースのPod環境でも使用可能であり、すでにいくつもの優れたブログ記事も多数存在します。 rheb.hatenablog.com 結論としては、仮想マシンに対しては次のようなネットワーク構成が可能といえます。 Podネットワークのみを使う PodネットワークとMultusにより実現された2つ目以降のネットワークの併用 Multusにより実現された2つ目以降のネットワークのみの使用 この構成の場合、以下のスライドの諸注意にあるように一部の機能が使用できなくなります speakerdeck.com 4. 使い慣れた機能が同等の機能として存在するかの確認 現在活用している仮想基盤で慣れ親しんできた機能がOpenShift Virtualizationにあるかどうか?これは新環境の採用を計画する際に非常に重要なポイントだといえます。 主に次のような機能については質問が多いように感じます。 仮想マシンを無停止で物理ホスト間で移行する機能 仮想マシンを無停止でストレージ間で移行する機能 仮想マシンが実行される物理ホストを、ルールを構成して制御する機能 仮想マシンへの通信について、許可拒否相当のポリシーを構成する機能 仮想マシンを実行するホストが障害などで停止時に、仮想マシンをフェイルオーバーする機能 ここに挙げられた機能は全てRed Hat OpenShift Virtualizationで利用可能です。 本記事掲載時点で、市場内でニーズが多いこともありVMware by BroadcomのvSphereの機能とOpenShift Virtualizationのどの機能が対応するかについては以下の資料で解説されています。 ※これらの情報ソースは都度更新されていくため、詳細はリンク先でご確認ください。 developers.redhat.com cloud.redhat.com www.redhat.com OpenShift Virtualizationに向けた情報収集テクニック これまで記事でお伝えしてきたように、OpenShift Virtualizationを支えるコアテクノロジーはコンテナオーケストレーションのためのKubernetesです。 下図で示すように、Kubernetesに対しRed Hatが特定の機能を追加し、さらにRed Hatの各種サービスを受けられるようにしたカスタムされたKubernetesがRed Hat OpenShiftです。 speakerdeck.com (Kubernetesは)オープンソースであり、かつ利用事例も多数あるため、 非常に情報が豊富であることが強み です。 しかし、 この情報の多さが時として落とし穴になる とも言えます。 インターネット上でKubernetesに関する文書や記事を探せば、多くの情報を得ることは可能です。しかし、 これらの情報が必ずしもRed Hat OpenShiftにもマッチするとは言えない ということです。いかにKubernetesがOpenShiftにとってのコアテクノロジーではあるとはいえ、Red Hat OpenShift向けに提供されている情報を参照することが望ましいです。 例えていうなら、RHEL上での特定の操作や機能について調べようと思った場合に、CentOS StreamやUbuntuなどの他のディストリビューションでの情報を用いて検索をすると、その検索結果がRHELにとって使えないかもしれない、というのに近いです。 さらに言えば、 Kubernetesで提供される機能の一部は仮想マシンには適用できない可能性があることも抑えておきたい です。 Kubernetesの登場における歴史を考えると、Kubernetes=コンテナのために登場したという背景があり、その機能は原則コンテナのために準備されたものであり、それらは 仮想マシンでの利用を想定していない わけです。 例えば、vSphere FT *4 のように仮想マシンを二重化して、片方の仮想マシンが停止をしてもシームレスにフェイルオーバーさせる構成を取りたい場合はコンテナベースのPodの場合はDeploymentと呼ばれるリソースがそれに近い *5 と言えます。 kubernetes.io では、もしvSphere FTと同じようなクラスタリングを構成したい場合はどうするかというと 『仮想マシンの間でクラスタリングを構成』 します。 Does OpenShift Virtualization support application clustering? Yes, the Red Hat Enterprise Linux (RHEL) High-Availability Add-on (Pacemaker) and Windows Server Failover Clustering (WSFC) are supported. 引用元 www.redhat.com 一見この考え方は、 『え、せっかくのハイパーバイザー環境なのに、それ自体の機能ではなく仮想マシンの中でクラスタリングを組むの?』 と思われるかもしれませんが、vSphereの環境などでも同じアプローチはあります。 VMware vSphereへのWSFCの導入方法 - VMware by Broadcom なお、RHELで仮想マシンを構成したい場合はHA Add-onを使用しますが、当社の社員により書かれた以下の記事でその詳細に解説がなされています。 qiita.com 本項目におけるポイントをまとめると次のようになります。 Kubernetesのために書かれた資料は、Red Hat OpenShiftにも適用可能なものとそうでないものに分かれる Red Hat OpenShiftのために用意された機能や情報は、OpenShift Virtualizationによって稼働する仮想マシンには適用されないものも存在する いかに情報が豊富にあるテクノロジーであるとはいえ、OpenShift Virtualizationで使用可能な技術やその情報は、適切に取得していく必要があるということです。 このことはRed Hatの公式ドキュメントを見てみればよくわかります。 こちらはRed Hat OpenShiftのためのドキュメントのトップページです。 docs.redhat.com こちらはRed Hat OpenShift Virtualizationのためのドキュメントのトップページです。 docs.redhat.com このようにページが分割されているため、適切に使い分けをするようにしましょう。 同じ名称、単語がついているからといって横着して検索精度を落とすような調べ方をすると後々痛い目を見ます。 あとがき ここまで、数多くの視点から『従来のハイパーバイザー環境からRed Hat OpenShift Virtualizationへの転換』にはいくつもの新しい視点を身につける必要があることを解説しました。 さて、本記事のタイトルにもあるように 数ヶ月で「OpenShift Virtualization Ready」 とあるように、実際にはどれくらいの時間が必要かというのを試算したものがこちらです。 最短プランは1ヶ月以内コース (実質1-2週間程度) 標準的なプランは3ヶ月以内コース 最短プランは1ヶ月以内コース (実質1週間程度) まず、最短プランについてはこちらをご覧いただきたいと思います。 OpenShift Virtualizationの基本は1週間で学習できるように 公式トレーニングが準備されています 上記で挙げている3種類のトレーニングコースがこちらです。 www.redhat.com www.redhat.com www.redhat.com まず最も最短と言える流れはDO156とDO256という2種類のトレーニングの受講です。 これはRed Hat OpenShift Virtualizationをこれから学ぶ方に向けて用意されたいわゆる基本コースであり、前半と後半のように分割されたものです。 Red Hatでは通常トレーニングクラスは原則1週間に1クラスの提供であるため、 試算としては2週間といういう計算 です。 一方でDO316というコースは、一見DO156とDO256を5日間(つまり約1週間)にまとめあげたコースに見えますが、実際の所やOpenShiftについて既に学習を終えている方を想定した作りとなっており、単純に2コースの合算コースとしてみるには少し厳しいところがあります。 また、DO156とDO256はOpenShiftについての基礎は含まれるかというと、これらについてもOpenShift Virtualizationを使用する上で最低限必要となる要素については触れる程度の感覚です。 もし将来的に仮想マシンだけではなく、コンテナベースでのワークロードの実行もOpenShift上で視野に入れたかったり、より一層Red Hat OpenShiftの多彩な機能の活用に興味を持っている場合は、更なるトレーニングコースの併用も視野に入れるべきです。それがこの後に続く標準的なプランです 標準的なプランは3ヶ月以内コース Red Hat OpenShiftについてしっかりと基礎から学びたい場合はDO180とDO280という2種類の公式トレーニングで学ぶことができます。 OpenShiftについても学習ステップを前半と後半に分けているためのコース分割です www.redhat.com www.redhat.com スライド内にも掲載していますが、Kubernetesの基礎スキルや知識を有した状態でこれらのコースを受講していただくことでより一層学習効果を高めることが期待できます。 理由としては、DO180もDO280もRed Hat OpenShiftが持つ固有の特性などの話もするため、時間の尺の都合上Kubernetesの基礎をゼロからお話しすると多少ビジーになるためです。 以下のように、無償で提供されるKubernetes入門コンテンツなども存在するため、もしRed Hat公式トレーニングをご受講いただく機会がある場合は、 事前にこうしたコンテンツも併用活用されるとより一層学習効果を高める ことが期待できます。 Linux Foundation、無料オンラインコース「Kubernetes入門」の提供を開始 - The Linux Foundation そして、上記のDO180やDO280を受講し終えた後に最初に挙げたDO316を受講することで一旦はOpenShift Virtualizationに対しReadyと成れます。 さらに次の要素が必要な場合は追加のトレーニングコースも準備されています。 Red Hat OpenShiftが持つSoftware Defined Storage機能を使用する *6 場合はDO370 www.redhat.com Red Hat OpenShiftが持つより高度な機能を学びたい場合はDO380 www.redhat.com このように、構成や要件によっては+αも生まれ、これらも加味すると追加の2週間が発生する試算となります。 ここまでを振り返ると次のような数字となります。 DO180 4日間 - OpenShiftの基礎(運用編) DO280 4日間 - OpenShiftの基礎(構成編) DO316 5日間 - OpenShift Virtualizationの基礎 DO370 5日間 - 外部ストレージを使用する場合は不要 DO380 5日間 - 本コースで紹介する機能を使わない場合は不要 Red Hatが提供する各種トレーニングの日数の 単純な合算で言えば23日間 です。 ただし、実際の現場では23日間連続で受講対象者となる方を現場から抜けるかと言えばそれは難しく、これらの受講計画を仮に全て立てるとしても 数ヶ月に跨るトレーニング計画となることが一般的 でしょう。 さらに言えば、Kubernetesの基礎やRHELの基礎を身につけるために1ヶ月程度と考えてみると 概ね3ヶ月程度がOpenShift Virtualization Readyになるための現実的な期間 となるでしょう。 この3ヶ月という数字をどう見るかですが、Kubernetesベースの環境は学習コスト(特に時間と学ぶべき範囲)が未知数というイメージをお持ちの方が多い中、具体化された数字が出てくることは組織の成長戦略を立てる上で重要な参考値として働くと思います。   最後に、『Red Hat式の学習法』をお伝えするために次のスライド *7 をご紹介します。 Red Hatの公式トレーニングでは、次のものが提供されます。 コース内容を完全に網羅した専用テキスト(PDFとepubの2種がダウンロード可能) 講師による講義(オンライン開催と対面開催の2種) コースに対応した専用演習環境でのハンズオン 殆どの技術トレーニングは、講師や教科書からのいわゆるインプット学習に偏りがちですが、 Red Hatのトレーニングでは受講生によるハンズオンでのアウトプットを重要視 しています。 実際の職務の遂行にあたり、 手を動かせることは即戦力たる武器 となり、 他のエンジニアとの差別化 の要因としても強く機能します。 『知識があるだけのエンジニア』を目指すのではなく、 『手を動かせるエンジニア』を目指しましょう そして、その身につけたスキルをぜひ対外的にも示すことが出来る認定資格として形にしませんか? Red Hatでは、OpenShift Virtualizationに対するスペシャリストであることを証明するための資格試験と認定資格をご用意しています。 www.redhat.com もちろん私も本認定資格は取得済みであり、取得をすると次のようなデジタルバッジが発行されます。 www.credly.com 以上の内容をもち、本記事の締めとしたいと思います。   この記事の内容が、少しでもRed Hat OpenShift Virtualizationを活用した組織づくりのお役に立てば幸いです。 *1 : Kubernetesそのものに対する認識は、それを取り扱う人によって異なる解釈もあります。この記事では主に読者をサーバ仮想化系インフラエンジニアと想定してこの表現としています *2 : コンテナや仮想マシンの外装となるもので、Kubernetes管理プレーンによる管理対象 *3 : セカンダリネットワークと呼ぶ *4 : VMware vSphereで使用可能なRTO=0を実現するための仮想化ミラーリング機能、 保護可能な仮想マシンは仮想CPU8コアまでです *5 : コンテナにとってはメモリの情報は揮発的であるため、vSphere FTと同一とは言えません。あくまでも近いだけです *6 : 外部ストレージを使用しないケース *7 : このスライドは、本記事冒頭でご紹介しました2025年10月に開催されたRed Hat Summit Connectで使用したスライドであるため、スライド内のタイトルはこのブログ記事とは異なります。
Apache Camel Advent Calendar 3日目の記事は、サポート担当古市が担当します。 テーマは、「Camel 4 を学ぶ環境整備」 手元で動かしながら学ぶのが一番ですので、まずはツールの準備をしましょう。 JVM Maven jbang camel-jbang vscode Extension Pack for Apache Camel by Red Hat JVM 製品版となる Red Hat Build of Apache Camel ( RHBAC )では、推奨バージョンが記載されたアーティクルがあります。 無償で作成できる Red Hat アカウントをご用意いただければ、こちらの記事をご確認いただけるはずです。 access.redhat.com 極力、記載されているバージョンの JVM をご用意ください。 Maven RHBAC は、quickstart用サンプルも含め、mavenを使いビルドやデプロイ、実行を行います。まだ手元にない方は、ご用意ください。 maven.apache.org jbang(camel-jbang) Camel 3.x から登場した camel-jbang は、赤帽ブログでも何回か投稿されています。 rheb.hatenablog.com rheb.hatenablog.com rheb.hatenablog.com 製品版は、 Camel CLI という名称で紹介されています。 docs.redhat.com コミュニティーサイトは、やはり一番情報が充実しています。 camel.apache.org それぞれインストール方法が記載されておりますので、ご確認いただいた上でご用意ください。 vscode(Extension Pack for Apache Camel by Red Hat) 製品版では、IDE環境としては VSCode の使用を推奨しており、専用 Extension Packも提供しています。 docs.redhat.com marketplace.visualstudio.com Extension Pack には Camel Language support や専用デバッガーが含まれる他、GUIエディターとなる kaoto も含まれています。 kaoto については改めて投稿する予定なので、ぜひお楽しみにしてください。 明日の advent calendar 4日目では、「Camel Componentとの付き合い方」についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com
コンサルタントの織です。OpenShift Virtualization Advent Calendar 2025の2日目の記事です。OpenShift Virtualization (KubeVirt) において、仮想マシンのDHCPリクエストに誰が答えているのか、について調査した結果をまとめました。詳細は下記をご参照ください。 zenn.dev
Red Hatの森若です。 サポートへのお問いあわせを受けていると、実際にトラブルが起きたあとで「そもそも調査に必要な情報が取得されていなかった」「取得されたログやcoredumpなどが消えていた」というケースに遭遇することがあります。 今日はRHEL構築時にやっておくべき、トラブルシュートのための準備をまとめます。 sosreport 取得 sosreportはRHELのサポートをうける際に必須です。インストーラでMinimal Install等を選ぶとsosパッケージが入っていない場合があります。 sosパッケージを導入 dnf install sos でsosパッケージを導入します sosreportが取得できることを確認 LANG=en_US.utf8 sos report --batch を実行して/var/tmpにsosreportのアーカイブが作成されることを確認します 負荷の確認: sosreport取得時の CPUやI/Oへの負荷がサービス要件に対して許容範囲内かを確認します。 セキュリティ規定などで情報を隠すことが必要な場合は sos clean によるホスト名やIPなどのマスクの実施、マスクが十分かの確認なども行います。 ※マスクにより利用できる情報が減り調査の難易度が上がりますので、可能であれば生のsosreport利用が望ましいです。 運用手順へのsosreport取得組み込み 問題解消後ではなく、問題発生中に sosreportを収集することで調査に有用な情報が収集できます。 問いあわせ時にsosreportを最初から添付することで実質的な調査開始が早くなります。 基本的なパッケージの導入 トラブルシュートに利用される主なソフトウェアをあらかじめインストールしておきます。必要なものは利用ソフトウェアにより変わりますが、どこでも必要となりうるものとしては以下があげられます。 sysstat: 10分おきの統計情報保存 lsof: どのプロセスがどのファイルを利用しているかを確認 net-tools: ネットワークの情報取得 strace: システムコール呼び出しを記録 tcpdump: パケットキャプチャの取得 gdb: gcoreコマンドで実行中プロセスのcoredumpを取得 bind-utils: digコマンドによるDNS調査 kdump動作確認 カーネルパニックやハングアップ時にメモリ内容を保全するkdumpを設定します。 kdumpの有効化とテスト 表記は英語ですが Kdump Helper を利用すると簡単に設定できます。 NMIスイッチ押下により任意の時点でダンプを取得できることを確認します。 注意: echo c > /proc/sysrq-trigger のようなコマンドによる取得は実際の障害時に利用できない場合があります 「NMIスイッチ押下」はハードウェアや仮想化環境によりどのように実施するかが変わります。これらの手順をあらかじめ確認しておくことも大切です。 VMware環境であればkdumpのかわりに、スナップショットを取得することが可能です。 How to capture a vmcore of hung Red Hat Enterprise Linux VMware guest system with a snapshot or suspending VM ログの設定 journalの永続化設定 mkdir /var/log/journal && journalctl --flush で永続化します RHEL 7以降でシャットダウン処理をログへ記録するために必要な設定です プログラムが異常終了したらcoredumpを保存するよう設定をおこなう。 RHEL 7, 8, 9.0から9.4のデフォルトではプロセスが異常終了しても、coredumpが保存されません。 設定手順: How do I use systemd-coredump to collect crashing application core files? RHEL 9.5, 10.0以降はデフォルトでcoredumpを保存します。 /etc/systemd/coredump.conf の設定を変更 プロセスのメモリサイズが大きい場合、デフォルトではcoredumpを取得しない場合があります。 保存することが重要な場合ProcessSizeMaxとExternalSizeMaxに実際のメモリ総量を上限として設定します。(反対に少なくするのは、coredump取得によるストレージI/O発生を抑制したい場合。) 複数回coredumpが発生したときにcoredumpが利用していいストレージサイズの上限をMaxUseに設定します。 ※(メモリ128GB, ストレージは500GBまで使っていい場合の例) ProcessSizeMax=128G ExternalSizeMax=128G MaxUse=500G coredumpの保存期間を延長 RHEL 9.4までのデフォルトの保存期間は3日です。 RHEL 9.5からは14日になりました。 障害発生から、実際に解析するまで最大どれくらいの期間が想定されるかにもとづいて十分長い期間に変更します。 変更手順: Why coredump gets deleted in RHEL 8/9 in 3 days? その他 パッケージの追加・更新手順を決めておく。 パッケージ更新をして問題が再現するかにより既知の問題か、未知の問題かを切り分けるため必要です。 おわりに トラブルは起きないのが一番ですが、起きてしまった時に「何も情報がない」状態では調査や解決は見込めません。 システム構築時のチェックリストとして、これらの設定をぜひ組み込んでみてください。
Red Hat のソリューションアーキテクトの瀬戸です。 これは Jakarta EE / Java EE Advent Calendar 2025 の二日目の記事です。 昨日は @kazumura による 解説: Jakarta EE Developer Survey 2025 で 明日は @TTakakiyo による Open LibertyでJakarta EEをフレームワークとして使う #Java - Qiita です。 以前、 JBoss EAP 8.1 で新しくサポートされた起動可能なJAR(Bootable jar)とGalleonによるサーバーの軽量化を試す - 赤帽エンジニアブログ という記事でJBoss EAPで起動可能なjar(uber-jar)がサポートされたよ!ということをご紹介させてもらいました。 その時にどうやって設定するの?standalone.xmlはどうやって変更するの?と質問を受けたので今回はそちらの方法を書きます。 簡単に言うと、pom.xmlにpackaging-scripts属性を追加し、実行するスクリプトを指定する事で、構成を変更することができます。 packageing-scriptの書き方の例( JBoss EAPのドキュメント: JBoss EAPのプロビジョニング より) <configuration> ~~~ <packaging-scripts> <packaging-script> <scripts> <script> ../scripts/script1.cli </script> </scripts> <commands> <command> /system-property=foo:add(value=bar) </command> </commands> <properties-files> <property-file> my-properties.properties </property-file> </properties-files> <java-opts> <java-opt> -Xmx256m </java-opt> </java-opts> <!-- Expressions resolved during server execution --> <resolve-expressions> false </resolve-expressions> </packaging-script> </packaging-scripts> ~~~ </configuration> 実際の例で試してみます。 待ち受けするポートを18080に、管理画面のポートを19990に変更します。 <packaging-scripts> <packaging-script> <commands> <command> /socket-binding-group=standard-sockets/socket-binding=http:write-attribute(name="port",value="18080") </command> <command> /socket-binding-group=standard-sockets/socket-binding=management-http:write-attribute(name="port",value="19990") </command> </commands> </packaging-script> </packaging-scripts> これを、 JBoss EAP 8.1 で新しくサポートされた起動可能なJAR(Bootable jar)とGalleonによるサーバーの軽量化を試す - 赤帽エンジニアブログ で使用したpom.xmlに追記して実行します。 ビルド中に指定したスクリプトが実行されることが確認できます。 ビルド中のスクリプトの実行 出来上がったjarを実行すると実際にポートが変更されていることが確認できます。 HTTPポートが18080に変更されている ということで、簡単にですが、JBoss EAPで起動可能なjarを指定したときに設定を変更する方法を紹介させてもらいました。 現時点では構築済みの設定ファイル(standalone.xml)を直接指定する方法は提供されていないようです。 必要とされているお客様は サポートチャンネル を通じてご連絡ください。 参考 第3章 JBoss EAP Maven プラグインを使用したサーバーのプロビジョニング | JBoss EAP のプロビジョニング | Red Hat JBoss Enterprise Application Platform | 8.1 | Red Hat Documentation A.3. JBoss EAP Maven プラグインの設定パラメーター | JBoss EAP のプロビジョニング | Red Hat JBoss Enterprise Application Platform | 8.1 | Red Hat Documentation
Apache Camel Advent Calendar 2日目の記事は、サポート担当古市が担当します。 テーマは、「Camel の歴史と今」 今回は、コミットから Camelの歴史を辿ります。 Apache Camel の first commit は、 2007/3/19 まで遡ります。 % git log --reverse commit 77b260b65ba821b3443d922320cc3d9b708c8d83 Author: James Strachan <jstrachan@apache.org> Date: Mon Mar 19 10:54:57 2007 +0000 Initial checkin of Camel routing library git-svn-id: https://svn.apache.org/repos/asf/activemq/camel/trunk@519901 13f79535-47bb-0310-9956-ffa450edef68 記事公開日時点(2025/12/2)では、 約18年 となりますので、Camel は歴史の長い Java Integration ライブラリーとなります。 Red Hat Fuse 6.x , 7.x のベースとなった Camel 2.x について確認してみます。 camel-2.0.0 は 2009/8/24 にリリースされています。 % git show camel-2.0.0 tag camel-2.0.0 Tagger: Hadrian Zbarcea <hadrian@apache.org> Date: Mon Aug 24 13:38:52 2009 +0000 camel-2.25.4 が  2.x 最後のリリースとなります。 % git show camel-2.25.4 tag camel-2.25.4 Tagger: Gregor Zurowski <gregor@zurowski.org> Date: Mon May 24 15:25:15 2021 +0000 2021/5/24 にリリースされているので、 Camel 2.x は 約12年間 メンテナンスされたメジャーバージョンとなります。 Camelの主要開発者が多数在籍した Fusesource社が Red Hat社により買収 されたのは、 2012/6/27 。改めて振り返ると、買収による悪影響もなく、Camelの開発/運営は継続されました。 その後、クラウド環境に順応する為に大幅な刷新が行われました。それが 2019/11/24 リリースの Camel 3.x となります。 % git show camel-3.0.0 tag camel-3.0.0 Tagger: Gregor Zurowski <gregor@zurowski.org> Date: Sun Nov 24 09:46:26 2019 -0800 3.x の大幅変更については、いくつか記事が公開されています。 rheb.hatenablog.com rheb.hatenablog.com 3.x 最後のリリースは 3.22.4 となります。 % git show camel-3.22.4 tag camel-3.22.4 Tagger: Gregor Zurowski <gregor@zurowski.org> Date: Wed Mar 5 20:49:10 2025 +0000 2025/3/5 リリースなので、 3.x は 約6年間 メンテナンスされたメジャーバージョンとなります。 2.x と比べると短い期間(それでも約6年間はメンテナンスされています)で 4.x の開発がスタートしていますが、以下の目的が主な要因です: Apache Camel 4 What's New (top 10) - Apache Camel Java EE から Jakarta EE への移管に伴う修正 サポート JDK を、Java 17 以上へ Spring Boot3 対応 Quarkus3 対応 4.0.0 は 2023/8/9 にリリースされ、現在に続きます。 % git show camel-4.0.0 tag camel-4.0.0 Tagger: Gregor Zurowski <gregor@zurowski.org> Date: Wed Aug 9 19:57:20 2023 +0000 Apache Camel の歴史を振り返ると、 過去18年 の中で 最大のターニングポイント と言えるリリースは、 2019/11/24 の Camel 3.x リリースでしょう。 クラウド環境への順応を意識した取り組みは、 2019年 から今日までの 約6年間 続いています。 明日の advent calendar 3日目では、「Camel 4 を学ぶ環境整備」 についてご紹介します。 アドベントカレンダーの一覧はこちらです。 qiita.com