⚠️ 提示:本站 AI 助手使用博主个人 API Token,没事别特么瞎用。
运维 · · 约 60 分钟阅读

NetBox 完全指南:IPAM/DCIM 部署、数据建模、API 自动化与排障

NetBox 是网络基础设施的「唯一真相源」(Source of Truth):不是监控工具,不是拓扑图工具,而是一个结构化的 IP 地址管理(IPAM) + 数据中心基础设施管理(DCIM) 数据库。本文覆盖 NetBox 与 LibreNMS/NetDisco 的定位区别、Docker 部署、核心数据模型层级关系(Site→Rack→Device→Interface→IP)、IPAM IP 地址与前缀管理、VLAN/VRF/ASN、DCIM 机架设备线卡、数据录入实操(GUI + REST API + pynetbox + Ansible 动态清单)、自定义字段与导出模板、Webhooks 集成、以及 12 个高频排障场景。

一、NetBox 是什么

定位:Source of Truth,不是监控

维度NetBoxLibreNMSNetDiscoZabbix
核心定位IPAM + DCIM 数据库网络监控 + 告警L2 拓扑发现全栈监控
数据来源人工录入 + API + DiscoverySNMP 自动采集SNMP/CDP/LLDP 自动SNMP/Agent 采集
拓扑图❌ 插件实现基础自动无
实时监控❌✅❌✅
IP 地址管理⭐ 核心能力基础基础❌
API⭐ REST + GraphQLRESTRESTAPI
适合谁运维团队 / 网络工程师NOC 值班网络工程师全栈运维

一句话:NetBox 是你网络的「CMDB」——你把 IP 分配、设备信息、线缆连接录进去,它帮你做结构化管理、防冲突、查询、给自动化提供数据源。它不扫描网络,是你告诉它网络长什么样。

为什么需要 NetBox

痛点Excel / WikiNetBox
IP 分配记录在 Excel多人编辑冲突、格式乱、不知道谁改了数据库 + 权限 + 变更日志
新设备分配 IP翻 Excel 找没用的,经常撞自动分配,防冲突
VLAN 谁在用查多个文档一个页面查全
机架里有什么Visio 图过期结构化设备 + 机架视图
Ansible 清单手动维护 hosts 文件动态从 NetBox API 拉
谁改了什么不知道变更日志全程记录

适用场景

场景适合度说明
中大型机房 IP 管理⭐⭐⭐⭐⭐核心设计目标
多站点数据中心⭐⭐⭐⭐⭐Site + Rack 层级
Ansible/Terraform 数据源⭐⭐⭐⭐⭐REST API 完美适配
VLAN/VRF 统一管理⭐⭐⭐⭐⭐IPAM 核心功能
线缆连接文档⭐⭐⭐⭐Cable 管理
小型办公网络⭐⭐⭐有点重,Excel 可能够
实时监控/告警⭐不是这个工具
自动拓扑发现⭐⭐需配合 NetDisco/Discovery 插件

二、部署

1.1 环境要求

资源最低推荐生产
CPU2 核4 核8 核
内存4 GB8 GB16 GB
磁盘10 GB50 GB100 GB+ SSD
OSLinux 任意Ubuntu 22.04 / Debian 12同左
PostgreSQL12+(NetBox 4.0 起;4.3+ 需 14+)15+16+
Redis4.0+(NetBox 4.x 起)7+7+
Docker20.10+24.0+24.0+

1.2 Docker Compose 部署(推荐)

# 1. 克隆官方 docker 仓库
git clone https://github.com/netbox-community/netbox-docker.git
cd netbox-docker

# 2. 复制环境变量模板(官方推荐用 env/ 目录下的文件,不是根目录 .env)
cp env/netbox.env.example env/netbox.env
cp env/postgres.env.example env/postgres.env
cp env/redis.env.example env/redis.env

# 3. 编辑 env/netbox.env,至少改这几项:
#    SECRET_KEY(用 python3 -c "import secrets; print(secrets.token_urlsafe(50))" 生成)
#    ALLOWED_HOSTS=localhost netbox.example.com
#    DB_NAME / DB_USER / DB_PASSWORD(与 postgres.env 一致)
#    REDIS_PASSWORD(与 redis.env 一致)
# 注:变量名是 SECRET_KEY(非 DJANGO_SECRET_KEY),ALLOWED_HOSTS 用空格分隔域名,不要写 0.0.0.0

# 4. 编辑 env/postgres.env:POSTGRES_DB / POSTGRES_USER / POSTGRES_PASSWORD
# 5. 编辑 env/redis.env:REDIS_PASSWORD

# 6. 启动
docker compose -f docker-compose.yml up -d

# 7. 查看状态
docker compose ps

# 8. 创建管理员
docker compose exec netbox /opt/netbox/netbox/manage.py createsuperuser

启动后访问 http://localhost:8000(容器内监听 8080,映射到宿主机 8000),用创建的管理员账号登录。

1.3 多容器架构

