Dockerを使う(基本編)

Dockerの自分メモ

VMWare上のUbuntuにDockerをインストールする
vmware上のubuntu 17.04 にdockerのredmineをいれる

下記の方のコマンド一覧を参考にして、実際に実行したときの自分メモ。
Dockerコマンドメモ

Dockerとは?

Dockerは仮想化を実現するいくつかの方法のうちの1つを実現するツールである。仮想化にはホスト型、ハイパーバイザー型、コンテナ型があり、Dockerはコンテナ型の仮想化技術になる。

ホスト型はホストのOS上にVMWareなどの仮想化ソフトを実行させて、そこの上にOSをインストールして仮想マシンを構築する方法。
ハイパーバイザー型は、Win10Proなどで利用できるHyper-Vが有名。
コンテナ型は、Linuxカーネルのコンテナ機能LXC(Linux Containers)をツール化したのがこのDockerになる。と思っている。

細かい仕組みはたくさん情報があるので割愛。それぞれにメリット・デメリットがある。

Dockerの大まかなイメージ

コンテナというキーワードがたくさん出てくるが、実際に触るとまずイメージというキーワードが出てくる。

  • Dockerイメージ

乱暴な言い方をすると、実行したいソフトウェアなどの無数のファイル群をtarやZIP圧縮して1個のファイルにまとめたものだと思って今のところ違和感がない。
ただ、このイメージの中身はイメージの入れ子になっていて、ほかのDockerイメージを複数組み合わせて1つのDockerイメージになっているものもある。Dockerイメージレイヤーと呼ばれている。

  • Dockerコンテナ

乱暴な言い方をすると、Dockerイメージを解凍したファイル群をグループ化したものだと思う。
Linuxのコンテナ技術を使って、同じイメージから複数のコンテナを展開してそれぞれ独立して実行させることができる。停止、削除もそのコンテナに対して実行できるので管理が楽でわかりやすい。

同一イメージから複数のコンテナに展開しても、ファイルツリーやプロセス空間がコンテナごとに独立して動作する仕組みになっている。あたかもパラレルワールドの状態になる。

dockerイメージの操作

  • Dockerイメージの検索

Dockerをインストールした直後では、Docker本体は存在するが当然イメージはない。必要なイメージはダウンロードする必要がある。一般的にはDocker Hubから入手する。プログラムソースをGithubから入手するのと似ている。

イメージの検索は、apt searchと似ている。

> docker search nignx
NAME                           DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
apleduardo/nignx-phpfpm                                                        2
diaojjj2017/nignx-v1                                                           1
lnxtm/docker-nginx             nignx                                           1                                       [OK]
jungju/grafana-nignx                                                           0
esquiter/nignx                                                                 0

  • Dockerイメージの取得

docker pullでイメージをダウンロードする。git pullと同じ感覚。

> docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
6ae821421a7d: Pull complete
58702d4af197: Pull complete
b165f42e8fd4: Pull complete
Digest: sha256:18c0755594af107923baa2e65fcef35aea4ab0cea7862d19c27aa127bacb458e
Status: Downloaded newer image for nginx:latest

ローカルにあるイメージの一覧はdocker imagesで確認できる。

>  docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              8c9ca4d17702        3 days ago          109MB
  • Dockerイメージの削除

もしコンテナに展開されている場合はさきにコンテナを削除docker rmしておく必要がある。

先ほどダウンロードしたnginxのイメージを削除してみる。REPOSITORY名かIMAGE IDを指定する。

> docker rmi nginx
  • Dockerイメージの詳細情報
> docker inspect [image]

