タグ: Docker

RHEL系Linux(Rocky Linux)でDockerのビルド領域変更

Dockerならではの問題に対処したのでメモを残します。

背景と課題

RHEL / Rocky Linux 9 環境のGPUサーバーにおいて、Dockerビルド(大規模LLMモデルの生成など)を実行した際、ルートパーティション(/)の使用率が100%に達する事象が発生しました。

  • 原因: Dockerはデフォルトで /var/lib/docker(ルート配下)にイメージやビルドキャッシュを保存します。
  • 環境: ルート領域は70GB程度ですが、/home 領域には数TBの空きがります。
  • 対策: パーティションリサイズ(LVM操作)はリスクが高いため、Dockerのデータ保存先(data-root)を /home 配下へ物理的に移行して解決します。

さっくりとした手順

  1. 現状を確認し、サービスを停止します。
  2. Dockerの移行ディレクトリを作成します。
  3. rsyncを用いて安全にデータを移行します。
  4. Dockerの設定ファイルを変更します。
  5. Dockerサービスの再起動を行います。
  6. 設定変更を確認します。

現状の確認とサービスの停止

まず、現在のDocker設定とディスク使用量を確認し、Dockerサービスを停止します。

  • Dockerの保存先確認
docker info | grep "Docker Root Dir"

(デフォルトは /var/lib/docker)

  • Dockerサービスを停止します。
sudo systemctl stop docker docker.socket
  • Dockerサービスの停止を確認します。
systemctl status docker

inactive(dead)を確認します。

移行先ディレクトリを作成します。

大容量領域(今回は /home 配下)に新しい保存用ディレクトリを作成します。

  • ディレクトリ作成
sudo mkdir -p /home/docker/data

データの移行(最重要)

既存のイメージやコンテナデータを保持するため、rsync を用いてデータを同期します。
cp コマンドよりも、権限やタイムスタンプを正確に保持できる rsync を推奨します。
rsyncはRocky9に最初から入っているコマンドです。

  • /var/lib/dockerの中身を、新ディレクトリへコピー
sudo rsync -aqxP /var/lib/docker/ /home/docker/data/

-a: アーカイブモード(権限等を保持)
-x: ファイルシステム境界を越えない
注意: コピー元のパス末尾に / を付けることで、ディレクトリそのものではなく「中身」を転送先に展開します。

設定ファイルの変更 (daemon.json)

  • ファイルのバックアップを取ります。(凄く重要)

何かあったときの切り戻しのため。特に、後述するjsonの編集をミスると地獄行きの通過駅無しの特急が待っています。

sudo cp -pi /etc/docker/daemon.json /path/to/backup/directory/daemon.json.$(date +%Y%m%d)
  • ファイルのバックアップをdiffで取ります。
sudo diff -u /path/to/backup/directory/daemon.json.$(date +%Y%m%d) /etc/docker/daemon.json

一般ユーザが読み取れないディレクトリ構造も考慮して、念のためsudoをつけます。

→ エラーがなければバックアップ成功。ここでコピー元とコピー先を逆にしているのは編集後のdiffを取るためです。

  • Dockerに新しい保存先を認識させるため、/etc/docker/daemon.json を編集します。(エディタは宗教問題のため、自分の教義・信仰に沿ったものを利用してください)

変更例:
data-root オプションを追記します。
JSON形式のため、行末のカンマ(,)の有無に注意してください。

{
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    },
    "data-root": "/home/docker/data"
}
  • 編集後の差分をdiffで確認します。
sudo diff -u /path/to/backup/directory/daemon.json.$(date +%Y%m%d) /etc/docker/daemon.json

以下のようになっていることを確認します。

-     "data-root": "/var/lib/docker"
+     "data-root": "/home/docker/data"

サービスの起動と確認

Dockerを起動し、設定が反映されているか確認します。

  • Dockerサービスを起動します。
sudo systemctl start docker
  • Dockerサービスの起動を確認します。
systemctl status docker

active(running)を確認します。

  • 設定反映の確認
docker info | grep "Docker Root Dir"

=> Docker Root Dir: /home/docker/data となっていれば成功です。

不要データの削除(任意)

動作確認後、元の /var/lib/docker を削除または退避させて、ルートパーティションの空き容量を回復させます。

安全のため、バックアップを取るか慎重に削除してください。この作業を行うときは深呼吸を3回ほど行い、飲み物を飲むなどして落ち着いてから行いましょう。

sudo rm -rf /var/lib/docker

結果

本対応により、ルートパーティションの圧迫が解消されました。

