dockerハンズオン
TRANSCRIPT
Dockerハンズオン
Can you escape vendor lock-in with the cloud?
image by: https://blog.linode.com/2014/01/03/docker-on-linode/
written by @mainyaa
image by: https://blog.linode.com/2014/01/03/docker-on-linode/
Docker
Linuxのaufsやlxcやcgroupやnamespacingなど
の仮想化技術を使いやすくしたツール
●Docker IndexでみんながDocker imageを公開してい
るのですぐに使い始められる
●https://index.docker.io/
DockerDockerで作成したコンテナをDockerレポジトリ(not Github)に持っておける
●コンテナの差分を積み上げるようにキャッシュしているの
で、インフラレイヤーをいじらない限りデプロイが速い
●Dockerレポジトリもオープンソースで公開されているので、
自分でDockerレポジトリ作成も可能
Docker●問題が発生したら、すぐにロールバックが出来る
●良さそうなサーバー関連ソフトウェアを見つけたら、す
ぐに環境を作って試してみることができる
●OSイメージのスクラッチから環境構築からサーバー立
ち上げまでを自動化できるため、
○→vender lock-inされない環境を作れる
普通の仮想技術との違い
● Dockerfileを記述することでスクラッチから環境構築し
てウェブアプリを動かすまで全てを完結
● gitのようにコマンドごとに差分を保存している
● イメージ差分をpullするので、デプロイも速い
● ソフトウェアのインストールをDockerだけで完結させる
CoreOSが出てくるなど、OS自体の仮想化の影響を与
えている
image by: http://docs.docker.io/
-> Install Docker
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.9.2
BuildVersion: 13C1021
$ brew -v
Homebrew 0.9.5
$ vagrant -v
Vagrant 1.4.3
Version Check
$ cat << 'EOF' >> ~/.bashrc
export PS1="\[\e[1;32m\][\u@\h:\w]\#\[\e
[00m\] "
EOF
$ source ~/.bashrc
tips1:色を付けよう
$ cat << 'EOF' >> ~/.bashrc
$ alias dl=’docker ps -l -q’
EOF
$ source ~/.bashrc
aliasでcontainer idのコピペを無くす
tips2: aliasを設定
$ brew tap phinze/homebrew-cask$ brew install brew-cask$ brew cask install virtualbox$ brew cask install vagrant
Install Vagrant
$ brew install boot2docker
$ brew install docker
Install Docker
tips: boot2dockerboot2dockerというDockerのみが入っている軽量ゲスト
OSをVirtualBox上に走らせてくれる。
boot2dockerは、vagrantに依存しない軽量ゲストOS操作ツール。
boot2dockerをインストールしておけば、vagrant sshではなく、Mac上のターミナルからdockerコマンドを立たけ
るようになる
# Install boot2docker
$ brew install boot2docker
Install boot2docker
$ boot2docker init
$ boot2docker up
$ echo << 'EOF' >> ~/.bashrc export DOCKER_HOST=tcp://localhost:4243
EOF
boot2docker起動
Docker on VirtualBox on Mac
$ docker version
Client version: 0.11.0
Go version (client): go1.2.1
Git commit (client): fb99f99
Server version: 0.11.0
Git commit (server): fb99f99
Go version (server): go1.2.1
Last stable version: 0.11.1, please update docker
version check
$ boot2docker stop
$ boot2docker delete
$ boot2docker download
$ boot2docker init
$ boot2docker up
もしboot2dockerが古いなら
busybox on Docker on VirtualBox on Mac
$ docker run busybox echo 'docker on Mac \o/'
Unable to find image 'busybox' (tag: latest) locally
Pulling repository busybox
3dd072f45bf6: Download complete
511136ea3c5a: Download complete
24abbd812704: Download complete
a943c4969b70: Download complete
docker on Mac \o/
$ docker run busybox echo 'docker on Mac \o/'
docker on Mac \o/
busyboxでhelloworld
$ docker ps -a
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS
NAMES
33273963cab6 busybox:latest echo docker on
Mac \ 3 days ago Exit 0
sick_bardeen
docker ps -a
-a オプションは終了したコンテナも全て表示してくれる。
33273963cab6 Exit 0 <- これは先ほどのhelloworld。正常
終了していることがわかる。
docker ps -a
$ docker images --tree
├─511136ea3c5a Virtual Size: 0 B
│ └─24abbd812704 Virtual Size: 0 B
│ └─a943c4969b70 Virtual Size: 2.489 MB
│ └─3dd072f45bf6 Virtual Size: 2.489 MB
Tags: busybox:latest
docker images --tree
images --treeはdockerのコンテナidのヒエラルキーと、
tagが見れる
docker images --tree
docker run コンテナを作成する.
docker stop コンテナを停止する.
docker start コンテナを起動する.
docker restart コンテナを再起動する.
docker attach 起動中のコンテナに接続する.
docker rm コンテナを破棄する(コンテナを停止する必要がある)
docker wait コンテナが停止するまでブロックする.
コマンド一覧
Docker on AWS
$ ssh docker-aws.ap-northeast-1b
$ cat << 'EOF' >> ~/.bashrc
export PS1="\[\e[1;31m\][\u@\h:\w]\#\[\e[00m\] "
EOF
$ source ~/.bashrc
promptに色を付けよう
$ yum install -y docker
$ sudo service docker start
$ groupadd docker
$ gpasswd -a #{USER} docker # sudo が要らなくなる魔法
$ sudo service docker restart
$ exit
$ exit # 一旦ログアウト
docker install
$ ssh docker-aws.ap-northeast-1b
$ docker run busybox echo 'docker on AWS \o/'
docker on AWS \o/
hello world!
$ docker version
Client version: 0.9.0
Go version (client): go1.2
Git commit (client): 2b3fdf2/0.9.0
Server version: 0.9.0
Git commit (server): 2b3fdf2/0.9.0
Go version (server): go1.2
Last stable version: 0.11.1, please update docker
hello world!
Ubuntu on Docker on AWS
$ docker run -t -i ubuntu /bin/bash
# uname -a
# exit
$ docker commit -m “hello ubuntu” `dl`
Hello Ubuntu!
Dockerfileを作ろう
-t -i は使わない$ docker run -t -i の使い方は覚えましたか?でも、この方法はデバッグ時以外は基本的に使いません。$ docker run -t -i + $ docker commitでやるスタイルもありますが、
Dockerfileを作るのがオススメ
DockerfileDockerfileを作って、$ docker build .を実行しましょう。
$ mkdir docker-redis
$ cd docker-redis
$ vim Dockerfile
from ubuntu
run apt-get update
$ docker build .
Dockerfileを作成
Dockerfilefrom ubuntuでベースとなるコンテナをfromで指定します。run apt-get updateでrun の後に実行したいコマンドを書いていきましょう。runを実行したら、その結果がどんどんキャッシュされて積み上がっていきます。http://docs.docker.io/en/latest/use/builder/
Tips: fswatchDockerfileを更新するたびに$ docker build .を実行するのが面倒くさい人はfswatchを使いましょう。$ brew install fswatch$ fswatch . “docker build .”
https://github.com/mainyaa/docker-redis
redis-serverをインストール
from ubuntu:12.04
maintainer KazuyukiMori <[email protected]>
run locale-gen en_US.UTF-8
run update-locale LANG=en_US.UTF-8
env DEBIAN_FRONTEND noninteractive
env LC_ALL C
env LC_ALL en_US.UTF-8
run echo "deb http://us.archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
run apt-get update
run apt-get install -y redis-server
expose 6379
entrypoint ["/usr/bin/redis-server"]
redis-serverをインストール
Dockerfileexpose 6379で公開するポート番号を指定します。entrypoint [“/usr/bin/redis-server”]でサーバーを立ち上げるコマンドを書きます。
run echo "deb http://us.archive.ubuntu.
com/ubuntu precise main universe" >
/etc/apt/sources.list
Dockerfileに必ずこの文章を書きましょう
キャッシュを使うと断然速い
Tips: キャッシュ
run locale-gen en_US.UTF-8
run update-locale LANG=en_US.UTF-8
env DEBIAN_FRONTEND noninteractive
env LC_ALL C
env LC_ALL en_US.UTF-8
英語の人はこの設定は要りません。
Dockerfileに必ずこの文章を書きましょう。シェルを前提にしているプログラ
ムが多いため、変なエラーを回避できます
Tips: locale + env
$ docker build -t <your name>/redis .
ビルド
↑タグ名 ↑ビルドターゲット
$ docker run -d -p 6379:6379 <yourname>/redis
デーモン実行
↑ポート設定
実行するコンテナID or タグ名
$ brew install redis
Warning: redis-2.8.4 already installed
$ redis-cli -h 108.59.85.37
108.59.85.37:6379> set docker awesome
OK
108.59.85.37:6379> get docker
"awesome"
Try it!
↑
$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESb5a165a64956 mainyaa/redis:latest /usr/bin/redis-serve 2 hours ago Up 2 hours 6379/tcp backstabbing_bell
try it! (AWS)
$ docker inspect b5a165a64956 "NetworkSettings": { "IPAddress": "172.17.0.2",
$ redis-cli -h 172.17.0.2
try it! (AWS)
$ docker login
$ docker push <yourname>/redis
レポジトリにpush
Docker Indexに無事にpushが出来ているか見てみようhttps://index.docker.io/
$ docker pull <yourname>/redis
$ docker run -d -p 6379:6379
<yourname>/redis
pullしてきたものはdocker buildしなくてよい。
そのままdocker runできる。
レポジトリからpull
$ Docker の問題点
Dockerの問題点● とにかくストレージを食う。すべての差分イメージを保存し
ているため、ストレージをかなり圧迫する
● Docker runは基本的にshellを持たない
○ cronでapt-get updateしていた人は分かるかもしれな
いけど、ユーザーインタラクションが必要になるとそこで
処理が止まってしまう
Dockerの問題点● ネットワーク設定に癖がある
● サーバーのリソース管理に物理ホストの上に、仮想ホスト、
Dockerのコンテナidというレイヤーが出来てしまうので混
乱しやすい
● Dockerがまだまだ安定していない。Docker公式にも本番
で運用するのはまだ速すぎると明言されている。
$ Docker Tips
$ docker build -t mainyaa/redis .
タグをかならずつけましょう
tips: build -t
$ docker ps -a | grep 'weeks ago' | awk '{print
$1}' | xargs docker rm
Dockerfileがあれば何時でもコンテナは作れるので、古い
ものはどんどん削除
tips: 古いコンテナ削除
tips: imageのツリーをpngに
$ docker images -viz | dot -Tpng -o docker.png
$ Advanced
Immutable Inftractureの制約● デファクトスタンダードはない
● ログの集約はクラウド時代に合ったものでなければならな
い
● サーバーのリソース管理や監視が難しいし、プロビジョニ
ングツールもデプロイツールも出来る事が多く、レイヤー
が複雑だし、データベースは使い捨てに出来ないし、スト
レージは使い捨てに出来ないし・・・
● /^o^\フッジッサーン
Log● ElesticSearch + kibanaでログの集約と可視化をしよう● collectd + graphite でログの集約と可視化をしよう● fluentd + Google BigQueryでログを解析しよう
ノードの管理、自動化
● skydock+skydnsで、dockerのstart/stopだけでDNSを更新しよう○ https://github.com/crosbymichael/skydock
● Serf+HAProxyでAutomatic Load Balancerをつくろう○ http://blog.glidenote.
com/blog/2013/10/30/serf-haproxy/
CoreOS全てのソフトをDockerで動かす野心的なOS。パッケージマネージャーのたぐいは入っておらず、クラスタでの動作に重きを置かれ、etcdによってノード間の設定情報を共有できる。ウェブアプリのホストに最適。
Jenkins and more!● Jenkinsでdockerイメージをビルドしてレポジトリにアップ
ロードしよう● Sensuで監視をしよう● busyboxで組み込み並みの超軽量サーバーをつくろう
まとめ● DockerはDockerfileをかけばいつでも環境ごと戻せるよ● Dockerfileがあれば、開発環境の構築がdocker runのみ
でよくなり、プロダクション環境と開発環境を限りなく近づけられる
● 開発環境の変更はDockerfileを書く→docker build→Jenkinsでビルド+serverspecのテスト実行→