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イメージのレイヤーを確認する

[bash] 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:~$
[/bash]

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 をインタラクティブモードで起動

[bash] 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:/#
[/bash]
2. Install Git package in the container(Dockerコンテナ更新)
[例] DockerコンテナにGitをインストール

[bash] 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:/#
[/bash]
3. Commit changes made in the container(Dockerイメージビルド)
[例] GitをインストールしたDockerコンテナより、新しいDockerイメージをビルドして、更新内容が反映されているか確認

[bash] 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:/#
[/bash]

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を使用して実施

[bash] 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:~$
[/bash]

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

[bash] vi Dockerfile
———-
FROM debian:jessie
RUN apt-get update && apt-get install -y \
git \
vim
———-
[/bash]

※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使用例

[bash] 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
[/bash]

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使用例

[bash] 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#
[/bash]

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にプッシュ

[bash] ### 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:~$
[/bash]

おわりに

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

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