剖析ironic

关键技术

在安装操作系统时需要存储介质来存储系统镜像、需要控制物理机开关机,在网络部署环境中还需要预启动环境。

  • PXE (预启动环境)
  • IPMI(电源管理)
  • iSCSI(存储)

什么是PXE

PXE(preboot execute environment) 预启动执行环境。PXE 是目前主流的无盘启动技术,它可以使计算机通过网络而不是从本地硬盘、光驱等设备启动,采用Client/Server的网络模式,在启动过程中,终端要求服务器分配IP地址,再用TFTP(trivial file transfer protocol)或MTFTP(multicast trivial file transfer protocol)协议下载一个启动软件包到本机内存中执行,由这个启动软件包完成终端基本软件设置,从而引导预先安装在服务器中的终端操作系统。

利用 PXE 进行系统安装需要被安装的主机上有 PXE 支持的网卡,不过现在的网卡一般都内嵌支持 PXE 的 ROM 芯片。当计算机引导时,BIOS 首先会把 PXE Client 调入内存中执行,PXE Client 被载入内存后,它便同时具有 DHCP client 和 TFTP Client 的功能,DHCP client 会向 DHCP server 请求 ip 分配给将要安装系统的主机,然后由 PXE Client 将放置在远端的文件通过 TFTP 下载到本地运行。 PXE过程图

安装流程如下:

  1. 客户机从自己的PXE网卡启动,向本网络中的DHCP服务器索取IP,并搜寻引导文件的位置
  2. DHCP服务器返回分给客户机IP以及NBP(Network Bootstrap Program )文件的放置位置(该文件一般是放在一台TFTP服务器上)
  3. 客户机向本网络中的TFTP服务器索取NBP
  4. 客户机取得NBP后之执行该文件
  5. 根据NBP的执行结果,通过TFTP服务器加载内核和文件系统
  6. 安装操作系统

PXE能提供操作系统镜像,但是如何远程开机呢,这件事就是由IPMI来做的。

什么是IPMI

智能平台管理接口(IPMI:Intelligent Platform Management Interface)是一项应用于服务器管理系统设计的标准,提供管理和监控CPU、固件(BIOS、UEFI)和操作系统等功能,由Intel、HP、Dell和NEC公司于1998年共同提出。利用此接口标准设计有助于在不同类服务器系统硬件上实施系统管理,使不同平台的集中管理成为可能,目前有超过200家公司支持IPMI。IPMI信息通过网络连接到基板管理控制器 (BMC)进行交流,不依赖BOIS或者操作系统,这使得在操作系统不响应或未加载的情况下其仍然可以进行开关机、信息提取等操作。Ironic 正是利用此技术可以远程的对裸机进行上下电或者其他操作,而不是依赖物理开关或者操作系统。

IPMI可以在操作系统启动之前、管理系统启动之前、操作系统或者管理系统失败(与带内系统管理的最大特性)时对物理机进行管理,利用IPMI可以实现以下功能:

  1. 可以在服务器通电(没有启动操作系统)情况下,对它进行远程管理:开机,关机,重启
  2. 基于文本的控制台重定向,可以远程查看和修改BIOS设置,系统启动过程,登入系统等
  3. 可以远程通过串口IP映射(SoL)连接服务器,解决ssh服务无法访问,远程安装系统,查看系统启动故障等问题
  4. 可以通过系统的串行端口进行访问
  5. 故障日志记录和 SNMP 警报发送,访问系统事件日志 (System Event Log ,SEL) 和传感器状况

IPMI技术功能点总结:

  • 远程电源控制 (on / off / cycle / status)
  • 串口的IP映射 Serial over LAN (SoL)
  • 支持健康关机(Graceful shutdown support)
  • 机箱环境监控 (温度, 风扇转速, CPU电压等)
  • 远程设备身份LED控制(Remote ID LED control)
  • 系统事件日志(System event log)
  • 平台事件跟踪(Platform Event Traps)
  • 数据记录(Data logging)
  • 虚拟KVM会话(Virtual KVM)
  • 虚拟媒介(Virtual Media)

