C14-OpenStack 網路服務 3:Octavia 負載平衡服務

0. 環境與準備

0.1 本課環境

主機角色管理網 IP
jmp001學員操作機(OpenStack CLI),接在外部網段 192.168.100.0/2410.127.0.3
ctl001 / ctl002 / ctl003控制節點:octavia_api、octavia_worker、octavia_health_manager,以及 OVN Central10.127.0.4 / .14 / .15
scp001 / scp002運算節點:後端 VM 與 amphora VM 跑在這裡10.127.0.7 / .18

講師已建立全班共用的後端環境,請不要修改或刪除:

資源名稱說明
Network / Subnetc14-net / c14-subnet(192.168.14.0/24)Self-Service 網路。你的 LB VIP 和 member 都在這個子網
Routerc14-router接 c14-subnet,對外閘道為 public1,所以 VIP 可以綁 Floating IP
Security Groupc14-sgingress 放行 TCP 80、ICMP、TCP 22
VMc14-web1(scp001)、c14-web2(scp002)cirros,以 busybox httpd 在 :80 回應一行 web1 或 web2,一看就知道請求被分到哪一台

本課每人建立兩個 LB,後端都是這兩台 VM:

C14 本課要建立的兩個負載平衡器 jmp001 接在 Provider 網路 public1(192.168.100.0/24)上,從這裡 curl 兩個 Floating IP。講師建立的 c14-router 連接 public1 與 Self-Service 網路 c14-net(192.168.14.0/24),c14-net 上有兩台後端 c14-web1(scp001)與 c14-web2(scp002),各自在 port 80 回應自己的名稱。每位學員建立兩個 LB,VIP 都在 c14-subnet:c14-stuNN-ovn 使用 OVN provider,沒有 VM,只是 OVN Northbound DB Load_Balancer 表的一列,TCP:80、SOURCE_IP_PORT;c14-stuNN-amp 使用 Amphora provider,由一台 amphora VM 裡的 HAProxy 處理 HTTP:80、ROUND_ROBIN 與 L7 policy,VIP 掛在 VRRP port 上,另以 lb-mgmt-net 與控制節點的 octavia-worker(9443)和 health-manager(5555)溝通。OVN 健康檢查從子網共用的 ovn-lb-hm port 發出。 provider network public1 192.168.100.0/24 jmp001 curl http://<FIP>/ 學員操作機 .10 self-service network c14-net(geneve) c14-subnet 192.168.14.0/24 c14-router FIP c14-stuNN-ovn provider:ovn(沒有 VM) TCP:80 → SOURCE_IP_PORT health monitor:TCP OVN NB Load_Balancer 的一列 VIP FIP c14-stuNN-amp provider:amphora HTTP:80 → ROUND_ROBIN、L7 amphora VM HAProxy ・ STANDALONE VRRP + VIP lb-mgmt-net:9443 設定 / 5555 心跳 c14-web1 主機:scp001 :80 回應「web1」 member web1 c14-web2 主機:scp002 :80 回應「web2」 member web2 兩台都套用 c14-sg(TCP 80、ICMP、22) ovn-lb-hm port OVN 健康檢查的來源,子網共用
本課要建立的兩個負載平衡器

0.2 本課的節奏

Amphora LB 要開一台 VM(amphora),試跑時從建立到 ACTIVE 約 5 分鐘;OVN LB 只是在 OVN 寫一列資料,約 6 秒。所以本課的順序是:

  1. A:先送出 Amphora LB 的建立指令,不等它
  2. B:等待的時間,從頭建一個 OVN LB 並測試
  3. C–E:回到已經好了的 Amphora LB,完成並測試
  4. F:清除

⚠️ 規則

  • 你使用的是和講師相同的管理員權限,只操作名稱有你編號的資源
  • 全班同時建 Amphora LB 時,20 台 amphora 一起開機,可能比試跑的 5 分鐘慢;到 C 節時還沒 ACTIVE 就再等一下,不要重複建立
  • 預期輸出是示意,UUID、IP、時間會與你看到的不同

