Triển khai NetBox làm Single Source of Truth: Quản lý tập trung DCIM, IPAM và Tự động hóa mạng

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

Bắt đầu nhanh (5 phút)

Các bảng tính Excel rời rạc và các trang wiki phân mảnh biến việc quản trị mạng thành một cơn ác mộng. Việc cấp phát subnet bị sai lệch, mô tả interface trở nên lỗi thời, còn việc bảo trì định kỳ thì chỉ dựa vào phỏng đoán. NetBox giải quyết triệt để sự hỗn loạn này bằng vai trò là một Single Source of Truth (SSoT) chuẩn xác cho Quản lý Hạ tầng Trung tâm Dữ liệu (DCIM) và Quản lý Địa chỉ IP (IPAM).

Để khởi chạy nhanh một instance ở môi trường local hoặc trên VM Ubuntu staging (2 vCPU, 4 GB RAM), hãy sử dụng dự án Docker Compose chính thức.

# 1. Clone repository NetBox Docker chính thức
git clone -b release https://github.com/netbox-community/netbox-docker.git
cd netbox-docker

# 2. Tạo file override cấu hình môi trường
touch docker-compose.override.yml

# 3. Pull image và khởi chạy các service ở chế độ chạy ngầm
docker compose pull
docker compose up -d

Hãy chờ khoảng 60 đến 90 giây để PostgreSQL và Redis hoàn tất việc chạy database migration ban đầu. Kiểm tra trạng thái hệ thống bằng lệnh docker compose ps. Khi tất cả container đã ở trạng thái healthy, tiến hành tạo tài khoản quản trị viên:

docker compose exec netbox /opt/netbox/netbox/manage.py createsuperuser \
  --username admin \
  --email [email protected]

Mở trình duyệt và truy cập vào http://<your-server-ip>:8000. Đăng nhập bằng tài khoản superuser vừa tạo để truy cập vào dashboard.

Đi sâu vào chi tiết: Mô hình hóa DCIM và IPAM

Trước khi bắt tay vào viết script tự động hóa, bạn cần hiểu rõ nguyên lý thiết kế cốt lõi của NetBox: nó mô hình hóa trạng thái kỳ vọng (intended state) chứ không phải dữ liệu đo lường vận hành (operational telemetry). NetBox ghi nhận topo mạng của bạn nên trông như thế nào, chứ không giám sát thông số đường truyền theo thời gian thực, mức sử dụng CPU hay số lần flap của BGP neighbor.

1. Phân cấp DCIM cốt lõi

  • Tổ chức (Organization): Nhóm các vị trí vật lý thành Regions, Site Groups và Sites (ví dụ: Region: US-East → Site: us-east-dc1).
  • Tủ Rack: Khai báo các tủ rack tiêu chuẩn (ví dụ: Rack-A01 chuẩn 42U với kích thước lắp đặt 19-inch tiêu chuẩn).
  • Loại thiết bị (Device Types): Định nghĩa thông số phần cứng cùng số lượng interface chính xác (ví dụ: Cisco Catalyst 9300-48P với 48 cổng 1G và 4 cổng uplink 10G SFP+).
  • Thiết bị (Devices): Khởi tạo thiết bị cụ thể kèm số serial (ví dụ: sw-leaf-01) được lắp tại vị trí U24 trong Rack-A01.

2. Ánh xạ IPAM

Thay vì nằm rải rác trên các bảng tính tách rời, các địa chỉ IP trong NetBox được gán trực tiếp vào từng interface của thiết bị. Điều này đảm bảo ánh xạ topo L2/L3 luôn chuẩn xác:

  • RIRs & Aggregates: Cấp phát các dải CIDR cấp cao (ví dụ: các dải IP RFC 1918 như 10.0.0.0/8 hoặc 172.16.0.0/12).
  • VRF: Phân chia bảng định tuyến khi triển khai mạng đa người dùng (multi-tenant) hoặc mạng quản trị out-of-band riêng biệt.
  • Prefixes: Chia nhỏ thành các subnet chức năng được ánh xạ tới VLAN cụ thể (ví dụ: 10.20.100.0/24 ánh xạ tới VLAN 100 - OOBM).
  • Địa chỉ IP (IP Addresses): Gán IP tĩnh cho interface kèm subnet mask theo chuẩn CIDR (ví dụ: gán 10.20.100.11/24 cho cổng GigabitEthernet1/0/1 trên sw-leaf-01).

Tự động tạo cấu hình qua Python API

Giá trị thực sự của SSoT được phát huy khi các pipeline tự động hóa có thể truy vấn trạng thái kỳ vọng trực tiếp từ API, chấm dứt hoàn toàn việc sao chép thủ công hay dùng các biến Jinja tĩnh dễ phát sinh lỗi.

Tạo API Token

Nhấp vào ảnh đại diện tài khoản ở góc trên bên phải giao diện web → API Tokens → Add a Token. Để trống thời hạn hết hạn đối với service account, copy token dạng chuỗi thập lục phân 40 ký tự và xuất ra biến môi trường:

export NETBOX_URL="http://127.0.0.1:8000"
export NETBOX_TOKEN="0123456789abcdef0123456789abcdef01234567"

