2014年3月17日月曜日

LoadBalancerもRSpecで定義: Lbspec

LoadBalancerのspecは、あるリクエストに対して、期待するレスポンスを返すか という表現では不十分である。実際にnodeにリクエストが到達するか ということを表現しなければいけない。そこで、LbspecというRSpecのMatcherを作った。これを使うと、LoadBalancerがnodeにリクエストを転送することをRSpecの書式で表現できる。

これでLoadBalancerもRSpecで定義できるはず。。

リンク

Installation

Gemfileに書く:

gem 'lbspec'

bundlerを実行する:

$ bundle

もしくはgem installする:

$ gem install lbspec

Requires

  • nodeにsshで入れる(~/.ssh/configなどで定義されている)

Usage

こんな感じで spec_helper.rbで require lbspec する:

# spec/spec_helper.rb
require 'rspec'
require 'lbspec'

あとはSpecを記述する:

require_relative 'spec_helper'

describe 'vhost_a' do
  it { should transfer('node_a') }
end

describe 'vhost_b' do
  it { should transfer(['node_b','node_c']) }
end

describe 'vhost_c:80' do
  it { should transfer(['node_b','node_c']).port(80) }
end

describe 'vhost_c:80' do
  it { should transfer(['node_b','node_c']).port(53).udp }
end

describe 'vhost_c:80' do
  it { should transfer('node_c').http.path('/test/') }
end

describe 'vhost_c:443' do
  it { should transfer(['node_b','node_c']).port(80).https.path('/test/') }
end

How it works

#transfer

  1. nodeにsshでログインする
  2. nodeでprobeをキャプチャーする
  3. probeを使ってリクエストを投げる(or パケットを投げる)
  4. nodeにprobeが来ているかで判定する

ここで、nodeではコマンドを実行しているだけなので、nodeに特別なプログラムを入れる必要はない。(ngrepとかtcpdumpが簡単かもしれないが、access.logをgrepするのほうが簡単かもしれない。)

#tranfer works

Configuration

#transfer

キャプチャとリクエストを投げる方法はカスタマイズできる。なので、キャプチャ方法を定義して、自分で投げたいリクエストを生成できる。

RSpec.configuration.lbspec_capture_command =
  lambda do |port, prove|
  port_str = port > 0 ? "port #{port}" : ''
  "sudo ngrep #{prove} #{port_str} | grep -v \"match:\""
end

RSpec.configuration.lbspec_https_request_command =
  lambda do |addr, port, path, prove|
  uri = 'https://' + "#{addr}:#{port}#{path}?#{prove}"
  system("curl -o /dev/null -sk #{uri}")
end

カスタマイズできるのは次のコマンド。

  • lbspec_capture_command with |port, prove|
  • lbspec_udp_request_command with |addr, port, prove|
  • lbspec_tcp_request_command with |addr, port, prove|
  • lbspec_http_request_command with |addr, port, path, prove|
  • lbspec_https_request_command with |addr, port, path, prove|

2014年2月23日日曜日

Trema Day #5 に参加してきた

Trema Day #5に参加してきたので、メモしておく。

感想

TremaはOSSでがんばっている。 小さいところでも貢献したいと思う。(まずはVagrant周りとかでも)

今回は懇親会にも参加できて、楽しかった。 ネットワーク屋が多いが、いろんな分野にまたがっているので、幅があって楽しい。

概要

  • 2014/02/22 (土) 13:00-17:00
  • KDDIウェブコミュニケーションズ CloudCoreセミナールーム
  • atnd
  • ust

他のかたのまとめなど


■意外に違う Trema と Trema-Edge

  • 大芝さん
  • Trema-Edge使ってみてTremaと違うところ
    • Pio, Sinatra が手強い
    • 不具合系の回避策とか(2014/02/22時点)
  • Trema Edgeとは
    • OpenFlow1.3
      • OpenFlow1.3の違いは扱わない
  • 変わっていないところ
    • 起動
      • 違いなし
    • ハンドラ定義
      • 違いなし
        • ポート情報の一覧の取得のところFeaturesRequest/Replyでとれなくなっている
    • タイマー定義とかメッセージ創始とか
      • 違いなし
        • フロー追加はoptionに変更あり(OpenFlow1.3関連?)
  • 変わっているところ
    • パケットインのときのパケット情報取得
      • マッチ条件の名前が変わっている
    • PortStatusのポート情報受け取り
      • PortStatusがPortクラスを継承している
    • PacketOutでデータのみのパケット出力
      • PacketInに指定していないとエラーになる
    • Sinatraとの連携しようとしたときの振る舞い
      • TremaのLoggerがSinatraのモジュールのLoggerとバッティングしている
      • エラーがでない
    • Trema::Pioと連携
      • Trema-EdgeがObjectクラスのところで修正している
      • array?がtrueとかになってしまう
      • ワークアラウンドするとarpとかだせることまで確認
    • 便利メソッドの有無
      • send_flow_mod_add など基本的なところくらいしかない
      • port.up?とかport.down?とかできない
    • Statsメッセージについて
      • マルチパートメッセージになった
    • OpenFlow1.3関連でいろいろ変わっている
      • 割愛

質疑応答

  • Q. Trema-Edgeのテスト用のスイッチとか、ダンプフローとかどうなっている?
  • A. 会社ではOpenFlowスイッチがあるので、あまり使っていない
  • C. sugyoさんがやりかたがあるらしいという情報がある
  • C. なんかやったらできる記憶がある
  • Q. グループテーブルっていまも使える?
  • A. あとで調べる(大山さんがあとでまとめていただける とのこと)

of_protocol で遊んでみた

  • 近藤さん(@Eishun_Kondoh)
  • 資料
  • of-protocolとは?
    • Erlangで実装
    • flowforwading.orgのなかのerlangな人たちが作ったLINCというスイッチのパーサ
    • 使えるバージョンは1.2、1.3のようだ
    • モジュール
      • ofprotocol
        • ofpv4utilsとか使うとなんかできる感じ
  • 使いかた(こんな感じ)
    • of_protocol:encode(#ofp_message)
    • of_protocol:decode(BinaryData)
  • Flower?ベースで作ってみた
    • 3.5klocくらい
    • Tremaにコネクトできた
  • 遊ぶのにはよいと思う。

質疑応答

  • Q. どこら辺を参考にしている?
  • A. LINC-Switchを参考にした
  • A. FlowERを参考にした
  • C. 半年コードを読んで、3ヶ月かけて実装したような感じ
  • C. Erlangの本(飛行機本)にはいろいろ書かれている
  • C. ElixirだとErlangのVMでRubyっぽい
  • C. ElixirだとRubyとかのように文法定義できるかんじ
  • Q. Erlangのメリットは?
  • A. VMの上で動いていて、他のマシンの上にあるVMに移せたりする
  • A. 小さいスレッドが作れる
  • A. 横方法にスケールアウトすることができる
  • Q. 構成図の四角はプロセス?
  • A. 違う。もっとごちゃごちゃしている

■Tremaをもっと手軽で簡単に。

  • 大山さん(@userlocalhost)
  • 素人がTremaを使うにあたって
    • 一般の声
      • Trema 覚えるの大変そう
      • やりたいことは簡単なのにやることが多い
    • 呪文が多い
    • そこで
      • Observed
        • 他のシステムと連携するシステム
      • Observedが仕組み
        • 外部システム連携は各プラグインが肩代わり
    • Trema−Gmail連携
      • Tremaから情報をとって、Gmailに送る
        • observe(見るところ).then(やること) という感じでかくと
    • HTTP-Trema連携
      • 監視しておいて落ちたら、他のサーバに振るテーブルにする
    • Pluginはいくつかある

質疑応答

  • Q. 他のフレームワークは?それとの優位性は?
  • A. JavaでCamelがある。連携作業を並列にやれたり とか効率的にできるように。まだpluginが充実していない。
  • Q. メッセージングで使えるやつのメッセージングツールとの差は?
  • A. fluentdはログに特化している
  • A. Observedはなんでも対応できるフレームワーク
  • Q. Observedは社内でやっているの?
  • A. 完全に個人のレベルでやっている
  • C. 呪文が多すぎる?について、視点が複数ある。サンプルコードが恣意的。
  • C. 共通化できると連携処理はかける
  • C. フレームワークを1つ覚えればいろいろできる
  • Q. 取りこぼしが起こるのか?syslogのように取りこぼしがあるのか?
  • A. 他のシステムに依存するところ。
  • Q. どれくらいTremaに対応しているか?
  • Q. なにができているか?
  • A. statをとる、flowを変更する というレベルはある。
  • C. Trema本体からそとに提供する仕組みがあるといいが、hookしてレポートする仕組みがあれば十分

■Go Deep

  • 千葉さん(@chibacchie)
    • 最近Rubyを勉強し始めた
  • 資料
  • Tremaでコントローラを作るときの課題
    • 受信したところからパケットパースするとるのは面倒だ
    • Rubyでパケットパーサが欲しい
    • libwireshark を使って、rubyに返す
    • ruby-wiresharkを作った
    • wiresharkの対応している分だけメソッドができる
    • まだ公開できるレベルではないが、公開できるようになったら公開する

質疑応答

  • Q. wiresharkのバージョンが変わると変わる?
  • A. 変わる
  • Q. Packetはリアルタイムで見える?
  • A. 見える。pcapの機能である。
  • C. parserの仕事。パースする。treeを表示する。意味がわかる。の両方の機能
  • C. wiresharkが意味づけしてくれる
  • Q. IPアドレスとかはRubyのクラスにマッピングできる?
  • A. できる
  • C. wiresharkのラッピングがgemでなはないのであるとうれしい

■[LT]エクルとリームなネットワーク機器テスト環境の実現

  • 空閑さん
  • ネットワークテスタHWが持つ高精度な試験をSWツールに適用したい
  • チャレンジ
    • アプローチ1: Userspace Dataplane
      • ハードのDataplaneをソフトに持って行く
    • アプローチ2: Timing API
      • パケット送受信のタイミングをNICにオフロード
      • Userspaceからパケットごとに送信タイミングを指定
        • NICにその送信タイミングにしたがって送出する実装を追加する
      • 8nsの精度
    • 2つの時間の指定方法
      • Global(絶対的な指定)
      • Local(相対的な指定)
    • アプローチ3: Programmable Interface
      • Ethernet Character device
        • echo "0000 FFFF"> /dev/ethpipe/0 などのようにする
        • リプレイできる
  • shell scriptで実装してみる
    • shell scriptで書いて8nsの精度でやる
  • アプリケーションとしては
    • latency emuration
    • "Extreme" network testing
    • Generic purpose network IO
  • オープンソースなので使える

質疑応答

  • Q. ppsとかをはかるとかそういうことにも使えるのか?
  • A. 使える。jitterとかを作れる。1GのNICで500Mbpsとかもきれいにだせる。
  • C. 10Gも目指す。
  • Q. bash押しな理由は?
  • A. シンプル化という視点でいうと、cat コマンドというイメージだったから。
  • A. sedとかして、プロセスが重くなる。gnu grepだと6Gbpsくらいはできる
  • A. 高速化を考えるんらASCIIにせずに、binaryで扱うとよいと思う。
  • Q. NICからデータをユーザープログラムが受け取るのは割り込みベース?
  • A. データの割り込みは間引きする
  • Q. いろいろDPDKとかに? ポーリング vs 割り込み
  • A. 割り込みだからできない という話ではない。(バウンダリ周り)

■[LT]VagrantとかTrema-edge switchとかデバッグツール

質疑応答

  • Q. Vagrantまわりで他になにか情報あるか?
  • A. あまりない
  • C. 作ってくれる人がいればぜひ

■[LT]Tremaの作り直し

  • 高宮さん(@yasuhito)
  • Tremaの現状
    • C
      • 37000行
      • test 30000行
    • Ruby
      • 8500行
      • test 7000行
    • 合計
      • 80000行
  • 目標
    • できるところはRubyにしたい(メンテナンスのため)
  • Cの部分の分類
    • switch manager
      • 試しに実装した
        • C: 3000行
        • Ruby : 200行
        • 期間1週間
    • switch daemon
    • openflow ライブラリ
    • main loop
    • messanger
    • packet in filter
  • 試しに実装してみた
    • switch manager
      • C: 3000行
      • Ruby : 200行
      • 期間1週間かかった
  • やることがたくさんある
  • 方針?
    • アプリからやる
    • Trema-Edgeから?
    • TremaでもRuby2.0以上にする予定
    • Tremaでも1.3をサポートする方向で。
    • がちでできるように性能は気にしてほしい
    • 必要なスパイスは消さないように

2013年12月19日木曜日

Vagrant 1.4.1でCentOS上でdockerを走らせてみる

Vagrantが1.4.1になって、Redhat、CentOSでもdockerのproviderが動くようになったということで、試してみた。

結果

とりあえず動かしてみることは簡単にできた。

Vagrantfileを作る

実行

vagrant up

こんな感じでdockerのコンテナができていることを確認

[otahi@otahiair test-docker-vagrant]$ vagrant up       
Bringing machine 'default' up with 'virtualbox' provider...
[default] Box 'centos65' was not found. Fetching box from specified URL for
the provider 'virtualbox'. Note that if the URL does not have
a box for this provider, you should interrupt Vagrant now and add
the box yourself. Otherwise Vagrant will attempt to download the
full box prior to discovering this error.
Downloading box from URL: https://github.com/2creatives/vagrant-centos/releases/download/v6.5.1/centos65-x86_64-20131205.box
Extracting box...te: 660k/s, Estimated time remaining: --:--:--)
Successfully added box 'centos65' with provider 'virtualbox'!
[default] Importing base box 'centos65'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Fixed port collision for 22 => 2222. Now on port 2200.
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2200 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] The guest additions on this VM do not match the installed version of
VirtualBox! In most cases this is fine, but in rare cases it can
cause things such as shared folders to not work properly. If you see
shared folder errors, please make sure the guest additions within the
virtual machine match the version of VirtualBox you have installed on
your host and reload your VM.