0.3 準備

指令
# [jmp001]
export NN=01                                     # ← 換成你的學員編號(01–20)
source ~/venv/bin/activate
source ~/creds/stu${NN}-openrc.sh
export WEB1=$(openstack port list --server c14-web1 -f value -c "Fixed IP Addresses" | cut -d"'" -f8)
export WEB2=$(openstack port list --server c14-web2 -f value -c "Fixed IP Addresses" | cut -d"'" -f8)
echo "c14-stu${NN}  web1=$WEB1  web2=$WEB2"
openstack loadbalancer provider list

預期輸出:

預期輸出
c14-stu01  web1=192.168.14.25  web2=192.168.14.81
+---------+------------------+
| name    | description      |
+---------+------------------+
| amphora | Amphora provider |
| ovn     | OVN provider     |
+---------+------------------+

Part A:先送出 Amphora LB(p.6、13)

指令
# [jmp001]
date +%T
openstack loadbalancer create --name c14-stu${NN}-amp --provider amphora \
  --vip-subnet-id c14-subnet -f yaml \
  -c id -c provider -c vip_address -c provisioning_status -c operating_status

預期輸出:

預期輸出
18:07:29
id: 29c0dc3b-1147-4e6c-9ace-241f192dbb1f
operating_status: OFFLINE
provider: amphora
provisioning_status: PENDING_CREATE
vip_address: 192.168.14.108

把 date 印出的時間記下來,C 節要算花了多久。

輸出意思
provisioning_status: PENDING_CREATE控制平面還在做:octavia-worker 正在請 Nova 開 amphora VM。指令沒加 --wait,所以馬上就返回
operating_status: OFFLINE還沒有任何流量在跑。兩個欄位是獨立的(p.13)
vip_addressVIP 已經先從 c14-subnet 配好了:它保留在一個 Neutron Port 上,C 節會看到

趁它還在建,試著加一個 Listener:

指令
# [jmp001]
openstack loadbalancer listener create --name test --protocol HTTP --protocol-port 80 c14-stu${NN}-amp

預期輸出:

預期輸出
Load Balancer 29c0dc3b-1147-4e6c-9ace-241f192dbb1f is immutable and cannot be updated. (HTTP 409) (Request-ID: req-c69cc884-…)

PENDING_* 期間物件是鎖住的,任何寫入都回 409(p.13、29)。這不是錯誤,等它變成 ACTIVE 就好。現在先去做 B。


Part B:OVN LB,從零到可用(p.14、19–23)

這一節要從零建出下面這個結構,每個元件右上角標的是建立它的步驟:

Part B 的 OVN LB 結構 Part B 建立的 OVN LB。B1 建立 Load Balancer c14-stuNN-ovn,VIP 192.168.14.127,沒有 VM,只是 OVN Northbound DB Load_Balancer 表的一列;B2 建立 TCP:80 的 Listener(HTTP 被拒);B3 建立 SOURCE_IP_PORT 的 Pool(ROUND_ROBIN 被拒);B4 加入 member web1、web2 與 TCP Health Monitor;B5 建立 Floating IP 綁到 VIP port,jmp001 經 NAT 連到 VIP。 Bn = 建立這個元件的步驟(本 Part 依序 B1 → B5) jmp001 curl http://FIP/ Floating IP 192.168.100.129 B5 Load Balancer c14-stuNN-ovn VIP 192.168.14.127 沒有 VM:只是 OVN NB Load_Balancer 表的一列 B1 Listener …-ovn-l80 TCP :80 HTTP 被拒(501) B2 Pool …-ovn-pool SOURCE_IP_PORT ROUND_ROBIN 被拒 B3 Member web1 192.168.14.25:80 B4 Member web2 192.168.14.81:80 B4 Health Monitor TCP 每 5s・逾時 3s B4 探測 流量:jmp001 → FIP → VIP → Listener → Pool → Member。Listener、Pool、Member 在 OVN 裡都寫進同一列 Load_Balancer;IP 為試跑時的示意值
Part B 的 OVN LB 結構:B1 Load Balancer、B2 Listener、B3 Pool、B4 Member 與 Health Monitor、B5 Floating IP

B1. Load Balancer

指令
# [jmp001]
time openstack loadbalancer create --name c14-stu${NN}-ovn --provider ovn \
  --vip-subnet-id c14-subnet --wait -f yaml \
  -c id -c provider -c vip_address -c vip_port_id -c provisioning_status -c operating_status

預期輸出:

預期輸出
id: 6a33c7e8-82e3-4508-b5d2-6461768ba4b6
operating_status: ONLINE
provider: ovn
provisioning_status: ACTIVE
vip_address: 192.168.14.127
vip_port_id: 324d6aa8-180b-4d2f-be09-f4aff5d68c07

real	0m6.463s

同樣是 loadbalancer create,加了 --wait 也只要幾秒:OVN provider 不開 VM,只把 LB 寫進 OVN Northbound DB 的 Load_Balancer 表(p.19)。

B2. Listener:OVN 只做 L4

先試 HTTP:

指令
# [jmp001]
openstack loadbalancer listener create --name test --protocol HTTP --protocol-port 80 c14-stu${NN}-ovn

預期輸出:

預期輸出
Provider 'ovn' does not support a requested option: OVN provider does not support HTTP protocol (HTTP 501) (Request-ID: req-…)

OVN 的分流發生在 L4,不解析 HTTP,所以 HTTP listener 在 API 層就被拒絕,不是建好了不生效(p.21)。改用 TCP:

指令
# [jmp001]
openstack loadbalancer listener create --name c14-stu${NN}-ovn-l80 \
  --protocol TCP --protocol-port 80 --wait c14-stu${NN}-ovn -f value -c id

預期輸出:

預期輸出
5c3dc5a1-374f-4615-82cb-fe50b77539fc

B3. Pool:OVN 只有一種演算法

指令
# [jmp001]
openstack loadbalancer pool create --name test --listener c14-stu${NN}-ovn-l80 \
  --protocol TCP --lb-algorithm ROUND_ROBIN
openstack loadbalancer pool create --name c14-stu${NN}-ovn-pool --listener c14-stu${NN}-ovn-l80 \
  --protocol TCP --lb-algorithm SOURCE_IP_PORT --wait -f value -c id

預期輸出:

預期輸出
Provider 'ovn' does not support a requested option: OVN provider does not support ROUND_ROBIN algorithm (HTTP 501) (Request-ID: req-…)
8d37643b-2df7-4e5a-8d01-d81fd334e6e5

OVN 只支援 SOURCE_IP_PORT:依「來源 IP + 來源 port」雜湊選後端;Amphora 則剛好相反,不支援這一種(p.12、21)。

這時候到 OVN 看一眼:

指令
# [jmp001]
export OVN_LB=$(openstack loadbalancer show c14-stu${NN}-ovn -f value -c id)
ssh 10.127.0.4 "sudo docker exec ovn_nb_db ovn-nbctl --columns=name,protocol,vips find Load_Balancer name=$OVN_LB"

預期輸出:

預期輸出
name                : "6a33c7e8-82e3-4508-b5d2-6461768ba4b6"
protocol            : tcp
vips                : {}

name 就是 Octavia 的 LB ID。vips 是空的:還沒有任何 member,OVN 不知道要轉給誰。這個狀態常被誤以為沒建成功(p.20)。

B4. Member 與 Health Monitor

指令
# [jmp001]
openstack loadbalancer member create --name web1 --address $WEB1 --protocol-port 80 \
  --subnet-id c14-subnet --wait c14-stu${NN}-ovn-pool -f value -c id
openstack loadbalancer member create --name web2 --address $WEB2 --protocol-port 80 \
  --subnet-id c14-subnet --wait c14-stu${NN}-ovn-pool -f value -c id
openstack loadbalancer healthmonitor create --name c14-stu${NN}-ovn-hm --type TCP \
  --delay 5 --timeout 3 --max-retries 2 --wait c14-stu${NN}-ovn-pool -f value -c id