参考资料: https://en.wikipedia.org/wiki/Intelligent_Platform_Management_Interface

什么是iSCSI

iSCSI是一个指令集,iSCSI技术是一种新储存技术,该技术是将现有SCSI接口与以太网络(Ethernet)技术结合,使服务器可与使用IP网络的储存装置互相交换资料。

早期的企业使用的服务器若有大容量磁盘的需求时,通常是透过SCSI来串接SCSI磁盘,因此服务器上面必须要加装SCSI卡,而且这个SCSI是专属于该服务器的。 后来这个外接式的SCSI设备被SAN的架构所取代,在SAN的标准架构下,虽然有很多的服务器可以对同一个SAN 进行存取的动作,不过为了速度需求,通常使用的是光纤通道。但是光纤通道很贵,不但设备贵,服务器上面也要有光纤卡,很麻烦,所以光纤的SAN在中小企业很难普及。

后来网络实在太普及,尤其是以IP封包为基础的LAN技术已经很成熟,再加上以太网路的速度越来越快,所以就有厂商将SAN的连接方式改为利用IP技术来处理。 然后再透过一些标准的设定,最后就得到Internet SCSI (iSCSI)这个的产生! iSCSI主要是透过TCP/IP的技术,将储存设备端透过iSCSI target (iSCSI目标端)功能,做成可以提供磁盘的服务器端,再透过iSCSI initiator (iSCSI初始化用户)功能,做成能够挂载使用iSCSI target的用户端,如此便能透过iSCSI设置来进行磁盘的应用了。

也就是说,iSCSI 这个架构主要将储存装置与使用的主机分为两个部分,分别是:

  • iSCSI target:就是储存设备端,存放磁盘或RAID的设备,目前也能够将Linux主机模拟成iSCSI target了! 目的在提供其他主机使用的磁盘。
  • iSCSI initiator:就是能够使用target的用户端,通常是服务器。 也就是说,想要连接到iSCSI target的服务器,也必须要安装iSCSI initiator的相关功能后才能够使用iSCSI target提供的磁盘。

iSCSI示意图

ironic内部技术

ironic代码结构

下面是ironic liberty版的代码结构,其中省略了部分文件

ironic-stable-liberty:.
│ 
│  babel.cfg
│  CONTRIBUTING.rst
│  driver-requirements.txt
│  LICENSE
│  MANIFEST.in
│  openstack-common.conf
│  README.rst
│  RELEASE-NOTES
│  requirements.txt
│  setup.cfg      #pbr的配置文件
│  setup.py 
│  test-requirements.txt
│  tox.ini        #tox配置文件
│  vagrant.yaml
│  Vagrantfile
│  
├─doc   #文档
│              
├─etc  #相关配置文件
│              
├─ironic
│  │  
│  ├─api        #api,使用peach框架
│  │  │  acl.py
│  │  │  app.py     #API入口
│  │  │  app.wsgi
│  │  │  config.py
│  │  │  expose.py
│  │  │  hooks.py
│  │  │  __init__.py
│  │  │  
│  │  ├─controllers   #控制器
│  │  │  │  base.py
│  │  │  │  link.py
│  │  │  │  root.py   #API总控制器
│  │  │  │  __init__.py
│  │  │  │  
│  │  │  └─v1      #v1 版本API
│  │  │          
│  │  └─middleware
│  │          
│  ├─cmd            # 服务入口
│  │      api.py
│  │      conductor.py
│  │      dbsync.py
│  │      __init__.py
│  │      
│  ├─common  常用方法
│  │              
│  ├─conductor  
│  │      manager.py  
│  │      rpcapi.py
│  │      task_manager.py
│  │      utils.py
│  │      __init__.py
│  │      
│  ├─db    #数据库相关,包括sqlalchemy、alembic
│  │                  
│  ├─dhcp  #neutron dhcp api
│  │      base.py
│  │      neutron.py
│  │      none.py
│  │      __init__.py
│  │      
│  ├─drivers    #驱动相关
│  │  │  agent.py    #agent_* 驱动
│  │  │  base.py
│  │  │  drac.py     #drac驱动
│  │  │  fake.py
│  │  │  ilo.py      #ilo驱动,惠普的
│  │  │  irmc.py     #irmc
│  │  │  pxe.py      #pxe_* 驱动
│  │  │  raid_config_schema.json
│  │  │  utils.py
│  │  │  __init__.py
│  │  │  
│  │  └─modules     #驱动的具体方法
│  │    
│  │              
│  ├─locale      #翻译
│  │              
│  ├─nova        #nova相关,这里包括与Nova computer冲突的临时解决办法
│  │          
│  ├─objects     #基本对象的方法,包括conducotr、node、port、field、chassis
│  │      
│  ├─openstack  #openstack相关的,这里包含处理镜像的方法的帮助函数
│  │          
│  └─tests    #测试相关
│      
│              
├─releasenotes   #发布历史
│              
└─tools     #相关工具

