tech.kayac.com

いやー今年もISUCONの予選参加募集がはじまりましたね! 昨年は出題側だったので胃が痛かったですが、今年は参加側ですので大変楽しみにしております。@acidlemonです。

Docker使ってますか?

さてみなさん、Docker使ってますか? 使ってる? 使ってない? ぼくは使ってませんでした。えー今どきBlue-Green Deploymentやってないの? Immutable Infrastuctureじゃないの? と言われそうですが、世の中にはいろんなしがらみとかもあってなかなか簡単にエイヤーでコンテナに移行できるわけでもないのは皆さんなんとなく感じているのではないでしょうか。

とはいえ、最近これだけ話題になっているDockerですので、そろそろ使ってみたいなぁ…ということで、まずは開発環境をDockerで上げられるようにしました。

Dockerでコンテナを作るときには2つのアプローチがあります。

一つはアプリケーションコンテナ。ステートレスなアプリケーションだけを入れて、永続ストアはコンテナの外におく。新しいアプリケーションをデプロイするときは新しいコンテナを作って上位のロードバランサをそちらに向けて、古いコンテナを破棄するというBlue-Green Deploymentのための使い方。

もう一つはサービスコンテナ。アプリケーションやストレージミドルウェアなどなど、サービスを動かすために必要なものを全部入れて作るコンテナです。これを作るメリットはどちらかというと「気軽に捨てられる」という感じなので、新しいバージョンをデプロイしたコンテナを手元や開発サーバで動かしてテストして、使い終わったらすぐコンテナを破棄するみたいな使い方です。

今回はサービスコンテナで開発中のサービスを気軽に立てられるようにしました。具体的にはワイルドカード付きのサブドメインをDockerが走っているホストに全部向けて、表においたnginxからコンテナにReverse Proxyします。

DockerfileにはMySQLとかRedisとかをインストールして、そのあとプロジェクトのリポジトリをcloneして、carton installして動作に必要なものを全部準備した状態のDockerイメージをビルドしておきます。RUNで実行するシェルスクリプトには、git pull、環境変数GIT_BRANCHを取ってきてgit checkout $GIT_BRANCH、そのあとcarton installで実行環境を最新化してProcletを使ったスクリプトを実行して必要なミドルウェア全部とWebアプリを立ち上げるようにしました。

ただ、これには一つ問題がありました。それは「エンジニアじゃないとコンテナ立てられないのでオレが忙しいのは変わらない」ということです。チームにはディレクターやデザイナーもおり、マスターデータやバナーなどのグラフィックをgitにコミットしてくれるのですが、結局それをデプロイしたコンテナを立てるという作業をエンジニアがやらないと、彼ら/彼女らが開発サーバで実地確認できないのです。

ということで、それを解決するためにmirageというツールをGoで書きました。前置きがちょっと長かったですね。

mirageのご紹介

mirageの機能と特徴はこんなかんじです。

  • RESTおよびWebのインタフェースで、Dockerコンテナを起動/停止することができます。その際、
    • サブドメインを指定して、コンテナへのリバースプロキシを提供します
    • gitのブランチ名を指定して、特定のブランチでサービスを構成できます
      • RUNで起動するプログラムから環境変数GIT_BRANCHにアクセスして指定したブランチ名を取得できます

インストールについてはREADMEにも書いてありますが、ビルド済みバイナリがありますのでこちらをご利用いただくのが便利です。簡単にどういう感じで動くのかという構成図をご覧ください。

mirage概要図

図がフルスタックすぎてよくわかりませんね! ということで使い方で機能を説明したいと思います。

まずDockerfileを作って、docker buildでイメージが出来てるという前提からスタートします。また、REST API、Web Interfaceどちらを使っても同じ機能を利用できますが、説明が面倒なのでここではcurlで説明します。

コンテナの起動

あなたはトピックブランチでの開発を終え、開発サーバにデプロイして実際に動かしてみることにしました。トピックブランチの名前はfeature/cool-cool-coolです。さぁ、cool.myapp.example.net でfeature/cool-cool-coolブランチをデプロイしたコンテナにアクセスできるようにしましょう。

curl http://docker.myapp.example.net/api/launch \
  -d subdomain=cool \
  -d branch=feature/cool-cool-cool \
  -d image=myapp:latest

これで、コンテナが起動します。mirageは起動したコンテナをinspectしてコンテナのIPアドレスを調べます。起動後、cool.myapp.example.com にアクセスすると、mirageは接続を起動したコンテナへリバースプロクシします。