再看一次 OVN:

指令
# [jmp001]
ssh 10.127.0.4 "sudo docker exec ovn_nb_db ovn-nbctl --columns=vips,health_check,ip_port_mappings find Load_Balancer name=$OVN_LB"
openstack port list --network c14-net --long -c Name -c "Device Owner" -c "Fixed IP Addresses" | grep ovn-lb

預期輸出:

預期輸出
vips                : {"192.168.14.127:80"="192.168.14.25:80,192.168.14.81:80"}
health_check        : [17cc0f78-540e-4e50-a651-231ccce7cfd5]
ip_port_mappings    : {"192.168.14.25"="2c159695-9718-42d9-aecb-d3cfcba2e227:192.168.14.83", "192.168.14.81"="e9a20d9d-6ed8-48c2-a4b8-734ec998482e:192.168.14.83"}
| ovn-lb-vip-6a33c7e8-82e3-4508-b5d2-6461768ba4b6      | ovn-lb:vip               | ip_address='192.168.14.127', subnet_id='4bd48b64-4d62-4ea3-8e98-28bfdd49ffce' |
| ovn-lb-hm-4bd48b64-4d62-4ea3-8e98-28bfdd49ffce       | ovn-lb-hm:distributed    | ip_address='192.168.14.83', subnet_id='4bd48b64-4d62-4ea3-8e98-28bfdd49ffce'  |

怎麼讀這段輸出

輸出意思
vips真正生效的那一欄,格式是 VIP:port = member:port,…。加了 member 才有值
health_check指向另一張表 Load_Balancer_Health_Check 的一列,裡面是 delay / timeout 等設定
ip_port_mappings每個 member 對應「它的 Logical Switch Port : 探測來源 IP」。探測來源就是下一行的 ovn-lb-hm-… port
ovn-lb-vip-…VIP 的 Neutron Port,device_owner 是 ovn-lb:vip
ovn-lb-hm-<subnet_id>健康檢查專用的 Port,每個 member 子網一個,全班共用。member 的 SG 要放行來自它的流量(p.25),c14-sg 已放行 TCP 80

Listener、Pool、Member 在 OVN 裡都不是獨立的列,而是這一列 external_ids 裡的 key。想看完整內容可以把 --columns=… 拿掉,改用 ovn-nbctl list Load_Balancer $OVN_LB。

B5. 綁 Floating IP 並測試

指令
# [jmp001]
export OVN_FIP=$(openstack floating ip create public1 --description c14-stu${NN}-ovn \
  --port $(openstack loadbalancer show c14-stu${NN}-ovn -f value -c vip_port_id) \
  -f value -c floating_ip_address)
echo $OVN_FIP
for i in 1 2 3 4 5 6; do curl -s -m 3 http://$OVN_FIP/; done

預期輸出:

預期輸出
192.168.100.129
web1
web2
web1
web1
web1
web2

做到這裡,回頭看 Amphora LB 好了沒。


Part C:Amphora LB(p.16–18、12–13)

Load Balancer 和 amphora 在 Part A 就送出了,C1–C3 先檢查它們,C4 起才在上面加元件。完成後的結構如下(虛線框是 Part D 才加的):

