UdemyでDockerを学ぶ② 〜Section2〜


リンクバル技術部の川畑です。最近はエンジニアなら誰でも憧れる、継続的デリバリーを実現するべくDocker勉強中。前回の記事UdemyでDockerを学ぶ① 〜概要からSection1〜では、Dockerの概要とDockerを構成する概念についてのレッスンが中心でした。今回はDockerイメージの管理などのレッスンが中心となります。それでは見ていきましょう。

「Section2: Working with Docker Images」の内容

Section2の内容は以下の通り。

  • 11 Docker Image Layers
  • 12 Build Docker Images by using Docker Commit Command
  • 13 Build Docker Images by Writing Docker file
  • 14 Dockerfile In-depth
  • 15 Push Docker Images to Docker Hub

それでは個別に見ていきます。

11. Docker Image Layers

  • 主な内容:Dockerイメージのレイヤーについての説明

Image Layers

  • DockerイメージはBase Image(ベースイメージ)の上に複数のイメージがスタックされるような構成

「docker history repository:tag」コマンド

  • Dockerイメージのレイヤーを確認するコマンド

[例] busyboxというリポジトリの1.24というタグのDockerイメージのレイヤーを確認する

ubuntu@ubuntu-xenial:~$ docker history busybox:1.24
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
47bcc53f74dc        12 months ago       /bin/sh -c #(nop) CMD ["sh"]                    0 B
<missing>           12 months ago       /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff   1.113 MB
ubuntu@ubuntu-xenial:~$

Image Layersの制限

  • 実行中のコンテナに加えられた変更は、書き込み可能なレイヤーに書き込まれる。
  • コンテナが削除されると、書き込み可能なレイヤーも削除される。元のイメージは変更されない。
  • 複数のコンテナがBase Imageへのアクセス可能。

12. Build Docker Images by using Docker Commit Command

  • 主な内容:Dockerコミットを使用してのDockerイメージのビルド

Ways to Build a Docker Image

  • Dockerイメージのビルド方法は2種類
    • Commit changes made in a Docker Container(Dockerコンテナを更新してコミット)
    • Write a Dockerfile

DockerコンテナのコミットによるDockerイメージビルドのハンズオン

  • 以下の手順で実際にハンズオン
    1. Spin up a container from a base image(Dockerコンテナ起動)
    2. Install Git package in the container(Dockerコンテナ更新)
    3. Commit changes made in the container(Dockerイメージビルド)
1. Spin up a container from a base image(Dockerコンテナ起動)

[例] Dockerイメージ debian:jessie をインタラクティブモードで起動

ubuntu@ubuntu-xenial:~$ docker run -it debian:jessie
Unable to find image 'debian:jessie' locally
jessie: Pulling from library/debian
693502eb7dfb: Already exists
Digest: sha256:52af198afd8c264f1035206ca66a5c48e602afb32dc912ebf9e9478134601ec4
Status: Downloaded newer image for debian:jessie
root@f613c1f47a63:/# ls
bin  boot  dev	etc  home  lib	lib64  media  mnt  opt	proc  root  run  sbin  srv  sys  tmp  usr  var
root@f613c1f47a63:/#
2. Install Git package in the container(Dockerコンテナ更新)

[例] DockerコンテナにGitをインストール

root@f613c1f47a63:/# apt-get update && apt-get install -y git
Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB]
Get:2 http://security.debian.org jessie/updates/main amd64 Packages [449 kB]
Ign http://deb.debian.org jessie InRelease
*** 省略 ***
Processing triggers for libc-bin (2.19-18+deb8u7) ...
Processing triggers for ca-certificates (20141019+deb8u2) ...
Updating certificates in /etc/ssl/certs... 174 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
Processing triggers for systemd (215-17+deb8u6) ...
root@f613c1f47a63:/#
3. Commit changes made in the container(Dockerイメージビルド)

[例] GitをインストールしたDockerコンテナより、新しいDockerイメージをビルドして、更新内容が反映されているか確認

ubuntu@ubuntu-xenial:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                     PORTS               NAMES
f613c1f47a63        debian:jessie       "/bin/bash"             8 minutes ago       Exited (1) 2 minutes ago                       stoic_shockley
ubuntu@ubuntu-xenial:~$ docker commit f613c1f47a63 lbrepo/debian:1.00
sha256:560c14112d73e58223a8328d6312e31e76756ef4b0bccd0d98ccda6d0254098b
ubuntu@ubuntu-xenial:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
lbrepo/debian      1.00                560c14112d73        35 seconds ago      218 MB
tomcat              8.0                 ab805da84643        23 hours ago        355.4 MB
debian              jessie              978d85d02b87        2 weeks ago         123 MB
busybox             1.24                47bcc53f74dc        12 months ago       1.113 MB
ubuntu@ubuntu-xenial:~$
ubuntu@ubuntu-xenial:~$ docker run -it lbrepo/debian:1.00
root@6cb9de1a58ff:/# ls
bin  boot  dev	etc  home  lib	lib64  media  mnt  opt	proc  root  run  sbin  srv  sys  tmp  usr  var
root@6cb9de1a58ff:/# git
usage: git [--version] [--help] [-C <path>] [-c name=value]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]
※省略
root@6cb9de1a58ff:/#

