Ansible 是一種功能強大的自動化工具,廣泛應用於組態管理、應用佈署和任務自動化等領域。在網路自動化方面,Ansible 提供了豐富的模組和功能,可以有效簡化網路裝置的組態和管理流程。本文將重點介紹如何使用 Ansible 與網路裝置進行互動,例如執行 Ping 測試、推播組態等,並探討如何利用 Jinja2 範本引擎實作網路組態的範本化,提升自動化效率。此外,文章還會涵蓋 Ansible 的一些進階應用,例如多主機結果處理、敏感資訊保護以及最佳實務等,幫助讀者更全面地掌握 Ansible 在網路自動化中的應用技巧。

Ansible 與網路範本化

本章將透過 Ansible 工具展示裝置互動的範例,引導讀者瞭解 Ansible 的基本概念,並透過特定案例探討如何與網路裝置互動。重點將放在使用範本組態裝置,並確保實作標準組態。讀者還將學習如何建立程式化的 Playbook 來透過指令碼執行特定操作。

Ansible 與網路範本

Ansible 是一種自動化工具或平台,以開源軟體的形式提供,用於組態路由器、交換器和各種型別的伺服器等裝置。Ansible 的主要目的是組態三種主要型別的任務:

組態管理

用於擷取和推播各種裝置上的組態,我們稱之為 Ansible 中的庫存。根據庫存的型別,Ansible 能夠批次推播特定或完整的組態。

應用佈署

在伺服器場景中,我們經常需要批次佈署某些特定的應用或補丁。Ansible 也能處理這些任務,包括批次上傳補丁或應用到伺服器、安裝它們,甚至根據特定任務自定義應用設定。

任務自動化

這是 Ansible 的一個功能,用於在單個裝置或一組裝置上執行某些編寫的任務。這些任務可以被編寫並組態 Ansible 以一次性或定期執行。

程式碼範例:使用 Netmiko 與 SNMP 互動

errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd(
    cmdgen.CommunityData('mytest'),
    cmdgen.UdpTransportTarget((ip, 161)),
    0, 25,
    '1.3.6.1.2.1.31.1.1.1.18', '1.3.6.1.2.1.2.2.1.2', '1.3.6.1.2.1.31.1.1.1.1'
)

for varBindTableRow in varBindTable:
    tval = ""
    for name, val in varBindTableRow:
        if (("Loopback45" in str(val)) or ("Lo45" in str(val))):
            tval = tval + "MIB: " + str(name) + " , Interface info: " + str(val) + "\n"
            loopbackpresent = True
    if (loopbackpresent):
        tval = tval + "IP address of the device: " + ip
        print(tval + "\n")
        if ("test interface created" in tval):
            pushconfig(ip, "Loopback45", "Mgmt loopback interface")
            checkloopback45("192.168.20.1", "Loopback45")

內容解密:

此程式碼片段展示瞭如何使用 SNMP 從網路裝置中擷取資訊。首先,透過 cmdGen.bulkCmd 方法傳送 SNMP 請求,查詢特定的 MIB 物件,如介面描述、介面名稱和介面別名。然後,遍歷傳回的結果,檢查是否包含特定的介面名稱(如 “Loopback45” 或 “Lo45”)。如果找到,則輸出相關資訊並執行相應的操作,如推播組態和檢查介面狀態。

重點回顧

本章介紹瞭如何使用 Python 與網路裝置互動,包括使用 Netmiko 和 SNMP。此外,還探討了多執行緒在可擴充套件性方面的重要性。下一章將探討使用 Ansible 進行範本化和裝置組態,並比較 Ansible、Chef 和 Puppet 的差異。

