SiamCafe.net Blog
Technology

Segment Routing Distributed System — ระบบ Network สำหรับ Data Center Fabric

segment routing distributed system
Segment Routing Distributed System | SiamCafe Blog
2026-02-05· อ. บอม — SiamCafe.net· 10,049 คำ

Segment Routing กับ Distributed System ทำงานร่วมกันอย่างไร

Distributed System ต้องการ network ที่มีความน่าเชื่อถือสูง latency ต่ำ และสามารถ route traffic ไปยังปลายทางที่ถูกต้องได้อย่างรวดเร็ว Segment Routing ตอบโจทย์เหล่านี้ด้วยการลดความซับซ้อนของ control plane กำจัด protocol state ที่ไม่จำเป็นออก และให้ความสามารถ Traffic Engineering ผ่าน source routing

ใน Data Center Fabric ที่รัน distributed system เช่น Kubernetes cluster, Kafka cluster หรือ Cassandra ring การใช้ Segment Routing ช่วยให้ network engineer สามารถกำหนด path ของ traffic ได้ชัดเจน ลด hop count สำหรับ latency-sensitive workload และทำ load balancing ข้าม multiple paths ได้อย่างมีประสิทธิภาพ

SR-MPLS เหมาะสำหรับ Data Center ที่มี MPLS infrastructure อยู่แล้ว ส่วน SRv6 เหมาะสำหรับ Data Center ใหม่ที่ต้องการ Network Programming capability เช่น Service Function Chaining ที่ traffic ต้องผ่าน Firewall, Load Balancer และ DPI ตามลำดับที่กำหนด

สถาปัตยกรรมทั่วไปสำหรับ Distributed System ที่ใช้ Segment Routing ประกอบด้วย Spine-Leaf Fabric, BGP-based Underlay, SR-MPLS หรือ SRv6 Overlay และ SDN Controller ที่จัดการ SR Policy

ออกแบบ Network Topology สำหรับ Distributed System

Spine-Leaf Topology เป็นรูปแบบมาตรฐานสำหรับ Data Center ที่รัน distributed system เพราะให้ predictable latency และ equal-cost paths ระหว่างทุก leaf switch

# network-topology.yaml — Containerlab Topology สำหรับ Distributed System Lab
name: sr-distributed-lab
topology:
  kinds:
    linux:
      image: frrouting/frr:v9.1.0
  nodes:
    # Spine Layer
    spine1:
      kind: linux
      binds:
        - configs/spine1/frr.conf:/etc/frr/frr.conf
        - configs/spine1/daemons:/etc/frr/daemons
    spine2:
      kind: linux
      binds:
        - configs/spine2/frr.conf:/etc/frr/frr.conf
        - configs/spine2/daemons:/etc/frr/daemons
    # Leaf Layer
    leaf1:
      kind: linux
      binds:
        - configs/leaf1/frr.conf:/etc/frr/frr.conf
        - configs/leaf1/daemons:/etc/frr/daemons
    leaf2:
      kind: linux
      binds:
        - configs/leaf2/frr.conf:/etc/frr/frr.conf
        - configs/leaf2/daemons:/etc/frr/daemons
    leaf3:
      kind: linux
      binds:
        - configs/leaf3/frr.conf:/etc/frr/frr.conf
        - configs/leaf3/daemons:/etc/frr/daemons
    leaf4:
      kind: linux
      binds:
        - configs/leaf4/frr.conf:/etc/frr/frr.conf
        - configs/leaf4/daemons:/etc/frr/daemons
    # Compute Nodes (Distributed System Nodes)
    kafka1:
      kind: linux
      image: alpine:latest
    kafka2:
      kind: linux
      image: alpine:latest
    kafka3:
      kind: linux
      image: alpine:latest

  links:
    # Spine-Leaf Full Mesh
    - endpoints: ["spine1:eth1", "leaf1:eth1"]
    - endpoints: ["spine1:eth2", "leaf2:eth1"]
    - endpoints: ["spine1:eth3", "leaf3:eth1"]
    - endpoints: ["spine1:eth4", "leaf4:eth1"]
    - endpoints: ["spine2:eth1", "leaf1:eth2"]
    - endpoints: ["spine2:eth2", "leaf2:eth2"]
    - endpoints: ["spine2:eth3", "leaf3:eth2"]
    - endpoints: ["spine2:eth4", "leaf4:eth2"]
    # Compute Connections
    - endpoints: ["leaf1:eth3", "kafka1:eth1"]
    - endpoints: ["leaf2:eth3", "kafka2:eth1"]
    - endpoints: ["leaf3:eth3", "kafka3:eth1"]

