Linuxのパッケージ管理とアップデートに関する基礎知識

Linuxのパッケージ管理に関連する用語や仕組みを整理してみました。主にRedHat系（Red Hat Enterprise Linux）についてまとめています。

## Linuxのパッケージ管理

パッケージとは、ソフトウェアをインストールするための必要なファイル（配布形態）です。

主なディストリビューションのパッケージ管理は以下のように分類されます。

|ディストリビューション|分類（拡張子）|管理コマンド|
|---|---|---|
|RedHat,CentOS,AlmaLinux|RPM（.rpm）|rpm,yum,dnf|
|Debian,Ubuntu|DEB（.deb）|dpkg,apt|
|FreeBSD|Ports Collection,Binary Packages（.txz,.tbz）|pkg,portsnap,portmaster,portupgrade|
|Solaris|SVR4,IPS（.pkg,.p5p）|pkgadd,pkgrm,pkginfo,pkg|

:::note warn
ディストリビューションごとにファイル形式や管理コマンドなどが異なります。
:::


### Linuxで利用される主なパッケージ
Linuxにはさまざまなパッケージが存在します。ディストリビューションによって既にインストール済みのパッケージもあれば、追加でインストールが必要なパッケージもあります。
ソフトウェア開発ではnginx（Webサーバ）やMariaDB（DBサーバ）などが有名です。

### パッケージの構成要素
RedHat系のパッケージは、RPM（Red Hat Package Manager）形式で配布され、以下のようなファイルで構成されています。

|名称|内容|
|---|---|
|プログラム本体|コンパイル済みの実行ファイル、直接実行可能なバイナリファイル|
|ライブラリ|プログラムが動作するために必要となる再利用可能な共通機能|
|設定ファイル|設定内容が記載されたテキストファイル、インストールスクリプト|
|ドキュメント|READMEなどのパッケージに関する情報|
|メタデータ|パッケージ名、バージョン、依存関係などの情報|

一方、ライブラリは他のプログラムから呼び出されて使用されます。コンパイル済みのものもあればソースコードのままのものもあります。有名なライブラリには以下のようなものがあります。

|ライブラリ|主な機能|
|---|---|
|glibc (GNU C Library)|C言語の標準ライブラリ|
|libcurl|URL転送ライブラリ|
|zlib|データ圧縮用のライブラリ|

### パッケージ管理の注意点
パッケージ管理を理解するには以下のような知識が必要です。

- 管理コマンドや設定ファイルにはどのようなものがあるか？
- 取得先のリポジトリをどうするか？（そもそもリポジトリって何？）
- 依存関係や競合関係の考慮は必要か？

### パッケージの操作方法
RedHat系パッケージの操作は、以下のようなパッケージマネージャ（コマンド）を使うことで、追加、更新、削除、照会などの操作が可能です。

- rpmコマンドの特徴（Red Hat Package Managers）
    - パッケージを個別に操作する
    - 依存関係や競合関係の解決は手動で行う必要がある
- yumコマンドの特徴（yellowdog updater modified）
    - リポジトリからパッケージを取得する
    - 依存関係や競合関係は自動で解決する
    - 一部の処理はバックグラウンドでrpmコマンドが使用されています
    - 既に開発が終了しており、現在はdnfに置き換えられている
- dnfコマンドの特徴（Dandified Yum）
    - yumの後継で、パフォーマンス向上やメモリ使用量の削減など改善が加えられている
    - 依存関係や競合関係の管理やトランザクション処理がより効率的になっている

なお、依存関係と競合関係の違いは以下の通りです。

- 依存関係（Dependencies）
    - パッケージが正常に動作するために必要な他のパッケージ
- 競合関係（Conflicts）
    - 2つのパッケージが同じファイルやリソースを変更しようとする場合、または同じ機能を提供しようとする場合に発生する問題

yumやdnfを使用する場合、基本的には管理者が依存関係や共存関係を考慮する必要はありません。

