Más contenido relacionado La actualidad más candente (20) Similar a ラズパイ2で動く Docker PaaS (20) ラズパイ2で動く Docker PaaS2. 自己紹介
佐藤 哲大(tetz)
某ネットワークベンダで、SDN(っぽい)仕事をして
ます
ネットワークプログラマビリティ勉強会の企画、運営
をしてます
http://network-programmability.connpass.com/
2
3. TL;DR
ラズパイ2で動く Docker PaaS を自作してみた
ので、その仕組みを紹介します
(時間に余裕があれば、)自作した PaaS を CI
(継続的インテグレーション)してみたので、その
仕組みを紹介します
3
4. デモ①
<paas_name> は、既存の Linux コマンドと Linux ユーザとコ
ンフリクトしなければ、なんでも可
<paas_name> は、ユーティリティコマンドと git リモートリポジトリ
の名前に使われる
<paas_name> scale web=3
git push <paas_name> master
4
$ wget http://raw.github.com/tetsusat/raspaas/master/bootstrap.sh
$ chmod +x bootstrap.sh
$ sudo ./bootstrap.sh <paas_name>
5. そもそも Docker PaaS のうれしさ
5
Docker PaaS従来のPaaS
ハードウェア
ハイパーバイザ
OS
ハードウェア
OS
Docker エンジン
実行環境
(言語、ライブラリ、ミド
ルウェア)
実行環境
(言語、ライブラリ、ミド
ルウェア)
アプリケーション アプリケーション
実行環境が多様化すると、PaaS ユー
ザはうれしいが、PaaS 事業者はメン
テナンスが大変
PaaS ユーザは Docker コンテナで
動作させられる言語、ライブラリ、ミド
ルウェアを自由に利用できる
PaaS 事業者は Docker コンテナが
動作する環境を用意すればいい
どちらもハッピー
7. PaaS のデファクト - Heroku
キャッチーでポップなワークフローにより一世風靡
7
$ heroku create
Creating polar-inlet-4930... done, stack is cedar-14
http://polar-inlet-4930.herokuapp.com/ | https://git.heroku.com/polar-inlet-4930.git
Git remote heroku added
$ heroku scale web=2
Scaling dynos... done, now running web at 2:standard-1x
$ git push heroku master
Fetching repository, done.
Counting objects: 10, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 876 bytes | 0 bytes/s, done.
Total 6 (delta 4), reused 0 (delta 0)
....
8. Heroku Inspired な
Docker PaaS?
最小公倍数的な特徴(私見)
ワークフローが Heroku っぽい
<heroku> create
git push <heroku> master
<heroku> scale web=3
Buildpack 対応(後述)
具体例
シングルノードで動作する Dokku
マルチノードで動作する Deis、Flynn
8
9. Raspaas
https://github.com/tetsusat/raspaas
利用可能な環境
x86_64
Ubuntu14.04 / Docker 1.6 # Vagrantfile 参照
ARMv7
Hypriot Docker Image for Raspberry Pi (Version 0.4)
http://blog.hypriot.com/downloads/
Scaleway (www.scaleway.com)
できること
git push … で Docker コンテナが立ち上がる
オートスケーリング (heroku scale web=3 みたいなやつ)
9
11. Heroku Inspired な
Docker PaaS 比較(不完全版)
11
Dokku Raspaas
CPU アーキテクチャ x86_64 x86_64 x86_64 x86_64 / ARMv7
OS CoreOS Ubuntu Ubuntu Ubuntu
ノード マルチ マルチ シングル シングル
アプリケーションの
デプロイ方式
Buildpack
Dockerイメージ
Dockerfile
Buildpack
Dockerイメージ
Buildpack
Dockerfile
Buildpack-like
Dockerfile
12. デモ(つづき)
12
$ git clone https://github.com/tetsusat/ruby-sample.git
$ teroku create
$ git push teroku master
$ teroku scale web=3
13. 利用コンポーネント
gitreceive (https://github.com/progrium/gitreceive/)
git push した際の git フックを仕掛けるためのユーティリティ
Consul (https://www.consul.io/)
サービスディスカバリ
Registrator (https://hub.docker.com/r/gliderlabs/registrator/)
Docker API からサービスを検知して Consul へ登録
Consul Template (https://github.com/hashicorp/consul-template)
Consul イベントを検知して Nginx の設定を更新
Nginx (http://nginx.org/)
ルータ(HTTP リクエストをロードバランス)
Docker Compose (https://docs.docker.com/compose/)
Docker コンテナ管理のユーティリティ
13
16. やってること(Rubyの場合)
#!/bin/bash
if [ -f "$1/Gemfile" ]; then
echo "Ruby"
exit 0
fi
exit 1
detect
ファイルから言語を検知
Gemfile があれば Ruby
requiremts.txt があれば Python
package.json があれば Node.js
本家 Buildpack と同じ
17. やってること(Rubyの場合)
17
#!/bin/bash
省略
# generate Dockerfile
echo "FROM raspaas/$LANG:$VERSION" > $1/Dockerfile
# generate docker-compose.yml
CMD=$(get_procfile_cmd $1/Procfile)
APP=$(get_app_name $1)
cat << EOF > $1/docker-compose.yml
web:
image: $2/$APP
command: $CMD
ports:
- 5000
EOF
compile
Dockerfile を作成
言語: detectスクリプトで検知
バージョン: Gemfile から
docker-compose.yml を作成
CMD: Procfile から
ポート番号: 5000 決め打ち
18. compile でできる Dockerfile
18
FROM ruby:2.2.2
ENV PORT 5000
EXPOSE 5000
RUN mkdir /app
WORKDIR /app
ONBUILD ADD ./Gemfile Gemfile
ONBUILD ADD ./Gemfile.lock Gemfile.lock
ONBUILD RUN bundle install
ONBUILD ADD . /app
FROM raspaas/ruby:2.2.2
compile スクリプトが作成する Dockerfile
raspaas/ruby:2.2.2
compile スクリプトは FROM 文一行からなる Dockerfile を作成
継承する親 Dockerfile は Automated Build で管理
https://hub.docker.com/r/raspaas/
なので、ARM では Buildpack-like が使えません (>_<)
20. Consul Template
20
{{range services}}upstream {{.Name}} {
{{range service .Name}}server 10.0.2.15:{{.Port}};
{{else}}server 127.0.0.1:65535; # force a 502{{end}}
}{{end}}
server {
listen 80;
{{range services}}location /{{.Name}} {
proxy_pass http://{{.Name}}/;
}{{end}}
}
upstream ruby-sample {
server 10.0.2.15:32768;
server 10.0.2.15:32769;
server 10.0.2.15:32770;
}
server {
listen 80;
}location /ruby-sample {
proxy_pass http://ruby-sample/;
}
}
/etc/nginx/conf.d/service.conf
(一部のみ)/templates/service.ctmpl
Consul のイベントをトリガーにテンプレートから特定のファイル(設
定ファイルなど)を動的に生成し、アクション(サービスのリローなど)
を実行
21. Consul と Registrator
21
Registrator は Docker API 経由で Docker の起動を検知し、Consul
に登録してくれる
$ docker run -d -v /var/run/docker.sock:/tmp/docker.sock --restart=always --
name registrator -h registrator gliderlabs/registrator consul://$DOCKER_IP:8500
$ docker run -d -p 8400:8400 -p 8500:8500 -p 8600:53/udp --restart=always --
name consul -h consul progrium/consul -server -advertise $DOCKER_IP -
bootstrap -ui-dir /ui
24. drone.io
Travis CI、Circle CI のように、Github 等の Git ホスティング
サービスと連携できるホスティング型の CI ツール
ホスティング版だけでなく、オンプレ環境で動作するオープンソース
版がある
Drone + Gitlab + Vagrant で PaaS の CI 環境をオンプレに
無料で作れそう。。。
24
25. PaaS の CI
25
Drone Host Vagrant/Virtualbox
Drone
Docker Engine
app app app
① Gitlab へ git push
② Gitlab から Drone を呼び出し
③ Drone がテスト用に Docker コンテナを生成
④ AnsibleでVagrant VM の起動
⑤ Ansibleで PaaS (raspaas) のインストール
⑥ Ansible で App (ruby-sample) のインストール
⑦ Infrataster でテスト
⑧ Ansible で App のオートスケーリング
⑨ Infrataster でテスト
⑩ AnsibleでVagrant VM の廃棄
④
⑩
⑤ ⑥ ⑧
⑦ ⑨
Docker コンテナ
VirtualBox VM
Infrataster
Ansible
①
②
③
27. .drone.yml
27
image: "tetz/drone-npstudy"
git:
path:$$GITLAB/tetsusat/raspaas
script:
- rm $HOME/.ssh/id_rsa
- echo 'StrictHostKeyChecking=no' > $HOME/.ssh/ssh-config
- ssh-keygen -f $HOME/.ssh/id_rsa -t rsa -q -N ''
- sshpass -p $$VAGRANT_HOST_PASS ssh-copy-id
$$VAGRANT_HOST_USER@$$VAGRANT_HOST
- echo 'vagrant-host ansible_ssh_host=$$VAGRANT_HOST
ansible_ssh_user=$$VAGRANT_HOST_USER' > hosts
- echo 'vagrant-guest ansible_ssh_port=22222 ansible_ssh_host=$$VAGRANT_HOST
ansible_ssh_user=$$VAGRANT_USER' >> hosts
- ansible-playbook -i hosts playbooks/vagrant-up.yml
- sshpass -p vagrant ssh-copy-id 'vagrant@$$VAGRANT_HOST -p 22222'
- ansible-playbook -i hosts playbooks/raspaas-setup.yml
- ansible-playbook -i hosts playbooks/app-setup.yml
- cd tests
- rspec spec/raspaas_app_spec.rb
- ansible-playbook -i ../hosts ../playbooks/app-auto-scale.yml
- rspec spec/raspaas_auto_scale_spec.rb
- ansible-playbook -i ../hosts ../playbooks/vagrant-destroy.yml
Ansibleインベントリ作成
Ansible Playbook 実行
Infrataster 実行
28. Ansible Playbooks
Raspaas のセットアップ
28
- hosts: vagrant-guest
tasks:
- name: restart docker engine
command: sudo service docker restart
- name: download bootstrap.sh
command: wget http://raw.github.com/tetsusat/raspaas/master/bootstrap.sh
- name: chmod +x bootstrap.sh
command: chmod +x bootstrap.sh
- name: start bootstrap script
command: sudo ./bootstrap.sh teroku
playbooks/raspaas-setup.yml
29. Ansible Playbooks
サンプル App のセットアップ
29
- hosts: vagrant-guest
tasks:
- name: change ssh config for git push
shell: echo 'StrictHostKeyChecking no' > $HOME/.ssh/config
- name: git clone
command: git clone https://github.com/tetsusat/ruby-sample.git
- name: teroku create
command: teroku create
args:
chdir: ruby-sample/
- name: git push
command: git push teroku master
args:
chdir: ruby-sample/
playbooks/app-setup.yml
30. Infrastater Spec ファイル
サンプル App のテスト
30
require 'spec_helper'
describe server(:vagrant_host) do
describe http('http://<vagrant_host>:8080/ruby-sample') do
it "responds content including 'Hello, world'" do
expect(response.body).to include('Hello, world')
end
end
end
tests/spec/raspaas_app_spec.rb
31. Infrastater Spec ファイル
オートスケーリングのテスト
31
require 'spec_helper'
seen = []
describe server(:vagrant_host) do
3.times do
describe http('http://<vagrant_host>:8080/ruby-sample') do
it "responds content including 'Hello, world' from unseen container" do
see = ""
if response.body =~ /Hello, world from (w+)/
see = $1
end
expect(seen).not_to include(see)
seen << see
end
end
end
end
tests/spec/raspaas_auto_scale_spec.rb