常見問題

  1. Netmiko 是否只支援根據 Cisco 的裝置?(是/否)
  2. 多執行緒的首選硬體規格是入門級機器還是高階機器?
  3. 我們可以使用 SNMP 向 Cisco 路由器推播任何組態嗎?(是/否)
  4. 要透過 Netmiko 向路由器推播多行組態,我們使用逗號分隔的字串還是列表?
  5. 從效率上講,從 Netmiko 還是 SNMP 擷取 Cisco 路由器的版本更快?
  6. 當我們想要向路由器推播組態時,是否需要將網路範本硬編碼在指令碼中?(是/否)
  7. 用於驗證來自路由器的 SNMP 資訊的術語是什麼?
  8. 用於建立多個執行緒的 Python 函式庫/模組名稱是什麼?
  9. 用於透過 SNMP 從網路裝置擷取資訊的 Python 函式庫/模組名稱是什麼?

Ansible 與網路範本化技術 Chapter 3

Ansible 基礎元件介紹

Ansible 框架由多個關鍵元件組成,這些元件共同協助管理員組態、佈署及管理節點。主要的元件包括:

  • Inventory(清單):這是一個設定檔,用於定義需要被存取的主機資訊。預設的清單檔案位於 /etc/ansible/hosts
  • Playbook(劇本):Playbook 是一系列指示 Ansible 組態、佈署及管理清單中定義節點的指令集。
  • Plays(劇):Plays 是針對特定節點執行的一組任務。一個 Playbook 可以包含一個或多個 Plays。
  • Tasks(任務):任務是在 Playbook 中執行的具體組態動作。
  • Variables(變數):變數是自定義的,可以根據任務執行的結果儲存值。
  • Roles(角色):角色定義了 Playbook 的執行層次結構。例如,一個 Web 伺服器的主要角色可以包含安裝特定應用程式的子任務或子角色。

自定義清單檔案與 Ad Hoc 命令

首先,我們來建立一個自定義的清單檔案,內容如下:

[myrouters]
test1 ansible_host=10.166.240.2
test3 ansible_host=10.162.240.2
test5 ansible_host=10.195.240.2
test4 ansible_host=10.165.240.2

ansible_host 是 Ansible 的內建變數,用於指定特定主機的 IP 位址。這些主機被歸類別在名為 myrouters 的群組下。

Ad Hoc 命令簡介

Ad Hoc 命令用於執行一次性任務,例如取得受管理節點的版本資訊。下面是一些 Ad Hoc 命令的範例:

  • 平行執行 ping 命令ansible myrouters -m ping -f 5
  • 使用特定的使用者名稱執行 ping 命令ansible myrouters -m ping -f 5 -u <username>
  • 使用 sudo 許可權執行 ping 命令ansible myrouters -m ping -f 5 -u username --become -k
  • 執行特定的命令ansible myrouters -a "show version" -f 5
  • 複製檔案到遠端主機ansible servers -m copy -a "src=https://www.blackcat1968.com/home/user1/myfile.txt dest=/tmp/myfile.txt"
  • 啟動或停止服務ansible mywebservers -m service -a "name=httpd state=started"ansible mywebservers -m service -a "name=httpd state=stopped"
  • 非同步執行長時間任務ansible servers -B 600 -m -a "show tech-support"
  • 檢查非同步任務的狀態ansible servers -m async_status -a "jobid"

Ansible Playbooks

Playbooks 是用 YAML 語言編寫的一系列指示,用於組態、佈署及管理節點。Playbooks 定義了工作流程,可以根據條件執行特定的任務,並根據任務執行的結果進行驗證。

Playbook 的基本結構

一個基本的 Playbook 由多個 Plays 組成,每個 Play 都針對特定的受管理節點群組執行特定的 Ansible 任務。

---
- name: Configure routers
  hosts: myrouters
  tasks:
    - name: Show version
      ios_command:
        commands:
          - show version

這個範例 Playbook 定義了一個名為 “Configure routers” 的 Play,針對 myrouters 群組中的主機執行 show version 命令。

使用 Plantuml 圖表呈現 Ansible 工作流程

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Ansible 網路自動化與範本組態技術