API

ironic-api提供一系列接口,详见ironic API

  • 节点相关(node)
    • 节点增删改查(List, Searching, Creating, Updating, and Deleting)
    • 合法性检查
    • 设置和清除维修状态
    • 设置和获取boot device
    • 获取节点当前综合信息,包括power, provision, raid, console等
    • 更改电源状态
    • 更改节点提供状态( manage, provide, inspect, clean, active, rebuild, delete (deleted), abort)
    • 设置RAID
    • 启动、停止、获取console
    • 查看、调用厂商定制方法(passthru方法)
  • 端口相关(Port)
    • 对物理端口(Port)的增删改查(Listing, Searching, Creating, Updating, and Deleting ),新建的时候就要指定端口的物理地址(一般是MAC地址)与Node进行绑定。
    • 查看与Node连接的端口
  • 驱动相关(driver)
    • 列举所有驱动
    • 查看驱动的详细信息、属性
    • 查看和调用厂商的驱动
  • Chassis(机箱,一组node的集合)
    • 增删改查

      Chassis这个资源类型是为了给节点分组用的,目前只有列举一组节点的功能。不赞成使用这个类型,将来可能会去除掉。

Conductor

Ironic-Conductor是Ironic中最主要的模块,通过Ironic-API对外提供功能,与Ironic-API之间通过RPC进行通信,负责绝大部分工作,包括与Neutron通信为物理机配置网络信息,与Glance通信获取镜像,与Cinder和Swift通信进行为物理机提Ironic-Conductor是Ironic中最主要的模块,通过Ironic-API对外提供功能,与Ironic-API之间通过RPC进行通信,负责绝大部分工作,包括与Neutron通信为物理机配置网络信息,与Glance通信获取镜像,与Cinder和Swift通信进行为物理机提供存储。 供存储。

同时控制着物理机状态的改变过程,下图是openstack Liberty中物理机状态转换图:

Ironic’s State Machine

在高可用方面,conductor 采用一致性哈希算法保证Condutor节点新增退出时不影响Bare metal节点。 

DB

采用MySQL,存储物理机和驱动的状态信息,可以换成其他数据库。

Drivers

驱动是真正操作物理机的模块,Ironic的驱动以插件形式设计,厂商可以实现自己的驱动来为自己的设备提供特色化功能。实现自己的驱动只需要实现几个相关的方法即可。

驱动架构

驱动有不同的属性,每个属性能够完成一定的功能,这些属性分为三种接口:

  • 核心接口(core),最基本的功能,是其他服务的依赖,所有驱动都必须实现的,包括power,deploy.
  • 标准接口(standard),实现通用功能,主要包括 management, console, boot, inspect, raid.
  • 厂商接口(vendor),提供个性化功能

接口功能:

分类接口功能主要需要实现的方法
core power 管理电源 get_properties、validate、 get_power_state、set_power_state、reboot
  deploy 部署方式 get_properties、validate、 deploy、tear_down、prepare、clean_up、take_over、prepare_cleaning、tear_down_cleaning