13. Build Docker Images by Writing Docker file

  • 主な内容:Dockerfileを使用してのDockerイメージのビルド

Dockerfileとは

  • A Dockerfile is a text document that contains all the instructions users provide to assemble an image.
  • Each instruction will create a new image layer to the image.
  • Instructions specify what to do when build the image.

[例] 「12.Build Docker Images by using Docker Commit Command」で実施した手順を、DockerFileを使用して実施

ubuntu@ubuntu-xenial:~$ touch Dockerfile
ubuntu@ubuntu-xenial:~$ vi Dockerfile
----------
FROM debian:jessie
RUN apt-get update
RUN apt-get install -y git
RUN apt-get install -y vim
----------
ubuntu@ubuntu-xenial:~$ docker build -t lbrepo/debian .
Sending build context to Docker daemon 17.41 kB
Step 1 : FROM debian:jessie
 ---> 978d85d02b87
Step 2 : RUN apt-get update
 ---> Running in 719b4ea56aa3
Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB]
Get:2 http://security.debian.org jessie/updates/main amd64 Packages [449 kB]
Ign http://deb.debian.org jessie InRelease
Get:3 http://deb.debian.org jessie-updates InRelease [145 kB]
Get:4 http://deb.debian.org jessie Release.gpg [2373 B]
Get:5 http://deb.debian.org jessie-updates/main amd64 Packages [17.6 kB]
Get:6 http://deb.debian.org jessie Release [148 kB]
Get:7 http://deb.debian.org jessie/main amd64 Packages [9049 kB]
Fetched 9874 kB in 4s (2304 kB/s)
Reading package lists...
 ---> fcd33f71e8c6
Removing intermediate container 719b4ea56aa3
Step 3 : RUN apt-get install -y git
 ---> Running in e93fcd8d608b
Reading package lists...
Building dependency tree...
Reading state information...

ubuntu@ubuntu-xenial:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
lbrepo/debian      latest              02b9ee5d396f        2 minutes ago       246.9 MB
lbrepo/debian      1.00                560c14112d73        32 minutes ago      218 MB
ubuntu@ubuntu-xenial:~$

Docker Build Context

  • Docker build command takes the path to the build context as an argument.
  • When build starts, docker client would pack all the files in the build context into a tarball then transfer the tarball file to the daemon.
  • By default, docker would search for the Dockerfile in the build context path.

14. Dockerfile In-depth

  • 主な内容:Dockerfileを使用した、Dockerイメージのビルドの詳細

Chain RUN Instructions

  • Each RUN command will execute the command on the top writable layer of the container, then commit the container as a new image
  • The new image is used for the next step in the Dockerfile. So each RUN instruction will create a new image layer.
  • It is recommended to chain the RUN instructions in the Dockerfile to reduce the number of image layers it creates.

[例] RUNコマンドを1行で記載した時のDockerfile

vi Dockerfile
----------
FROM debian:jessie
RUN apt-get update && apt-get install -y \
  git \
  vim
----------

※Step数が減りimageレイヤーが少なくて済むのでこちらが推奨、あとDocker cacheを使用しないためにも推奨

Sort Multi-line Arguments Alphanumerically

  • This will help you avoid duplication of packages and make the list much easier to update.

※パッケージのインストールなどはアルファベット順に記載するのが推奨

CMD Instructions

  • CMD instruction specifies what command you want to run when the container start up.
  • If we don’t specify CMD instruction in the Dockerfile, Docker will use the default command defined in the base image.
  • The CMD instruction doesn’t run when building the image, it only runs when the container starts up.
  • You can specify the command in either exec form which is preferred or in shell form.

[例] Dockerfileを使用したビルド時のCMD使用例

vi Dockerfile
----------
FROM debian:jessie
RUN apt-get update && apt-get install -y \
  git \
  vim
CMD ["echo", "hello world"]
----------
ubuntu@ubuntu-xenial:~$ docker build -t lbrepo/debian .
Sending build context to Docker daemon 20.99 kB
Step 1 : FROM debian:jessie
 ---> 978d85d02b87
Step 2 : RUN apt-get update && apt-get install -y   git   vim
 ---> Using cache
 ---> 584092dac09a
Step 3 : CMD echo hello world
 ---> Running in efa912c4360a
 ---> d7383292215a
Removing intermediate container efa912c4360a
Successfully built d7383292215a
ubuntu@ubuntu-xenial:~$ docker run d7383292215a
hello world
ubuntu@ubuntu-xenial:~$
ubuntu@ubuntu-xenial:~$ docker run d7383292215a echo "hello docker"
hello docker