package "網路架構" {
    package "應用層" {
        component [HTTP/HTTPS] as http
        component [WebSocket] as ws
        component [gRPC] as grpc
    }

    package "傳輸層" {
        component [TCP] as tcp
        component [UDP] as udp
        component [TLS/SSL] as tls
    }

    package "網路層" {
        component [IP] as ip
        component [ICMP] as icmp
        component [路由協議] as routing
    }

    package "鏈路層" {
        component [Ethernet] as eth
        component [WiFi] as wifi
        component [ARP] as arp
    }
}

http --> tcp
ws --> tcp
grpc --> tcp
tcp --> tls : 加密
tls --> ip
udp --> ip
ip --> routing
routing --> eth
routing --> wifi
eth --> arp

@enduml

此圖示呈現了使用 Ansible 的基本工作流程,從定義清單到執行 Playbook 並檢查結果。

內容解密:

此圖表展示了 Ansible 自動化流程的主要步驟。首先,管理員需要定義清單,列出所有需要管理的節點。接著,編寫 Playbook 以定義需要在這些節點上執行的任務。然後,Ansible 會根據 Playbook 中的指示執行相應的任務。最後,檢查任務執行的結果,以確保所有操作都正確完成。

Ansible 與網路範本化技術解析

介紹 Ansible Playbook

Ansible 是一種自動化工具,用於組態管理、應用程式佈署和任務自動化。Playbook 是 Ansible 的核心元件,它定義了一系列任務,用於在目標主機上執行特定的操作。

Playbook 範例解析

以下是一個簡單的 Playbook 範例:

- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
    - name: test connection
      ping:

在這個範例中,我們可以看到以下幾個重要的部分:

  • hosts:指定了 Playbook 要執行的目標主機群組或節點。
  • vars:定義了變數,可以在 Playbook 中使用。
  • tasks:定義了要執行的任務列表。
  • name:對任務進行了描述。

網路互動範例

從所有路由器 Ping 特定 IP

以下是一個 Playbook 範例,用於從所有路由器 Ping 全球 DNS IP(8.8.8.8):

- name: Checkping
  hosts: all
  gather_facts: false
  tasks:
    - name: run ping for the host
      ios_command:
        commands: ping 8.8.8.8 repeat 1
      register: trace_result
    - name: Debug registered variables
      debug: var=trace_result

這個 Playbook 使用 ios_command 模組來執行 Ping 命令,並將結果註冊到 trace_result 變數中。然後,使用 debug 模組來顯示註冊的變數。

從所有路由器 Ping 多個 IP

以下是一個 Playbook 範例,用於從所有路由器 Ping 多個 IP,並識別出 Ping 失敗的 IP:

- name: Run ping commands
  hosts: all
  gather_facts: false
  remote_user: test
  connection: local
  vars:
    publicips:
      "dns1": "4.2.2.2"
      "dns2": "8.8.8.8"
      "dns3": "1.1.1.1"
      "dns4": "8.8.8.4"
  tasks:
    - name: run ping to every other host
      ios_command:
        commands: ping "{{ item.value }}" repeat 1
      with_dict: "{{ publicips }}"
      register: trace_result
    - name: Check ping failure
      fail: msg="Ping not responding {{ item.stdout_lines }}"
      when: "'100 percent' not in item.stdout[0]"
      with_items: "{{ trace_result.results }}"

這個 Playbook 使用 with_dict 命令來迭代 publicips 變數中的 IP 地址,並使用 ios_command 模組來執行 Ping 命令。然後,使用 fail 模組來檢查 Ping 失敗的情況。

Playbook 結構解析

一個典型的 Playbook 結構包括以下幾個部分:

  1. 基本宣告:定義了 Playbook 的名稱、目標主機和使用者名稱等資訊。
  2. 變數宣告:定義了 Playbook 中使用的變數。
  3. 任務執行:定義了要執行的任務列表。

Ansible 與網路範本化技術深度解析

深入理解 Ansible 在網路自動化中的關鍵應用

在現代網路管理中,Ansible 已成為不可或缺的自動化工具,尤其是在處理複雜的網路組態和驗證過程中。本章將探討 Ansible 的進階應用,特別是在網路裝置管理、範本化組態以及結果驗證等方面的專業技術。

第四節:驗證機制詳解

當我們成功取得網路裝置的回應後,需要對結果進行嚴格的驗證。以下 playbook 範例展示瞭如何迭代處理多主機執行結果:

- name: 檢查 Ping 失敗狀況
  fail:
    msg: "Ping 無回應 {{ item.stdout_lines }}"
  when: "'100 percent' not in item.stdout[0]"
  with_items: "{{ trace_result.results }}"

程式碼深度解析:

  1. fail 模組:當條件滿足時主動終止 playbook 執行並輸出自定義錯誤訊息
  2. when 條件判斷:檢查輸出中是否包含 “100 percent” 字串以判斷 Ping 是否成功
  3. with_items 迭代處理:遍歷 trace_result.results 中的每個執行結果

內容解密:

  • trace_result.results 儲存了多主機執行的結果列表
  • 使用 with_items 對每個主機的結果進行迭代處理
  • 當 Ping 失敗(輸出不含 “100 percent”)時觸發 fail 模組終止執行

安全資訊保護機制

在執行敏感操作時,為了保護機密資訊不被洩露,可以啟用 no_log: True 組態:

- name: 敏感操作範例
  some_module:
    sensitive_param: "secret_value"
  no_log: True

啟用 no_log 後的輸出變化:

{
  "censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result",
  "changed": false
}

詳細解析:

  1. 安全隱藏機制:啟用後敏感資訊不會直接顯示在輸出中
  2. 稽核追蹤:仍可透過 -vvv 詳細模式觀察執行過程
  3. 安全性提升:有效防止敏感資訊在日誌或輸出中洩露

網路範本化技術實務

網路範本是預先定義的組態基線,能根據不同裝置需求生成特定組態。常見的範本分類別依據包括:

  1. 裝置角色(如核心交換器、邊界路由器)
  2. 裝置規模(根據使用者數量劃分的大中小型組態)
  3. 功能需求(如開啟特定路由協定)

T-Shirt Sizing 組態策略

  1. 第一階段:規模評估

    • 根據使用者數量劃分裝置規模(極小、小、中、大型)
    • 定義不同規模對應的 SKU(Stock Keeping Unit)
  2. 第二階段:組態定義

    • 為不同 SKU 定義標準化組態範本
    • 例如:極小型裝置可能不需要複雜的路由組態
  3. 第三階段:角色定義

    • 確定裝置在網路架構中的角色(如交換器、路由器)
    • 根據角色套用對應的範本組態

Jinja2 範本實作範例

以下範例展示如何使用 Jinja2 建立網路裝置的基本組態範本:

vsmalltemplate.j2 範本內容:

interface Loopback 99
description "This is switch mgmt for device {{ inventory_hostname }}"

checktemplate.yml Playbook:

- name: 生成組態檔案
  hosts: all
  gather_facts: false
  tasks:
    - name: Ansible 組態生成
      template:
        src: vsmalltemplate.j2
        dest: "{{ inventory_hostname }}.txt"

詳細解析:

  1. template 模組:負責將 Jinja2 範本渲染成實際組態檔案
  2. inventory_hostname 變數:自動參照目前處理的主機名稱
  3. 動態組態生成:為每個主機生成對應的組態檔案(以主機名稱命名)

最佳實務與注意事項

  1. 範本設計原則

    • 高度模組化與可重複使用性
    • 清晰的變數定義與參照機制
  2. 安全性考量

    • 對敏感資訊進行適當的保護(如使用 no_log
    • 確保範本渲染過程的安全性
  3. 除錯與驗證

    • 使用 -vvv 模式觀察詳細執行過程
    • 建立完善的驗證機制確保組態正確性