# Deploy lab
# sudo containerlab deploy -t network-topology.yaml

IP Addressing Plan สำหรับ Segment Routing Fabric

# IP Addressing Plan
# =============================================
# Device    | Loopback      | SRGB Range    | Node SID
# =============================================
# spine1    | 10.0.0.1/32   | 16000-23999   | 16001
# spine2    | 10.0.0.2/32   | 16000-23999   | 16002
# leaf1     | 10.0.0.11/32  | 16000-23999   | 16011
# leaf2     | 10.0.0.12/32  | 16000-23999   | 16012
# leaf3     | 10.0.0.13/32  | 16000-23999   | 16013
# leaf4     | 10.0.0.14/32  | 16000-23999   | 16014
# =============================================
#
# P2P Links: 10.1.x.y/31
# spine1-leaf1: 10.1.1.0/31  (spine=.0, leaf=.1)
# spine1-leaf2: 10.1.1.2/31
# spine1-leaf3: 10.1.1.4/31
# spine1-leaf4: 10.1.1.6/31
# spine2-leaf1: 10.1.2.0/31
# spine2-leaf2: 10.1.2.2/31
# spine2-leaf3: 10.1.2.4/31
# spine2-leaf4: 10.1.2.6/31
#
# Server Subnets:
# leaf1: 10.10.1.0/24 (kafka1: 10.10.1.10)
# leaf2: 10.10.2.0/24 (kafka2: 10.10.2.10)
# leaf3: 10.10.3.0/24 (kafka3: 10.10.3.10)

ตั้งค่า SR-MPLS บน FRRouting สำหรับ Data Center Fabric

FRRouting (FRR) เป็น routing suite แบบ open source ที่รองรับ Segment Routing ทั้ง SR-MPLS และ SRv6 ใช้ได้กับ Linux host และ container

# configs/spine1/daemons
zebra=yes
bgpd=no
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=yes
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pathd=yes
pbrd=no
bfdd=yes
fabricd=no
vrrpd=no

# configs/spine1/frr.conf — Spine1 FRRouting Configuration
frr version 9.1
frr defaults datacenter
hostname spine1
!
interface lo
 ip address 10.0.0.1/32
 ip router isis FABRIC
 isis passive
!
interface eth1
 description to-leaf1
 ip address 10.1.1.0/31
 ip router isis FABRIC
 isis network point-to-point
 isis hello-interval 1
 isis hello-multiplier 3
!
interface eth2
 description to-leaf2
 ip address 10.1.1.2/31
 ip router isis FABRIC
 isis network point-to-point
 isis hello-interval 1
 isis hello-multiplier 3
!
interface eth3
 description to-leaf3
 ip address 10.1.1.4/31
 ip router isis FABRIC
 isis network point-to-point
!
interface eth4
 description to-leaf4
 ip address 10.1.1.6/31
 ip router isis FABRIC
 isis network point-to-point
!
router isis FABRIC
 net 49.0001.0100.0000.0001.00
 is-type level-2-only
 metric-style wide
 log-adjacency-changes
 segment-routing on
 segment-routing global-block 16000 23999
 segment-routing node-msd 8
 segment-routing prefix 10.0.0.1/32 index 1
!
! TI-LFA สำหรับ fast reroute
interface eth1
 isis ti-lfa
!
interface eth2
 isis ti-lfa
!
interface eth3
 isis ti-lfa
!
interface eth4
 isis ti-lfa
!

Configuration สำหรับ Leaf Switch

# configs/leaf1/frr.conf — Leaf1 FRRouting Configuration
frr version 9.1
frr defaults datacenter
hostname leaf1
!
interface lo
 ip address 10.0.0.11/32
 ip router isis FABRIC
 isis passive
!
interface eth1
 description to-spine1
 ip address 10.1.1.1/31
 ip router isis FABRIC
 isis network point-to-point
 isis hello-interval 1
 isis hello-multiplier 3
 isis ti-lfa
!
interface eth2
 description to-spine2
 ip address 10.1.2.1/31
 ip router isis FABRIC
 isis network point-to-point
 isis hello-interval 1
 isis hello-multiplier 3
 isis ti-lfa
!
interface eth3
 description to-kafka1
 ip address 10.10.1.1/24
!
router isis FABRIC
 net 49.0001.0100.0000.0011.00
 is-type level-2-only
 metric-style wide
 log-adjacency-changes
 segment-routing on
 segment-routing global-block 16000 23999
 segment-routing node-msd 8
 segment-routing prefix 10.0.0.11/32 index 11
