LoginSignup
123

More than 5 years have passed since last update.

ChatOps( Slack / Hubot / Docker )で検証環境をポンポン作って、ポンポン捨てる

Posted at

この投稿について

Slack/Hubot/Dockerを用いたChatOpsでアプリの検証環境をポンポン作って、ポンポン捨てる方法をまとめます。
チャットから誰でも手軽に使い捨てのアプリの検証用環境を作成できるので、チーム開発の生産性向上が期待できます。

システム構成の概要図

Untitled (7).png

システム構築手順

SlackとHubotの連携

HubotをPaaSであるHerokuにデプロイさせ、Slackと連携させます。
こちらの具体的な手順については、「Slack / Hubot / GitHub / CircleCI によるChatOpsなデプロイ方法」の前半部分で詳しくまとめていますので、そちらを参照ください。

Dockerを動かすサーバーの用意(EC2)

今回はAWSのEC2を用います。

EC2の起動

まずは、Dockerを動かすインスタンスを立ち上げる。
今回はCommunityAMIの「ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-20140927」というものを利用。

zz_スクリーンショット_2014-12-12_14_43_26.png

検証なので、インスタンスタイプはt2.microを選択。

zz_スクリーンショット_2014-12-12_14_44_17.png

インスタンスの名前は適当に分かりやすいものを付けておけばOK。

zz_スクリーンショット_2014-12-12_14_45_27.png

Security Groupの設定では、SSH用ポートの他に、追加で49153〜65535ポートを解放しておく。
これはDockerのポートフォワーディングで使用されるポートである。

zz_スクリーンショット_2014-12-12_14_47_29.png

インスタンスが立ち上がれば、IPを確認してちゃんとSSH接続できるか確認。

ssh -i .ssh/docker-key.pem ubuntu@54.65.169.132

> ubuntu@ip-172-31-6-189:~ $

ユーザーの作成

Dockerを操作する用のユーザーを作成する。ここではwankoという名前で作成。

