05-H3C_IRF零配置举例
本章节下载: 05-H3C_IRF零配置举例 (278.03 KB)
H3C IRF零配置典型举例
资料版本:6W100-20201031
产品版本:Release 7595
Copyright © 2020 新华三技术有限公司 版权所有,保留一切权利。 非经本公司书面许可,任何单位和个人不得擅自摘抄、复制本文档内容的部分或全部,并不得以任何形式传播。 除新华三技术有限公司的商标外,本手册中出现的其它公司的商标、产品标识及商品名称,由各自权利人拥有。 本文档中的信息可能变动,恕不另行通知。 |
目 录
本文档主要介绍了如何通过自动配置和Python功能使设备自动组成IRF。
本文档中的配置均是在实验室环境下进行的配置和验证,配置前设备的所有参数均采用出厂时的缺省配置。如果您已经对设备进行了配置,为了保证配置效果,请确认现有配置和以下举例中的配置不冲突。
本文档假设使用的设备均处于独立运行模式。
本文档假设您已了解IRF、Python和自动配置的特性。
只有相同型号的机框之间才能建立IRF。建议您在进行IRF零配置时的所有成员设备上均使用相同的单板配置方案,即选用的单板数量及型号、安装槽位号、以及对应 单板的工作模式设置等都保持一致。
如图1所示,某公司两台设备Device A和Device B放置在距离网络管理员较远的地方,所有设备的物理连接已经完成。为了简少网络配置的工作量,需要该公司的管理员通过设备的IRF零配置功能对两台设备进行一定的初始配置。现要求通过IRF零配置实现以下功能:
· Device A和Device B自动组成IRF。
· 网络管理员能够通过Telnet方式远程登录Device A和Device B组成的IRF设备。
· 登录Device A和Device B虚拟成的IRF设备时需要密码认证。
图1 IRF零配置组网图
· 为了保证IRF零配置的成功执行,需要在Device A和Device B上电启动之前按图1所示将网络环境搭建完成,将进行IRF零配置所需的文件准备好并存储在HTTP服务器上,同时要保证DHCP服务器上已经配置完成。Device A和Device B启动时会先从HTTP server下载Python脚本,然后根据Python脚本中的命令控制整个IRF零配置的流程。关于IRF零配置的所需文件的详细介绍,请参见“4.3.2 准备HTTP Server上的配置文件”。
· 当设备初次上电会自动进入自动配置的流程;当设备中不存在下次启动配置文件的时候,设备启动以后也可以进入到自动配置的流程。
· 为了使设备能成功组成IRF,必须保证Device A和Device B所使用的软件版本相同,所以Python脚本中添加了为Device A和Device B加载相同的启动软件版本的内容。
# 启动DHCP服务,创建名称为1的DHCP地址池,配置地址池动态分配IP地址的网段为192.168.1.0/24。
<DeviceC> system-view
[DeviceC] dhcp enable
[DeviceC] dhcp server ip-pool 1
[DeviceC-dhcp-pool-1] network 192.168.1.0 24
# 配置DHCP客户端远程启动文件为HTTP形式的URL。
[DeviceC-dhcp-pool-1] bootfile-name http://192.168.1.40/device.py
[DeviceC-dhcp-pool-1] quit
(1) 创建Python脚本device.py并保存到HTTP服务器上。Python脚本是设备进行IRF零配置操作的主要文件,需要用户自行准备并保存在HTTP服务器上。Python脚本需要完成的主要操作:
· 判断Flash是否存在足够的存储空间(请用户根据实际情况进行判断);
· 从HTTP服务器下载配置文件;
· 从HTTP服务器下载启动软件包;
· 从HTTP服务器下载sn.txt文件;
· 配置设备下次启动时使用的启动软件包;
· 解析sn.txt文件并修改设备的IRF成员编号;
· 配置设备下次启动时使用的配置文件;
· 重新启动设备。
Python脚本的具体内容如下(Python脚本中标注有简单的中文注释,使用时请将中文注释删除):
#!usr/bin/python
import comware
from time import strftime,gmtime,sleep
import signal
import os
import string
import commands
import hashlib
#python_config_file_mode
#'python_static'
#python_serial_number
#U can use 2 modes to obtain the config file
#- 'python_static'
#- 'python_serial_number'
python_config_file_mode = "python_serial_number"
#配置本次软件升级设备flash所需的最小剩余空间,单位为KB
#Required space to copy config kickstart and system image in KB
required_space = 500000
#配置HTTP服务器的相关参数:用户名、密码、HTTP服务器IP地址、VPN实例名称、登录的超时时间
#transfer information
username = ""
password = ""
hostname = "192.168.1.40"
protocol = "http"
vrf = ""
config_timeout = 120
irf_timeout = 120
image_timeout = 2100
#HTTP服务器的下载路径
#Server File Path
server_path = ""
#下载到本地设备时,存放到Flash根目录下
#Loacl File path
local_path = "flash:/"
#下载到设备之后的配置文件名
#Local config name
config_local_name = "startup.cfg"
#HTTP服务器上的配置文件名
#Server config name
config_server_name = "startup.cfg"
#下载到本地的启动软件包
#Local boot name
boot_local_name = "S12500G.ipe"
#HTTP服务器上的启动软件包
#Server boot name
boot_server_name = " S12500G.ipe"
#下载到本地的SN文件名
#Local irf name
irf_local_name = "sn.txt"
#HTTP服务器上的sn文件名
#Server irf name
irf_server_name = "sn.txt"
#设备本地上记录升级日志的log文件名
python_log_name = ""
#在设备上记录升级日志的方法
#Write Log File
def write2Log(info):
global python_log_name, local_path
if python_log_name == "":
try:
python_log_name = "%s%s_python_%s_script.log" %(local_path, strftime("%Y%m%d%H%M%S", gmtime()), os.getpid())
except Exception as inst:
print inst
fd = open(python_log_name, "a")
fd.write(info)
fd.flush()
fd.close()
#获取设备的chassis号和slot号,与前面定义的local_path变量,共同计算出文件本地的存放路径
# get path according to the Chassis and Slot
def getPath(chassisID, slotID):
global local_path
path = ""
obj = comware.get_self_slot()
if (obj[0] == chassisID) and (obj[1] == slotID):
return local_path
if chassisID != -1:
path = "chassis%d#" % chassisID
if slotID != -1:
path = "%sslot%d#%s" %(path, slotID, local_path)
return path
#删除下载到本地的文件
#Remove File
def removeFile(filename):
try:
os.remove(filename)
except os.error:
pass
#计算该设备需要删除的文件数量
#Cleanup one device temp files
def cleanDeviceFiles(str, oDevNode):
global config_local_name, boot_local_name, irf_local_name
sFilePath = getPath(oDevNode[0], oDevNode[1])
if str == "error":
removeFile("%s%s" %(sFilePath, config_local_name))
removeFile("%s%s" %(sFilePath, boot_local_name))
removeFile("%s%s" %(sFilePath, irf_local_name))
removeFile("%s%s.md5" %(sFilePath, config_local_name))
removeFile("%s%s.md5" %(sFilePath, boot_local_name))
removeFile("%s%s.md5" %(sFilePath, irf_local_name))
write2Log("\ndelete %s all files\n" %sFilePath)
print "\ndelete %s all files" %sFilePath
#Cleanup files
def cleanupFiles(str):
aSlotRange = []
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
aSlotRange.append(comware.get_self_slot())
i = 0
while i < len(aSlotRange):
if(aSlotRange[i] != None):
cleanDeviceFiles(str, aSlotRange[i])
i = i + 1
#计算设备flash上的剩余空间大小
#Verify if free space is available to download config, boot-loader image
def verifyfreespace(path):
global required_space
try:
s = os.statvfs(path)
freespace = (s.f_bavail * s.f_frsize) /1024
write2Log("\nthe %s free space is %s" %(path, freespace))
print "\n####the %s free space is %s####" %(path, freespace)
if required_space > freespace:
write2Log("\nthe %s space is not enough" % path)
print "\n####the %s space is not enough####" % path
return False
except Exception as inst:
write2Log("\nverify %s free space exception: %s" % (path, inst))
print "\n####verify %s free space exception: %s####" % (path, inst)
return False
return True
#判断设备上的剩余空间是否充足
#verify device freespace
def verifyDeviceFree(obj):
path = getPath(obj[0], obj[1])
if True != verifyfreespace(path):
return False
return True
#check all mpu free space
def verifyAllFreeSpace():
aSlotRange = []
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
aSlotRange.append(comware.get_self_slot())
bAllEnough = True
i = 0
while i < len(aSlotRange):
if(aSlotRange[i] != None) and (True != verifyDeviceFree(aSlotRange[i])):
bAllEnough = False
i = i + 1
return bAllEnough
def doExit(str):
if str == "success":
write2Log("\nThe script is running success!")
print "\n#### The script is running success! ####"
cleanupFiles("success")
comd = "reboot force"
comware.CLI(comd, False)
exit(0)
if str == "error":
write2Log("\nThe script is running failed!")
print "\n#### The script is running failed! ####"
cleanupFiles("error")
exit(1)
else:
exit(0)
#获取软件升级时chassis号和slot号参数
#get Chassis and Slot
def getChassisSlot(style):
if style == "master":
obj = comware.get_self_slot()
if len(obj) <= 0:
write2Log("\nget %s chassis and slot failed" % style)
print "\n####get %s chassis and slot failed####" % style
return None
return obj
#获取启动软件包发生错误返回的信息
#signal terminal handler function
def sig_handler_no_exit(signum, function):
write2Log("\nSIGTERM Handler while configuring boot-loader variables")
print "\n####SIGTERM Handler while configuring boot-loader variables####"
#软件升级过程发生错误时返回的信息
#signal terminal handler
def sigterm_handler(signum, function):
write2Log("\nSIGTERM Handler")
print "\n####SIGTERM Handler####"
cleanupFiles("error")
doExit("error")
#从HTTP服务器上下载文件
#transfer file
def doCopyFile(src = "", des = "", login_timeout = 10):
global username, password, hostname, protocol, vrf
print "INFO: Starting Copy of %s" % src
try:
removeFile(des)
obj = comware.Transfer(protocol, hostname, src, des, vrf, login_timeout, username, password)
if obj.get_error() != None:
write2Log("\ncopy %s failed: %s" % (src, obj.get_error()))
print "\n####copy %s failed: %s####" % (src, obj.get_error())
return False
except Exception as inst:
write2Log("\ncopy %s exception: %s" % (src, inst))
print "\n####copy %s exception: %s####" % (src, inst)
return False
write2Log("\ncopy file %s to %s success" % (src, des))
print "INFO: Completed Copy of %s" % src
return True
#Get MD5SUM from md5ConfigFile
def getMD5SumGiven(keyword, filename):
try:
file = open(filename, "r")
line = file.readline()
while "" != line:
if not string.find(line, keyword, 0, len(keyword)):
line = line.split("=")
line = line[1]
line = line.strip()
file.close()
return line
line = file.readline()
file.close()
except Exception as inst:
write2Log("\nget %s md5 exception: %s" % (filename, inst))
print "\n####get %s md5 exception: %s####" % (filename, inst)
return ""
#verify MD5SUM of the file
def verifyMD5sumofFile(md5sumgiven, filename):
if md5sumgiven == "":
write2Log("\nverify %s md5 error: the %s md5 file is error" %(filename, filename))
print "\n####verify %s md5 error: the %s md5 file is error####" %(filename, filename)
return False
try:
m = hashlib.md5()
f = open(filename, 'rb')
buffer = 8192
while 1:
chunk = f.read(buffer)
if not chunk:
break
m.update(chunk)
f.close()
md5calculated = m.hexdigest()
except Exception as inst:
write2Log("\nverify %s md5 exception: %s" % (filename, inst))
print "\n####verify %s md5 exception: %s####" % (filename, inst)
return False
if md5sumgiven == md5calculated:
return True
write2Log("\nverify %s md5 error: md5sumgiven is %s filemd5 is %s" %(filename, md5sumgiven, md5calculated))
print "\n####verify %s md5 error: md5sumgiven is %s filemd5 is %s####" %(filename, md5sumgiven, md5calculated)
return False
#Check MD5 file
def checkFile(src, dest):
src = "%s.md5" % src
destmd5 = "%s.md5" % dest
bFlag = doCopyFile(src, destmd5, 120)
if (True == bFlag) and (True == verifyMD5sumofFile(getMD5SumGiven("md5sum", destmd5), dest)):
write2Log("\ncheckFile success: %s" % destmd5)
print "\n####checkFile success: %s####" % destmd5
return True
elif (True != bFlag):
write2Log("\n%s is not exist! Don't verify the MD5 file!" % destmd5)
print "INFO: %s is not exist! Don't verify the MD5 file!" % destmd5
return True
return False
#Get config file according to the mode
def getCfgFileName():
global config_server_name
if (python_config_file_mode == "python_serial_number") and (os.environ.has_key('DEV_SERIAL')):
config_server_name = "%s.cfg" % os.environ['DEV_SERIAL']
return config_server_name
else:
return config_server_name
#copy file to all standby slot
def syncFileToStandby(sSrcFile, sFileName):
try:
aSlotRange = []
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
i = 0
while i < len(aSlotRange):
if(aSlotRange[i] != None):
sDestFile = "%s%s" %(getPath(aSlotRange[i][0], aSlotRange[i][1]), sFileName)
removeFile(sDestFile)
open(sDestFile,"wb").write(open(sSrcFile,"rb").read())
write2Log("\nsync file to standby %s" % (sDestFile))
print "\n####sync file to standby %s####" % (sDestFile)
i = i + 1
except Exception as inst:
write2Log("\nsync file to standby %s exception: %s" % (sSrcFile, inst))
print "\n####sync file to standby %s exception: %s####" % (sSrcFile, inst)
#根据脚本开始处定义的全局变量,下载启动软件包、配置文件、sn文件等
#Procedure to copy config file using global information
def copyAndCheckFile(src, dest, timeout):
global server_path, local_path
srcTmp = "%s%s" % (server_path, src)
sDestFile = "%s%s" % (local_path, dest)
if (True == doCopyFile(srcTmp, sDestFile, timeout)) and (True == checkFile(srcTmp, sDestFile)):
syncFileToStandby(sDestFile, dest)
return True
else:
srcTmp = "%sdefault_%s" %(server_path, src)
if (True == doCopyFile(srcTmp, sDestFile, timeout)) and (True == checkFile(srcTmp, sDestFile)):
syncFileToStandby(dest)
return True
return False
# split the Chassis and Slot
def splitChassisSlot(chassisID, slotID):
chassis_slot = ""
if chassisID != -1:
chassis_slot = " chassis %d" % chassisID
if slotID != -1:
chassis_slot = "%s slot %d" %(chassis_slot, slotID)
return chassis_slot
#从HTTP服务器上下载启动软件包
def copyBootImage():
global image_timeout, local_path, boot_server_name, boot_local_name
src = "%s" % boot_server_name
return copyAndCheckFile(src, boot_local_name, image_timeout)
#从HTTP服务器上下载配置文件
def copyCfgFile():
global config_timeout, local_path, config_local_name
src = "%s" % getCfgFileName()
return copyAndCheckFile(src, config_local_name, config_timeout)
#从HTTP服务器上下载sn.txt文件
def copyIrfStack():
global irf_timeout, local_path, irf_local_name, irf_server_name
src = "%s" % irf_server_name
return copyAndCheckFile(src, irf_local_name, config_timeout)
#执行boot-loader命令,为设备指定下次主用启动文件
# Procedure to Install Boot Image
def installBoot(chassis_slot, sFile, style):
result = None
write2Log("\ninstall%s%s begin" %(chassis_slot, style))
print "INFO: Install%s%s Start, Please Wait..." %(chassis_slot, style)
comd = "boot-loader file %s%s%s" % (sFile, chassis_slot, style)
try:
result = comware.CLI(comd, False)
if result == None:
write2Log("\nboot-loader file %s%s%s failed" % (sFile, chassis_slot, style))
print "\n####boot-loader file %s%s%s failed####" % (sFile, chassis_slot, style)
return False
except Exception as inst:
write2Log("\nboot-loader %s exception: %s" % (sFile, inst))
print "\n####boot-loader %s exception: %s####" % (sFile, inst)
return False
return True
#Procedure to install boot image
def installBootImage():
global boot_local_name
aSlotRange = [comware.get_self_slot()]
if ("get_standby_slot" in dir(comware)):
aSlotRange = aSlotRange + comware.get_standby_slot()
bInstallOk = True
i = 0
while i < len(aSlotRange):
sFile = "%s%s" %(getPath(aSlotRange[0][0], aSlotRange[0][1]), boot_local_name)
if False == installBoot(splitChassisSlot(aSlotRange[i][0], aSlotRange[i][1]), sFile, " main"):
bInstallOk = False
i = i + 1
return bInstallOk
#执行startup saved-configuration命令为设备指定下次启动配置文件
def startupCfg():
global local_path, config_local_name
result = None
dest = "%s%s" %(local_path, config_local_name)
write2Log("\nstartup saved-configuration %s begin" %dest)
print "INFO: Startup Saved-configuration Start"
comd = "startup saved-configuration %s main" % dest
try:
result = comware.CLI(comd, False)
if result == None:
write2Log("\nstartup saved-configuration %s failed" % dest)
print "\n####startup saved-configuration %s failed####" % dest
return False
except Exception as inst:
write2Log("\nstartup %s exception: %s" % (dest, inst))
print "\n####startup %s exception: %s####" % (dest, inst)
return False
write2Log("\nstartup saved-configuration %s success" % dest)
print "INFO: Completed Startup Saved-configuration"
return True
def getIrfCfg(line, num):
line = line.split()
number = None
if 3 == len(line):
number = line[num]
else :
number = None
return number
def getMemberID():
aMemId = comware.get_self_slot()
memId = None
if aMemId[0] == -1 :
memId = aMemId[1]
else :
memId = aMemId[0]
return memId
def getNewMemberID():
global irf_local_name, local_path, env
filename = "%s%s" %(local_path, irf_local_name)
serNum = os.environ['DEV_SERIAL']
reNum = None
try:
file = open(filename, "r")
line = file.readline()
while "" != line:
if (serNum == getIrfCfg(line, 0)):
file.close()
reNum = getIrfCfg(line, 2)
return reNum
line = file.readline()
file.close()
except Exception as inst:
write2Log("\nget renumberID exception: %s" % inst)
print "\n####get renumberID exception: %s####" % inst
write2Log("\nget %s renumberID failed" % filename)
print "\n#### get %s renumberID failed ####" % filename
return reNum
#判断设备是否是处于已经建立IRF
def isIrfDevice():
try:
result = comware.CLI("display irf", False)
if result == None:
return False
except Exception as inst:
return False
return True
#解析sn.txt文件并使用renumber修改设备的IRF成员编号
def getIrfComd():
comd = None
newMemberID = getNewMemberID()
aMemId = comware.get_self_slot()
if None == newMemberID:
return None
if False == isIrfDevice():
comd = "system-view ; irf member %s ; chassis convert mode irf" % newMemberID
else:
comd = "system-view ; irf member %s renumber %s" % (getMemberID(), newMemberID)
return comd
def stackIrfCfg():
global env
if (not os.environ.has_key('DEV_SERIAL')):
write2Log("\nenviron variable 'DEV_SERIAL' is not found!")
print "\n####environ variable 'DEV_SERIAL' is not found!####"
return False
comd = getIrfComd()
if None == comd:
return False
result = None
write2Log("\nstartup stack irf begin")
print "INFO: Startup stack irf Start"
try:
result = comware.CLI(comd, False)
if result == None:
write2Log("\nstartup stack irf failed: %s" % comd)
print "\n####startup stack irf failed: %s####" %comd
return False
except Exception as inst:
write2Log("\nstartup stack irf exception: %s command: %s" % (inst, comd))
print "\n####startup stack irf exception: %s command: %s####" % (inst, comd)
return False
write2Log("\nstartup stack irf success")
print "INFO: Completed Startup Stack Irf"
return True
#check if all standby slots are ready
def ifAllStandbyReady():
if (("get_slot_range" in dir(comware)) == False):
return True
aSlotRange = comware.get_slot_range()
bAllReady = True
for i in range(aSlotRange["MinSlot"], aSlotRange["MaxSlot"]):
oSlotInfo = comware.get_slot_info(i)
if (oSlotInfo != None) and (oSlotInfo["Role"] == "Standby") and (oSlotInfo["Status"] == "Fail"):
bAllReady = False
write2Log("\nSlot %s is not ready!" %i)
print "\n####Slot %s is not ready!####" %i
return bAllReady
#if have any standby slot was not ready sleep for waiting
def waitStandbyReady():
while ifAllStandbyReady() == False:
sleep(10)
#python main
#when download file user can stop script
waitStandbyReady()
signal.signal(signal.SIGTERM, sigterm_handler)
if (True == verifyAllFreeSpace()) and (True == copyBootImage()) and (True == copyCfgFile()) and (True == copyIrfStack()):
#after download file user can not stop script
signal.signal(signal.SIGTERM, sig_handler_no_exit)
if (True == installBootImage()) and (True == startupCfg()) and (True == stackIrfCfg()):
doExit("success")
doExit("error")
(2) 创建配置文件serial_number.cfg(serial_number 为进行IRF零配置设备的序列号,例如下面所使用的配置文件名称)并在保存到HTTP服务器上。配置文件包含了所有设备建立IRF、通过Telnet方式远程登录、登录时密码认证的相关命令。文件内容如下:
· 210235A045B05B0004354.cfg:
#
telnet server enable
#
irf mac-address persistent timer
irf auto-update enable
undo irf link-delay
irf member 1 priority 1
#
irf-port 1/2
port group mdc 1 interface HundredGigE3/0/1 mode enhanced
#
interface HundredGigE3/0/1
port link-mode bridge
#
interface M-GigabitEthernet0/0/0
ip address 192.168.0.63 255.255.255.0
#
line vty 0 63
user-role network-admin
set authentication password simple 123
#
· 210235A045B05B0004350.cfg:
#
telnet server enable
#
irf mac-address persistent timer
irf auto-update enable
undo irf link-delay
irf member 2 priority 1
#
irf-port 2/1
port group mdc 1 interface HundredGigE3/0/1 mode enhanced
#
interface HundredGigE3/0/1
port link-mode bridge
#
interface M-GigabitEthernet0/0/0
ip address 192.168.0.63 255.255.255.0
#
line vty 0 63
user-role network-admin
set authentication password simple 123
#
(3) 创建sn.txt文件并保存在HTTP服务器上。每个设备的主控板都有序列号,sn.txt文件将序列号和成员编号做一对一的映射,以便Pythone脚本能够自动给设备配置指定的成员编号。设备通过运行Python脚本来解析sn.txt文件,然后修改设备的IRF成员编号,并根据自身的成员编号来完成相应的IRF配置。文件内容如下:
sn Irf group Irf number
210235A045B05B0004354 100 1
210235A045B05B0004350 100 2
sn.txt文件中的sn列为设备机框的序列号(serial number),可以通过粘贴在设备机框后面板上的标签查看其序列号,也可以通过在设备上执行display device manuinfo命令进行查看。sn.txt文件中的Irf group列是用来标记IRF组的数字,用户可以自行编辑,不会对设备的配置产生影响。sn.txt文件中的Irf number列为设备在IRF组中的成员编号。
(4) 将软件启动包S12500G.ipe保存在HTTP服务器上。软件启动包是设备启动、运行的必备软件,使用自动配置进行软件升级,使现有设备的启动软件版本一致,以保证Device A和Device B能够成功建立IRF。
启动HTTP管理软件,开启HTTP服务(配置过程略)。
下面以Telnet方式登录Device A为例验证设备是否成功完成自动配置,Device B和Device A验证效果相同,不再赘述。
# 登录设备并输入密码进行身份验证。
Password:
******************************************************************************
* Copyright (c) 2004-2019 New H3C Technologies Co., Ltd. All rights reserved.*
* Without the owner's prior written consent, *
* no decompiling or reverse-engineering shall be allowed. *
******************************************************************************
<DeviceA>
以上信息表明输入密码通过身份验证后,设备登录成功。
# 显示IRF中所有成员设备的相关信息。
<DeviceA> display irf
MemberID Slot Role Priority CPU-Mac Description
1 1 Standby 1 00e0-fc0f-8c02 ---
*+2 1 Master 1 00e0-fc0f-8c14 ---
--------------------------------------------------
* indicates the device is the master.
+ indicates the device through which the user logs in.
The Bridge MAC of the IRF is: 000c-1000-1111
Auto upgrade : yes
Mac persistent : 6 min
Domain ID : 0
Auto merge : yes
IRF mode : enhanced
以上显示信息表明IRF已经成功建立。
· Device A和Device B:
#
telnet server enable
#
irf mac-address persistent timer
irf auto-update enable
undo irf link-delay
irf member 1 priority 1
irf member 2 priority 1
#
irf-port 1/2
port group mdc 1 interface HundredGigE3/0/1 mode enhanced
#
irf-port 2/1
port group mdc 1 interface HundredGigE3/0/1 mode enhanced
#
interface HundredGigE3/0/1
port link-mode bridge
#
interface M-GigabitEthernet0/0/0
ip address 192.168.0.63 255.255.255.0
#
line vty 0 63
user-role network-admin
set authentication password hash $h$6$40hhbS6PeVJORuQu$X/9nQ9PSpPbtGDukVYGOW2Ao
9yJaekVbzovWv23pEKCVwzqqRP8Elnm1qRm4TEIbAetmwQG5gWyREMC3zRCOaQ==
#
· Device C:
#
dhcp enable
#
dhcp server ip-pool 1
network 192.168.1.0 mask 255.255.255.0
bootfile-name http://192.168.1.40/device.py
#
进入自动配置流程后,屏幕上打印出“File "autocfgjuQccA", line 5”,脚本中的import signal命令出错。
请检查脚本里面的命令前面是否出现了多余的空格或字符,请不要随便修改脚本格式。
从HTTP Server上获取配置文件和程序文件是提示md5文件获取失败或未获取到md5文件。
md5文件用于检查HTTP Server上配置文件和程序文件的正确性。脚本中会有md5文件检查的步骤,当HTTP Server上没有配置文件和程序文件对应的md5文件时,会提示未获取到md5文件,此步骤就会被忽略,继续执行下面的脚本,无需关注;当HTTP Server上有配置文件和程序文件对应的md5文件时,请确保md5文件的正确性。
· H3C S12500G-AF系列交换机 基础配置指导-R759X
· H3C S12500G-AF系列交换机 基础命令参考-R759X
· H3C S12500G-AF系列交换机 虚拟化技术配置指导-R759X
· H3C S12500G-AF系列交换机 虚拟化技术命令参考-R759X
不同款型规格的资料略有差异, 详细信息请向具体销售和400咨询。H3C保留在没有任何通知或提示的情况下对资料内容进行修改的权利!