!
ip route 10.10.1.0/24 eth3

# ตรวจสอบ SR-MPLS status
# vtysh -c "show isis segment-routing node"
# vtysh -c "show mpls table"
# vtysh -c "show isis neighbor"

ใช้ SR Policy สำหรับ Traffic Engineering ระหว่าง Cluster

SR Policy ใช้สำหรับกำหนดเส้นทางเฉพาะสำหรับ traffic ที่ต้องการ latency ต่ำหรือ bandwidth สูง เช่น Kafka replication traffic ระหว่าง broker

# SR Policy Configuration ผ่าน FRR pathd
# configs/leaf1/frr.conf — เพิ่ม SR Policy

segment-routing
 traffic-eng
  segment-list SL_LEAF1_TO_LEAF3_VIA_SPINE1
   index 10 mpls label 16001
   index 20 mpls label 16013
  !
  segment-list SL_LEAF1_TO_LEAF3_VIA_SPINE2
   index 10 mpls label 16002
   index 20 mpls label 16013
  !
  policy color 100 endpoint 10.0.0.13
   name KAFKA_REPLICATION_TO_LEAF3
   binding-sid 1100
   candidate-path preference 200 name PRIMARY explicit segment-list SL_LEAF1_TO_LEAF3_VIA_SPINE1
   candidate-path preference 100 name BACKUP explicit segment-list SL_LEAF1_TO_LEAF3_VIA_SPINE2
  !
  policy color 200 endpoint 10.0.0.12
   name LOW_LATENCY_TO_LEAF2
   binding-sid 1200
   candidate-path preference 100 name DIRECT explicit segment-list SL_LEAF1_TO_LEAF2
  !
 !
!

# ตรวจสอบ SR Policy
# vtysh -c "show segment-routing traffic-eng policy"
# Output:
# Policy color 100 endpoint 10.0.0.13
#   Name: KAFKA_REPLICATION_TO_LEAF3
#   Status: Active
#   Binding SID: 1100
#   Candidate Path:
#     Preference 200 (PRIMARY): Active
#       Segment List: 16001 -> 16013

สร้าง script สำหรับจัดการ SR Policy แบบ dynamic

#!/usr/bin/env python3
# sr_policy_manager.py — จัดการ SR Policy สำหรับ Distributed System
import subprocess
import json
import sys

class SRPolicyManager:
    def __init__(self, router_host="localhost"):
        self.router = router_host

    def vtysh(self, commands):
        if isinstance(commands, str):
            commands = [commands]
        cmd_str = "\n".join(commands)
        result = subprocess.run(
            ["vtysh", "-c", cmd_str] if len(commands) == 1 else ["vtysh"],
            input=cmd_str if len(commands) > 1 else None,
            capture_output=True, text=True
        )
        return result.stdout

    def get_isis_database(self):
        output = self.vtysh("show isis database detail")
        return output

    def get_sr_node_info(self):
        output = self.vtysh("show isis segment-routing node")
        return output

    def get_mpls_table(self):
        output = self.vtysh("show mpls table json")
        try:
            return json.loads(output)
        except json.JSONDecodeError:
            return {}

    def get_policy_status(self):
        output = self.vtysh("show segment-routing traffic-eng policy")
        return output

    def create_policy(self, color, endpoint, name, segment_list, binding_sid):
        commands = [
            "configure terminal",
            "segment-routing",
            " traffic-eng",
            f"  segment-list SL_{name}",
        ]
        for idx, (i, label) in enumerate(enumerate(segment_list, 10)):
            commands.append(f"   index {i*10} mpls label {label}")
        commands.extend([
            "  !",
            f"  policy color {color} endpoint {endpoint}",
            f"   name {name}",
            f"   binding-sid {binding_sid}",
            f"   candidate-path preference 100 name PRIMARY explicit segment-list SL_{name}",
            "  !",
            " !",
            "!",
            "end",
        ])
        return self.vtysh(commands)

    def delete_policy(self, color, endpoint):
        commands = [
            "configure terminal",
            "segment-routing",
            " traffic-eng",
            f"  no policy color {color} endpoint {endpoint}",
            " !",
            "!",
            "end",
        ]
        return self.vtysh(commands)

    def health_check(self):
        node_info = self.get_sr_node_info()
        mpls_table = self.get_mpls_table()
        policy_status = self.get_policy_status()

        print("=== SR Health Check ===")
        print(f"\n[Node Info]\n{node_info[:500]}")
        print(f"\n[MPLS Table Entries]: {len(mpls_table) if isinstance(mpls_table, list) else 'N/A'}")
        print(f"\n[Policy Status]\n{policy_status[:500]}")

