OpenSwitch a Ansible automatizace prakticky (3): konfigurace a testování fabric s Ansible

Minule jsme napojili naši virtuální topologii na Ansible a spustili náš první testovací Playbook. Dnes provodeme automatizovanou konfiguraci L3 fabric a otestujeme síť.

Příprava konfiguračních podkladů

Pro zprovoznění L3 fabric potřebujeme Loopback adresu, IP adresy na jednotlivých spojeních mezi prvky a nastavení BGP (autonomní systémy, peering). V našem Ansible prostředí si vytvoříme jeden YAML soubor, ve kterém všechny tyto požadavky zaznamenáme. Dnes to uděláme ručně, ale připravuji ještě generátor, který by vám s přípravou souboru pomohl (například by automaticky očísloval autonomní systémy apod.).

Prohlédněte si soubor topology.yml, ve kterém to všechno je.

$ cat vars/topology.yml
---
switches:
  leaf1:
    ops_interfaces:
      - name: lo1
      - name: 1
      - name: 2
    ops_ports:
      - name: lo1
        ipv4_address: 192.168.0.1/32
      - name: 1
        ipv4_address: 10.1.0.1/30
      - name: 2
        ipv4_address: 10.2.0.1/30
    ops_vrfs:
      - name: vrf_default
        router_id: 192.168.0.1
        bgp_routers:
          - as_number: 65001
            router_id: 192.168.0.1
            networks: [192.168.0.1/32]
            neighbors:
              - address: 10.1.0.2
                remote_as: 65101
              - address: 10.2.0.2
                remote_as: 65102
  leaf2:
    ops_interfaces:
      - name: lo1
      - name: 1
      - name: 2
    ops_ports:
      - name: lo1
        ipv4_address: 192.168.0.2/32
      - name: 1
        ipv4_address: 10.1.1.1/30
      - name: 2
        ipv4_address: 10.2.1.1/30
    ops_vrfs:
      - name: vrf_default
        bgp_routers:
          - as_number: 65002
            router_id: 192.168.0.2
            networks: [192.168.0.2/32]
            neighbors:
              - address: 10.1.1.2
                remote_as: 65101
              - address: 10.2.1.2
                remote_as: 65102
  leaf3:
    ops_interfaces:
      - name: lo1
      - name: 1
      - name: 2
    ops_ports:
      - name: lo1
        ipv4_address: 192.168.0.3/32
      - name: 1
        ipv4_address: 10.1.2.1/30
      - name: 2
        ipv4_address: 10.2.2.1/30
    ops_vrfs:
      - name: vrf_default
        bgp_routers:
          - as_number: 65003
            router_id: 192.168.0.3
            networks: [192.168.0.3/32]
            neighbors:
              - address: 10.1.2.2
                remote_as: 65101
              - address: 10.2.2.2
                remote_as: 65102
  leaf4:
    ops_interfaces:
      - name: lo1
      - name: 1
      - name: 2
    ops_ports:
      - name: lo1
        ipv4_address: 192.168.0.4/32
      - name: 1
        ipv4_address: 10.1.3.1/30
      - name: 2
        ipv4_address: 10.2.3.1/30
    ops_vrfs:
      - name: vrf_default
        bgp_routers:
          - as_number: 65004
            router_id: 192.168.0.4
            networks: [192.168.0.4/32]
            neighbors:
              - address: 10.1.3.2
                remote_as: 65101
              - address: 10.2.3.2
                remote_as: 65102
  spine1:
    ops_interfaces:
      - name: lo1
      - name: 1
      - name: 2
      - name: 3
      - name: 4
    ops_ports:
      - name: lo1
        ipv4_address: 192.168.1.1/32
      - name: 1
        ipv4_address: 10.1.0.2/30
      - name: 2
        ipv4_address: 10.1.1.2/30
      - name: 3
        ipv4_address: 10.1.2.2/30
      - name: 4
        ipv4_address: 10.1.3.2/30
    ops_vrfs:
      - name: vrf_default
        bgp_routers:
          - as_number: 65101
            router_id: 192.168.1.1
            networks: [192.168.1.1/32]
            neighbors:
              - address: 10.1.0.1
                remote_as: 65001
              - address: 10.1.1.1
                remote_as: 65002
              - address: 10.1.2.1
                remote_as: 65003
              - address: 10.1.3.1
                remote_as: 65004
  spine2:
    ops_interfaces:
      - name: lo1
      - name: 1
      - name: 2
      - name: 3
      - name: 4
    ops_ports:
      - name: lo1
        ipv4_address: 192.168.1.2/32
      - name: 1
        ipv4_address: 10.2.0.2/30
      - name: 2
        ipv4_address: 10.2.1.2/30
      - name: 3
        ipv4_address: 10.2.2.2/30
      - name: 4
        ipv4_address: 10.2.3.2/30
    ops_vrfs:
      - name: vrf_default
        bgp_routers:
          - as_number: 65102
            router_id: 192.168.1.2
            networks: [192.168.1.2/32]
            neighbors:
              - address: 10.2.0.1
                remote_as: 65001
              - address: 10.2.1.1
                remote_as: 65002
              - address: 10.2.2.1
                remote_as: 65003
              - address: 10.2.3.1
                remote_as: 65004