> docker inspect mysql
[
    {
        "Id": "sha256:81f094a7e4ccc963fde3762e86625af76b6339924bf13f1b7bd3c51dbcfda988",
        "RepoTags": [
            "mysql:latest"
        ],
        "RepoDigests": [
            "mysql@sha256:a571337738c9205427c80748e165eca88edc5a1157f8b8d545fa127fc3e29269"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2019-02-06T07:06:04.898919867Z",
        "Container": "93d3c07fe0cba1f21dcc2e8e644ac8a897305eefee402f270dd6b1b2652635fc",
        "ContainerConfig": {
            "Hostname": "93d3c07fe0cb",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.7",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.15-1debian9"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"mysqld\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:f6ef3ab29f84d76d5b484c15354757977544e81d5da417d95c4116d682c0c331",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "18.06.1-ce",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.7",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.15-1debian9"
            ],
            "Cmd": [
                "mysqld"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:f6ef3ab29f84d76d5b484c15354757977544e81d5da417d95c4116d682c0c331",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 476982381,
        "VirtualSize": 476982381,
        "GraphDriver": {
            "Data": {
                "LowerDir": 
                
                :
                
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

コンテナの展開と開始

先ほどダウンロードしたnginxを例にしてコンテナのnginxを起動してみる。

イメージからコンテナに展開するのはdocker runコマンドで行う。このコマンドでイメージからコンテナに展開してプロセス実行まで行う。また、オプションでホストと仮想コンテナ間のネットワークの設定など指定できる。

下記の例では、nginxコンテナを展開して、--nameで名前を"webserver"、-pでホストの8080番ポートからコンテナ内の80番ポートへ転送するように設定してnginxを起動している。-dはデーモンとして実行する意味だと思う。

ちなみに今回は事前にdocker pullでイメージを取得していたので、そのイメージからコンテナが展開されているが、ない場合は自動的にdocker hubから探してダウンロードする。

> docker run --name "webserver" -d -p 8080:80 nginx
923e637a4cf6a001da8aee08bf76db14b9664ca29eba1cd30d1eea799db5bc3d

webserverという名前でnginxプロセスが稼働している。docker psは稼働しているコンテナの一覧を表示できる。

イメージ的には、通信設定を行った後にservicesystemctlでサービス化するときの処理に似ている。正常な設定ができていれば、この手順は1回だけで良い。

後述するdocker startでも触れているが、サービスの起動を毎回docker runで行ってしまうと、いくつものデーモンが起動してしまうので注意。

ただし-pでポート転送指定するときに値が重複してエラーにはなるが、そうでないものは気が付きにくい。とくにHello-worldなどを何度もdocker runするとコンテナが幾つも生成されてしまう。

コンテナの停止

docker stopコマンドで、稼働中のコンテナを停止することができる。

> docker stop webserver

docker psでプロセスを確認すると、稼働中プロセス一覧には存在してないことが分かる。
(docker ps -aで停止中のコンテナが一覧表示される)

> docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES

2回目以降の起動

最初にdocker runでコンテナを展開した。同じコマンドで実行すると、すでに同じ名前でコンテナが存在している旨のメッセージが表示されてエラーになる。前回コンテナとして展開したプロセスを再度起動したい場合は、docker startコマンドを使う。

> docker run --name "webserver" -d -p 8080:80 nginx
docker: Error response from daemon: Conflict. The container name "/webserver" is already in use by container "923e637a4cf6a001da8aee08bf76db14b9664ca29eba1cd30d1eea799db5bc3d". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

また、起動中コンテナの再起動の場合はdocker restart、状態表示する場合はdocker statsを使う。serviceコマンドと感覚は同じ。(ただしWSLの場合、docker statsがうまく表示できない)

> docker start webserver
webserver
> docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
923e637a4cf6        nginx               "nginx -g 'daemon ..."   3 hours ago         Up 19 seconds       0.0.0.0:8080->80/tcp   webserver

以下はUbuntu上でdockerコンテナを稼働させた状態でdocker statsを実行した結果。2つのコンテナが稼働している。
docker-basic002

コンテナ一覧の表示

稼働中のコンテナはdocker psで一覧表示することができた。停止中のコンテナの表示には、-aをつけて実行する。STATUS列に状態が表示されて、UP xxxが稼働中でExited xxxが停止中になる。NAMES列がコンテナの名前になる。

以下の例では、docker run hello-worldを何度も実行していてHello-worldコンテナがたくさん生成されているような状態になっていることが分かる。

> docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                NAMES
6b4d2c41a8ac        nginx               "nginx -g 'daemon ..."   13 hours ago        Up 5 seconds               0.0.0.0:80->80/tcp   webserver
06ce5eb38488        hello-world         "/hello"                 13 hours ago        Exited (0) 4 minutes ago                        laughing_wozniak
3903232005ae        hello-world         "/hello"                 47 hours ago        Exited (0) 47 hours ago                         reverent_hoover
331a3ea16bb2        hello-world         "/hello"                 47 hours ago        Exited (0) 47 hours ago                         elated_mclean
036b05b3b993        hello-world         "/hello"                 47 hours ago        Exited (0) 47 hours ago                         kind_goldberg
c7df5bd36284        hello-world         "/hello"                 47 hours ago        Exited (0) 47 hours ago                         laughing_lamport
26f6c370b2be        hello-world         "/hello"                 47 hours ago        Exited (0) 47 hours ago                         cranky_mahavira
9b1218b9e518        hello-world         "/hello"                 47 hours ago        Exited (0) 47 hours ago                         friendly_torvalds

不要なコンテナを削除する

docker rmコマンドでコンテナ名かIDを指定して削除できる。削除したあとにdocker ps -aすると、削除したコンテナがなくなっていることが分かる

> docker rm cranky_mahavira

次回は複数コンテナの連携についてまとめる。

-->