on-demand cloud command
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.bundle
bin
commands
lib
scripts
share
spec
.gitignore
.rspec
Gemfile
Gemfile.lock
LICENSE
README.md
oc.rb

README.md

これは何?

On-demand Cloud command、名付けてocです。
その場限りでクラウドインスタンスを起動して、各インスタンスにコマンドを分散実行させる事を目的としたユーティリティコマンドです。

インストール

ruby 1.9.3以上をインストールしておいてください。
git cloneの後は、bundleし、PATHを設定します。

$ git clone git@github.com:uwork/oc.git ~/.occmd

$ cd ~/.occmd

$ bundle install

$ echo 'export PATH=$PATH:~/.occmd/bin' >> ~/.bash_profile

$ source ~/.bash_profile

チュートリアル

基本的な使い方から紹介します。
AWSのアクセスキーは、EC2およびVPCを操作できるユーザーを用意してください。
また、色々自動で作ったり消したりするので、できればまっさらなAWSアカウントで使って頂くのが良いかと思います。

# 1. ocを初期化します ( ~/.aws/credentials 等を作成しているだけです。)
$ oc setup aws
setup aws credentials [default]
  profile: default
  region: us-east-1
  aws access id: xxxxxxxxxxxxx <-- AWSのアクセスキーを入力します
  aws access secret: xxxxxxxxxxxxx <-- AWSのアクセスシークレットを入力します
INFO: aws credentials saved: /home/user/.aws/credentials
INFO: aws config saved: /home/user/.aws/config
INFO: oc config saved: /home/user/.oc/config

# 2. ocで利用するVPCを初期化します
$ oc profile prepare

# 3. インスタンスを起動します。(t2.microを3台)
# なおデフォルトでは、ocを実行するマシンのグローバルIPのみ接続可能なセキュリティグループを付与します。
$ oc node new -r default -t t2.micro -n 3

# 4. 各ノードでコマンドを実行します。
$ oc cmd "echo helloworld!"

...
INFO: [xxx.xxx.xxx.xxx] > helloworld! 
INFO: [xxx.xxx.xxx.xxx] > helloworld!
INFO: [xxx.xxx.xxx.xxx] > helloworld!
...

# 5. すべてのインスタンスをterminateします。
$ oc node halt -y

# 6. 先ほど作成したVPCを削除します。
$ oc profile clean

用語

いくつか独自の用語があるのでここで説明します。

用語 説明
プロファイル ocでの環境単位。プロファイル毎にアクセスキーを保存したり、タグをつけてリソースを管理する
ロール インスタンスの用途を表すロール。プロビジョニングの内容を定義する種別にもなる

コマンドのヘルプ

$ oc help
Commands:
  oc.rb cmd COMMAND                          # 各ノードでコマンドを実行する
  oc.rb firewall ACTION NAME                 # ファイアウォールについてACTION{add|remove}する
  oc.rb get remote_file_path                 # 各ノードからファイルを取得する
  oc.rb help [COMMAND]                       # Describe available commands or one specific command
  oc.rb node ACTION                          # ノードを操作する
  oc.rb profile ACTION                       # ACTION{prepare|clean}別にプロファイルを操作する
  oc.rb setup TYPE                           # TYPE{aws}別にocの初期設定を行う(アクセスキーの設定など)
  oc.rb sync up|down LOCAL_PATH REMOTE_PATH  # 各ノードとファイルを同期する    

oc setup

環境初期化します。awsのシークレットキーなどを設定します。

oc setup aws -p [profile] -o [output] -r [region]

# -p プロファイルを指定します。ここで指定したプロファイルで、その後の処理を固定します。デフォルトはdefaultです。
# -o aws-sdkの出力フォーマットを指定します。デフォルトはjsonです。
# -r aws-sdkのリージョンを指定します。デフォルトはus-east-1(バージニア北部リージョン)です。

oc profile prepare

oc のプロファイルを準備します。
AWSのVPCを初期化したり、必要なセキュリティグループを作成します。