Trích xuất Inventory và xuất cấu hình với Python

Sử dụng pynetbox để truy vấn các REST endpoint và Jinja2 để render cấu hình cho Cisco IOS hoặc các thiết bị mạng khác.

pip install pynetbox jinja2 netaddr

Lưu đoạn script sau thành file generate_network_config.py:

import os
import ipaddress
import pynetbox
from jinja2 import Template

NETBOX_URL = os.getenv("NETBOX_URL", "http://127.0.0.1:8000")
NETBOX_TOKEN = os.getenv("NETBOX_TOKEN")

nb = pynetbox.api(NETBOX_URL, token=NETBOX_TOKEN)

# Jinja2 template để cấu hình cổng switch
interface_template = Template("""
! Cấu hình được tạo tự động cho thiết bị {{ device.name }}
hostname {{ device.name }}
!
{% for iface in interfaces %}
interface {{ iface.name }}
 description {{ iface.description or 'Cổng không sử dụng' }}
 {% if iface.ip %}
 ip address {{ iface.ip.ip }} {{ iface.ip.netmask }}
 {% else %}
 no ip address
 {% endif %}
 {% if iface.enabled %}no shutdown{% else %}shutdown{% endif %}
!
{% endfor %}
""")

def build_config(device_name: str):
    device = nb.dcim.devices.get(name=device_name)
    if not device:
        raise ValueError(f"Không tìm thấy thiết bị '{device_name}' trong inventory của NetBox.")

    # Truy vấn tất cả interface vật lý và logic của thiết bị đích
    interfaces = list(nb.dcim.interfaces.filter(device_id=device.id))

    for iface in interfaces:
        # Lấy địa chỉ IPv4/IPv6 chính được gán cho interface này
        ip_records = list(nb.ipam.ip_addresses.filter(interface_id=iface.id))
        if ip_records:
            # Phân tích định dạng CIDR (ví dụ: 10.20.100.11/24) thành IP và netmask dạng dotted
            parsed_ip = ipaddress.ip_interface(ip_records[0].address)
            iface.ip = parsed_ip
        else:
            iface.ip = None

    rendered = interface_template.render(device=device, interfaces=interfaces)
    print(rendered)

if __name__ == "__main__":
    # Ví dụ: Render cấu hình cho edge switch
    build_config("sw-leaf-01")

Chạy script để sinh ra các đoạn lệnh cấu hình Cisco CLI chuẩn xác, sẵn sàng triển khai chỉ trong chưa đầy hai giây. Khi một kỹ sư cập nhật mô tả interface hoặc thay đổi cấp phát IP trên NetBox, pipeline sẽ đồng bộ chính xác các thay đổi này trên 50 switch mà không lo rủi ro gõ nhầm lệnh.

Tích hợp Ansible Dynamic Inventory

Bạn không cần phải duy trì các file hosts.ini tĩnh theo cách thủ công. Collection chính thức của NetBox sẽ tự động đồng bộ inventory, role và platform tag vào các Ansible playbook theo thời gian thực.

ansible-galaxy collection install netbox.netbox

Tạo một file dynamic inventory plugin có tên netbox_inventory.yml:

plugin: netbox.netbox.nb_inventory
api_endpoint: http://127.0.0.1:8000
token: 0123456789abcdef0123456789abcdef01234567
validate_certs: false
config_context: true
group_by:
  - site
  - device_roles
query_filters:
  - status: active

Kiểm tra xem Ansible đã tạo các host group chính xác hay chưa:

ansible-inventory -i netbox_inventory.yml --graph

Kinh nghiệm thực tiễn cho vận hành Day-2

  • Lưu trữ biến nền tảng trong Config Contexts: Giữ mô hình thiết bị luôn gọn gàng. Hãy khai báo các biến dùng chung ở cấp toàn cục hoặc site—chẳng hạn như BGP AS number (ví dụ: 65001), NTP server (10.0.0.123) và địa chỉ Syslog—bên trong Config Contexts của NetBox.
  • Kích hoạt GitOps pipeline thông qua Webhooks: Thiết lập NetBox Webhook để gửi HTTP POST payload tới GitHub Actions hoặc GitLab CI runner mỗi khi có cập nhật về interface hoặc thiết bị. Quy trình này sẽ kích hoạt kiểm tra dry-run diff ngay lập tức.
  • Thực thi kỷ luật SSoT nghiêm ngặt: Nghiêm cấm việc thay đổi cấu hình trực tiếp (ad-hoc CLI) trên switch production. Nếu kỹ sư can thiệp thủ công mà không cập nhật qua NetBox, đợt triển khai tự động hóa tiếp theo sẽ ghi đè và làm mất các bản vá nóng đó.
  • Tự động sao lưu database hàng ngày: PostgreSQL lưu trữ toàn bộ dữ liệu nguồn chuẩn của hệ thống mạng. Hãy thiết lập cron job chạy hàng ngày lúc 02:00 UTC để dump database và lưu trữ các bản nén ở một vị trí off-site an toàn:
# Tự động sao lưu PostgreSQL hàng ngày
docker compose exec -T postgres pg_dump -U netbox netbox | gzip > /var/backups/netbox_$(date +%F_%H%M%S).sql.gz
Share: