ラズパイ2で動く docker paas

33
ララララ 2 ラララ Docker PaaS Tetsuhiro Sato

Upload: npsg

Post on 16-Apr-2017

3.104 views

Category:

Engineering


3 download

TRANSCRIPT

Page 1: ラズパイ2で動く Docker PaaS

ラズパイ 2 で動く Docker PaaS

Tetsuhiro Sato

Page 2: ラズパイ2で動く Docker PaaS

2

自己紹介

佐藤 哲大( tetz ) 某ネットワークベンダで、 SDN (っぽい)仕

事をしてます ネットワークプログラマビリティ勉強会の企画、

運営をしてますhttp://network-programmability.connpass.com/

Page 3: ラズパイ2で動く Docker PaaS

3

TL;DR ラズパイ2で動く Docker PaaS を自作し

てみたので、その仕組みを紹介します (時間に余裕があれば、)自作した PaaS

を CI (継続的インテグレーション)してみたので、その仕組みを紹介します

Page 4: ラズパイ2で動く Docker PaaS

4

デモ①

<paas_name> は、既存の Linux コマンドと Linux ユーザとコンフリクトしなければ、なんでも可

<paas_name> は、ユーティリティコマンドと git リモートリポジトリの名前に使われる <paas_name> scale web=3 git push <paas_name> master

$ wget http://raw.github.com/tetsusat/raspaas/master/bootstrap.sh $ chmod +x bootstrap.sh$ sudo ./bootstrap.sh <paas_name>

Page 5: ラズパイ2で動く Docker PaaS

5

そもそも Docker PaaS のうれしさDocker PaaS従来の PaaS

ハードウェア

ハイパーバイザ

OS

ハードウェア

OS

Docker エンジン

実行環境(言語、ライブラ

リ、ミドルウェア)

実行環境(言語、ライブラ

リ、ミドルウェア)

アプリケーション アプリケーション

実行環境が多様化すると、 PaaS ユーザはうれしいが、 PaaS 事業者はメンテナンスが大変

PaaS ユーザは Docker コンテナで動作させられる言語、ライブラリ、ミドルウェアを自由に利用できる

PaaS 事業者は Docker コンテナが動作する環境を用意すればいい

どちらもハッピー

Page 6: ラズパイ2で動く Docker PaaS

6

なぜ、ラズパイ2で Docker PaaS ?

建前 ラズパイ2からクアッドコアに。これをカツカツに使いた

い 本音

x86 だと、すでにすぐれた Docker PaaS がかなりある(>_<)

Page 7: ラズパイ2で動く Docker PaaS

PaaS のデファクト - Heroku キャッチーでポップなワークフローにより一世風靡

7

$ heroku createCreating polar-inlet-4930... done, stack is cedar-14http://polar-inlet-4930.herokuapp.com/ | https://git.heroku.com/polar-inlet-4930.gitGit remote heroku added

$ heroku scale web=2Scaling dynos... done, now running web at 2:standard-1x

$ git push heroku masterFetching 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)....

Page 8: ラズパイ2で動く Docker PaaS

8

Heroku Inspired なDocker PaaS?

最小公倍数的な特徴(私見)ワークフローが Heroku っぽい

<heroku> creategit push <heroku> master<heroku> scale web=3

Buildpack 対応(後述) 具体例

シングルノードで動作する Dokkuマルチノードで動作する Deis 、 Flynn

Page 9: ラズパイ2で動く Docker PaaS

9

Raspaashttps://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 みたいなやつ )

Page 10: ラズパイ2で動く Docker PaaS

10

ちなみに Buildpack

アプリケーションを自動で検知し、実行する環境を用意する Heroku の仕組み