flowchart TB
  subgraph DC["Docker Compose"]
    direction TB
    NB["netbox<br/>Web + API + GraphQL<br/>容器内:8080 → 宿主机:8000"]
    NW["netbox-worker<br/>后台异步任务:Webhook / 清理"]
    NH["netbox-housekeeping<br/>定期清理任务(session、变更日志等)"]
    PG[("postgres<br/>数据存储<br/>:5432")]
    RD[("redis<br/>缓存 + 队列<br/>:6379")]
    NB --> PG
    NB --> RD
    NW --> PG
    NW --> RD
    NH --> PG
    NH --> RD
  end
容器职责端口
netboxDjango Web UI + REST API + GraphQL8080(容器内)→ 8000(宿主机)
netbox-worker后台异步任务(Webhook 发送、缓存清理等)—
netbox-housekeeping定期清理过期 session、变更日志、报告—
postgres数据库5432
redis缓存 + Celery 任务队列6379

1.4 关键配置项

# env/netbox.env 关键项

# Django 密钥(必须改)
SECRET_KEY='你的50字符随机字符串'

# 允许访问的主机名(空格分隔,不要写 0.0.0.0)
ALLOWED_HOSTS=localhost netbox.example.com

# 数据库(env/netbox.env 中用 DB_*,env/postgres.env 中用 POSTGRES_*)
DB_NAME=netbox
DB_USER=netbox
DB_PASSWORD=强密码

# Redis
REDIS_PASSWORD=强密码

# 可选:LDAP/OIDC 认证
# 在 configuration/configuration.py 里配

# 可选:邮件
# EMAIL_HOST / EMAIL_PORT / EMAIL_HOST_USER / EMAIL_HOST_PASSWORD

1.5 Nginx 反向代理 + HTTPS

server {
    listen 443 ssl http2;
    server_name netbox.yourdomain.com;

    ssl_certificate     /etc/ssl/certs/netbox.pem;
    ssl_certificate_key /etc/ssl/private/netbox.key;

    client_max_body_size 25M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name netbox.yourdomain.com;
    return 301 https://$host$request_uri;
}

在 .env 里加:

ALLOWED_HOSTS=netbox.yourdomain.com

1.6 升级

# 备份
docker compose exec postgres pg_dump -U netbox netbox > netbox-backup-$(date +%Y%m%d).sql

# 拉新镜像
docker compose pull

# 重启(自动迁移数据库)
docker compose up -d

# 检查迁移日志
docker compose logs netbox | grep -i migrat

三、核心数据模型

2.1 层级关系图

flowchart TB
  ORG["Organization(组织)"]
  ORG --> SITE["Site(站点 / 机房)"]
  ORG --> TEN["Tenant(租户 / 业务线)"]
  SITE --> LOC["Location(区域 / 楼层)"]
  LOC --> RACK["Rack(机架)"]
  RACK --> DEV["Device(设备)"]
  DEV --> IF["Interface(接口)"]
  DEV --> CP["Console Port(串口)"]
  DEV --> PP["Power Port(电源口)"]
  DEV --> MOD["Module(线卡模块)"]
  IF --> IP["IP Address"]
  IF --> CAB["Cable(线缆)"]
  IF --> MAC["MAC Address"]
  DEV -. 型号 .-> DT["Device Type(型号)"]
  DT --> MFR["Manufacturer(厂商)"]
  DT --> IT["Interface Template"]
  DT --> CPT["Console Port Template"]
  SITE --> VLAN["VLAN(虚拟局域网)"]
  VLAN -. 属于 .-> VG["VLAN Group"]
  SITE --> VRF["VRF(虚拟路由转发)"]
  SITE --> PFX["Prefix(IP 前缀)"]
  PFX --> IP
  SITE --> CLU["Cluster(集群)"]
  CLU -. 类型 .-> CT["Cluster Type"]
  CLU --> VM["Virtual Machine"]
  VM --> VIF["VM Interface"]
  VIF --> IP
  SITE --> ASN["ASN(自治系统号)"]
  SITE --> CIRC["Circuit(专线电路)"]
  CIRC -.-> CTP["Circuit Type / Provider"]
  SITE --> PWR["Power Panel / Power Feed"]

2.2 关键对象说明

对象作用示例必填前置
Site物理位置(机房/数据中心)BJ-IDC-1 北京机房1—
Location站点内区域(楼层/区域)Floor-3-Rack-Row-ASite
Rack机架(U 位管理)Rack-A01Site/Location
Manufacturer设备厂商Cisco / Huawei / Dell—
Device Type设备型号(模板)Catalyst 9300-48PManufacturer
Device具体设备实例core-sw-01Device Type + Site
Interface设备上的接口GigabitEthernet0/1Device
IP AddressIP 地址10.10.10.1/24Interface(可选)
PrefixIP 前缀(子网)10.10.10.0/24VRF / VLAN(可选)
VLAN虚拟局域网VLAN 100 (Servers)VLAN Group / Site
VRF虚拟路由转发实例prod-vrf—
Tenant租户/业务线Finance-Team—
ClusterVM 集群vmware-cluster-1Cluster Type + Site
Virtual Machine虚拟机web-server-01Cluster
Cable物理线缆连接接口 A ↔ 接口 B两个 Interface
ASN自治系统号AS65001—
Circuit专线电路MSTP-100M-To-IDC2Circuit Type + Provider