ubuntu:~$ sudo adduser wanko
Adding user `wanko' ...
Adding new group `wanko' (1001) ...
Adding new user `wanko' (1001) with group `wanko' ...
Creating home directory `/home/wanko' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for wanko
Enter the new value, or press ENTER for the default
    Full Name []: 
    Room Number []: 
    Work Phone []: 
    Home Phone []: 
    Other []: 
Is the information correct? [Y/n] y

sudo権限を付与

ubuntu:~$ sudo usermod -G sudo wanko

パスワードレスでsudoになれるように設定

ubuntu:~$ sudo visudo

#以下を、追記
wanko ALL=(ALL) NOPASSWD: ALL

/etc/ssh/sshd_configを変更して、パスワードによるログインを許可

ubuntu:~$ sudo vi /etc/ssh/sshd_config
/etc/ssh/sshd_config
#PasswordAuthentication no
PasswordAuthentication yes

変更した設定を反映するために、sshdを再起動

sudo service ssh restart

追加したユーザーでパスワードログインできるか確認

ssh wanko@54.65.169.132

wanko@54.65.169.132's password:

GitHubにレポジトリ作成

今回はDockerのコンテナにGitHubからアプリをcloneしてきて動かしたいので、その検証用のレポジトリを作ります。
今回はHTMLだけのシンプルなアプリにしています。

実際のレポジトリ
https://github.com/s-kiriki/docker-test-app

また今回はChatOpsでブランチを自由に切り替えてDockerコンテナに任意のブランチをデプロイ出来るかを検証したいので、
以下の2つのブランチを用意しました。

・masterブランチ
シンプルに「Hello from Docker!」とだけ表示される実装

・add_imageブランチ
「Hello from Docker!」の下にDockerのイメージ(クジラのやつ)が表示される実装

スクリーンショット 2014-12-12 15.52.35.png

DockerホストOSの用意

上で立ち上げたインスタンスにDockerをインストールして、各種設定を行っていきます。
以下、このDockerのインストールされたインスタンスをDockerホストOSと書きます。

Dockerのインストール

公式サイトに従ってインストールする。

sudo apt-get update
sudo apt-get install docker.io

インストールされたか確認

sudo docker --version
Docker version 1.0.1, build 990021a

Version1.3より追加されたdocker execを使いたいので、Dockerを最新版にUPDATE

curl -sSL https://get.docker.com/ubuntu/ | sudo sh
sudo docker --version
Docker version 1.4.0, build 4595d4f

Dockerfileおよび、コンテナに転送するファイルの作成

Dockerfileを以下のように作成します。

Dockerfile
FROM centos:centos6

RUN yum update -y
RUN yum install -y httpd
RUN yum install -y git

ADD ./app_init.sh /

RUN mkdir /root/.ssh/
ADD id_rsa /root/.ssh/id_rsa
RUN chmod 700 /root/.ssh/id_rsa

RUN echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config

EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

ADDコマンドで指定しているapp_init.shid_rsaはコンテナに転送するものですので、予め手元で作成にておく必要があります。
id_rsaはGitHubに認証可能な秘密鍵で、app_init.shは以下のようなgit cloneで先ほどつくった検証用のレポジトリをcloneしてくるシェルスクリプトです。

app_init.sh
#!/bin/bash

if [ $# -ne 1 ]; then
 echo "You must specify branch name"
 exit 1 
fi

BRANCH_NAME=$1

cd /var/www/html && git clone -b $BRANCH_NAME --depth 1 git@github.com:s-kiriki/docker-test-app.git

Dockerイメージの作成

上で作ったDockerfileよりDockerイメージを作成します。
今手元には、Dockerfileapp_init.shid_rsaがあることを確認してください。

wanko@ip-172-31-6-189:~$ ls
app_init.sh  Dockerfile  id_rsa

イメージの作成はdocker buildコマンドで行います。-tオプションでイメージ名(今回はdocker-appとした)を指定し、最後の.Dockerfileのパス(今回はカレントディレクトリ)を指定しています。

$ sudo docker build -t docker_app .

Dockerイメージが作られたかをdocker imageコマンドで確認します。

$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker_app          latest              6900f52b1ac5        5 seconds ago       466.5 MB

コンテナの起動

上で作ったDockerイメージを使って、docker runコマンドでコンテナを起動させます。
-dオプションでApacheをデーモン化させ、-Pオプションでポートフォワーディングを行います。

$ sudo docker run -d -P docker_app
afbf3bd7c6be6e36ca436d34880b49970bacb25a72a9a351c9d3c28d5a8cd0a6

コンテナが作られたかは、docker psコマンドで確認できます。

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                   NAMES
afbf3bd7c6be        docker_app:latest   "/usr/sbin/httpd -D    2 minutes ago       Up 2 minutes        0.0.0.0:49157->80/tcp   kickass_brown     

80番ポートが49157番ポートにポートフォワーディングされているのがわかります。

この状態で、http://54.65.169.132:49157/(54.65.169.132の部分はDockerホストOSのアドレス)にアクセスすると、Apacheのホーム画面が表示されているはずです。

スクリーンショット 2014-12-12 17.17.05.png

アプリの設置

次に、このdocker runで立ち上げたコンテナにアプリを設置します(GitHubからclone)。
コンテナに対してのコマンドの実行はdocker execコマンドで行えます。
今回はコンテナ側に既にあるapp_init.shを実行させればいいだけなので、以下のようにします。

$ sudo docker exec kickass_brown sh app_init.sh master

kickass_brownはコンテナ名、masterはブランチ名

これでコンテナにアプリが設置されたので、http://54.65.169.132:49157/docker-test-appにアクセスすると以下のようにアプリが動くはずです。

スクリーンショット 2014-12-12 17.37.38.png

Dockerで起動させたコンテナでGitHub上のアプリが動きました!!

ここまでのまとめ

ここでは、大きく分けて以下のようなことを行ってきました。

  1. Dockerのインストール
  2. Dockerfileの作成とアプリ設置シェルスクリプトの作成
  3. Dockerイメージの作成(docker build)
  4. Dockerコンテナの起動(docker run)
  5. アプリの設置(docker exec)

今回の最終目的はChatOps(Slackから指令を出す)で、指定のアプリの検証環境をポンポンつくること(コンテナをポンポン起動させること)であったので、この1~5の中の4と5をSlack経由で行う必要があります。
以降の節で、これらの方法を説明していきます。

HubotからDockerコンテナの起動とアプリの設置を行う

SlackとHubot(Heroku上にデプロイ)の連携は既に済んでいるので、あとはHubotからDockerホストOSに命令を出してコンテナの起動とアプリの設置が行えれば、ChatOpsでアプリの検証環境を作れることになります。

この実装方法として、今回はDockerホストOSにDockerコンテナの起動とアプリの設置を行うシェルスクリプトを用意し、そのスクリプトをHubotからsshで接続して実行するという構成にしました。

シェルスクリプトの用意(DockerホストOS)

DockerホストOSにDockerコンテナの起動とアプリの設置を行う以下のようなシェルスクリプトを用意します。

container-up.sh
#!/bin/bash

if [ $# -ne 1 ]; then
 echo "You must specify branch name"
 exit 1
fi

BRANCH_NAME=$1

CONTAINER_ID=`sudo docker run -d -P docker_app` # コンテナの起動
if [ $? -ne 0 ]
then
        echo "Error occured on running container."
        exit 1
fi

echo "Created Container:$CONTAINER_ID"

PORT_FORWARDING=`sudo docker port $CONTAINER_ID`
if [ $? -ne 0 ]
then
        echo "Error occured on checking port forwarding."
        exit 1
fi

sudo docker exec $CONTAINER_ID sh app_init.sh $BRANCH_NAME # アプリの設置
if [ $? -ne 0 ]
then
        echo "Error occured on setting app."
        exit 1
fi

echo ":docker: Your app is ready!! $PORT_FORWARDING" # :docker: というのはSlackのカスタム絵文字

ポンポン作るだけではなく、ポンポン捨てることも目的だったので、同様にコンテナを削除するスクリプトも以下のように作ります。

container-remove.sh
#!/bin/bash

if [ $# -ne 1 ]; then
 echo "You must specify container name or ID"
 exit 1
fi

CONTAINER_ID=$1

REMOVED_CONTAINER=`sudo docker rm -f $CONTAINER_ID`
if [ $? -ne 0 ]
then
        echo "Error occured on removing container $CONTAINER_ID."
        exit 1
fi

echo ":docker: Removed container: $REMOVED_CONTAINER" # :docker: というのはSlackのカスタム絵文字

Hubotスクリプトの作成

次に、DockerホストOSに設置したcontainer-up.shおよびcontainer-remove.shをssh経由で実行するためのスクリプトをHubotに追加します。

simple-sshというnpmモジュールを使うのでインストールしておきます。

npm install simple-ssh --save

実際のコードは以下のようにしました。

hubot-container.coffee
# Description:
#  Handling Docker containers.
#
# Dependencies:
#   "simple-ssh": "^0.8.1"
#   "hubot-slack": "^2.2.0"
#
# Configuration:
#   [Required]
#     DOCKER_HOST
#     DOCKER_USER
#     DOCKER_PASSWD
#
# Author:
#   s-kiriki


module.exports = (robot) ->

    _getSSH = (msg) ->
        if !process.env.DOCKER_HOST
            return msg.send 'You must set ENV: DOCKER_HOST'
        if !process.env.DOCKER_USER
            return msg.send 'You must set ENV: DOCKER_USER'
        if !process.env.DOCKER_PASSWD
            return msg.send 'You must set ENV: DOCKER_PASSWD'

        SSH = require('simple-ssh');
        ssh = new SSH({
            host: process.env.DOCKER_HOST,
            user: process.env.DOCKER_USER,
            pass: process.env.DOCKER_PASSWD
        });
        return ssh

    robot.respond /container up( (.+))?/i, (msg) ->
        branch_name = msg.match[2] || "master"
        ssh = _getSSH(msg)
        ssh.exec("sh container-up.sh #{branch_name}", {
            out: (stdout) ->
                msg.send stdout
        }).start();

    robot.respond /container remove (\w+)/i, (msg) ->
        container_id = msg.match[1]
        ssh = _getSSH(msg)
        ssh.exec("sh container-remove.sh #{container_id}", {
            out: (stdout) ->
                msg.send stdout
        }).start();

    robot.respond /container list/i, (msg) ->
        ssh = _getSSH(msg)
        ssh.exec("sudo docker ps | awk '{print $1, $(NF-1), $(NF)}'", {
            out: (stdout) ->
                msg.send stdout
        }).start(); 

Heroku上でHubotスクリプト用の環境変数をセット

hubot-container.coffeeではDOCKER_HOSTDOCKER_USERDOCKER_PASSWDを環境変数でセットする必要があるので、これらをHeroku上で設置します。

zz_スクリーンショット_2014-12-12_18_19_07.png

デモ

ようやく準備が整ったので、SlackからDockerを操作して検証環境をポンポン作ってみます。

SlackとHubotの連携確認

まずは、ちゃんとSlackとHubotがうまく連携して動いてるか確認してみます。

zz_スクリーンショット_2014-12-12_18_24_05.png

ちゃんと動いてますね。ではいよいよ、コンテナを起動してアプリをデプロイしてみます。

コンテナの起動とアプリのデプロイ

スクリーンショット 2014-12-12 18.51.30.png

49160番ポートでコンテナが起動したようなので、http://54.65.169.132:49160/docker-test-app/にアクセスしてみます。

スクリーンショット 2014-12-12 18.54.53.png

うまく、アプリがデプロイされてます(ブランチが未指定の場合はmasterブランチがcloneされるようにしてある)。

では次に、別のブランチをデプロイしてみましょう。

スクリーンショット 2014-12-12 18.59.32.png

49162番ポートでコンテナが起動したようなので、http://54.65.169.132:49162/docker-test-app/にアクセスしてみます。

スクリーンショット 2014-12-12 18.56.54.png

今度は、指定したとおりadd_imageブランチの内容がデプロイされています。

コンテナの削除

今度は不要なコンテナを削除してみます。
最初に49160番ポートで起動した方のコンテナを消してみます。

スクリーンショット 2014-12-12 19.05.02.png

コンテナが削除され、http://54.65.169.132:49160/docker-test-app/にアクセスしても接続できなくなっていることが確認できます。

コンテナ一覧の確認

コンテナ一覧を確認できるコマンドも実装したので試してみます。

スクリーンショット 2014-12-12 19.07.40.png

うまく表示されました!

以上長くなりましたが、Slack/Hubot/Dockerを使ったChatOpsでアプリの検証環境をポンポン作って、ポンポン捨てる方法についてまとめました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
123