standard console 通过硬件得到物理机的控制台 get_properties、validate、start_console、stop_console、get_console
  management 管理物理机硬件 get_properties、validate、get_supported_boot_device、set_boot_device、get_boot_device 、get_sensors_data
  boot 启动相关的动作 get_properties、validate、prepare_ramdisk、clean_up_ramdisk、prepare_instance、clean_up_instance
  inspect 硬件自检,主要检查内存、CPU、本地分区 inspect_hardware
  raid 设置raid get_properties、validate、 create_configuration、delete_configuration、get_logical_disk_properties
vendor   厂商的自定义功能 get_properties、validate、...

驱动架构示意图:

驱动结构示意图

Liberty支持的驱动,在setup.cfg中可以看到

    agent_ilo = ironic.drivers.ilo:IloVirtualMediaAgentDriver
    agent_ipmitool = ironic.drivers.agent:AgentAndIPMIToolDriver
    agent_irmc = ironic.drivers.irmc:IRMCVirtualMediaAgentDriver
    agent_pyghmi = ironic.drivers.agent:AgentAndIPMINativeDriver
    agent_ssh = ironic.drivers.agent:AgentAndSSHDriver
    agent_vbox = ironic.drivers.agent:AgentAndVirtualBoxDriver
    agent_ucs = ironic.drivers.agent:AgentAndUcsDriver
    iscsi_ilo = ironic.drivers.ilo:IloVirtualMediaIscsiDriver
    iscsi_irmc = ironic.drivers.irmc:IRMCVirtualMediaIscsiDriver
    pxe_ipmitool = ironic.drivers.pxe:PXEAndIPMIToolDriver
    pxe_ipminative = ironic.drivers.pxe:PXEAndIPMINativeDriver
    pxe_ssh = ironic.drivers.pxe:PXEAndSSHDriver
    pxe_vbox = ironic.drivers.pxe:PXEAndVirtualBoxDriver
    pxe_seamicro = ironic.drivers.pxe:PXEAndSeaMicroDriver
    pxe_iboot = ironic.drivers.pxe:PXEAndIBootDriver
    pxe_ilo = ironic.drivers.pxe:PXEAndIloDriver
    pxe_drac = ironic.drivers.drac:PXEDracDriver
    pxe_snmp = ironic.drivers.pxe:PXEAndSNMPDriver
    pxe_irmc = ironic.drivers.pxe:PXEAndIRMCDriver
    pxe_amt = ironic.drivers.pxe:PXEAndAMTDriver
    pxe_msftocs = ironic.drivers.pxe:PXEAndMSFTOCSDriver
    pxe_ucs = ironic.drivers.pxe:PXEAndUcsDriver
    pxe_wol = ironic.drivers.pxe:PXEAndWakeOnLanDriver
    pxe_iscsi_cimc = ironic.drivers.pxe:PXEAndCIMCDriver
    pxe_agent_cimc = ironic.drivers.agent:AgentAndCIMCDriver

    #fake* 驱动是假的驱动,里面没有具体实现,用于测试
    fake = ironic.drivers.fake:FakeDriver
    fake_agent = ironic.drivers.fake:FakeAgentDriver
    fake_inspector = ironic.drivers.fake:FakeIPMIToolInspectorDriver
    fake_ipmitool = ironic.drivers.fake:FakeIPMIToolDriver
    fake_ipminative = ironic.drivers.fake:FakeIPMINativeDriver
    fake_ssh = ironic.drivers.fake:FakeSSHDriver
    fake_pxe = ironic.drivers.fake:FakePXEDriver
    fake_seamicro = ironic.drivers.fake:FakeSeaMicroDriver
    fake_iboot = ironic.drivers.fake:FakeIBootDriver
    fake_ilo = ironic.drivers.fake:FakeIloDriver
    fake_drac = ironic.drivers.fake:FakeDracDriver
    fake_snmp = ironic.drivers.fake:FakeSNMPDriver
    fake_irmc = ironic.drivers.fake:FakeIRMCDriver
    fake_vbox = ironic.drivers.fake:FakeVirtualBoxDriver
    fake_amt = ironic.drivers.fake:FakeAMTDriver
    fake_msftocs = ironic.drivers.fake:FakeMSFTOCSDriver
    fake_ucs = ironic.drivers.fake:FakeUcsDriver
    fake_cimc = ironic.drivers.fake:FakeCIMCDriver
    fake_wol = ironic.drivers.fake:FakeWakeOnLanDriver

