Sự hỗn loạn của mạng đa thiết bị (Multi-Vendor)
Năm ngoái, đội ngũ hạ tầng của chúng tôi đã chạm đến giới hạn chịu đựng. Chúng tôi quản lý một mạng trục (backbone) gồm 40 router Juniper MX, 150 switch Cisco Catalyst và 72 chi nhánh chạy Mikrotik CCR. Mỗi khi cần cấu hình một VLAN mới hoặc cập nhật máy chủ NTP, ba kỹ sư khác nhau phải đăng nhập vào ba môi trường CLI riêng biệt. Cú pháp cho lệnh description của Cisco khác với description của Juniper, và hoàn toàn khác biệt so với comment của Mikrotik.
Những lỗi đánh máy đơn giản gây ra sự cố thường xuyên. Một lệnh commit bị bỏ lỡ trên thiết bị Juniper hoặc quên write memory trên switch Cisco đồng nghĩa với việc cấu hình sẽ biến mất sau khi khởi động lại. Quản lý thủ công không chỉ chậm chạp mà còn là một rủi ro lớn. Chúng tôi cần ngừng coi router như những “thú cưng” (pets) và bắt đầu đối xử với chúng như những dòng mã (code).
Tại sao CLI thủ công và Script tự viết lại chạm ngưỡng giới hạn
Nỗ lực giải quyết vấn đề đầu tiên của chúng tôi là sử dụng các script Python tùy chỉnh với Paramiko và Netmiko. Các thư viện này rất mạnh mẽ, nhưng chúng tôi nhanh chóng nhận ra mình phải duy trì hơn 1.400 dòng mã rườm rà và dễ lỗi. Chúng tôi dành nhiều thời gian để xử lý lỗi timeout SSH và phân tích lỗi đặc thù của từng hãng hơn là thực sự quản lý mạng. Chúng tôi không xây dựng mạng lưới; chúng tôi đang xây dựng một ứng dụng phần mềm chỉ để duy trì hoạt động tối thiểu.
Chọn công cụ phù hợp: Python vs. Ansible
Chúng tôi đã đánh giá ba hướng đi chính:
- CLI thủ công: Không tốn chi phí ban đầu, nhưng rủi ro vận hành cao và khả năng mở rộng bằng không.
- Script Python tùy chỉnh: Linh hoạt cao, nhưng yêu cầu kỹ năng lập trình chuyên nghiệp mà các quản trị viên cấp thấp thường thiếu.
- Ansible: Không cần agent, sử dụng YAML dễ đọc và có hệ sinh thái Network Modules khổng lồ được hỗ trợ trực tiếp từ các hãng.
Ansible đã chiến thắng vì nó tách biệt dữ liệu (như địa chỉ IP và VLAN ID) khỏi logic (các lệnh cụ thể cần thiết để áp dụng chúng). Sự tách biệt này chính là nơi sự kết hợp giữa Ansible Network Modules và template Jinja2 trở thành một lợi thế quan trọng.
Quy trình triển khai thực tế: Modules + Templates
Sau sáu tháng vận hành thực tế, quy trình của chúng tôi đã ổn định theo kiến trúc ba tầng sạch sẽ. Cách tiếp cận này chuyển trọng tâm của bạn từ “tôi phải gõ lệnh này thế nào?” sang “mạng lưới nên trông như thế nào?”
1. Định nghĩa Inventory đa thiết bị
Ansible cần biết driver nào để sử dụng cho từng thiết bị. Chúng tôi định nghĩa điều này trong file hosts.ini. Bằng cách thiết lập biến ansible_network_os, chúng tôi chỉ dẫn chính xác cho Ansible bộ module nào cần tải cho từng loại phần cứng.
[campus_switches]
sw-cisco-01 ansible_host=10.0.1.10 ansible_network_os=cisco.ios.ios
sw-juniper-01 ansible_host=10.0.1.20 ansible_network_os=junipernetworks.junos.junos
sw-mikrotik-01 ansible_host=10.0.1.30 ansible_network_os=community.general.routeros
2. Trừu tượng hóa cấu hình với Jinja2
Chúng tôi tránh việc viết các playbook riêng cho từng hãng bằng cách sử dụng template Jinja2. Chúng tôi tạo một cấu trúc dữ liệu YAML và ánh xạ nó vào cú pháp cụ thể của từng hãng. Ví dụ, hãy xem xét một banner hệ thống tiêu chuẩn.
Đầu tiên, chúng tôi định nghĩa các biến trong group_vars/all.yml:
system_banner: "Truy cập hạn chế. Mọi hoạt động đều được ghi lại."
snmp_community: "itfromzero_readonly"
Sau đó, chúng tôi tạo các template cụ thể. Đây là phiên bản Cisco (templates/cisco_ios.j2):
banner motd ^
{{ system_banner }}
^
Và phiên bản Juniper (templates/juniper_junos.j2):
set system login message "{{ system_banner }}"
3. Playbook: Nơi mọi thứ kết nối
Playbook sử dụng các module config chuyên dụng để đẩy các template đã được render. Các module này có tính chất idempotent (đồng nhất). Chúng kiểm tra trạng thái hiện tại và chỉ gửi lệnh nếu cấu hình thiết bị không khớp với template của bạn.
- name: Triển khai cấu hình hệ thống đa thiết bị
hosts: campus_switches
gather_facts: false
tasks:
- name: Đẩy cấu hình Cisco
cisco.ios.ios_config:
src: templates/cisco_ios.j2
when: ansible_network_os == 'cisco.ios.ios'
- name: Đẩy cấu hình Juniper
junipernetworks.junos.junos_config:
load: merge
src: templates/juniper_junos.j2
when: ansible_network_os == 'junipernetworks.junos.junos'
- name: Đẩy cấu hình Mikrotik
community.general.routeros_command:
commands:
- /system identity set name={{ inventory_hostname }}
- /snmp community set [find default=yes] name={{ snmp_community }}
when: ansible_network_os == 'community.general.routeros'
Những bài học xương máu từ thực tế
Chuyển sang mô hình này không hoàn toàn suôn sẻ. Nếu bạn đang bắt đầu hành trình này, hãy lưu ý bốn điểm sau:
- Tin tưởng nhưng phải xác minh với
check_mode: Luôn chạy playbook với tham số--checktrước. Điều này thực hiện chạy thử (dry run), cho bạn thấy chính xác sự khác biệt (diff) của những gì sẽ thay đổi mà không ảnh hưởng đến lưu lượng mạng thực tế. - Thu thập thông tin (Fact gathering) là kẻ thù của hiệu năng: Thiết bị mạng phản hồi rất chậm. Hãy tắt
gather_factstheo mặc định trừ khi bạn thực sự cần số sê-ri phần cứng. Thay đổi nhỏ này đã giảm thời gian thực thi của chúng tôi gần 40%. - Khóa chặt các thông tin bảo mật: Đừng bao giờ lưu mật khẩu SSH hoặc chuỗi SNMP ở dạng văn bản thuần túy. Hãy sử dụng
ansible-vaultđể mã hóa các biến nhạy cảm. Chỉ mất năm phút để thiết lập nhưng ngăn chặn được các vụ rò rỉ bảo mật nghiêm trọng. - Chuẩn hóa quy tắc đặt tên: Tự động hóa hoạt động tốt nhất khi tên interface tuân theo một quy luật nghiêm ngặt. Nếu một switch dùng
GigabitEthernet0/1và switch khác dùngge-0/0/0, logic Jinja2 của bạn sẽ nhanh chóng trở thành một mớ hỗn độn các câu lệnh if lồng nhau.
Kết quả: Hạ tầng dưới dạng mã (Infrastructure as Code)
Sự thay đổi lớn nhất không nằm ở phần mềm—mà là ở tư duy. Chúng tôi không còn “đăng nhập vào switch” nữa. Thay vào đó, chúng tôi sửa đổi file YAML, gửi một Git Pull Request và để đường ống CI/CD kích hoạt Ansible playbook. Điều này tạo ra một nhật ký kiểm tra (audit trail) hoàn hảo cho mọi thay đổi.
Bằng cách tận dụng các module chuyên dụng của Ansible, chúng tôi đã cắt giảm thời gian triển khai cho các chi nhánh mới từ hai ngày xuống còn chỉ hai mươi phút. Quan trọng hơn, chúng tôi đã loại bỏ lỗi do con người gây ra—nguyên nhân của 90% thời gian ngừng hoạt động trước đây. Nếu bạn vẫn đang quản lý các môi trường đa thiết bị một cách thủ công, bạn thực chất đang ngồi chờ thảm họa xảy ra. Hãy bắt đầu nhỏ bằng cách tự động hóa thứ gì đó đơn giản, như cài đặt DNS. Lợi ích sẽ thấy rõ ngay khi kết thúc tuần.

