LoginSignup
12
14

More than 3 years have passed since last update.

Docker ただの基礎からの復習

Last updated at Posted at 2020-02-06

1.Dockerのインストール

1-1Docker Desktop for 〇〇をダウンロードし、インストールする

Docker Desktop for Mac
Docker for Mac で Dockerコンテナを実行する場合、MacOSで直にコンテナが動作するのではなく、HyperKitというMacの仮想化機能を利用して内部的には軽量のLinuxを動作させ、その上でDockerコンテナを実行します。

本編は、Docker Desktop for Mac を利用していますが、基本的なDockerコマンドなどの使い方はWindowsも同じです。
Windowsをお使いの場合は、Windows Docker Desktop for Windowsを利用してください。

2.Dockerコンテナの実行

2-1 hello-worldを動作させてみよう

とりあえず、hello-worldイメージを実行し、コンテナを動かして見ましょう。

docker run hello-world

スクリーンショット 2019-06-29 21.26.44.png
初回は、インターネット経由でDocker HubからDockerイメージをダウンロードしてきます。
同じDockerイメージがPC上に存在する場合は、②③が省略され、ローカル上にあるDockerイメージからDockerコンテナが実行されます。

:でタグを指定できます。指定が何もない場合は、latest(最新)となります。

下記のように実行してみましょう。ただし、実行結果は「2-1.hello-worldを動作させてみよう」と同じ結果になります。

docker run hello-world:latest

2-2 Dockerイメージ

Dockerイメージとは、コンテナの実行に必要なファイルを纏めたファイルシステムです。

image.png
一度作成したイメージのレイヤーは、「読み取り専用」となり変更を加えることはできません。
コンテナレイヤー上にファイルの追加や削除を行い、それをまたDockerイメージとして保存することも可能です。

whalesayイメージを実行し、Helloと喋らせてみましょう。

docker run docker/whalesay cowsay Hello

Unable to find image 'docker/whalesay:latest' locally
latest: Pulling from docker/whalesay
e190868d63f8: Pull complete 
909cd34c6fd7: Pull complete 
0b9bfabab7c1: Pull complete 
a3ed95caeb02: Pull complete 
00bf65475aba: Pull complete 
c57b6bcc83e3: Pull complete 
8978f6879e2f: Pull complete 
8eed3712d2cf: Pull complete 
Digest: sha256:178598e51a26abbc958b8a2e48825c90bc22e641de3d31e18aaf55f3258ba93b
Status: Downloaded newer image for docker/whalesay:latest
 _______ 
< Hello >
 ------- 
    \
     \
      \     
                    ##        .            
              ## ## ##       ==            
           ## ## ## ##      ===            
       /""""""""""""""""___/ ===        
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~   
       \______ o          __/            
        \    \        __/             
          \____\______/ 

ローカル上にダウンロード済みのDockerイメージの一覧を表示させてみましょう。

docker images

Dockerイメージにタグ付けすることも可能です。

docker tag docker/whalesay whalesay:v1

コンテナの情報を取得してみましょう。

docker inspect docker/whalesay

作成したdocker/whalesayを削除してみましょう。
なお、dockerが起動しているときにDockerイメージを削除することはできません。
dockerが起動しているときに、強制的にDockerイメージを削除する場合は、docker rmi の後に -f をつけることによって、強制的に削除することも可能ではあります。(下記の例では、-f は使っていません。)

docker rmi docker/whalesay

Dockerイメージを削除したので、Dockerコンテナは実行せず、Dockerイメージをダウンロードだけするには、pullします。

docker pull docker/whalesay

2-3 Dockerファイル

先程は、DockerイメージをDocker Hubから取得してきましたが、Dockerファイルを作成してビルドすることも可能です。

まず、作業用のフォルダを作成しておきましょう。

mkdir imagebuild
cd imagebuild

下記のとおり、Dockerfileを作成します。

Dockerfile
FROM docker/whalesay:latest
RUN apt-get -y update && apt-get install -y fortunes
CMD /usr/games/fortune | cowsay

## FROM : ベースイメージの指定
## RUN  : コマンド実行
## CMD  : デーモン実行

作成したDockerfileファイルからイメージをビルドするには以下のコマンドを実行します。-tはタグの指定です。

docker build -t docker-whale .

ビルドしたイメージを実行して見ましょう。

docker run docker-whale
 ________________________________________ 
/ As the trials of life continue to take \
| their toll, remember that there is     |
| always a future in Computer            |
| Maintenance.                           |
|                                        |
\ -- National Lampoon, "Deteriorata"     /
 ---------------------------------------- 
    \
     \
      \     
                    ##        .            
              ## ## ##       ==            
           ## ## ## ##      ===            
       /""""""""""""""""___/ ===        
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~   
       \______ o          __/            
        \    \        __/             
          \____\______/   