2.3 录入顺序(推荐流程)

1. Organization/Tenant     → 先建组织和业务线
2. Site/Location/Rack      → 建站点、区域、机架
3. Manufacturer/DevType    → 建厂商和设备型号(模板)
4. Device                  → 录入具体设备到机架
5. Interface               → 设备上的接口(可从模板自动生成)
6. VLAN/VRF/Prefix         → 建 VLAN、VRF、IP 前缀
7. IP Address              → 分配 IP 到接口
8. Cable                   → 连接设备间的线缆
9. Cluster/VM              → 虚拟机和集群

四、IPAM:IP 地址管理

3.1 Prefix(前缀)管理

Prefix 是 IP 子网管理的基础单位。

IPAM → Prefixes → Add

┌───────────────────────────────────────────┐
│ Prefix:    10.10.10.0/24                  │
│ Site:      BJ-IDC-1                       │
│ VRF:       (none) / prod-vrf              │
│ VLAN:      VLAN 100 (Servers)             │
│ Status:    Active                         │
│ Role:      Production Server Network      │
│ Description: 服务器区生产网段             │
│ Tags:      [production]                   │
└───────────────────────────────────────────┘

Status(状态)取值:

状态含义颜色
Active在用绿
Reserved保留(不分配)蓝
Deprecated废弃红
Container容器(包含子前缀)灰

Role(角色)取值(可自定义):

角色说明
Production生产网段
Management管理网(OOB/IPMI)
Staging预发布
Loopback设备 loopback
Point-to-Point点对点链路

3.2 IP 地址分配

IPAM → IP Addresses → Add

┌────────────────────────────────────────────┐
│ Address:   10.10.10.11/24                  │
│ Interface: core-sw-01 → Vlan100           │  ← 绑定到具体设备接口
│ VRF:       (none)                          │
│ Tenant:    Finance-Team                    │
│ Status:    Active                          │
│ DNS Name:  web-01.prod.example.com         │
│ Description: Web 服务器 01                 │
└────────────────────────────────────────────┘

IP 分配的三种方式:

# 方式 1:手动指定 IP
GUI → IP Addresses → Add → 填 10.10.10.11/24

# 方式 2:从 Prefix 自动分配下一个可用 IP
# API:
curl -X POST http://localhost:8000/api/ipam/prefixes/1/available-ips/ \
  -H "Authorization: Token YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"description": "auto-assigned"}'
# 返回自动选的下一个可用 IP

# 方式 3:批量分配
curl -X POST http://localhost:8000/api/ipam/prefixes/1/available-ips/ \
  -H "Authorization: Token YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"quantity": 10}'
# 一次分配 10 个 IP

3.3 前缀层级与聚合

NetBox 支持前缀嵌套,自动计算聚合:

10.0.0.0/8 (Container)
  ├─ 10.10.0.0/16 (Container)
  │    ├─ 10.10.10.0/24 (Active, Servers)
  │    ├─ 10.10.20.0/24 (Active, Management)
  │    └─ 10.10.30.0/24 (Active, Storage)
  └─ 10.20.0.0/16 (Container)
       └─ 10.20.10.0/24 (Active, DMZ)

在 Prefix 列表页,可以用树状视图查看嵌套关系。

3.4 VLAN 管理

IPAM → VLANs → Add

┌────────────────────────────────────────────┐
│ VID:       100                             │
│ Name:      Servers                         │
│ VLAN Group: BJ-IDC-1-VLANs                 │  ← 按 Site 分组
│ Site:      BJ-IDC-1                        │
│ Status:    Active                          │
│ Role:      Production                      │
│ Description: 服务器区 VLAN                 │
└────────────────────────────────────────────┘

VLAN 与 Prefix 关联:一个 Prefix 可以关联到一个 VLAN,表示这个子网跑在这个 VLAN 上:

Prefix 10.10.10.0/24 → VLAN 100 (Servers)
Prefix 10.10.20.0/24 → VLAN 200 (Management)

3.5 VRF 管理

VRF(Virtual Routing and Forwarding)用于多租户/多网络隔离:

IPAM → VRF → Add

┌────────────────────────────────────────────┐
│ Name:       prod-vrf                       │
│ RD:         65001:100                      │  ← Route Distinguisher
│ Description: 生产环境 VRF                  │
│ Tenant:     Finance-Team                   │
└────────────────────────────────────────────┘

Prefix 和 IP Address 都可以关联 VRF。不同 VRF 下同一个 IP 不算冲突(因为在不同路由表里)。


五、DCIM:数据中心基础设施管理

4.1 机架管理

DCIM → Racks → Add

┌─────────────────────────────────────────────┐
│ Name:      Rack-A01                         │
│ Site:      BJ-IDC-1                         │
│ Location:  Floor-3-Row-A                    │
│ Status:    Active                           │
│ Type:      4-post cabinet(机架形态:2-post/4-post/wall/cabinet)│
│ Width:     19 inches                        │
│ Height:    42U(U 数,不是 Type 字段)      │
│ Descending units: ☐ (从下往上编号)         │
└─────────────────────────────────────────────┘