oc profile prepare -p [profile] --cidr=[CIDR] --subnets=[name/CIDR/mask/auto-ip?]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# --cidr VPCのCIDRを指定します。デフォルトは10.0.0.0/16です。
# --subnets 作成するサブネットを指定します。
#   フォーマットは [subnet-name]/[subnet-CIDR]/[subnet-mask]/[自動でグローバルIPを付与するか] です。
#   デフォルトは public-subnet/10.0.1.0/24/true です。

oc profile clean

プロファイルに関連するVPC設定などを消去します。
依存するリソースが存在する場合、エラーになります。(terminatedではないインスタンスが存在している場合等)

oc profile clean -p [profile]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。

oc firewall add

プロファイルに関連するVPCのセキュリティグループを追加します。

oc firewall add [name] -p [profile] -r [rule] -d [description]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r セキュリティグループのルールを記述します。必須です。
#    フォーマットは [in/out]/[tcp/udp/all]/[port/all]/[ip/client/all] です。
#    サンプル: in/tcp/3306/client
# -d セキュリティグループの説明文を指定します。必須です。

oc firewall remove

プロファイルに関連するVPCのセキュリティグループを削除します。

oc firewall remove [name] -p [profile]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。

oc node new

ノードを起動します。どのような設定のインスタンスを作成するかは、後述のロール設定を一読ください。
ちなみにAZ(availability-zone)は操作簡略化のため region + "a" で固定しています。
aというAZが存在しない場合、エラーでインスタンスが作成できない可能性が高いです。

oc node new -p [profile] -t [type] -n [num] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 起動するノードのロールを指定します。デフォルトはdefaultです。必須です。
# -n 起動するノード数を指定します。デフォルトは1です。
# -t 起動するノードのスペックを指定します。(awsであればt2.micro等)必須です。

oc node down

インスタンスを停止します。削除までは行いません。

oc node down -p [profile] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 停止するノードのロールを指定します。

oc node up

ノードを起動します。

oc node up -p [profile] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 起動するノードのロールを指定します。

oc node halt

ノードを削除します。

oc node halt -p [profile] -r [role] -y

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 削除するロールを指定します。
# -y このオプションを設定すると削除の確認をしません。

oc node ls

ノードのリストを表示します。

oc node ls -p [profile] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 表示するロールを指定します。

oc node provision

ロールの定義に従って、ノードをプロビジョニングします。 現在対応しているのはchef-solo, chef-zero, ansible, shellです。

oc node provision -p [profile] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r プロビジョニングするロールを指定します。必須です。

oc node ssh

ノードにsshでログインします。

oc node ssh -p [profile] -i [node-id]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -i ログインするノードのIDを指定します。必須です。ノードのIDはnode lsで確認します。

oc sync up

ローカルからリモートにディレクトリをrsyncします。常にローカルパス リモートパスの順に引数指定します。

oc sync up /local/path /remote/path -p [profile] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 同期するロールを指定します。

oc sync down

リモートからローカルにrsyncします。常にローカルパス リモートパスの順に引数指定します。
基本的に、"{/local/path}/node-{public_ip}" に各ノードのディレクトリ内容を同期します。

oc sync down /local/path /remote/path -p [profile] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 同期するロールを指定します。

oc get

リモートのファイルをSCPダウンロードします。 基本的に現在のディレクトリ以下に "node-{public_ip}" というディレクトリを作成し、ノード別にダウンロードします。

oc get /remote/path -p [profile] -r [role]

# -p プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# -r 取得するロールを指定します。

oc cmd

各ノードでコマンドを実行します。 -d オプションでディレクトリを同期することで、各ノードにスクリプトを配置して実行させる事も可能です。 さらに、 コマンド文字列内に #index# を与えると、ノード毎に別のインデックス値に置換します。 また、 #nodes# も同様に、全体のノード数に置換します。

oc cmd "COMMAND" --profile=[profile] --role=[role] --dir=[sync dir]

# ※COMMANDへの干渉を避けるため、cmdのオプションはエイリアスを無効化しています。
# --profile プロファイルを指定します。デフォルトはsetupの際に指定したプロファイルです。
# --role コマンドを実行するロールを指定します。
# --dir ノードと同期するディレクトリを指定します。

