プログラミングと旅と映画の日々

普段はスマホ決済サービスの会社でバッグエンドを担当しているエンジニアです。プログラミングと趣味の映画、株、時々うどんに関してブログを書いていこうと思います。海外ドラマ、クロスバイクも好きです。

【Docker】コンテナのリンクオプションとは【入門】

Dockerコンテナのリンクオプションとは

f:id:takanori5:20181028132956p:plain
こんにちは

本日はDockerのリンク機能についてみていきます。

リンクオプションの使い方

以下のコマンドで実行可能

docker run --link <コンテナ名orコンテナID> :<リンク先コンテナの別名>...

リンクオプションを付けた場合の動作

リンクオプションを付けてコンテナを起動した場合、

  • リンク先のコンテナにエイリアスで通信できるようになる(リンクしなくてもIPで通信は可能)
  • リンク先の環境変数や、リンク先コンテナのネットワークに対する環境変数が自動で追加される

実践

これから行うコンテナの構成図と概要

リバースプロキシコンテナとstatic siteコンテナの2つの構成を表す。
リバースプロキシコンテナからstatic siteコンテナにエイリアスでアクセスできるようにしていく

f:id:takanori5:20181110142101p:plain
*ちなみに、このようにブラウザからサーバの間にリバースプロキシを挟むことで
複数のウェブサーバーに負荷を分散させたり、身元を隠すことが可能です。

まず、nginxの設定ファイルを作成します

nginxのconfファイル作成
$ vim reverser_proxy.conf

$ cat reverser_proxy.conf
server {
 listern 8080;
 server_name localhost;

 location / {
  proxy_pass http://ss;
 }
}

この設定により、リバースプロキシコンテナの8080ポートにアクセスがきた場合に
ssというhostにリクエストを転送する動作となる

次にこの作成した設定ファイルをnginxの設定ファイルのディレクトリに配置して
新しいイメージを作成するDockerファイルを作成していきます!!

Dockerfileの作成
$ vim Dockerfile
$ cat Dockerfile
FROM nginx:latest
COPY /reverse_proxy.conf /etc/nginx/conf.d/reverse_proxy.conf
RUN apt-get update && apt-get install -y inetutuils-ping

COPY /reverse_proxy.conf /etc/nginx/conf.d/reverse_proxy.conf
で先ほど作成したconfをnginxの設定ファイルのディレクトリに配置
RUN apt-get update && apt-get install -y inetutuils-ping
その後pingで通信確認するのに必要なパッケージを取得しています。

ではDockerfileをビルドします。

imagebuild
$docker build -t reverse_proxy .
$ docker build -t reverse_proxy .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM nginx:latest
 ---> dbfc48660aeb
Step 2/3 : COPY /reverse_proxy.conf /etc/nginx/conf.d/reverse_proxy.conf
 ---> Using cache
 ---> 4ba07543c8af
Step 3/3 : RUN apt-get update && apt-get install -y inetutils-ping
 ---> Running in 818d2f64318c
