yuuho.wiki

カオスの欠片を集めて知恵の泉を作る

ユーザ用ツール

サイト用ツール


tips:docker:start

Docker

Docker

install

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce
docker run -it

イメージ

イメージ名,タグの変更

  • docker tag old_name:tag new_name:tag

    元のイメージは消去されない.

イメージ 書き出し/読み込み

gzip 使うとき

docker save hoge/fuga:piyo > hoge_fuga_piyo.tar
docker load < hoge_fuga_piyo.tar

gzip 使わないとき

docker save hoge/fuga:piyo | gzip -c > hoge_fuga_piyo.tar.gz
docker load < hoge_fuga_piyo.tar.gz

dangling なイメージの削除

最近は複雑なフィルタやコマンドライン変数など使わずにできるようになった。

docker image prune

volume

無名 volume の確認

docker volume ls
DRIVER    VOLUME NAME
local     63a68bdc4cd34a2d378502716f9e3582bc3cc2432581470c8077a67773b778b0
local     676245ef8581ad1a2b3481628f6e097d7371ed076b47d02d8d9d70d8bc6a8994

ボリュームの詳細な情報を知ることができる。

docker volume inspect 63a68bdc4cd34a2d378502716f9e3582bc3cc2432581470c8077a67773b778b0

どのコンテナから参照されている volume なのかは各コンテナの詳細情報から調べるしか無い。 以下のようにすればどこにマウントされていたかわかる

docker inspect コンテナID | grep 63a68bdc4cd34a2d378502716f9e3582bc3cc2432581470c8077a67773b778b0

何からも参照されていないもの

docker volume ls -f dangling=true

削除

docker volume rm 63a68bdc4cd34a2d378502716f9e3582bc3cc2432581470c8077a67773b778b0

Dockerfile で sudo 可能ユーザーを作る

ARG GID=1111
ARG UID=1111
ARG CONTAINER_USERNAME=sdwebui
ARG PASSWORD=sdwebui
RUN groupadd -g ${GID} ${CONTAINER_USERNAME} \
    && useradd -m -s /bin/bash -u ${UID} -g ${GID} -G sudo ${CONTAINER_USERNAME} \
    && echo "${PASSWORD}\n${PASSWORD}\n" | passwd ${CONTAINER_USERNAME} \
    && echo "Defaults visiblepw" >> /etc/sudoers \
    && echo "${CONTAINER_USERNAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
USER ${UID}:${GID}

稼働中コンテナに入る

ログイン(login) する。

docker exec -it CONTAINER_ID /bin/bash

rootless Docker

イメージ保存場所の変更

~/.config/docker/daemon.json を変更するべし。 rootfull ならたぶん /etc/docker/daemon.json

v23未満

{
  "graph": "/mnt/extra/docker"
}

v23以降

{
  "data-root": "/mnt/extra/docker"
}

編集したら設定を反映。

systemctl --user restart docker
docker info | grep "Docker Root Dir"

で確認。 /home/USER/.local/share/docker から切り替わっていたらOK。

docker-compose

yaml ファイルの検証

docker compose config

podman

podman は docker(moby) みたいにコンテナ動かすやつ。dockerコマンドを単純に podman に置き換えるだけで使えるようにしているっぽい。 docker よりも優れた点がいくつかある。 rootless docker を使う上で問題となる bind マウントのユーザーの所有権問題などがうまく解決されている?

インストール

管理者権限で podman をインストールすると、全ユーザーが使えるようになる。
基本的には普通に使うと rootless モードで実行される。docker みたいに裏で daemon が走っていたりはしない。

リポジトリ追加

ubuntu18.04, 20.04 はデフォルトではリポジトリがない(公式にはサポート対象外)。

. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" \
    | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key \
    | sudo apt-key add -

インストール

sudo apt update
sudo apt install podman

ubuntu 18.04, 20.04 では少し古いバージョンがインストールされる。 20.04 だとミラーサーバーが壊れてて .deb ファイルがうまくダウンロードされないことがある。

GPUを使用する場合

ランタイムをインストールして設定ファイルを一部変更する。

sudo apt install nvidia-container-runtime