Playbook pro fabric

Ansible umožňuje používat různých úrovní abstrakcí, tedy schopnosti stavět na práci jiných – a to přesně uděláme. Přímo Ansible tým vytvořil moduly pro práci s OpenSwitch, které podporují různé transportní mechanismy (používejme REST, ale dostupné je i bušení přes dávky v CLI nebo SSH) a operace jako je splynutí konfigurační databáze prvku a vašeho kousku. Základní operace tedy máme „zdarma“.

Ansible dále podporuje koncept rolí, což je v jakási možnost združit komplikovanější Playbooky do jediné entity nazvané role, které jen předáte nějaké parametry a ona váz zbaví komplexních detailních operací. Tak například pro základní nastavení prvku potřebujeme přiřadit hostname, povolit fyzické porty, nastavit IP adresy L3 portů a tak podobně. Naštěstí přímo tým OpenSwitch má projek nazvaný ops-ansible a v něm připravilo roli „switch“ a „bgp“. Těm stačí předat co chci nastavit či změnit v nastavení prvku nebo bgp a je to.

Náš Playbook tedy díky tomu není vůbec složitý. Prohlédněte si ho:

$ cat build-fabric.yml
---
- name: Configure hostname and interfaces
  hosts: all
  remote_user: root
  gather_facts: no
  vars_files:
    - vars/topology.yml
    - vars/connections.yml
  vars:
    ops_system_hostname: "{{ inventory_hostname }}"
    ops_interfaces: "{{ switches[inventory_hostname].ops_interfaces }}"
    ops_ports: "{{ switches[inventory_hostname].ops_ports }}"
    ops_config_override: no
    ops_intf_admin_state: up

  pre_tasks:
    - name: Ensure port is routed
      command: "vtysh -c 'config terminal' -c 'interface {{ item.name }}' -c 'routing'"
      with_items: "{{switches[inventory_hostname].ops_interfaces}}"
      when: item.name != "lo1"

    - name: Touch loopback
      command: "vtysh -c 'config terminal' -c 'interface loopback 1'"

  roles:
    - switch

- name: Configure BGP
  hosts: all
  remote_user: root
  gather_facts: no
  vars_files:
    - vars/topology.yml
    - vars/connections.yml
  vars:
    ops_config_override: no
    ops_vrfs: "{{ switches[inventory_hostname].ops_vrfs }}"

  roles:
    - ops-bgp-role

Co v něm děláme? Načteme topologii ze souboru topology.yml. Následně spustíme dvě přípravné úlohy, které šáhnou na porty (to je workaround, protože porty v Dockeru tím jak nebyly fyzické, tak nemají vyplněny všechny „chlívečky“ v knfigurační databázi – u fyzického prvku by to tak nebylo). Pak už jen jednoduše načteme topologické proměnné a provedeme roli switch (ta nastaví hostname, interface, IP adresaci) a pak BGP (ta nastaví BGP a neighbory). Takže vlastně nic složitého, ne? Díky open source práci lidí z Ansible na modulech a lidí z OpenSwitch na rolích žádné složité Jinja2 šablony a operace nad nimi řešit nemusíme.

Spusťte teď Playbook na vybudování našeho fabric.

$ ansible-playbook -i hosts build-fabric.yml