## dnfの役割を理解する

Linux（RedHat系）のパッケージ管理にはdnf（またはyum）を利用することが一般的です。
dnfによるパッケージ管理にはコマンドによる操作方法と設定ファイルによる定義の理解が必要です。

### dnfコマンドとオプション
dnfコマンドには主に以下のようなオプションがあります。

|コマンド|意味|
|---|---|
|dnf install|パッケージをインストールする|
|dnf update|インストール済みパッケージをアップデートする|
|dnf upgrade|インストール済みパッケージをアップデートし、旧パッケージを自動削除する|
|dnf remove|インストール済みパッケージを削除する|
|dnf reinstall|インストール済みパッケージを再インストールする|
|dnf downgrade|パッケージをダウングレードする|
|dnf distro-sync|システムを最新バージョンに同期する|
|dnf install ./package.rpm|ローカルのRPMファイルを指定してインストールする|
|dnf install ./package.rpm|ローカルのRPMファイルを指定してアップデートする|
|dnf info|パッケージの詳細情報を表示する|
|dnf list installed|インストール済みパッケージを表示する|
|dnf check-update|アップデート可能なパッケージ一覧を表示する|
|dnf repoquery --requires|パッケージの依存関係を表示する|
|dnf search|パッケージを検索する|
|dnf repolist|リポジトリ一覧を表示する|
|dnf repolist enabled|有効になっているリポジトリ一覧を表示する|
|dnf config-manager --set-enabled|指定したリポジトリを恒久的に有効化する|
|dnf config-manager --set-disabled|指定したリポジトリを恒久的に無効化する|
|dnf config-manager --add-repo|リポジトリURLを追加する|
|dnf --enablerepo|特定のリポジトリを一時的に有効化する|
|dnf --disablerepo|特定のリポジトリを一時的に無効化する|
|dnf clean all|キャッシュやダウンロード済みパッケージを削除する|
|dnf update --skip-broken|依存関係エラーをスキップしてアップデートする|
|dnf update --exclude|指定したパッケージをアップデート対象から除外する|
|dnf update --disableexcludes|除外設定を無効化してアップデートする|
|dnf --version|dnfのバージョンを表示する|

:::note warn
コマンドによるリポジトリ指定やアップデート除外などは、実行時にのみ有効な暫定対応です。設定を恒久的に反映したい場合は、設定ファイルによる定義が必要です。
:::

### dnfに関する設定ファイル

主に以下の設定ファイルが存在します。

