dnf コマンドでパッケージ形式とモジュール形式、二つのインストール形式を混在させようとした場合どうなるのか検証を行った結果、両者の違いについて理解を深められたので得られた知見について共有します。
背景
CentOS8 ではパッケージ管理に大きな変更がありました。
RedHat からリリースされるコンテンツは、 BaseOS と Appstream の二つのリポジトリから配信されるようになります。
特に Appstream では、従来のパッケージ形式のソフトウェア管理に加わる形で、新たにモジュールという概念が追加されました。
端的に言えばモジュールとは、サイズの小さなリポジトリの集合から構成されるもので、RPM をさらに拡張させた新たなパッケージ管理の仕組みです。
yum コマンドの使用感をそのままに新たな概念が導入された結果、dnf コマンドにはパッケージ形式とモジュール形式という二つのインストール形式が共存することになりました。
どっちも使うとどうなる?
ここでふと素朴な疑問が浮かびます。
パッケージとモジュール、両方から同じソフトウェアをインストールすると意図していない動作が起きたりするんじゃ……?
実際に検証を行い、dnf コマンドの挙動を確認しました。
検証項目
-
先にパッケージでインストールした後に……
1-a. 違うバージョンをモジュールでインストールする。
1-b. 同じバージョンをモジュールでインストールする。
1-c. モジュールのアンインストールを実行する。 -
先にモジュールでインストールした後に……
2-a. 違うバージョンをパッケージでインストールする。
2-b. 同じバージョンをパッケージでインストールする。
2-c. パッケージのアンインストールを実行する。
1. 先にパッケージでインストールした後に……
nginx 1.14 をパッケージインストールします。
"モジュールプロファイルのインストール"、"モジュールストリームの有効化"という見慣れない項目が yum から増えていますね。
検証 1-a, 1-b, 1-c では以下をインストールした状態をスタートとして、検証を行います。
$ sudo dnf -y install nginx
依存関係が解決しました。
=============================================================================================================================================================================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
=============================================================================================================================================================================================================================================
group/moduleパッケージをインストール:
nginx x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 570 k
nginx-all-modules noarch 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 23 k
nginx-filesystem noarch 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 24 k
nginx-mod-http-image-filter x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 35 k
nginx-mod-http-perl x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 45 k
nginx-mod-http-xslt-filter x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 33 k
nginx-mod-mail x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 64 k
nginx-mod-stream x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 85 k
モジュールプロファイルのインストール:
nginx/common
モジュールストリームの有効化:
nginx 1.14
1-a. 違うバージョンをモジュールでインストールする。
1.16 をモジュールとしてインストールしようとすると……できませんでした。
$ sudo dnf module install nginx:1.16/common
メタデータの期限切れの最終確認: 0:33:39 時間前の 2020年05月22日 02時29分55秒 に実施しました。
依存関係が解決しました。
オペレーションは、モジュール 'nginx' ストリーム '1.14' を ストリーム '1.16' へと切り替える結果となります
エラー: 有効化されたモジュールのストリームの切り替えはできません。
モジュールからすべてのインストールされたコンテンツを削除し、'dnf module reset <module_name>' コマンドを使用してモジュールをリセットすることを推奨します。モジュールのリセット後に、別のストリームをインストールできます。
パッケージとして nginx をインストールした際、1.14 のモジュールストリームが有効化されたためです。
モジュールストリームの有効化:
nginx 1.14
こうしてシステムにインストールされているバージョンを管理し、異なるバージョンが混在しないよう管理しているわけですね。
しかし、エラーメッセージを読む限り dnf module reset
コマンドで nginx モジュールをリセットすることによってモジュールの切り替えを行えるようです。
1.14 をインストールしたままモジュールストリームをリセットして 1.16 をインストールしようとしてみます。
$ sudo dnf module reset nginx
メタデータの期限切れの最終確認: 1:43:20 時間前の 2020年05月28日 08時18分52秒 に実施しました。
依存関係が解決しました。
=============================================================================================================================================================================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
=============================================================================================================================================================================================================================================
モジュールの再設定:
nginx
トランザクションの概要
=============================================================================================================================================================================================================================================
これでよろしいですか? [y/N]: y
完了しました!
$ sudo dnf module install nginx:1.16/common
メタデータの期限切れの最終確認: 1:43:32 時間前の 2020年05月28日 08時18分52秒 に実施しました。
依存関係が解決しました。
=============================================================================================================================================================================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
=============================================================================================================================================================================================================================================
アップグレード:
nginx x86_64 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 581 k
nginx-all-modules noarch 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 24 k
nginx-filesystem noarch 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 25 k
nginx-mod-http-image-filter x86_64 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 35 k
nginx-mod-http-perl x86_64 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 46 k
nginx-mod-http-xslt-filter x86_64 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 34 k
nginx-mod-mail x86_64 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 64 k
nginx-mod-stream x86_64 1:1.16.1-1.module_el8.1.0+250+351caf85 AppStream 91 k
モジュールプロファイルのインストール:
nginx/common
モジュールストリームの有効化:
nginx 1.16
トランザクションの概要
=============================================================================================================================================================================================================================================
アップグレード 8 パッケージ
ダウンロードサイズの合計: 900 k
これでよろしいですか? [y/N]:
nginx 1.16 へのアップグレードと、 1.16 ストリームの有効化が行われる結果になりました。なるほど、これなら不整合は起きません。
1-b. 同じバージョンをモジュールでインストールする。
さて、マシンの状態を nginx 1.14 パッケージインストール直後まで戻して今度は同じバージョンをモジュールインストールしようとしてみましょう。
$ sudo dnf module install nginx
CentOS-8 - AppStream 6.2 kB/s | 4.3 kB 00:00
CentOS-8 - Base 10 kB/s | 3.9 kB 00:00
CentOS-8 - Extras 3.9 kB/s | 1.5 kB 00:00
依存関係が解決しました。
=============================================================================================================================================================================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
=============================================================================================================================================================================================================================================
モジュールプロファイルのインストール:
nginx/common
トランザクションの概要
=============================================================================================================================================================================================================================================
これでよろしいですか? [y/N]:
rpm パッケージのダウンロードは行わず、モジュールプロファイルのインストールのみ行われるようです。
モジュール独自の概念として、ストリームの中には更にプロファイルという細かな区分が存在します。続々と用語が増えていきますがあまり難しいものではありません!
例えば、postgresql にはどんなプロファイルがあるのか見てみましょう。
$ sudo dnf module list postgresql
メタデータの期限切れの最終確認: 0:17:37 時間前の 2020年05月28日 10時22分19秒 に実施しました。
CentOS-8 - AppStream
Name Stream Profiles Summary
postgresql 9.6 client, server [d] PostgreSQL server and client module
postgresql 10 [d][e] client, server [d] [i] PostgreSQL server and client module
postgresql 12 client, server PostgreSQL server and client module
nginx には common プロファイルしかありませんでしたが、postgresql には client と server の2通りのプロファイルがあることが確認できます。同バージョン内の別々の機能を持つ rpm 群をプロファイルによって分けて提供しているわけですね。
話を nginx に戻します。dnf module -y install nginx
コマンドの実行前と実行後における dnf module list nginx
コマンドの出力結果について比較してみます。
$ sudo dnf module list nginx
メタデータの期限切れの最終確認: 0:00:56 時間前の 2020年05月28日 10時22分19秒 に実施しました。
CentOS-8 - AppStream
Name Stream Profiles Summary
nginx 1.14 [d][e] common [d] nginx webserver
nginx 1.16 common nginx webserver
ヒント: [d]efault, [e]nabled, [x]disabled, [i]nstalled
$ sudo dnf module list nginx
メタデータの期限切れの最終確認: 0:11:19 時間前の 2020年05月28日 10時22分19秒 に実施しました。
CentOS-8 - AppStream
Name Stream Profiles Summary
nginx 1.14 [d][e] common [d] [i] nginx webserver
nginx 1.16 common nginx webserver
ヒント: [d]efault, [e]nabled, [x]disabled, [i]nstalled
Profiles 列の 1行目、common に変化が見られます。実行前は common[d]
、実行後は common[d][i]
となっています。
[i]
は現在システムにインストールされているプロファイルを示すマークです。モジュールとして nginx 1.14 をインストールしたことによって、 nginx モジュールの 1.14 ストリーム中の common プロファイルがインストールされたとシステムに認識されたようです。
1-c. モジュールのアンインストールを実行する。
パッケージインストールを行った後にモジュールのアンインストールコマンドを実行するとどうなるか確認してみましょう。
$ sudo dnf module remove nginx
メタデータの期限切れの最終確認: 0:10:29 時間前の 2020年05月28日 11時21分52秒 に 実施しました。
引数 nginx でプロファイルを一致できません
依存関係が解決しました。
行うべきことはありません。
完了しました!
$ rpm -qa | grep nginx
nginx-mod-http-perl-1.14.1-9.module_el8.0.0+184+e34fea82.x86_64
nginx-all-modules-1.14.1-9.module_el8.0.0+184+e34fea82.noarch
nginx-mod-mail-1.14.1-9.module_el8.0.0+184+e34fea82.x86_64
nginx-mod-stream-1.14.1-9.module_el8.0.0+184+e34fea82.x86_64
nginx-1.14.1-9.module_el8.0.0+184+e34fea82.x86_64
nginx-mod-http-image-filter-1.14.1-9.module_el8.0.0+184+e34fea82.x86_64
nginx-filesystem-1.14.1-9.module_el8.0.0+184+e34fea82.noarch
nginx-mod-http-xslt-filter-1.14.1-9.module_el8.0.0+184+e34fea82.x86_64
おや、どうやらモジュールとしてインストールされている認識ではないのでこの方法では何もしてくれないようです。
dnf remove
ならアンインストールしてくれますね。
$ sudo dnf remove nginx
依存関係が解決しました。
================================================================================
パッケージ Arch バージョン Repo サイズ
================================================================================
削除中:
nginx x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 1.7 M
未使用の依存関係の削除:
nginx-all-modules
noarch 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 0
nginx-filesystem
noarch 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 0
nginx-mod-http-image-filter
x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 29 k
nginx-mod-http-perl
x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 61 k
nginx-mod-http-xslt-filter
x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 25 k
nginx-mod-mail x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 113 k
nginx-mod-stream
x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 171 k
トランザクションの概要
================================================================================
削除 8 パッケージ
解放された容量: 2.0 M
これでよろしいですか? [y/N]:
2. 先にモジュールでインストールした後に……
検証 2-a では nginx の代わりに postgresql を使用します。(詳細は後述)
検証 2-b, 2-c では nginx 1.14 をインストールした状態をスタートとして検証を行います。
$ sudo dnf module -y install nginx
メタデータの期限切れの最終確認: 0:29:16 時間前の 2020年05月28日 11時21分52秒 に実施しました。
依存関係が解決しました。
=============================================================================================================================================================================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
=============================================================================================================================================================================================================================================
group/moduleパッケージをインストール:
nginx x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 570 k
nginx-all-modules noarch 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 23 k
nginx-filesystem noarch 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 24 k
nginx-mod-http-image-filter x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 35 k
nginx-mod-http-perl x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 45 k
nginx-mod-http-xslt-filter x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 33 k
nginx-mod-mail x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 64 k
nginx-mod-stream x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 AppStream 85 k
モジュールプロファイルのインストール:
nginx/common
モジュールストリームの有効化:
nginx 1.14
2-a. 違うバージョンをパッケージでインストールする。
1-a に対応した検証を行うのであれば nginx 1.14 をモジュールインストールした状態で nginx 1.16 をパッケージインストールするのが望ましいところですが、 nginx 1.16 をパッケージインストールできませんでした。そのため、代わりに postgresql 9.6 をモジュールインストールした後に postgresql 10 する形で検証を行います。
# 9.6 をモジュールインストールする前に、10 がパッケージインストールされることを確認。
$ sudo dnf install postgresql
メタデータの期限切れの最終確認: 0:14:16 時間前の 2020年06月05日 02時08分54秒 に 実施しました。
依存関係が解決しました。
================================================================================
パッケージ Arch バージョン Repo サイズ
================================================================================
インストール:
postgresql x86_64 10.6-1.module_el8.0.0+15+f57f353b AppStream 1.5 M
依存関係のインストール:
libpq x86_64 12.1-3.el8 AppStream 195 k
モジュールストリームの有効化:
postgresql 10
トランザクションの概要
================================================================================
インストール 2 パッケージ
ダウンロードサイズの合計: 1.7 M
インストール済みのサイズ: 6.4 M
これでよろしいですか? [y/N]: N
$ sudo dnf module -y install postgresql:9.6
(省略)
$ sudo dnf install postgresql
メタデータの期限切れの最終確認: 0:04:46 時間前の 2020年06月05日 02時08分54秒 に 実施しました。
パッケージ postgresql-9.6.10-1.module_el8.0.0+16+7a9f6089.x86_64 は既にインスト ールされています。
依存関係が解決しました。
行うべきことはありません。
完了しました!
モジュールインストールを行う前と行った後で、 dnf install postgresql
でインストールされるバージョンが異なっています。
どうやらストリームが有効化されると、それに準じたバージョンがインストールされるようです。
ストリームが有効化されていない場合は [d]
マークで示されていたデフォルトストリームに倣うことになります。
ついでに、 nginx 1.16 をモジュールインストールした後に nginx 1.14 をパッケージインストールしてみます。
$ sudo dnf install nginx
メタデータの期限切れの最終確認: 0:43:27 時間前の 2020年05月28日 11時21分52秒 に実施しました。
パッケージ nginx-1:1.16.1-1.module_el8.1.0+250+351caf85.x86_64 は既にインストールされています。
依存関係が解決しました。
行うべきことはありません。
完了しました!
今までの dnf install nginx
コマンドでは 1.14 がインストールされていましたが、今度は 1.16 のインストールを試みています。
有効化されているストリームに従ってパッケージをインストールしていることが確認できました。
2-b. 同じバージョンをパッケージでインストールする。
今度は nginx 1.14 をモジュールインストールした状態で、nginx パッケージをインストールしてみます。
$ sudo dnf install nginx
メタデータの期限切れの最終確認: 0:57:13 時間前の 2020年05月28日 11時21分52秒 に実施しました。
依存関係が解決しました。
行うべきことはありません。
完了しました!
まあそうでしょうね、という結果です。
逆の時はモジュールプロファイルの更新がありましたが今度は何もありません。
2-c. パッケージのアンインストールを実行する。
nginx 1.14 モジュールを dnf remove nginx
でアンインストールします。
$ sudo dnf remove nginx
依存関係が解決しました。
=============================================================================================================================================================================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
=============================================================================================================================================================================================================================================
削除中:
nginx x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 1.7 M
依存関係パッケージの削除:
nginx-all-modules noarch 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 0
未使用の依存関係の削除:
nginx-mod-http-image-filter x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 29 k
nginx-mod-http-perl x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 61 k
nginx-mod-http-xslt-filter x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 25 k
nginx-mod-mail x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 113 k
nginx-mod-stream x86_64 1:1.14.1-9.module_el8.0.0+184+e34fea82 @AppStream 171 k
トランザクションの概要
=============================================================================================================================================================================================================================================
削除 7 パッケージ
解放された容量: 2.0 M
これでよろしいですか? [y/N]:y
アレ? 1 パッケージ足りないですね。そのままアンインストールを実行して何が残ったか調べてみましょう。
$ rpm -qa | grep nginx
nginx-filesystem-1.14.1-9.module_el8.0.0+184+e34fea82.noarch
nginx-filesystem
が残ってしまっています。
確かに nginx の依存パッケージの一つのはずですが、異なるアンインストール方法で削除してしまうとこのようなことも起こりえるようです。
ところで、 dnf module remove
はモジュールとしてインストールされている認識がシステムにない時、アンインストールを行わないことを確認しました。
この状態で dnf module reset nginx
するともしかして……
$ sudo dnf module -y reset nginx
メタデータの期限切れの最終確認: 1:46:13 時間前の 2020年05月28日 14時24分53秒 に 実施しました。
依存関係が解決しました。
================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
================================================================================
モジュールプロファイルの無効化:
nginx/common
モジュールの再設定:
nginx
トランザクションの概要
================================================================================
完了しました!
$ sudo dnf module remove nginx
メタデータの期限切れの最終確認: 2:13:00 時間前の 2020年05月28日 11時21分52秒 に実施しました。
引数 nginx でプロファイルを一致できません
依存関係が解決しました。
行うべきことはありません。
完了しました!
$ rpm -qa | grep nginx
nginx-filesystem-1.14.1-9.module_el8.0.0+184+e34fea82.noarch
nginx-filesystem
を nginx の依存パッケージとしてアンインストールすることができなくなってしまいました。
dnf remove nginx-filesystem
で個別に削除することはできますが、パッケージのアンインストールを行う前に dnf module list
でどちらの方式でインストールを行っているか確認したほうが無難そうです。
まとめ
- CentOS8 はストリームによって、異なるバージョンのソフトウェアがシステム内に混在しないよう管理している。
- CentOS8 はプロファイルによって、「モジュールとしてインストールされたか」「されている場合はどのプロファイルか」を認識している。
- パッケージインストールを行った後にモジュールインストールを行うと、メタ情報の更新が差分として行われる。
- モジュールインストールしたものに対してパッケージのアンインストールを行うと、依存関係を正常に辿れない場合がある。
おわりに
- モジュールでインストールしたら、モジュールでアンインストールしよう!!
弊社 web サイトではコンテナ、クラウド、構成管理ツール、パッケージマネージャなど、 IT 基盤構築に関する様々な技術情報の公開を行っています。興味がありましたら覗いてみてください。
http://c.itdo.jp/category/technical-information/