机架视图展示每个 U 位被什么设备占用:

┌───┐
│42 │
│41 │  ┌──────────────┐
│40 │  │ core-sw-01   │  2U
│39 │  │ Catalyst 9300│
│38 │  └──────────────┘
│37 │  (空)
│36 │  ┌──────────────┐
│35 │  │ server-01    │  1U
│34 │  └──────────────┘
│.. │  ...
│ 1 │  ┌──────────────┐
│   │  │ PDU          │  1U
│   │  └──────────────┘
└───┘

4.2 设备型号(Device Type)

Device Type 是设备模板,定义接口规格,不绑定具体实例。

DCIM → Device Types → Add

┌────────────────────────────────────────────┐
│ Manufacturer:  Cisco                       │
│ Model:         C9300-48P                   │
│ Part Number:   C9300-48P-A                 │
│ Height (U):    1                           │
│ Is Full Depth: ☑ (前后都有端口)           │
│ Subdevice Role: Parent (支持子模块)        │
│                                            │
│ Interface Templates:                       │
│   Management 0  → 1000BASE-T (mgmt)       │
│   1-48          → 1000BASE-T(48 口千兆电口,P=PoE+)│
│   49-52         → 10GBASE-X(4 口 SFP+ 上联)        │
│                                            │
│ Console Port Templates:                    │
│   Console 0     → RJ45                    │
│                                            │
│ Power Port Templates:                      │
│   Power 0       → C13                     │
│   Power 1       → C13                     │
└────────────────────────────────────────────┘

Device Type 的导入方式:

# 方法 1:从官方仓库导入(推荐)
# https://github.com/netbox-community/devicetype-library
# 里面有 4000+ 常见设备型号

git clone https://github.com/netbox-community/devicetype-library.git

# NetBox → Administration → Import Data → 选择 JSON/CSV 文件

# 方法 2:手动创建
# 方法 3:API 批量导入(见第六节)

4.3 设备实例(Device)

DCIM → Devices → Add

┌────────────────────────────────────────────┐
│ Name:          core-sw-01                  │
│ Device Type:   C9300-48P                   │
│ Site:          BJ-IDC-1                    │
│ Rack:          Rack-A01                    │
│ Position (U):  39                          │  ← 机架 U 位
│ Face:          Front                       │  ← 前面/后面
│ Status:        Active                      │
│ Serial Number: FOC1234567                  │
│ Asset Tag:     ASSET-001                   │
│ Tenant:        Finance-Team                │
│ Primary IP4:   10.10.10.1/24               │  ← 管理 IP
│ Description:   核心交换机 01               │
└────────────────────────────────────────────┘

创建设备后,接口会从 Device Type 的模板自动生成。

4.4 接口(Interface)

DCIM → Devices → core-sw-01 → Interfaces

┌─────────────────────────────────────────────┐
│ Name              Type      Enabled  MTU    │
│                                             │
│ GigabitEthernet1   1000BASE-T  ✓      1500 │
│ GigabitEthernet2   1000BASE-T  ✓      1500 │
│ ...                                         │
│ TenGigabitEthernet49 10GBASE-X ✓      9216 │
│ ...                                         │
│ Vlan100             virtual    ✓      9216 │  ← SVI 接口类型是 virtual(非 L2VLAN)
│ │                                           │
│ │ └─ IP: 10.10.10.1/24                      │  ← IP 绑定到 VLAN 接口
│ │    └─ VRF: (none)                         │
│ │    └─ DNS: core-sw-01.prod.local          │
│ │                                           │
│ Management0         1000BASE-T ✓      1500 │
│ │                                           │
│ │ └─ IP: 192.168.1.11/24 (Management VRF)   │
│ └──────────────────────────────────────────┘

4.5 线缆连接(Cable)

DCIM → Cables → Add

┌───────────────────────────────────────────┐
│ Termination A:                            │
│   Device: core-sw-01                      │
│   Interface: FortyGigabitEthernet49       │
│                                           │
│ Termination B:                            │
│   Device: dist-sw-01                      │
│   Interface: FortyGigabitEthernet49       │
│                                           │
│ Type:     Cat6a (铜缆) / SMF (单模光纤)   │
│ Length:   3 m                             │
│ Color:    Yellow (光纤黄色)               │
│ Status:   Connected                       │
└───────────────────────────────────────────┘

线缆连接后,两侧接口的状态自动变为 Connected,在设备拓扑视图能看到连线关系。


六、虚拟化与集群

5.1 集群(Cluster)

Virtualization → Clusters → Add

┌───────────────────────────────────────────┐
│ Name:          vmware-cluster-1           │
│ Type:          VMware vSphere             │
│ Site:          BJ-IDC-1                   │
│ Tenant:        Finance-Team               │
└───────────────────────────────────────────┘

5.2 虚拟机(Virtual Machine)