Ign:1 http://cdn-fastly.deb.debian.org/debian stretch InRelease
Get:2 http://security-cdn.debian.org/debian-security stretch/updates InRelease [94.3 kB]
Get:3 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease [91.0 kB]
Get:4 http://cdn-fastly.deb.debian.org/debian stretch Release [118 kB]
Get:5 http://cdn-fastly.deb.debian.org/debian stretch-updates/main amd64 Packages [5152 B]
Get:6 http://security-cdn.debian.org/debian-security stretch/updates/main amd64 Packages [454 kB]
Get:7 http://cdn-fastly.deb.debian.org/debian stretch Release.gpg [2434 B]
Get:8 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 Packages [7099 kB]
Fetched 7864 kB in 17s (448 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  netbase
The following NEW packages will be installed:
  inetutils-ping netbase
0 upgraded, 2 newly installed, 0 to remove and 1 not upgraded.
Need to get 242 kB of archives.
After this operation, 390 kB of additional disk space will be used.
Get:1 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 netbase all 5.4 [19.1 kB]
Get:2 http://cdn-fastly.deb.debian.org/debian stretch/main amd64 inetutils-ping amd64 2:1.9.4-2+b1 [223 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 242 kB in 0s (249 kB/s)
Selecting previously unselected package netbase.
(Reading database ... 7027 files and directories currently installed.)
Preparing to unpack .../archives/netbase_5.4_all.deb ...
Unpacking netbase (5.4) ...
Selecting previously unselected package inetutils-ping.
Preparing to unpack .../inetutils-ping_2%3a1.9.4-2+b1_amd64.deb ...
Unpacking inetutils-ping (2:1.9.4-2+b1) ...
Setting up netbase (5.4) ...
Setting up inetutils-ping (2:1.9.4-2+b1) ...
Removing intermediate container 818d2f64318c
 ---> 6f5bab86233d
Successfully built 6f5bab86233d
Successfully tagged reverse_proxy:latest

build成功です!
docker imagesで念のため確認しておきます。
大丈夫そうですね!

$ docker images
REPOSITORY               TAG                   IMAGE ID            CREATED              SIZE
reverse_proxy            latest                6f5bab86233d        About a minute ago   127MB

続いてstatic siteコンテナを起動しておきます。

static siteコンテナの起動
$ docker run --name static-site -e AUTHOR="Takanori5" -d dockersamples/static-site
Unable to find image 'dockersamples/static-site:latest' locally
latest: Pulling from dockersamples/static-site
fdd5d7827f33: Pull complete
a3ed95caeb02: Pull complete
716f7a5f3082: Pull complete
7b10f03a0309: Pull complete
aff3ab7e9c39: Pull complete
Digest: sha256:daa686c61d7d239b7977e72157997489db49f316b9b9af3909d9f10fd28b2dec
Status: Downloaded newer image for dockersamples/static-site:latest
6be1be9837e6b1ff70952a4c1fca4035ec4aeae6279ff4b18d441950e9ba1355

*-eは引数の環境変数を設定するオプション
 このページではAUTHORという環境変数に名前を設定しておくとそれが静的ページに表示される仕組みとなっています。

次に、先ほど作成したリバースプロキシイメージから
コンテナを起動します

リバースプロキシイメージからコンテナを起動
$ docker run --name reverse_proxy  -p 8080:8080 --link static-site:ss -d reverse_proxy
226d3824bfdb0b5a02498e8354740c8b4542598ae3a7a339c5d60b2ae6902c39

このコンテナは8080番ポートを外部に公開し、
staticsiteコンテナにリンクして、エイリアスとしてssという名前を付けています。

起動中のプロセスを一度確認します。

$ docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                            NAMES
4b70064342f6        reverse_proxy               "nginx -g 'daemon of…"   5 seconds ago       Up 4 seconds        80/tcp, 0.0.0.0:8080->8080/tcp   reverse-proxy
6be1be9837e6        dockersamples/static-site   "/bin/sh -c 'cd /usr…"   12 minutes ago      Up 11 minutes       80/tcp, 443/tcp                  static-site

2つのコンテナが起動できました。

コンテナの動作確認

では、2つのコンテナの動作確認をしていきます!!

まずはブラウザでローカルホストの8080にアクセスしてみます。
http://localhost:8080/
f:id:takanori5:20181110153119p:plain
このWebページはリバースプロキシを経由してstaticsiteコンテナにアクセスすることで取得しています。
では、リバースプロキシコンテナにシェル接続してリンクによる設定を確認してみます。

$ docker exec -it reverse-proxy /bin/bash
root@4b70064342f6:/#

まずは、どのようにしてstaticsiteやssというエイリアス名で通信先を特定できたのか確認します。
hostファイルを見ます。

root@4b70064342f6:/# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.4	ss 6be1be9837e6 static-site
172.17.0.5	4b70064342f6

172.17.0.4 ss 6be1be9837e6 static-site
ここで名前解決していますね。
これがリンク機能の一つです。
続いてenvコマンドで環境変数の設定を見ていきます。

/# env |grep SS_
SS_ENV_NGINX_VERSION=1.9.12-1~jessie
SS_PORT_443_TCP_ADDR=172.17.0.4
SS_PORT_80_TCP=tcp://172.17.0.4:80
SS_PORT_443_TCP=tcp://172.17.0.4:443
SS_ENV_AUTHOR=Takanori5
SS_PORT_80_TCP_PROTO=tcp
SS_PORT=tcp://172.17.0.4:80
SS_PORT_443_TCP_PORT=443
SS_PORT_80_TCP_ADDR=172.17.0.4
SS_NAME=/reverse-proxy/ss
SS_PORT_443_TCP_PROTO=tcp
SS_PORT_80_TCP_PORT=80

author変数に値が設定されていますね!
この環境変数はreverse-proxyコンテナに明示的に指定していませんが、
リンク先コンテナに指定しているものなので
リンク機能により自動で設定がされています!
便利ですね!!

これらがリンクの機能です!
コンテナ名の名前解決はリンクを使わなくても
Dockerのネットワークを作ることで実現できるので
ここで見たように環境変数を注入したい時だけ使うといいみたいです。

今回は以上です。

【Docker】起動中のコンテナのシェルへの接続方法【入門】

起動中のDockerコンテナのシェルへの接続方法

f:id:takanori5:20181028132956p:plain
以下の二つの方法で接続可能

docker attach コンテナ名
docker exec -it コンテナ名 /bin/bash

docker attach コンテナ名

コンテナで起動しているPID=1のプロセスの標準入出力(STDIN/STDOUT)に接続(attach)する。

docker exec -it コンテナ名 /bin/bash

dockerコンテナで任意のコマンドを実行させる。

  • itオプションについては意味合いは以下の通り

i 標準入力(STDIN)を開いたままにする
t 擬似ttyに接続する。ディスプレイ(STDOUT)をつなぐイメージ

execの方が 不意にコンテナが止めてしまったりといったことが起きづらいためこちらを推奨

【Docker】Docker fileのCOPY命令で設定ファイルを保存【入門】

Docker fileのCOPY命令ADD命令

f:id:takanori5:20181028132956p:plain
COPY命令はホストマシン上のファイルをイメージ内にコピーする命令です。

nginxイメージ内に修正した設定ファイルの内容を保存していきたいと思います。

まずはnginxコンテナを立ち上げていきます。

$ docker run --name tmp-nginx --rm -d nginx
960e083f54488cf5815e4bd3bb6830b4135d27e2bfb6bbfadd28b7e8dcf4be5e

-rm オプションはdocker imagestop時にコンテナを自動削除するオプションです。

コンテナからホストへのコピー
$docker cp <コンテナID>:/etc/my.cnf my.cnf
ホストからコンテナへのコピー
$docker cp my.cnf <コンテナID>:/etc/my.cnf

では、やってみます

$ docker cp tmp-nginx:/etc/nginx/conf.d/default.conf ./
$ ls
default.conf

copyできました。
では設定ファイルに修正を加えます。

$ vim default.conf
#port番号を80から8080に変更します。
server {
    listen       8080;
    server_name  localhost;
...
}

以下のようなDockerfileを作成して、COPY命令を書きます。

nginxのイメージを元にしてCOPY命令を書きます。

$ cat Dockerfile
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/default.conf

ではbuildします。

$ docker build -t nginx:ver1 .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM nginx:latest
 ---> dbfc48660aeb
Step 2/2 : COPY default.conf /etc/nginx/conf.d/default.conf
 ---> 9179d15926aa
Successfully built 9179d15926aa
Successfully tagged nginx:ver1

build成功。これを元にコンテナを起動します。

$ docker run --name web -p 8080:8080 --rm nginx:ver1
172.17.0.1 - - [02/Nov/2018:07:32:24 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36" "-"

8080ポートで接続できました。

【Docker】nginxイメージでウェブサーバー構築【入門】

nginxイメージでウェブサーバー構築

f:id:takanori5:20181028132956p:plain
https://hub.docker.com/_/nginx/

nginxのコンテナを立ち上げるコマンドは以下

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

コマンドの末尾の\は複数業に続くコマンドを指定する場合に使う

  • d detachモード(バックグラウンんどで動作。常駐型のものは-dを指定しましょう)

実際にnginxコンテナを起動していきます。

$ docker run --name test-nginx -d -p 8080:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f17d81b4b692: Pull complete
d5c237920c39: Pull complete
a381f92f36de: Pull complete
Digest: sha256:b73f527d86e3461fd652f62cf47e7b375196063bbbd503e853af5be16597cb2e
Status: Downloaded newer image for nginx:latest
5b2ea9c3c6deda192a973468c5d3619c2e0a57582c42a11165542a2da0c960ae

localhostの8080にアクセルして確認します。
すると以下のデフォルトの画面が出ると成功です!
dockerコンテナが動作していますね。
f:id:takanori5:20181102150020p:plain

nginxの80番ポートをコンテナを実行している仮想マシンの8080ポートにマッピング
仮想マシンの8080にアクセスされるとnginxのネットワークポート80番ポートに繋がる
nginxがコンテンツを返しデフォルトページが表示される。

f:id:takanori5:20181102150341p:plain

host上のhtmlファイルをnginxで公開

host上のディレクトリをコンテナにマウントしていきます。
nginxのhubのページをみにいきます。
以下に記載があります。
f:id:takanori5:20181102153550p:plain

  • vオプションがついていますね。
-v <host側のディレクトリ>:<コンテナ側のマウントポイント>:<オプション>
//例
$ docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx

/usr/share/nginx/htmlはnginxのドキュメントルートディレクトリです。roオプションはリードオンリーの略。

今回は以下のようなディレクトリ構成で -vを指定して実行してみます。

-v USER/<ユーザー名>/docer-tutorial/html:/usr/share/nginx/html:ro

マウントを利用することでイメージにはソースコードは含めずに
gitでソースは管理して、マウントして修正内容などをすぐに確認できます。
超便利ですね!

マウントするように簡単なhtmlファイルを以下のディレクトリないに作成します。

/Users/hodzumitakanori/docker-tutorial/html

$ cat index.html
<!DOCTYPE html>
<html>
<body>
<h1>Hello takanori5!<h1>
</body>
</html>

コマンドを実行!

$ docker run --name nginx -v /Users/hodzumitakanori/docker-tutorial/html:/usr/share/nginx/html:ro -d -p 8080:80 nginx
c401ad4ccdc84fdaed5ce047a684ceb2a831eec85e803f1e93fe3c4ae5cb0eec

f:id:takanori5:20181102155441p:plain

【Docker】Docker hubへのイメージのプッシュ方法【入門】

Docker hubへのイメージのpush 方法

f:id:takanori5:20181028132956p:plain
リポジトリにイメージを追加してみます。

pushするにはDocker hubにログインする必要あり。
以下のコマンドを実行

$ docker login
hodzumitakanori-no-MacBook-Air:imagebuild hodzumitakanori$ docker login
Authenticating with existing credentials...
Login Succeeded

Login Succeeded!!

docker hubのタグ付けのルール

/:<タグ名>
タグ名の指定を省略すると自動でlatestタグと判定される

$ docker tag docker-whale takanori5/docker-whale:ver1
$ docker images
REPOSITORY          TAG                   IMAGE ID            CREATED             SIZE
takanori5/docker-whale   ver1                  0c788d9552c9        5 days ago          277MB

tag付けできました。

ではdocker hubにpushしていきます。

docker push <docker ID>/<image名>:<タグ名>
$ docker push takanori5/docker-whale:ver1
The push refers to repository [docker.io/takanori5/docker-whale]
288eb47d521e: Pushed
5f70bf18a086: Mounted from docker/whalesay
d061ee1340ec: Mounted from docker/whalesay
d511ed9e12e1: Mounted from docker/whalesay
091abc5148e4: Mounted from docker/whalesay
b26122d57afa: Mounted from docker/whalesay
37ee47034d9b: Mounted from docker/whalesay
528c8710fd95: Mounted from docker/whalesay
1154ba695078: Mounted from docker/whalesay

ver1: digest: sha256:dd05678a4931ce83947b376e5ab0c39a632f80f8504a7072bfc7de2ff2ee7635 size: 2614

push できました。


アップできています。
f:id:takanori5:20181102144315p:plain

試しにローカルのイメージを削除した上でpullしてみましょう。

//削除
$ docker rmi -f 0c788d9552c9
Untagged: hoz/docker-whale:ver1
Untagged: docker-whale:latest
Untagged: takanori5/docker-whale:ver1
Untagged: takanori5/docker-whale@sha256:dd05678a4931ce83947b376e5ab0c39a632f80f8504a7072bfc7de2ff2ee7635
Deleted: sha256:0c788d9552c9375eb30546618e033a2cf7d72bc7b216aa9997b64fea2bcc612b
Deleted: sha256:e77d0b9fa75be179620913aad7f08dbea9b4374b183940fbd7463305f9f5517c

//結果確認
$ docker images
REPOSITORY          TAG                   IMAGE ID            CREATED             SIZE
hello-world         latest                4ab4c602aa5e        7 weeks ago         1.84kB
mysql               5.7.21                5195076672a7        7 months ago        371MB
nginx               1.13.9-alpine         537527661905        8 months ago        17.9MB
php                 7.2.2-fpm-alpine3.6   59d3e94a05b7        8 months ago        77.2MB
docker/whalesay     latest                6b362a9f73eb        3 years ago         247MB

//hubからpull
$ docker pull takanori5/docker-whale:ver1
ver1: Pulling from takanori5/docker-whale
e190868d63f8: Already exists
909cd34c6fd7: Already exists
0b9bfabab7c1: Already exists
a3ed95caeb02: Already exists
00bf65475aba: Already exists
c57b6bcc83e3: Already exists
8978f6879e2f: Already exists
8eed3712d2cf: Already exists
fa71efe4e5ff: Already exists
Digest: sha256:dd05678a4931ce83947b376e5ab0c39a632f80f8504a7072bfc7de2ff2ee7635

これでこのレポジトリにアクセスできるアカウント保持者は
誰でもこのイメージを取得できるようになりました!!

【Docker】Docker fileを使用したイメージの構築方法【入門】

Docker fileを使用したイメージの構築方法

f:id:takanori5:20181028132956p:plain
Docker fileを使用してイメージを構築することをイメージビルドと呼ぶ

docker fileからイメージをビルドするコマンド

docker build -t hoge .
-t hoge(タグ名を指定)/ . ビルドコンテキストを指定(この場合current directory)

current directory にあるDockerfileがビルドされる

イメージビルド時にビルドコンテキストのファイルはDockerデーモンに転送されるので重いファイルは置かないように注意。