LoginSignup
2
2

Dockerの機能と利用手順をコード付きで解説!!!

Last updated at Posted at 2024-03-02

目的

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.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でフィルターをかけると以下の様になる。


docker_hub.png
右に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オプションで起動したあとに実行するコマンドを書く

docker-compose.yml
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ファイルを作成する。

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のさまざまな使い方について整理した。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2