可以将上面的驱动进行分类,得到:

  • pxe/iscis
  • agent
  • fake (假的驱动,用于示例,测试)

我们把fake驱动排除,其他的驱动可以分为两类:

  • 一是以pex 或者 iscsi 为前缀的驱动采用PXE部署机制,这些驱动将根硬盘作为iSCSI设备暴露给ironic conductor,由conductor将镜像复制到这里.
  • 二是以agent_ 为前缀的驱动采用Agent部署机制,conductor准备一个存储在swift上的镜像URL给IPA,由IPA下载镜像和完成部署的操作。

从Kilo版开始,所有驱动使用agent进行部署。

每种驱动的功能会调用不同的模块来实现,比如:

  • pxe_ deploy 用的是iscsi_deploy.ISCSIDeploy(), boot用的是pxe.PXEBoot(), power根据后缀不同使用的不同
  • agent_ deploy用的是agent.AgentDeploy(), boot 用的是pxe.PXEBoot(), power根据后缀不同而不同
  • iscis_ deploy用的iscsi_deploy.ISCSIDeploy(),power根据后缀不同而不同

驱动列表

  • 社区驱动
种类用途实现的驱动
SSH 用VM模拟物理机时使用 pxe-ssh使用pxe部署、ssh管理电源; agent-ssh使用agent部署、ssh管理电源
VirtualBox VirtualBox驱动用来将虚拟机模拟成裸机节点进行测试Ironic。Ironic使用pex_ssh和agent_ssh驱动连接VirtualBox主机(要安装在Linux下,Windows下SSH不太好用) - pxe_vbox:使用基于iSCSI的部署机制- agent_vbox:使用基于agent的部署机制
IPMI 使用IPMItool进行管理电源 pxe_ipmitool; agent_ipmitool;
pyghmi pyghmi是ironic实现的一个Python ipmitool lib 用于替代ipmitool pxe_ipminative;agent_pyghmi
  • 厂商驱动
种类说明实现的驱动
DRAC 戴尔公司的一种系统管理硬件和软件解决方案(Dell Remote Access Controller) pxe_drac
AMT 英特尔主动管理技术,远程带外管理个人电脑的硬件和固件的技术,用于监控、维修、更新、升级硬件和固件 pex_amt
SNMP SNMP电源驱动用户管理数据中心机架的配电单元,可与PXE驱动结合起来用于网络部署和配置 pxe_snmp
iLO iLO是Integrated Ligths-out的简称,是HP服务器上集成的远程管理端口,只要将服务器接入网络并且没有断开服务器的电源,不管HP服务器的处于何种状态(开机、关机、重启),都可以允许用户通过网络进行远程管理 iscsi_ilo, agent_ilo, pxe_ilo。 iscsi_ilo和agent_ilo使用iLO实现带外管理,iscsi_ilo使用diskimage-builder建立镜像,从网络启动;而agent_ilo使用IPA的部署镜像,裸机节点从本地启动。pxe_ilo使用PXE/iSCSI部署(和常规PXE驱动一样)
SeaMicro SeaMicro服务器是由AMD公司发布的,基于ARM处理器,特点是节能。SeaMicro电源驱动可以使用SeaMicro服务器的电源周期管理功能。 pxe_seamicro, 使用PXE/iSCSI进行部署镜像,然后使用SeaMicro替代IPMI对裸机进行管理。
iRMC 富士通的驱动,通过ServerView Common Command Interface(SCCI,富士通的卡)控制电源 - pxe_irmc,使用PXE部署 - iscis_irmc,支持用虚拟光驱来部署镜像 - agent_irmc,支持使用虚拟光驱部署IPA
UCS 思科的驱动,用户管理思科 UCS B/C 系列的服务器(类似IPMI) - pxe_ucs: 使用PXE/iSCSI部署镜像,使用UCS代替IPMI管理节点 - agent_ucs:使用IPAramdisk部署镜像,使用UCS代替IPMI管理节点
CIMC 思科为standalone Cisco UCS C系列服务器提供的驱动,可以利用CIMC进行管理裸机(代替IPMI) pxe_iscsi_cimc,使用PXE+iSCSI部署 - pxe_agent_cimc,使用PXE启动+Agent部署
Wake-On-Lan Wake-On-Lan是一个允许通过网络消息打开电脑电源的标准,不需要额外硬件,但还在测试阶段。Wake-On-Lan只有打开电源的功能,关闭电源需要手工执行。它没有获取电源状态的能力,任何电源状态的API调用它只返回数据库里的值。 pex_wol:使用PXE/iPXE启动,iSCSI部署。
iBoot iBoot power driver通过DxP协议对使用了Dataprobe(美国一家制造商)iBoot 设备的服务器进行电源周期管理 pxe_iboot,使用PXE/iPXE启动,iSCSI部署。

