Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
31
Help us understand the problem. What is going on with this article?
@takehilo

Docker社の言う"Container as a Service"をやってみた

More than 5 years have passed since last update.

本記事はDocker Advent Calendar 2015の13日目の記事です。

概要

先日の DockerCon Europe 2015において、Docker社は「Container as a Service」という戦略を打ち出しました。詳しくはpublickeyさんの記事を見ていただければと思いますが、ここで紹介されているデモが非常に興味深かったので、再現してみることにしました。

作成するデモの内容

Github > Travis CI > Docker Hub > Tutum のCI/CDパイプラインを作ります。上記記事で紹介されているデモと少し流れが違いますが、やりたいことは同じです。git pushするだけで、テストが実行され、Dockerイメージがビルドされ、最終的にはアプリがデプロイされるという自動化フローを作ります。

Tutumについて

Docker社が今年の10月に買収したコンテナのデプロイサービスです。位置付け的にはKubernetesやMesosなどと同じくコンテナのスケジューリング機能を持つサービスですが、Dockerホストクラスタを直感的なGUIで簡単にクラウド上に用意できることから、より開発者フレンドリーなサービスだと言えると思います。VMから下の管理を全てTutumに任せることができるため、ユーザは開発に集中することができます。まだベータ版であることから、誰でも無料で試すことができます1

Tutumはそれ自体がクラウドを持っているわけではなく、Tutumを通してAWSやDigital Oceanといったクラウドサービス上にDockerホストクラスタを構築し、そのクラスタ上にコンテナを配置していくという形になります。今回はAWSを利用します。

デモに利用するアプリについて

AngularJSのチュートリアルで使用されているangular-phonecatというアプリを利用することにします。これを自分のGithubリポジトリにforkする形で進めていきます。

事前準備

以下の準備をしておいてください。なお、Macを前提とします。

  • Github上でangular-phonecatリポジトリをforkする
  • Homebrewをインストールする
  • Google Chromeをインストールする
  • Docker Toolboxをインストールし、dockerコマンドがたたける状態にする
  • AWSアカウントのアクセスキーとシークレットアクセスキーを取得しておく
    • TutumがEC2等を操作するため、適切な権限が付与されている必要があります。詳しくは公式ドキュメントを参照してください

nodebrewのインストール

angular-phonecatはnode.jsを使用します。以下の手順でnode.jsが使えるようにしておきます。

$ brew install nodebrew
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile

$ nodebrew install-binary v0.12.9
$ nodebrew use v0.12.9

$ node -v
v0.12.9
$ npm -v
2.14.9

アプリの実行確認

angular-phonecatがどんなアプリなのか、まずは試しておきましょう。forkしたリポジトリをクローンし、アプリを実行してみます。

$ git clone https://github.com/tktk8924/angular-phonecat.git
$ cd angular-phonecat
$ npm install
$ npm start

ブラウザでhttp://localhost:8000/appにアクセスすると、アプリが表示されます。

今度はテストを実行してみます。このリポジトリにはユニットテストとE2Eテストが用意されています。E2Eテストは実際に稼働しているアプリに対してテストが行われるので、アプリは起動したままにしておいてください。

$ npm test
...
Chrome 47.0.2526 (Mac OS X 10.11.1): Executed 5 of 5 SUCCESS (0.077 secs / 0.073 secs)
Firefox 41.0.0 (Mac OS X 10.11.0): Executed 5 of 5 SUCCESS (0.06 secs / 0.058 secs)
TOTAL: 10 SUCCESS

$ npm run protractor
...
7 tests, 11 assertions, 0 failures

上記のように出力されていればテスト成功です。

Dockerコンテナ化

angular-phonecatは最終的にDockerコンテナとしてTutum上にデプロイされることになりますので、Dockerfileを作成してイメージをビルドできるようにします。

Dockerfileの作成

以下の内容でDockerfileを作成します。

FROM node:0.12

WORKDIR /app
COPY ./ .

RUN npm install
RUN node_modules/.bin/bower --allow-root install

EXPOSE 8000
CMD ["npm", "start"]

Dockerfileはクローンしたリポジトリのルートディレクトリに置いてください。

$ tree angular-phonecat -L 1
angular-phonecat
├── Dockerfile
├── LICENSE
├── README.md
├── app
├── bower.json
├── node_modules
├── package.json
├── scripts
└── test

コンテナの起動テスト

イメージをビルドして、アプリがコンテナで動作することを確認します。Dockerfileがあるディレクトリで以下のコマンドを実行します。

$ docker build -t angular-phonecat .
$ docker images
REPOSITORY                       TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
angular-phonecat                 latest              88fd1db238cb        10 minutes ago      855.8 MB

イメージができたらコンテナを起動してみましょう。以下のコマンドを実行してください。

$ docker run -d -p 8000:8000 --name angular-phonecat angular-phonecat
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
58b967642168        angular-phonecat    "npm start"         11 minutes ago      Up 10 minutes       0.0.0.0:8000->8000/tcp   angular-phonecat

http://{Your Docker Host IP}:8000/appにアクセスして、アプリが表示されることを確認してください。

