Opensourcetechブログ

OpensourcetechによるNGINX/Kubernetes/Zabbix/Neo4j/Linuxなどオープンソース技術に関するブログです。

docker 〜Dockerfile を使用した、コンテナの作成・起動〜

 

こんにちは、鯨井貴博@opensourcetechです。

 

今回は、docker で  Dockerfile を使用したコンテナの作成、

および起動を試してみます。

 

コンテナは、nginx on CentOS7 を作成しています。

 

docker環境は、Mac OS用のCommunity Edition(ver18.03.1-ce)を使っています。

f:id:opensourcetech:20180612171859p:plain

 

 

 

Dockerfileの作成

以下のような Dockerfile を作りました。

FROM centos:latest・・・①
MAINTAINER SubMattNesk(kujiraitakahiro) <*******@gmail.com>・・・②
COPY ./nginx.repo /etc/yum.repos.d/・・・③
RUN ["/bin/bash","-c","yum -y install nginx"]・・・④
EXPOSE 80・・・⑤
LABEL "version" = "0.02" \・・・⑥
"description" = "presented by SubMattNesk"
ADD ./emon.html /usr/share/nginx/html/・・・COPYと似てるけどちょっと違う
#ENTRYPOINT : When "docker run", you can't overwrite it.
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]・・・⑦
#CMD : When "docker run", you can overwrite it.
#For example, using command options.
CMD ["-c","/etc/nginx/nginx.conf"]・・・⑧

github.com

 

①FROM

FROM centos:latest

以下(Docker hub)にあるcentosのコンテナイメージの「latest」を元イメージとして使用しています。

https://hub.docker.com/_/centos/

f:id:opensourcetech:20180612172620p:plain

 

②MAINTAINER

MAINTAINER SubMattNesk(kujiraitakahiro) <*******@gmail.com>

メンテナンスをしている人(管理者など)の情報を追記するもの。

 

③COPY

COPY ./nginx.repo /etc/yum.repos.d/

後のステップで実施する「docker build」時に、

操作PCのカレントディレクトリにある nginx.repoというファイルを

コンテナの /etc/yum.repos.d/ にコピーするもの。

 

④RUN

RUN ["/bin/bash","-c","yum -y install nginx"]

 ※上記のようにカッコ[ ]や、ダブルクォーテーション・カンマで書く方式を、EXEC方式という。

コンテナ構築時に実施するコマンドを指定するもの。

/bin/bash -c yum -y install nginxと書いても同じ意味(shell方式)。

 

⑤EXPOSE

EXPOSE 80

コンテナイメージで後悔するポートを指定するもの。

上記の場合、TCP80が公開される。

 

⑥LABEL

LABEL "version" = "0.02" \
"description" = "presented by SubMattNesk"

コンテナに付加するラベルを指定するもの。

複数指定したい場合は、上記のように「 \(バックスラッシュ)」 を使う。

 

⑦ENTRYPOINT

ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]

コンテナイメージ構築後に実施するコマンドを指定するもの。

※RUNと同様に、shell方式でもOK。

※Dockerfile内では一回しか使えず、複数行書いた場合には最後のものが実施される。

※systemctl(systemd)では起動出来ないので、注意。

 

⑧CMD

CMD ["-c","/etc/nginx/nginx.conf"]

ENTRYPOINTに続く、コマンドのオプションを指定しているもの。

※RUNと同様に、shell方式でもOK。

※ENTRYPOINTの中に含めてもいいが、

 CMDで書くことで docker run時に上書き(例えば、/etc/nginx.confなど別の設定ファイルを指定するなど)が可能。

※Dockerfile内では一回しか使えず、複数行書いた場合には最後のものが実施される。

 

上記の他に、操作するユーザーを切り替える「USER」や、

カレントディレクトリを変更する「WORKDIR」・変数を定義する「ENV」などがあります。

詳細は、以下で確認してください。

| Docker Documentation

 

 

ADD と COPY の違い

ADDの場合、リモートホストからのダウンロードや、圧縮されたファイルであれば解凍するなどの機能を持っていますが、

COPYは、操作PCにあるファイルを指定された先にコピーするだけ

 

 

コンテナイメージの作成

docker build コマンドを使います。

なお、前のステップで作成したDockerfile(その他、nginx.repoやemon.html)は、

作業時のカレントディレクトリに配置してあります。

※「---> Using cache」は、既にいくつかコンテナイメージがある場合のみ表示され(既存のイメージの再利用)、初めてコンテナイメージを作る時には表示されません。

