SiamCafe.net Blog
Technology

IS-IS Protocol Progressive Delivery

is is protocol progressive delivery
IS-IS Protocol Progressive Delivery | SiamCafe Blog
2025-08-24· อ. บอม — SiamCafe.net· 1,456 คำ

IS-IS Protocol Progressive Delivery คืออะไร

IS-IS (Intermediate System to Intermediate System) เป็น link-state routing protocol ที่ใช้ใน large-scale networks โดยเฉพาะ ISP และ data center networks IS-IS ทำงานบน Layer 2 (ไม่ใช่ IP) ทำให้รองรับทั้ง IPv4 และ IPv6 ได้อย่างดี Progressive Delivery คือแนวทาง deploy changes ทีละขั้น ตั้งแต่ canary, blue-green ไปจนถึง full rollout การรวม IS-IS Protocol กับ Progressive Delivery ช่วยให้ network engineers อัพเดท routing configurations อย่างปลอดภัย ทดสอบ changes กับ traffic ส่วันนี้อยก่อน และ rollback ได้เร็วเมื่อมีปัญหา

IS-IS Protocol Fundamentals

# isis_basics.py — IS-IS protocol fundamentals
import json

class ISISBasics:
    FEATURES = {
        "link_state": {
            "name": "Link-State Protocol",
            "description": "แต่ละ router รู้ topology ทั้งหมดของ network — สร้าง shortest path tree",
            "algorithm": "Dijkstra's SPF (Shortest Path First) algorithm",
        },
        "layer2": {
            "name": "Layer 2 Operation",
            "description": "IS-IS ทำงานบน Layer 2 (CLNS) — ไม่ต้องพึ่ง IP",
            "benefit": "รองรับ IPv4 + IPv6 + อื่นๆ ในตัว — ไม่ต้อง separate protocol",
        },
        "hierarchical": {
            "name": "Two-Level Hierarchy",
            "description": "Level 1 (intra-area) + Level 2 (inter-area) — scalable",
            "benefit": "ลด LSP flooding — Level 1 routers ไม่ต้องรู้ Level 2 topology",
        },
        "tlv_extensible": {
            "name": "TLV-Based (Extensible)",
            "description": "ใช้ Type-Length-Value encoding — เพิ่ม features ใหม่ได้ง่าย",
            "benefit": "เพิ่ม Segment Routing, IPv6, Traffic Engineering ผ่าน TLVs",
        },
        "fast_convergence": {
            "name": "Fast Convergence",
            "description": "BFD + fast hellos + incremental SPF — convergence < 1 second",
            "benefit": "Network กู้คืนเร็วเมื่อ link fail",
        },
    }

    COMPARISON = {
        "isis_vs_ospf": {
            "isis": "Layer 2, TLV-extensible, two-level hierarchy, ISP-preferred",
            "ospf": "Layer 3 (IP), fixed format, multi-area, enterprise-preferred",
            "when_isis": "Large ISP networks, data centers, SR-MPLS, multi-protocol",
            "when_ospf": "Enterprise networks, smaller scale, familiar to most engineers",
        },
    }

    def show_features(self):
        print("=== IS-IS Features ===\n")
        for key, feat in self.FEATURES.items():
            print(f"[{feat['name']}]")
            print(f"  {feat['description']}")
            print()

    def show_comparison(self):
        print("=== IS-IS vs OSPF ===")
        comp = self.COMPARISON['isis_vs_ospf']
        print(f"  IS-IS: {comp['isis']}")
        print(f"  OSPF: {comp['ospf']}")

basics = ISISBasics()
basics.show_features()
basics.show_comparison()

Progressive Delivery for Network Changes

# progressive.py — Progressive delivery for network changes
import json

class ProgressiveDelivery:
    STRATEGIES = {
        "canary_routing": {
            "name": "Canary Routing",
            "description": "Deploy routing change ไป 1-2 routers ก่อน — monitor ก่อน rollout",
            "steps": [
                "1. เลือก canary router (non-critical path)",
                "2. Apply IS-IS config change",
                "3. Monitor 1-4 ชั่วโมง: adjacency, SPF runs, traffic, errors",
                "4. ถ้า OK → rollout ไป next batch",
                "5. ถ้ามีปัญหา → rollback canary router ทันที",
            ],
        },
        "rolling_update": {
            "name": "Rolling Update",
            "description": "Update routers ทีละ batch — ไม่ update ทั้งหมดพร้อมกัน",
            "steps": [
                "1. แบ่ง routers เป็น batches (5-10 routers per batch)",
                "2. Update batch 1 → monitor → confirm OK",
                "3. Update batch 2 → monitor → confirm OK",
                "4. ทำจนครบทุก batch",
                "5. ถ้า batch ไหนมีปัญหา → หยุด + rollback batch นั้น",
            ],
        },
        "blue_green_network": {
            "name": "Blue-Green Network Paths",
            "description": "สร้าง 2 paths (blue/green) → สลับ traffic ด้วย IS-IS metric",
            "steps": [
                "1. Blue path: ใช้ IS-IS metric ต่ำ (preferred) — production traffic",
                "2. Green path: ใช้ IS-IS metric สูง (backup) — apply new config",
                "3. ทดสอบ green path: ส่ง test traffic",
                "4. Switch: ลด green metric, เพิ่ม blue metric → traffic ย้ายไป green",
                "5. Rollback: สลับ metrics กลับ → traffic กลับ blue ทันที",
            ],
        },
    }

    def show_strategies(self):
        print("=== Progressive Delivery Strategies ===\n")
        for key, s in self.STRATEGIES.items():
            print(f"[{s['name']}]")
            print(f"  {s['description']}")
            for step in s['steps'][:3]:
                print(f"    {step}")
            print()

pd = ProgressiveDelivery()
pd.show_strategies()

Python Network Automation

# automation.py — Python IS-IS automation tools
import json

class ISISAutomation:
    CODE = """
# isis_deployer.py — Progressive IS-IS deployment automation
import json
import time
from datetime import datetime
from dataclasses import dataclass
from typing import List, Dict

@dataclass
class Router:
    hostname: str
    ip: str
    role: str  # core, distribution, access
    isis_level: str  # L1, L2, L1L2
    batch: int = 0

class ISISDeployer:
    def __init__(self, routers: List[Router]):
        self.routers = routers
        self.deployment_log = []
        self.rollback_configs = {}
    
    def plan_batches(self, batch_size=5):
        '''Plan deployment batches — core routers last'''
        # Sort: access first, core last
        priority = {'access': 0, 'distribution': 1, 'core': 2}
        sorted_routers = sorted(self.routers, key=lambda r: priority.get(r.role, 1))
        
        for i, router in enumerate(sorted_routers):
            router.batch = i // batch_size
        
        batches = {}
        for r in sorted_routers:
            batches.setdefault(r.batch, []).append(r)
        
        return batches
    
    def backup_config(self, router):
        '''Backup current config before change'''
        # In production: SSH to router, get running config
        config = f"# Backup of {router.hostname} at {datetime.utcnow().isoformat()}"
        self.rollback_configs[router.hostname] = config
        return True
    
    def apply_config(self, router, config_template):
        '''Apply IS-IS config change to router'''
        self.backup_config(router)
        
        # In production: SSH/NETCONF to apply config
        self.deployment_log.append({
            'timestamp': datetime.utcnow().isoformat(),
            'router': router.hostname,
            'action': 'apply',
            'status': 'success',
        })
        
        return {'status': 'applied', 'router': router.hostname}
    
    def verify_health(self, router):
        '''Verify IS-IS health after change'''
        # In production: check adjacency, SPF, routes, traffic
        checks = {
            'adjacency_up': True,
            'spf_runs_normal': True,
            'route_count_ok': True,
            'traffic_flowing': True,
            'error_rate_normal': True,
        }
        
        all_healthy = all(checks.values())
        
        self.deployment_log.append({
            'timestamp': datetime.utcnow().isoformat(),
            'router': router.hostname,
            'action': 'verify',
            'healthy': all_healthy,
            'checks': checks,
        })
        
        return {'healthy': all_healthy, 'checks': checks}
    
    def rollback(self, router):
        '''Rollback to previous config'''
        backup = self.rollback_configs.get(router.hostname)
        if not backup:
            return {'status': 'error', 'reason': 'No backup found'}
        
        # In production: SSH/NETCONF to restore config
        self.deployment_log.append({
            'timestamp': datetime.utcnow().isoformat(),
            'router': router.hostname,
            'action': 'rollback',
            'status': 'success',
        })
        
        return {'status': 'rolled_back', 'router': router.hostname}
    
    def deploy_progressive(self, config_template, monitor_minutes=30):
        '''Execute progressive deployment'''
        batches = self.plan_batches()
        results = []
        
        for batch_num in sorted(batches.keys()):
            batch_routers = batches[batch_num]
            print(f"\\n=== Batch {batch_num} ({len(batch_routers)} routers) ===")
            
            batch_ok = True
            for router in batch_routers:
                # Apply
                apply_result = self.apply_config(router, config_template)
                print(f"  Applied: {router.hostname}")
                
                # Wait briefly
                time.sleep(5)
                
                # Verify
                health = self.verify_health(router)
                if not health['healthy']:
                    print(f"  UNHEALTHY: {router.hostname} — rolling back batch")
                    
                    # Rollback entire batch
                    for r in batch_routers:
                        self.rollback(r)
                    
                    batch_ok = False
                    break
            
            if not batch_ok:
                results.append({'batch': batch_num, 'status': 'rolled_back'})
                break
            
            results.append({'batch': batch_num, 'status': 'success',
                           'routers': [r.hostname for r in batch_routers]})
            
            # Monitor period between batches
            if batch_num < max(batches.keys()):
                print(f"  Monitoring for {monitor_minutes} minutes...")
                time.sleep(monitor_minutes * 60)
        
        return results

# routers = [
#     Router("core-1", "10.0.0.1", "core", "L2"),
#     Router("dist-1", "10.0.1.1", "distribution", "L1L2"),
#     Router("access-1", "10.0.2.1", "access", "L1"),
# ]
# deployer = ISISDeployer(routers)
# results = deployer.deploy_progressive("new_isis_config")
"""

    def show_code(self):
        print("=== IS-IS Deployer ===")
        print(self.CODE[:600])

auto = ISISAutomation()
auto.show_code()

IS-IS Configuration Examples

# configs.py — IS-IS configuration examples
import json

class ISISConfigs:
    CISCO_CONFIG = """
! Cisco IOS-XR IS-IS configuration
router isis CORE
 is-type level-2-only
 net 49.0001.0000.0000.0001.00
 address-family ipv4 unicast
  metric-style wide
  segment-routing mpls
  fast-reroute per-prefix
  fast-reroute per-prefix tiebreaker node-protecting index 100
 !
 address-family ipv6 unicast
  metric-style wide
 !
 interface Loopback0
  passive
  address-family ipv4 unicast
   prefix-sid index 1
  !
 !
 interface GigabitEthernet0/0/0/0
  point-to-point
  hello-interval 1
  hello-multiplier 3
  address-family ipv4 unicast
   metric 10
  !
 !
"""

    JUNOS_CONFIG = """
# Juniper Junos IS-IS configuration
protocols {
    isis {
        level 2 {
            wide-metrics-only;
        }
        interface ge-0/0/0.0 {
            point-to-point;
            level 2 metric 10;
            family inet {
                bfd-liveness-detection {
                    minimum-interval 100;
                    multiplier 3;
                }
            }
        }
        interface lo0.0 {
            passive;
        }
    }
}
"""

    def show_cisco(self):
        print("=== Cisco IOS-XR Config ===")
        print(self.CISCO_CONFIG[:400])

    def show_junos(self):
        print("\n=== Juniper Junos Config ===")
        print(self.JUNOS_CONFIG[:400])

configs = ISISConfigs()
configs.show_cisco()
configs.show_junos()

Monitoring & Verification

# monitoring.py — IS-IS monitoring and verification
import json

class ISISMonitoring:
    HEALTH_CHECKS = {
        "adjacency": "IS-IS adjacencies ขึ้นครบ — ไม่มี neighbor down",
        "spf_runs": "SPF computation count ปกติ — ไม่มี excessive recalculations",
        "route_count": "จำนวน routes ใน RIB ปกติ — ไม่หายไป",
        "lsp_errors": "ไม่มี LSP errors หรือ corruptions",
        "traffic_flow": "Traffic ไหลปกติ — ไม่มี black holes หรือ loops",
        "convergence_time": "Convergence time < 1 second (with BFD + fast SPF)",
    }

    METRICS = {
        "adjacency_count": "จำนวน IS-IS adjacencies (up/down)",
        "spf_calculation_count": "จำนวนครั้ง SPF คำนวณใหม่ — spike = instability",
        "lsp_count": "จำนวน LSPs ใน LSDB — เปลี่ยนมาก = topology change",
        "interface_utilization": "Traffic utilization per interface — ดู traffic shift",
        "bfd_sessions": "BFD session status — detect link failures fast",
    }

    TOOLS = {
        "netconf_yang": "NETCONF/YANG: programmatic config + monitoring — structured data",
        "snmp": "SNMP: traditional monitoring — IS-IS MIB for adjacency, routes",
        "streaming_telemetry": "gNMI/streaming telemetry: real-time metrics — push-based",
        "syslog": "Syslog: IS-IS events (adjacency changes, SPF runs) → SIEM",
    }

    def show_checks(self):
        print("=== Health Checks ===\n")
        for check, desc in self.HEALTH_CHECKS.items():
            print(f"  [{check}] {desc}")

    def show_tools(self):
        print(f"\n=== Monitoring Tools ===")
        for tool, desc in self.TOOLS.items():
            print(f"  [{tool}] {desc}")

monitoring = ISISMonitoring()
monitoring.show_checks()
monitoring.show_tools()

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

Q: ทำไมต้อง Progressive Delivery สำหรับ network changes?

A: Network changes มีความเสี่ยงสูง: Config ผิด = network outage ทั้งหมดได้ IS-IS change กระทบ routing → traffic อาจ loop หรือ black hole Progressive Delivery: ลดความเสี่ยงโดย deploy ทีละขั้น → ตรวจจับปัญหาเร็ว → rollback ก่อน outage สถิติ: network changes เป็นสาเหตุ 50-80% ของ network outages

Q: IS-IS กับ OSPF อันไหนดีกว่าสำหรับ data center?

A: IS-IS preferred สำหรับ data center ขนาดใหญ่: TLV extensibility — รองรับ Segment Routing ดีกว่า Single protocol for IPv4+IPv6 — ไม่ต้อง OSPFv2+v3 Flat hierarchy ดีกว่าสำหรับ leaf-spine topology ISP experience: ทีม network ส่วนใหญ่ที่ทำ large-scale ใช้ IS-IS OSPF ก็ใช้ได้: ถ้า team คุ้นเคย OSPF + data center ไม่ใหญ่มาก

Q: Segment Routing กับ IS-IS ทำงานร่วมกันอย่างไร?

A: IS-IS เป็น control plane ที่ distribute segment labels: Prefix-SID: แต่ละ router ได้ unique segment ID — advertise ผ่าน IS-IS TLVs Adjacency-SID: แต่ละ link ได้ segment ID — สำหรับ explicit path SR-MPLS: ใช้ IS-IS distribute labels → MPLS forwarding SRv6: ใช้ IS-IS distribute SRv6 SIDs → IPv6 forwarding IS-IS TLV extensibility ทำให้เพิ่ม SR features ง่าย — ไม่ต้องเปลี่ยน protocol

Q: Rollback network change ทำอย่างไร?

A: Automated: เก็บ config backup ก่อน change → restore ด้วย NETCONF/SSH อัตโนมัติ IS-IS metric: สลับ traffic ด้วย metric change — เร็วกว่า config rollback Commit confirmed: Junos/IOS-XR มี commit confirmed — auto-rollback ถ้าไม่ confirm ภายใน X นาที Best practice: ทุก change ต้องมี rollback plan document + tested ก่อน deploy

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

Proxmox VE Cluster Progressive Deliveryอ่านบทความ → Azure Container Apps Progressive Deliveryอ่านบทความ → CrewAI Multi-Agent Progressive Deliveryอ่านบทความ → CSS Nesting Progressive Deliveryอ่านบทความ → Distributed Tracing Progressive Deliveryอ่านบทความ →

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