自動でできるかな?
2015/7/3 npstudy #5
@_norin_
自己紹介
❖ データセンターの中の人

サーバやらネットワークやらクラウドやら
❖ 以前は広域イーサやEoMPLSやってました
本日のお話
❖ 定型作業の自動化って大昔から言われてたよね

じゃあ実際どこまでできるのかやってみた&その結果
❖ IaaSを使う側ではなく作る側の話です
❖ 特定の機器の話をしますが、disるのが目的ではありません
機械とお話するところ
この辺りのお話
ユーザがアクセス
するところ
シナリオ
VM VM VM
hyper visor bare metal
L2 switch(ToR)
L3 switch
trunk access
trunk
最近流行りのクラウド 昔ながらの物理サーバ
1. L2−ホスト間のInterfaceを設定して
2. L2&L3にVLAN作って
3. L3のVLANにIP振って
4. L2−L3間のtrunkにVLAN振って
5. L2のdownlinkにVLAN振って
6. ホストーL2間のリンクを開放して
7. 監視サーバからホストにpingが通る (^o^)/
L3 switch
host
L2 switch
trunk
Access
具体的なオペレーション
❖ Interface
❖ Description,Speed,Duplex,trunk/access,up/down
❖ VLAN
❖ IP Address
❖ (Access Control、QoS、etc)
対象
❖ エッジ・アクセスに近い機器

サーバと接続・回線開通などで日々設定する機器
❖ 検証機器

C3750/2950

A3600/2400

FWX120

 CSR1000v
How
❖ CLI ・・・・・・・ 標準・万能・人にやさしく・機械に厳しく
❖ SNMP ・・・・・・ エンタープライズ以上の機器
❖ NETCONF ・・・・ エンタープライズ以上の一部機器
❖ REST ・・・・・・  クラウド向けとか
❖ WebUI ・・・・・ コンシューマー&L4-向け



※CLIは省略
❖ IF設定
❖ Up/Down IF-MIB::ifAdminStatus
実行してみる

 $ snmpset -v 1 -c community host interfaces.ifTable.ifEntry.ifAdminStatus.10001 i 1 

 IF-MIB::ifAdminStatus.10001 = INTEGER: up(1)




SNMP
❖ Speed/Duplex
❖ IF-MIB::ifHighSpeed
❖ EtherLike-MIB::dot3StatsDuplexStatus
実行

 $ snmpset -v 1 -c community host ifXTable.ifXEntry.ifHighSpeed.10001 i 1000

 Error in packet.

 Reason: (noSuchName) There is no such variable name in this MIB.

 Failed object: IF-MIB::ifHighSpeed.10001



MIBを眺めてみる




ifHighSpeed OBJECT-TYPE

SYNTAX Gauge32

MAX-ACCESS read-only

STATUS current
dot3StatsDuplexStatus OBJECT-TYPE

SYNTAX INTEGER

 {

  unknown(1),

  halfDuplex(2),

  fullDuplex(3)

 }

 MAX-ACCESS read-only

❖ C3750
CISCO-STACK-MIB::

portAdminSpeed OBJECT-TYPE

SYNTAX INTEGER {

autoDetect(1),

autoDetect10100(2),

-- Auto Detect with,

-- only allowed values: 10 & 100

s4000000(4000000), -- 4 Mbps

s10000000(10000000), -- 10 Mbps

        ・・・

s64000(64000), -- 64 kps

s10G(10) -- 10 Gps

}

MAX-ACCESS read-write

STATUS current IndexはCISCO-STACK-MIB::portIfIndexを指定( ifIndex)
$ snmpwalk -c public host ifDescr # ifIndex

IF-MIB::ifDescr.10002 = STRING: FastEthernet1/0/2

$ snmpwalk -c public host portIfIndex # ifIndex <=> portIfIndex

CISCO-STACK-MIB::portIfIndex.1.4 = INTEGER: 10002

$ snmpset -c private host portAdminSpeed.1.4 i 1 # autoDetect
※C2950はCISCO-C2900-MIBが対応
❖ AX3600/2400、CSR1000v

private MIBにない
❖ FWX120

これもprivate MIBにない&実装しているMIBが少ない