Before:

Filesystem           Size  Used Avail Use% Mounted on
/dev/mapper/rl-root   70G   70G   20K 100% /

After:

Filesystem           Size  Used Avail Use% Mounted on
/dev/mapper/rl-root   70G  6.0G   65G   9% /
/dev/mapper/rl-home  6.9T  198G  6.7T   3% /home

トラブルシューティング

  • SELinux: 起動に失敗する場合、SELinuxが非標準ディレクトリへのアクセスをブロックしている可能性があります。一時的に setenforce 0 で切り分けを行うか、適切なコンテキストを設定してください。
  • JSON構文エラー: daemon.json の記述ミス(カンマ忘れなど)があるとDockerが起動しません。編集後は慎重に確認を行いましょう。

ナレッジサーバ構築メモ-2- Docker/Knowlege構築篇

はじめに

先日から始まった「Linux機にナレッジサーバを構築して運用する」プロジェクト。

OS基盤の前に、

  • 何かあっても切り戻しができる
  • VMと異なりリソース消費が少ない

ことから、Dockerを入れてみます。

前提条件

ベースPCは前述したとおり。

  • Kubuntu 21.04を導入
  • NWをIPv4のローカルで固定
  • 家庭内のNWからSSH接続できるよう設定

Dockerインストール

以下、全てrootで実施します。

(参考:https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04-ja)

  • 必要なパッケージをインストール
# aptitude install apt-transport-https ca-certificates curl software-properties-common
  • Docker公式リポジトリをシステムに追加
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
  • パッケージ更新→ Dockerインストール
# aptitude update
# aptitude install docker-ce
# aptitude install docker-compose
  • Dockerステータス確認
# systemctl status docker

● docker.service - Docker Application Container Engine
    Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
    Active: active (running) since Sun 2021-09-12 07:54:43 JST; 1min 35s ago
TriggeredBy: ● docker.socket
      Docs: https://docs.docker.com
  Main PID: 51598 (dockerd)
    Tasks: 9
    Memory: 28.6M
    CGroup: /system.slice/docker.service
            └─51598 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

以下、通常ユーザで実行します。

  • 通常ユーザでdockerを実行できるように設定
$ usermod -aG docker [ユーザ名]
  • 反映後、ログアウトし再ログイン
  • 自動起動有効化
$ sudo systemctl enable docker

docker 動作確認

まずはコンテナが動いているかを確認します。

(参考:https://qiita.com/Esfahan/items/52141a2ad741933d7d4c)

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS   PORTS     NAMES

→ 何も動いておらず。

  • Docker上でbash起動
$ docker run -i -t centos /bin/bash
# cat /etc/redhat-release
CentOS Linux release 8.3.2011
→ CentOS8.3が起動
# exit
  • Dockerイメージ再確認
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED             STATUS                     PORTS     NAMES
99b9e451b8c0   centos   "/bin/bash"   About a minute ago   Exited (0) 14 seconds ago             compassionate_allen
  • テスト用のイメージ削除
$ docker rm [コンテナID]
  • テスト用イメージ削除確認
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS   PORTS     NAMES

何も動いていないことを再確認。

DockerコンテナからKnowledgeを作成

ここまで来たらあっけなく終わりました。

$ sudo docker pull koda/docker-knowledge
$ sudo mkdir /home/manualmaton/knowledge ## コンテナを格納するディレクトリ
$ sudo chmod a+w /home/manualmaton/knowledge
$ sudo docker run -d -p 80:8080 -v /home/manualmaton/knowledge:/root/.knowledge --name knowledge koda/docker-knowledge

あとは、ブラウザ上から

http://[サーバのIPアドレス]

にアクセスし

正常にアクセス完了。Tomcatやnginxの設定すら不要でした。

残る課題

  • コンテナの自動起動設定。→ 現状、リスタートしても自動的にサービスが立ち上がらないので、ベースマシン再起動のたびにdocker start knowledgeを入力する必要があります。これを自動起動する設定を行います。
  • データ(コンテナ)の自動バックアップ

まとめ

なんとなく作ったシステムが実は有用だったと気づいたものの、それを再現するためのメモがなかったことに唖然としました。

「前に取得した知識がどこかで役立つよう」

メモを残しておくことは本当に大事だと思ったわけで。

なにはともあれ、今後は

  • 適当なMarkdownエディタを使って生地を作成
  • それをKnowledgeに放り込む

スタイルが確立しそうな予感です。

Powered by WordPress & Theme by Anders Norén