bash-3.2$ docker build -t sample/nginx2 ./
Sending build context to Docker daemon 7.168kB
Step 1/9 : FROM centos:latest
---> 49f7960eb7e4
Step 2/9 : MAINTAINER SubMattNesk(kujiraitakahiro) <*******@gmail.com>
---> Using cache
---> 45d851346e99
Step 3/9 : COPY ./nginx.repo /etc/yum.repos.d/
---> Using cache
---> e4510b7db268
Step 4/9 : RUN ["/bin/bash","-c","yum -y install nginx"]
---> Using cache
---> 8705a0d8d7fd
Step 5/9 : EXPOSE 80
---> Using cache
---> 94cad7d5e020
Step 6/9 : LABEL "version" = "0.02" "description" = "presented by SubMattNesk"
---> Using cache
---> 56642d6c4f0c
Step 7/9 : ADD ./emon.html /usr/share/nginx/html/
---> Using cache
---> c3ef14035ef9
Step 8/9 : ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
---> Running in b5aec538ea91
Removing intermediate container b5aec538ea91
---> a280cbd2b5cc
Step 9/9 : CMD ["-c","/etc/nginx/nginx.conf"]
---> Running in 698c073be3b4
Removing intermediate container 698c073be3b4
---> 5c4776e2ffa1
Successfully built 5c4776e2ffa1
Successfully tagged sample/nginx2:latest・・・・作成されたコンテナイメージ

 作成されたコンテナイメージには、「sample/nginx2」というタグが付けられています。

 

 

作成したコンテナイメージの確認

docker images コマンドを使います。

作成された「sample/nginx2」があることがわかります。

それ以外は、既にあったコンテナイメージです。

bash-3.2$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sample/nginx2 latest 5c4776e2ffa1 Less than a second ago 276MB
sample/nginx latest 2100cb31ecba 18 hours ago 276MB
centos latest 49f7960eb7e4 7 days ago 200MB

 

 

コンテナの起動

docker run コマンドを使います。

 

オプションは、以下のような意味があります。

-d:バックグラウンドで実施

-p:操作PCのTCP8080 と コンテナのTCP80 をバインド

-w:ワーキングディレクトリ指定

-t:タグ指定

 

また、起動確認は docker ps コマンドで行います。

bash-3.2$ docker run -d -p 8080:80 -w /root -i -t sample/nginx2
dee3cdbdfe0b745fa770d71f10886a335ca9a29d4390e492d29970e358509174
bash-3.2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dee3cdbdfe0b sample/nginx2 "/usr/sbin/nginx -g …" Less than a second ago Up 4 seconds 0.0.0.0:8080->80/tcp competent_proskuriakova

 その他のオプションについては、以下を参照下さい。

docker run | Docker Documentation

 

docker run が失敗してコンテナがうまく起動出来なかった場合には、

以下のように docker ps で何も表示されず、docker ps -a とすると、

Exited (0)」と書かれたものがあるので docker rm [CONTAINER ID]で残っているコンテナを削除してやり直します。

bash-3.2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bash-3.2$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad12d45d2dd1 sample:0.02 "/bin/sh -c /usr/sbi…" 10 seconds ago Exited (0) 14 seconds ago blissful_ramanujan

 

以下、削除例です。

bash-3.2$ docker rm ad12d45d2dd1
ad12d45d2dd1
bash-3.2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bash-3.2$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

 

また、docker run がうまく出来ない場合、

前ステップの docker run で作られたコンテナイメージが良くないことがありますので、

docker rmi [コンテナイメージのタグ]として削除・Dockerfileの見直し・再docker buildしてやり直します。

bash-3.2$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sample 0.01 96c7fb19316c 2 hours ago 276MB・・・削除したいコンテナイメージ
kujiraitakahiro/submattnesk latest 96c7fb19316c 2 hours ago 276MB
bash-3.2$ docker rmi sample:0.01
Untagged: sample:0.01・・・削除された
bash-3.2$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kujiraitakahiro/submattnesk latest 96c7fb19316c 2 hours ago 276MB

 

 

dockerの情報確認

docker -v / docker version / docker info コマンドを使います。

bash-3.2$ docker -v
Docker version 18.03.1-ce, build 9ee9f40
bash-3.2$ docker version
Client:
Version: 18.03.1-ce
API version: 1.37
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:13:02 2018
OS/Arch: darwin/amd64
Experimental: false
Orchestrator: swarm

Server:
Engine:
Version: 18.03.1-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:22:38 2018
OS/Arch: linux/amd64
Experimental: true
bash-3.2$ docker info
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 10
Server Version: 18.03.1-ce
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 773c489c9c1b21a6d78b5c538cd395416ec50f88
runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 4.9.87-linuxkit-aufs
Operating System: Docker for Mac
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.952GiB
Name: linuxkit-025000000001
ID: MKEX:SNWC:G2C4:EW4Z:5ZPR:OFYF:EILE:C35S:SODF:CHWN:KFFZ:GHJW
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): true
File Descriptors: 30
Goroutines: 53
System Time: 2018-06-12T12:51:01.248400321Z
EventsListeners: 2
HTTP Proxy: docker.for.mac.http.internal:3128
HTTPS Proxy: docker.for.mac.http.internal:3129
Registry: https://index.docker.io/v1/
Labels:
Experimental: true
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false

 

 

 