Virtualization → Virtual Machines → Add

┌────────────────────────────────────────────┐
│ Name:          web-server-01               │
│ Cluster:       vmware-cluster-1            │
│ Status:        Active                      │
│ Role:          Web Server                  │
│ Tenant:        Finance-Team                │
│ Platform:      Ubuntu 22.04 LTS            │
│ vCPUs:         4                           │
│ Memory (MB):   8192                        │
│ Disk (GB):     100                         │
│ Primary IP4:   10.10.10.11/24              │
│ Description:   Nginx Web 服务器            │
└────────────────────────────────────────────┘

VM 也有 Interface,可以绑定 IP Address,和物理设备的 Interface 模型一致。


七、REST API 自动化

6.1 获取 API Token

NetBox Web UI → 右上角用户名 → API Tokens → Add
┌────────────────────────────────────────┐
│ Description: Ansible 自动化            │
│ Write Enabled: ☑                      │
│ Expires: (none)                        │
│ [Create]                               │
│                                        │
│ Token: 0123456789abcdef0123456789abc   │  ← 只显示一次,保存好
└────────────────────────────────────────┘

6.2 curl 示例

TOKEN="0123456789abcdef0123456789abcdef01234567"
BASE="http://localhost:8000/api"

# 列出所有 Site
curl -s -H "Authorization: Token $TOKEN" $BASE/dcim/sites/ | python3 -m json.tool

# 列出所有 Prefix
curl -s -H "Authorization: Token $TOKEN" "$BASE/ipam/prefixes/?limit=0" | python3 -m json.tool

# 从 Prefix 自动分配一个 IP
curl -s -X POST "$BASE/ipam/prefixes/1/available-ips/" \
  -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"description": "web-server-01"}' | python3 -m json.tool

# 创建设备
curl -s -X POST "$BASE/dcim/devices/" \
  -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "access-sw-01",
    "device_type": 1,
    "site": 1,
    "rack": 1,
    "position": 35,
    "face": "front",
    "status": "active"
  }' | python3 -m json.tool

# 创建 IP 地址并绑定到接口
curl -s -X POST "$BASE/ipam/ip-addresses/" \
  -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "10.10.10.12/24",
    "assigned_object_type": "dcim.interface",
    "assigned_object_id": 5,
    "description": "web-server-02"
  }' | python3 -m json.tool

# 搜索:所有属于 VLAN 编号 100 的 Prefix(vlan_vid 按编号过滤,vlan_id 按数据库主键过滤)
curl -s -H "Authorization: Token $TOKEN" \
  "$BASE/ipam/prefixes/?vlan_vid=100&limit=0" | python3 -m json.tool

6.3 pynetbox(Python 库)

pip install pynetbox
import pynetbox

nb = pynetbox.api(
    'http://localhost:8000',
    token='0123456789abcdef0123456789abcdef01234567'
)

# ── 查询 ──

# 列出所有活跃设备
devices = nb.dcim.devices.filter(status='active')
for d in devices:
    print(f"{d.name} @ {d.site.name} → {d.device_type.model}")

# 查某个 Site 的所有接口
interfaces = nb.dcim.interfaces.filter(device_id=1)
for iface in interfaces:
    print(f"{iface.name} {iface.type} enabled={iface.enabled}")

# 查某 Prefix 下已分配的 IP(status=active)
assigned_ips = nb.ipam.ip_addresses.filter(parent='10.10.10.0/24', status='active')

# 查某 Prefix 下的空闲 IP(走 available-ips 端点,不能用 filter)
prefix = nb.ipam.prefixes.get(prefix='10.10.10.0/24')
free_ips = prefix.available_ips.list()

# ── 创建 ──

# 创建设备
device = nb.dcim.devices.create(
    name='access-sw-02',
    device_type=1,
    site=1,
    rack=1,
    position=33,
    face='front',
    status='active'
)

# 从 Prefix 自动分配 IP
new_ip = nb.ipam.ip_addresses.create(
    address='10.10.10.12/24',
    assigned_object_type='dcim.interface',
    assigned_object_id=5,
    description='auto-assigned'
)

# ── 更新 ──

# 更新设备状态
device = nb.dcim.devices.get(name='access-sw-02')
device.status = 'decommissioning'
device.save()

# ── 批量操作 ──

# 批量创建接口
nb.dcim.interfaces.create([
    {'device': 1, 'name': 'GigabitEthernet0/1', 'type': '1000base-t'},
    {'device': 1, 'name': 'GigabitEthernet0/2', 'type': '1000base-t'},
    {'device': 1, 'name': 'GigabitEthernet0/3', 'type': '1000base-t'},
])

6.4 Ansible 动态清单

# ansible.cfg
[inventory]
enable_plugins = netbox.netbox.nb_inventory

# 安装 collection(推荐,替代旧版 pip install ansible-modules-netbox)
ansible-galaxy collection install netbox.netbox
# netbox.yml
plugin: netbox.netbox.nb_inventory
api_endpoint: http://localhost:8000
token: 0123456789abcdef0123456789abcdef01234567
validate_certs: false

