Docker講習会
⽬的
Dockerすごいって思ってもらう
Dockerこわくないって思ってもらう
Docker使っても良いかもって思ってもらう
1
Dockerとは?
コンテナ型仮想環境の構築・管理ツール
コンテナ型仮想化って?
「コンテナ」という独⽴した区画を作成し,そこで仮想環境
を作る技術
VMほどしっかりと分離されていない
VM: ホストOSからは別のマシンとして⾒える
コンテナ: ホストOSからはプロセスとして⾒える
2
とりあえず使ってみよう
(vm)$ sudo docker run -p 8080:80 nginx:1.17-alpine
ブラウザで, localhost:8080 を開いてみよう
このnginxはどこで動いている?
3
仮想環境をなぜ使うのか
ホスト環境との分離のため
依存ソフトウェアのバージョン衝突防⽌
複数プロジェクト同⼠でDB,設定の混在防⽌
開発者間での環境共有のため
仮想環境を渡すだけですぐ開発開始できる
デプロイの容易さのため
仮想環境ごとデプロイすれば楽 4
.
.
.
.
別にDockerじゃなくても普通のVMで
良いのでは?
5
Dockerをなぜ使うのか
コンテナ型仮想化
軽量(すぐ起動,すぐ終了,サイズ⼩)
強⼒なエコシステム
多様な周辺ツール
クラウドによるマネージドサービス
6
Dockerのキホン
Dockerイメージ
コンテナのもと.
Dockerコンテナ
仮想環境を動かすもの.Dockerイメージから⽣成される.
この2つはオブジェクト指向でいうクラスとインスタンスの関係に似
ている.これからイメージとコンテナの関係をつかんでいこう
7
Dockerイメージを確認しよう
(vm)$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.17-alpine 48c8a7c47625 5 weeks ago 21.8MB
先ほどの docker run は「イメージを取得してコンテナを⽣成,起動」
するコマンド
8
コンテナを起動
$ sudo docker run -d -p 8080:80 --name myserver nginx:1.17-alpine
"-d"と"--name [name]"オプションがつきました.
コンテナを確認してみよう
$ sudo docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
756632c14e60 nginx:1.17-alpine "nginx -g 'daemon of…" 17 seconds ago Up 16 seconds 0.0.0.0:8080->80/tcp myserver
9
コンテナに⼊ろう
コンテナ内部に⼊ってみよう.
$ sudo docker container exec -it myserver sh
/ #
コンテナ内部の / (ファイルシステムルート)に移動しました.
ホストOSとはファイルシステムが分離されているのがわかります.
10
コンテナ内部のOS..?
(container)/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.10.4
...
Alpine Linuxは⾮常に⼩さなLinuxディストリビューションで,よく
Dockerイメージに利⽤されます.
コンテナ内部でホストとは別のOSが動いているように⾒えますが,実
際はそのように⾒せかけているだけです.
参考: https://qiita.com/kirikunix/items/33414240b4cacee362da 11
コンテナ内部に変更を加える
/ # echo "helloooo" >> /usr/share/nginx/html/index.html
/ # exit
index.html はnginxで配信されているファイルです. >> でファイルに
追記しています
ブラウザに反映されていますか?
12
もう1つコンテナを起動しよう
$ sudo docker run -d -p 8081:80 --name myserver2 nginx:1.17-alpine
イメージは同じ nginx:1.17-alpine です.
名前は myserver2
-pに指定するのは 8081:80
に注意してください.
13
ブラウザで確認
localhost:8080 と localhost:8081 を⾒⽐べてみよう
14
わかったこと
イメージはコンテナの"もと"
イメージからコンテナをたくさん⽣成できる
イメージさえ渡せば,同じ環境を作成できる
コンテナ同⼠は独⽴している
コンテナ内部で変更を加えても,イメージには影
響しない
コンテナ内部で⾊々変更するべきでない 15
仮想環境をなぜ使うのか(再掲)
ホスト環境との分離のため
依存ソフトウェアのバージョン衝突防⽌
複数プロジェクト同⼠でDB,設定の混在防⽌
開発者間での環境共有のため
仮想環境を渡すだけですぐ開発開始できる
デプロイの容易さのため
仮想環境ごとデプロイすれば楽 16
今更だけど今⽇のシステム構成
DockerをVM (Ubuntu Xenial)上で動かしている
DockerはLinux上の⽅が良い感じに動くので
厳密にはLinuxでしか動かない
Vagrant: Virtualboxのような仮想化ソフト(ハイ
パバイザ)の構成ツール
Vagrantfileにポート転送の設定を書いてるのでホ
ストから疎通できるようになってます 17
イメージを作る
コンテナをいじるのが良くないことがわかった
じゃあ,イメージごといじれば良い!
作り⽅
Dockerfileを書いてビルドする
コンテナから⽣成する
18
Dockerfile
イメージの設計図
記述すること
ベースにしたいイメージ
イメージ作成時に実⾏したいコマンド
コンテナ実⾏時に実⾏したいコマンド
などなど
19
Dockerfile⾒てみる
VMの /vagrant/hello-dockerfile/Dockerfile をみてみよう
FROM nginx:1.17-alpine
FROM: ベースとなるイメージを指定
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY: ホストのファイルをコンテナへコピー
20
RUN set -x &&
apk --update add openssl &&
...(omitted)
chmod 400 /etc/nginx/server_private.key
RUN: イメージ作成時に実⾏するコマンド
ここで⽣成したファイルなどはイメージに含まれる
CMD ["nginx", "-g", "daemon off;"]
CMD: コンテナ起動時に実⾏するコマンド
21
イメージを作る(ビルド)
$ cd /vagrant/hello-dockerfile
$ sudo docker build -t hoge/myserver:1.0 .
タグは[Dockerhubのユーザー名]/イメージ名:バージョンで作るのが
普通
Dockerfileの"RUN"で指定したコマンドが⾛りました.できたイメー
ジを $ sudo docker images で確認してみよう
22
コンテナ起動
これはさっきと同様
$ sudo docker run -d -p 4443:443 --name https-server hoge/myserver:1.0
警告画⾯が出たら"thisisunsafe"とタイプする
23
Dockerhub
dockerイメージがたくさんアップロードされてる
24
Dockerfileを作ってみよう
⾃分で作成したイメージもFROMでベースに指定できる
FROM hoge/myserver:1.0
RUN apk --update add sl
...
25
multi stage build(1/2)
go/Dockerfile
# ビルド⽤のイメージ
FROM golang:1.14-alpine as builder
WORKDIR /go/src/app
COPY ./main.go .
RUN GOOS=linux GOARCH=amd64 go build -o /go/bin/app
# 実⾏⽤のイメージ
FROM alpine:3.11
COPY --from=builder /go/bin/app /go/bin/app
RUN addgroup --system myapp &&
adduser --no-create-home --disabled-password --system --ingroup myapp myapp
USER myapp
ENTRYPOINT [ "/go/bin/app" ] 26
multi stage build(2/2)
FROM golang:1.14-alpine as builder
...
COPY --from=builder /go/bin/app /go/bin/app
コンパイルさえできれば後は処理系が必要ない場合に使う
(例: golang, C++, Rust, webpack)
ビルド⽤と実⾏⽤のイメージを分離できる
$ sudo docker images | awk '{print $1 ":" $7}' | grep go
hoge/goapp:13.1MB # こちらだけサーバにデプロイすればOK
golang:369MB # これはもう必要ない 27
おまけ
RUN addgroup --system myapp &&
adduser --no-create-home --disabled-password --system --ingroup myapp myapp
USER myapp
CMD や ENTRYPOINT : 指定したコマンドは実⾏ユー
ザがroot
セキュリティ上良くない
USER
実⾏ユーザを変更
システムユーザを作成して実⾏している 28
実際,Dockerはどういうところで使う
のか?
ここまでで基礎は⼤体OK
使われ⽅をいくつか紹介
29
ユースケース1: 実⾏環境を使いたい
環境構築がめんどくさいツールを使う時,誰かが
DockerhubにイメージをUPしていることがある
ただし,安易にイメージを信頼するのはセキュリティ上良く
ない
$ cd bookmaker
$ sudo docker run --rm -v `pwd`:/work nuitsjp/mdview ./work/build.sh
-v: ホストのディレクトリをコンテナにマウント
イメージ名の後に実⾏コマンドを⼊⼒できる 30
31
ユースケース2
jupyter notebook
ブラウザで実⾏できるPythonのREPL環境
データサイエンスやMLの⼈が良く使う
$ sudo docker run --rm -p 8080:8888 -v `pwd`:/home/jovyan/work jupyter/base-notebook
32
ユースケース3: web
web開発では複数のコンテナを動かしたいことがほとんど(1サービ
ス1コンテナが原則)
フロントエンド⽤サーバ
アプリケーションサーバ
DB
=> docker-composeを使う
33
docker-compose
複数のコンテナをまとめて管理するツール
/web/docker-compose.yamlを⾒てみよう
34
version: '3'
services:
server:
...
db:
...
volumes:
- db-store:/var/lib/mysql
...
volumes:
db-store:
db-storeはホストのディレクトリになる. 実体は
/var/lib/docker/volumes/web_db-store/_data にある
35
server
└── server
├── Dockerfile # 開発⽤Dockerfile
├── Dockerfile.prod # 本番⽤Dockerfile
├── main.go
└── tmp
開発⽤: ファイルの変更をウォッチして⾃動ビル
ド
本番⽤: ビルドするだけ
36
compose起動
$ sudo docker-compose up -d
$ sudo docker images や $ sudo docker-compose ps で確認してみよう
コンテナを削除して,再起動してみよう.DBのデータはどうなります
か?
37
まとめ
イメージからコンテナを(複数)⽣成できる
コンテナに変更を加える事は普通しない
イメージをDockerfileから作って共有しよう
docker composeを使って複数コンテナ管理
さあ,次は君の番!
38

Docker講習会資料