|yumのファイル名|dnfのファイル名|説明|
|---|---|---|
|/etc/yum.conf|/etc/dnf/dnf.conf|メインの設定ファイル、リポジトリやキャッシュ、GPGチェックの設定など基本的な設定|
|/etc/yum.repos.d/*.repo|/etc/yum.repos.d/*.repo|リポジトリ情報が記載されているファイル群、リポジトリごとに個別の.repoファイルがある|
|/etc/yum/vars/*|/etc/dnf/vars/*|変数の定義ディレクトリ、releaseverやbasearchなどの変数が定義|
|/var/log/yum.log|/var/log/dnf.log|パッケージインストールやアップデートのログが保存されるファイル|
|/var/cache/yum/*|/var/cache/dnf/*|パッケージのキャッシュやメタデータが保存されるディレクトリ|
|N/A|/etc/dnf/modules.d/*.module|dnfでモジュールストリームを管理するためのファイル、特定のバージョンや機能セットを選択してインストールする際に使用|
|N/A|/etc/dnf/plugins/|dnfプラグインの設定ディレクトリ、プラグインの動作を設定|

dnfコマンドの基本的な動作は`/etc/dnf.conf`の`[main]セクション`の配下に定義します。
主な設定項目(デフォルトで定義されているもの)を抜粋します。

|オプション|設定内容|
|---|---|
|cachedir|パッケージのキャッシュを保存するディレクトリ|
|keepcache|ダウンロード後のキャッシュ保持の有無|
|debuglevel|デバッグメッセージの出力レベル|
|logfile|ログの出力先|
|gpgcheck|インストール時のGPGキーのチェック有無|
|plugins|プラグインの使用許可の有無|
|fastestmirror|使用可能なミラーの中で最も速いものを選択するか|
|exclude|更新やインストールから除外するパッケージのパターンを指定|
|includepkgs|インストールまたは更新するパッケージを限定するためのリスト|
|timeout|リポジトリ接続のタイムアウト時間|
|proxy|プロキシサーバーのアドレス|
|proxy_username|プロキシサーバーの認証情報（ユーザ名）|
|proxy_password|プロキシサーバーの認証情報（パスワード）|
|sslverify|SSL証明書の検証を行うか|
|metadata_expire|リポジトリのメタデータのキャッシュ有効期間|

主な設定項目(追加定義が必要なもの)を抜粋します。
|オプション|設定内容|
|---|---|
|exactarch|アーキテクチャに一致するパッケージのみのインストール有無|
|obsoletes|パッケージ更新時の旧パッケージの置き換え有無|
|installonly_limit|インストール済みカーネルのバージョン保持数|
|deltarpm|deltarpmの使用の有無|
|assumeyes|dnfコマンド実行時にすべての質問に自動的に「はい」と答えるか|
|color|コマンドの出力に色を付けるか|



`[main]セクション`の他に`[repository]セクション`を作成し、リポジトリ関連の情報を定義することも可能でが、リポジトリごとの設定は`/etc/dnf.conf`に直接記載せずに、`/etc/dnf.repos.d/*.repo`に定義することが推奨されます。

|オプション|設定内容|
|---|---|
|name|リポジトリ名（必須）|
|baseurl|リポジトリの保存先URL（必須）|
|enablerepo|リポジトリの有効化or無効化の設定|
|gpgcheck|GPGのチェックを有効化or無効化の設定|
|gpgkey|使用する公開鍵のURL（またはファイル名）|


### dnfとリポジトリの関係性

リポジトリとは各種パッケージを保存しておくためのサーバ（保存庫）です。
インターネット上のリポジトリを外部リポジトリ、社内ネットワーク上のリポジトリを内部リポジトリと呼びます。
外部リポジトリは以下のようなものがあります。公式リポジトリとサードパーティリポジトリに分けられます。

- BaseOS
    - Red Hat Enterprise Linuxの基本的なOS機能を提供する公式リポジトリ
    - コアパッケージが含まれる
- AppStream
    - モジュール化されたアプリケーションや開発ツールを提供する公式リポジトリ
    - バージョンやエディションの選択が可能
- EPEL（Extra Packages for Enterprise Linux）
    - Fedoraプロジェクトの有志によるRedHat系ディストリビューション向けのサードパーティリポジトリ
- Remi Repository
    - PHPやその他の開発ツールの最新バージョンを提供するサードパーティリポジトリ
    - PHP関連のパッケージが豊富
- ELRepo
    - ハードウェアやドライバ関連のパッケージを提供するサードパーティリポジトリ
- Zabbix
    - Zabbix監視ソフトウェアの公式サードパーティリポジトリ
    - 監視ツールの最新バージョンや関連パッケージを提供
- Docker
    - Dockerの公式サードパーティリポジトリ
    - Dockerエンジンやコンテナ関連のツールを提供

基本的なパッケージはRHELの公式リポジトリから取得可能ですが、ZabbixやDockerのようにサービスごとの公式リポジトリ（サードパーティリポジトリ）から取得しなければならないパッケージも存在します。

### パッケージ取得元のリポジトリが選択される優先順位

パッケージの取得元のリポジトリが複数存在する場合、一般的には以下のような基準で利用されるリポジトリの優先順位が決まります。

#### キャッシュの利用
既にキャッシュされたパッケージがあれば、ネットワーク越しのリポジトリから再ダウンロードせずにキャッシュを利用します。キャッシュがない場合、リポジトリからパッケージがダウンロードされます。

#### リポジトリの有効性
リポジトリが有効でなければ使用されません。無効なリポジトリはパッケージ選択に影響しません。

#### リポジトリの優先度
yumの場合、`/etc/dnf.repos.d/*.repo`の`priority`オプションが設定されている場合、優先度が小さいリポジトリが選択されます。

一方、dnfでは`priority`オプションが標準で組み込まれていないため、`dnf-plugin-priorities`パッケージをインストールすることで、`priority`オプションが使用可能になります。

```shell:dnf-plugins-coreのインストール
$ sudo dnf install dnf-plugins-core
```

#### パッケージのバージョン
同一パッケージの複数バージョンが存在する場合、最新バージョンのパッケージが優先されます。

#### コストオプション
costオプションが設定されている場合、低コストのリポジトリが優先されます。dnfではcostオプションを使ってリポジトリ選択に影響を与えることができます。

#### リポジトリファイルの読み込み順
リポジトリファイルの読み込み順序やincludeされた順番も影響しますが、通常はリポジトリの優先度やその他の設定がより重要です。

:::note warn
リポジトリが選択される優先順位はさまざまな要因により変わります。
:::

なお、リポジトリを管理するには以下のコマンドが便利です。

- RHEL7以前…yum-config-managerコマンド
- RHEL8以降…dnf config-managerコマンド

```shell:dnf config-managerによるリポジトリの有効化と無効化
$ sudo dnf config-manager --set-enabled <repository-name>
$ sudo dnf config-manager --set-disabled <repository-name>
```

dnf-config-managerはdnfの一部として提供されるためパッケージの追加インストールは不要です。

一方、yum-config-managerコマンドを利用するには、yum-utilsパッケージの追加インストールが必要です。

```shell:yum-config-managerのインストール
$ sudo dnf install yum-utils
```

### 公式リポジトリに対象のパッケージが含まれていない場合

RedHatの公式リポジトリに目的のパッケージが含まれていない場合、EPELなどのサードパーティリポジトリからパッケージを取得します。

通常、パッケージ管理はdnfコマンドにオプションを加えて実行するシンプルなものですが、サードパーティリポジトリからパッケージを取得する場合、以下のような手順となります。

```shell:サードパーティリポジトリを追加し、メタデータをキャッシュに保存する
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf makecache
```

```shell:パッケージをインストールする
sudo dnf install docker-ce docker-ce-cli containerd.io
```

:::note info
取得元のリポジトリによりインストール方法が異なることがあります。
:::

### リポジトリとGPG

GPG（GNU Privacy Guard）は、リポジトリからダウンロードしたパッケージの信頼性と整合性を保証するための暗号化技術です。デジタル署名を用いて、以下の要素を確認します：

- 信頼性の保証
    - パッケージが公式リポジトリから提供されているか評価する
    - 第三者による改ざんがないかを確認する
- 整合性の確認
    - パッケージが配布中に変更されたり、改ざんや破損がないかを検証する
- セキュリティの強化
    - パッケージがマルウェアやウイルスに感染していないかをチェックする

通常、リポジトリを設定する際には、GPG公開鍵も同時にインポートしてパッケージの署名を検証します。
署名に問題がある場合、パッケージのインストールは中断され、警告メッセージが表示されます。

GPGの設定は、各リポジトリの設定ファイル（通常は`/etc/dnf.repos.d/*.repo`）内で次のように定義されます：

- gpgcheck
    - GPG署名の検証を有効にするか、無効にするかの設定。
- gpgkey
    - 使用する公開鍵のURLまたはファイル名を指定します。

これにより、GPGによってパッケージ管理のセキュリティが強化され、安全なパッケージの取得と管理が実現します。

## 関連用語のまとめ

Linuxのパッケージ管理を勉強すると似たようなキーワードがたくさん出てきますが、それぞれの言葉の意味を正確に理解できていなければ認識誤りなどが起こってしまいます。

一部、重複もありますが、おさらいも兼ねて関連する用語を改めて整理してみました。

|用語|意味|
|---|---|
|ディストリビューション|OSの配布版で、基本的なOSとその関連ソフトウェアを含む一式|
|リリースバージョン|ディストリビューションの特定のバージョン、新機能や改善点を含むリリースのバージョン番号|
|カーネル|OSの中核部分で、ハードウェアとソフトウェアのリソースを管理する基本的な部分|
|モジュール|カーネルやOSの機能を拡張するための部品（例：ハードウェアのドライバや追加機能など）|
|ライブラリ|各種プログラムが共通して利用するための機能やコードの集まり|
|パッケージ|インストール可能なソフトウェアの単位でプログラムやその依存関係を含む|
|リポジトリ|パッケージを保存し配布するための場所、リポジトリからソフトウェアをダウンロードする|
|レポジトリファイル|リポジトリの設定情報を含むファイル、どのリポジトリを使用するかを定義する|
|メタデータ|リポジトリ内のパッケージの情報や依存関係などを含むデータ、パッケージの検索や管理に使用される|
|GPGキー|ソフトウェアのパッケージに対してデジタル署名を行うための公開鍵、パッケージの信頼性と整合性を確認する|
|サードパーティリポジトリ|公式リポジトリ以外の、外部の開発者や団体が提供するリポジトリ、公式のサポートがないことが多い|
|リポジトリURL|リポジトリへのアクセス先のURL、リポジトリの場所を指定する|
|パッケージマネージャ|ソフトウェアのインストール、更新、削除を管理するツール（例：yum、dnf）|
|AppStream|RHEL 8以降で導入されたソフトウェア配布の仕組み、複数のバージョンを提供し、アプリケーションの選択と管理を容易にする|
|RHSCL|Red Hat Software Collectionsの略、RHEL向けの追加ソフトウェアパッケージ群で、より新しいバージョンのアプリケーションを提供|

### ディストリビューション

ディストリビューションは、Linuxカーネルを基盤に、多様なソフトウェア（パッケージ管理システム、ユーザーインターフェース、ユーティリティなど）を統合して提供されるOSの形態です。
代表的なディストリビューションには以下のものがあります：

- RHEL (Red Hat Enterprise Linux)
    - 商用サーバー向けの企業向けディストリビューション
- CentOS
    - RHELの無償クローン
    - 商用サポートがなく、コミュニティ主導のディストリビューション
- AlmaLinux
    - CentOSの後継として位置づけられるRHELクローン
    - 商用サポートがなく、コミュニティ主導
- Rocky Linux
    - CentOSの後継として設立された、RHELクローン
    - 商用サポートなし、コミュニティ主導。
- Amazon Linux
    - AWS (Amazon Web Services) に最適化されたAmazon提供のディストリビューション
    - クラウド環境向け
- Fedora
    - RHELの upstream（先行開発版）として位置づけられるディストリビューション
    - 比較的、最新の技術を採用
- Debian
    - 安定性と自由度の高いオープンソースディストリビューション
- Ubuntu
    - Debianを基にしたユーザーフレンドリーなディストリビューション
    - デスクトップからサーバーまで広く利用されている

これらのディストリビューションは、それぞれ異なる目的や使用ケースに応じて最適化されており、ユーザーや企業のニーズに合わせて選ばれます。
以前はCentOSが採用されていることも多かったですが、最近はサポート期間などの都合上、AlmaLinuxやRocky Linuxが後継として採用されることが増えてきました。

### ディストリビューションとカーネルバージョンの違い

OSの中核を成すソフトウェアが「カーネル」です。
ディストリビューションは、カーネルを含むOS全体のパッケージであり、通常、特定のリリースバージョンごとに指定されたカーネルバージョンが含まれています。


|リリースバージョン|初期カーネルバージョン|アップデート後カーネルバージョン|
|---|---|---|
|RHEL 7.x|3.10系|3.10 系|
|RHEL 8.x|4.18系|5.4～5.14系|
|RHEL 9.x|5.14系|5.14 系|

:::note info
一つのリリースバージョンに対して適用されるカーネルバージョンは複数存在します。
:::

### パッケージ名の意味（バージョン情報とリリース番号）
例えば、ファイル名が`kernel-4.18.0-425.3.1.el8.x86_64.rpm`の場合、各部分の意味は次のようになります。

- kernel（パッケージ名）
    - 「カーネル」パッケージであることを示す
- 4.18.0（バージョン番号）
    - カーネルのメジャー、マイナー、パッチレベルを示す
- 425.3.1.el8（リリース番号）
    - ビルド番号やリビジョンを含むもので、特定のバージョンにおける変更やパッチレベルを示す
    - el8 は「Enterprise Linux 8」を示し、バージョン8に対応していることを示す
- x86_64（アーキテクチャ）
    - 「64ビットのCPU」を指しており、64ビットのシステムで使用されることを示す
- rpm（拡張子）
    - Red Hat Package Manager形式のパッケージファイルであることを示す

基本的には、カーネルに限らず、他のパッケージ名もこのような構造でファイル名が決まります。
つまり、パッケージ名、バージョン、リリース番号、アーキテクチャ、およびファイル形式が含まれ、これによりパッケージの詳細と適用対象が明示されます。

### モジュールとライブラリの違い

モジュールは、Linuxカーネルやソフトウェアの機能を追加・拡張するための部品です。
たとえば、カーネルモジュールは、ハードウェアサポートや新しいファイルシステム機能を提供するためにカーネルに動的に組み込まれます。
モジュールは、特定の機能やサービスを分けて管理し、必要に応じて読み込むことができます。

ライブラリは、アプリケーションが実行時に利用する共通のコードや関数の集合です。
例えば、C言語の標準ライブラリは、プログラムが基本的な操作を行うための関数群を提供します。
ライブラリは、アプリケーションが直接呼び出して利用し、コードの再利用を促進します。

モジュールはシステムやカーネルの機能を拡張する部品で、ライブラリはプログラムの機能を提供するコードの集まりです。

## dnfコマンドが失敗する原因

トラブルシューティング時に役立つようにdnfが失敗する原因として考えられる項目をピックアップしました。
※ネットワーク機器などの外部要因による通信障害については割愛します。

### ネットワークの問題
dnfは外部のリポジトリに対してアクセスするため、ネットワーク設定が原因により失敗するケースが多いです。
#### リポジトリへの通信がブロックされる問題
取得元リポジトリの設定（URLやGPGキーなど）によりパッケージのインストールに失敗することがあります。
`/etc/yum.repos.d/*.repo`の設定内容を見直すか、リポジトリを再インストールすることで解消する可能性があります。

リポジトリへアクセスするためのfirewalldの設定も必要です。
通常、リポジトリへの通信はHTTP（ポート80）またはHTTPS（ポート443）を使用するため、firewalldによるポートの開放が必要です。

```shell:firewalldによるリポジトリへの接続ポートの解放
# HTTP (ポート80)を許可
$ sudo firewall-cmd --permanent --add-service=http

# HTTPS (ポート443)を許可
$ sudo firewall-cmd --permanent --add-service=https

# 設定の再読み込み
$ sudo firewall-cmd --reload
```

#### DNSサーバへの通信がブロックされる問題

通常、リポジトリへのアクセス設定はホスト名（ドメイン名）で定義されるため、リポジトリへアクセスするにはDNSによる名前解決が必要です。
DNSサーバの設定は`/etc/resolv.conf`により以下のように定義されます。
```shell:/etc/resolv.confの設定
nameserver 8.8.8.8
nameserver 8.8.4.4
```
また、DNSサーバへアクセスするためのfirewalldの設定（UDPポート53の開放）も必要です。

```shell:firewalldによるDNSへの接続ポートの解放
# DNSのポート（UDP 53）を許可
$ sudo firewall-cmd --permanent --add-port=53/udp

# 設定の再読み込み
$ sudo firewall-cmd --reload
```

#### プロキシサーバへの通信がブロックされる問題

```shell:/etc/dnf.confの設定
[main]
proxy=http://proxy.example.com:port
proxy_username=your_username
proxy_password=your_password
```
なお、プロキシサーバへのfirewalldの設定はリポジトリへのアクセス同様HTTP（ポート80）またはHTTPS（ポート443）を利用します。

::: note info
通常の外部への通信時にはhttp_proxyやhttps_proxyなどの環境変数で定義されたプロキシサーバを経由して通信します。
:::

### SELinuxの設定による問題
SELinuxとはLinuxカーネルに組み込まれているセキュリティを強化するためのモジュールです。
アクセス制御の強化やポリシーの適用を通じて、プロセスやユーザの操作を制限し、セキュリティリスクを軽減します。
SELinuxのポリシー設定によりyumコマンドが必要とするファイルやネットワークリソースへのアクセスが制限されることがあります。主に以下のような切り分けが可能です。

- SELinuxのステータスを確認する
- SELinuxのログを確認する
- SELinuxのポリシーを調整する

SELinuxの設定は複雑で難易度が高いため、無効化されていることも多いです。

### キャッシュの問題
パッケージの取得がキャッシュの問題で失敗する場合は、キャッシュをクリアすることで問題が解決します。
キャッシュは、一時的にダウンロードしたパッケージやメタデータを保存するために使用されますが、これが破損したり、古くなったりすると、パッケージ操作が正常に行えなくなることがあります。

```shell:cleanオプションによるキャッシュのクリア
$ sudo dnf clean all
```

キャッシュがクリアされると、次回の操作時に新しいキャッシュが再生成されます。

:::note info
キャッシュ全体をクリアする必要がない場合、特定のキャッシュだけをクリアすることも可能です。
:::



### パッケージの依存関係の問題

通常、dnfやyumはすべての依存関係を厳密にチェックし、依存関係の解決ができない場合にはアップデートやインストールを中断します。
`--skip-brokenオプション`を使用すると、依存関係の問題があるパッケージを無視して、他のパッケージだけをアップデートします。

```shell:--skip-brokenオプションによる問題のある依存関係のスキップ
$ sudo dnf --skip-broken update
```

`--skip-brokenオプション`は、一時的な対応策であり、根本的な解決策にはなりません。
長期的に依存関係の問題を無視し続けることは、システムの安定性や一貫性に悪影響を及ぼす可能性があるため、推奨される場面は限定的です。


### ディストリビューションごとのバージョン上限の問題
ディストリビューションのリリースバージョンにより、各種パッケージのバージョン上限が定められていることがあります。

|パッケージ|RHEL7|RHEL8|RHEL9|
|---|---|---|---|
|kernel|3.10.x|4.18.x〜5.14.x|5.14.x|
|OpenSSL|1.0.2|1.1.1|3.x|
|PHP|5.4(標準),7.x(RHSCL)|7.x(標準),8.x(AppStream)|8.x(標準)|
|MySQL|5.7|8.0|8.x|
|Python|2.7|3.6|3.9|
|Perl|5.16|5.26|5.32|
|Apache HTTP Server|2.4.x|2.4.x|2.4.x|

:::note info
Apache HTTP ServerはRHEL6までは2.2.xが標準でしたが、RHEL7以降は2.4.xが標準となります。
:::

基本的な傾向としては、以下のようなイメージになるでしょう。

- メジャーバージョンが複数あるパッケージ
    - 比較的頻繁に更新されるため複数のメジャーバージョンが存在する
    - ディストリビューションのリリースバージョンによってバージョン制限がある
    - ディストリビューションごとのバージョンの上限を意識する必要がある
    - 例）OpenSSL、PHP、MySQL、Python、Perlなど
- メジャーバージョンが一つのパッケージ
    - 比較的安定しているため同一のメジャーバージョンが長期間にわたって使用される
    - ディストリビューションのリリースバージョンに依存せず
    - バージョン制限を意識する必要が少ない
    - 例）BIND、Postfix、Squidなど一般的なパッケージ全般？

OpenSSLやMySQLなどの特定のバージョンを利用するためには、前提として互換性のあるディストリビューションを採用する必要があります。

:::note info
DockerやZabbixのようにサードパーティリポジトリより取得するパッケージについては、ディストリビューションごとの上限を意識する必要は少ないでしょう。
:::

古いディストリビューションで新しいメジャーバージョンのパッケージを使用したい場合、主に以下のような方法が考えられます。

- サードパーティリポジトリや独自ビルドで新しいパッケージをインストールする
- コンテナを利用する
- AppStreamにより特定のバージョンを使用する（RHEL8以降）
- システム全体の上位のディストリビューションにアップグレードする

サードパーティリポジトリや独自ビルドにより新しいパッケージをインストールすることも可能ですが、RedHatの公式サポートが受けられなかったり、互換性の問題が発生する可能性もあったりします。
高いセキュリティや安定性が求められるようなシステムの場合、根本的な解決策としては、上位のディストリビューションにアップグレードすることが推奨されています。

:::note alert
REHL7のディストリビューションに対してRHEL8のような異なるリポジトリを追加してパッケージをインストールすることは依存関係や互換性の問題を引き起こしたり公式サポートを受けられなくなるため推奨されません。
:::

### サブスクリプションのの設定
Red Hatのサブスクリプションを管理するには`Subscription Manager`コマンドを使います。
`Subscription Manager`コマンドにより、Red Hatのシステムへ登録することで、公式リポジトリにアクセスしたし、セキュリティパッチやソフトウェアの更新、追加パッケージのダウンロードなどが可能です。
`Subscription Manager`の主な機能は以下の通りです。

```shell:システムへの登録と解除
$ sudo subscription-manager register --username=<RHNユーザー名> --password=<RHNパスワード>
$ sudo subscription-manager unregister
```

```shell:サブスクリプションの表示と取得
$ sudo subscription-manager list --available
$ sudo subscription-manager attach --auto
```

```shell:リポジトリの有効化と表示
$ sudo subscription-manager repos --enable=<repo_id>
$ sudo subscription-manager repos --list
```

適切にサブスクリプションを登録することで、セキュリティパッチやバグ修正などのパッケージをダウンロードおよびインストールできるようになります。

:::note info
サードパーティリポジトリからパッケージの取得する場合は、公式リポジトリへアクセスする必要がないため、Subscription Managerの設定は必須ではありません。
:::


## まとめ
改めてこの記事の内容をまとめます。

- ディストリビューションごとにパッケージのファイル形式や管理コマンドが異なる
- パッケージは実行可能なソフトウェアで依存関係や競合関係の考慮が必要
- ライブラリはプログラムが動作するために必要となる再利用可能な共通機能
- カーネルはOSの中核部分でリソース管理などを担う
- モジュールはカーネルの拡張機能で、機能追加を可能にする
- リポジトリはパッケージの取得先で公式パッケージとサードパーティパッケージがある
- ディストリビューションのリリースバージョンにより利用可能なパッケージのバージョンに上限がある
- ネットワークやサブスクリプトの設定に不備があるとリポジトリへのアクセスが失敗する

<script async class="docswell-embed"
        src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js"
        data-src="https://www.docswell.com/slide/ZEXDLQ/embed"
        data-aspect="0.5625">
</script>
<div class="docswell-link">
  <a href="https://www.docswell.com/s/go_nishimoto/ZEXDLQ-2025-05-02-002917">Linuxのパッケージ管理とアップデート基礎知識 by @go_nishimoto</a>
</div>


## 参考文献

https://atmarkit.itmedia.co.jp/ait/articles/1608/29/news019.html