4月になりました。新年度・新学期のはじまりということで、新しいことにチャレンジする機会です。今回はRed Hatとその互換ディストリビューションに慣れている人向けに、Ubuntuに乗り換えるための基礎知識として、RHEL環境のパッケージ管理の常識をUbuntuに持ち込むための、少しマニアックなレシピをお届けします。
サポート期間と採用ソフトウェアの違い
RHELとその互換ディストリビューションのユーザーがUbuntuに手を出すにあたり問題になるのが、サポート期間の違いです。サーバー構築の現場では、一度構築してしまえばディストリビューションとしての寿命が尽きるまで使う、ということは決して珍しくありません。そして、RHELはLinuxディストリビューションの中でも、サポート期間の長いディストリビューションです。
RHEL5/6は10年間のサポート期間を持ち、フェーズによって差はあるものの、継続的にセキュリティアップデートやバグフィックスが行われます。このサポート期間は、エクステンドライフフェーズのための契約を結ぶことでさらに+3年され、計13年間 使い続けることができます。
互換ディストリビューションではエクステンドライフフェーズ部分には追従しないため[1] 、ベースとなる10年間のみになってしまいますが、それでもSLESの7年に比べても非常に長いものとなっています。ただし、RHELのリリース周期は2~3年に一度で、実際のサポート期間はこの数字よりは少なくなります。
この一方で、Ubuntuのサポート期間は通常のリリースで1.5年、LTSで5年です。LTSは2年ごとにリリースされるので、最短ケースでは3年強です。サポート期間という観点では、Ubuntuは非常に不利です。
また、Ubuntuの「サポート期間」が及ぶ範囲にも注意が必要です。Ubuntuにおいて、5年間のサポートが公式にコミットされているのは、事実上、mainに属するパッケージだけです。main以外のパッケージは、コミュニティ(要するに「有志」 )によるサポートや、「 リリースしたベンダのサポートに依存」という形で管理されます。main以外のリポジトリ、たとえばuniverseにあるパッケージを中心にサービスを構築してしまうと、最悪の場合、自分が「有志」としてパッケージを更新する必要が出てくるかもしれません。
ただし、Fedoraとしてリリースされてから厳密な検証を行い、長期間のリリースエンジニアリングを行った上でリリースされるRHELと異なり、UbuntuのLTSは比較的「生きのいい」ソフトウェアが含まれています。Linuxカーネルのバージョンで比較すると、RHEL6(2010年11月リリース)は2.6.30、Ubuntu 10.04(2010年4月リリース)は2.6.32です。RHELと比べると寿命が短いかわりに、新鮮なソフトウェアを使うことができる、ということがUbuntuの強みです。
もし現場でUbuntuを使う場合は、このあたりをきちんと理解しておく必要があります。
新規ハードウェアのサポート方法
RHELのリリースバージョンは、6.0→6.1→6.2……といった形で継続的に更新されていきます。この更新のタイミングでカーネルも新しいブランチに切り替わり、新しいハードウェアに対応していきます。たとえば、「 6.0ではサポートされていなかったデバイスが、6.1からは使えるようになる」ということです。
これに対してUbuntuでは、「 一度リリースされたものには、ドライバの追加は行われない」という対応が基本です。いくつかの例外はありますが、「 あるデバイスが動作しなかった場合、より新しいUbuntuのリリースを使う必要がある」ということです。サポート期間の違いもあり、一度構築したシステムに手を加えずにおいておき、より新しいハードウェアを調達したらそこでも同じように再現して使い続ける、という使い方は不向きだ、と言うこともできるでしょう。
いくつかある例外の一つは、RAID HBAのドライバです。そもそもストレージが認識されないとOSはインストールできないため、リリース後にも更新が行われる可能性があります。ただし、Ubuntuでは一度リリースしたISOイメージを更新することはないので、LTSリリース以外では意味がありません。LTSリリースに限り、「 10.04.1」と末尾に数字を付ける「ポイントリリース」が行われてISOイメージが更新されます。これは、「 その時点の最新のアップデート」を盛り込んだISOイメージです。たとえば10.04.4は、10.04を最新まで更新した状態をISOイメージに反映したものです。これを用いることで、新しいRAID HBAを搭載して動作させることができます。
なお、Ubuntuのリリースバージョンは、「 そのリリースが行われた年・月」を組み合わせたものです。2012年4月にリリースされたから12.04、といった形です。このバージョン文字列はあくまでもカレンダー上の数字を元にしたものですので、「 11.04と11.10はマイナーバージョンアップだが12.04はメジャーバージョンアップ」といった考え方ではありません。
まとめると、次のようになります。
RHELは6.0→6.1→6.2……と更新されるにつれて、ユーザランドはほとんど変わらずに[2] 対応ハードウェアが増えていく。
Ubuntuは8.04→8.10→9.04→9.10→10.04……と更新されていくが、それぞれ異なるリリースであり、ユーザランドは異なるものになる。LTSのみ、ポイントリリースを使うことでインストールCDが更新される。
[2] 厳密にはカーネル以外、ユーザランド部分も更新されるので「同じ環境で使い続けられる」かというと少々微妙なところです。完全に同じユーザランドで更新を受け取りたい場合、RHELはEUS(Extended Update Support)を使うことになります。
パッケージの管理
前振りはこのくらいにして、Ubuntuのパッケージ管理の特性を見ていきましょう。
RHEL環境のシステム管理において、yumとRPMを適切に使いこなすことは基本です。これと同じように、Ubuntu環境ではaptとdpkgを適切に使う必要があります。RHELで良く行われる操作のうち、特にUbuntuで気にするべき点を並べてみましょう。
パッケージのインストールと削除
RHELで利用するyumと、Ubuntuで利用するapt(apt-get, apt-cache)は、基本的な操作はほとんど同じです。yum install ( パッケージ名)とすることで依存するパッケージをまとめてインストールできるのと同じように、apt-get install(パッケージ名)を用いることができます。
パッケージの検索を行う場合は少々異なり、「 apt-get」のかわりに「apt-cache」を用いることになります。より詳しい点はman等を参照してください。
パッケージに含まれるファイルの一覧
RPM環境では、「 あるパッケージに含まれるすべてのファイル」を閲覧する場合は、「 rpm -ql ( パッケージ名) 」を用います。Ubuntuのようなdpkgベースのシステムの場合は、「 dpkg -L ( パッケージ名) 」を用います。
設定ファイルの待避
RPMを用いた環境で良く起きる事故は、「 設定ファイルを編集してシステムを動かしていたら、パッケージのアップデートで巻き戻ってしまった」というものです。
yum updateなどでRPMを更新すると、「 .rpmold」や「.rpmnew」をつけた形で設定ファイルが残される場合もありますが、たとえば/etc/logrotate.d/の下にあるファイルは問答無用で置き換えられてしまいます。致命的なのは「問答無用で」というところで、パッケージアップデートの前後で「本来想定していない変更」が加えられていないか、一通り確認する必要があります。
これは、「 conffile」として指定されていないファイルはすべて(≒RPMパッケージの作者が設定ファイルだと信じているものすべて)置き換えられる、というRPMの仕様によるものです。conffileに適切に指定を行っていない場合、RPMパッケージにスクリプト(rpm -q --scripts)を含めることで、適切に設定ファイルの待避を行う、というアプローチもありますが、いずれにせよパッケージの作者が適切に設定している、という前提が必要になります。
このため、RHEL環境の管理においては、設定ファイルを編集する前にまず「rpm -qc」を行ってconffileの一覧を確認し、編集しようとするファイルがconffileとして指定されていなければetckeeperなどで回避する、といった対処が必要になってしまいます。
Ubuntuの場合、こうした操作は必要ありません。/etc以下は暗黙で設定ファイルが配置される場所として認識されているため、これらのファイルを置き換える場合はapt-get upgrade実行時に確認が行われます。こうした「RPMパッケージがファイルを置き換えてしまう問題」へのバッドノウハウは、こと設定ファイルに関する限りは気にする必要がありません。
パッケージのソースファイルの入手
システム管理において、バグを発見した場合にはソースを確認したいことがあります。RHEL環境ではyumの設定を変更してSRPMを入手できるようにしておき、yumでSRPMを入手→rpm2cpioでcpio形式に変換、というのが基本的なソースの入手方法です。
Ubuntuの場合、apt-get source ( パッケージ名)とすることで自動的にパッケージのソースファイル群をダウンロードすることができます。dpkg-devパッケージを導入しておくと、ダウンロード完了後に自動的にソースが展開されます。
良く行われる作業
脆弱性情報の確認
RHELでは、特定のCVE-IDで示される脆弱性の影響を調査する場合はRed Hat Bugzilla で、CVE-IDを検索するのが普通です。これにより、Bug 796829 – CVE-2012-0879 kernel: block: CLONE_IO io_context refcounting issues などといった具体的なバグ情報が入手できます。
Ubuntuの場合、Ubuntu CVE Tracker を用いることで、特定の問題の影響を確認できます。
有償サービスの調達
RHELの場合はアップデートを入手する上で、RHN(Red Hat Network)の購読契約が必須です。RHNの契約を結ぶことで、パッケージのアップデートとテクニカルサポートを受けることができます。
Ubunutの場合、こうした契約なしにパッケージのアップデートを得ることができます。テクニカルサポートが必要な場合は、Ubuntu Advantageの契約を結ぶことで有償サービスを受けることができます。日本国内の場合はアシストが代理店です 。
バージョン情報の確認
Red Hat系のディストリビューションでは、/etc/redhat-releaseファイルを用いてリリースを確認するのが通常です。Ubuntuにはこれに該当するファイルはありません(厳密には/etc/debian_versionというファイルがあるのですが、これはベースになったDebianのバージョンを返すため、Ubuntuのリリースバージョンを調べるためには利用できません) 。
Ubuntu環境でバージョン情報を確認する場合、lsb_release -dを用いてください。
Ubuntuって何?
ここまで話してきて大変いまさらですが、「 Ubuntuがどういうものか」についてあらためて触れておきましょう。なぜ改めてこれを理解する必要があるかというと、UbuntuとDebian、そしてuniverseパッケージのありかたについて把握するために必要だからです。
Ubuntuは、Debian GNU/Linuxから派生したLinuxディストリビューションの一つです。作り込まれたデスクトップ環境と、独自のユーティリティを搭載したサーバー環境が強みです。
Ubuntuは「Debianベース」ではありますが、Debianとの完全な互換性はありません。Debian用のパッケージはUbuntuでは動かない可能性があります。
Ubuntuの大部分は、Debianのソフトウェアリポジトリに含まれるパッケージと同じソースをもとに、Ubuntu独自にビルドを行ったものです。最初に、なぜこうした処置が必要なのかを把握しておきましょう。教材は、Red Hatユーザーにはお馴染みの「互換ディストリビューション」です[3] 。
ソースを共用するディストリビューション
Red Hat Enterprise Linux(RHEL)「 系列」と呼ばれるディストリビューションには、本家にあたるRHELに加えて、「 互換ディストリビューション」と呼ばれるものが存在します。
こうした互換ディストリビューションは、Red Hat Enterprise LnuxのソースRPM(SRPM)を取得して、「 手元でビルド」したものを公開しているものです[4] 。Scientific Linux[5] ・CentOS・Oracle Linuxなどが該当します。
Index of /pub/redhat/linux/enterprise からSRPMを入手し、それらをコンパイルするためのビルドファームを作り出せば、理論上は(作業の膨大さを無視すれば)自分で同じようなディストリビューションを制作することもできるでしょう[6] 。
RHEL互換ディストリビューション特有の問題
互換ディストリビューションはその性質上、ビルドに失敗する可能性があります。ここで言う「ビルドの失敗」には、いくつかの意味があります。
典型的なものは、RHELのRPMとは異なる状態でビルドしてしまうことです。
SRPMからのパッケージビルドの何割かは、tarballからの「./configure; make; make install」と同じ処理をしています。./configureはシステム内に存在する各種ヘッダファイルやライブラリを認識して、ビルド時に有効にする機能を自動的に変化させることがあります[7] 。
これを引き起こすと[8] 、RHELのバイナリと機能が異なるバイナリが生成される可能性があります[9] 。
もうひとつの「失敗したビルド」は、「 バージョン番号を付け損なっている」ケースです。
現在のRHELでは、rpmbuild時に「dist」キーワードを与えてrpmbuildコマンドを実行することでパッケージをビルドします。これはFedora(バージョン文字列に「fcN」 )とRHEL(同じく「elN」を含む)の間でパッケージをやりとりする際、.specファイルを書き換えずに済むので非常に便利なのですが、もしもキーワードを与えずにビルドしてしまうと、本来期待されているものと異なるバージョン文字列を持ったパッケージができてしまいます。これにより、いくつかの互換ディストリビューションでビルドミスが生じたことがあります[10] 。この結果として、一部のディストリビューションではlibpngなどのパッケージのバージョンがRHELと食い違う、あるいは「yum-versionfix」プラグインを提供することでバージョン文字列の不整合を解決する、といった手法が用いられています。
Ubuntuが独自にビルドを行う理由
Ubuntuが独自にビルドを行っている理由も、こうした「同じソースを元にしているが、齟齬のあるソフトウェア」を作り出してしまう危険性からです。ただし、RHEL互換ディストリビューションとは理由が異なります。
UbuntuはDebianのパッケージとはまったく別に、いくつかの独自のパッケージや、独自にパッチを追加したパッケージを用意しています。カーネルもkernel.ubuntu.comで開発される独自のものを利用しています。また、Ubuntuのリリース時期は、Debianのものとは異なります。Ubuntuは「Debianの不定期なリリース(できあがった時がリリース日) 」というアプローチへの代替策として、「 定期的なリリース」を前提にしています。この結果、ソフトウェアの構成はDebianのものとは異なります。単にバージョンが違うだけでなく、準備されているライブラリの機能が違う、といったこともありえるかもしれません。
この結果、そのままではライブラリの不整合で問題を起こす可能性があります。Debianからバイナリをそのまま持ってくると、正常に動作しない可能性がある、ということです。
Ubuntuではこれを回避するため、Debianに含まれるパッケージをDebianからUbuntuのuniverseリポジトリへ「持ってくる」際(syncと呼びます) 、ソフトウェアをビルドし直しています。これにより、Debianとは違うバイナリ状態になる可能性はありますが(ビルド環境が揃っていないので、ビルドすると別のものができあがる) 、整合性が保たれた状態になります。これは、RHELに対するEPELのあり方によく似ています。EPELはFedoraのSRPMをリビルドしてRHELに持ち込んだもので、Ubuntuにおけるuniverseととてもよく似ている、と言えます。
まとめると、次のようになります。
RHELからRHEL互換ディストリビューションを作るプロセスと、DebianからUbuntuを作るプロセスはよく似ている。しかし、意図は異なる。
RHEL互換ディストリビューションは、「 Red Hatと完全に同じ状態」を作ろうとしている。
Ubuntuは、「 Debianとは全く違うが、整合性を持って動く状態」を作ろうとしている。