IOS-XE ZTP操作指南

一台网络设备上线之后,需要先完成大量的配置,它才能开始工作。通常的做法是,在设备上线之前,先安排几位工程师,找一块场地,把所有设备拆箱、加电、刷配置,然后再上架。这样做,不仅浪费人力和时间,还很容易出错。通过一些Day Zero Automation技术可以将这些配置工作自动化地完成,节省项目实施的时间,避免初始化配置时出现人为操作错误。

使用IOS XE操作系统的Cisco交换机和路由器支持3种Day0 Automation技术:iPXE、ZTP和PnP。其中PnP依赖于DNA Center,成本稍微高一些,但得到的是一个“交钥匙工程”,用户基本上不需要付出技术成本,还能够得到Software Image Management (SWIM)等增值服务。PXE和ZTP则是开源的解决方案。

图片来源:https://developer.cisco.com/docs/ios-xe/#!day-zero-provisioning-quick-start-guide/day-zero-automation

Catalyst 3650/3850/9200/9300L/9300/9400/9500系列交换机支持iPXE(需满足特定的IOS XE版本要求)。但使用iPXE有一个很重要的限制:Catalyst交换机默认的Boot mode是本地启动。如果要启用iPXE,需要先在CLI做一些配置:

Device# configure terminal
Device(config)# boot ipxe forever switch 1
Device(config)# end
Device# copy run start

通常,在实施一个园区网项目的时候,如果有条件为每台交换机做预配置启用iPXE,还不如直接把完整的配置灌进去了。所以,我们更倾向于选择ZTP作为Catalyst网络设备Day0 Operation的方式,而不是iPXE。

下图是ZTP的工作流程。有几个关键节点:

  • DHCP Option
  • Guest Shell
  • Python脚本
IOSXE ZTP流程

DHCP Option

DHCP Server通过DHCP Option来告诉DHCP Client从哪里下载Python脚本文件。下载的方式可以是HTTP,也可以是TFTP。如果规划使用HTTP Server提供文件下载,则仅用DHCP Option 67为DHCP Client提供文件的URL。

IOS-XE设备配置DHCP Server和Option 67的命令如下:

Device(config)# ip dhcp excluded-address 10.1.1.1
Device(config)# ip dhcp pool pnp_device_pool
Device(config-dhcp)# network 10.1.1.0 255.255.255.0
Device(config-dhcp)# default-router 10.1.1.1  
Device(config-dhcp)# option 67 ascii http://192.168.1.1:8000/python_script.py
Device(config-dhcp)# end

Linux dhcpd.conf配置如下:

subnet 10.1.1.0 netmask 255.255.255.0 {
  range 10.1.1.2 10.1.1.255;
  option bootfile-name "http://192.168.1.1:8000/python_script.py";
}

如果规划使用TFTP Server提供文件下载,则需同时使用Option 150和67。其中Option 150的作用是将TFPT Server的IP地址告诉DHCP Client;Option 67的作用是为DHCP Client提供文件的Path。

IOS-XE设备配置DHCP Server、Option 150和Option 67的命令如下:

Device(config)# ip dhcp excluded-address 10.1.1.1
Device(config)# ip dhcp pool pnp_device_pool
Device(config-dhcp)# network 10.1.1.0 255.255.255.0
Device(config-dhcp)# default-router 10.1.1.1 
Device(config-dhcp)# option 150 ip 192.168.1.1 
Device(config-dhcp)# option 67 ascii /sample_python_dir/python_script.py
Device(config-dhcp)# end

Linux dhcpd.conf配置如下:

subnet 10.1.1.0 netmask 255.255.255.0 {
  range 10.1.1.2 10.1.1.255; 
  option bootfile-name "/sample_python_dir/python_script.py";
  option tftp-server-name "192.168.1.1"; 
}

Guest Shell

Guestshell是Cisco IOS XE设备内置的一个Linux环境,用户可以自行安装并运行软件包或脚本,而无需担心对网络设备的运行会产生影响,因为它与宿主机是解耦的。Guestshell已经安装了Python和常用的库,用户可以使用pip installyum install或者rpm -i安装软件包。Python版本为:

  • IOS XE 17.3.1以前的版本:Python 2.7,默认Python V2
  • 从IOS XE 17.1.1开始:支持Python 3.6,并且从IOS XE 17.3.1开始,默认Python V3

在ZTP的工作流程中,IOS XE设备需要下载Python脚本然后在Guest Shell里面运行,完成设备的升级和配置工作。到目前为止,除了Catalyst 9200L以外的所有C9K交换机都支持Guest Shell,这也意味着9200L交换机不支持ZTP,但其他所有型号的C9K都可以支持ZTP。另外,Catalyst 3650和3850也支持Guest Shell和ZTP。

Python脚本

git clone https://github.com/jeremycohoe/IOSXE-Zero-Touch-Provisioning.git

Clone之后,把里面的ztp-advanced.py简单改改就可以直接用了。请注意,这是一个Python2的脚本,如果设备出厂的IOS XE是17.3.1或者更高版本,需要将脚本修改成Python3。程序运行逻辑如下:

def main():
    # 获取设备序列号,并指定以序列号命名的Config文件
    serial = get_serial()
    config_file = "{}.cfg".format(serial)