Guest Additions Version: 4.3.4
VirtualBox Version: 4.2
[default] Mounting shared folders...
[default] -- /vagrant
[default] Running provisioner: docker...
[default] Installing Docker (latest) onto machine...
[default] Pulling Docker images...
[default] -- Image: centos
[otahi@otahiair test-docker-vagrant]$ vagrant ssh
[vagrant@vagrant-centos65 ~]$ sudo docker images        
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              6.4                 539c0211cd76        8 months ago        300.6 MB (virtual 300.6 MB)
centos              latest              539c0211cd76        8 months ago        300.6 MB (virtual 300.6 MB)
[vagrant@vagrant-centos65 ~]$ sudo docker run centos echo hello
hello
[vagrant@vagrant-centos65 ~]$ 

2013年8月24日土曜日

RSpecを使ってDNSのテストを自動で実施する方法

DNSのテストを素早く回すことができるrspec-dnsというのがあるので紹介する。 これを使えば、DNSを変更するときにだいぶ安心できるはず。

使うもの

どのように書くのか?

次のように update_config でDNSを指定する。(config/dns.ymlというのを更新するので、なにもやらなければ、config/dns.ymlに記載されているまま) レコードごとにspecを記載していく。 複数のDNSをテストしたい場合は、 update_config でDNSを指定していく。

実行のやり方

  • git clone
    • % git clone -b example https://github.com/otahi/rspec-dns.git
  • move into example directory and run
    • % cd rspec-dns/example
    • % rvm use 1.9.3
    • % bundle install --path=vendor/bundle --binstubs=vendor/
    • % bundle exec rspec -c -f doc

どのような出力になるか?

% bundle exec rspec -c -f doc 

github.com
  should have the correct dns entries with {:type=>"A", :address=>"192.30.252.128"}
  should have the correct dns entries with {:type=>"A", :address=>"192.30.252.129"}
  should have the correct dns entries with {:type=>"A", :address=>"192.30.252.130"}
  should have the correct dns entries with {:type=>"A", :address=>"192.30.252.131"}
  should have the correct dns entries with {:type=>"A", :address=>"204.232.175.90"}
  should have the correct dns entries with {:type=>"A", :address=>"207.97.227.239"}
  should have the correct dns entries with {:type=>"MX", :exchange=>"ASPMX.L.GOOGLE.com", :preference=>10}
  should have the correct dns entries with {:type=>"MX", :exchange=>"ALT1.ASPMX.L.GOOGLE.com", :preference=>20}
  should have the correct dns entries with {:type=>"MX", :exchange=>"ALT2.ASPMX.L.GOOGLE.com", :preference=>20}
  should have the correct dns entries with {:type=>"MX", :exchange=>"ASPMX2.GOOGLEMAIL.com", :preference=>30}
  should have the correct dns entries with {:type=>"MX", :exchange=>"ASPMX3.GOOGLEMAIL.com", :preference=>30}
  should have the correct dns entries with {:type=>"NS", :name=>"ns1.p16.dynect.net"}
  should have the correct dns entries with {:type=>"NS", :name=>"ns2.p16.dynect.net"}
  should have the correct dns entries with {:type=>"NS", :name=>"ns3.p16.dynect.net"}
  should have the correct dns entries with {:type=>"NS", :name=>"ns4.p16.dynect.net"}
  should have the correct dns entries with {:type=>"TXT", :data=>"v=spf1 include:_spf.google.com include:_netblocks.zdsys.com include:sendgrid.net include:mailgun.org include:smtp.github.com ~all"}
  should have the correct dns entries with {:type=>"SOA", :mname=>"ns1.p16.dynect.net", :rname=>"hostmaster.github.com", :refresh=>3600, :retry=>600, :expire=>604800, :minimum=>60}

Finished in 2.4 seconds
17 examples, 0 failures
% 

Reference

2013年8月4日日曜日

Linux Container (lxc) on Cent OS 6.4 on Vagrant VM

Linux Container(lxc) on Cent OS 6.4 on Vagrant VM

vagrant で作ったCent OS 6.4 のVMの上に、Linux Containerを複数起動できる環境を作る方法をまとめる。 中身はgithubを参照のこと。

背景

  • MacやWindowsをホストとして利用するときに、Linux由来のツールをそのまま利用することが難しい場合がある。
    • たとえば、iptables, openvswitch など
  • lxcの情報はUbuntuの情報が多く、いつも使っているCent OSの情報が少なかったので、ちょっと試した。
  • ちょっとした複数マシン連携のテストなんかに使えるかな?と思う。
  • Tremaの環境を作って遊びたいときに使えるのではないか?とか。

構成

lxcのVM2つをvagrant で作ったCent OS のVMの上に作る。

layout.

事前条件

  • VirtualBox installed(upper 4.2.16)
  • vagrant installed(uppper 1.2.0)
  • vagrant box has been set as "centos64-base"
    • %vagrant box add centos64-base http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130427.box
      • ここのURLはそのうちなくなるかもしれない

動かし方

  • git リポジトリをとってくる
    • %git clone https://github.com/otahi/vagrant-centos-lxc.git
  • vagrant up
    • %vagrant up
  • しばし待つ
  • vagrant VMにログイン
    • %vagrant ssh
  • lxc VMs にログイン
    • %sudo lxc-console -n vm1
    • %sudo lxc-console -n vm2
  • これで構成図のとおりのVMが動いているはず。

2013年7月28日日曜日

Trema Day #3 に参加してきた(一部)

Trema Day #3に参加してきたので、まとめる。 ぜんぜんまとまっていないが、とりあえず出す。ということで。。

全体(といっても前半)

4歳の息子が一緒にいきたがったので、連れて行ったが、 結果としては最初に少し間に合わず、途中で帰ることに。。

ustに録画がでたので、あとでこちらを参考に、あとで書き直す予定。

Wakame-VDCの話はとても興味深かった。 TremaをHiper Visorごとにいれてあり、それを集中管理するという方法が、 「そういう使い方もあるのか」と思った。 Wakame-VDC自身も興味深かった。lxcとかも使えるということで、 Macの上にVMを立てて、いろいろ遊べる気がした。 ちょっといろいろ調べてみようと思う。

RubyでPacketParserの話も興味深かった。 今回はLLDPの話だったが、もっとレイヤが上位のパケットを考えると、 tcpdumpレベルでは難しいパケットの抽出もでき、 解析もけっこうやりやすくなるのかもしれないと思った。

概要

  • 2013/07/27 (土) 13:00-17:00
  • KDDIウェブコミュニケーションズ CloudCoreセミナールーム
  • atnd
  • ust

他のかたのまとめ

Wakame-VDCの仮想ネットワーク

  • あくしゅ 山崎泰宏( @sparklegate )さん
  • Virtual Networking
    • 構造
      • Agent Network
    • VM同士のネットワーク
    • eth0とeth1でeth1をマネジメントにしてhva(Hyper Visor Agent)を接続
    • 分離
      • 物理NW
      • 論理NW
      • VM
    • WakameではHVに1つのovs、1つのhva(Tremaコントローラ含む)
    • dhcp、dnsなどはTremaコントローラで折り返す
    • トンネリング
      • MAC2MAC(と呼んでいる方法を使っている)
        • ARPのブロードキャストドメインをコントロール
        • ARPブロードキャストをユニキャストに変換する(これでスイッチは学習できる)
          • L3は超えられない
      • DBで管理できているので、それを使ってやる
    • WakameではTremaとovsの間はUnixSocket通信している
    • Wakame-vnetというのを切り出そうとしている
  • Q&A
    • RabbitMQからZeroMQにした理由は?
      • セルロイドというライブラリがzeroMQだった
      • 小さいパケットの処理が早い
    • ブロードキャストをユニキャストに変換するのはarp以外にも制御できる?
      • 明らかに対向がわかるものしかできない
  • 資料
    • 見つけられていないが、OPEN CARFの資料を参考にするとちょっとわかりやすいかも。

OpenFlowでSDN作りました

  • 中程さん@UEC
  • ospf -> sospf関連のとOpenFlowの話
  • ospfだと経路が重なり輻輳の問題がある
    • それを解決したい
  • 今回はPOXで書いたので長くなってしまった

Rubyでパケットパーサ

  • @yasuhito さん
    • trema #3の話
      • Lineを貼ってみた
      • フィールドオブドリームズのように人が来る
    • 今回はコンビニの大木さんが発表。
  • LLDPを使ったトポロジ探索サンプルプログラム
    • 短く、読みやすく、改造しやすく
    • LLDPジェネレータとパーサ
    • PacketFu
      • ちょっと流儀が。。
    • Racket
      • おしい
    • BinData
      • けっこう使われている
      • バイナリをパースするライブラリ
      • DSL的
  • BinData
    • プリミティブ型があり、それを組み合わせて定義できる
  • Trema::Packetとして共通部を切り出してやっていければなと思う
  • 資料

OpenFlowの可視化ツール

  • 大山裕泰さん
  • ***ここで帰ることになってしまった。。***

LT 安くOFS&冗長化

  • あとで

LT OpenStackでのトラフィックフロー制御

Virtual Network Platform の紹介

2013年6月28日金曜日

Vagrantでパケアナ #pakeana 16

第16回「ネットワークパケットを読む会(仮)」で話した。

PC上のVMで他人に迷惑をかけずに実験をするための方法を考えたので、突っ込みをください。


Vagrant packana16-otahi from Hiroshi Ota


※init.shの最終行は2013/06/29追加。これがないと、HostOnlyNetwork以外はIPパケットがでない。

@twovs さんの「how to GET GET」はあとで役に立つと思うので、メモしておく。