Ironic-Python-Agent

在PXE部署环境中,deploy模块是通过打开一个iSCSI设备,ironic-conductro将OS的镜像文件写到iSCSI的设备,所以deploy_ramdisk只是完成了iSCSI部署的工作,但开发者觉得既然已经把kernel和ramdisk传过去了,只做一个工作是不是太少了,而且还太缺乏灵活性了,所以就想在ramdisk里装一个Python Agent。 实际上就是多提供了一个Restful API,控制节点可以通过这个agent远程实现与物理机节点互动,而不仅仅使用dd命令。

Ironic Python Agent(简称IPA或者agent)是一个基于python的代理,用于处理ironic中裸机节点的一系列动作,比如检查、配置、清除和部署镜像。运行在ramdisk中,暴露出REST API给conductor。Ironic-Python-Agent可以在deploy模块直接访问硬件,提供以下功能:

  • 磁盘格式化
  • 磁盘分区
  • 安装OS( Bootloaders, OS)
  • 固件升级
  • raid配置

在Condutor端使用agent驱动,物理机端使用IPA,IPA通过暴露API给Condutor调用,则可完成相应功能。IPA启动时通过发送lookup()请求给Condutor获取UUID,相当于注册自己,并且每隔一段时间给Condutor发送心跳包进行连接。

1. 与conductor的交互

IPA使用lookup和hearteat机制与Ironic Conductor进行交互

  1. 启动时agent给Conductor的vendor_passthru lookup endpoint(地址为/v1/drivers/{driver}/vendor_passthru/lookup)发送一个硬件的profile
  2. 然后Ironic就可以得出该节点的uuid,在成功发现该节点之后,agent隔N秒发送心跳包给Conductor(hearteat地址为/v1/nodes/{node_ident}/vendor_passthru/heartbeat )
  3. conductor执行一系列动作,包括查询已经运行的命令的状态,

2. 与ramdisk、agent的关系

IPA是一个运行在ramdisk中python程序,当物理机注册时使用agent为前缀的驱动时,则会使用agent方式部署,即允许包含有IPA的ramdisk。

3. 硬件管理

硬件管理器(HardwareManager)是IPA中的一个概念,IPA通过重写硬件管理器来支持多种硬件平台。通过自定义 hardware managers 可以允许用户引入特定的硬件工具集、文件和清除步骤等等,比如可以引入 BIOS flashing utility and BIOS file,然后在cleaning step中重写BIOS版本。

修改硬件的方法按照优先顺序发送给每个管理器,管理器检查是否包含该方法,如果没有则抛出IncompatibleHardwareMethodError异常,IPA继续发送给下一个管理器,直到某个管理器包含该方法并且返回方法的结果,如果所有的管理器都没有改方法则抛出 HardwareManagerMethodNotFound异常。

4. pxe部署与agent部署对比

使用pxe部署流程:

iscsi部署流程

使用IPA部署流程:

IPA部署流程

posted @ 2016-11-14 21:35  MKY-门可意  阅读(2615)  评论(1编辑  收藏  举报