Part C 的 Amphora LB 結構 Part C 完成的 Amphora LB。Load Balancer c14-stuNN-amp 在 Part A 建立(VIP 192.168.14.108),同時自動開出一台 amphora VM 執行 HAProxy;C1–C3 只檢查狀態、amphora、VIP port 與 VRRP port。C4 建立 HTTP:80 的 Listener、ROUND_ROBIN 的 Pool 與 member web1、web2;C5 建立 HTTP Health Monitor;C6 建立 Floating IP 綁到 VIP port。Part D1 再在 Listener 上加 L7 Policy,/admin 回 403。 Cn = 建立這個元件的步驟(本 Part 依序 C4 → C6,LB 已在 Part A 建立) jmp001 curl http://FIP/ Floating IP 192.168.100.171 C6 Load Balancer c14-stuNN-amp VIP 192.168.14.108 A amphora VM HAProxy・STANDALONE A 自動 C1–C3 只做檢查:狀態、amphora、 VIP port 與 VRRP port Listener …-amp-l80 HTTP :80 每步約 20–45 秒 C4 Pool …-amp-pool ROUND_ROBIN 嚴格輪流 C4 Member web1 192.168.14.25:80 C4 Member web2 192.168.14.81:80 C4 Health Monitor HTTP GET / 每 5s C5 探測 L7 Policy /admin → 403 D1 流量:jmp001 → FIP → VIP(在 amphora 的 VRRP port 上)→ HAProxy → Member。虛線框是 Part D 才加的元件;IP 為試跑時的示意值
Part C 的 Amphora LB 結構:A Load Balancer 與 amphora、C4 Listener / Pool / Member、C5 Health Monitor、C6 Floating IP、D1 L7 Policy

C1. 確認建好了

指令
# [jmp001]
date +%T
openstack loadbalancer show c14-stu${NN}-amp -f yaml \
  -c provider -c vip_address -c vip_port_id -c provisioning_status -c operating_status -c created_at -c updated_at

預期輸出:

預期輸出
18:14:27
created_at: '2026-11-07T10:07:32'
operating_status: ONLINE
provider: amphora
provisioning_status: ACTIVE
updated_at: '2026-11-07T10:12:14'
vip_address: 192.168.14.108
vip_port_id: 646572d9-187c-47ae-b8f5-cb428d41a529

試跑時每 5 秒記錄一次狀態,可以看到時間花在哪裡:

經過LBamphoraNova VM正在發生什麼
0:00PENDING_CREATEPENDING_CREATE—worker 建 VIP port、準備開 VM
0:19PENDING_CREATEBOOTINGBUILDNova 排程、建 VM
0:46PENDING_CREATEBOOTINGACTIVEVM 在開機:Nova 已經是 ACTIVE,但 amphora 裡的系統還沒起來
4:19PENDING_CREATEALLOCATEDACTIVEamphora-agent 在 9443 回應了,worker 開始下發設定
4:54ACTIVEALLOCATEDACTIVE完成

大部分時間都花在 VM 開機:本環境是巢狀虛擬化,amphora 開機約 3.5 分鐘。

C2. 撐住這個 LB 的 amphora

指令
# [jmp001]
openstack loadbalancer amphora list --loadbalancer c14-stu${NN}-amp
export AMP=$(openstack loadbalancer amphora list --loadbalancer c14-stu${NN}-amp -f value -c id)
openstack loadbalancer amphora show $AMP -f yaml \
  -c role -c status -c lb_network_ip -c vrrp_ip -c ha_ip -c vrrp_port_id -c ha_port_id -c compute_id -c cert_expiration

預期輸出:

預期輸出
+--------------------------------------+--------------------------------------+-----------+------------+---------------+----------------+
| id                                   | loadbalancer_id                      | status    | role       | lb_network_ip | ha_ip          |
+--------------------------------------+--------------------------------------+-----------+------------+---------------+----------------+
| 278409b4-4417-4a06-802e-9cc5e3cbf029 | 29c0dc3b-1147-4e6c-9ace-241f192dbb1f | ALLOCATED | STANDALONE | 172.16.0.126  | 192.168.14.108 |
+--------------------------------------+--------------------------------------+-----------+------------+---------------+----------------+
compute_id: d19d194d-d4e7-4f5f-b6b7-1a7c061e8237
lb_network_ip: 172.16.0.126
vrrp_ip: 192.168.14.202
ha_ip: 192.168.14.108
vrrp_port_id: 3f302b32-18bb-4d80-9456-bee893829aed
ha_port_id: 646572d9-187c-47ae-b8f5-cb428d41a529
cert_expiration: '2026-12-07T10:07:36'
role: STANDALONE
status: ALLOCATED
欄位意思
role: STANDALONE只有一台 amphora,拓樸是 SINGLE(本環境預設)。ACTIVE_STANDBY 會有 MASTER、BACKUP 兩台(p.20)
lb_network_ipamphora 在管理網 lb-mgmt-net 上的位址。控制節點從這裡用 HTTPS 9443 下發設定,amphora 從這裡用 UDP 5555 送心跳(p.18)
vrrp_ipamphora 在 c14-subnet 上實際插著的網卡的位址
ha_ip就是 VIP
compute_idamphora 是一台真的 Nova VM,這是它的 server ID
cert_expiration控制平面與 amphora 之間的憑證到期時間,可以拿來做監控(p.31)