プロキシするポートはmirageの設定ファイルで指定可能です。例えば、mirageの8080ポートで待ち受けている通信をコンテナの5000ポートへリバースプロクシするといったことも可能です。また、複数のポートを待ち受けて、それぞれ指定したポートへリバースプロクシすることもできます。

コンテナの停止

feature/cool-cool-coolブランチの動作確認が終わったらもうコンテナはいらないので、破棄しましょう。

  curl http://docker.myapp.example.net/api/terminate \
    -d subdomain=cool 

これで、コンテナが停止します。停止したあとはcool.myapp.example.comにアクセスしても、mirageが404を返します。


はい! 非常にざっくりした説明でした!

いやーしかしこれはあれです。毎回curlでこんなに長いコマンドを叩いているのは大変です。そんなわけで、IRC botやhubotなどを利用している人は、botにcurlを叩かせればよいですね! もともとREST APIはそれ用に用意しています。bot作るのめんどいなーという人は、Web Interfaceで使ってみてください。

ちなみに、コンテナを起動するときのDocker Imageは基本的にほぼ固定になるとおもいます。そういう使い方であれば、mirageの設定ファイルでデフォルトのコンテナを指定できます。そうなれば、サブドメインとブランチを指定すればスポーンと上がってくるので、コンテナを起動するのがますます楽になりますね。

実際に活用するまでにDockerfile作ったりドメイン設定を変えたりみたいな感じでいろいろ仕込みが必要ですが、仕込んでしまえばあとは楽に使えます。

とはいえこの記事だけで使うのはちょっと大変かもしれません。実際に使い始めるまでのチュートリアルは別途書こうかなぁと思っています。なお、一刻も早く使ってみたいけどよくわからんという人は、8/29、8/30に開催のYAPC::Asia 2014で @acidlemon を捕まえて根掘り葉掘り聞いていただければと思います。それではYAPCの会場でお会いしましょう!

カヤックではYAPCでビール飲むのが好きなエンジニアや、Goでツール作ったりするのが好きなエンジニアを募集しています!

こんにちは、 @Konboiです。 久しぶりの更新です。

残念ながら自分のトークは採択されませんでしたが、このたび開催されるYAPC::Asia 2014に、KAYACからはマコピーのトークが2本採択されました。

ここでその内容を簡単にご紹介します。

macpy01.png

Perl meets Real World 〜ハードウェアと恋に落ちるPerlの使い方〜

Perlといえば電子の世界に閉じたプログラムを書かれる方が多いと思われますが、その対極に位置すると思われていた現実世界に干渉しうるハードウェアプログラミングの分野が、ここ最近かなりウェブ系技術に接近しています。

そこでこのトークでは、いかにPerlやカジュアルなツールを用いて自由自在に電子回路を組み上げ、望み通りのハードウェアを作り出し、Perlとともに現実世界に生まれ落ちる方法を伝えたいと思っています。

特にArduinoやRaspberryPiなどMaker文化の中心にあるデバイスたちをメインに、電圧の測り方からカジュアルな電子回路の組み方、Perlを使ったネギの振り方までエッセンスを抜き出して話します。

趣味開発のためのクラウド/VPS活用術

仕事でプログラムを書く時は指定された環境や、便利な社内ツール群、相談にのってくれる仲間や、何より豊富なコンピューティングリソースがあるでしょう。

しかし仕事から分離された趣味の開発ではそういったサーバは使えないことがあるわけで、それをどのように調達したり工夫を行うことで、いかに自分のポケットマネーから最大の自己満足感を得られるかを紹介させていただきます。

以下の様な内容を紹介させていただきます。

  • おすすめのVPS/クラウドサービス 作業用、助っ人、本番用、それぞれの使い分け
    • Amazon EC2/S3 etc, Google Cloud Platform, Digital Ocean, VULTR, さくらのVPS etc...
  • 自宅サーバという選択肢におけるメリット・デメリット
    • 超低消費電力サーバ RaspberryPi で出来る事出来ないこと
  • 作業場という意味での自宅やコワーキングスペースとか図書館
  • ホビーとしてのPerl

スクリーンショット 2014-07-24 18.07.46.png

以上 マコピー のトークをご期待ください。ソーシャルメディアを通じて投票してくださった皆様、ありがとうございました!

カヤックはYAPC::Asia 2014のスポンサーもしています

スピーカー以外にもKAYAC社員も多数参加する予定ですので、

採択されなかったトークに興味がある人、KAYACに興味のある方もそうでない方もお気軽に話しかけていただけると幸いです。