# 判断设备IOS版本是否是Golden image,如果不是,则需要升级
if upgrade_required():
# 检查Golden image是否已经存在于设备Flash
if check_file_exists(img_cat9k):
# 如果Flash里面有image文件,则校验其MD5 checksum
if not verify_dst_image_md5(img_cat9k, img_cat9k_md5):
# 如果MD5 checksum有误,则重新下载image
file_transfer(tftp_server, img_cat9k)
if not verify_dst_image_md5(img_cat9k, img_cat9k_md5):
# 如果重新下载的image仍然MD5 checksum校验失败,则打印错误,退出程序
raise ValueError(‘Failed Xfer’)
else:
# 如果Flash里面没有image文件,则下载image
file_transfer(tftp_server, img_cat9k)
# 如果下载的image MD5 checksum校验失败,则打印错误,退出程序
if not verify_dst_image_md5(img_cat9k, img_cat9k_md5):
raise ValueError(‘XXX Failed Xfer XXX’)

# 给宿主机(网络设备)配置EEM脚本,用于升级IOS版本
deploy_eem_upgrade_script(img_cat9k)
# 在宿主机上运行EEM脚本,开始升级IOS版本
cli(‘event manager run upgrade’)
time.sleep(600)

# 给宿主机配置EEM脚本,用于升级之后清理inactive镜像文件
deploy_eem_cleanup_script()
# 在宿主机上运行EEM脚本,清理inactive镜像文件
cli(‘event manager run cleanup’)
time.sleep(30)

# 检查设备Flash上是否存在待部署的Config文件,如果不存在,则下载Config文件
if not check_file_exists(config_file):
file_transfer(tftp_server, config_file)
time.sleep(10)
# 设备自带的证书都删除
find_certs()
time.sleep(10)

try:
# 在网络设备上执行configure replace xxx force命令,用Config文件强行替换设备原有的config
configure_replace(config_file)
# 重新生成证书
configure(‘crypto key generate rsa modulus 4096’)
except Exception as e:
pass

项目实操流程

1. 准备设备清单和变量表

通常设备供货商可以提供Excel格式的设备清单,里面包含序列号和产品型号等信息。可以根据这个表格制作变量表。如果没有现成的表格,则需要用扫码枪或者手机安装APP把所有设备的条形码扫一遍,再导出表格。

表格可以是.csv或者.xls等格式,取决于你选择的Python库。本文使用.csv格式。下面是一个简单的例子,所有接入交换机的配置都一样,只有主机名和管理IP地址不同。

请注意,表格的列头就是变量名,不能有中文字符。

pid,serial_number,asset_number,hostname,mgmt_ip,mgmt_ip_mask,mgmt_gw
C9300-48T,SN11111111,ASSET11111,SZ-Campus-Floor1-1,10.1.1.1,255.255.255.0,10.1.1.255
C9300-48T,SN22222222,ASSET22222,SZ-Campus-Floor2-2,10.2.2.2,255.255.255.0,10.2.2.255
C9300-48T,SN33333333,ASSET33333,SZ-Campus-Floor3-3,10.3.3.3,255.255.255.0,10.3.3.255

2. 准备配置模版

可以参考我以前写的使用 Jinja2 模版生成网络设备配置文件。因为这个例子只有4个变量,所以就不把Jinja模版贴出来了。

3. 为每一个序列号生成一份配置文件

根据CSV格式的变量表,和Jinja模版,写一个Python脚本,为每一个序列号生成一份配置文件。下面是一个简单的Example:

import jinja2
from os import mkdir, path
from csv import DictReader

# Global variables
WORK_DIR = ‘./’
OUTPUT_DIR = path.join(WORK_DIR, ‘configs’)
CSV = path.join(WORK_DIR, ‘inventory.csv’)
JINJA_TEMPLATE = path.join(WORK_DIR, ‘template.j2’)

# Create configs directory if not created already
def check_output_dir_exists():
if not path.exists(OUTPUT_DIR):
mkdir(OUTPUT_DIR)

# Read devices and vars
def get_devices(csv_file):
devices = []
with open(csv_file, mode=‘r’as f:
rows = DictReader(f)
for row in rows:
devices.append(row)
return devices

# Read jinja template
def get_template(jinja_file):
with open(jinja_file, mode=‘r’as f:
template = jinja2.Template(f.read())
return template

# Generate config files
def generate_configs(csv_file, jinja_file):

check_output_dir_exists()
devices = get_devices(csv_file)
template = get_template(jinja_file)

for device in devices:
serial_number = device[‘serial_number’]
output_file = path.join(OUTPUT_DIR, ‘.’.join([serial_number, ‘cfg’]))
with open(output_file, mode=‘w’, encoding=‘utf-8’as f:
f.write(template.render(device))

if __name__ == “__main__”:
generate_configs(CSV, JINJA_TEMPLATE)

4. 准备Guestshell Python脚本,配置HTTP/TFTP Server和DHCP Server

按照上文的介绍,准备Guestshell Python脚本,配置HTTP/TFTP Server和DHCP Server,把Python脚本,安装镜像和配置文件都上传到HTTP/TFTP Server。

对于带内网管且管理VLAN ID不为1的场景,需要在汇聚交换机上创建一个ZTP专用VLAN并配置Native VLAN,DHCP Relay或DHCP Server。相应地,接入交换机的Jinja配置模版需要shutdown vlan1。然后就可以执行ZTP部署了。

5. 复杂场景的最佳实践

如果您的场景比较复杂,建议按照功能制作多个变量表,再合并生成配置文件。另外,对于这种复杂操作,建议增加配置校验的步骤。具体的操作方法可以参考:

git clone https://github.com/Tes3awy/Cisco-Configuration-Using-Python-Jinja-CSV.git

 

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