目的
dockerの機能を網羅的に解説する。詳細は目次参照。
環境
Ubuntu 20.04
NVIDIA-SMI 525.147.05
GPU RTX3090Ti
CUDA 11.8
ROS NOETIC
IDE VSCODE
docker環境構築
まず、nvidiaドライバをインストールするところからはじめる。Nouveauの無効化するためにターミナルを開き以下を実行、
$ sudo gedit /etc/modprobe.d/blacklist-nouveau.conf
以下を記載して保存、
blacklist nouveau
options nouveau modeset=0
以下を実行して反映、
$ sudo update-initramfs -u
次にnvidiaドライバをインストーする、
$ sudo ubuntu-drivers autoinstall
525がリストにのっていればインストールしても問題ないので以下を実行
$ sudo apt install nvidia-driver-525
リブートする、
$ sudo reboot
これで問題なくUbuntuが起動して自分のアカウントにログインできると成功。
次に、Dockerをインストールする。以下を順番に実行、
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
dockerが起動するか確認、
$ sudo docker run hello-world
sudoなしでdockerを利用するために、ユーザーをdockerグループに所属させる
$ sudo gpasswd -a $USER docker
dockerの再起動、起動中のコンテナはなくなるので注意、
$ sudo systemctl restart docker
/var/run/docker.sockの権限も変更しておく、
$ sudo chown user:docker /var/run/docker.sock
前回と同じコマンドで反映されているか確認、
$ docker run hello-world
次にnvidia dockerをインストールする、
$ distribution=$(. /etc/os-release; echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
$ curl -s -L "https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list" | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
$ sudo apt-get update
$ sudo apt-get install -y nvidia-docker2
$ sudo systemctl restart docker
docker hubを使ってみる
dockerで効率的な開発をするためにはdocker hubにあがっているイメージをダウンロードして差分で必要なモジュールを組んでいくことが基本となる。まずはdocker hubを利用開始するためにアカウントを作る。以下にアクセスしてサインアップする。
https://hub.docker.com/
次に以下のサイトを参考にして、dockerのレジストリ(ローカル)にログインする。
https://www.kagoya.jp/howto/cloud/container/dockerlogin/
以下のコマンドをタイプ、
$ docker login
ユーザーネーム欄にはdocker hubのサインアップ時に使ったメールアドレスを記入、パスワードはdocker hubと同一のものを記入。
これで開発した結果(イメージ)をローカルのレジストリに保存したり、リモート(ハブ)にプッシュできる。リモートへのプッシュについては最後に実施よてい 。
docker hubを実際に使ってみる。右上の検索エディットボックスで"ubuntu 20.04"と検索してみる。検索結果からubuntuを選んで表示し、tagからさらに20.04でフィルターをかけると以下の様になる。
右にcopyのボタンがあるので押し、その結果をubuntuのターミナルにペーストして実行、
$ docker pull ubuntu:20.04
20.04: Pulling from library/ubuntu
8ee087424735: Pull complete
Digest: sha256:bb1c41682308d7040f74d103022816d41c50d7b0c89e9d706a74b4e548636e54
Status: Downloaded newer image for ubuntu:20.04
docker.io/library/ubuntu:20.04
上記のとおり表示されたらdocker hubからイメージのダウンロードに成功。
dockerイメージの利用
docker image pull
はリモートのレジストリからdockerイメージをダウンロードするコマンド。以下のように利用。
docker image pull [オプション] image_name
実際の使用例は以下のとおり、
$ docker pull ubuntu:20.04
上記コマンドでは、以下のオプションが利用可能、
【–quiet , -q】
冗長な出力を省略
【–platform】
サーバーがマルチプラットフォームに対応している場合にプラットフォームを指定
docker image ls
ダウンロード済のイメージを一覧で表示するコマンド、
docker image ls [オプション]
使用例は以下の通り、
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 20.04 18ca3f4297e7 5 weeks ago 72.8MB
上記コマンドでは以下のオプションが利用可能、
【–all , -a】
全てのイメージを表示
※デフォルトでは中間イメージは表示されない。中間イメージとはDockerイメージ生成時に自動で作成されるイメージ、
【digests】
ダイジェスト値を表示
【–filter , -f】
指定した条件でフィルタ検索を実行
【–no-trunc】
詳細な情報を含めて出力
【–quiet , -q】
イメージIDのみを表示
docker image history
は、dockerイメージの履歴を表示するコマンドです。以下のように使う。
docker image history [オプション] image_name
使用例は以下の通り、
$ docker image history ubuntu:20.04
IMAGE CREATED CREATED BY SIZE COMMENT
18ca3f4297e7 5 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 5 weeks ago /bin/sh -c #(nop) ADD file:4b4e122c96445546e… 72.8MB
<missing> 5 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 5 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 5 weeks ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 5 weeks ago /bin/sh -c #(nop) ARG RELEASE 0B
上記コマンドでは、以下のオプションが利用可能、
【–human , -H】
人が読みやすい形式で表示
【–no-trunc】
詳細な情報を含めて出力
【–quiet , -q】
イメージIDのみを表示
docker image rm
ダウンロード済のイメージを削除するコマンド、
docker image rm [オプション] image_name
使用例は以下の通り、
$ docker image rm ubuntu:20.04
Untagged: ubuntu:20.04
Untagged: ubuntu@sha256:bb1c41682308d7040f74d103022816d41c50d7b0c89e9d706a74b4e548636e54
Deleted: sha256:18ca3f4297e795532c0d053ba443d392d5d316ee83ddee0de27f1e742a7db273
Deleted: sha256:28da0445c4497f3ecb56288bd74d91ed1ff6f86578d1d0f6f9cb2781915163b1
本コマンドでは以下のオプションが利用可能、
【–force , -f】
イメージを強制的に削除
【–no-prune】
タグづけされていない親イメージは削除しない
イメージ削除時の記載方法は以下でもOK、
$ docker rmi ubuntu:20.04
dockerコンテナの作成
作成
取得済みのイメージからコンテナを作成と同時にコンテナにログイン、
$ docker run -it ubuntu:20.04
Unable to find image 'ubuntu:20.04' locally
20.04: Pulling from library/ubuntu
8ee087424735: Pull complete
Digest: sha256:bb1c41682308d7040f74d103022816d41c50d7b0c89e9d706a74b4e548636e54
Status: Downloaded newer image for ubuntu:20.04
root@ee238f84c159:/#
ログアウト
ログイン中のコンテナをログアウト。ショートカットキー Ctrl + P
-> Ctrl + Q
を順番に押す。これをVSCODE内でやるとタイピングするとコンテナからログアウトすると同時にVSCODEが閉じるので注意、
一覧表示
コンテナの情報を一覧表示。どのイメージから作成されたか、現在の状態、名前などを確認可能。
すべてのコンテナを表示する場合、
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ee238f84c159 ubuntu:20.04 "/bin/bash" About a minute ago Exited (129) 22 seconds ago jovial_moore
起動中のコンテナのみ表示する場合
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
停止
ログイン中のコンテナを停止する場合
Ctrl + D
or $ exit
ログアウト中のコンテナを停止
$ docker container stop [container id or name]
or
$ docker stop [container id or name]
起動
$ docker container start [container id or name]
or
$ docker start angry_rhodes
ログイン
コンテナのシェルスクリプトを指定してログイン、
$ docker exec -it [container id or name] bash
削除
$ docker container rm [container id or name]
or
$ docker rm [container id or name]
Build Cache の削除
Docker イメージの取得時に生成される Build Cache を削除する。まず、docker が使っているストレージ容量を確認。
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 15 6 57.83GB 44.5GB (76%)
Containers 7 0 139.1GB 139.1GB (100%)
Local Volumes 0 0 0B 0B
Build Cache 97 0 1.428GB 1.428GB
次に Build Cache を削除する。
$ docker builder prune
dockerコンテナの保存と読込
コンテナをバックアップする方法はdocker save
を使う方法とdocker export
コマンドを使う方法がある。
docker saveの場合
次の順番に実行
1)コンテナをimageに落とし込んで(commit)
$ docker commit [container_id] [image_name]
2)imageをtarファイルに圧縮(save)
$ docker save [image_name] > [file_name]
3)別の環境でtarファイルをロード(load)
$ docker load < [tar file_path]
docker exportの場合
1)コンテナをtarファイルに圧縮(export)
$ docker export YOUR_CONTAINER_ID > NAME
2)別の環境でtarファイルをインポート(import)
$ docker import < hogehoge.tar - IMAGE_NAME:TAG
importしたイメージを起動する時はdocker run
コマンドを指定する必要があるので注意。
dockerイメージファイルの作成
欲しいイメージがないとき、もしくはイメージはあってもコンテナ内でのライブラリのインストールに手間がかかる場合にはdockerfileを作成して、その中に必要なインストールコマンドをすべて書き込み、buildコマンドで自らイメージを作成することができる。dockerfileという名前のファイルを作成し、以下を記入して保存、
FROM ubuntu:20.04
RUN apt update && apt upgrade
dockerfileのビルドは以下で実施。新規にイメージができる。
$ docker build -t [image_name]:[tag_name] --file=[docker_file_path] .
この後でコンテナを作るためにdocker run
コマンドを指定する必要があるので注意。
Ubuntuの通常アカウントの様にコンテナを作成してログインしたい場合には以下をbuild、アカウントはinitialを例として設定、
FROM ubuntu:20.04
# apt update
RUN apt-get update
RUN apt-get install -y sudo
# add sudo user
RUN groupadd -g 1000 developer && \
useradd -g developer -G sudo -m -s /bin/bash initial && \
echo 'initial:initial' | chpasswd
RUN echo 'Defaults visiblepw' >> /etc/sudoers
RUN echo 'initial ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER initial
Dockerfile では以下のコマンドを使用可能、
コマンド | 説明 |
---|---|
FROM | ベースとなるイメージ |
RUN docker build | 時に実行するコマンド |
CMD | docker run 時に実行するコマンド |
ENTRYPOINT | docker run 時に実行するコマンド |
MAINTAINER | 作者情報 |
LABEL | ラベル情報(メタデータ) |
EXPOSE | 公開ポート番号 |
ENV | 環境変数 |
ARG | 一時変数 |
COPY | ホストからコンテナへのファイルコピー |
ADD | ホストからコンテナへのファイルコピー |
VOLUME | ボリューム |
USER | 実行ユーザ |
SHELL | シェル指定 |
WORKDIR | ワークディレクトリ |
ONBUILD | ビルド時に実行するコマンド |
STOPSIGNAL | コンテナ終了時に送信されるシグナル |
HEALTHCHECK | ヘルスチェック |
opencv-4.5/cuda-11.1のdockerfileの作成例、
FROM nvidia/cuda:11.1-devel-ubuntu20.04
ARG OPENCV_VERSION=4.5.0
RUN apt-get update && apt-get upgrade -y &&\
# Install build tools, build dependencies and python
apt-get install -y \
python3-pip \
build-essential \
cmake \
git \
wget \
unzip \
yasm \
pkg-config \
libswscale-dev \
libtbb2 \
libtbb-dev \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libavformat-dev \
libpq-dev \
libxine2-dev \
libglew-dev \
libtiff5-dev \
zlib1g-dev \
libjpeg-dev \
libavcodec-dev \
libavformat-dev \
libavutil-dev \
libpostproc-dev \
libswscale-dev \
libeigen3-dev \
libtbb-dev \
libgtk2.0-dev \
pkg-config \
## Python
python3-dev \
python3-numpy \
&& rm -rf /var/lib/apt/lists/*
RUN cd /opt/ &&\
# Download and unzip OpenCV and opencv_contrib and delte zip files
wget https://github.com/opencv/opencv/archive/$OPENCV_VERSION.zip &&\
unzip $OPENCV_VERSION.zip &&\
rm $OPENCV_VERSION.zip &&\
wget https://github.com/opencv/opencv_contrib/archive/$OPENCV_VERSION.zip &&\
unzip ${OPENCV_VERSION}.zip &&\
rm ${OPENCV_VERSION}.zip &&\
# Create build folder and switch to it
mkdir /opt/opencv-${OPENCV_VERSION}/build && cd /opt/opencv-${OPENCV_VERSION}/build &&\
# Cmake configure
cmake \
-DOPENCV_EXTRA_MODULES_PATH=/opt/opencv_contrib-${OPENCV_VERSION}/modules \
-DWITH_CUDA=ON \
-DCMAKE_BUILD_TYPE=RELEASE \
# Install path will be /usr/local/lib (lib is implicit)
-DCMAKE_INSTALL_PREFIX=/usr/local \
.. &&\
# Make
make -j"$(nproc)" && \
# Install to /usr/local/lib
make install && \
ldconfig &&\
# Remove OpenCV sources and build folder
rm -rf /opt/opencv-${OPENCV_VERSION} && rm -rf /opt/opencv_contrib-${OPENCV_VERSION}
上記を使うためには以下でbuild
docker build -t [image_name] .
上記で作成したimageからcontainerを作るためには以下を実行、なおsample_dockerは任意につけた名前、
$ docker run sample_docker/opencv-cuda:cuda-11.1-opencv-4.5
dockerでGUIをつかう
docker内からウィンドウを表示できるようにするため、dockerと異なるターミナルで以下を実行
$ xhost +
or
$ xhost +local:root
docker runコマンド時にホストマシンのXの利用を許可するオプションを追加、
docker run --gpus all -it --privileged --net=host --ipc=host -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -v $HOME/.Xauthority:/home/$(id -un)/.Xauthority -e XAUTHORITY=/home/$(id -un)/.Xauthority sample_docker/opencv-cuda:cuda-11.1-opencv-4.5
dockerとROSを連携する
ベースイメージはros:noetic-desktop-fullを利用、ubuntu20.04のイメージにROSをインストールする方法もあるが時間がかかるのでROSインストール済みのイメージを利用。dockerfileの書き方は以下を参照、
FROM osrf/ros:noetic-desktop-full
ARG OPENCV_VERSION=4.5.0
RUN apt-get update && apt-get upgrade -y &&\
# Install build tools, build dependencies and python
apt-get install -y \
python3-pip \
build-essential \
cmake \
git \
wget \
unzip \
yasm \
pkg-config \
libswscale-dev \
libtbb2 \
libtbb-dev \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libavformat-dev \
libpq-dev \
libxine2-dev \
libglew-dev \
libtiff5-dev \
zlib1g-dev \
libjpeg-dev \
libavcodec-dev \
libavformat-dev \
libavutil-dev \
libpostproc-dev \
libswscale-dev \
libeigen3-dev \
libtbb-dev \
libgtk2.0-dev \
pkg-config \
## Python
python3-dev \
python3-numpy \
&& rm -rf /var/lib/apt/lists/*
RUN cd /opt/ &&\
# Download and unzip OpenCV and opencv_contrib and delte zip files
wget https://github.com/opencv/opencv/archive/$OPENCV_VERSION.zip &&\
unzip $OPENCV_VERSION.zip &&\
rm $OPENCV_VERSION.zip &&\
wget https://github.com/opencv/opencv_contrib/archive/$OPENCV_VERSION.zip &&\
unzip ${OPENCV_VERSION}.zip &&\
rm ${OPENCV_VERSION}.zip &&\
# Create build folder and switch to it
mkdir /opt/opencv-${OPENCV_VERSION}/build && cd /opt/opencv-${OPENCV_VERSION}/build &&\
# Cmake configure
cmake \
-DOPENCV_EXTRA_MODULES_PATH=/opt/opencv_contrib-${OPENCV_VERSION}/modules \
-DWITH_CUDA=ON \
-DCMAKE_BUILD_TYPE=RELEASE \
# Install path will be /usr/local/lib (lib is implicit)
-DCMAKE_INSTALL_PREFIX=/usr/local \
.. &&\
# Make
make -j"$(nproc)" && \
# Install to /usr/local/lib
make install && \
ldconfig &&\
# Remove OpenCV sources and build folder
rm -rf /opt/opencv-${OPENCV_VERSION} && rm -rf /opt/opencv_contrib-${OPENCV_VERSION}
# Install apt packages
RUN apt-get update && apt-get install -y git vim wget tmux terminator && apt-get clean && rm -rf /var/lib/apt/lists/*
# Install ROS packages
RUN apt-get update && apt-get install -y \
ros-noetic-joy ros-noetic-teleop-twist-joy \
ros-noetic-teleop-twist-keyboard ros-noetic-laser-proc \
ros-noetic-rgbd-launch ros-noetic-rosserial-arduino \
ros-noetic-rosserial-python ros-noetic-rosserial-client \
ros-noetic-rosserial-msgs ros-noetic-amcl ros-noetic-map-server \
ros-noetic-move-base ros-noetic-urdf ros-noetic-xacro \
ros-noetic-compressed-image-transport ros-noetic-rqt* ros-noetic-rviz \
ros-noetic-gmapping ros-noetic-navigation ros-noetic-interactive-markers \
ros-noetic-dynamixel-sdk \
ros-noetic-turtlebot3-msgs \
ros-noetic-turtlebot3 && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Create ROS workspace
RUN echo "source /opt/ros/noetic/setup.bash" >> /root/.bashrc
RUN mkdir -p /root/catkin_ws/src
RUN cd /root/catkin_ws && /bin/bash -c "source /opt/ros/noetic/setup.sh; catkin_make"
RUN echo "source /root/catkin_ws/devel/setup.bash" >> /root/.bashrc
RUN cd /root/catkin_ws/src && git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3_simulations.git
RUN cd /root/catkin_ws && /bin/bash -c "source /opt/ros/noetic/setup.bash; catkin_make"
イメージの作成は以下、
$ docker build -t sample_ros_image:latest .
コンテナの作成は以下、
docker run -it \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--name=turtlebot_ros \
sample_ros_image:latest \
bash
dockerコンポーズを使ってみる
dokcer-composeをインす―ルする。
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
上記でインストールが完了する。
Turtlebot3 Gazeboを起動するdocker-compose.ymlの例。GUIを表示するための環境変数などを追加、commandオプションで起動したあとに実行するコマンドを書く
version: "3"
services:
ros:
image: sample_ros_image:latest
container_name: sample_container
environment:
- DISPLAY
- QT_X11_NO_MITSHM=1
- TURTLEBOT3_MODEL=burger
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
tty: true
command: bash -c "source /root/catkin_ws/devel/setup.bash; roslaunch turtlebot3_gazebo turtlebot3_world.launch"
network_mode: "host"
docker-compose upでGazeboのturtlebot3_worldが起動する
downするとdockerコンテナが消えるので注意
$ docker-compose up
$ docker-compose down
実行後にROSトピックを見たりファイル編集したい場合execコマンドでdocker コンテナに入る。
docker-composeでコンテナを作成するとdocker attachコマンドが使えないので注意。
$ docker exec -it sample_container bash
dockerで複数のコンテナを連携させる
ros_tutorialsのtalkerとlistenerを別々のコンテナで実行してコンテナ間で通信するサンプルを作成する。ベースイメージのros:noeticにはros_tutorialはインストールされていないため、ros_tutorialをインストールするDockerfileを作成する
FROM ros:noetic-ros-core
RUN apt-get update && apt-get install -y
RUN apt-get install -y ros-noetic-ros-tutorials \
ros-noetic-common-tutorials \
&& rm -rf /var/lib/apt/lists/
dockefileをbuildしてイメージの作成
$ docker build --tag ros:ros-tutorials .
コンテナを作成して実行するためのdocker-compose.ymlファイルを作成する。
version: '3'
networks:
ros:
driver: bridge
services:
ros-master:
image: ros:noetic-ros-core
hostname: ros-master
command: roscore
networks:
- ros
restart: always
talker:
image: ros:ros-tutorials
depends_on:
- ros-master
hostname: talker
environment:
- "ROS_HOSTNAME=talker"
- "ROS_MASTER_URI=http://ros-master:11311"
command: rosrun roscpp_tutorials talker
networks:
- ros
restart: always
listener:
image: ros:ros-tutorials
depends_on:
- ros-master
hostname: listener
environment:
- "ROS_HOSTNAME=listener"
- "ROS_MASTER_URI=http://ros-master:11311"
command: rosrun roscpp_tutorials listener
networks:
- ros
restart: always
以下で実行する、
$ docker-compose up
docker-composeで作成されるコンテナは以下の3つ
コンテナ | 説明 |
---|---|
ros-master | ROS masterにするコンテナ roscoreだけ実行 |
talker | tutorials talkerを実行するコンテナ |
listener | tutorials listenerを実行するコンテナ |
dockerをVSCODEから使ってみる
VS Code の拡張機能 dockerをインストール。詳細は以下の3つを参照方。
https://qiita.com/katakaku/items/b8dcac4aa14d585e4038
https://qiita.com/IsHYuhi/items/b96b50f907626bc4e376
https://qiita.com/829yasubee/items/d336c26f3a5393a264ac
まとめ
dockerのさまざまな使い方について整理した。