ifMIBも未実装(64bitカウンタ。。。)

❖ VLAN
❖ C3750/C2950

IF同様private MIBにて実装(VTP-MIB)
❖ VLANの追加

$ snmpset -c private crumpy vtpVlanEditOperation.1 integer 2

$ snmpset -c private crumpy vtpVlanEditBufferOwner.1 octetstring "Gerald"

$ snmpset -c private crumpy vtpVlanEditDot10Said.1.11 octetstringhex 000186AB

$ snmpset -c private crumpy vtpVlanEditOperation.1 integer 3
❖ ポートへVLAN追加

$ snmpget -c private crumpy ifDescr

interfaces.ifTable.ifEntry.ifDescr.6 : DISPLAY STRING- (ascii): FastEthernet0/5



$ snmpset -c private crumpy vmVlan.6 integer 48
http://www.cisco.com/cisco/web/support/JP/100/1004/1004104_vlans.html
❖ AX3600/2400

MIBがございません<_ _>

❖ CSR1000v/FWX120

(略)
❖ IPアドレス設定
❖ C&A

IP-MIBではdeprecateな「ipAddrTable」だけ実装

「ipAddressTable」はcreate可能なので出来そうだけど。。。

❖ F

MIBがあるわけでもなく
SNMP敗北
NETCONF
気を取り直してNETCONF


AX3600/2400とCSR1000vが実装
❖ ざっくりNETCONF
❖ RFC6241
❖ XMLで設定・取得ができる
❖ こんなのを投げます
<get-config>

<interface>

<name>fastethernet-1/0</name>

<type>ianaift:ethernetCsmacd</type>

</interface>
❖ AX3600/2400
Request:

<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<rpc message-id="4965">
<get-config>
<source> <running /> </source>
</get-config>
</rpc> </rpc>
Response
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<rpc-reply message-id="4965">
<data>
<ns1:ConfigData xmlns:ns1="urn:net:alaxala:oan:onapi:commons:netmod:1.0">
#Last modified by i2ts at Wed Jul 1 17:58:58 2015 with version 11.4
!
hostname &quot;Labo-AX&quot;
clock timezone JST +9
・・・
get−configはできたが設定用のschemaが見つからず断念
❖ CSR1000v




標準schemaよりもなんでも出来る分、こっちの方が便利かも
<?xml version="1.0" encoding="UTF-8"?>

<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

<edit-config>

<target>

<running/>

</target>

<config>

<cli-config-data>

<cmd> interface GigabitEthernet2 </cmd>

<cmd> speed 1000 </cmd>

</cli-config-data>

</config>

</edit-config>

</rpc>]]>]]>

REST
イマドキハヤリのREST


が、対応してるSwitchが無い
CSR1000v、FWX120でちゃれんじ
CSR1000v
イマドキさんです :-)
❖ IF up/down
POST /api/v1/interfaces/gigabitEthernet1/state

Content-Type: application/json



{

"if-name" : "gigabitEthernet1",

"enabled" : true

}


❖ Sub-IF(VLAN) & IP設定
POST /api/v1/interfaces

Content-Type: application/json



{ 

"subinterface-vlan": {"vlan-id":23},

"if-name": "GigabitEthernet2.23",

"subnet-mask": "255.255.255.0",

"ip-address": "22.10.10.23",

"type": "ethernet"

}
FWX120
それ、RESTちゃう。。。

