More Related Content Similar to Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014 Similar to Dockerで遊んでみよっかー YAPC::Asia Tokyo 2014 (20) More from Masahiro Nagano More from Masahiro Nagano (20) Dockerで遊んでみよっかー YAPC::Asia Tokyo 20142. Me
• 長野雅広 Masahiro Nagano
• @kazeburo
• Operations Engineer / Site Reliability
• LINE Corp.
• YAPC::Asia 2013 Tokyo ベストトーク賞3位
• ISUCON3 優勝
12. 「遊ぶ」という
タイトルにした理由
• Dockerはまだ若い技術。しかし、大きな可能性
がある技術であり、数えきれないほどの周辺ツ
ールがリリースされている
• つまり、ベストプラクティスが定まっていない
• 新しい技術に対して「使う」「使わない」の2
つのスタンスしかないことはない
• 手元で「遊んでみる」ことから始めよう
14. 今日の内容
• Docker の基本
• Docker!leとDockerイメージのビルド
• DockerでPerlを使う
• Dockerで自動化
• DockerでWebアプリケーション
19. Docker とは
• アプリケーションの開発・配布・実行のためのオ
ープンなプラットフォーム
• Dockerを使ってパッケージング(Dockerized)された
アプリケーションはポータビリティが高く、Mac
OS Xの開発環境、Linux上のQA環境、オンプレミ
ス・クラウド上の本番環境など、(Dockerがサポ
ートされている環境なら)どこでも実行が可能
20. Docker プラットフォーム
Docker Hub
Docker!le Docker
Engine
アプリケーションの
共有と配布
アプリケーションの
パッケージング
アプリケーションの
実行
コンテナ技術
開発環境クラウドオンプレミス
21. コンテナ とは
• アプリケーションを実行する環境をHostOS
から隔離させ、それぞれに異なるリソース
を提供する。その隔離されたプロセスの組
を「コンテナ」という
• アプリケーション毎に隔離された実行環境
を用意する手段としてはVM(仮想マシン)も
ある
22. Apps
Bin/Libs
Guest OS
Hypervisor
Host OS
Server
Apps
Guest OS
VM
VM
Bin/Libs
VM
Apps
Bin/Libs
Guest OS
VM
同じ独立性を確保しながら、よ
り少ないリソースで動作する
Apps
Bin/Libs
Apps
Bin/Libs
Apps
Bin/Libs
Docker Engine
Host OS
Server
Container
Container
Container
VMとコンテナ
Container
kernelは共有
23. コンテナの動作
Container Process Container
Docker Engine
Host OS
Server
Process
process A
process B
process C Docker EngineがHost OSから
各リソースを隔離する
Process
24. コンテナの動作
隔離されるリソース
• ファイルシステム
• ネットワーク・ホスト名
• プロセステーブル
• ユーザ権限
• CPU・メモリなどのリソース制御
* Linux Kernelの機能を利用
26. Docker のインストール
Linux Kernel が必要なので、Virtulbox, VMware
などで仮想マシンを起動する必要がある
1) boot2dockerを導入し、Mac上のdocker
コマンドからAPIを経由して操作
2) Vagrantで任意のLinuxディストリビュー
ションを入れる
28. boot2docker
Process
Container
Process
Container
Process
Docker Daemon
boot2docker (linux)
TCP 2375
Docker
Command VirtualBox
Mac OS X
APIを使ってDockerを制御
Mac用DockerはAPIを呼ぶよ
うに作られている
30. boot2docker vs. Vagrant
pros cons
boot2docker
・インストールが楽
・Mac上からDockerを
透過的に扱える
・ファイル共有に
難あり
Vagrant
・ファイル共有がしやすく
柔軟に設定可能
・Guest OSの機能を活用
・Guest OSにログインする
必要あり
* 迷いにくい Vagrant を使っていきます
32. VagrantでDocker 手作業編
Mac OS X
$ mkdir vagrant-docker
$ cd vagrant-docker
$ vagrant init chef/centos-6.5
$ vagrant up
$ vagrant ssh
33. VagrantでDocker 手作業編
Guest OS
$ sudo yum install -y http://
download.fedoraproject.org/pub/epel/6/x86_64/epel-release-
6-8.noarch.rpm
$ sudo yum install -y docker-io
$ sudo service docker start
$ sudo /sbin/chkconfig docker on
$ sudo usermod -a -G docker vagrant
# ログインしなおして
$ docker -v
Docker version 1.1.2, build d84a070/1.1.2
34. VagrantでDocker 自動化編
Mac OS X
$ cat Vagrantfile
$script = <<EOF
yum install -y http://download.fedoraproject.org/pub/
epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install -y docker-io
/sbin/chkconfig docker on
usermod -a -G docker vagrant
EOF
Vagrant.configure(2) do |config|
config.vm.box = "chef/centos-6.5"
config.vm.provision "shell", inline: $script
end
$ vagrant up
初回起動時に自動で実行
35. “Hello World”
Guest OS
起動するベースDockerイメージ
$ docker run ubuntu:14.04 echo Hello World
Unable to find image 'ubuntu:14.04' locally
Pulling repository ubuntu
c4ff7513909d: Download complete
511136ea3c5a: Download complete
...
cc58e55aa5a5: Download complete
Hello World
$
36. bash で入ってみる
Guest OS
stdinの維持とttyの割り当て
$ docker run -i -t ubuntu:14.04 bash
root@0840910014be:/# cat /etc/lsb-release | grep
DESCRIPTION
DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS"
root@0840910014be:/# exit
$
38. 揮発性の確認
Guest OS
$ docker run -i -t ubuntu:14.04 bash
root@0840910014be:/# echo “hello world” > /tmp/foo
root@0840910014be:/# exit
exit
$ docker run -i -t ubuntu:14.04 bash
root@0840910014be:/# ls -l /tmp/foo
ls: cannot access /tmp/foo: No such file or directory
ファイルシステム破棄
echo > /tmp
`bash` `bash`
time
新しいコンテナ!
39. Docker の特徴まとめ
• コンテナ技術を活用したアプリケーシ
ョンの配布・実行のプラットフォーム
• 揮発性のあるコンテナ
• Docker!leと階層化イメージ
次の話題
40. 今日の内容
• Docker の基本
• Docker!leとDockerイメージのビルド
• DockerでPerlを使う
• Dockerで自動化
• DockerでWebアプリケーション
43. Docker!le
Docker!le
FROM centos:centos6
MAINTAINER Masahiro Nagano <kazeburo@gmail.com>
RUN yum install -y http://download.fedoraproject.org/
pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN yum install -y sl
CMD sl
元となるイメージ
build時に実行する
コマンド
docker run時に
実行するコマンド
44. Dockerイメージの作成 #0
Mac OS X
$ ls
Dockerfile Vagrantfile
$ vagrant ssh
Guest OS
$ cd /vagrant
$ ls
Dockerfile Vagrantfile
$ docker build -t localdev/sl .
自動でGuestOSに
マウントされる
イメージに付けるTag名
47. docker build ログ
Guest OS
$ docker build -t localdev/sl .
Step 0 : FROM centos:centos6
Step 1 : MAINTAINER Masahiro Nagano <kazeburo@gmail.com>
Step 2 : RUN yum install -y http://download.fedoraproject.org/
pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
---> Running in 2207ff8a8f8c
...
Step 3 : RUN yum install -y sl
...
Step 4 : CMD sl
---> Running in 65df9252f6ff
---> a8d304eb9f7c
Removing intermediate container 65df9252f6ff
Successfully built a8d304eb9f7c
$
48. docker build とイメージの作成
Docker!le
FROM centos:centos6
MAINTAINER Masahiro Nagano
<kazeburo@gmail.com>
RUN yum install -y epel-release-
6-8.noarch.rpm
RUN yum install -y sl
CMD sl
ファイルシステムの変更点
差分イメージを重ねて行く
centos6
Dockerはaufs、device-mapper、brtfsなどを使い、
差分ファイルシステムを実現している
49. docker build とイメージの作成
Docker!le
FROM centos:centos6
MAINTAINER Masahiro Nagano
<kazeburo@gmail.com>
RUN yum install -y epel-release-
6-8.noarch.rpm
RUN yum install -y sl
CMD sl
ファイルシステムの変更点
差分イメージを重ねて行く
epel
centos6
Dockerはaufs、device-mapper、brtfsなどを使い、
差分ファイルシステムを実現している
50. docker build とイメージの作成
Docker!le
FROM centos:centos6
MAINTAINER Masahiro Nagano
<kazeburo@gmail.com>
RUN yum install -y epel-release-
6-8.noarch.rpm
RUN yum install -y sl
CMD sl
ファイルシステムの変更点
差分イメージを重ねて行く
sl
epel
centos6
Dockerはaufs、device-mapper、brtfsなどを使い、
差分ファイルシステムを実現している
51. docker build とイメージの作成
Docker!le
FROM centos:centos6
MAINTAINER Masahiro Nagano
<kazeburo@gmail.com>
RUN yum install -y epel-release-
6-8.noarch.rpm
RUN yum install -y sl
CMD sl
ファイルシステムの変更点
差分イメージを重ねて行く
CMD
sl
epel
centos6
Dockerはaufs、device-mapper、brtfsなどを使い、
差分ファイルシステムを実現している
53. 差分イメージの枝構造
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y sl
CMD sl
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y fortune
CMD fortune
centos6
base
epel
sl
CMD
54. 差分イメージの枝構造
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y sl
CMD sl
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y fortune
CMD fortune
centos6
base
epel
sl
CMD
55. 差分イメージの枝構造
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y sl
CMD sl
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y fortune
CMD fortune
centos6
base
epel
sl
Docker!leに変更を加えると
そこから枝が分かれる。
幹は共有する
CMD
56. 差分イメージの枝構造
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y sl
CMD sl
FROM centos:centos6
RUN yum install -y epel.rpm
RUN yum install -y fortune
CMD fortune
centos6
base
epel
sl fortune
Docker!leに変更を加えると
そこから枝が分かれる。
幹は共有する
CMD CMD
60. “RUN”
コマンドの実行
Docker!le
RUN command args args
RUN [“command”,”args”,”args”]
上は [“bash”, ”-c”, “command args args”]
Docker!le
RUN curl -L http://cpanmin.us/ | perl - -n App::cpanminus
64. “COPY”
HostOSからコンテナへのファイルコピー
FROM centos:centos6
COPY README.md /opt/
README.md
RUN yum install -y sl
CMD sl
centos6
base
COPY
sl
CMD
$ touch README.md
$ docker build .
65. “COPY”
HostOSからコンテナへのファイルコピー
FROM centos:centos6
COPY README.md /opt/
README.md
RUN yum install -y sl
CMD sl
centos6
base
COPY
sl
CMD
$ touch README.md
$ docker build .
66. “COPY”
HostOSからコンテナへのファイルコピー
FROM centos:centos6
COPY README.md /opt/
README.md
RUN yum install -y sl
CMD sl
centos6
base
COPY
$ touch README.md
$ docker build .
sl sl’
CMD CMD’
69. “ENV”
環境変数
Docker!le
ENV KEY NAME
Docker!le
ENV PLACK_ENV production
ENV PATH $PATH:/opt/local/perl-5.20/bin
変数も使用できる
70. “CMD”
docker run時に起動するコマンド
Docker!le
CMD command args args
CMD [“command”,”args”,”args”]
上は [“bash”, ”-c”, “command args args”]
“RUN” と一緒
73. 今日の内容
• Docker の基本
• Docker!leとDockerイメージのビルド
• DockerでPerlを使う
• Dockerで自動化
• DockerでWebアプリケーション
75. System Perl
Guest OS
$ docker run -i -t ubuntu:14.04 bash
root@8ac58f29a17a:/# perl -v
This is perl 5, version 18, subversion 2 (v5.18.2) built for
x86_64-linux-gnu-thread-multi
(with 41 registered patches, see perl -V for more detail)
Copyright 1987-2013, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
root@8ac58f29a17a:/#
ubuntuの場合
77. System Perl
Guest OS
$ docker run -i -t centos:centos6 bash
bash-4.1# perl -v
CentOSの場合
78. System Perl
Guest OS
$ docker run -i -t centos:centos6 bash
bash-4.1# perl -v
bash: perl: command not found
bash-4.1#
CentOSの場合
CentOSはイメージサイズを小さくする
ために perl は削られている!
83. Dockerイメージを選ぶ基準
• official repository
• Docker!leが公開されている
• Description、Docker!leをみてニーズを
満たしているかどうか確認する
• Automated build repository を利用している
92. kazeburo/perl の使い方
Guest OS
$ docker run -i -t kazeburo/perl:v5.18 perl -v
This is perl 5, version 18, subversion 1 (v5.18.1) built for
x86_64-linux
Copyright 1987-2013, Larry Wall
..
$
93. kazeburo/perl の使い方
Docker!le
FROM kazeburo/perl:v5.18
RUN cpanm -n Plack
CMD plackup -v
cpanmも導入済み
GuestOS
$ docker build -t localdev/perl .
$ docker run localdev/perl
Plack 1.0031
$
94. 今日の内容
• Docker の基本
• Docker!leとDockerイメージのビルド
• DockerでPerlを使う
• Dockerで自動化
• DockerでWebアプリケーション
97. Docker の活用例
速い起動速度と揮発性を利用
Docker コンテナで MySQL を
使ったテストの高速化
http://blog.linknode.net/article/1404955273
アプリケーション
だけじゃない
Docker を用いた rpm / deb パッケージ
作成の継続的インテグレーション
http://yuuki.hatenablog.com/entry/
docker-package-ci
101. perl-build 使い方
shell
$ curl -s https://raw.githubusercontent.com/
tokuhirom/Perl-Build/master/perl-build | perl -
5.20.0 ~/local/perl-5.20
依存モジュールの
インストールなく使える
102. fatpackの手順
• サポートしたい一番古いperlを用意
perl-buildでは “5.8.5”
• ExtUtils::MakeMaker のアップデート
perl-5.12以前なら “6.56” をいれる
• cpanm, App::FatPacker をインストール
• 依存モジュールのインストール・アップデート
• fatpack
103. fatpackの手順
• サポートしたい一番古いperlを用意
perl-buildでは “5.8.5”
• ExtUtils::MakeMaker のアップデート
再利用が可能
perl-5.12以前なら “6.56” をいれる
• cpanm, App::FatPacker をインストール
• 依存モジュールのインストール・アップデート
• fatpack
105. Dockerを使ったfatpack
Docker!le
FROM jmmills/plenv-base:latest
RUN plenv install 5.8.5
ENV PLENV_VERSION 5.8.5
RUN curl -L http://cpanmin.us/ | plenv exec perl - -n
ExtUtils::MakeMaker@6.56
RUN curl -L http://cpanmin.us/ | plenv exec perl - -n
App::cpanminus
RUN curl -L http://cpanmin.us/ | plenv exec perl - -n
Perl::Strip App::FatPacker
RUN plenv rehash
CMD bash -l -c 'cd /perl-build; cpanm -n --
installdeps . ; bash author/fatpack.sh'
106. Dockerを使ったfatpack
GuestOS
$ git clone https://github.com/tokuhirom/Perl-
Build.git
$ cd Perl-Build/author
$ docker build -t perl-build .
$ docker run -v ../:/perl-build perl-build
“Perl-Build” ディレクトリを
コンテナ内の”/perl-build”にマウント
109. Vagrant+Docker
Vagrant!le
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.synced_folder "../", "/perl-build"
config.vm.provision "docker", run: "always" do |d|
d.build_image "/perl-build/author",
args: "-t perl-build"
end
config.vm.provision "shell", run: "always",
inline: "docker run -v /perl-build:/perl-build perl-build"
config.vm.provision "destroy", destroy: false, run: "always"
end
110. Vagrant+Docker
Vagrant!le
/path/to/perl-buildをGuestOSの
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.synced_folder "../", "/perl-build"
config.vm.provision "docker", run: "always" do |d|
/perl-buildにマウント
d.build_image "/perl-build/author",
args: "-t perl-build"
end
config.vm.provision "shell", run: "always",
inline: "docker run -v /perl-build:/perl-build perl-build"
config.vm.provision "destroy", destroy: false, run: "always"
end
111. Vagrant+Docker
Vagrant!le
/path/to/perl-buildをGuestOSの
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.synced_folder "../", "/perl-build"
config.vm.provision "docker", run: "always" do |d|
/perl-buildにマウント
d.build_image "/perl-build/author",
args: "-t perl-build"
end
config.vm.provision "shell", run: "always",
inline: "docker run -v /perl-build:/perl-build perl-build"
config.vm.provision "destroy", destroy: false, run: "always"
end
docker provisionerを使うと
自動でGuestOSにdockerが入る
112. Vagrant+Docker
Vagrant!le
/path/to/perl-buildをGuestOSの
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.synced_folder "../", "/perl-build"
config.vm.provision "docker", run: "always" do |d|
/perl-buildにマウント
d.build_image "/perl-build/author",
args: "-t perl-build"
end
config.vm.provision "shell", run: "always",
inline: "docker run -v /perl-build:/perl-build perl-build"
config.vm.provision "destroy", destroy: false, run: "always"
end
docker provisionerを使うと
自動でGuestOSにdockerが入る
shell provisionerでdocker run
113. Vagrant+Docker
Vagrant!le
/path/to/perl-buildをGuestOSの
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.synced_folder "../", "/perl-build"
config.vm.provision "docker", run: "always" do |d|
/perl-buildにマウント
d.build_image "/perl-build/author",
args: "-t perl-build"
end
config.vm.provision "shell", run: "always",
inline: "docker run -v /perl-build:/perl-build perl-build"
config.vm.provision "destroy", destroy: false, run: "always"
end
docker provisionerを使うと
自動でGuestOSにdockerが入る
GuestOSを自動で停止shell provisionerでdocker run
余計なリソース使わない
114. docker provisionerで
docker runを行わない理由
Vagrant!le
config.vm.provision "docker", run: "always" do |d|
d.build_image "/perl-build/author", args: "-t perl-build"
d.run “perl-build”
end
docker provisionerで run
これだと、fatpackが終わる前に、vagrant upが終わり、
元のシェルにもどってしまい、いつfatpackが完了するか分からない
115. Vagrant+Docker
MacOS X
$ vagrant plugin install vagrant-destroy-provisioner
$ vagrat up
=> GuestOSの起動
=> docker provisionerでDockerイメージのビルド
=> shell provisioner経由でdocker run
==> 依存モジュールのインストール
==> fatpack
$ git status ../perl-build
..
# modified: ../perl-build
..
$
117. 今日の内容
• Docker の基本
• Docker!leとDockerイメージのビルド
• DockerでPerlを使う
• Dockerで自動化
• DockerでWebアプリケーション
120. Webアプリケーションの
Docker への Deploy
CMD carton exec -- plackup
RUN carton install
COPY . /opt/app
FROM perl:v5.20
docker イメージ
121. docker build
Docker!le 先にcpan!leをコピーし
carton installを行う事で
FROM kazeburo/perl:v5.20
RUN mkdir -p /opt/app
cacheを有効活用
COPY ./cpanfile /opt/app/cpanfile
COPY ./cpanfile.snapshot /opt/app/cpanfile.snapshot
WORKDIR /opt/app
RUN carton install --deployment
EXPOSE 5000
残りをコピー
COPY . /opt/app
CMD carton exec -- plackup -s Starlet --port 5000 -a app.psgi
124. Vagrantでport_forward
Vagrant!le
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.network "forwarded_port",
Macのtcp 25000 を
GuestOSの 15000 に
forward
guest:15000, host:25000
config.vm.provision "docker", run: "always" do |d|
d.pull_images "kazeburo/perl:v5.20"
end
end
Mac/
Vagrant GuestOS 25000 15000 5000 コンテナ