ちなみに2回目以降、キャッシュをを使用せずビルドするには、以下のように実行します。

docker build --no-cache -t docker-whale .

次に自身で作成したDockerイメージをDockerHubに公開して見ましょう。
[DockerHub]の Repository に docker-whale を作成しておいてください。

Docker Hubにログインします。

docker login

タグをつけておきます。

docker tag docker-whale <Docker ID>/docker-whale:v1

DockerイメージをDockerHubにPushし、DockerHubにあることを確認しましょう。

docker push <Docker ID>/docker-whale:v1

2-4 デタッチモード(-d)

-d はデタッチモードといい、コンテナの実行をバックグラウンドで行うものです。

docker run --name nginx-d1 -d -p 8080:80 nginx

http://localhost:8080/にアクセスすると表示されると思います。

なお、-p の動作について図で簡単に見ておきましょう。
image.png
localhost:8080はコンテナのPort:80に転送するという意味です。

-d をつけない場合との動作の違いを確認しておきましょう。

docker run --name nginx-d2 -p 8080:80 nginx

http://localhost:8080/にアクセスして見ましょう。

WEBページの表示は変わりませんが、WEBページにアクセスした際、↓のようにログが画面に流れていることがわかります。

172.17.0.1 - - [03/Jul/2019:10:38:14 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-"
172.17.0.1 - - [03/Jul/2019:10:38:22 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-"

この状態ではフォアグラウンドで動作しているので、ctrl+C でプロセス終了した場合、コンテナも停止されてしまうという違いがあります。
そのため、WEBページなどは基本デタッチモードで動作させるようします。

2-5 マウント(-V)

ホストマシンにあるディレクトリをコンテナ上にマウントしてみましょう。

私はMacを利用しています。まずは、/Users/<ユーザ名>/docker/htmlにindex.htmlを作成しておきます。

index.html

<!DOCTYPE html>
<html>
<body>

<h1>hellow</h1>

</body>
</html>

では、マウントしてみましょう。

docker run --name nginx-m1 -v /Users/<ユーザ名>/docker/html:/usr/share/nginx/html:ro -d -p 8080:80 nginx

http://localhost:8080/にアクセスし表示されるか確認しましょう。
表示されたことが確認できたら、/Users/<ユーザ名>/docker/html/index.htmlの内容を編集し、編集内容が反映されているかも再度アクセスして確認してみましょう。

2-6 コピー(copy)

COPYコマンドはホストマシン↔︎コンテナ内にコピーするコマンドです。

Dockerコンテナを用意しておきます。

docker run --name nginx-c1 --rm -d nginx

作業しやすいように、copyディレクトリを作成しておきます。

mkdir copy
cd copy/

copyコマンドで設定ファイルを取り出してみます。先程作成したnginx-c1の中にあるdefault.confを取り出します。lsでコピーされたかも確認しておいてください。

docker cp nginx-c1:/etc/nginx/conf.d/default.conf ./ 
ls

ここでは、動作検証のためにわざとlisten:8080に変え、→ DockerFileを作成し、→ ビルドします。

default.conf
listen:8080

## 80→8080に変更する。
Dockerfile
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/default.conf
docker build -t nginx:c2 .

Dockerコンテナをlisten:80で実行しますが、これは先程default.confをlisten:8080に変更したのでアクセスできません。

docker run --name web -p 8080:80 --rm nginx:c2

8080番ポートだと、アクセスできるようになりました。

docker run --name web -p 8080:8080 --rm nginx:c2

2-7 Dockerの基本コマンド

i はコンテナの標準入力を取得して、双方向に接続できるようにするもので、
t はコンテナ内にttyを割り当てる意味があります。
コンテナでシェルを実行して、フォアグラウンドで実行状態にしておきたい場合はよく使われます。

docker create --name c-container -it alpine /bin/sh

コンテナの一覧を表示させるコマンドです。

docker ps     実行中のコンテナを表示する。
docker ps -a 実行中以外のコンテナも表示する。

その他、Dockerを開始や停止するコマンドです。

docker start 開始
docker stop 停止
docker pause 一時停止
docker unpause 一時停止を解除

2-8 シェルへの接続(attach,exec)

起動中のコンテナに接続する方法を確認して行きましょう。2通りあります。

attach
exec ☆推奨

とりあえず、Dockerコンテナを起動します。

docker run --name shell-1 -it ubuntu /bin/bash

まずは、attachで接続して、exitで抜けてみます。
attachで接続し、exitで抜けた場合は、プロセスが終了し、コンテナも終了されてしまうので注意が必要です。
基本的にはctrl+p ctrl+qでぬけることで、コンテナも終了せずにできます。
ただし、起動時に-itをつけていない場合は、ctrl+p ctrl+qでぬけることができません。

docker attach shell-1
exit

次に、execで接続し、同じようにexitで抜けてみましょう。
この場合は、exitで抜けてもコンテナは起動したままの状態です。
そのため、基本的にはexecで接続するようにします。

docker exec -it shell-1 /bin/bash
exit

2-9 docker commit

commitコマンドは、コンテナに対して行った設定や更新したファイルを、新しいDockerイメージとして格納することが出来ます。
ただし、コンテナ内で行われた作業はどこにも明確な記録として残らないため、極力「2-3 Dockerファイル」を使うようにしましょう。

Dockerコンテナを作成しておきます。

docker run --name commit-1 -it -d --rm ubuntu /bin/bash

このDockerコンテナに、何かしらの変更をしておきます。

docker exec -it commit-1 /bin/bash
cd /tmp/
dd if=/dev/zero of=tempfile bs=1M count=10
exit

commit-1をcommit-2としてコミットし、→ 新しいDockerコンテナを起動すると完了です。

docker commit commit-1 commit-2
docker run -it commit-2 /bin/bash

2-10 リンク(--link)

コンテナ名、またはエイリアスでリンク先に通信できるようにします。
ただし、--linkオプションはすでに非推奨ですので、後述の「Dockerのネットワーク」を主に学習してください。
なので、ここでは--linkオプションについては簡単な操作だけ行います。
image.png

作業用のproxyというフォルダを作成しておきましょう。

mkdir proxy
cd  proxy

reverse_proxy.conf を作成しておきます。

reverse_proxy.conf
server {
    listen 8080
    server_name localhost;

    location / {
        proxy_pass http://ss;
    }
}

先程作成したreverse_proxy.confを使い、Dockerfileを作成します。

Dockerfile
FROM nginx:latest
COPY /reverse_proxy.conf /etc/nginx/conf.d/reverse_proxy.conf
RUN apt-get update && apt-get install -y inetutils-ping

proxyという名前でDockerfileをビルドします。

docker build -t proxy .

dockersamples/static-siteのdockerコンテナを実行します。

docker run --name website -e AUTHOR="naata" -d dockersamples/static-site

proxyのdockerコンテナを実行します。

docker run --name webproxy -p 8080:8080 --link website:ss -d proxy

websiteとwebproxyのdockerコンテナが起動していることを確認しておきます。

docker ps

http://localhost:8080にアクセスして表示されるか確認してみましょう。これで、webproxyを経由して、websiteが表示されていることになります。

3 Automated build

Githubなどのソースコードのホスティングサービスでビルドテキストを管理し、リポジトリ上のビルドコンテキストを管理し、リポジトリ上のビルドコンテキストの内容が変更された場合に自動的にビルドを実行する仕組み。

3-1 GitHub にレポジトリを作成

GithubにDocker_Automated_buildというrepositoryを作成しておいてください。

3-2 Dockerhub 設定

自分のアカウントから[Account Settings]をクリック。
image.png

[Linked Accounts]のGitHubで[Connect provider]をクリック。
image.png

docker_repositoryをdocker_automated_buildで作成し、「3-1 GitHub にレポジトリを作成」で作成したgit_repositoryを選択する。
image.png

基本的な設定は以上なので、検証していきます。

3-3 検証##

以下は通常のgit操作となりますので、詳しい説明は省略します。

git config --global user.name ""
git config --global user.email ""

git clone https://github.com/aaa/Docker_Automated_build

cd Docker_Automated_build/
Dockerfile
FROM dockersamples/static-site
ENV AUTHOR="naata"
git add Dockerfile
git commit -m "First Automated"
git push origin master

DockerHubを確認し、SUCCESSとなっていればOK
スクリーンショット 2020-02-05 19.13.25.png

念のため pull して確認もしておきましょう。

docker pull aaa/docker_automated_build
docker images

4 Docker Machine

4-1 Docker Machine

Docker Machineは、Docker for Mac / Docker for WindowsまたはDocker toolboxに付属してインストールされるソフトウェアです。
Docker Engineをインストールした仮想マシンの作成、起動、停止、再起動などをコマンドラインから実行することができるツールです。

4-2 Dockerホストの作成

単純にローカルPCにDockerホストを作成していきます。

docker-machine create --driver virtualbox default

作成されたか確認して見ましょう。

docker-machine ls

作成されたDockerホストに接続して見ましょう。操作対象のDockerホストを設定するための、設定コマンドが表示されます。
環境変数を設定すると、Docerコマンドの操作対象がenvの引数に指定したDockerホストに設定されます。

docker-machine env default 

eval $(docker-machine env default)

確認のために、hello-worldコンテナを実行し見ましょう。

docker run hello-world

Dockerホストにsshすることもできます。

docker-machine ssh default

exitで抜けましょう。

exit

dockerホストのipを確認し、nginxを実行し、このipでwebページがかえってくるか確認して見ましょう。

docker-machine ip default
docker run -d -p 8080:80 nginx

docker-machine を明示的に停止、開始するには以下の通り指定します。

docker-machine stop default
docker-machine start default

activeなdocker-machineを解除するには。

docker-machine env -u
eval $(docker-machine env -u) 

5 Dockerのネットワーク

「2-10 リンク(--link)」で紹介した--linkオプションは利用せず、ユーザー定義ネットワークを使う方法が推奨されています。

docker networkの一覧を表示すると、デフォルトで3つのネットワークがあることがわかります。

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3d43dcdb4080        bridge              bridge              local
8b1af105abd9        host                host                local
afffac7bcd1b        none                null                local

5-1 bridge

コンテナはデフォルトでブリッジドライバーに所属します。

ブリッジネットワークの詳細を確認して見ましょう。

docker network inspect bridge
subnet → このネットワーク内のipが割り当てられる。
Getway → dockerホストのdocker0に割り当てられたI/Fとなります。

コンテナを2つ起動して見ましょう。

docker run -itd --name net1 alpine /bin/sh
docker run -itd --name net2 alpine /bin/sh

それぞれのコンテナにipが割り当てられたことを確認します。

docker inspect brige

コンテナ net1 ↔︎ net2 で疎通ができるか確認してみましょう。

ping <ip>

なお、デフォルトでdnsは提供されないため、コンテナ名で通信することはできません。そのため、ネットワークを追加します。

docker network create my_net

これに先ほどのコンテナ2台を追加します。

docker network connect my_net net1
docker network connect my_net net2

これで、 net1 ↔︎ net2 がコンテナ名で通信できるか確認してみましょう。

ping <コンテナ名>

ちなみに、最初からmy_netネットワークに所属させるためには以下のコマンドを使います。

docker run -itd --name net3 --network my_net alpine

また、ネットワークを切り離すには以下のとおり実行します。

docker network disconnect bridge net2

5-2 none

nullドライバに接続してコンテナは、ループバックI/F以外にネットワークI/Fを持たない状態になります。
また、noneネットワークを接続するコンテナは、その他の全てのネットワークを切断した状態にしなければいけません。

docker run -itd --name none1 --network none alpine /bin/sh
docker attach none1
ip addr show
/ # ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever

5-3 host

hostドライバを使用したネットワークです。
hostネットワークに接続したコンテナはdockerホストと同じネットワーク設定を持ちます。
ホストネットワークのコンテナでwebサーバーを起動した場合、ホストマシンのipの80でlistenしているのと同じ動作になります。
そのため、-p を利用しなくても、コンテナを起動しただけで、dockerホストの80にアクセスすれば、コンテナの80に接続することができます。

docker run -d --name host --network host nginx

hostのipにアクセスして表示されるか確認だけしておきましょう。

6 Dockerのデータ管理

コンテナで扱う動的なデータは起動中のコンテナの読み書き可能なレイヤーにおくこともできますが、いくつかのデメリットがあります。
それは、
・コンテナが削除された時点でデータは消えてしまう。
・コンテナ間でデータを共有することができない。
・書き込みのパフォーマンスもホスト上へのデータの書き込みに加えて、書き込みのパフォーマンスがよくない。
これは、通常のファイルシステムとは異なるユニオンファイルシステムが利用されているためです。
dockerにはホスト上のディレクトリやファイルをコンテナにマウントする仕組みやホストのメモリをファイルシステムとしてコンテナにマウントする仕組みが用意されています。

6-1 volume

image.png
複数のコンテナにマウントすることもでき、複数のコンテナで共通のファイルを読み書きすることができます。
ただし、異なるホスト間で共有することはできません。
ボリュームはコンテナが削除されても消えず、明示的に削除するまで消えません。

まずは、docker volumeコマンドをいくつか覚えましょう。

docker volumeを作成するコマンドです。

docker volume create vol-1

一覧を表示するコマンドです。

docker volume ls

詳細情報を確認するコマンドです。

docker volume inspect vol-1

削除するコマンドです。

docker volume rm vol-1

ではここから、volumeをマウントする方法です。2つの方法があります。
-v
--mount → 基本的にこっちの方が推奨されているのでこっちで覚えましょう。

今回は-vでも試してみます。ここではまだvolumeがないのでvol2を作成ています。

docker run -itd --name mount1 -v vol2:/app nginx

--mountで試します。

docker run -itd --name mount2 --mount source=vol2,target=/app nginx

docker execで接続して、同じファイルがあるか確認しておきましょう。

docker exec -itd mount1 /bin/bash
cd /app
touch hogehoge
exit

docker exec mount2
cd /app

読み取り専用(readonly)にする場合は、以下のとおり実行します。

docker run -itd --name mount3 --mount source=vol3,destination=/etc/nginx,readonly nginx

6-2 bind mount

image.png
ホストが管理しているファイルやディレクトリをコンテナにマウントします。

これも2つの方法があります。

-v
--mount → 基本的にこっちが推奨されているのでこっちを使います。

-vでカレントディレクトリに存在しないディレクトをマウントします。

docker run -itd --name bindmount1 -v "$(pwd)"/source:/app nginx

lsでsourceディレクトリが作成されていることを確認しておきましょう。

ls
T632717CF0F94D06EE      source

--mountを利用する場合は、type=bindを指定します。

docker run -itd --name bindmount2 --mount type=bind,source"$(pwd)"/source2,target=/app nginx

エラーになったと思います。
--mountではディレクトが存在しない場合はエラーになります。これにより謝って空のディレクトリをマウントしてしまわないことを防ぎます。

6-3 tmpfs

image.png
ホストのメモリ領域をマウントします。ホストやDockerがシャットダウンされた場合は、データは消えます。なので、一時的なものをおくために利用します。

type=tmpfsで指定します。

docker run -itd --name tmpfs1 --mount type=tmpfs,destination=/app nginx

7 Docker Compose

Docker compose とは、複数のコンテナから成るサービスを構築・実行する手順を自動的にし、管理を容易にする機能です。
Docker compose では、compose ファイルを用意してコマンドを1 回実行することで、そのファイルから設定を読み込んですべてのコンテナサービスを起動することができます。

7-1 docker-compose.yml

サービス 説明
image ベースイメージの指定
build Dockerfileの指定
command コンテナ内で実行するコマンドの設定
links コンテナ間リンク設定
ports ホストOS外部への公開ポート設定
expose コンテナ間のみでの公開ポート設定
volumes ボリュームマウントの設定
volumes_from 別コンテナをボリュームとしてマウントするための設定
environment 環境変数設定
env_file 環境変数をファイル読み込みで設定
container_name コンテナの名前設定

7-2 docker-composeインストール

OSごとのインストール方法は↓。
Install Docker Compose

インストールされていることを確認しておきましょう。

docker-compose --version

7-3 docker-compose.ymlの作成

作業ディレクトリdocker-compose-testを作成しておきましょう。

mkdir docker-compose-test
cd  docker-compose-test

ここでは、dbwordpressを作成しています。

docker-compose.yml

version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - "./.data/db:/var/lib/mysql"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    links:
      - db
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_PASSWORD: wordpress

後は以下コマンドで起動完了です。

docker-compose up -d

8 dockerignore

Dockerfileからイメージをビルドする場合、Dockerfileの存在するディレクトリの中身はtarで固められdaemonへと送られます。
このようなimageに含まないファイルも送信するため、dockerignoreを使います。

そもそも不要なファイルを含めなければいいと思いますが。。。

詳しくは、↓のページを参考にさせていただきました。
.dockerignore アンチパターン

12
14
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
12
14