chefのdata_bagを暗号化する
chef serverだとdata baseのcreate時に--secret-file オプションで暗号化が簡単に可能ですが、chef solo / knife solo環境data bagでも実はknife-solo_data_bagを使うと簡単に実現可能です。
knife-solo_data_bagインストール
gem install knife-solo_data_bag
or
Gemfiles & bundle install
使い方などは以下を参照すると
- usage & Version Support
https://github.com/thbishop/knife-solo_data_bag
秘密鍵の作成
今回、RSAの2048bitで作成します。
$ openssl genrsa -aes256 2048 | tr -d '\r\n' > .chef/data_bag_key
knife設定とその他
--secret-file .chef/data_bag_keyでも可能ですが、毎回指定していると忘れるので書いておきます。
$ vim .chef/knife.rb encrypted_data_bag_secret ".chef/data_bag_key"
$ vim ~/.bash_profile export EDITOR='vim'
knife soloでdata bagの作成
作成はknife solo data bag createです。
$ knife solo data bag create s3 test { "id": "test", "keys": { "key_1": "12345", "key_2": "54321" } }
作成されたデータを覗くとdata部分が暗号化されているかと思います。 ファイルはeditor経由ではなくknife solo editで編集します。
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)
- 作者: 吉羽龍太郎,安藤祐介,伊藤直也,菅井祐太朗,並河祐貴
- 出版社/メーカー: 技術評論社
- 発売日: 2014/05/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (15件) を見る
- 作者: 澤登亨彦,樋口大輔,クリエーションライン株式会社
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2014/04/25
- メディア: 大型本
- この商品を含むブログ (1件) を見る
Aerospike Deep Driveに参加してきた
参加メモです。6/24(水) 19:00〜22:00。
個人的にはpartition mapの話が勉強になりました。Aerospikeは構築するだけであれば非常に簡単でドキュメントにインフラ周りの仕組みがなかなか記載されていないので、裏側を知れたのは非常に嬉しいです。
Aerospikeと他KVSとの違い、適用分野等
- 導入事例
- 導入時に検討した他のKVS
- 導入して気づいたこと
IDSyncサービス
- 自社IDと他社IDのマッピング
属性データの加工
ID Syncサービスとは
- マッピングテーブルを生成
- アンケートで特定の解答をした人に広告配信
自社サイトに訪問した人にメール広告を配信
システム
- ELB + Nginx + uWSGI
- バックエンドにaerospike
- 平均応答速度は1ms
- ピーク時で1000req/s程度
主キーが自社ID、他社IDを主キーとしたものを保持
様々な属性情報を、異なるソースから取得
- 保持している属性情報を人が理解できるように
- 基盤にaerospike
- cookie IDを元に様々なデータを保持
- 要素ごとに個別のsetを保持(useragent, IP, company, ...etc)
他のKVSとの比較
DynamoDB
- 費用面がネック
- キャパシティを超えたリクエストがロスト(キューイングなし)
- 10万read/sで130万/月、10万write/sで650万/月
Redis(ElasticCache)
- 容量制限あり(最大240GB)
- 到達した場合に代替手段がないのでスケールしない
Cloud Bigtable
- GCPにしないとレイテンシが発生する
- 応答速度がAerospike比で約5〜10倍(らしい)
導入して気づいたこと
- clientが高機能
- レコードがどのノードに配置されているか主キーのハッシュ値で把握している
- コネクション取得時にテーブルを取得する
マッピングテーブルはノードの削除・追加時に更新される
Clientもパワーが必要
- 高多重度でリクエストを行う必要あり
1リクエスト1msで3.6億レコードを取り出す
メモリの使用量が大きい
SSDのみの利用でも意外とメモリを利用する
- インデックスがメモリ展開される
- 1レコードにつき64バイト
Nmaespaceが分割しにくい
SSDを使用する場合、ブロックデバイス単位でしかNamespaceを分けることができない
Queryの制約
- SQLライクな記述でレコードを参照するこも可能だが・・・
- 指定したサーバで処理が走る(クライアント側ではない)
- 並列実行ができない
- バックアップのQuery扱い
mysqldumpの様なコマンドがある。平文。データ量と時間に注意
その他 雑感
- インメモリだと特に速い
- 設定項目がほぼないので構築が楽
ドキュメントにない機能がライブラリにある(ソースコードみよう!)
まとめ
- Aerospikeの速度が必要なケースってあまり多くなさそう
- マッチしそうなケース
- データ量の見積もりが難しい場合
- 時間あたりのリクエスト数が膨大な場合
- リソースの見積もりが難しい
新機能を使ってみて
クライアントライブラリ
新機能の実装優先度
scalaもcommunity Labsにあるよ
大体の使い方を知るにはサンプルプログラムを読む/実行するのがよい
- vagrantで入れてAMCでアクセスしてみよう(ここまで30分)
- GitHubで公開されているclientライブラリにもexamplesが同梱
充実度はJavaが一番
基本の保存と検索
- client.put / client.get
- サポートしている型はシンプル
- list / mapはgetlist/getmapはないget objectでダウンキャスト
- ver3からlist / set / map / stackをサポート。LDTS
LargeListは昇順でソートされている
limitation
- ソートは昇順
- write block size設定によって1要素の容量が制限される
- 1Mbなら200kb / 128kbなら30kb
- add_all(), udate_all()は1GBまで
- XDRはLDT対象外
- aqlで内容を確認できない
その他
- LDTのデータは1つのサーバノードで保存されクラスタ内に分散しない
- TTLはRecord単位
- LDTの堀はluaを使うのでCPUを消費する
LDT * luaはサンプル少なくて苦労する
OSS化
- あまり使われてない機能・環境を使う場合はEnterprise Editionを推奨
Aerosparkあるよ
Node.jsクライアントを半年間、使ってみて
− 運用のし易さで選定 - クラスタ構成、パフォーマンス、サーバ台数削減 - メモリリーク問題 - heapdump / tcp connection? /clinen closeで治るか? -> 治らず - binの文字長 - 感想:サーバサイドの運用が楽、クライアントは・・・
マイグレーション
partition map
- クラスタ内のデータを4096個に分割したもの
- partitionはレコードを均等に入れる4096個のバケツ
- キーのハッシュの先頭12bitを使用
- パーティションをサーバに均等に分割
- 各サーバのMACとpartitionIDを使って各ノードの順番を決める。これをパーティションマップ。
- partition mapは左からreplication factorに従い選択される
- clientからのアクセスは1ホップ
- オートシャーディング、オートバランシング
ノード追加
- ノード追加
- Gossipプロトコルで伝達。全ノードのノードリストができてからMap作成に移る
- patition mapが更新される。計算上既存ノードの順序は変わらず新規ノードが入ってくる(マイグレーション処理が少ない)
- 新規ノードにデータがあるノードからコピーされる
- 新規ノードがslaveであればClientはMasterへ、新規ノードがMasterならclientはコピーが終るまではslaveへ。2台同時追加でmaster/slave両方がコピー中の場合はmapの右へ
- slaveで受けているときはコピーを続けつつmasterのjournalへ書き込む
最後にjournalをflashする
通常時はmaster/slaveに書き込んでACK, 非同期でSSDへFlash。reptication factor 3だと3台書き込めてからレスポンス。
- migration走って容量減った? -> partition mapでslave以下に降格したデータが消える。reprication factorは3 !?
- 2TBで3台->4台にしたときに18時間
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
- 作者: 本橋信也,河野達也,鶴見利章
- 出版社/メーカー: リックテレコム
- 発売日: 2014/03/06
- メディア: Kindle版
- この商品を含むブログを見る
データベース徹底攻略 (WEB+DB PRESS plus)
- 作者: 松信嘉範,羽生章洋,ミック,奥野幹也,松下雅和,桑野章弘,青木峰郎,ひろせまさあき,小林篤,島田慶樹,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2014/03/15
- メディア: 大型本
- この商品を含むブログ (3件) を見る
OpenvSwitch関連コマンドのチートシート的な何か
まずOpenvSwitchに関するコマンドは大きく4つです。観点としてはOpenStackで使ったときにトラブルシューティングで使いそうなものが多いかもしれません。
Neutronってよくわらかないって人は、以下も参照してみるとイメージが付きやすいと思います。
- ovs-vsctl
- Used for configuring the ovs-vswitchd configuration database (known as ovs-db)
- ovs-ofctl
- A command line tool for monitoring and administering OpenFlow switches
- ovs-dpctl
- Used to administer Open vSwitch datapaths
- ovs−appctl
- Used for querying and controlling Open vSwitch daemons
1. ovs-vsctlコマンド
ovs-vsctlって何?
マニュアルにも「ovs-vsctl connects to an ovsdb-server process that maintains an Open vSwitch configuration database.」の記載がある通りovsdb-serverプロセスを操作するためのコマンドです。ovs-vsctlを叩いた時の内部的な動きはざっくり以下の通りです。
ovs-vsctl -> ovsdb-server <-> ovs-vswitchd <-> openvswitch_mod -> ovsdb
※ openvswitch_mod(datapath)はパケットの転送処理を行うカーネルモジュールです。
参考までにプロトコル番号です。
management(OVSDB) Channel TCP/6632 Openflow channel TCP/6633
せっかくなのでkiloのレポジトリから取ってきました。バージョンは以下の通りです。
[komei@localhost ~]# ovs-vsctl -V ovs-vsctl (Open vSwitch) 2.3.1 Compiled Dec 26 2014 15:35:14 DB Schema 7.6.2
ovsdb-serverはデフォルトで/var/run/openvswitch/db.sockファイルを使用します。このファイルをコピーすれば設定情報は復元できます。
[komei@localhost ~]# ps aux | grep open root 21413 0.0 0.5 46488 2528 ? S< 6月17 0:12 ovsdb-server /etc/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/var/run/openvswitch/db.sock --private-key=db:Open_vSwitch,SSL,private_key --certificate=db:Open_vSwitch,SSL,certificate --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert --no-chdir --log-file=/var/log/openvswitch/ovsdb-server.log --pidfile=/var/run/openvswitch/ovsdb-server.pid --detach --monitor root 21426 0.0 7.0 268568 35180 ? S<Ll 6月17 4:23 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/openvswitch/ovs-vswitchd.pid --detach --monitor
ovs-vsctlのオプション
databaseファイルを指定
[komei@localhost ~]# ovs-vsctl --db=unix:/var/run/openvswitch/db.sock show ed7907f7-314f-465d-8971-e6a8792c9dfd Bridge br-int Port "qr-peer2" tag: 2 Interface "qr-peer2" Port br-int Interface br-int type: internal Port "vm-peer1" Interface "vm-peer1" Port "vm-peer2" tag: 2 Interface "vm-peer2" Port "ns-peer2" tag: 2 Interface "ns-peer2" Port "qr-peer1" Interface "qr-peer1" Bridge br-ex Port "qg-peer1" Interface "qg-peer1" Port "qg-peer2" Interface "qg-peer2" Port "pub-peer1" Interface "pub-peer1" Port br-ex Interface br-ex type: internal ovs_version: "2.3.1"
外部のovsdbへ接続
ovsdbへの外部アクセスに備えてlistenする
- ptcp:port[:ip]
- pssl;port[:ip]
openvswitchのsyslog
--no-syslogでsyslogへの出力を制御できる
デフォルトでは以下の通りsyslog形式でログが出力されています。
[komei@localhost ~]# cat /var/log/messages | grep ovs-vsctl Jun 23 00:01:26 localhost ovs-vsctl: ovs|00001|vsctl|ERR|'list' command requires at least 1 arguments
他には以下のオプションもあります。
--log-file[=file]
デフォルトでは/var/log/openvswitch/ovs-vsctl.logです
その他の便利なオプション
--dry-run
--timeout=secs
--syslog-target=host:port
ovs-vsctlの確認コマンド
Bridgeのリスト
[komei@localhost ~]# ovs-vsctl list-br br-ex br-int
Bridgeの存在確認
[komei@localhost ~]# ovs-vsctl br-exists br-ex1 [komei@localhost ~]# echo $? 2 [komei@localhost ~]# ovs-vsctl br-exists br-ex [komei@localhost ~]# echo $? 0
Bridgeのリスト確認
[komei@localhost ~]# ovs-vsctl list-ports br-ex pub-peer1 qg-peer1 qg-peer2 [komei@localhost ~]# ovs-vsctl list-ports br-int ns-peer2 qr-peer1 qr-peer2 vm-peer1 vm-peer2
ポートがどのBridgeに接続されているか
[komei@localhost ~]# ovs-vsctl port-to-br pub-peer1 br-ex
OpenFlowコントローラーの確認
[komei@localhost ~]# ovs-vsctl get-controller br-ex
set-controllerもあります。opendaylightのエントリで書いたような記憶もありますが。
蛇足ですがNetFlowやsFlowにも対応しています。あとMirroringやQoS、GREトンネルにも対応しています。
[komei@localhost ~]# ovs-vsctl add-port br0 gre0 --set Interface gre0 type=gre options:remote_ip=1.2.3.4
ovs-ofctl
ovs-ofctlって何?
openvswichのopen flow部分を見るコマンドです。
OpenflowスイッチとしてのBridge確認
[komei@localhost ~]# ovs-ofctl show br-ex OFPT_FEATURES_REPLY (xid=0x2): dpid:00001237cc5df04d n_tables:254, n_buffers:256 capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE 1(qg-peer1): addr:ea:9c:0d:31:eb:4b config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 2(pub-peer1): addr:82:ca:37:c4:9c:1d config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max 3(qg-peer2): addr:1a:13:3c:79:30:12 config: 0 state: 0 current: 10GB-FD COPPER speed: 10000 Mbps now, 0 Mbps max LOCAL(br-ex): addr:12:37:cc:5d:f0:4d config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
flowのstatisticsを確認
[komei@localhost ~]# ovs-ofctl dump-flows br-int NXST_FLOW reply (xid=0x4): cookie=0x0, duration=488096.484s, table=0, n_packets=48, n_bytes=3800, idle_age=65534, hard_age=65534, priority=0 actions=NORMAL
openvswitch Portのstatistics
[komei@localhost ~]# ovs-ofctl dump-ports br-int qr-peer2 OFPST_PORT reply (xid=0x4): 1 ports port 3: rx pkts=145, bytes=13290, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=161, bytes=14586, drop=0, errs=0, coll=0
ovs-dpctl
ovs-dpctlって何?
ovs-dpctlはデータパス部分の設定や確認をするコマンドです。
openvswitchのdata path確認
[komei@localhost ~]# ovs-dpctl dump-dps system@ovs-system
openvswitchを通過するflow一覧を表示
- まだ何も表示されない
[komei@localhost ~]# ovs-dpctl dump-flows
- Pingを打って通信を発生させる
[komei@localhost ~]# ip netns exec qpublic ping 192.168.101.12 PING 192.168.101.12 (192.168.101.12) 56(84) bytes of data. 64 bytes from 192.168.101.12: icmp_seq=1 ttl=63 time=0.322 ms 64 bytes from 192.168.101.12: icmp_seq=2 ttl=63 time=0.224 ms
- 再度表示
[komei@localhost ~]# ovs-dpctl dump-flows recirc_id(0),skb_priority(0),in_port(5),eth(src=e2:26:c6:c9:1b:72,dst=26:81:8d:99:47:80),eth_type(0x0800),ipv4(src=192.168.101.200/0.0.0.0,dst=192.168.101.12/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0xff), packets:1, bytes:98, used:0.140s, actions:10 recirc_id(0),skb_priority(0),in_port(7),eth(src=4a:f3:46:10:ec:34,dst=c6:79:ae:27:8e:db),eth_type(0x0800),ipv4(src=192.168.101.12/0.0.0.0,dst=10.0.0.3/0.0.0.0,proto=1/0,tos=0/0,ttl=63/0,frag=no/0xff), packets:1, bytes:98, used:0.140s, actions:9 recirc_id(0),skb_priority(0),in_port(9),eth(src=c6:79:ae:27:8e:db,dst=4a:f3:46:10:ec:34),eth_type(0x0800),ipv4(src=10.0.0.3/0.0.0.0,dst=192.168.101.12/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0xff), packets:2, bytes:196, used:0.140s, actions:7 recirc_id(0),skb_priority(0),in_port(10),eth(src=26:81:8d:99:47:80,dst=e2:26:c6:c9:1b:72),eth_type(0x0800),ipv4(src=192.168.101.12/0.0.0.0,dst=192.168.101.200/0.0.0.0,proto=1/0,tos=0/0,ttl=63/0,frag=no/0xff), packets:2, bytes:196, used:0.140s, actions:5
- statisticsを確認
[komei@localhost ~]# ovs-ofctl dump-flows br-int NXST_FLOW reply (xid=0x4): cookie=0x0, duration=488404.848s, table=0, n_packets=130, n_bytes=11388, idle_age=0, hard_age=65534, priority=0 actions=NORMAL [komei@localhost ~]# ovs-ofctl dump-flows br-int NXST_FLOW reply (xid=0x4): cookie=0x0, duration=488405.936s, table=0, n_packets=132, n_bytes=11584, idle_age=0, hard_age=65534, priority=0 actions=NORMAL
その他
MACアドレステーブル確認
[komei@localhost ~]# ovs-appctl fdb/show br-ex port VLAN MAC Age 1 0 5e:6e:bb:98:eb:d5 5 2 0 e2:26:c6:c9:1b:72 1 3 0 26:81:8d:99:47:80 1 [komei@localhost ~]# ovs-appctl fdb/show br-int port VLAN MAC Age 2 0 42:8a:36:9d:7d:21 7 1 0 06:b0:47:10:06:32 7 3 2 4a:f3:46:10:ec:34 1
※ Ageはデフォルトで300秒
[komei@localhost ~]# ip netns exec qpublic ip a 15: pub-veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether e2:26:c6:c9:1b:72 brd ff:ff:ff:ff:ff:ff inet 192.168.101.200/24 scope global pub-veth1 valid_lft forever preferred_lft forever inet6 fe80::e026:c6ff:fec9:1b72/64 scope link valid_lft forever preferred_lft forever
23: qg-veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 26:81:8d:99:47:80 brd ff:ff:ff:ff:ff:ff inet 192.168.101.9/24 scope global qg-veth2 valid_lft forever preferred_lft forever inet 192.168.101.12/32 scope global qg-veth2 valid_lft forever preferred_lft forever inet6 fe80::2481:8dff:fe99:4780/64 scope link valid_lft forever preferred_lft forever
17: qr-veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 4a:f3:46:10:ec:34 brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/8 scope global qr-veth2 valid_lft forever preferred_lft forever inet6 fe80::48f3:46ff:fe10:ec34/64 scope link valid_lft forever preferred_lft forever
21: vm-veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether c6:79:ae:27:8e:db brd ff:ff:ff:ff:ff:ff inet 10.0.0.3/8 scope global vm-veth2 valid_lft forever preferred_lft forever inet6 fe80::c479:aeff:fe27:8edb/64 scope link valid_lft forever preferred_lft forever
※ qvo, qvb, tapとかが入っているのを確認。
MACアドレスのテーブルサイズ変更
openvswitchで設定できるテーブルサイズ
other_config : mac-table-size: optional string, containing an integer, at least 1 The maximum number of MAC addresses to learn. The default is currently 2048. The value, if specified, is forced into a reasonable range, cur‐ rently 10 to 1,000,000.
現在のテーブルサイズ確認
[komei@localhost ~]# ovs-vsctl list bridge br-int _uuid : 4fc8c288-5a54-41ed-85f4-854eaf1f31fd controller : [] datapath_id : "00008ac2c84fed41" datapath_type : "" external_ids : {} fail_mode : [] flood_vlans : [] flow_tables : {} ipfix : [] mirrors : [] name : br-int netflow : [] other_config : {mac-table-size="4096"} ports : [01e94661-0d5d-4154-b931-2f05068de40f, 25f9a4ed-7f73-4069-a9e2-fd67d4b870b4, 9c08bee6-0304-4cb5-82a4-676806f6e94e, d013c5a1-2e70-4e87-8d7a-5759b4e9cd22, e8245b4a-7be5-4cc8-a8f0-3f5f10b6f247, f09afbd4-7477-4de7-acf0-e42ee7edd9eb] protocols : [] sflow : [] status : {} stp_enable : false
テーブルサイズ変更
[komei@localhost ~]# ovs-vsctl set Bridge br-int other_config:mac-table-size=8192 [komei@localhost ~]# ovs-vsctl list bridge br-int _uuid : 4fc8c288-5a54-41ed-85f4-854eaf1f31fd controller : [] datapath_id : "00008ac2c84fed41" datapath_type : "" external_ids : {} fail_mode : [] flood_vlans : [] flow_tables : {} ipfix : [] mirrors : [] name : br-int netflow : [] other_config : {mac-table-size="8192"} ports : [01e94661-0d5d-4154-b931-2f05068de40f, 25f9a4ed-7f73-4069-a9e2-fd67d4b870b4, 9c08bee6-0304-4cb5-82a4-676806f6e94e, d013c5a1-2e70-4e87-8d7a-5759b4e9cd22, e8245b4a-7be5-4cc8-a8f0-3f5f10b6f247, f09afbd4-7477-4de7-acf0-e42ee7edd9eb] protocols : [] sflow : [] status : {} stp_enable : false
何故か設定範囲を超えた値が入る気が・・・
[komei@localhost ~]# ovs-vsctl set Bridge br-int other_config:mac-table-size=1000000000 [komei@localhost ~]# ovs-vsctl list bridge br-int _uuid : 4fc8c288-5a54-41ed-85f4-854eaf1f31fd controller : [] datapath_id : "00008ac2c84fed41" datapath_type : "" external_ids : {} fail_mode : [] flood_vlans : [] flow_tables : {} ipfix : [] mirrors : [] name : br-int netflow : [] other_config : {mac-table-size="1000000000"} ports : [01e94661-0d5d-4154-b931-2f05068de40f, 25f9a4ed-7f73-4069-a9e2-fd67d4b870b4, 9c08bee6-0304-4cb5-82a4-676806f6e94e, d013c5a1-2e70-4e87-8d7a-5759b4e9cd22, e8245b4a-7be5-4cc8-a8f0-3f5f10b6f247, f09afbd4-7477-4de7-acf0-e42ee7edd9eb] protocols : [] sflow : [] status : {} stp_enable : false
現在のテーブル数確認
お好みで。
sudo ovs-appctl fdb/show br-int | wc -l
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
OpenStackクラウドインテグレーション オープンソースクラウドによるサービス構築入門
- 作者: 日本OpenStackユーザ会
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/28
- メディア: 大型本
- この商品を含むブログ (1件) を見る
オープンソース・クラウド基盤 OpenStack入門 構築・利用方法から内部構造の理解まで (アスキー書籍)
- 作者: 中井悦司,中島倫明
- 出版社/メーカー: KADOKAWA / アスキー・メディアワークス
- 発売日: 2014/06/03
- メディア: Kindle版
- この商品を含むブログ (2件) を見る
Openstack(Neutron)が中でやっていることを確認してみた
CentOS7で確認してみました。自分で試してみるとわかりやすいですね。Linux bridgeは割愛していますが、構成はNetwork NodeとCompute Nodeを1台にまとめた状態です。
- Network Node
- Compute Node
それでは順を追って記載してきます。
Open vSwitchをインストール
せっかくなのでOpenStackのレポジトリから引っ張ってきます。
[root@localhost ~]# yum install https://repos.fedorapeople.org/repos/openstack/openstack-kilo/rdo-release-kilo-1.noarch.rpm [root@localhost ~]# yum info openvswitch 読み込んだプラグイン:fastestmirror Loading mirror speeds from cached hostfile * base: www.ftp.ne.jp * extras: www.ftp.ne.jp * updates: www.ftp.ne.jp 利用可能なパッケージ 名前 : openvswitch アーキテクチャー : x86_64 バージョン : 2.3.1 リリース : 2.el7 容量 : 1.8 M リポジトリー : openstack-kilo 要約 : Open vSwitch daemon/database/utilities URL : http://openvswitch.org ライセンス : ASL 2.0 and LGPLv2+ and SISSL 説明 : Open vSwitch provides standard network bridging functions and : support for the OpenFlow protocol for remote per-flow control of : traffic. [root@localhost ~]# sudo yum install openvswitch
qrouterとqdhcpを作成する
Network NodeではルーティングやFloating IPの処理をqrouterで、dhcpの処理をqdhcpで行っています。まず初期状態を確認してみます。
[root@localhost ~]# ip netns [root@localhost ~]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 08:00:27:3f:bf:85 brd ff:ff:ff:ff:ff:ff
早速、neutronのnetwork node用のnamespaceを作成してみます。neutron-dhcp-agentがnamespace内にdnsmasqを起動しています。ここではqdhcpは作成までにとどめておきます。
[root@localhost ~]# ip netns add qrouter1 [root@localhost ~]# ip netns add qdhcp1 [root@localhost ~]# ip netns qdhcp1 qrouter1
qrouter1はルーティングを行うのでsysctlをいじります。
[root@localhost ~]# ip netns exec qrouter1 sysctl net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1
OpenvSwitchを作成する
次にopenvswitchとしてbr-int / br-exを作成します。先ほどインストールした際にovs-vsctlコマンドが使えるようになっていると思います。
[root@localhost ~]# ovs-vsctl add-br br-int [root@localhost ~]# ovs-vsctl add-br br-ex [root@localhost ~]# ovs-vsctl show ed7907f7-314f-465d-8971-e6a8792c9dfd Bridge br-int Port br-int Interface br-int type: internal Bridge br-ex Port br-ex Interface br-ex type: internal ovs_version: "2.3.1"
接続用のvethを作成する
qrouterとbr-int接続用のvethを作成。vethはケーブルと両端のポートをイメージするとわかりやすいです。
[root@localhost ~]# ip link add qr-veth1 type veth peer name qr-peer1 [root@localhost ~]# ip link add ns-veth1 type veth peer name ns-peer1 [root@localhost ~]# ip link show qr-veth1 7: qr-veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 42:8a:36:9d:7d:21 brd ff:ff:ff:ff:ff:ff [root@localhost ~]# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 08:00:27:3f:bf:85 brd ff:ff:ff:ff:ff:ff 3: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT link/ether da:65:5a:6e:60:93 brd ff:ff:ff:ff:ff:ff 4: br-int: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT link/ether 8a:c2:c8:4f:ed:41 brd ff:ff:ff:ff:ff:ff 5: br-ex: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT link/ether 12:37:cc:5d:f0:4d brd ff:ff:ff:ff:ff:ff 6: qr-peer1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether ea:30:cb:58:07:2d brd ff:ff:ff:ff:ff:ff 7: qr-veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 42:8a:36:9d:7d:21 brd ff:ff:ff:ff:ff:ff 8: ns-peer1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 56:04:a1:a5:44:9a brd ff:ff:ff:ff:ff:ff 9: ns-veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 0e:0b:df:2c:ec:52 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]# ip link set br-int up [root@localhost ~]# ip link set br-ex up
vethの片側をnamespaceへ移動する。
[root@localhost ~]# ip link set qr-veth1 netns qrouter1 [root@localhost ~]# ip link set ns-veth1 netns qdhcp1
移動が成功していることを各namespaceで確認
[root@localhost ~]# ip link show qr-veth1 Device "qr-veth1" does not exist. [root@localhost ~]# ip netns exec qrouter1 ip link show qr-veth1 7: qr-veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 42:8a:36:9d:7d:21 brd ff:ff:ff:ff:ff:ff
ポートにアドレスを付与します
[root@localhost ~]# ip netns exec qrouter1 ip addr add 10.0.0.1/255.0.0.0 dev qr-veth1 [root@localhost ~]# ip netns exec qdhcp1 ip addr add 10.0.0.2/255.0.0.0 dev ns-veth1
リンクをUPさせます
[root@localhost ~]# ip link set qr-peer1 up [root@localhost ~]# ip link set ns-peer1 up [root@localhost ~]# ip netns exec qrouter1 ip link set qr-veth1 up [root@localhost ~]# ip netns exec qdhcp1 ip link set ns-veth1 up
public側とインスタンス用のnamespaceを作成する
VM用と疑似Public用のnamespaceを作成
[root@localhost ~]# ip netns add qvm1 [root@localhost ~]# ip netns add qpublic [root@localhost ~]# ip netns qpublic qvm1 qdhcp1 qrouter1
各コンポーネントを接続
VMとbr-int、publicとbr-ex、qrouterとbe-ex接続用のveth作成とnamespaceへ配置
[root@localhost ~]# ip link add vm-veth1 type veth peer name vm-peer1 [root@localhost ~]# ip link add qg-veth1 type veth peer name qg-peer1 [root@localhost ~]# ip link add pub-veth1 type veth peer name pub-peer1 [root@localhost ~]# ip link set vm-veth1 netns qvm1 [root@localhost ~]# ip link set qg-veth1 netns qrouter1 [root@localhost ~]# ip link set pub-veth1 netns qpublic
各namespace内のポートにアドレスを付与
[root@localhost ~]# ip netns exec qvm1 ip addr add 10.0.0.3/255.0.0.0 dev vm-veth1 [root@localhost ~]# ip netns exec qrouter1 ip addr add 192.168.101.10/255.255.255.0 dev qg-veth1 [root@localhost ~]# ip netns exec qpublic ip addr add 192.168.101.200/255.255.255.0 dev pub-veth1 [root@localhost ~]#
openvswitchにポートを追加。
[root@localhost ~]# ovs-vsctl add-port br-int vm-peer1 [root@localhost ~]# ovs-vsctl add-port br-ex qg-peer1 [root@localhost ~]# ovs-vsctl add-port br-ex pub-peer1 [root@localhost ~]# ip link set vm-peer1 up [root@localhost ~]# ip link set qg-peer1 up [root@localhost ~]# ip link set pub-peer1 up [root@localhost ~]# ip netns exec qvm1 ip link set vm-veth1 up [root@localhost ~]# ip netns exec qpublic ip link set pub-veth1 up [root@localhost ~]# ip netns exec qrouter1 ip link set qg-veth1 up
qrouter1のインタフェースとRouting確認
[root@localhost ~]# ip netns exec qrouter1 ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 7: qr-veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 42:8a:36:9d:7d:21 brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/8 scope global qr-veth1 valid_lft forever preferred_lft forever inet6 fe80::408a:36ff:fe9d:7d21/64 scope link valid_lft forever preferred_lft forever 13: qg-veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 5e:6e:bb:98:eb:d5 brd ff:ff:ff:ff:ff:ff inet 192.168.101.10/24 scope global qg-veth1 valid_lft forever preferred_lft forever inet6 fe80::5c6e:bbff:fe98:ebd5/64 scope link valid_lft forever preferred_lft forever [root@localhost ~]# ip netns exec qrouter1 ip r 10.0.0.0/8 dev qr-veth1 proto kernel scope link src 10.0.0.1 192.168.101.0/24 dev qg-veth1 proto kernel scope link src 192.168.101.10
Floating IPに関する設定
Floating IP用のアドレスをaliasとして付与
[root@localhost ~]# ip netns exec qrouter1 ip addr add 192.168.101.11 dev qg-veth1 [root@localhost ~]# ip netns exec qrouter1 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 7: qr-veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 42:8a:36:9d:7d:21 brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/8 scope global qr-veth1 valid_lft forever preferred_lft forever inet6 fe80::408a:36ff:fe9d:7d21/64 scope link valid_lft forever preferred_lft forever 13: qg-veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 5e:6e:bb:98:eb:d5 brd ff:ff:ff:ff:ff:ff inet 192.168.101.10/24 scope global qg-veth1 valid_lft forever preferred_lft forever inet 192.168.101.11/32 scope global qg-veth1 valid_lft forever preferred_lft forever inet6 fe80::5c6e:bbff:fe98:ebd5/64 scope link valid_lft forever preferred_lft foreve
次にqrouter1でpublicから来たパケットをDNATするルールをiptablesに記載します。
[root@localhost ~]# ip netns exec qrouter1 iptables -t nat -A PREROUTING -d 192.168.101.11 -j DNAT --to 10.0.0.3 [root@localhost ~]# ip netns exec qrouter1 iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT all -- 0.0.0.0/0 192.168.101.11 to:10.0.0.3 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination
さらにSNATのルールを記載します。1対1NATです。
[root@localhost ~]# ip netns exec qrouter1 iptables -t nat -A POSTROUTING -s 10.0.0.3 -j SNAT --to 192.168.101.11 [root@localhost ~]# ip netns exec qrouter1 iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT all -- 0.0.0.0/0 192.168.101.11 to:10.0.0.3 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination SNAT all -- 10.0.0.3 0.0.0.0/0 to:192.168.101.11
インスタンス周りの設定をして疎通確認
[root@localhost ~]# ip netns exec qvm1 ip route add default via 10.0.0.1 dev vm-veth1 [root@localhost ~]# ip netns exec qvm1 ip route default via 10.0.0.1 dev vm-veth1 10.0.0.0/8 dev vm-veth1 proto kernel scope link src 10.0.0.3
Floating 経由で通信できることを確認します
[root@localhost ~]# ip netns exec qpublic ping 192.168.101.11 PING 192.168.101.11 (192.168.101.11) 56(84) bytes of data. 64 bytes from 192.168.101.11: icmp_seq=1 ttl=64 time=0.246 ms 64 bytes from 192.168.101.11: icmp_seq=2 ttl=64 time=0.070 ms 64 bytes from 192.168.101.11: icmp_seq=3 ttl=64 time=0.079 ms
テナントを追加で作ってみる
namespaceが分かれているのでL3レベルで独立性を保つ事が可能です。そのためneutronがテナントを作るようにqrouter/qdhcpを新たに作成します。openvswitchではtagを使って分離します。
qrouter2/qdhcp2を新たに作成するなどは同じです。アドレスも全く同じで問題ありません。以下の通りtagをつけること点がポイントです。
[root@localhost ~]# ip netns exec qrouter2 ip addr add 10.0.0.1/255.0.0.0 dev qr-veth2 [root@localhost ~]# ip netns exec qdhcp2 ip addr add 10.0.0.2/255.0.0.0 dev ns-veth2
[root@localhost ~]# ovs-vsctl add-port br-int qr-peer2 tag=2 [root@localhost ~]# ovs-vsctl add-port br-int ns-peer2 tag=2 [root@localhost ~]# ovs-vsctl add-port br-int vm-peer2 tag=2
疎通確認
内部的には同じアドレス(10.0.0.3)のインスタンス2台にpublicから疎通が取れています。
[root@localhost ~]# ip netns exec qpublic ping 192.168.101.12 PING 192.168.101.12 (192.168.101.12) 56(84) bytes of data. 64 bytes from 192.168.101.12: icmp_seq=1 ttl=63 time=0.411 ms 64 bytes from 192.168.101.12: icmp_seq=2 ttl=63 time=0.082 ms ^C --- 192.168.101.12 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.082/0.246/0.411/0.165 ms [root@localhost ~]# ip netns exec qpublic ping 192.168.101.11 PING 192.168.101.11 (192.168.101.11) 56(84) bytes of data. 64 bytes from 192.168.101.11: icmp_seq=1 ttl=64 time=0.163 ms 64 bytes from 192.168.101.11: icmp_seq=2 ttl=64 time=0.162 ms 64 bytes from 192.168.101.11: icmp_seq=3 ttl=64 time=0.059 ms ^C --- 192.168.101.11 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.059/0.128/0.163/0.048 ms
次は実際にneutronをインストールして確認してみる予定です。
参考;
君にもできる! にゅーとろん君になってみよー!! 「Neutronになって理解するOpenStack Net - OpenStack最…
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
オープンソース・クラウド基盤 OpenStack入門 構築・利用方法から内部構造の理解まで (アスキー書籍)
- 作者: 中井悦司,中島倫明
- 出版社/メーカー: KADOKAWA / アスキー・メディアワークス
- 発売日: 2014/06/03
- メディア: Kindle版
- この商品を含むブログ (2件) を見る
OpenStackクラウドインテグレーション オープンソースクラウドによるサービス構築入門
- 作者: 日本OpenStackユーザ会
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/28
- メディア: Kindle版
- この商品を含むブログを見る
fluentdをログ集約サーバとして使った時のメモ
まだ探り探りなのでもし良い方法があれば教えてください。
fluentd(td-agent)インストール用レシピ
excuteは使いたくなかったのですが一旦こちらで進めています。
execute 'Install td-agent' do command "curl -L #{node['td-agent']['install']['url']} | sh" not_if 'rpm -q td-agent' end template "/etc/td-agent/td-agent.conf" do owner 'root' mode 0644 source "#{node['td-agent']['conf']}.erb" notifies :reload, 'service[td-agent]' end node['td-agent']['server']['gem']['plugin'].each do |plugin| execute 'Install fluent-plugin-#{plugin}' do command "#{node['td-agent']['server']['gem']['dir']} install fluent-plugin-#{plugin}" not_if "#{node['td-agent']['server']['gem']['dir']} list | grep #{plugin}" end end service 'td-agent' do action [:enable, :start] supports restart: true, reload: true, status: true end
attributeやtemplateはこれに合わせて設定しています。割愛します。
各サーバから集めたログを同時書き込み
<match hoge.log.**> type file path /hoge/logs/foo.log output_time false </match>
各サーバからhogeというジャンルのlogをどのサーバから送ったかわかるようなtag設計にして送出するようにしています。hoge.log.
forest+ file_alternativeだと同時書き込みが・・・
tagごとのbuffer_pathがかぶるとNGのため同時書き込みが・・・。もう一つプラグイン挟めば良いと思うのですが、素直にtype fileにしました。
<match hoge.log.**> type forest subtype file_alternative remove_prefix hoge.log <template> path /hoge/logs/foo.log output_data_type attr:message output_include_tag true output_include_time false add_newline true </template> </match>
plain text状態のログ先頭にtagの一番後ろを付与(ohaiで取ったhostnameにしています)。pathでhogeというジャンルのlogということがわかるのでremove_prefixでtagから抜いています。
symlinkはbuffer_typeがfileの時のみ有効
buffer_type file buffer_path /fuga/logs/bar.buf symlink_path /fuga/logs/bar.log
http://docs.fluentd.org/articles/buf_file
buffer_type (required) The value must be file.
td-agentで集めたログのローテーションをどうするか
- time_sliceで期間を指定してローテーションされるが、logrotateのように世代管理ができないので・・・
- time_sliceをnoneとしたいが・・・
このあたりを使うのが良いのでしょうか。検討中。
find /hoge/logs/ -mtime +1
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
サーバ/インフラエンジニア養成読本 ログ収集〜可視化編 [現場主導のデータ分析環境を構築!] Software Design plus
- 出版社/メーカー: 技術評論社
- 発売日: 2014/08/14
- メディア: Kindle版
- この商品を含むブログを見る
【改訂新版】 サーバ/インフラエンジニア養成読本 管理/監視編 [24時間365日稼働を支える知恵と知識が満載!] (Software Design plus)
- 作者: 養成読本編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2014/04/11
- メディア: 大型本
- この商品を含むブログ (3件) を見る
Zabbix server Lack of free swap space on Zabbix serverが止まらなかったので見てたら・・
freeコマンドで見るとメモリは余っているのにswapを使っている。swapの領域を増やせばエラーはなくなるけど対応としてはそもそもswapを使ってほしくないと思ったので以下を調整。
$ cat /etc/sysctl.conf | grep swapp vm.swappiness=0
kernel 2.6からのパラメータです。0 - 100で値が低くするとスワップを極力使用しなくなる。デフォルト値は60です。
反映は以下の通りです。
$ sysctl -p
zabbix-server/mysql止めてやった方が良いです。
改訂版 Zabbix統合監視実践入門 ~障害通知、傾向分析、可視化による省力運用 (Software Design plus)
- 作者: 寺島広大
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/17
- メディア: 大型本
- この商品を含むブログ (1件) を見る
サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)
- 作者: 鈴木健太,吉田健太郎,大谷純,道井俊介
- 出版社/メーカー: 技術評論社
- 発売日: 2014/08/08
- メディア: 大型本
- この商品を含むブログ (1件) を見る
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
BIG-IPでL3DSR(n-path routing)を設定する
BIG-IPでL3DSR(n-path routing)を設定する方法です。
- ipip tunnel
- dscp
1. ipip tunnel
BIG-IPのipip tunnel設定
設定は簡単です。
Local Traffic -> Pools -> IP Encapsulation
ipipを選択
以上です。
Server側(CentOS/REHL)
ipipトンネルを有効にします。DirectにReplyをするためルーティングをトンネルインタフェースに向ける必要はありません。また、L2DSRと同様にLoopbackインタフェースはVIPとなるIPを設定してください。tunl0に設定するアドレスはnodeに設定したアドレスです。
$ modprobe ipip $ sudo ifconfig lo:0 192.168.1.1 netmask 255.255.255.255 -arp up $ sudo ifconfig tunl0 10.1.1.1 netmask 255.255.255.0 up
確認方法
lsmod | grep tun
sysctlも対象のLoopbackインタフェースが以下になっていることを確認します。
arp_ignore=3 arp_announce=2 rp_filter=0
2. DSCP
BIG-IPのDSCP設定
Local Traffic -> Pools -> IP Encapsulation
IP ToS to Server ToS で指定の値を設定。ここでいう値はToSです。
Server側(CentOS/REHL)
以下を使用します。やっていることはiptablesのmangleでdscpが指定の値にmatchした場合にdestinationのアドレスを変えるということです。で、その動作を実現するのに以下を使うと非常に楽です。
インストールはこちらを参照
l3dsr/README at master · yahoo/l3dsr · GitHub
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門
- 作者: みやたひろし
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2013/12/27
- メディア: 大型本
- この商品を含むブログ (7件) を見る
- 作者: トニーブルーク,Tony Bourke,鍋島公章,横山晴庸,上谷一
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2001/12
- メディア: 単行本
- 購入: 6人 クリック: 195回
- この商品を含むブログ (20件) を見る
- 作者: Steven Iveson
- 出版社/メーカー: Steven Iveson
- 発売日: 2013/12/29
- メディア: Kindle版
- この商品を含むブログを見る