/etc/nvidia-container-runtime/config.toml を一行だけ修正。

sudo vim /etc/nvidia-container-runtime/config.toml
no-cgroups = true

ubuntuのみ追加でやらないといけないこと
nvidia-container-runtime をインストールしたときには /usr/share/containers/oci/hooks.d/oci-nvidia-hook.json が自動生成されるはずだが、 Ubuntu 環境ではうまくいっていないみたい。( 参考 ) なので以下のように自分で作成する。

sudo mkdir -p /usr/share/containers/oci/hooks.d/
sudo vim /usr/share/containers/oci/hooks.d/oci-nvidia-hook.json
oci-nvidia-hook.json
{
    "version": "1.0.0",
    "hook": {
        "path": "/usr/bin/nvidia-container-toolkit",
        "args": ["nvidia-container-toolkit", "prestart"],
        "env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
        ]
    },
    "when": {
        "always": true,
        "commands": [".*"]
    },
    "stages": ["prestart"]
}

使用

基本的には docker コマンドを単純に podman に置き換えるだけ。
デフォルトでは rootless モードで起動される。

GPUを使用する場合

podman run -it --rm --security-opt=label=disable \
    --hooks-dir=/usr/share/containers/oci/hooks.d/ \
    -v /home/horiuchi/work/tmp:/workdir \
    -w /workdir nvidia/cuda:11.3.1-cudnn8-devel-ubuntu20.04 /bin/bash

–security-opt=label=disable–hooks-dir=/usr/share/containers/oci/hooks.d/ が必要無さそう? nvidia イメージを使うと自動的に hooks を見てくれるっぽい。

rootlessモードでコンテナ内の特定のユーザーになる

例えば外で UID=3333 、コンテナ内で UID=4444 になりたい場合、 uidmap の設定をちゃんとしないと bind マウントした volume がコンテナ内で root の所有となるため、 コンテナ内の 4444 ユーザーからアクセスできない。

以下のように起動する。--uidmap オプションを二回入れないといけないところが重要。

podman run -it --rm --uidmap 0:1:4444 --uidmap 4444:0:1 \
        -v /home/horiuchi/tmp:/workdir \
        -w /workdir docker.io/library/ubuntu:20.04 /bin/bash

nvidia のランタイムでは uidmap が効かずに落ちる…(2022/12/06)

本来的には /etc/subuid を参考にもうひとつ --uidmap をする必要がある。 例 --uidmap 4445:4445:61092 (4444+1, 4444+1, 65536-4444, 65536は/etc/subuidの3番目の項目)

podman で docker-compose を使う

podman のデーモンの起動が必要。これでソケットを作って docker の代わりに使えるようにする。

systemctl --user enable --now podman.socket
export DOCKER_HOST=unix:///run/user/1705/podman//podman.sock

VSCode Devcontainer を podman で利用する

devcontainer.json で userns 設定をするっぽい。 もしかしたら nvidia と一緒にはできないかも。

DevContainer

gitリポジトリにおいて、①VSCodeとdevcontainerで環境を使う場合、②docker-composeだけで環境を使用する場合、の2つのやり方を実現したい。

以下のようなディレクトリ構成にするのが良い。

- /
    - docker-compose.yaml
    - Makefile
    - .devcontainer/
        - devcontainer.json
        - docker-compose.yaml   : devcontainer特有のcompose設定

devcontainer.json には次のように書けば良い。

.devcontainer/devcontainer.json
{
    "dockerComposeFile": ["../docker-compose.yaml", "docker-compose.yaml"],
    "service": "CONTAINER_SERVICE_NAME",
    "workspaceFolder": "/workspaces/GIT_REPOSITORY_NAME",
    "postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
}

tips: composeのオーバーライド

docker-compose.override.yaml というファイルを作ると自動的にオーバーライドするような仕組みが存在している(ドキュメントには書かれていない?)

composeファイルを結合するとき、同名の辞書があると要素を追加するような形で結合される。つまり、すでにあった要素は消されない。 明示的に消したい場合、たとえば

ports: !reset[]

と書くことで消去することができるらしい。

tips/docker/start.txt · 最終更新: 2025/02/27 21:25 by yuuho