Oracle Linuxには2種類のカーネルがあります。それはRHEL互換カーネルと呼ばれるRed Hat Compatible Kernel(RHCK)と、Oracle Linux独自のUnbreakable Enterprise Kernel(UEK)です。
いままでOracle Linuxを使ったことがないと、Unbreakable Enterprise Kernelに不安を感じるかもしれません。そこで今回はUnbreakable Enterprise Kernelについて解説すると共に、互換性や使い分けの判断基準などを説明します。
Red Hat Compatible KernelとUnbreakable Enterprise Kernel
基礎知識として、Red Hat Compatible KernelとUnbreakable Enterprise Kernelの概要を説明します。
Red Hat Compatible Kernelとは
Red Hat Compatible Kernel(RHCK)とは、その名の通りRHELカーネルのソースコードをリビルドしただけのRHEL互換カーネルです。リビルドしただけなので、バージョン番号が同じであればバグも含めてRHELと同じ挙動です。
次の表はOracle LinuxのメジャーバージョンごとのRHCKとglibcのバージョンです。同一Linuxメジャーバージョン内は互換性を重視して、kernelやglibcなどの重要コンポーネントのベースバージョンは変更しません。その代わり、アップデートがあるときは、次の説明するようにリリース番号を変更します。
Linuxバージョン | RHCKバージョン | glibcバージョン |
---|---|---|
Oracle Linux 9 | 5.14.0 | 2.34 |
Oracle Linux 8 | 4.18.0 | 2.28 |
Oracle Linux 7 | 3.10.0 | 2.17 |
次の図はkernelとglibcのRPMパッケージ名を表したものです。アップデートパッケージをリリースするときは、ベースとなるVersionは変わらずReleaseが更新されます。
図1 kernel/glibcのVersionとRelease
Unbreakable Enterprise Kernelとは
Unbreakable Enterprise Kernel(UEK)は、RHCKより新しいカーネルをベースとしたOracle Linux独自のカーネルで、RHCKと互換性があります。特徴としては以下のマニュアルの記述が参考になります。
公式ドキュメント Unbreakable Enterprise Kernel
The Unbreakable Enterprise Kernel (UEK) is a Linux kernel built by Oracle and supported through Oracle Linux support. Its focus is performance, stability, and minimal backports by tracking the mainline source code as closely as is practical. UEK is well-tested and used to run Oracle’s Engineered Systems, Oracle Cloud Infrastructure, and large enterprise deployments for Oracle customers.
Database Installation Guide for Linux
The Unbreakable Enterprise Kernel is included and enabled by default in Oracle Linux kernels. It is based on a recent stable mainline development Linux kernel, and also includes optimizations developed in collaboration with Oracle Database, Oracle middleware, and Oracle hardware engineering teams to ensure stability and optimal performance for the most demanding enterprise workloads.
おもなポイントは次の点です。
- UEKはLinuxカーネルで、Oracleが開発およびサポートしている
- Oracle Linuxのデフォルトカーネルである
- メインラインLinuxカーネルの新しいstable版をベースにしている
- パフォーマンスや安定性にフォーカスし、ExadataやOracle Databaseのチームとコラボレーションして開発
- ExadataやOracle Cloud Infrastructureなどの大規模エンタープライズワークロード環境でテスト済み
Oracle Linuxとカーネルバージョンの関係
UEKはベースとするカーネルごとにバージョン番号が変わり、UEK6やUEK7のように命名されます。また、RHCKとの大きな違いは、Oracle LinuxのメジャーバージョンとUEKのバージョンを固定化しないことです。次の表はUEKとOracle Linuxの対応表です。この表からわかるように、Oracle Linux 8はUEK6とUEK7を使用できます。
UEKバージョン | カーネルバージョン | Oracle Linux 7 | Oracle Linux 8 | Oracle Linux 9 |
---|---|---|---|---|
UEK7 | 5.15.0 | × | ○ | ○ |
UEK6 | 5.4.17 | ○ | ○ | × |
UEK5 | 4.14.35 | ○ | × | × |
UEK4 | 4.1.12 | ○ | × | × |
次の表はOracle Linuxにおける、RHCKとUEKのカーネルバージョンを比較したものです。Oracle Linux 9は2022年リリースと新しいためRHCKとUEKのバージョン差は少ないです。しかし、Oracle Linux 7やOracle Linux 8ではリリースしてから時間がたっているため、RHCKとUEKのバージョン差が開いています。
Linuxバージョン | RHCK | UEK |
---|---|---|
Oracle Linux 9 | 5.14.0 | 5.15.0 |
Oracle Linux 8 | 4.18.0 | 5.4.17, 5.15.0 |
Oracle Linux 7 | 3.10.0 | 4.1.12, 4.14.35, 5.4.17 |
Linuxカーネルバージョンの命名規則
ここまでLinuxカーネルのバージョンについて説明してきました。ここで、あらためて命名規則を振り返ってみましょう。実のところ、いままで何度か変更されていることや、オリジナルのkernel.orgとLinuxディストリビューションでは命名規則が少し違うため、絶対的なものは存在しません。
kernel.orgでの命名規則
まずはLinuxカーネルの公式サイトkernel.orgでの命名規則です。Linuxカーネルは「a.b.c」のように命名され、それぞれ次のように呼ばれます。ただし、この呼び方は絶対的なものではありません。
a:メジャーリリースナンバー
b:マイナーリリースナンバー
c:パッチナンバーもしくはリビジョンナンバー
また、5.19の次は6.0ですが、機能が大きく変わったからではありません。単にbの数字が大きくなりすぎるのは好ましくなく、おおむねbが20くらいになったら、aをカウントアップするという慣習によるものです。そしてcがバグフィクスなどのパッチレベルの修正です。そのため現在は「a.b」もしくは「a.b.c」を合わせてリリースナンバー(リリース番号)もしくはバージョンナンバー(バージョン番号)と呼ぶのが一般的です。
次の図でMajor Releaseに取り消し線が引いてあるのは、現在ではあまり使われなくなったためです。ただし、明示的に1つ目の数字を指したいときには使用します。
図2 Linux Kernelバージョンの命名規則
次の図を見てください。Linuxカーネルの開発ヒストリーです。灰色の部分が開発期間で、一定期間を過ぎると次のバージョンに開発は移ります。つまり特定のLinuxリリース「a.b.c」は「開発→サポート→数回に一度LTS(Long Time Support)」というライフサイクルを繰り返します。なお、LTSカーネルは1年に一度リリースされ、5年程度サポートが続きます。
引用元:https://en.wikipedia.org/wiki/Linux_kernel_version_history
図3 Linux Kernel Version History 6.x
図4 Linux Kernel Version History 5.x
Linuxディストリビューションでの命名規則
Linuxディストリビューションとkernel.orgでは命名規則は少し違います。Linuxディストリビューションのカーネルは「a.b.c-z」のように命名され、実際にはcがゼロで「a.b.0-z」となるディストリビューションが主流です。RHELだけでなくUbuntuも同じで、UEK7以降も同様です。
次の図はLinuxディストリビューションにおけるカーネルバージョンの呼び方を表したものです。現在のところ共通した認識は無く、使う文脈や人によって異なるようです。
図5 Linuxディストリビューションにおける呼び方
初登場の用語としてベースバージョン(Base Version)があります。これは元にしたkernel.orgのバージョンを示しています。ただし、cの数字は強制的にゼロなので、ベースバージョンが5.15.0のとき元にしたカーネルバージョンが5.15.0とは限りません。たとえば、UEK7は5.15.0というバージョンですが、元になっているのは5.15.6です。
$ rpm -q --changelog kernel-uek-5.15.0-105.125.6.2.2.el9uek | tail -n 2
- Linux 5.15.6 (Greg Kroah-Hartman)
mainline、longterm、stable、rcの関係
Linuxカーネル本家The Linux Kernel Archivesのページを見てみましょう。複数のLinuxカーネルバージョンが並び、mainlineやlongterm、stable、rcなどと書かれています。それぞれについて説明します
図6 The Linux Kernel Archives
kernel.orgから一部のカーネルバージョンを抜粋し、コメントを加えたのが次の図です。開発の主体がmainlineです。rc(release candidate)が取れると正式版となるため、mainlineとstableは同じ状態を指します。stable版のうち、数バージョンに一度longtermとなって長期間サポートされます。
図7 kernel.orgにおけるライフサイクル
バックポートとは
ここで覚えていただきたい言葉があります。それはバックポート(backport,backporting) です。バックポートとは、新しいバージョンのソフトウェアに含まれる機能や修正を、古いバージョンのソフトウェアに適用することを指します。
たとえばバージョン6.0で新たに取り込んだパッチを、バージョン5.0に適用することをバックポートと言います。一般に両者のバージョンが離れるほど、コードベースの差が大きくなるので適用が困難になります。また、古いバージョンでは該当のバグが存在せず、バックポートが不要なこともあります。
バックポートの反対語は何だろうと気になる方もいるかもしれません。たとえばバージョン5.0のソフトウェアのバグフィクスを、より新しい6.0のソフトウェアに適用するケースです。いろいろ調べたのですが共通した用語はなく、backport、merging、forward-portingなどが使われるようです。あまり気にせずバックポートと呼んでいるかたも多いように感じます。
次の文章は、冒頭で紹介したUEKの説明文の一部です。
Its focus is performance, stability, and minimal backports by tracking the mainline source code as closely as is practical.
これまでに説明したことと合わせて考えると、Oracle社は次の主張をしていると言えます。
- 新しいメインラインソースコードを元にしたほうが、新機能やバグフィクスをより多く取り込んでいるので、パフォーマンスや安定性に優れている可能性が高い
- 新しいメインラインソースコードを元にしたほうが、ソースコードの差が少ないので、最少のバックポートで済む
Linux内部構造の基礎知識
UEKで、もっとも気になることの一つはRHELカーネル(RHCK)との互換性でしょう。互換性を理解するにはLinux OSに対する知識が不可欠です。そこでLinux内部構造の基礎知識を説明します。
Linux OSの主要コンポーネント
次の図はLinux OSの主要コンポーネントと、それぞれの関係を表した図です。Linux OSを理解するうえで重要なので、ぜひ覚えてください。
- Linuxカーネル
カーネルはLinux OSのコアコンポーネントです。アプリケーションからの要求を受け、プログラムを実行するために、プロセス管理やメモリ管理を行います。また、カーネルモジュールであるデバイスドライバを利用して、ファイルシステムの管理やI/Oのためデバイスを制御します。 カーネルの役割をまとめると次のとおりです。ハードウェアに働きかける機能と理解するとよいでしょう。- CPU/メモリ/ディスク/ネットワークカードなどのハードウェアの資源管理
- Linux上で動作するアプリケーションのプロセス管理・制御
- カーネルモジュール
カーネルモジュールは、カーネルの機能を拡張するバイナリファイルです。おもにデバイスドライバで、必要なときにロード可能な形式になっています。このような仕組みによって、ドライバを追加するだけで新しいハードウェアに対応できるだけでなく、メモリを削減できます。 - システムライブラリ
システムライブラリ(単にライブラリとも言う)は、プログラムがよく使用する関数の集まりで、オペレーティングシステムが提供するほとんどの機能を提供しています。もっとも有名なのがglibcで、Linuxで使用する標準Cライブラリです。 元々はGNUが開発したGNU C Libraryなのでglibcと呼ばれます。
図8 Linuxの内部構造
基本的な動きを理解する(ライブラリ関数とシステムコール)
図8のアプリケーションは、OS標準で含まれているコマンドやユーティリティなども含めた、さまざまなプログラムを指します。これらのプログラムは、ライブラリ関数やシステムコールを呼び出すことでプログラムとして動作します。それぞれの違いを理解しましょう。
「ライブラリ」は/lib64
や/usr/lib
などにインストールされています。nm
コマンドでglibcのシンボル情報を表示すると、printf()
が含まれていることがわかります。シンボル情報とは、ライブラリや実行プログラムに含まれる関数や変数のことです。
printf()
は引数で与えた通りに動作し、必要があればカーネルに指示を出します。
$ rpm -qf /lib64/libc.so.6
glibc-2.34-60.0.3.el9.x86_64
$ nm /lib64/libc.so.6 | grep "T printf"
000000000006f430 T printf
000000000006e8f0 T printf_size
000000000006f350 T printf_size_info
「システムコール」はファイルの入出力や新しいプロセス生成、ネットワーク通信などハードウェアを操作する機能を提供します。図8では、アプリケーションから直接システムコールを呼び出しています。しかし、glibcに含まれるシステムコールのラッパー関数経由で呼び出すこともあります。
ここまで読んでみていかがでしょうか。glibcを初めとするライブラリ群がとても重要なことがわかります。そのためにRHEL系ディストリビューションでは、メジャーバージョンが変わるまでは、glibcのバージョンも変更しません。
カーネルモードとユーザーモード
カーネルモードとユーザーモードについて説明します。
カーネルやデバイスドライバなどハードウェアリソースにアクセスするプログラムは「カーネルモード」という特別な特権モードで実行されます。CPUの保護機能を利用した単一で独立したメモリ空間で実行され、コンテキストスイッチが不要なため、非常に高速に動作します。カーネルは各プロセスを実行するだけでなく、ハードウェアへの保護されたアクセスを提供します。
それに対して一般的なプログラムは、「ユーザーモード」というメモリ空間で実行されます。ユーザーモードで動作するプログラムはハードウェアに直接アクセスできません。そのためシステムコールを介してカーネル機能にアクセスし、カーネルが最終的にハードウェアにアクセスします。
基礎知識まとめ
ここまで説明してきたLinux内部構造の基礎について簡単にまとめます。
- カーネルもglibcもLinuxの重要コンポーネントだが役割は異なる
- カーネルはハードウェアを制御する役割を担っている
- ライブラリは一般的なプログラムが使用する関数を提供している。ライブラリでもっとも重要なのはglibcである
- ハードウェアにアクセスするにはシステムコールを呼び出す必要がある
- プログラムは、システムコールもしくはライブラリ関数を経由してハードウェアにアクセスしている
コンテナが動く仕組み
次にコンテナについて説明します。カーネルの説明をしてきたのに「なぜコンテナ?」と不思議に思うかもしれません。それは、コンテナの仕組みを理解することは、カーネルの互換性を理解する題材として適しているからです。
コンテナの構造
次の図は、ハイパーバイザー型とコンテナ型の仮想化を比較したものです。仮想マシンにはゲストOSがありカーネルも含まれています。それに対してコンテナに含まれているのはアプリケーションとライブラリだけです。カーネルは含まれていません。
図9 ハイパーバイザ型とコンテナ型の違い
コンテナ内にカーネルが不要な理由は、ホストOSにあるカーネルを利用しているからです。コンテナはLinuxのcgroupsやNamespaceなどの機能を利用してコンテナ同士を分離していますが、ホストOS上で動作するプロセスに過ぎません。次の図を見てください。コンテナにはアプリケーションを実行するのに必要なライブラリやプログラムが含まれていれば動作します。
図10 コンテナが動作する仕組み
Linuxカーネルの互換性
ここで重要なことがあります。
コンテナイメージを作成したOSと、ホストOSのLinuxバージョンが異なっても動作します。
たとえば、コンテナエンジンが動作するホストOSがUbuntu Server 22.04 LTSだとします。このときコンテナイメージをOracle Linux 9で作成しても、必要なライブラリやバイナリが含まれていれば動作します。どちらもLinuxの必要はありますが、Linuxカーネルのバージョンが多少異なっても動作します。
ただし、これは技術的に動作するかの話であり、ベンダーの技術サポート対象の有無とは関係ありません。
図11 Linuxカーネルの互換性
もう少し詳しく説明します。次の図12を見てください。Linuxのシステムコールにおけるアプリケーションとカーネル間のインターフェイスをApplication Binary Interface(ABI)と呼びます。Linuxカーネル開発では、以前のバージョンから存在するシステムコールを同じ仕様で呼び出せるように互換性に配慮して開発しています。そのためLinuxカーネルのバージョンが多少違っても、アプリケーションは同じように動作します。
図12 Application Binary Interfaceによる互換性の維持
Application Binary Interface(ABI)
ABIはインターフェイス定義であり、具体的には、システムコール名や引数のデータ型、引数の数、戻り値のデータ型や値などです。これらを変更しないようにLinuxカーネルは開発されています。ABIが変わらなければ、システムコール呼び出しでエラーになることはありません。
ただし、カーネルバージョンが異なれば、システムコールの内部実装は異なる可能性はあります。しかし、システムコールは「ディスクにデータを書き込む」「メモリ確保する」などハードウェアに対するプリミティブな命令です。そのため外的な振る舞いも変わらないようにしています。それによって互換性が保たれています。
図13 ABIで維持されている互換性
非互換性で注意すること
逆に非互換性で注意することは何でしょうか。次の図14を見てください。それはデバイスドライバなどのカーネルモジュールです。カーネルのバージョン番号は一致しても、末尾のリリース番号が異なれば動作しない可能性があります。カーネルモジュールによっては、多少のリリース番号違いは吸収できることもありますが、再コンパイルが推奨されています。
カーネルとは関係ありませんが、アプリケーションの互換性で注意するのは、言語やフレームワークなどで使用するライブラリがあります。ライブラリは頻繁にバージョンアップされることが多く、○○○ライブラリ2.0以上などの制限があることは一般的です。
図14 カーネルモジュールの非互換性
UEKとRHCKの比較
これまでさまざまな基礎知識を説明してきたので、ようやく本題の比較です。互換性と機能を比較します。
RHCKとの互換性
UEKとRHCKの互換性です。ここまで読まれたかたは、わかっているのではないでしょうか。UEKはRHCKとABI互換性を維持するように開発されています。そのためユーザーモードで動作する通常のアプリケーションであれば、互換性はあります。
ただし、いくつか注意点もあります。
商用ソフトウェア製品のサポート
一つ目は商用ソフトウェア製品のサポートの有無です。Oracle Linuxをサポートしている商用ソフトウェア製品でも、RHCKはサポートしていても、UEKをサポートしていないことがあります。実際のところ、ユーザーモードで動作するアプリケーションであれば、通常は問題なく動作するのですが、ベンダーのサポートポリシーを優先する場合にはRHCKを使用します。
互換性に注意する商用ソフトウェアとしてはアンチウイルス製品があります。アンチウイルス製品はカーネルモジュールとして動作するものもあるため、その場合には、対応していることを確認する必要があります。
日本製ソフトウェアは充実していませんが、Oracle Linux ISVカタログ
でOracle Linuxの対応を確認できます。
サポート対象ハードウェアの有無
有名メーカー製サーバーを利用するとき、もっとも注意することはOracle Linuxがサポート対象ハードウェアに含まれていることです。メーカーのサポート対象になっていない場合、何かトラブルが発生したときに対応してもらえない可能性が高いです。
また、サーバー機はRAIDコントローラーやNICなど、特殊なハードウェアを搭載しているため、メーカーが独自のデバイスドライバを提供していることもあります。サポート対象になっていない場合、これらのドライバを使用できない可能性があります。
メーカーのWebページやOracle Linuxハードウェア認定リストなどでサポート情報を確認します。それらのページにはRHCKやUEKのサポート状況も記載されています。
機能の違い
機能の違いを一般的に説明するのは難しいところです。なぜならば、カーネルのバージョンによって異なるからです。一般にUEKのほうが新しいメインラインカーネルをベースにしているので、性能は優れ、機能は多いと言えます。
たとえばOracle Linux 9では、UEK7のベースバージョンは5.15.0で、RHCKのベースバージョンは5.14.0です。現時点ではあまり変わりません。しかし、次の表のようにUEKは同一メジャーバージョンでも変わります。数年後にはOracle Linux 9用にUEK8がリリースされ、カーネルバージョンの差は広がるでしょう。
Linuxバージョン | UEK4 | UEK5 | UEK6 | UEK7 |
---|---|---|---|---|
Oracle Linux 9 | × | × | × | ○ |
Oracle Linux 8 | × | × | ○ | ○ |
Oracle Linux 7 | ○ | ○ | ○ | × |
UEKだけの機能として有名なところではocfs2やbtfsがあります。それ以外にもありますが、詳しくは「Unbreakable Enterprise Kernelのリリースノート」の「新機能および変更点」を確認してください。
図15 Unbreakable Enterprise Kernelリリース7 リリースノート
まとめ:UEKとRHCKの使い分け
UEKは、Oracle DatabaseやOracle Linux KVMの大規模ワークロードを考えて設計されています。また、より新しいカーネルをベースとしているので、性能面・機能面で優れていることが多いでしょう。
しかし、UEKが絶対ではありません。状況や目的に応じて、使い分けるべきものだと考えています。次の1や2の場合は、RHCKの利用を検討すべきでしょう。重要なことは、UEKとRHCKの違いを理解して適切に使用することです。また、これまで説明したことをまとめた表も紹介します。
- 物理サーバーを使⽤していて、メーカーのサポート対象がRHCKだけのとき
→RHCKを使用 - 商⽤ソフトウェアを使⽤していて、ベンダーがRHCKだけをサポートしているとき
→RHCKを使用したほうが好ましい。ただし、自社システムで利用し、リスクを許容できるのであればUEKもあり
UEKとRHCKを比較したときのメリット・デメリット
項目 | メリット | デメリット |
---|---|---|
機能・性能 | 比較するUEKとRHCKのバージョンに依存するが、UEKのほうが新しいメインラインカーネルを使用しているため、機能も性能も優れている可能性が高い。また、Oracle Database向けの最適化が施されていることがある。 | |
ユーザーモードで動作するアプリケーションの互換性 | 互換性あり | 商用パッケージ製品などの場合、ベンダーのサポートポリシーによってサポート対象外になることがある |
カーネルモードで動作するカーネルモジュール | ソースコード提供されているデバイスドライバなどは互換性がある可能性が高い | カーネルモードで動作するアンチウイルスソフトウェアやデバイスドライバなどは、原則として互換性なし |
その他 | 有名メーカー製サーバーでは、Oracle Linux(RHCK)をサポートしていてもUEKをサポートしていないことがある |