# 按设备角色/站点/标签分组
# 注:NetBox 4.0 起 DeviceRole 已泛化为 Role,字段用 role
group_by:
  - role
  - sites
  - tags

# 只取活跃设备
query_filters:
  - status: active
# 使用动态清单
ansible all -i netbox.yml -m ping

# 只 ping 某个 Site 的设备
ansible -i netbox.yml -m ping "site_BJ-IDC-1"

# 从 NetBox 获取变量
ansible-inventory -i netbox.yml --host web-server-01 --vars

6.5 Ansible Playbook 示例

---
- name: 配置交换机接口
  hosts: "site_BJ-IDC-1"
  vars:
    netbox_url: http://localhost:8000
    netbox_token: 0123456789
  tasks:
    # 从 NetBox 拉设备信息
    - name: 获取设备信息
      uri:
        url: "{{ netbox_url }}/api/dcim/devices/?name={{ inventory_hostname }}"
        headers:
          Authorization: "Token {{ netbox_token }}"
        return_content: yes
      register: device_info

    # 从 NetBox 拉接口列表(接口是独立 API 端点,设备 API 不含 interfaces 字段)
    - name: 获取设备接口列表
      uri:
        url: "{{ netbox_url }}/api/dcim/interfaces/?device_id={{ (device_info.content | from_json).results[0].id }}"
        headers:
          Authorization: "Token {{ netbox_token }}"
        return_content: yes
      register: interface_info

    # 用接口信息配置交换机
    - name: 配置接口
      cisco.ios.ios_interfaces:
        config:
          - name: "{{ item.name }}"
            enabled: "{{ item.enabled }}"
      loop: "{{ (interface_info.content | from_json).results }}"

八、自定义与扩展

7.1 自定义字段(Custom Fields)

给任何对象加业务属性:

Admin → Customization → Custom Fields → Add

┌─────────────────────────────────────────────┐
│ Name:          asset_owner                  │
│ Type:          Text                         │
│ Object Types:   ☑ dcim.device              │
│                ☑ virtualization.virtualmachine │
│ Required:       ☐                          │
│ Default:        (none)                      │
│ Description:    资产归属人                  │
│ Filter Logic:   Filterable                  │
└─────────────────────────────────────────────┘

加完后,设备/VM 页面会多一个 asset_owner 字段,可以在列表里过滤搜索。

在设备页面加外部链接:

Admin → Customization → Custom Links → Add

┌────────────────────────────────────────────┐
│ Name:          Open in Grafana             │
│ Object Type:   dcim.device                 │
│ URL:           https://grafana.example.com/d/dashboard?var-device={{ object.name }} │
│ Button Class:  Info                        │
│ New Window:    ☑                          │
└────────────────────────────────────────────┘

7.3 Webhooks

设备状态变更时自动触发外部操作:

Admin → Operations → Webhooks → Add

┌────────────────────────────────────────────┐
│ Name:          Device-Status-Change        │
│ Content Type:   dcim.device                │
│ HTTP Method:    POST                       │
│ URL:            http://ansible-tower:8080/api/v2/job_templates/5/launch/ │
│ HTTP Content Type: application/json        │
│ Body:          {"device": "{{ object.name }}", "status": "{{ object.status }}"} │
│ Secret:         webhook-auth-token         │
│ Conditions:     {"and":[{"attr":"status.value","op":"ne","value":"active"}]} │  ← JSON 逻辑表达式(示意:status != active)│

7.4 导出模板

用 Jinja2 模板生成自定义报告:

Admin → Customization → Export Templates → Add

┌────────────────────────────────────────────┐
│ Name:          device-rack-report          │
│ Object Type:   dcim.device                 │
│ Template:                                  │
│ {% for device in queryset %}               │
│ {{ device.name }},{{ device.site.name }},{{ device.rack.name }},U{{ device.position }} │
│ {% endfor %}                               │
└────────────────────────────────────────────┘

使用:设备列表页 → 导出 → 选 device-rack-report。

7.5 GraphQL 查询

NetBox 内置 GraphQL(2.11+,v4.0 起迁移至 Strawberry 引擎):

# 查询某站点的所有设备和 IP
curl -s -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -X POST http://localhost:8000/graphql/ \
  -d '{
    "query": "{ site(name: \"BJ-IDC-1\") { devices { name device_type { model manufacturer { name } } interfaces { name ip_addresses { address } } } } }"
  }' | python3 -m json.tool

九、常用 API 速查