GithubとTravis CIの連携

まずはGithubとTravis CIを連携させ、git pushに対して自動でテストが実行されるようにしましょう。

Travis CIにログインし、プロファイルページで該当のリポジトリを有効にします。下記のようになればOKです。

Kobito.fWry8b.png

Docker Hub Automated Buildの設定

続いて、Docker Hubに自動ビルド(Automated Build)の設定を行います。Travis CIにてテストが成功したら、さきほど作成したDockerfileを使って自動でイメージがビルドされるようにします。

Docker Hubにログインし、Linked Accounts & ServicesページでGithubとリンクしておきます。途中で聞かれるアクセス権限については、Public and Private(Recommended)の方を選択してください。下記のようになればOKです。

Kobito.DfnPdr.png

次に、画面右上のCreate > Create Automated Buildをクリックします。するとGithubのリポジトリ一覧が表示されるので、angular-phonecatをクリックします。

ここではShort Descriptionにてきとうな文字列を入れ、Createをクリックします。

Kobito.teNDSX.png

これでDocker Hub上にangular-phonecatリポジトリが作成されました。

Kobito.2brQkd.png

Build Settingsに移動して、「When active, builds will happen automatically on pushes.」のチェックを外します。Githubへのプッシュではなく、Travis CIをビルド開始のトリガーにするためです。

Kobito.IFnkas.png

さらに画面下の方にあるBuild TriggerのところのActivate Triggersをクリックします。するとこのイメージのビルドを開始するためのTrigger URLが表示されます。Travis CIからこのURLにHTTP POSTすることで、イメージのビルドが開始されます。

Kobito.lvYzC3.png

Github > Travis CI > Docker Hub のフローを自動化する

それでは、git pushによってDockerイメージがビルドされるところまでを自動化しましょう。

angular-phonecatリポジトリにはTravis CIのビルド設定ファイルである.travis.ymlがすでに含まれていますが、これを以下のように変更したいと思います。

travis.yml
language: node_js
node_js:
  - 0.12

before_script:
  - export DISPLAY=:99.0
  - sh -e /etc/init.d/xvfb start
  - npm start > /dev/null &
  - npm run update-webdriver
  - sleep 3

script:
  - node_modules/.bin/karma start test/karma.conf.js --no-auto-watch --single-run --reporters=dots --browsers=Firefox
  - node_modules/.bin/protractor test/protractor-conf.js --browser=firefox

after_success: .travis/after_success.sh

after_successscriptのテストが成功したら実行されるスクリプトです。テストが成功したらDocker Hubでイメージをビルドするようにします。下記のスクリプトファイルを作成してください。Trigger URLはご自分の環境に合わせて修正してください。

travis/after_success.sh
#!/bin/bash

if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
  curl -i -H "Content-Type: application/json" --data '{"source_type": "Branch", "source_name": "master"}' -X POST {Your Trigger URL}
fi

※このままではTrigger URLはGithub上で公開されることになってしまいます。Trigger URLが知られてしまうと誰でもイメージのビルドができてしまうので危険です。Travis CIではこのような秘密にしておきたいデータを暗号化して記述できるようにする機能がありますので、そちらを利用してください。

$TRAVIS_PULL_REQUESTはTravis CIによって提供される環境変数で、ビルドするコードのリビジョンがプルリクされたものかどうかを判別するために使います。Dockerイメージのビルドはmasterブランチにマージされたコードを使って行いたいのでこのような書き方をしています。

もともとあったscriptsディレクトリは不要なので削除します。また、after_success.shに実行権限をつけます。

$ rm -fr scripts
$ chmod +x .travis/after_success.sh

これで準備は完了です。これまでの変更をコミットしてgit pushしましょう。Travis CIでテストが実行され、Docker Hubでイメージがビルドされるはずです。

$ git add .

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   .travis.yml
        new file:   .travis/after_success.sh
        new file:   Dockerfile
        deleted:    scripts/private/README.md
        deleted:    scripts/private/old/README.md
        deleted:    scripts/private/old/ScrapeData.js
        deleted:    scripts/private/old/format-json.sh
        deleted:    scripts/private/old/goto_step.bat
        deleted:    scripts/private/old/goto_step.sh
        deleted:    scripts/private/old/snapshot.sh
        deleted:    scripts/private/push-to-github.sh
        deleted:    scripts/private/retag.sh
        deleted:    scripts/private/test-all.sh
        deleted:    scripts/private/update-gh-pages.sh
        deleted:    scripts/update-repo.sh

$ git commit -m "Add Dockerfile and integration with Docker Hub"

$ git push -u origin master

Travis CIのビルド完了画面

Kobito.Bk2uM1.png

Docker HubのBuild Details画面

Kobito.0twOon.png

Tutum利用準備

ようやくTutumを使うところまで来ました。さっそくログインしてみましょう。Docker Hubのアカウントでログインできます。

ログインしたら、まずはTutumをAWSとリンクさせます。画面右上のアカウントをクリックし、Account infoページに移動してください。

Kobito.TN9ZaJ.png

次に、Amazon Web ServicesのAdd credentialsボタンをクリックして、アクセスキーとシークレットアクセスキーを入力します。これでAWSとのリンクは完了です。