C3. VIP 的兩個 Port

指令
# [jmp001]
openstack port list --network c14-net --long -c Name -c "Fixed IP Addresses" -c Status | grep octavia
openstack port show $(openstack loadbalancer show c14-stu${NN}-amp -f value -c vip_port_id) \
  -c name -c device_owner -c admin_state_up -c status -f yaml
openstack port show $(openstack loadbalancer amphora show $AMP -f value -c vrrp_port_id) \
  -c name -c allowed_address_pairs -c status -f yaml

預期輸出:

預期輸出
| octavia-lb-vrrp-278409b4-4417-4a06-802e-9cc5e3cbf029 | ip_address='192.168.14.202', subnet_id='4bd48b64-4d62-4ea3-8e98-28bfdd49ffce' | ACTIVE |
| octavia-lb-29c0dc3b-1147-4e6c-9ace-241f192dbb1f      | ip_address='192.168.14.108', subnet_id='4bd48b64-4d62-4ea3-8e98-28bfdd49ffce' | DOWN   |
admin_state_up: false
device_owner: Octavia
name: octavia-lb-29c0dc3b-1147-4e6c-9ace-241f192dbb1f
status: DOWN
allowed_address_pairs:
- ip_address: 192.168.14.108
  mac_address: fa:16:3e:96:ed:c7
name: octavia-lb-vrrp-278409b4-4417-4a06-802e-9cc5e3cbf029
status: ACTIVE
Port作用
octavia-lb-<lb_id>(VIP port)只負責佔住 VIP 位址,不讓別人配走。admin_state_up: false、DOWN,流量不走它
octavia-lb-vrrp-<amphora_id>(VRRP port)真的插在 amphora 上。VIP 被加進它的 allowed_address_pairs,Neutron 才允許 VIP 從這個 port 送出

排查流量要看 VRRP port,看位址保留才看 VIP port(p.19)。對照 B4:OVN 的 VIP port(ovn-lb-vip-…)只有一個,因為沒有 VM。

C4. Listener、Pool、Member:每一步都要等 amphora

指令
# [jmp001]
time openstack loadbalancer listener create --name c14-stu${NN}-amp-l80 \
  --protocol HTTP --protocol-port 80 --wait c14-stu${NN}-amp -f value -c id
openstack loadbalancer pool create --name c14-stu${NN}-amp-pool --listener c14-stu${NN}-amp-l80 \
  --protocol HTTP --lb-algorithm ROUND_ROBIN --wait -f value -c id
openstack loadbalancer member create --name web1 --address $WEB1 --protocol-port 80 \
  --subnet-id c14-subnet --wait c14-stu${NN}-amp-pool -f value -c id
openstack loadbalancer member create --name web2 --address $WEB2 --protocol-port 80 \
  --subnet-id c14-subnet --wait c14-stu${NN}-amp-pool -f value -c id
openstack loadbalancer member list c14-stu${NN}-amp-pool -c name -c address -c provisioning_status -c operating_status

預期輸出:

預期輸出
ff07a18f-1f57-48a2-b131-aa4594b375f2

real	0m44.007s
dd91a6cd-b49a-48ce-8d1a-5d566917d48f
09b128f1-be99-4288-bc1b-b84f031c7dc7
4a4b65b1-a13e-4997-9329-93c9e99726fe
+------+---------------------+---------------+------------------+
| name | provisioning_status | address       | operating_status |
+------+---------------------+---------------+------------------+
| web1 | ACTIVE              | 192.168.14.25 | NO_MONITOR       |
| web2 | ACTIVE              | 192.168.14.81 | NO_MONITOR       |
+------+---------------------+---------------+------------------+

C5. Health Monitor:從 NO_MONITOR 到 ONLINE

指令
# [jmp001]
openstack loadbalancer healthmonitor create --name c14-stu${NN}-amp-hm --type HTTP \
  --delay 5 --timeout 3 --max-retries 2 --url-path / --wait c14-stu${NN}-amp-pool -f value -c id
sleep 10
openstack loadbalancer member list c14-stu${NN}-amp-pool -c name -c operating_status

預期輸出:

預期輸出
d698a89c-05eb-4d91-b832-d402fba85c11
+------+------------------+
| name | operating_status |
+------+------------------+
| web1 | ONLINE           |
| web2 | ONLINE           |
+------+------------------+

C6. 綁 Floating IP 並測試

指令
# [jmp001]
export AMP_FIP=$(openstack floating ip create public1 --description c14-stu${NN}-amp \
  --port $(openstack loadbalancer show c14-stu${NN}-amp -f value -c vip_port_id) \
  -f value -c floating_ip_address)
echo $AMP_FIP
for i in 1 2 3 4 5 6; do curl -s -m 3 http://$AMP_FIP/; done

預期輸出:

預期輸出
192.168.100.171
web1
web2
web1
web2
web1
web2

和 B5 對照:ROUND_ROBIN 是嚴格輪流。FIP 綁在 VIP port 上,流量經 NAT 送到 VIP,再由 amphora 裡的 HAProxy 轉給 member。


Part D:只有 Amphora 做得到的事(p.11、23–24)

D1. L7 Policy:擋掉 /admin

指令
# [jmp001]
openstack loadbalancer l7policy create --name c14-stu${NN}-amp-deny-admin \
  --action REJECT --position 1 --wait c14-stu${NN}-amp-l80 -f value -c id
openstack loadbalancer l7rule create --type PATH --compare-type STARTS_WITH \
  --value /admin --wait c14-stu${NN}-amp-deny-admin -f value -c id
curl -s -o /dev/null -w "/admin/x -> %{http_code}\n" http://$AMP_FIP/admin/x
curl -s -w " <- / %{http_code}\n" http://$AMP_FIP/

預期輸出:

預期輸出
9e3909d7-cb1f-4fdc-ad7d-006b68739d9a
bf2c818c-fdca-43dd-9e17-80d4790230bc
/admin/x -> 403
web1
 <- / 200

同樣的事在 OVN LB 上做:

指令
# [jmp001]
openstack loadbalancer l7policy create --action REJECT c14-stu${NN}-ovn-l80

預期輸出:

預期輸出
Provider 'ovn' does not support a requested action: This provider does not support creating l7policies. (HTTP 501) (Request-ID: req-…)

要看到路徑才能決定怎麼分流,OVN 只看 L4,所以完全不支援 L7(p.21)。

D2. 統計

指令
# [jmp001]
openstack loadbalancer stats show c14-stu${NN}-amp
openstack loadbalancer stats show c14-stu${NN}-ovn

預期輸出:

預期輸出
+--------------------+-------+
| Field              | Value |
+--------------------+-------+
| active_connections | 0     |
| bytes_in           | 810   |
| bytes_out          | 1840  |
| request_errors     | 0     |
| total_connections  | 10    |
+--------------------+-------+
+--------------------+-------+
| Field              | Value |
+--------------------+-------+
| active_connections | 0     |
| bytes_in           | 0     |
| bytes_out          | 0     |
| request_errors     | 0     |
| total_connections  | 0     |
+--------------------+-------+

Part E:兩個狀態欄位(p.13、28–29)

把 web2 從 Amphora LB 的 pool 停用:

指令
# [jmp001]
openstack loadbalancer member set --disable --wait c14-stu${NN}-amp-pool web2
openstack loadbalancer member show c14-stu${NN}-amp-pool web2 -c admin_state_up -c provisioning_status -c operating_status
openstack loadbalancer status show c14-stu${NN}-amp
for i in 1 2 3 4; do curl -s -m 3 http://$AMP_FIP/; done