[ 参考 ] Buildpack Adventure 2 (http://ba2.herokuapp.com/)

Page 11: ラズパイ2で動く Docker PaaS

11

Heroku Inspired なDocker PaaS 比較(不完全版)

Dokku Raspaas

CPU アーキテクチャ x86_64 x86_64 x86_64 x86_64 / ARMv7

OS CoreOS Ubuntu Ubuntu Ubuntu

ノード マルチ マルチ シングル シングル

アプリケーションのデプロイ方式

BuildpackDocker イメージDockerfile

BuildpackDocker イメージ

BuildpackDockerfile

Buildpack-likeDockerfile

Page 12: ラズパイ2で動く Docker PaaS

12

デモ(つづき)

$ git clone https://github.com/tetsusat/ruby-sample.git $ teroku create$ git push teroku master$ teroku scale web=3

Page 13: ラズパイ2で動く Docker PaaS

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 コンテナ管理のユーティリティ

Page 14: ラズパイ2で動く Docker PaaS

14

git push でデプロイできる仕組み

Git Repogit push teroku master

① git clone …

③ docker build ….

④ docker run …

② Dockerfile の作成(なければ)

Page 15: ラズパイ2で動く Docker PaaS

15

Buildpack-like

https://github.com/tetsusat/buildpack-like

Raspaas 向けの Builpack っぽい仕掛け 以下の言語に対応

Ruby (2.2.2) Python (2.7.10) Node.js (0.12.7)

言語毎に 2 つのスクリプトからなる detect compile

Page 16: ラズパイ2で動く Docker PaaS

やってること( Ruby の場合)

#!/bin/bash

if [ -f "$1/Gemfile" ]; then echo "Ruby" exit 0fi

exit 1

detect

ファイルから言語を検知 Gemfile があれば Ruby requiremts.txt があれば Python package.json があれば Node.js

本家 Buildpack と同じ

Page 17: ラズパイ2で動く Docker PaaS

17

やってること( Ruby の場合)

#!/bin/bash

省略

# generate Dockerfileecho "FROM raspaas/$LANG:$VERSION" > $1/Dockerfile

# generate docker-compose.ymlCMD=$(get_procfile_cmd $1/Procfile)APP=$(get_app_name $1)cat << EOF > $1/docker-compose.ymlweb: image: $2/$APP command: $CMD ports: - 5000EOF

compile

Dockerfile を作成 言語: detect スクリプトで検知 バージョン: Gemfile から

docker-compose.yml を作成 CMD : Procfile から ポート番号 : 5000 決め打ち

Page 18: ラズパイ2で動く Docker PaaS

18

compile でできる DockerfileFROM 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 . /appFROM 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 が使えません (>_<)

Page 19: ラズパイ2で動く Docker PaaS

19

オートスケーリングの仕組み

Docker エンジン

registrator

① 登録

Nginx +consul template

app

consul② 設定更新

teroku scale web=3

app app

Docker コンテナ(システム)

Docker コンテナ(ユーザ)

HTTP リクエスト

Docker API

Page 20: ラズパイ2で動く Docker PaaS

20

Consul Template

{{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 のイベントをトリガーにテンプレートから特定のファイル(設定ファイルなど)を動的に生成し、アクション(サービスのリローなど)を実行

Page 21: ラズパイ2で動く Docker PaaS

21

Consul と Registrator 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

Page 22: ラズパイ2で動く Docker PaaS

22

Scaleway ARM ベースのベアメタルクラウドサービス 4 コア CPU + 50GB SSD で € 2.99

(安っ!)

Page 23: ラズパイ2で動く Docker PaaS

23

Drone+Gitlab+Vagrant でPaaS の CI 環境を構築してみた

Page 24: ラズパイ2で動く Docker PaaS

24

drone.io

Travis CI 、 Circle CI のように、 Github 等の Git ホスティングサービスと連携できるホスティング型の CI ツール

ホスティング版だけでなく、オンプレ環境で動作するオープンソース版がある

Drone + Gitlab + Vagrant で PaaS の CI 環境をオンプレに無料で作れそう。。。

Page 25: ラズパイ2で動く Docker PaaS

25

PaaS の CI

Drone Host Vagrant/Virtualbox

DroneDocker 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

Page 26: ラズパイ2で動く Docker PaaS

26

Serverspec と Infrataster

[ 参考 ] Introduction Infrataster(https://speakerdeck.com/ryotarai/introducing-infrataster)

Page 27: ラズパイ2で動く Docker PaaS

.drone.yml

27

image: "tetz/drone-npstudy"git: path:$$GITLAB/tetsusat/raspaasscript: - 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 実行

Page 28: ラズパイ2で動く Docker PaaS

28

Ansible PlaybooksRaspaas のセットアップ

- 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

Page 29: ラズパイ2で動く Docker PaaS

29

Ansible Playbooksサンプル App のセットアップ

- 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

Page 30: ラズパイ2で動く Docker PaaS

30

Infrastater Spec ファイルサンプル App のテスト

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 endend

tests/spec/raspaas_app_spec.rb

Page 31: ラズパイ2で動く Docker PaaS

31

Infrastater Spec ファイルオートスケーリングのテスト

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 endend

tests/spec/raspaas_auto_scale_spec.rb

Page 32: ラズパイ2で動く Docker PaaS

32

実行イメージ

失敗 成功

Page 33: ラズパイ2で動く Docker PaaS

33

おわり

ご清聴、ありがとうございました m(_ _)m