それでは、Dockerホストクラスタを構築します。TutumではDockerホストをNodeと呼んでいます。Launch new node clusterをクリックしてください。

Kobito.ub7cn2.png

とりあえずNode cluster nameだけ入力し、Launch node clusterをクリックします。するとNodeが1台EC2上に構築されます。VPCやセキュリティグループなど、必要な設定はTutumが全てやってくれます。

Kobito.fPw3oh.png

Nodeが構築されました。

Kobito.EdVZV5.png

アプリのデプロイ

Nodeが構築され、コンテナをデプロイする準備ができました。いよいよangular-phonecatアプリをデプロイします。あんまり面白くありませんが、とりあえずangular-phonecatコンテナを1台デプロイしてみることにします。

Tutumでは同じイメージから起動されたコンテナの集まりをServiceと呼びます。Create serviceをクリックしてください。

Kobito.IWrtl4.png

まずはイメージを選択します。Public repositories > Search Docker hubと進んで、さきほど作成した自分のangular-phonecatイメージリポジトリ名を入力します。そしてSelectをクリックしてください。

Kobito.79xK2B.png

続いてServiceの設定です。一箇所だけ、Portsの設定を修正します。Publishedにチェックを入れて、Node portに80を指定します。これでangular-phonecatコンテナに対してインターネット上からポート80番でアクセス出来るようになります。docker run -p 80:8000と同じ意味ですね。修正できたらCreate and deployをクリックしてください。

Kobito.6th9w7.png

これでコンテナのデプロイが始まります。Docker Hubからイメージをpullし、AWS上のNode内にコンテナが起動します。デプロイが完了するとこんな感じの画面が確認できると思います。

Kobito.hI0h7t.png

それではangular-phonecatアプリにアクセスしてみましょう。Endpointsタブを開いてください。

Kobito.sJ1WSa.png

するとService endpointsというところにServiceのURLが表示されています。このURL(に/appを加えて)をブラウザで開いてください。

Kobito.A8Znif.png

angular-phonecatアプリが表示されました。これでアプリのデプロイは完了です。

Docker Hub > Tutum Redeployのフローを自動化する

最後に、Docker HubとTutumを連携させます。Docker Hubにてイメージが更新されたら、さきほどデプロイしたコンテナを自動でRedeploy(コンテナを停止し、最新のイメージをpullして新しいコンテナをデプロイする)します。こうすることですぐに変更が反映されるようになります。

さきほどデプロイしたコンテナ(Service)の画面からTriggersタブに移動します。ここでTriggersというものを登録します。TriggersというのはTutumのAPIの一つであり、外部のプログラムからこのAPIにHTTP POSTすることで、ServiceをRedeployさせることができます。Add trigger欄に任意の文字列を入力し、+Addをクリックします。

Kobito.mwmGOc.png

Triggerが登録されました。このURLをDocker Hub側からPOSTすることで、Serviceの自動Redeployを可能にします。URLはコピーしておいてください。

今度はDocker Hub側にWebhookの設定を追加します。Docker Hub上のangular-phonecatリポジトリページに行き、その中のWebhooksというタブに移動してください。

Kobito.Mt9jAg.png

Add Webhookをクリックし、さきほどコピーしたURLを登録します。

Kobito.10iNOv.png

Kobito.BV0rfA.png

Webhookが登録されました。これでDockerイメージが更新されるたびにコンテナがRedeployされ、変更が自動で反映されるようになります。

お疲れ様でした。これで全ての設定が完了しました。

Git Push!!

アプリに変更を加えてgit pushしてみましょう。app/partials/phone-list.htmlの6行目に以下のコードを追記してください。検索ボックスの上に見出しをつけます。

<h1>Angular Phonecat</h1>

コミットしてgit pushしましょう。

$ git commit -am "Add heading"
$ git push origin master

ServiceのURLにアクセスしてみましょう。下記のような画面になっていれば成功です。

Kobito.v2ftgE.png

おわりに

今回はGithub>Travis CI>Docker Hub>TutumというCI/CDパイプラインを作ってみましたが、このパイプラインの組み合わせは色々なパターンがあると思います。特に企業のプロダクションで利用するということであれば、イメージをprivateにしておきたいはずです。実はTutumにはPrivate Registryの機能があって、直接Tutumにイメージをプッシュすることで、イメージをprivateに利用できるようになっています。

本記事ではDockerコンテナベースの自動化フローの構築を目的としていたので、コンテナ1台立ち上げただけのシンプルな構成でしかTutumを使用しませんでした。しかし、Tutumはすでにプロダクションで利用できるだけの非常に多岐に渡る機能を持っていて、今後注目されていくサービスになることは間違いないでしょう。


  1. 2015年Q3にプロダクションレディーになるということなので今すぐ試しましょう! 

31
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
takehilo
iOSアプリ開発エンジニア note: https://note.mu/takehilo 個人開発アプリ: https://apple.co/2S9HRR4
uzabase
企業活動の意思決定を支える情報インフラの提供

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
31
Help us understand the problem. What is going on with this article?