操作API 路径方法
列出所有 Site/api/dcim/sites/GET
列出所有 Rack/api/dcim/racks/GET
列出所有 Device/api/dcim/devices/GET
列出所有 Interface/api/dcim/interfaces/GET
列出所有 Prefix/api/ipam/prefixes/GET
列出所有 IP Address/api/ipam/ip-addresses/GET
列出所有 VLAN/api/ipam/vlans/GET
列出所有 VRF/api/ipam/vrfs/GET
列出所有 Cable/api/dcim/cables/GET
列出所有 VM/api/virtualization/virtual-machines/GET
从 Prefix 分配 IP/api/ipam/prefixes/{id}/available-ips/POST
查可用 IP/api/ipam/prefixes/{id}/available-ips/GET
查前缀内可用前缀/api/ipam/prefixes/{id}/available-prefixes/GET
按关键字搜索设备/api/dcim/devices/?name__ic=core(模糊)/ ?name=core(精确)GET
按 Site 过滤/api/dcim/devices/?site_id=1GET
按 VLAN 编号过滤 Prefix/api/ipam/prefixes/?vlan_vid=100(vlan_id 是数据库主键)GET
按租户过滤 IP/api/ipam/ip-addresses/?tenant_id=1GET
更新设备/api/dcim/devices/{id}/PATCH
删除设备/api/dcim/devices/{id}/DELETE

分页参数:

参数作用
limit=0返回所有(不分页,大查询慎用)
limit=50每页 50 条(默认 50)
offset=100跳过前 100 条

十、排障

排障 1:无法登录 / 403 Forbidden

# 1. 检查 ALLOWED_HOSTS 是否包含你的域名(Docker 模式下从环境变量注入,不在 configuration.py)
docker compose exec netbox env | grep ALLOWED

# 2. 检查 Token 是否正确
curl -H "Authorization: Token YOUR_TOKEN" http://localhost:8000/api/dcim/sites/
# 返回 403 → Token 写错了或没权限

# 3. 检查用户是否激活
docker compose exec netbox /opt/netbox/netbox/manage.py shell
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='admin')
>>> print(u.is_active, u.is_superuser)

排障 2:Docker 容器启动失败

# 1. 看 postgres 起了没
docker compose ps postgres
# 如果 Exited → 磁盘满或密码不对

# 2. 看 redis 起了没
docker compose ps redis

# 3. 看 netbox 日志
docker compose logs netbox | tail -30
# 常见报错:
#   "could not connect to server" → postgres 没起或网络不通
#   "relation does not exist" → 数据库没迁移 → docker compose exec netbox /opt/netbox/netbox/manage.py migrate

排障 3:数据库迁移失败

# 手动执行迁移
docker compose exec netbox /opt/netbox/netbox/manage.py migrate

# 如果报 "already exists" → 数据库和代码版本不匹配
# 方法 1:降级回旧版镜像
# 先编辑 docker-compose.yml 将 netbox 服务的 image 改为 netboxcommunity/netbox:v3.5.0
docker compose pull netbox
docker compose up -d

# 方法 2:从备份恢复
cat netbox-backup.sql | docker compose exec -T postgres psql -U netbox

排障 4:API 返回空结果

# 1. 检查过滤条件
curl -s -H "Authorization: Token $TOKEN" \
  "http://localhost:8000/api/dcim/devices/?site_id=999" | python3 -m json.tool
# site_id=999 不存在 → 返回空 results 但不是报错

# 2. 检查权限
# 某些 Token 只读 → 不能 POST
curl -s -X POST -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"test"}' http://localhost:8000/api/dcim/sites/
# 返回 403 → Token 没开 Write

# 3. 检查分页
# 默认只返回前 50 条
curl -s -H "Authorization: Token $TOKEN" \
  "http://localhost:8000/api/dcim/devices/?limit=0"  # limit=0 = 全部

排障 5:IP 冲突 / 无法分配

# 看看这个 IP 是不是已经被占用了
curl -s -H "Authorization: Token $TOKEN" \
  "http://localhost:8000/api/ipam/ip-addresses/?address=10.10.10.11"
# 如果有结果 → 这个 IP 已被分配

# 强制使用已被分配的 IP → 先删除旧的或改 status=reserved
curl -s -X PATCH -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "deprecated"}' \
  "http://localhost:8000/api/ipam/ip-addresses/5/"

排障 6:Device Type 导入失败

# 常见原因:Manufacturer 不存在
# Device Type 必须关联一个已存在的 Manufacturer

# 先建 Manufacturer
curl -s -X POST -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Cisco", "slug": "cisco"}' \
  http://localhost:8000/api/dcim/manufacturers/

# 再导入 Device Type
# 从 devicetype-library 仓库拉 JSON
# 或手动创建

排障 7:机架视图 U 位不显示设备

原因:设备没填 Position (U) 或设备 U 数为 0
# 检查设备
curl -s -H "Authorization: Token $TOKEN" \
  "http://localhost:8000/api/dcim/devices/?name=core-sw-01" | python3 -m json.tool
# 看 "position" 和 "device_type" 的 "u_height"

# 修复:设置 position
curl -s -X PATCH -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"position": 39, "face": "front"}' \
  "http://localhost:8000/api/dcim/devices/1/"

排障 8:Cable 连接不显示

原因:Cable 的两个 Termination 之一状态不对
检查:
1. 两个 Interface 都存在且 enabled
2. 两个 Interface 不能在同一个 Device 上
3. Interface 类型兼容(以太网↔以太网,串口↔串口)
4. 创建 Cable 后 Interface 状态自动变 Connected

排障 9:Redis 连接失败

