読者です 読者をやめる 読者になる 読者になる

Less is Best

rubyが好き。技術の話とスタートアップに興味があります。

Dockerを使ってCLI環境を構築する

Docker

最近DockerをつかってCLI環境の改善をしています。コンセプトとしてはRancherOSと似たようなもので、使いたいコマンドをDocker経由で使えるようにしています。

下記コマンドを$HOME/bin/runとして保存して.bashrc等にexport PATH=$HOME/bin:$PATHなどとしてパスを通しておくと、dockerを使える環境でさえあればどの環境でも同一のCLIツールを使えるようになってとても便利です。

#!/bin/sh
docker run -it --rm -v $PWD:/pwd -w /pwd $@

コマンド実行するときはこんな感じ。

run yoshiso/js-beautify -r -n path/to/main.js

おおきなメリットは2つあって、1つは必要なdockerイメージをその場でダウンロードしてくれるので、インストール方法を意識する必要が無いこと。2つ目はdockerさえ動いていればどの環境でも同一のバージョンのバイナリの実行を担保できること。curlの--unix-socketオプション使いたいけどローカルのバージョン古かったどうしようみたいなことがなくなります。 デメリットも大きく2つあって、1つはそういう使い方をできるイメージが少ないこと。自分でイメージビルドできれば問題無いわけですが、一手間かかります。もう1つはストレージを消費しやすいことですが、alpineベースのイメージを使っていればそこまで大きな問題ではないかなと思ってます。

こんな感じで用意しておくと新しいマシンでもgit pullしてpath通すだけで環境整うのでおすすめです。

github.com

便利なので、ぜひお試しあれ。

Docker v1.12 swarmクラスタをrubyのDSLで管理するツールAlgoを作りました

docker ruby

At first

Docker v1.12のリリースまでもうすぐですね!swarmモードを始め、今回のDockerのアップデートはワクワクする機能が盛りだくさんで楽しみです。 今日はDockerのv1.12からリリースされる予定のDocker内蔵のswarmモードとサービスの機能を使ってクラスタを管理するツールAlgoを作ってみました。

github.com

Why

Docker v1.12から使えるようになるswarmモードとserviceの機能, ハートビート機能の実装により、Docker単体でサービスクラスタを簡単に用意できるようになりました。 是非活用したいと思ったところですが、3点問題点がありました。1つはdocker-composeはv1.12からリリースされるswarmモードに関してサポートを行わないこと(docker bundle用のエクスポートにてサポート)。2つめは、現時点のdocker bundleの機能が貧弱すぎること。3つめとして、docker service create/updateでサービスを管理するのはさすがにご遠慮したいこと。

久しぶりにRubyも書きたかったのでrubyで書いてみた。

What is it?

やりたかったことは下記の事。

  • ファイルに定義したクラスタ定義をswarmクラスタに適用する
    • Ruby DSLによるサービス/ネットワークの定義
  • 冪等な実行
  • Dry-runのサポート

定義ファイルを下記のように書いて

awesomecluster.rb

cluster 'awesomecluster' do

  # Define service/network prefix for cluster
  prefix 'awsm'

  # Define cluster wide available environment variable
  env 'CLUSTER_ENV', 'PRODUCTION'

  # Define cluster wide available label
  label 'com.example.sample', 'clusterwidelabel'

  # Define network
  network 'net1'

  # Define service
  service 'name' do
    image 'quay.io/yss44/curl'
    replicas 3
    command 'sh'
    args '-ic', "while true; do curl -s awsm-nginx > /dev/null; echo $?; sleep 3; done"

    update_parallelism 2

    # Service related environment variable
    env 'APP_DOMAIN', 'example.com'

    network 'net1'
  end

  # Define another service
  service 'nginx' do
    image 'nginx:alpine'
    replicas 2
    network 'net1'
  end

end

algo apply awesomecluster.rbでコマンドを実行すると、swarmクラスタを更新します。

algo apply awesomecluster.rb
# Applying to cluster awesomecluster...
# network: awsm-net1, status: created
# service: awsm-name, status: created
# service: awsm-nginx, status: created
# Complete applying for cluster awesomecluster!

ファイルを更新して再度algo apply awesomecluster.rbを行うと、差分をswarmクラスタに反映します。

# Change configuration
sed -i s/replicas 2/replicas 1/g awesomecluster.rb

# Dry-run
algo apply examples/awesomecluster.rb
# Running with dry-run mode...
# Applying to cluster awesomecluster...
# network: awsm-net1, status: ok
# service: awsm-name, status: ok
# service: awsm-nginx, status: changed
# Complete applying for cluster awesomecluster!

How to install?

gemとしておいているのでgem install algoですぐにでも試せます。詳しくはgithubにて

github.com

Want to do

  • とりあえずまだすべてのDSLを書いたわけではないので埋めていきたいところ
  • デーモンを用意してオートスケールの仕組みの実装とかできたら面白そうかもと思ってます。
    • autoscale_min, autoscale_max, scaledown_when, scaleup_when的なDSLにて
  • 現状APIの制限によりサービスのネットワークの変更ができないのでなんとかしたい

Afterword

熱があるのになんでこんなにコードを書いているのか謎。つらい。