[TextFSM] Rule Actionsの仕組みと使い方
はじめに
ntc-templateを編集するために最近調べたので、自分なりに理解した内容を纏める。
参考にした文献は次のとおり。
TextFSM · google/textfsm Wiki · GitHub
21. Parsing command output with TextFSM — Python for network engineers 1.0 documentation
- はじめに
- 準備
- 動作確認
- Line Actions:Continue
- Record Actions:NoRecord
- Record Actions:Record
- Record Actions:Clear
- Record Actions:Clearall
- State Transition
- Error Action
- 所感
準備
動作確認用のコード。 解析対象のデータも併せて定義している。
import textfsm InputData = ''' 2022_01_01 banana 100 orange 200 2022_12_31 banana 200 carrot 300 ''' with open('test.template') as template: fsm = textfsm.TextFSM(template) result = fsm.ParseText(InputData) print(fsm.header) print(*result, sep='\n')
基本とするTemplate
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record
解析結果はこうなる。
インプットと同じく2,4行目は日付が空欄。
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['', 'orange ', '200'] ['2022_12_31', 'banana ', '200'] ['', 'carrot ', '300']
動作確認
各Ruleには下記のアクションを指定できる。
指定する際はLine Actions
.Record Action
State Transition
の形式。
何も指定しないとNext.NoRecord
のアクションを取る。
- Line Actions
- Next
- Continue
- Record Actions
- NoRecord
- Record
- Clear
- Clearall
- State Transition
- Error Action
Line Actions:Next
今回のインプット行について解析を終了し次のインプット行の処理に移る。
Line Actionを定義しない場合このアクションとなる。
Template
- 明示的にNextアクションを定義
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Next.Record ^\s*${Item}\s*${Qty} -> Next.Record
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['', 'orange ', '200'] ['2022_12_31', 'banana ', '200'] ['', 'carrot ', '300']
元々デフォルトでNextアクションなので明示しても挙動は変わらない。
Line Actions:Continue
今回のインプット行について解析を終了せず、次行以降のルールと照合を続ける。
Template(いったんContinue無し)
- 2行目にルールを追加。ひとまずContinueは無し
- 話がややこしくなるので明示的なEOF Stateも追加
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} ^\s*${Item}\s*${Qty} -> Record EOF
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_12_31', 'banana ', '200']
2行目にRecordがないので日付無しのインプット行は出力されない。
3行目のルールは辿り着くことがないので無意味。
Template(Continue付き)
- 先ほどの2行目のルールにContinueを追加
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Continue ^\s*${Item}\s*${Qty} -> Record EOF
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['', 'orange ', '200'] ['2022_12_31', 'banana ', '200'] ['', 'carrot ', '300']
今度は日付無しのインプット行も出力された。
Continueにより3行目のルールまで処理が到達したためこうなる。
Record Actions:NoRecord
収集したValueを記録しない。Actionを定義しない場合この動作となる。
記録しないものの内部的にはValueを収集している点に注意。
Template
- 各ルールにNoRecordを指定
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> NoRecord ^\s*${Item}\s*${Qty} -> NoRecord
結果
['Date', 'Item', 'Qty'] ['2022_12_31', 'carrot ', '300']
3行目のDateと4行目のItem,Qtyが混ざった値が出力された。
各インプット行がルールと合致する度に各Valueは上書きして保持されるらしい。
つまり下記のように動作している。
インプット1行目処理時点…['2022_01_01', 'banana ', '100']
インプット2行目処理時点…['2022_01_01', 'orange ', '200'] * Item,QtyのValueを上書き
インプット3行目処理時点…['2022_12_31', 'banana ', '200'] * 全てのValueを上書き
インプット4行目処理時点…['2022_12_31', 'carrot ', '300'] * Item,QtyのValueを上書き
→暗黙のEOF Stateにより出力される。
Record Actions:Record
収集したValueを記録する。
改めて試すべきこともないので挙動確認は省略。
Record Actions:Clear
収集したがまだRecordしておらず、内部保持しているValueを開放するアクション。
ただしFilldownのValueは開放しない。
Template(Filldown無し)
- 1行目のルールに
Continue.Clear
を指定 - 2行目のルールは何も収集せずRecord(
^\d
は日付有り行が該当する)
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Continue.Clear ^\d -> Record ^\s*${Item}\s*${Qty} -> Record EOF
結果
['Date', 'Item', 'Qty'] ['', 'orange ', '200'] ['', 'carrot ', '300']
日付有りのインプット行については下記の流れで処理される。
その結果として日付無し行のみ出力される。
- 1行目のルールに引っかかる
- 各Valueが収集される
- 収集した値がClearアクションで解放される
- Continueアクションにより2行目のルールへ進む
- 2行目のルールに引っかかる
- Recordアクションが動作するが、先ほどClearしたため格納するものがない
Template(Filldown有り)
- ValueにFilldownオプションを付与
Value Filldown Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Continue.Clear ^\d -> Record ^\s*${Item}\s*${Qty} -> Record EOF
結果
['Date', 'Item', 'Qty'] ['2022_01_01', '', ''] ['2022_01_01', 'orange ', '200'] ['2022_12_31', '', ''] ['2022_12_31', 'carrot ', '300']
動作の流れは先ほどと同じだが、FilldownオプションのついたDateは
Clear対象外のため各行で出力される。
Record Actions:Clearall
Clearに近いが、こちらはFilldownオプション付きのValueも開放する。
Template
- Clear検証時(Filldown有り)のものをClearallに変えただけ
Value Filldown Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Continue.Clearall ^\d -> Record ^\s*${Item}\s*${Qty} -> Record EOF
結果
['Date', 'Item', 'Qty'] ['', 'orange ', '200'] ['', 'carrot ', '300']
Clear検証時にFilldownオプションを使わなかったときと同じ出力になった。
State Transition
あるStateから他のStateへ移行する。
以降のインプット行の解析は移行後のStateで実施される。
他のアクションの後に半角スペースを空けて定義する。
Template
- ルールを2つのStateへ分割
- Start StateのルールにState Transitionを定義
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record Test1 Test1 ^\s*${Item}\s*${Qty} -> Record EOF
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['', 'orange ', '200'] ['', 'carrot ', '300']
1行目のRecordが終わった後にTest1 Stateへ移行する。
インプット2~4行目はTest1 Stateで解析されるため
結果として2,4行目だけがマッチし出力される。
Error Action
ルールにマッチした場合、Errorとして解析処理を止める。 これまでRecordした内容もすべて破棄する。
Template
- 2行目のルールを
Record
からError
へ変更
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Error
結果
textfsm.parser.TextFSMError: State Error raised. Rule Line: 7. Input Line: orange 200
インプットorange 200
がTemplateの7行目でErrorと判定された。
所感
疲れた。誰かのお役に立つことを期待します。(そもそも内容に誤りがないことを祈る)
[TextFSM] 予約済みStateの仕組みと使い方
はじめに
ntc-templateを編集するために最近調べたので、自分なりに理解した内容を纏める。
参考にした文献は次のとおり。
TextFSM · google/textfsm Wiki · GitHub
21. Parsing command output with TextFSM — Python for network engineers 1.0 documentation
準備
動作確認用のコード。 解析対象のデータも併せて定義している。
import textfsm InputData = ''' 2022_01_01 banana 100 orange 200 2022_12_31 banana 200 carrot 300 ''' with open('test.template') as template: fsm = textfsm.TextFSM(template) result = fsm.ParseText(InputData) print(fsm.header) print(*result, sep='\n')
基本とするTemplate
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record
解析結果はこうなる。
インプットと同じく2,4行目は日付が空欄。
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['', 'orange ', '200'] ['2022_12_31', 'banana ', '200'] ['', 'carrot ', '300']
動作確認
TextFSMには下記の予約済みStateが存在する。それぞれの動作を確認する。
- Start
- EOF
- END
Start State
定義必須のState。
インプット行との照合はこのStateの1行目のRuleから始まる。
ここでは次の2つの動作を確認する。
- Start Stateを定義しない場合
- State以外のStateを追加定義した場合
Template(State Stateを未定義)
- Startの代わりに
Test1
という名称でStateを定義
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Test1 ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record
結果
textfsm.parser.TextFSMTemplateError: Missing state 'Start'.
必須のStateがないためErrorで処理が止まった。
Template(他のStateを追加定義)
Test1
,Test2
というStateを定義
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Test1 ^\s*${Item}\s*${Qty} -> Record Start ^${Date}\s*${Item}\s*${Qty} -> Record Test2 ^\s*${Item}\s*${Qty} -> Record
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_12_31', 'banana ', '200']
日付入りの行のみ出力された。
処理はStart Stateから始まり、かつ他のStateへは飛ばないためこうなる。
※ 後ほど確認するState Transition Actionを使えば他のStateへ飛べる
EOF State
インプットの全行について処理を終えた後に自動的に作動するState。
明示的に定義しなかった場合、下記の暗黙のEOF Stateが作動する。
EOF ^.* -> Record
これは今現在収集している情報をRecordするという意味を持つ。
ここでは次の2つの動作を確認する。
- 暗黙のEOF State
- 明示的なEOF State
Template(暗黙のEOF State)
- ほぼ元々と同じ形だが、最後のルールにRecordがない点に注目
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty}
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_12_31', 'banana ', '200'] ['', 'carrot ', '300']
日付入りの行だけが出力されると思いきや、4行目のcarrot,300
も出てきた。
^\s*${Item}\s*${Qty}
はRecordしないもののItem,QtyのValueを収集しており、
それが暗黙のEOF Stateによって出力されるためこうなる。
このあたりの挙動は下記の記事でも確認している。
[TextFSM] Rule Actionsの挙動確認 - るつぼっと
Template(明示的なEOF State)
- 最後のルールにRecordがない
- 新たに
EOF
Stateを定義
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} EOF
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_12_31', 'banana ', '200']
先ほどと違い、日付入りの行だけが出力された。
EOF Stateを明示的に定義した場合、先ほどの暗黙的な動作が
取られないためこのような結果となる。
END State
このStateが作動した時点で解析処理を終了するState。
未解析のインプット行が残っていても終了させる。
Template
- 2行目のルールを
Record
からEND
へ変更
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> END END
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['', 'orange ', '200']
2行目までが解析および出力された。
どうやらEND StateにはRecordアクションも含まれるようだ。
[TextFSM] オプションフラグの仕組みと使い方
はじめに
ntc-templateを編集するために最近調べたので、自分なりに理解した内容を纏める。
参考にした文献は次のとおり。
TextFSM · google/textfsm Wiki · GitHub
21. Parsing command output with TextFSM — Python for network engineers 1.0 documentation
オプション一覧
ちゃんとした説明は公式サイトを参照。
- Filldown
対象Valueの現在行の解析結果が空だったら、前の行の値をコピーする。 - Fillup
対象Valueの前の行の解析結果が空だったら、今の行の値をコピーする。 - Required
このフラグのValueが空だと、今回の行の解析結果はテーブルに格納されない。 - List
値を複数保持する。これが無いと前の値は上書きされる。 - Key
使い道が分からんので今回はパス。
動作確認
作成したTemplate(test.template)を参照し、結果を出力するためのコード。
解析対象のデータも併せて定義している。
import textfsm InputData = ''' 2022_01_01 banana 100 orange 200 carrot 300 2022_12_31 banana 200 ''' with open('test.template') as template: fsm = textfsm.TextFSM(template) result = fsm.ParseText(InputData) print(fsm.header) print(*result, sep='\n')
基本とするTemplate
Value Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record
解析結果はこうなる。
インプットと同じく2~3行目は日付が空欄。
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['', 'orange ', '200'] ['', 'carrot ', '300'] ['2022_12_31', 'banana ', '200']
Filldownオプション
Template
- DateのValueに
Filldown
オプションを付与
Value Filldown Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_01_01', 'orange ', '200'] ['2022_01_01', 'carrot ', '300'] ['2022_12_31', 'banana ', '200'] ['2022_12_31', '', '']
Dataの空欄が埋まった。でも最後に余計な1行が出てきた。
暗黙のEOF Stateのせいだと思われるので次のとおりEOF Stateを明示的に定義して修正。
(このあたりの仕様の話は公式の説明を参照)
Template(EOF Stateを明示的に定義)
- 末尾に
EOF
Stateを追記
Value Filldown Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record EOF
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_01_01', 'orange ', '200'] ['2022_01_01', 'carrot ', '300'] ['2022_12_31', 'banana ', '200']
最後の行が消えました。
Fillupオプション
Template
- DateのValueに
Fillup
オプションを付与
Value Fillup Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_12_31', 'orange ', '200'] ['2022_12_31', 'carrot ', '300'] ['2022_12_31', 'banana ', '200']
最終行の2022_12_31の値が上方向の空欄に反映された。
挙動の仕組み上、今回はEOF Stateを明示する必要なし。
Requiredオプション
Template
- DateのValueに
Required
オプションを付与
Value Required Date (\d+_\d+_\d+) Value Item (\D+) Value Qty (\d+) Start ^${Date}\s*${Item}\s*${Qty} -> Record ^\s*${Item}\s*${Qty} -> Record
結果
['Date', 'Item', 'Qty'] ['2022_01_01', 'banana ', '100'] ['2022_12_31', 'banana ', '200']
RequiredであるDateのValueがない行は格納されなくなった。
Listオプション
説明の前に具体的な活用例を示す。
Continueオプションと併せて使うため、下記の記事も参考にどうぞ。
[TextFSM] Rule Actionsの挙動確認 - るつぼっと
Template
- ItemとQtyのValueに
List
オプションを付与 - 1行目に
Continue.Record
付きのルールを追加
^\dは「行頭が数字」という条件のため今回は日付有りの行が該当 - その他の行は
Record
無し
Value Date (\d+_\d+_\d+) Value List Item (\D+) Value List Qty (\d+) Start ^\d -> Continue.Record ^${Date}\s*${Item}\s*${Qty} ^\s*${Item}\s*${Qty}
結果
['Date', 'Item', 'Qty'] ['2022_01_01', ['banana ', 'orange ', 'carrot '], ['100', '200', '300']] ['2022_12_31', ['banana '], ['200']]
このとおり、同じ日付についてはItemやQtyの値が一つのリストに纏められた。
こういう使い方をするらしい。
と言ってもこれだけじゃ分からないので動作を整理してみる。
動作の流れ
【注意】
以降は文献や動作結果から想像した内容です。誤りがあるかもしれません。
また、説明の都合により次の言葉を独自に定義しています。
- Output Table…Recordアクションにより値が格納される場所
- Buffer…ルールで抽出した値がRecordで格納されるまでに一時保存される場所
1.
1行目のInputが1行目のルールと照合され、合致する。
Recordアクションが取られるが何もBufferされていないため何も格納されない。
2.
Continueアクションに基づき2行目のルールと照合され、合致する。
各Valueに紐づく値がBufferへ格納される。
RecordアクションがないためOutput Tableには格納されない。
3.
2行目のInputが1,2行目のルールと照合され、合致しない。
続いて3行目のルールと照合され、合致する。
各Valueに紐づく値がBufferへ格納される。
※ 今回はList形式のため値が追加される。List形式でない場合は値が上書きされる
RecordアクションがないためOutput Tableには格納されない。
4.
3行目のInputが1,2行目のルールと照合され、合致しない。
続いて3行目のルールと照合され、合致する。
各Valueに紐づく値がBufferへ格納される。
RecordアクションがないためOutput Tableには格納されない。
5.
4行目のInputが1行目のルールと照合され、合致する。
Recordアクションが取られBufferされた値がOutput Tableへ格納される。
6.
Continueアクションに基づき2行目のルールと照合され、合致する。
各Valueに紐づく値がBufferへ格納される。
RecordアクションがないためOutput Tableには格納されない。
7.
Inputを全行読み込んだため最後に暗黙のEOF Stateの処理が走る。
つまり、Bufferされた値がOutput Tableへ格納される。
以上。
こんな動作をしているものと想定してます。
[CML] 複数機器のConfigを1回の操作でエクスポートする方法
はじめに
CMLではラボの物理構成をエクスポートできる。
加えて、対象機器を選択した状態のメニューから EDIT CONFIG > FETCH FROM DEVICE を実行しておくことでエクスポート内容にconfigを含めることができる。
でも機器が沢山あると1台ずつ実行するのは結構面倒くさい。
結論
機器を未選択状態のメニューから NODES > EXTRACT CONFIGS を実行すれば1回でOK。
FETCH FROM DEVICE同様、機器が起動していないと実行できない点に注意。
所感
この操作自体はエクスポートではないので、記事のタイトルは微妙に不正確。
でも意味は伝わりやすいと思うからこのままとする。
[CML] 自宅のPCからCisco DEVNET上のCML機器へSSH接続する方法
結論
- Deviceに10.10.20.x/24のIPアドレスを割り当てる
- Deviceに自宅の端末セグメント向けのルーティングを設定する(NextHop:10.10.20.254)
- External Connectorをブリッジモードで接続する
10.10.20.x/24のセグメントの一部IPはCMLサーバ自体やデフォルトLabの機器にも割り当てられている。 使うIPが重複しないよう注意すること。デフォルトLabについては止めるか削除してしまえば重複しない。
メモ_確認したところ
10.10.20.254のIPはデフォルトLabの機器のConfigから確認。 自宅の端末セグメントはipconfigで確認。 自宅の端末からトンネル経由で到達できるCML側セグメントはroute printで確認。
C:\>ipconfig Windows IP 構成 イーサネット アダプター イーサネット 5: 接続固有の DNS サフィックス . . . . .: lab.devnetsandbox.local IPv4 アドレス . . . . . . . . . . . .: 192.168.254.11 サブネット マスク . . . . . . . . . .: 255.255.255.0 デフォルト ゲートウェイ . . . . . . .: C:\> C:\>route print | find "192.168.254.11" 10.10.20.0 255.255.255.0 192.168.254.1 192.168.254.11 2 10.10.21.0 255.255.255.0 192.168.254.1 192.168.254.11 2 10.10.22.0 255.255.255.0 192.168.254.1 192.168.254.11 2 10.10.23.0 255.255.255.0 192.168.254.1 192.168.254.11 2 10.10.24.0 255.255.255.0 192.168.254.1 192.168.254.11 2 10.17.248.0 255.255.255.0 192.168.254.1 192.168.254.11 2 10.17.248.11 255.255.255.255 192.168.254.1 192.168.254.11 2 10.17.248.12 255.255.255.255 192.168.254.1 192.168.254.11 2 172.16.30.0 255.255.255.0 192.168.254.1 192.168.254.11 2 192.168.254.0 255.255.255.0 リンク上 192.168.254.11 257 192.168.254.11 255.255.255.255 リンク上 192.168.254.11 257 192.168.254.255 255.255.255.255 リンク上 192.168.254.11 257 224.0.0.0 240.0.0.0 リンク上 192.168.254.11 10000 255.255.255.255 255.255.255.255 リンク上 192.168.254.11 10000
【Windows】1台のPCで複数のWebサーバを構築する(LB試験用)
IISを使って適当にWebサーバを構築する方法。
LBの負荷分散機能の動作確認用などに使うだけなので、まともな構築と思ってはいけない。
環境:Windows10 Home
0.構成
以降の作業は全て右端のPCに対するものです。
その他の周辺環境は準備されている前提とします。
1.IPアドレスの割り振り
よく見る(?)IPアドレス設定画面右下の詳細設定
をクリック。
追加
からIPアドレスを追加する。
2.IISサービスの有効化
下図のとおりインターネット インフォメーション サービス
にチェックを入れるだけ。
3.Webサイトの構築
管理ツール
からインターネット インフォメーションサービス (IIS) マネージャー
を選択。
サイト
を右クリックしてWebサイトの追加...
を選択。
サイト名と物理パスを適当に指定。IPアドレスは先ほど設定したうちの一つを指定。
同じ要領で2つ目のサイトも作成。
上記で指定したそれぞれのコンテンツディレクトリへindex.html
ファイルを格納する。
権限によって直接作成できない場合は他のディレクトリで作成したファイルをコピペする。
中身のコンテンツはどちらのサーバにアクセスしてるか判別できればなんでもいい。
(画像は省くがそれぞれの index.html に test1 と test2 とだけ記している)
これでおしまい。
4.動作確認
冒頭の図の左端のPCからサイトのURLへアクセスする。
test1 か test2 と表示されるはず。(挙動はLBの負荷分散方式による)