docker compose logs netbox | grep -i redis
# 报 "Error 111 connecting to redis" → redis 容器没起

# 修复
docker compose up -d redis
# 等 redis 健康后再起 netbox
docker compose restart netbox

排障 10:升级后页面 500

# 大概率是静态文件没收集
docker compose exec netbox /opt/netbox/netbox/manage.py collectstatic --noinput

# 还是 500 → 看详细错误
docker compose exec netbox /opt/netbox/netbox/manage.py runserver 0.0.0.0:8000
# 直接看 traceback

排障 11:Nginx 502 / Connection Refused

# netbox 在跑吗
docker compose ps netbox
# 如果 Exited → docker compose logs netbox 看报错

# 端口对不对
ss -tlnp | grep 8000
# 没有监听 → netbox 没起或端口没映射

# Nginx 反代配置里 proxy_pass 地址对不对
# 应该是 http://127.0.0.1:8000

排障 12:pynetbox 报 ObjectNotFound

# 用 .get() 找不到时报 ObjectNotFound
# 原因:名字写错或对象不存在

# 排查
import pynetbox
nb = pynetbox.api('http://localhost:8000', token='...')
# 列出所有看名字
for d in nb.dcim.devices.all():
    print(d.name)

# 用 filter 而不是 get
devices = nb.dcim.devices.filter(name__isw='core')  # isw = starts with(大小写不敏感)
# 包含匹配用 name__ic='core',精确匹配用 name='core'

十一、最佳实践

10.1 数据录入规范

  1. 先建厂商和设备型号:从 devicetype-library 仓库批量导入 4000+ 型号,省去手动创建
  2. IP 管理用 API 不用手动:自动分配防冲突,人类手动填必出错
  3. VLAN 统一编号:全公司 VLAN ID 唯一,不要每个站点自己编一套
  4. VRF 区分多租户:不同业务线共享 IP 段时用 VRF 隔离
  5. Cable 必填:不画线缆连接的 NetBox 只是半个 CMDB
  6. Device Serial Number 必填:保修和资产追踪靠这个
  7. Tenant 给所有资源打标签:按租户/业务线过滤是最常用查询

10.2 与其他工具集成

工具集成方式用途
Ansible动态清单 + API用 NetBox 数据驱动配置
TerraformProvider用 NetBox 做 IP 分配
GrafanaJSON API 数据源仪表盘展示基础设施状态
PrometheusNetBox Exporter监控指标 + CMDB 关联
NetDiscoAPI 对账NetDisco 自动发现 → 写入 NetBox
GitLab CIAPI管道里自动注册设备

10.3 安全建议

项建议
Token 权限按需开 Write,只读 Token 更安全
用户管理开 LDAP/OIDC,别只用本地密码
HTTPS生产必须反代 + 证书
备份pg_dump 每天 cron
审计Webhook 记录变更到外部系统
升级先备份 → 再升级 → 看迁移日志

10.4 推荐插件

插件功能安装
netbox-topology-views拓扑图可视化pip install netbox-topology-views
netbox-bgpBGP 会话管理pip install netbox-bgp
netbox-ddnsDNS 动态更新pip install netbox-ddns
netbox-plugin-dnsDNS 记录管理pip install netbox-plugin-dns
(已弃用)netbox-reports自定义合规检查NetBox 3.5 弃用、v4.0 移除,功能并入 Custom Scripts(内置)
# 安装插件
# 1. Docker 模式:在 configuration/plugins.py 里加
echo "PLUGINS = ['netbox_topology_views']" >> /opt/netbox/netbox/netbox/configuration/plugins.py

# 2. 重启
docker compose restart netbox

# 3. 迁移
docker compose exec netbox /opt/netbox/netbox/manage.py migrate

十二、运维常用操作

# 查看 NetBox 版本(无 manage.py version 子命令,走 API)
curl -s -H "Authorization: Token $TOKEN" http://localhost:8000/api/status/ | python3 -m json.tool | grep netbox_version

# 创建超级用户
docker compose exec netbox /opt/netbox/netbox/manage.py createsuperuser

# 重置用户密码
docker compose exec netbox /opt/netbox/netbox/manage.py changepassword admin

# 收集静态文件
docker compose exec netbox /opt/netbox/netbox/manage.py collectstatic --noinput

# 数据库迁移
docker compose exec netbox /opt/netbox/netbox/manage.py migrate

# 进入 Django shell
docker compose exec netbox /opt/netbox/netbox/manage.py shell

# 备份数据库
docker compose exec postgres pg_dump -U netbox netbox > backup-$(date +%Y%m%d).sql

# 恢复
cat backup-20260828.sql | docker compose exec -T postgres psql -U netbox

# 清理旧 session
docker compose exec netbox /opt/netbox/netbox/manage.py clearsessions

# 清理变更日志(保留 90 天)
docker compose exec netbox /opt/netbox/netbox/manage.py \
  shell -c "from datetime import datetime, timedelta; from extras.models import ObjectChange; ObjectChange.objects.filter(time__lt=datetime.now()-timedelta(days=90)).delete()"
问问 AI