作成したコンテナへのアクセス

今回は nginx(Webサーバ)を構築したので、

操作PCのブラウザから 「http://localhost:8080」や「http://localhost:8080/emon.html」とすれば、

以下のようにコンテンツファイル(index.htmlやemon.html)が開きます。

f:id:opensourcetech:20180612181654p:plain

f:id:opensourcetech:20180612181708p:plain

 

 

コンテナ内でのコマンド操作

コンテナ内でも、通常のLinuxと同様のコマンドラインを使用することが可能です。

方法は3つ。

1つ目は docker exec コマンドを使用し、指定したコマンドのみ実施する方法。

bash-3.2$ docker exec 93d11e92e83d ping 1.1.1.1 -c 3
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=37 time=17.1 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=37 time=22.5 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=37 time=16.8 ms

--- 1.1.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2007ms
rtt min/avg/max/mdev = 16.868/18.877/22.599/2.634 ms
bash-3.2$ docker exec 93d11e92e83d echo "Hello, World"
Hello, World

 2つ目は、docker exec コマンドで /bin/bash(シェル)を実施し、継続的に操作する方法。

コンテナから抜けるときは、exit とします。

bash-3.2$ docker exec -it 93d11e92e83d /bin/bash
[root@93d11e92e83d ~]# cat /etc/redhat-release ・・・・コンテナのシェル
CentOS Linux release 7.5.1804 (Core)
[root@93d11e92e83d ~]# exit
exit
bash-3.2$

 3つ目は、docker attach で接続する方法。

attachからの抜け出し方は、ctrl(押したまま)p、qとタイプ。

もしくは、exitコマンドをコンテナ内で実施する(コンテナプロセスが停止するので注意)。

bash-3.2$ docker attach 93d11e92e83d

 

 

コンテナのプロセス確認

docker top コマンドを使います。

bash-3.2$ docker top 93d11e92e83d
PID USER TIME COMMAND
2355 root 0:00 nginx: master process /usr/sbin/nginx -g daemon off; -c /etc/nginx/nginx.conf
2386 999 0:00 nginx: worker process

 

 

 

 

コンテナの停止

docker stop コマンドを使います。

bash-3.2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dee3cdbdfe0b sample/nginx2 "/usr/sbin/nginx -g …" Less than a second ago Up 4 seconds 0.0.0.0:8080->80/tcp competent_proskuriakova
bash-3.2$ docker stop dee3cdbdfe0b
dee3cdbdfe0b
bash-3.2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

※起動中のコンテナの元になったコンテナイメージ(docker imagesで表示)を削除するには、コンテナの停止(docker stop)・コンテナの削除(docker rm)が必要ですのでご注意。

 

 

おまけ:コンテナ起動につけられる名前について

以下の起動しているコンテナを見ると、NAMESの項目が「competent_proskuriakova」となっているのが分かります。

bash-3.2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dee3cdbdfe0b sample/nginx2 "/usr/sbin/nginx -g …" Less than a second ago Up 4 seconds 0.0.0.0:8080->80/tcp competent_proskuriakova

 

複数コンテナを起動してみるとわかるのですが、

他にも「relaxed_liskov」や「festive_wescoff」など、

誰やねん!と突っ込みたくなるような名前がつけられています。

 

これは、名無し状態のコンテナに自動的に名前が付けられるもので、

GO言語で書かれた docker のソースコードを辿っていけば分かるのですが、

names-generator.go によって生成されている名前となります。

moby/names-generator.go at master · moby/moby · GitHub

docker のソースコードのトップは、以下。

Docker · GitHub

 

なお、docker run 実行時に「--name」オプションを使えば任意の名前を付ける事で回避出来ます。

f:id:opensourcetech:20180612182406p:plain

bash-3.2$ docker run --name test1 -d -p 8080:80 -w /root -i -t sample/nginx2
93d11e92e83d2a5786ccbabee0a4a6dc6138a47a87060c146d23cf512bf44d4b
bash-3.2$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93d11e92e83d sample/nginx2 "/usr/sbin/nginx -g …" 3 seconds ago Up 1 second 0.0.0.0:8080->80/tcp test1

 

 

 

 

www.slideshare.net

github.com

www.facebook.com

twitter.com

www.instagram.com

 

 

にほんブログ村 IT技術ブログ Linuxへ
Linux

にほんブログ村 IT技術ブログ オープンソースへ
オープンソース

 

Opensourcetech by Takahiro Kujirai