if __name__ == "__main__":
    mgr = SRPolicyManager()
    if len(sys.argv) > 1 and sys.argv[1] == "health":
        mgr.health_check()
    elif len(sys.argv) > 1 and sys.argv[1] == "create":
        mgr.create_policy(
            color=100, endpoint="10.0.0.13",
            name="TEST_POLICY",
            segment_list=[16001, 16013],
            binding_sid=1100
        )
    else:
        print("Usage: sr_policy_manager.py [health|create]")

ตั้งค่า SRv6 Network Programming สำหรับ Service Chaining

SRv6 ใช้ IPv6 address เป็น Segment Identifier ทำให้สามารถ encode function (เช่น End, End.DT4, End.DX6) ไว้ใน SID ได้ เหมาะสำหรับ Service Function Chaining

# SRv6 Configuration สำหรับ FRRouting
# configs/spine1/frr.conf — SRv6 Section

segment-routing
 srv6
  locators
   locator MAIN
    prefix fc00:0:1::/48 block-len 32 node-len 16 func-bits 16
    behavior usid
   !
  !
 !
!

router isis FABRIC
 segment-routing srv6
  locator MAIN
 !
!

# SRv6 SID Table จะถูกสร้างอัตโนมัติ:
# fc00:0:1::        End (node SID)
# fc00:0:1:1::      End.X (adjacency SID to leaf1)
# fc00:0:1:40::     End.DT4 (decap and lookup in IPv4 table)
# fc00:0:1:41::     End.DT6 (decap and lookup in IPv6 table)

# ตรวจสอบ SRv6 SID Table
# vtysh -c "show segment-routing srv6 sid"
# SID                     Behavior    Context
# fc00:0:1::              End         -
# fc00:0:1:1::            End.X       eth1
# fc00:0:1:40::           End.DT4     default

# Service Function Chaining Example:
# Traffic จาก kafka1 ไป kafka3 ต้องผ่าน:
# 1. Firewall (leaf2)
# 2. DPI (leaf4)
# 3. ถึง kafka3 (leaf3)
#
# SRv6 Segment List:
# [fc00:0:12::, fc00:0:14::, fc00:0:13:40::]
#
# สร้าง SRv6 Policy
# ip -6 route add 10.10.3.0/24 encap seg6 mode encap \
#   segs fc00:0:12::, fc00:0:14::, fc00:0:13:40:: dev eth1

สร้าง Service Chain สำหรับ Distributed System Traffic

#!/bin/bash
# setup_srv6_service_chain.sh — ตั้งค่า SRv6 Service Chain

# Enable SRv6 บน Linux kernel
sysctl -w net.ipv6.conf.all.seg6_enabled=1
sysctl -w net.ipv6.conf.default.seg6_enabled=1
sysctl -w net.ipv6.conf.eth1.seg6_enabled=1

# สร้าง SRv6 Service Chain สำหรับ Kafka Replication Traffic
# Path: leaf1 -> leaf2(firewall) -> leaf3(kafka3)
ip -6 route add fc00:0:13:40::/128 encap seg6 mode encap \
  segs fc00:0:12::, fc00:0:13:40:: dev eth1 \
  table 100

# สร้าง policy routing rule
ip rule add from 10.10.1.0/24 to 10.10.3.0/24 \
  ipproto tcp dport 9092 table 100

# ตรวจสอบ routing table
ip -6 route show table 100
ip rule show

# Monitor SRv6 traffic
tcpdump -i eth1 -n 'ip6 proto 43' -c 10

# ตรวจสอบ SRv6 counters
cat /proc/net/segment_routing/hmac_info
ip -6 route show cache

Monitoring Segment Routing ด้วย Prometheus และ gNMI

ใช้ gNMI (gRPC Network Management Interface) เพื่อเก็บ SR metrics จาก router แล้วส่งไปยัง Prometheus