PLAY [Configure hostname and interfaces] ***************************************

TASK [Ensure port is routed] ***************************************************
skipping: [spine1] => (item={u'name': u'lo1'})
skipping: [spine2] => (item={u'name': u'lo1'})
skipping: [leaf2] => (item={u'name': u'lo1'})
skipping: [leaf1] => (item={u'name': u'lo1'})
skipping: [leaf3] => (item={u'name': u'lo1'})
changed: [leaf2] => (item={u'name': 1})
changed: [spine1] => (item={u'name': 1})
changed: [leaf1] => (item={u'name': 1})
changed: [leaf3] => (item={u'name': 1})
changed: [spine2] => (item={u'name': 1})
changed: [leaf3] => (item={u'name': 2})
skipping: [leaf4] => (item={u'name': u'lo1'})
changed: [leaf1] => (item={u'name': 2})
changed: [leaf2] => (item={u'name': 2})
changed: [spine1] => (item={u'name': 2})
changed: [spine2] => (item={u'name': 2})
changed: [spine2] => (item={u'name': 3})
changed: [spine1] => (item={u'name': 3})
changed: [leaf4] => (item={u'name': 1})
changed: [spine2] => (item={u'name': 4})
changed: [spine1] => (item={u'name': 4})
changed: [leaf4] => (item={u'name': 2})

TASK [Touch loopback] **********************************************************
changed: [spine2]
changed: [spine1]
changed: [leaf2]
changed: [leaf1]
changed: [leaf3]
changed: [leaf4]

TASK [switch : print JSON input for this play] *********************************
skipping: [spine1]
skipping: [spine2]
skipping: [leaf1]
skipping: [leaf2]
skipping: [leaf3]
skipping: [leaf4]

TASK [switch : configure the switch] *******************************************
changed: [spine2]
changed: [spine1]
changed: [leaf2]
changed: [leaf3]
changed: [leaf1]
changed: [leaf4]

TASK [switch : result from the switch] *****************************************
skipping: [spine1]
skipping: [spine2]
skipping: [leaf1]
skipping: [leaf2]
skipping: [leaf3]
skipping: [leaf4]

PLAY [Configure BGP] ***********************************************************

TASK [ops-bgp-role : print JSON input for this play] ***************************
skipping: [spine1]
skipping: [spine2]
skipping: [leaf1]
skipping: [leaf2]
skipping: [leaf3]
skipping: [leaf4]

TASK [ops-bgp-role : configure the bgp role] ***********************************
changed: [leaf3]
changed: [spine1]
changed: [spine2]
changed: [leaf1]
changed: [leaf2]
changed: [leaf4]

TASK [ops-bgp-role : result from the switch] ***********************************
skipping: [spine1]
skipping: [spine2]
skipping: [leaf1]
skipping: [leaf2]
skipping: [leaf3]
skipping: [leaf4]

PLAY RECAP *********************************************************************
leaf1                      : ok=4    changed=4    unreachable=0    failed=0
leaf2                      : ok=4    changed=4    unreachable=0    failed=0
leaf3                      : ok=4    changed=4    unreachable=0    failed=0
leaf4                      : ok=4    changed=4    unreachable=0    failed=0
spine1                     : ok=4    changed=4    unreachable=0    failed=0
spine2                     : ok=4    changed=4    unreachable=0    failed=0

Po nějaké minutce je hotovo. Můžeme se připojit do některého z prvků a vše si ověřit.

$ docker exec -ti spine1 vtysh
spine1# show run
Current configuration:
!
hostname spine1
!
!
!
!
router bgp 65101
     bgp router-id 192.168.1.1
     network 192.168.1.1/32
     neighbor 10.1.0.1 remote-as 65001
     neighbor 10.1.1.1 remote-as 65002
     neighbor 10.1.2.1 remote-as 65003
     neighbor 10.1.3.1 remote-as 65004
!
vlan 1
    no shutdown
interface 1
    no shutdown
    ip address 10.1.0.2/30
interface 2
    no shutdown
    ip address 10.1.1.2/30
interface 3
    no shutdown
    ip address 10.1.2.2/30
interface 4
    no shutdown
    ip address 10.1.3.2/30
interface loopback 1
    ip address 192.168.1.1/32