預期輸出(status show 節錄 pool 以下):

預期輸出
+---------------------+---------+
| Field               | Value   |
+---------------------+---------+
| admin_state_up      | False   |
| operating_status    | OFFLINE |
| provisioning_status | ACTIVE  |
+---------------------+---------+
…
                "pools": [
                    {
                        "id": "dd91a6cd-b49a-48ce-8d1a-5d566917d48f",
                        "name": "c14-stu99-amp-pool",
                        "provisioning_status": "ACTIVE",
                        "operating_status": "ONLINE",
                        …
                        "members": [
                            {
                                "id": "09b128f1-be99-4288-bc1b-b84f031c7dc7",
                                "name": "web1",
                                "operating_status": "ONLINE",
                                "provisioning_status": "ACTIVE",
                                …
                            },
                            {
                                "id": "4a4b65b1-a13e-4997-9329-93c9e99726fe",
                                "name": "web2",
                                "operating_status": "OFFLINE",
                                "provisioning_status": "ACTIVE",
                                …
web1
web1
web1
web1

兩個狀態欄位各說了什麼

欄位web2 的值意思
admin_state_upFalse你剛才的 --disable:管理性停用
provisioning_statusACTIVE控制平面做完了:這次設定變更已經推進 amphora 並生效
operating_statusOFFLINE流量面:被管理性停用,不接新連線(p.13)。注意它不是 ERROR:web2 本身沒壞

恢復:

指令
# [jmp001]
openstack loadbalancer member set --enable --wait c14-stu${NN}-amp-pool web2
sleep 10
for i in 1 2 3 4; do curl -s -m 3 http://$AMP_FIP/; done

預期輸出:

預期輸出
web1
web2
web1
web2

Part F:清除

指令
# [jmp001]
openstack floating ip delete $AMP_FIP $OVN_FIP
openstack loadbalancer delete --cascade --wait c14-stu${NN}-ovn
openstack loadbalancer delete --cascade --wait c14-stu${NN}-amp
openstack loadbalancer list --name c14-stu${NN}-amp
openstack loadbalancer list --name c14-stu${NN}-ovn
sleep 30
openstack server list --all-projects --name amphora- -c Name -c Status

預期輸出:(兩個 loadbalancer list 沒有輸出;amphora 清單裡沒有你在 C2 看到的 amphora-<AMP>)

預期輸出
+----------------------------------------------+--------+
| Name                                         | Status |
+----------------------------------------------+--------+
| amphora-492313f3-1ba5-4235-a674-0226f257a3d1 | ACTIVE |
+----------------------------------------------+--------+

小結

AmphoraOVN
建立 LB約 5 分鐘(開一台 VM)約 6 秒(寫一列資料)
每次修改設定20–45 秒(推設定進 amphora)約 4 秒
Listener 協定HTTP 可以(也可 TCP、HTTPS、UDP…)HTTP 被拒絕,只有 TCP / UDP / SCTP
演算法ROUND_ROBIN:嚴格輪流只有 SOURCE_IP_PORT:依雜湊
Health MonitorHTTP(看回應碼)TCP(只看連得上)
L7 Policy可以,/admin 回 403501 不支援
統計有全部是 0
VIP 的 Neutron PortVIP port + 每台 amphora 一個 VRRP port一個 ovn-lb-vip-… + 子網共用的 ovn-lb-hm-…
資料面在哪裡看amphora list / showovn-nbctl … Load_Balancer

講師補充(不必操作):試跑時對 OVN LB 執行 member set --weight 5,指令成功、member show 也顯示 5,但 OVN 的 vips 欄位沒有權重的概念,設定不會生效,而且那個 member 的 operating_status 之後一直停在 NO_MONITOR。投影片 p.24 說 OVN「不支援」weight,實際行為是「API 接受、資料面忽略」,所以不要只看 API 有沒有報錯。