# gnmi-exporter-config.yaml — gNMI Collector Configuration
subscriptions:
  - name: sr-mpls-counters
    paths:
      - "/network-instances/network-instance[name=default]/segment-routing/sr-mpls"
      - "/network-instances/network-instance[name=default]/mpls/label-blocks"
    mode: sample
    sample-interval: 30s

  - name: isis-adjacency
    paths:
      - "/network-instances/network-instance[name=default]/protocols/protocol[name=ISIS]/isis/interfaces"
      - "/network-instances/network-instance[name=default]/protocols/protocol[name=ISIS]/isis/levels"
    mode: on-change

  - name: interface-counters
    paths:
      - "/interfaces/interface/state/counters"
    mode: sample
    sample-interval: 10s

targets:
  spine1:
    address: 10.0.0.1:57400
    username: admin
    password: admin
    skip-verify: true
  spine2:
    address: 10.0.0.2:57400
    username: admin
    password: admin
    skip-verify: true

outputs:
  prometheus:
    type: prometheus
    listen: ":9273"
    path: "/metrics"
    metric-prefix: "sr_"
    export-timestamps: true

# รัน gnmic collector
# gnmic --config gnmi-exporter-config.yaml subscribe

Prometheus Alert Rules สำหรับ SR monitoring

# sr-prometheus-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: sr-alerts
spec:
  groups:
    - name: segment-routing
      rules:
        - alert: ISISAdjacencyDown
          expr: sr_isis_adjacency_state != 1
          for: 30s
          labels:
            severity: critical
          annotations:
            summary: "ISIS adjacency down on {{ $labels.interface }}"

        - alert: SRPolicyInactive
          expr: sr_te_policy_state != 1
          for: 2m
          labels:
            severity: warning
          annotations:
            summary: "SR Policy {{ $labels.policy_name }} is inactive"

        - alert: HighPacketLoss
          expr: rate(sr_interface_counters_in_discards[5m]) > 100
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "High packet loss on {{ $labels.interface }}"

        - alert: MPLSLabelExhaustion
          expr: (sr_mpls_srgb_size - sr_mpls_srgb_used) / sr_mpls_srgb_size < 0.1
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "MPLS label pool below 10% on {{ $labels.node }}"

FAQ คำถามที่พบบ่อย

Q: FRRouting รองรับ SR-MPLS features อะไรบ้าง?

A: FRR รองรับ IS-IS SR Extensions, Prefix SID, Adjacency SID, TI-LFA, SR Policy ผ่าน pathd, Flex-Algo (experimental) และ SRv6 ผ่าน kernel integration ยังไม่รองรับบาง feature เช่น SR-MPLS OAM และ PCE-initiated SR Policy แต่กำลังพัฒนาอยู่

Q: Segment Routing ช่วยลด latency ของ Distributed System ได้จริงไหม?

A: SR ไม่ได้ลด latency โดยตรงแต่ช่วยให้ engineer กำหนดเส้นทางของ traffic ได้แม่นยำขึ้น เช่นบังคับให้ Kafka replication traffic ใช้เส้นทางที่สั้นที่สุด หรือแยก latency-sensitive traffic ออกจาก bulk transfer traffic นอกจากนี้ TI-LFA ลด convergence time เหลือต่ำกว่า 50ms ทำให้ distributed system ไม่กระทบเมื่อเกิด link failure

Q: ควรใช้ IS-IS หรือ OSPF เป็น IGP สำหรับ Segment Routing?

A: แนะนำ IS-IS เพราะรองรับ SR Extensions ได้ดีกว่า scale ได้ดีกว่าสำหรับ large fabric และเป็น protocol ที่ vendor ส่วนใหญ่ focus พัฒนา SR features ไว้ OSPF ก็รองรับ SR แต่ feature set อาจตามหลัง IS-IS

Q: SRv6 มี overhead เท่าไหร่เมื่อเทียบกับ SR-MPLS?

A: SR-MPLS ใช้ 4 bytes ต่อ label ส่วน SRv6 ใช้ 16 bytes ต่อ segment (IPv6 address) บวก SRH header อีก 8 bytes สำหรับ path ที่มี 3 segments SR-MPLS ใช้ 12 bytes ส่วน SRv6 ใช้ 56 bytes ดังนั้น SRv6 มี overhead สูงกว่า 4-5 เท่า ซึ่งสำคัญสำหรับ packet ขนาดเล็กใน distributed system ที่มี high packet rate

📖 บทความที่เกี่ยวข้อง

Segment Routing Data Pipeline ETLอ่านบทความ → Segment Routing Load Testing Strategyอ่านบทความ → Elixir Ecto Distributed Systemอ่านบทความ → Segment Routing API Gateway Patternอ่านบทความ → Segment Routing Cost Optimization ลดค่าใช้จ่ายอ่านบทความ →

📚 ดูบทความทั้งหมด →