spine1# show bgp neighbors
  name: 10.1.0.1, remote-as: 65001
    state: Established
    tcp_port_number: 179

    statistics:
       bgp_peer_dropped_count: 0
       ...
       bgp_peer_update_in_count: 6
       bgp_peer_update_out_count: 4
       bgp_peer_uptime: 15080

  name: 10.1.1.1, remote-as: 65002
    state: Established
    tcp_port_number: 179

    statistics:
       bgp_peer_dropped_count: 0
       ...
       bgp_peer_update_in_count: 3
       bgp_peer_update_out_count: 3
       bgp_peer_uptime: 15077

  name: 10.1.2.1, remote-as: 65003
    state: Active
    tcp_port_number: 179

    statistics:
       bgp_peer_dropped_count: 0
       bgp_peer_dynamic_cap_in_count: 0
       ...
       bgp_peer_update_in_count: 0
       bgp_peer_update_out_count: 0
       bgp_peer_uptime: 0

  name: 10.1.3.1, remote-as: 65004
    state: Established
    tcp_port_number: 179

    statistics:
       bgp_peer_dropped_count: 0
       bgp_peer_dynamic_cap_in_count: 0
       ...
       bgp_peer_update_in_count: 5
       bgp_peer_update_out_count: 9
       bgp_peer_uptime: 15082

Všechny soubory najdete zde: https://github.com/HPENetworking/scriptsonly/tree/master/OpenSwitch/leafspine-ops

Perfektní. Dnes jsme si vysvětlili jak se dá Ansible použít a také to udělali. Příště se zaměříme na automatické testování funkčnosti sítě a také na koncept životního cyklu – tedy jak vracet síť do požadovaného stavu (pokud se odchílí) a jak narolovat změny v nastavení sítě.

Similar posts
  • Moderní 10G v datovém centru s novou ... HPE tento týden oznámilo evoluční vývoj portfolia v oblasti data center 1U prvků s 10G/40G/100G technologií, konkrétně novou řadu 5940. Co je nového? Hardwarové vlastnosti Prvky přichází s novou generací 10/40/100 čipů, které umožnily mít nově prvky se 100G uplinky (a to hned šesti) a také přináší podporou nových vlastností jako je směrování VXLAN (předchozí [...]
  • ArubaOS-Switch 16.02: IP SLA i pro Ar... IP SLA Ve světě směrovačů už poměrně dlouho existuje možnost monitorovat dostupnost a kvalitu spojení s využitím L3 protokolů. Můžete například z pobočky v pravidelných intervalech testovat dostupnost brány datového centra nebo klíčového serveru včetně měření doby jeho reakce (round-trip-time). Dá se také namířit dva routery proti sobě tak, že jeden se ptá a druhý [...]
  • OpenSwitch v GNS3 – chcete GUI ... GNS3 verze 1.5 Pokud neznáte GNS3, jde o velmi dobrý síťový simulátor. Narozdíl od jiných řešení, o kterých jsem na netSvět už psal (Docker, shell skript, Mininet), je zaměřený především na síťaře, kteří chtějí pracovat s virtuální sítí a přizpůsobuje se jejich pohodlí. Do CI/CD pipeline se tedy moc nehodí, ale za to má výborné [...]
  • OpenSwitch a Ansible automatizace pra... Posledně jsme si nastavili naší virtuální OpenSwitch leaf-spine topologii a vybudovali jsme BGP L3 fabric. Dnes si ukážeme více z životního cyklu s použitím Ansible – otestování sítě, vrácení odchylek do požadovaného stavu sítě a rolování změn. Jste líní číst? Mrkněte na video: Playbook pro testování sítě Ansible můžete použít i pro testování, že síť [...]
  • OpenSwitch a Ansible automatizace pra... V minulém díle jsme si rozjeli Lead-Spine OpenSwitch topologii s využitím Dockeru a skript nám vygeneroval také hosts file pro Ansible. Dnes se vyzkoušíme napojení na Ansible 2.1. Příprava Ansible a vašeho VM První co potřebujeme udělat je nainstalovat Ansible minimálně ve verzi 2.1. Postup najdete zde: http://docs.ansible.com/ansible/intro_installation.html Dále vyřešíme nastavení SSH klienta v naší [...]

No Comments Yet

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *