RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

Dockerの基本操作をまとめてみた

はじめに

こんにちは。新卒2年目のtaku_76です。といってもあと半月ほどで3年目になります。
今回は以前ある記事でコンテナ技術の習得は必須ということを見て、コンテナ技術について表面的なことしか知らないなーと思い、学習しています。まだ学習途中ですが、初めに学んだ基本的な内容をまとめておこうと思います。

Dockerとは

Docker社が提供しているコンテナ型のアプリケーション実行環境です。

コンテナ型の仮想化とは

OSのカーネルを利用してホストOS上にアプリケーション実行環境を作るものです。
以下のような構造となっています。

f:id:taku_76:20200312011222p:plain
コンテナ型仮想化の構成
Docker Engineがコンテナ型仮想化のコアとなる部分で、コンテナの作成、起動、停止、削除などの操作はDocker Engineを介して行われます。使い方としましてはDockerのコマンドを実行することでDocker Engineに指示を出すことになります。 以下にコンテナ型仮想化のメリットとデメリットをまとめます。

  • メリット

    • ホストOSのカーネルを使用するため、動作が早くリソースの使用率が少ない
    • 同じDockerイメージからコンテナを起動することで、環境が変わっても問題なく動作させることができる
  • デメリット

    • コンテナはホストOSのカーネルを使用して動作するため、カーネルを共有できないOSでコンテナを動作させることができない

Dockerイメージとは

特定のコンテナを実行するのに必要なファイルをまとめたファイルシステムです。一般的にOSのライブラリやアプリケーションなどがあり、Dockerイメージは自分で作成することもできます。構成としてはイメージのデータはレイヤーで構成され、読み取り専用なので編集することはできません。以下Dockerイメージの構成となります。 f:id:taku_76:20200312013328p:plain 左がDockerイメージで右がDockerイメージから作成したコンテナの図になります。Dockerイメージは図のように階層構造でデータが管理されており、各層のレイヤーはコマンドを実行する際に階層が積み重ねられます。そして、Dockerイメージを元にコンテナを起動すると読み書き可能なコンテナレイヤーの層が作られます。コンテナレイヤー上にファイルの追加など行い、それをまたイメージとして保存することも可能です。注意として、過去のレイヤーで追加したファイルをコンレナレイヤーで削除し、新しいイメージを作成しても過去のレイヤーから対象のファイルが消えることはありません。よって、無駄なファイルがイメージに含まれないように作成することが大切です。

Dockerコンテナの実行

helloworldイメージの実行と動作解説

コンテナの実行は簡単です。以下のコマンドをターミナルで入力します。

$ docker run hello-world

すると結果を以下のようになります。

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

ここで起こっていることを説明します。
1.まずローカルでDockerクライアントがDockerデーモンに接続してhello-worldのイメージを探します。
2.今回はローカルにhello-worldのイメージは存在しないので、インターネットを経由してDocker社がホスティングしているDocker Hubのサーバに探しに行きます。
3.イメージが見つかればダウンロードしてローカルに保存します。
4.保存したイメージをもとにコンテナを起動して、コンテナに定義されたコマンドを実行します。
※同じイメージがローカルに存在する場合は、2と3は省略されます。(ダウンロードがないので早く実行される)

ちなみに、docker runコマンドは複数のコマンドをまとめて実行したもので、以下のコマンドをまとめています。
1.docker pull:イメージの取得
2.docker create:コンテナの作成
3.docker start:コンテナの起動
取得したイメージは以下のコマンドで確認することができます。

$ docker imeges

結果は以下のようになります。

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        14 months ago       1.84kB

リポジトリに含まれるイメージがTAGによって管理されているのですが、特にTAGを指定しなかった場合にはlatestTAGのイメージがダウンロードされます。
また、以下のコマンドでイメージの詳細情報を表示することができます。

$ docker inspect hello-world

結果は以下のようになります。

[
    {
        "Id": "sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e",
        "RepoTags": [
            "hello-world:latest"
        ],
        "RepoDigests": [
            "hello-world@sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2019-01-01T01:29:27.650294696Z",
        "Container": "8e2caa5a514bb6d8b4f2a2553e9067498d261a0fd83a96aeaaf303943dff6ff9",
        "ContainerConfig": {
            "Hostname": "8e2caa5a514b",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
(中略)

Dockerコンテナの設定情報として、ホスト名や環境変数コンテナ起動時に実行されるコマンドやコマンド実行時のディレクトリの情報などが表示されます。そのほかにも様々な情報が表示されていますので、詳細情報を確認する際によく使われるコマンドです。
そして、ローカルで取得したイメージの削除を行います。次のコマンドで削除することができます。

$ docker rmi hello-world

強制削除を行う場合は-fオプションを使用します。
ここまででhello-worldイメージを用いてDockerイメージの取得から削除までを解説しました。

nginxイメージの実行と動作解説

ここではnginxイメージを使用してデフォルトのnginxの画面が表示されるところまで進めます。
nginxコンテナを立ち上げるコマンドは以下になります。

$ docker run --name <コンテナ名> -d -p <ホスト側のポート番号>:<コンテナ側のポート番号> <イメージ名>

コマンドの解説ですが、runについては説明済みですので割愛します。--name <コンテナ名>ですが、コンテナを識別したりコンテナの操作を行うために、起動するコンテナに名前をつけるオプションです。引数は任意の名前をとります。-dオプションはデタッチモードとしてコンテナの実行をバッググラウンドで行うためのオプションです。-pオプションは、コンテナのポートをコンテナ外に公開する設定です。ホストマシンが外部に公開するポート番号:コンテナにマッピングするポート番号という構成です。
それでは実際にnginxコンテナを起動してみます。

$ docker run --name nginx-test -d -p 8080:80 nginx

以下のような結果になります。

Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
68ced04f60ab: Pull complete 
28252775b295: Pull complete 
a616aa3b0bf2: Pull complete 
Digest: sha256:2539d4344dd18e1df02be842ffc435f8e1f699cfc55516e2cf2cb16b7a9aea0b
Status: Downloaded newer image for nginx:latest

この状態でhttp://localhost:8080/にアクセスするとデフォルトのnginxの画面が表示され、nginxコンテナが正常に起動できていることが確認できます。
こちらについて解説しますと、nginxコンテナの80番ポートをコンテナを実行している仮想マシンの8080番ポートに対応させています。これによって仮想マシンの8080番ポートにアクセスした場合、nginxコンテナのネットワークインターフェースの80番ポートに転送するように設定されます。そして80番でlistenしていたnginxがコンテンツを返し、ウェブブラウザの画面にデフォルトが表示されます。
ここで、コンテナの状態を確認するために以下のコマンドを実行します

$ docker ps

以下のような結果になります。

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
14da03714d91        nginx               "nginx -g 'daemon of…"   26 minutes ago      Up 3 minutes       0.0.0.0:8080->80/tcp   nginx-test

STATUSを見ると、現在実行中であり起動して3分経過していることがわかります。
そして以下のコマンドでコンテナの実行を停止することができます。

$ docker stop nginx-test

状態を確認します。

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
14da03714d91        nginx               "nginx -g 'daemon of…"   32 minutes ago      Exited (0) 6 seconds ago                           nginx-test

STATUSがExited状態となり停止していることが確認できます。
ここまでで、nginxコンテナの起動から停止までの解説をしました。

最後に

今回はDockerについて基本的なことや操作をまとめました。Dockerファイルについても記載したかったですが、次の記事を書く機会に自分の作成したいアプリケーション実行環境を構築した話を書きたいと思っています。

Copyright © RAKUS Co., Ltd. All rights reserved.