TLS非対応なのにURLにパスワード直書きはヤメテ(-"-;)


POST /custom/api?password=password HTTP/1.1
vlan lan1/1 802.1q vid=101 name="vlan 101"
ip lan1/1 address 192.168.0.1/24
no lan shutdown lan1 1
❖ なんちゃってRESTならC3750でも(WebUIとは別のURI)

ドキュメントが見つからなかったのでunofficialなのかも?
POST /ios_web_exec/commandset HTTP/1.1
Authorization: Basic xxxxxxx
! COMMANDSET VERSION="1.0"
! OPTIONS BEGIN
! ACTION_ON_FAILURE="0" MODE="0"
! OPTIONS END
show interfaces status
end
! END
! COMMANDSET END
WebGUI
❖ コンシューマー向けブロードバンドルータやLoad balancer/Firewall、

その他直観的な操作のほうが分かりやすい機器などで実装
❖ ブラウザ経由で設定するので、HTTPのリクエスト・レスポンスがわかれば

なんでもできる(はず)

LiveHTTPHeaderなりFiddlerなりで解析頑張りましょう
(略)
まとめと所感
❖ かつてに比べて自動化しやすくはなっている
❖ NETCONF/REST/Webなど入口(アクセス手段)は増えた
❖ が、メッセージボディの規格がまとまっていない
❖ CLI 最強!!
❖ Command over XXXが実装の容易さ&ユーザの使い勝手的に一番いいのでは
❖ 応答メッセージの解析はいままでどおり

plain text/XML/JSONなどフォーマットの数だけ手間が増えたような?
❖ SNMPは情報取得用と割り切る
❖ 設定 CLI、確認 SNMP、など役割分担するのが現実的
❖ SETに対応するMIBが増えれば使い勝手はかなり良くなるはず
❖ 10GbEが当たり前の時代、64bitカウンタは必須
❖ NETCONFの使い勝手は対応モデルの数次第
❖ 真っ当に使おうとするとモデルの数が少なすぎてSNMPより不便

現状の標準MIBくらいは対応してくれないと
❖ Commandの埋め込みが使えればこちらの方がはるかに便利
❖ 自動化したい作業は限られる
❖ IF・IP・VLANなどInterface関連、VXLANなどのpseudo wireくらい

密結合なシステムはサーバサイドでも自動化はやりにくい
❖ APIが一番必要なのはローエンド∼ミドルレンジのL2/L3Switch
❖ 特殊なハイエンド機器は特殊なエンジニアが特殊ないじり方をする

ルータは最近見かけなくなりました
❖ CLI Only機器の扱い
❖ South boundはいままでどおりtelnet + expectでガンバル
おまけ
❖ VMware ESX
❖ 仮想基盤(hyper visor)
❖ 設定・情報取得はGUI/CLIとSOAP(like NETCONF)
❖ オブジェクト設計がイマドキ

❖ Request:

<QueryDvsConfigTarget xmlns="urn:vim25">

<_this type="DistributedVirtualSwitchManager">ha-dvsmanager</_this>

</QueryDvsConfigTarget>
❖ Response:

<QueryDvsConfigTargetResponse xmlns="urn:vim25">

<returnval>

<distributedVirtualPortgroup>

<switchName>DSwitch</switchName>

<switchUuid>0c 60 37 50 ef 60 45 49-07 36 1d 31 13 65 f5 dd</switchUuid>

<portgroupName>common segment</portgroupName>

・・・・・

<distributedVirtualSwitch>

<switchName>test-network</switchName>

<switchUuid>3f 90 03 50 64 12 05 33-49 84 05 2e 78 45 47 16</switchUuid>

</distributedVirtualSwitch>

</returnval>

</QueryDvsConfigTargetResponse>
require 'rbvmomi'

vim = RbVmomi::VIM.connect(:host=>host, :user=>user, :password=>pass, :insecure=>true) # connect server

vim.serviceContent.dvSwitchManager.QueryDvsConfigTarget # query
お膳立て含めて3行
仮想スイッチの取得
❖ SOAP

<CreateDVPortgroup_Task>

<_this type="VmwareDistributedVirtualSwitch">dvs</_this>

<spec>

<name>test_dvpg</name>

<numPorts>8</numPorts>

<defaultPortConfig>

<vlan>

<inherited>false</inherited>

<vlanId>977</vlanId>

</vlan>

</defaultPortConfig>

<type>earlyBinding</type>

</spec>

</CreateDVPortgroup_Task>
❖ ruby code

vlan = RbVmomi::VIM::VmwareDistributedVirtualSwitchVlanIdSpec.new 

vlan.vlanId = 977

vlan.inherited = "false"

portSetting = RbVmomi::VIM::VMwareDVSPortSetting.new

portSetting.vlan = vlan

...dvs.CreateDVPortgroup_Task(spec: {name: "test_dvpg", defaultPortConfig: portSetting, })

VLAN(仮想ポートグループ)の作成

自動でできるかな?