Docker Cache

  • Each time Docker executes an instruction it builds a new image layer.
  • The next time, if the instruction doesn’t change, Docker will simply reuse the existing layer.

Docker cacheをさせない方法

  1. Dockerfileで同じ記載だとCacheを使うので、なるべくStepをまとめることで一意性を低くする
  2. 「docker build」コマンドに「–no-cache=true」オプション付与

COPY Instruction

  • The COPY instruction copies new files or directories from build context and adds them to the file system of the container.

[例] Dockerfileを使用したビルド時のCOPY使用例

touch abc.txt
vi Dockerfile
----------
FROM debian:jessie
RUN apt-get update && apt-get install -y \
  git \
  vim
COPY abc.txt /src/abc.txt
----------
ubuntu@ubuntu-xenial:~$ docker build -t lbrepo/debian .
Sending build context to Docker daemon  21.5 kB
Step 1 : FROM debian:jessie
 ---> 978d85d02b87
Step 2 : RUN apt-get update && apt-get install -y   git   vim
 ---> Using cache
 ---> 584092dac09a
Step 3 : COPY abc.txt /src/abc.txt
 ---> 93f183fc0322
Removing intermediate container b7228fe1b27e
Successfully built 93f183fc0322
ubuntu@ubuntu-xenial:~$ docker run -it 93f183fc0322
root@cb4474e669ff:/# ls
bin  boot  dev	etc  home  lib	lib64  media  mnt  opt	proc  root  run  sbin  src  srv  sys  tmp  usr	var
root@cb4474e669ff:/# cd src
root@cb4474e669ff:/src# ls
abc.txt
root@cb4474e669ff:/src#

ADD Instruction

  • ADD instruction can not only copy files but also allow you to download a file from internet and copy to the container.
  • ADD instruction also has the ability to automatically unpack compressed files.
  • The rule is : use COPY for the sake of transparency, unless you’re absolutely sure you need ADD.

※ADDは圧縮ファイルを自動的に解凍したりすることも可能、なるべくCOPYを使用することを推奨

15. Push Docker Images to Docker Hub

  • 主な内容:ビルドしたDockerイメージをDockerHubにPush

Latest Tag

  • Docker will use latest as a default tag when no tag is provided.
  • A log of repositories use it to tag the most up-to-date stable image, However, this is still only a convention and is entirely not being enforced.
  • Images which are tagged latest will not be updated automatically when a newer version of the image is pushed to the repository.
  • Avoid using latest tag.

[例] ビルドしたDockerイメージにタグを付与して、DockerHubにプッシュ

### imageの確認
ubuntu@ubuntu-xenial:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
lbrepo/debian      latest              93f183fc0322        31 minutes ago      246.4 MB
<none>              <none>              d7383292215a        43 minutes ago      246.4 MB
<none>              <none>              02b9ee5d396f        About an hour ago   246.9 MB
lbrepo/debian      1.00                560c14112d73        About an hour ago   218 MB
tomcat              8.0                 ab805da84643        25 hours ago        355.4 MB
debian              jessie              978d85d02b87        2 weeks ago         123 MB
busybox             1.24                47bcc53f74dc        12 months ago       1.113 MB

### タグをつけた別imageを生成
ubuntu@ubuntu-xenial:~$ docker tag 560c14112d73 lbrepo/debian:1.01

### imageが生成されていることを確認
ubuntu@ubuntu-xenial:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
lbrepo/debian      latest              93f183fc0322        37 minutes ago      246.4 MB
<none>              <none>              d7383292215a        49 minutes ago      246.4 MB
<none>              <none>              02b9ee5d396f        About an hour ago   246.9 MB
lbrepo/debian      1.00                560c14112d73        About an hour ago   218 MB
lbrepo/debian      1.01                560c14112d73        About an hour ago   218 MB
tomcat              8.0                 ab805da84643        25 hours ago        355.4 MB
debian              jessie              978d85d02b87        2 weeks ago         123 MB
busybox             1.24                47bcc53f74dc        12 months ago       1.113 MB

### DockerHubにログイン
ubuntu@ubuntu-xenial:~$ docker login --username=lbrepo
Password:
Login Succeeded

### DockerHubにPush
ubuntu@ubuntu-xenial:~$ docker push lbrepo/debian:1.01
The push refers to a repository [docker.io/lbrepo/debian]
39a1ee9552c7: Pushed
d17d48b2382a: Mounted from library/tomcat
1.01: digest: sha256:eb74f2457f03400fccbe0490effe47e08bbac4835db8e8325fce66357474777e size: 741
ubuntu@ubuntu-xenial:~$

おわりに

今回は主にDockerイメージの管理について学びました。Udemyの本講座はまだまだつづきますが、キリが良いので今回のレポートはここまでとさせて頂きます。

リンクバルでは エンジニアを積極募集中 です。興味のある方のご応募お待ちしております。