ノードが4台いる状態での #index# , #nodes# の例
(ホスト別に並列処理しているため、実際はこのようにきれいな順序では出力されません)

oc cmd "echo node: #index# / #nodes#"
...
INFO: [xxx.xxx.xxx.xxx] > node: 0 / 4
INFO: [xxx.xxx.xxx.xxx] > node: 1 / 4
INFO: [xxx.xxx.xxx.xxx] > node: 2 / 4
INFO: [xxx.xxx.xxx.xxx] > node: 3 / 4
...

ロール定義ファイルについて

ロール定義ファイルは、ノードをどのような設定で起動するかをYAMLで定義する設定ファイルです。
ロールはparentを持つことで設定を継承する事ができます。

オプション 概要
image インスタンスのベースイメージ。awsであればamiのidを指定。
role ロール名。ファイル名と同じにしておく。
parent 継承元ロール。
firewall 適用するファイアウォール名を記述する。awsの場合はSecurityGroup名。
iam_role IAM RoleのロールARNを記述する。
devices 接続するデバイスを定義する。
provision プロビジョニングの設定を記述する。

デフォルトでは、share/roles/ 以下に web.yml と default.yml を定義しています。
各コマンドのオプションでロールを指定する際は、このファイル名に付与したロール名を指定してください。

独自のロールを用意する場合、/etc/oc.roles.d/ 以下に [ロール名.yml] という名前のファイルを配置してください。

cat /etc/oc.roles.d/original_role.yml

image: ami-e3106686
parent: default
role: original_role
firewall:
  - basic-onlyme

iam_role: arn:aws:iam::99999999999:instance-profile/role_name

devices:
  - /dev/xvda:
    size: 10
    type: standard
    ondelete: true

provision:
  repo: git@localhost:user/repo.git
  key: /path/to/.ssh/id_rsa

  type: shell
  option: "yum -y install httpd"

なお、組み込みで提供しているfirewall(セキュリティグループ)は以下の3つです。

  • basic-onlyme: oc実行マシンのグローバルIPからはどのプロトコル・ポートでも疎通可能
  • basic-login : oc実行マシンのグローバルIPからのみtcp 22番を疎通可能
  • basic-http : tcp 80,443をanyで疎通可能

ちなみにoc実行マシンのグローバルIPは、 http://checkip.amazonaws.com/ で行っています。

分散処理サンプル

複数のノードで分散処理を行い、結果を取得するサンプルです。

下準備として、このような ruby スクリプトを準備します。
100万までの数値について、sha1のハッシュ値を計算します。
引数にノードのインデックスとノード数を渡して、ノード毎に処理する範囲を変えます。

require 'digest/sha1'

step = 1000000 / ARGV[1].to_i
from = ARGV[0].to_i * step
to = from + step

(from..to).each do |num|
  puts Digest::SHA1.hexdigest(num.to_s)
end

ocでノードを10台用意し、rubyをインストールした後、スクリプトを実行します。

$ oc node new -t t2.micro -r default -n 10

$ oc cmd "sudo yum install -y ruby"

$ oc cmd "ruby hash.rb #index# #nodes# > hashed.txt"

$ oc get hashed.txt

これでディレクトリ直下にノード毎の結果が帰ってくるはず。

$ ls -l node*
node-xxx.xxx.xxx.xxx:
total xxxxx
-rw-rw-r-- 1 user user xxxxxxxx Oct 10 00:00 hashed.txt

node-xxx.xxx.xxx.xxx:
total xxxxx
-rw-rw-r-- 1 user user xxxxxxxx Oct 10 00:00 hashed.txt

その他

  • awsのリージョンをus-east-1以外に設定した場合
    →amiがリージョン毎に異なる為、share/roles/defualt.yml を編集して、適切なamiに変更してください。

ライセンス

MITライセンスに準拠します

免責

本ソフトウェアによって起こったいかなる事象についても制作者は責任を負いません。
すべて自己責任にてご利用ください。