KAYACではエンジニアを大募集しています。

カヤックでは現在、絶賛エンジニアを募集中です。 Perlに限らず、Webサービス、スマートフォンアプリ開発、ゲーム開発興味のある方、ハードも触れるエンジニアを募集中です!!

仲間募集

この記事は tech.kayac.com Advent Calendar 2013 24日目の記事となります

いよいよ、Advent Calendarも最終日ですね。人生を考えてしまう、不惑が目前となってきた@takihitoです。 「不惑の心構え」 について書きたいところですが、そこは孔子専門家に譲ることにして、今回はちょっと便利な自作ツ ールの紹介したいと思います(訂正:社内にいるのは老子の専門家とのことです、ごめんなさい;;)

APIレスポンスのJSONモックを作る際、Keyが多いと面倒だったりしますよね。 DBとテーブルが既にある場合、tsv2jsonを使うとカラムをキー名としたJSON形式に変換することが出来ます

$ mysql -u root game -e "select id,price,exp from monster limit 3" | tsv2json
[{"exp":"200","price":"150","id":"1"},{"exp":"200","price":"150","id":"2"},{"exp":"200","price":"150","id":"3"}]

DBにクエリを発行するとTSV形式のデータが返ってくるので、それを直接JSON形式に変換といった感じですね。 -n オプションを を付けることで値の形式を文字列から数値型に変更することも出来ます

$ mysql -u root game -e "select id,price,exp from monster limit 3" | tsv2json -n id,exp
[{"exp":200,"price":"150","id":1},{"exp":200,"price":"150","id":2},{"exp":200,"price":"150","id":3}]

csv2jsonもあるので、Excel→CSVにしてCSVファイルから変換することもできます。 xxx2xxx系のツールはネットのあちこちに落ちていたりもしますが、この程度であれば自作し手元に用意していてもいいですね。

jqを使ってみる

JSONといえば、 jqコマンドですね。絞り込みや成形を行うことが出来ます。

idが2以上のデータだけを表示させるにはこんな感じで。mapでリストをなめながら、selectの条件に一致する要素だけを絞り込みます。

$ mysql -u root bushiroadkr -e "select id,price,exp from monster" | tsv2json -n id,exp | jq "map(select(.id >= 2 ))"
[
  {
    "id": 2,
    "price": "150",
    "exp": 200
  },
  {
    "id": 3,
    "price": "150",
    "exp": 200
  }
]

SQLで条件書けば良いだけの話かもしれないですが、ファイルとして手元に落とした後でも、お手軽に絞り込めて重宝だったりします。

そういえば、今年はLTSV元年でした。社内の新規案件では、LTSV形式のログを吐き出す事が多くなってきています。 ltsview は-jオプションを使うことでjson形式で成形し吐き出すことが出来ます。

# レスポンスタイム0.5sec以上のログ
$ cat access_log.ltsv | ltsview -j | jq 'select( .response_time | tonumber >= 0.5 )'

ただし、lstviewだと行ごとの成形になるので、グループ分けしたい時にはちょっと不便なので自作のltsv2jsonを使ったりしています。

# URL毎に分類
$ cat access_log.ltsv | ltsv2json | jq 'group_by(.uri)' 

[
  [
    {
      "status": "200",
      "response_time": "0.028",
      "uri": "/api/mypage",
    },
    {
      "status": "200",
      "response_time": "0.033",
      "uri": "/api/mypage",
    },
  ],
  [
    {
      "status": "200",
      "response_time": "0.099",
      "uri": "/api/paly",
    },
# レスポンスタイム0.5sec以上のログ
$ cat access_log.ltsv | lstv2json -j | jq 'map(select( .response_time | tonumber > 0.5 ))'

他にも

  • csv2perl

csvをperlのデータオブジェクトに変換、ファイルに落とせばdoして取り込む事ができるので、スクリプトで集計処理する時には便利ですね

  • json2yaml

YAMLの形式がイマイチよく分からないとお悩みの方は、JSON形式で書いてjson2yamlで形式変換するとスッキリ解決しそうです

まとめ

さて、Advent Calendar 2013 はいかがだったでしょうか? 様々な職種、退職者の方もいたりして大変オープンな雰囲気が伝わっていただけたら幸いです。

香盤表では25日の欄があったので、トリではないと油断していたのですが 「 普通は24日までだよね」という空気になり、小ネタで25日にパスしようとした目論見が外れた感じです。 なかなか人生思い通りにならなうものですな

それでは、また来年のAdvent Calendarでお会いしましょう。