Cloud Hosted Router (CHR) 是一个 RouterOS 版本,支持虚拟机运行。 它支持 x86 64 位架构,可用于大多数流行的管理软件,如 VMWare、Hyper-V、VirtualBox、KVM 等。 CHR默认启用完整的 RouterOS 功能,但和其他 RouterOS 版本有不同的许可模型。
系统要求
软件包版本:RouterOS v6.34 或更新版本
主机 CPU:64 位,支持虚拟化
内存:128MB 或更多(最大:128GB)
磁盘:CHR 虚拟硬盘驱动器的 128MB 磁盘空间(最大:16GB)
最小 RAM 取决于接口数量和 CPU 数量。 可以使用以下公式得到一个大概的数字:
RouterOS v6 - RAM = 128 + [ 8 * (CPU_COUNT) * (INTERFACE_COUNT - 1) ]
RouterOS v7 - RAM = 256 + [ 8 * (CPU_COUNT) * (INTERFACE_COUNT - 1) ]
**注意:**建议为 CHR 实例分配至少 1024MiB 的 RAM。
CHR 已经在以下平台上进行了测试:
VirtualBox 6 on Linux and OS X
VMWare Fusion 7 and 8 on OS X
VMWare ESXi 6.5
Qemu 2.4.0.1 on Linux and OS X
Hyper-V on Windows Server 2008r2, 2012 and Windows 10 (Only Generation 1 Hyper-V virtual machine is supported at the moment)
Xen Server 7.1
警告: 不支持提供准虚拟化的管理程序。
各种管理软件上可用的网络和磁盘接口:
ESX:
Network: vmxnet3, E1000
Disk: IDE, VMware paravirtual SCSI, LSI Logic SAS, LSI Logic Parallel
Hyper-V:
Network: Network adapter, Legacy Network adapter
Disk: IDE, SCSI
Qemu/KVM:
Network: Virtio, E1000, vmxnet3 (optional)
Disk: IDE, Sata, Virtio
VirtualBox
Network: E1000, rtl8193
Disk: IDE, Sata, SCSI, SAS
注意: SCSI 控制器 Hyper-V 和 ESX 仅可用于辅助磁盘,系统映像必须与 IDE 控制器一起使用!
警告: 如果特定管理软件上有更好的接口选项,则不建议使用 E1000 网络接口!
如何使用 CHR 映像安装虚拟 RouterOS 系统
这里提供 4 种不同的虚拟磁盘映像供选择。 注意,它们只是磁盘映像,不能简单地运行。
RAW disk image (.img file)
VMWare disk image (.vmdk file)
Hyper-V disk image (.vhdx file)
VirtualBox disk image (.vdi file)
安装CHR步骤
下载 用于管理软件的虚拟磁盘映像
2.创建客户虚拟机 3.使用之前下载的镜像文件作为虚拟磁盘驱动器 4.启动guest CHR虚拟机 5.登录到CHR。 默认用户是“admin”,没有密码
注意,可以克隆和复制正在运行的 CHR 系统,但副本会知道之前的试用期,因此不能通过复制 CHR 来延长试用时间。 但是,可以单独许可这两个系统。 要制作新的试用系统,需要全新安装并重新配置 RouterOS。
安装 CHR 指南
VMWare Fusion / Workstation and ESXi 6.5
CHR 许可证
CHR 有 4 个许可级别:
free
p1 perpetual-1 ($45)
p10 perpetual-10 ($95)
p-unlimited perpetual-unlimited ($250)
60 天免费试用许可证适用于所有付费许可证级别。 要获得免费试用许可证,必须在 MikroTik.com 上拥有一个帐户,因为所有许可证管理都在那里。
Perpetual 是终身许可证(一次购买,永久使用)。 可以将永久许可证转移到另一个 CHR 实例。 正在运行的 CHR 实例将指示它必须访问帐户服务器以更新其许可证的时间。 如果 CHR 实例无法续订许可证,会表现为试用期结束,不允许将 RouterOS 升级到更新的版本。
获得运行中的试用系统许可后,必须 从CHR手动运行 /system license renew 功能激活。 否则,系统将不知道获取了许可。 如果没有在系统截止时间之前执行此操作,试用将结束,则必须全新安装 CHR,请求新的试用,然后使用获得的许可证进行授权。
| 许可证 | 速度限制 | 价格 |
|---|---|---|
| Free | 1Mbit | FREE |
| P1 | 1Gbit | $45 |
| P10 | 10Gbit | $95 |
| P-Unlimited | Unlimited | $250 |
付费许可证
p1
p1 (perpetual-1) 许可级别允许 CHR 无限期运行。 每个接口传速度限制为 1Gbps。 CHR 提供的所有其他功能都可以不受限制地使用。 可以将 p1 升级到 p10 或 p-unlimited (可以按标准价格购买新的许可证级别)。购买升级后,以前的许可证可供你的帐户以后使用。
p10
p10_(perpetual-10)许可级别允许 CHR 无限期运行。 每个接口传速度限制为 10Gbps。 CHR 提供的所有其他功能都可以不受限制地使用。 可以将 _p10 升级到 p-unlimited ,购买升级后,以前的许可证将可供你的帐户以后使用。
p-unlimited
p-unlimited (永久无限制)许可级别允许 CHR 无限期运行。 它是最高级别的许可证,没有强制限制。
免费许可证
有多种选择可以免费使用和试用 CHR。
free
free 许可级别允许 CHR 无限期运行。 每个接口的上传速度限制为1Mbps。 CHR 提供的所有其他功能都可以不受限制地使用。 要使用它,要做的就是从下载页面下载磁盘映像文件并创建一个虚拟客户机。
60 天试用
除了有限的免费安装,还可以通过 60 天试用来测试 P1/P10/PU 许可证的速度。
你必须在 MikroTik.com 上注册一个帐户。 然后从路由器请求所需的试用许可级别,这会将路由器 ID 分配给你的帐户,并允许从你的帐户购买许可证。 所有付费许可证均可试用。 试用期是从获取之日起的 60 天,过了这段时间后,你的许可证菜单将显示“限制升级”,意味着 RouterOS 无法再升级。
如果你计划购买所选许可证,则必须在试用结束日期后 60 天内购买。 如果试用结束,并且在结束后 2 个月内没有购买,该设备将不再出现在你的 MikroTik 帐户中。 必须进行新的 CHR 安装才能在规定的时间范围内进行购买。
要申请试用许可证,必须从 CHR 设备命令行运行命令 "/system license renew"。 系统会要求你提供 mikrotik.com 帐户的用户名和密码。
如果你计划使用多个相同类型的虚拟系统,那么下一台机器可能具有与原始机器相同的系统 ID。 这可能发生在某些云提供商处,例如 Linode。 为避免这种情况,在你请求试用许可证之前,在你第一次启动后,运行命令"/system license generate-new-id"。 注意,只有当 CHR 在免费类型的 RouterOS 许可证上运行时,才能使用此功能。 如果你已经获得付费或试用许可证,请不要使用生成功能,因为你无法再更新当前密钥.
获取许可证
初始设置后,CHR 实例将分配 free 许可证。 从那里可以将许可证升级到更高级别。 获得试用许可证后,所有使用许可证的工作都在 帐户服务器 上完成,在那里可以将许可证升级到更高级别,除非已经是 p-unlimited .
从免费许可升级到 p1 或更高版本
从 free 级别升级到任何更高层会导致在 帐户服务器 上注册 CHR 实例。 为此,你必须输入 MikroTik.com 用户名和密码以及想要获得的许可级别。 因此,将在帐户服务器上为你的帐户分配一个 CHR ID 号,并为该 ID 创建一个 60 天的试用期。 有 2 种方法可以获得许可证 - 使用 WinBox 或 RouterOS 命令行界面:
使用WinBox (Sytem -> License menu):
使用命令行:
[admin@MikroTik] > /system license print
system-id: 6lR1ZP/utuJ
level: free
[admin@MikroTik] > /system license renew
account: mymikrotikcomaccount
password: *********************
level: p1
status: done
[admin@MikroTik] > /system license print
system-id: 6lR1ZP/utuJ
level: p1
next-renewal-at: jan/10/2016 21:59:59
deadline-at: feb/09/2016 21:59:59
要获得更高级别的试用版,请设置一个新的 CHR 实例,续订许可证,然后选择所需的级别。
要从试用许可证升级到付费许可证,请转到 MikroTik.com 帐户服务器 并在云托管路由器 (CHR) 选择“所有密钥”:
你将看到CHR机器和许可证列表:
要从试用许可证升级到付费许可证,请单击“升级”,选择所需的许可证级别(不同于试用许可证的级别),然后单击“升级密钥”:
选择付费方式:
可以使用帐户余额(存款)、信用卡 (CC)、PayPal 或使用余额(预付)密钥(如果有)进行支付。
许可证更新
在``/system license``菜单中,路由器将指示 next-renewal-at 时间,它将尝试联系位于 licence.mikrotik.com 上的服务器。 通信尝试将在 next-renewal-at 日期后每小时执行一次,在服务器响应错误之前不会停止。 如果到达 deadline-at 日期但仍未成功联系帐户服务器,则路由器将认为许可证已过期并将不允许进一步的软件更新。 但是,路由器将继续使用与以前相同的许可等级。
虚拟网络适配器
自 RouterOS v7 起支持“vmxnet3”和“virtio-net”适配器的Fast Path。
RouterOS v6 不支持Fast Path。
故障排除
在 VMware ESXi 上运行
改变MTU
VMware ESXi 支持最大 9000 字节的 MTU。 要从中获益,必须调整 ESXi 安装允许更高的 MTU。 ESXi 服务器正确允许 ESXi 服务器在 MTU **更改后**添加虚拟以太网接口以传输巨型帧。 在 ESXi 服务器上的 MTU 更改之前添加的接口将被 ESXi 服务器禁止(它仍将旧 MTU 报告为最大可能大小)。 如果有这个,必须重新添加接口到虚拟客户机。
示例 有 2 个接口添加到 ESXi 客户机,接口上自动检测到 MTU 显示添加接口时的 MTU 大小:
[admin@chr-vm] > interface ethernet print
Flags: X - disabled, R - running, S - slave
# NAME MTU MAC-ADDRESS ARP
0 R ether1 9000 00:0C:29:35:37:5C enabled
1 R ether2 1500 00:0C:29:35:37:66 enabled
在 Linux 上使用网桥
如果 Linux 网桥支持 IGMP 侦听,并且 IPv6 流量存在问题,则需要禁用该功能,因为它与 MLD 数据包(多播)交互并且不会通过它们。
echo -n 0 > /sys/class/net/vmbr0/bridge/multicast_snooping
数据包未从客户机传递
问题:在访客 CHR 上配置软件接口(VLAN、EoIP、网桥等)后,它会停止把数据传递到路由器之外。
解决方法:检查VMS(Virtualization Management System)安全设置,是否允许其他MAC地址通过,是否允许带有VLAN标签的数据包通过。 根据需要调整安全设置,例如允许 MAC 欺骗或某个 MAC 地址范围。 对于 VLAN 接口,通常可以定义允许的 VLAN 标签或 VLAN 标签范围。
在各种管理程序中使用 CHR 上的 VLAN
某些管理软件在虚拟机上使用 VLAN 之前,需要先在管理程序本身配置。
ESXI
在特定 VM 的端口组或虚拟交换机中启用混杂模式。
ESX 文档:
Hyper-V
Hyper-V documentation:
bhyve hypervisor
无法在此管理软件上运行 CHR。 CHR 不能作为准虚拟化平台运行。
Linode
当创建多个具有相同磁盘大小的 Linode 时,新的 Linode 将具有相同的 systemID。 这会导致获得试用/付费许可证的问题。 为避免这种情况,请在首次启动后和申请试用或付费许可证之前运行命令“/system license generate-new-id”。 确保 ID 是唯一的。
一些有用的文章:
NIC 接口未标记特定 VLAN:
允许通过其他的VLAN:
VMWare
时间同步
必须从 GUI 启用(“与主机同步时间”)。 默认情况下禁用反向同步 - 如果客户机领先主机超过 ~5 秒,则不执行同步
电源操作
poweron 和 resume 脚本分别在开机和恢复操作后执行(如果存在并启用)。
poweroff 和 suspend 脚本分别在关机和挂起操作之前执行。
如果脚本花费的时间超过 30 秒或包含错误,则操作失败
如果失败,重试相同的操作将忽略任何错误并成功完成
失败的脚本输出被保存到文件(例如’poweroff-script.log','resume-script.log’等)
可以从管理程序 GUI(“运行 VMware 工具脚本”)或通过控制台启用/禁用脚本
暂停/备份
客户机文件系统暂停仅在请求时执行。
freeze 脚本在冻结文件系统之前执行
如果管理软件无法准备快照或 freeze 脚本失败,则执行 freeze-fail 脚本
thaw 脚本在拍摄快照后执行
脚本运行时间限制为 60 秒
freeze 脚本超时和错误导致备份操作中止
FAT32 磁盘未暂停
将失败的脚本输出保存到文件中(例如“freeze-script.log”、“freeze-fail-script.log”、“thaw-script.log”)
客户机信息
网络、磁盘和操作系统信息每 30 秒向管理程序报告一次(默认情况下,GuestStats(内存)被禁用,可以通过在 VM 配置中设置“guestinfo.disable-perfmon =“FALSE””来启用)。
报告网络接口的顺序可以通过设置“guestinfo.exclude-nics”、“guestinfo.primary-nics”和“guestinfo.low-priority-nics”选项来控制。 可以使用标准 wildcard 模式。
条款
可以使用 vim API 中的 ProcessManager 来执行脚本。 Python 绑定 可用
主要数据结构:GuestProgramSpec
workingDirectory 和 envVariables 成员被忽略
programPath 必须设置为“inline”或“import”
如果 programPath 是'inline',arguments 被解释为脚本文本
如果 programPath 是'import',arguments 被解释为文件路径
在将 GuestProgramSpec 与 GuestAuthentication 实例一起用作 StartProgramInGuest 的参数后获得唯一的 _JobID_。
可以使用 ListProcessesInGuest 命令跟踪脚本进度。 ListProcessesInGuest 接受作业 ID 的数组; 传递一个空数组将报告从 API 启动的所有作业
可以使用 ListProcessesInGuest 命令跟踪脚本进度。 ListProcessesInGuest 接受作业 ID 的数组; 传递一个空数组将报告从 API 启动的所有作业
ListProcessesInGuest 返回 GuestProcessInfo 实例数组:
pid 字段设置为 JobID
endTime 仅在完成后设置
成功时 exitCode 设置为 0,错误时设置为 -1
name 设置为“inline”或“import”(与 GuestProgramSpec 中的 programPath 相同)
有关已完成作业的信息将保留约 1 分钟,或直到调用 ListProcessesInGuest_(具有相应的 _JobID )。 如果脚本失败,则会创建一个名为“vix_job_$JobID$ .txt”的文件,其中包含脚本输出。 脚本运行时间限制为 120 秒,脚本输出不会在超时时保存,
也可以使用 vmrun 命令 runScriptInGuest
PowerCLI 命令 Invoke-VMScript 不支持
不支持主机/客户机文件传输
Python示例
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys,time
from pyVim import connect
from pyVmomi import vmodl,vim
def runInline(content,vm,creds,source):
''' Execute script source on vm '''
if isinstance(source, list):
source = '\n'.join(source)
ps = vim.vm.guest.ProcessManager.ProgramSpec(
programPath = 'console',
arguments = source
)
return content.guestOperationsManager.processManager.StartProgramInGuest(vm,creds,ps)
def runFromFile(content,vm,creds,fileName):
''' Execute script file located on CHR '''
ps = vim.vm.guest.ProcessManager.ProgramSpec(
programPath = 'import',
arguments = fileName
)
return content.guestOperationsManager.processManager.StartProgramInGuest(vm,creds,ps)
def findDatastore(content,name):
sessionManager = content.sessionManager
dcenterObjView = content.viewManager.CreateContainerView(content.rootFolder, [vim.Datacenter], True)
datacenter = None
datastore = None
for dc in dcenterObjView.view:
dstoreObjView = content.viewManager.CreateContainerView(dc, [vim.Datastore], True)
for ds in dstoreObjView:
if ds.info.name == name:
datacenter = dc
datastore = ds
break
dstoreObjView.Destroy()
dcenterObjView.Destroy()
return datacenter,datastore
def _FAILURE(s,*a):
print(s.format(*a))
sys.exit(-1)
#------------------------------------------------------------------------------#
if __name__ == '__main__':
host = sys.argv[1] # ip or something
user = 'root'
pwd = 'MikroTik'
vmName = 'chr-test'
dataStoreName = 'datastore1'
service = connect.SmartConnectNoSSL(host=host,user=user,pwd=pwd)
if not service:
_FAILURE("Could not connect to the specified host using specified username and password")
content = service.RetrieveContent()
#---------------------------------------------------------------------------
# Find datacenter and datastore
datacenter,datastore = findDatastore(content,dataStoreName)
if not datacenter or not datastore:
connect.Disconnect(service)
_FAILURE('Could not find datastore \'{}\'',dataStorename)
#---------------------------------------------------------------------------
# Locate vm
vmxPath = '[{0}] {1}/{1}.vmx'.format(dataStoreName, vmName)
vm = content.searchIndex.FindByDatastorePath(datacenter, vmxPath)
if not vm:
connect.Disconnect(service)
_FAILURE("Could not locate vm")
#---------------------------------------------------------------------------
# Setup credentials from user name and pasword
creds = vim.vm.guest.NamePasswordAuthentication(username = 'admin', password = '')
#---------------------------------------------------------------------------
# Run script
pm = content.guestOperationsManager.processManager
try:
# Run script
src = [':ip address add address=192.168.0.1/24 interface=ether1;']
jobID = runInline(content, vm, creds, src)
# Or run file (from FTP root)
# jobID = runFromFile(content,vm,creds, 'scripts/provision.rsc')
#---------------------------------------------------------------------------
# Wait for job to finish
pm = content.guestOperationsManager.processManager
jobInfo = pm.ListProcessesInGuest(vm, creds, [jobID])[0]
while jobInfo.endTime is None:
time.sleep(1.0)
jobInfo = pm.ListProcessesInGuest(vm, creds, [jobID])[0]
if jobInfo.exitCode != 0:
_FAILURE('Script failed!')
except:
raise
else:
connect.Disconnect(service)
KVM
QEMU 客户机代理可用。 可以用 guest-info 命令检索支持的代理命令。 可以用 guest-file-* 命令执行主机-客户机文件传输。 可以使用 guest-network-get-interfaces 命令检索客户机网络信息。
可以通过使用 guest-exec 命令和 GuestExec 数据结构来执行脚本:
如果提供了 path 成员,则执行相应的文件
如果未设置 path 成员且提供了 input-data 成员,则 input-data 值用作脚本输入
如果设置了 capture-output ,则报告脚本输出
args 和 env 成员未使用
可以使用 guest-exec-status 命令监控脚本作业进度。 GuestExecStatus 数据结构填充如下:
成功时 exitcode 成员设置为 0
如果脚本超时_exitcode_设置为1
如果脚本包含错误 exitcode 设置为 -1
signal 成员未设置
未使用 err-data 成员
如果 capture-output 为真,则 Base64 编码的脚本输出存储在 out-data 中
还提供了一个额外的代理隧道('chr.provision_channel')