目录

Ironic

Ironic is an OpenStack project which provisions bare metal (as opposed to virtual) machines. It may be used independently or as part of an OpenStack Cloud, and integrates with the OpenStack Identity (keystone), Compute (nova), Network (neutron), Image (glance), and Object (swift) services.

The Bare Metal service manages hardware through both common (eg. PXE and IPMI) and vendor-specific remote management protocols. It provides the cloud operator with a unified interface to a heterogeneous fleet of servers while also providing the Compute service with an interface that allows physical servers to be managed as though they were virtual machines.

官方文档https://docs.openstack.org/ironic/latest/

裸金属节点特指没有部署操作系统的物理服务器,相对于虚拟机,裸金属节点具有更强的计算能力、资源独占以及安全隔离等优点。Ironic 旨在为用户提供自助式的裸金属管理服务,Ironic 即可以独立使用,也可以与 OpenStack 集成,我们主要关注后者。

  • Ironic Standalone(Bifrost):Ironic 自身构建独立、轻量级裸金属管理平台。
  • 集成至 OpenStack(Nova):Ironic 作为 Nova 驱动程序的多租户裸金属云。

: Bifrost 是自动化部署 Standalone Ironic 的 Ansible playbooks 集合。

Ironic 为 OpenStack 提供裸金属管理服务,允许用户像管理虚拟机一样管理裸金属节点,部署裸机就像是部署虚拟机一样简单,为用户提供了多租户网络的裸金属云基础设施。Ironic 主要依赖 PXE 和 IPMI 技术来实现裸金属节点批量部署和系统控制,因此大部分物理服务器型号都可以通过 Ironic 进行系统安装和电源状态管理,对于个别物理服务器型号,也可以基于 Ironic 的可插拔驱动架构快速开发出针对性的管理驱动程序。凭借标准 API、广泛的驱动程序支持和轻量级的空间占用,使 Ironic 适用于从小型边缘部署到大型数据中心的各种用例,提供了理想的运行环境来托管高性能的云应用程序和架构,包括当下流行的 Kubernetes 等容器编排平台。

应用 Ironic 能够解决的问题

  1. 裸金属资源自服务:为用户提供自助式的裸金属资源服务
  2. OpenStack 自动化部署:真正意义上的全自动化部署,包括裸金属装机和配置的自动化

Ironic 与其他 OpenStack Projects 的协同

  • Keystone:提供身份认证与鉴权服务。
  • Glance:提供镜像与元数据注册服务。
  • Nova:作为 Ironic 的调度与管理抽象层。
  • Ironic:提供裸金属管理服务。
  • Neutron:提供多租户网络服务。
  • Cinder:提供块存储服务。
  • Ceilometer:the OpenStack Telemetry module (ceilometer) for consuming the IPMI metrics.
  • Swift:the OpenStack Object Storage (swift) provides temporary storage for the configdrive, user images, deployment logs and inspection data.

Ironic 裸金属管理服务-LMLPHP

软件架构设计

Ironic 裸金属管理服务-LMLPHP

  • Ironic Api:提供北向 RESTful API。
  • Ironic Conductor:完成裸机管理服务的绝大部分工作。如:添加、编辑、删除裸机;开/关裸机电源;提供、部署、清理裸机等。
  • Drivers:针对不同裸机型号实现的交互模块,每个 Ironic Conductor 实例会挂靠不同的 Drivers 清单来操作对应型号的裸机节点。
  • Ironic Inspector:“裸机自省模块”,即负责裸机特征信息的自动化录入工作,尽量减少人工录入的必要。
  • Ironic Python Agent:简称 IPA,是一个运行在 RAMDisk 之上的 Python 服务,暴露 RESTful API 接收 Ironic Inspector 和 Ironic Conductor 的远程访问,完成带内裸机的自省与操作。
  • RAMDisk:“内存磁盘”,即支持在没有安装操作系统的裸机内存中提供 Ironic Python Agent 程序的运行环境。RAMDisk 属于 Deploy Images 一类,使用 diskimage-builder 工具来构建。
  • diskimage-builder:用于制作 Deploy Images 和 User Images 的工具。
  • python-ironicclient:Ironic CLI。
  • ironic-ui:Horizon dashboard 插件。
  • DB:数据库。
  • MQ:消息队列

:网络管理可分为带外管理(out-of-band)和带内管理(in-band)两种方式。

  • 带外管理(Out-of-band):网络的管理控制信息与用户网络的承载业务信息在不同的逻辑信道传送,指使用独立管理通道进行设备维护,它允许系统管理员远程监控、管理服务器和其他网络设备,无论这些设备是否处于开机状态。
  • 带内管理(In-band):网络的管理控制信息与用户网络的承载业务信息通过同一个逻辑信道传送。指使用常规数据通道(e.g. 以太网)来管理设备。带内管理的明显限制是这种管理容易受到被管理设备受攻击或损害的影响。要远程管理出现故障的网络服务器和路由器,管理员需要能通过网络访问它们。但如果网络发生故障,就无法远程管理那些设备,带外管理通过部署与数据通道物理隔离的管理通道来解决这个限制。

资源模型设计

Ironic 裸金属管理服务-LMLPHP

node:裸金属的基础信息。包括 CPU、存储等信息,还包括 Ironic 管理该裸金属所使用的 Driver 类型信息。

chassis:裸金属模板信息,用于 node 的管理分类。

port:裸金属网口的基础信息,包括 MAC 地址、LLDP 等信息。

portgroup:裸金属上联交换机对裸金属网口的端口组配置信息。

conductor:记录 ironic-conductor 的状态及其支持 Driver 类型的信息。

volume connector/target:记录裸金属的块设备挂载信息。

全生命周期的状态机设计

官方文档:https://docs.openstack.org/ironic/rocky/contributor/states.htmlIronic 裸金属管理服务-LMLPHP

Inspection 裸金属上架自检阶段

当裸机完成硬件安装、网络连线等上架工作后,由管理员将裸机的信息录入到 Ironic 进行纳管,以此支持它的各项后续操作。该阶段中,根据需要可以应用 Ironic Inspector 的功能实现裸机硬件配置信息以及上联交换机信息的自动采集,即裸金属的自检。但基于具体 Drivers 实现的不同,Ironic Inspector 有时并不能完成全部的工作,仍需要人工录入。

自检阶段主要由 IPA 和 Ironic Inspector 共同完成,前者负责信息的采集和传输,后者负责信息的处理。IPA 采集的信息,包括 CPU 个数、CPU Feature Flag、Memory Size、Disk Size、网卡 IP、MAC 地址等,这些信息会被作为 Nova Scheduler 的调度因子。如果接入了 SDN 网络,还需要监听裸机业务网卡上收到的 LLDP(链路发现协议)报文。LLDP 报文由 SDN 控制器发出,包含了 Chassis ID 和 Port ID,用于标记交换机的端口信息,使得 SDN 控制器可以将指定的转发规则下发到指定的交换机端口上。

Inspection 状态机:【数据录入】-> 【运维管理】-> 【数据检测】-> 【节点可用】。

Ironic 裸金属管理服务-LMLPHP

  • enroll:初始化裸金属节点数据库表记录,等待用户进一步校验;
  • verifying:在用户确认裸金属节点信息无误后,发起 manage API 请求,Ironic 会依赖用户录入的信息做依赖数据校验,确认用户录入的数据是否满足下一步操作的要求;
  • manageable:若通过检验,则表示裸金属节点是可管理的,是裸金属数据维护的一个中间状态;
  • inspecting:此状态是 Ironic 为了完善裸金属节点信息而设置的一个自动化数据检测和录入过程,主要是为了将自动录入 CPU、RAM、Disks、NICs 等硬件信息而无需用户手动录入。
  • available:在用户对 manageable 的裸金属节点执行 provide API 请求(此动作意在告诉 Ironic 此裸金属节点已经准备好,可进入下一步的操作系统部署工作)之后,裸金属节点进入 cleaning 状态(才阶段的意义在于为用户提供一个纯净的裸金属节点),等待 cleaning 完成之后该裸金属节点正式标记为可用状态。用户可以随意使用,此时裸金属节点的基础信息(e.g. CPU、RAM、Disks、NICs)全部录入完毕。

Provision 裸金属部署阶段

在裸金属完成上架自检处于 available 的状态之后,就可以进入 Provision 部署阶段。即用户根据业务需要指定镜像、网络等信息来部署裸金属实例。由云平台自动化完成资源调度、操作系统安装、网络配置等工作。一旦实例创建成功后,用户就可以使用物理服务器运行业务了。

Provision 状态机:【设定部署模板】-> 【传入部署参数】-> 【进入裸金属阶段 randisk】-> 【ironic-python-agent 接管裸金属节点】-> 【注入镜像数据】->【引导操作系统】->【激活裸金属节点】。

Ironic 裸金属管理服务-LMLPHP

  • available:用户可以对一个处于可用状态的裸金属节点发起 actice API 请求执行操作系统部署,请求的同时需要将部署的详细信息(e.g. user-image、instance metadata、网络资源分配)持久化到裸金属数据库表记录中;
  • deploying:部署准备阶段,此时 Ironic 会主动 cache ramdisk 到 ironic-conductor 并执行启动动作。如果此时的裸金属节点处于开启状态则执行重启动作;
  • wait callback:等待裸金属节点完成启动或重启,Ironic 根据不同 Driver 类型的策略控制裸金属节点进入操作系统引导(BootLoader)。PXE 是其默认的引导方式,在这个阶段 Ironic 会等待裸金属节点的 BootLoader 进入 ramdisk,运行在 ramdisk 中的 ironic-python-agent 会回调 Ironic,告知裸金属节点已经接收 ironic-python-agent 的控制,可以进一步执行 user-image 的注入动作,并监控进度。待 user-image 注入完成后,Ironic 会进一步控制裸金属节点从 user-image 启动,并完成控制层面的数据维护;
  • active:此状态表示裸金属节点的操作系统部署完成,但并不代表操作系统已经加载完成,裸金属节点的操作系统加载仍需要一定的等待时间。

Clean 裸金属回收阶段

Clean 阶段保证了 Ironic 能够在多租户环境中为不同用户提供始终纯净(配置统一、无非必要数据残留)的裸金属节点。Clean 阶段对裸金属节点的配置以及数据清理设计了一个统一可扩展的流程。通过这套流程,用户可以指定需要的清理流程,比如:抹盘、RAID 配置、BIOS 设置等项目,以及这些项目的执行优先级排序。

Ironic 裸金属管理服务-LMLPHP

  • 在 Inspection 阶段接收到 Provide 请求之后会执行 Cleaning,保证可用的裸金属节点是纯净的。
  • 在 Provision 阶段接收到 Delete 请求之后会执行 Cleaning,保证可用的裸金属节点是纯净的。

快速体验 Ironic(Stein)

官方文档:https://docs.openstack.org/ironic/stein/contributor/dev-quickstart.html#deploying-ironic-with-devstack

下载 Devstack

git clone https://git.openstack.org/openstack-dev/devstack.git -b stable/stein
sudo ./devstack/tools/create-stack-user.sh
sudo su - stack

配置 local.conf

[[local|localrc]]
HOST_IP=192.168.1.100 # Use TryStack(99cloud) git mirror
GIT_BASE=http://git.trystack.cn
#GIT_BASE=https://git.openstack.org # Reclone each time
RECLONE=no # Enable Logging
DEST=/opt/stack
LOGFILE=$DEST/logs/stack.sh.log
VERBOSE=True
LOG_COLOR=True
SCREEN_LOGDIR=$DEST/logs
LOGDAYS=1 # Define images to be automatically downloaded during the DevStack built process.
DOWNLOAD_DEFAULT_IMAGES=False
IMAGE_URLS="http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img" # use TryStack git mirror
GIT_BASE=http://git.trystack.cn
NOVNC_REPO=http://git.trystack.cn/kanaka/noVNC.git
SPICE_REPO=http://git.trystack.cn/git/spice/sice-html5.git # Apache Frontend
ENABLE_HTTPD_MOD_WSGI_SERVICES=False # IP Version
IP_VERSION=4 # Credentials
ADMIN_PASSWORD=password
DATABASE_PASSWORD=password
RABBIT_PASSWORD=password
SERVICE_PASSWORD=password
SERVICE_TOKEN=password
SWIFT_HASH=password
SWIFT_TEMPURL_KEY=password # Enable Ironic plugin
enable_plugin ironic https://git.openstack.org/openstack/ironic stable/stein # Disable nova novnc service, ironic does not support it anyway.
disable_service n-novnc # Enable Swift for the direct deploy interface.
enable_service s-proxy
enable_service s-object
enable_service s-container
enable_service s-account # Cinder
VOLUME_GROUP_NAME="stack-volumes"
VOLUME_NAME_PREFIX="volume-"
VOLUME_BACKING_FILE_SIZE=100G # Neutron
ENABLED_SERVICES+=,q-svc,q-agt,q-dhcp,q-l3,q-meta
# By default, DevStack creates a 10.0.0.0/24 network for instances.
# If this overlaps with the hosts network, you may adjust with the
# following.
NETWORK_GATEWAY=10.1.0.1
FIXED_RANGE=10.1.0.0/24
FIXED_NETWORK_SIZE=256 # Swift temp URL's are required for the direct deploy interface
SWIFT_ENABLE_TEMPURLS=True # Create 3 virtual machines to pose as Ironic's baremetal nodes.
IRONIC_VM_COUNT=3
IRONIC_BAREMETAL_BASIC_OPS=True
DEFAULT_INSTANCE_TYPE=baremetal # Enable additional hardware types, if needed.
#IRONIC_ENABLED_HARDWARE_TYPES=ipmi,fake-hardware
# Don't forget that many hardware types require enabling of additional
# interfaces, most often power and management:
#IRONIC_ENABLED_MANAGEMENT_INTERFACES=ipmitool,fake
#IRONIC_ENABLED_POWER_INTERFACES=ipmitool,fake
# The 'ipmi' hardware type's default deploy interface is 'iscsi'.
# This would change the default to 'direct':
#IRONIC_DEFAULT_DEPLOY_INTERFACE=direct # Change this to alter the default driver for nodes created by devstack.
# This driver should be in the enabled list above.
IRONIC_DEPLOY_DRIVER=ipmi # The parameters below represent the minimum possible values to create
# functional nodes.
IRONIC_VM_SPECS_RAM=1280
IRONIC_VM_SPECS_DISK=10 # Size of the ephemeral partition in GB. Use 0 for no ephemeral partition.
IRONIC_VM_EPHEMERAL_DISK=0 # To build your own IPA ramdisk from source, set this to True
IRONIC_BUILD_DEPLOY_RAMDISK=False VIRT_DRIVER=ironic # Log all output to files
LOGFILE=/opt/stack/devstack.log
LOGDIR=/opt/stack/logs
IRONIC_VM_LOG_DIR=/opt/stack/ironic-bm-logs

服务状态检查

[root@localhost ~]# openstack compute service list
+----+------------------+-----------------------+----------+---------+-------+----------------------------+
| ID | Binary | Host | Zone | Status | State | Updated At |
+----+------------------+-----------------------+----------+---------+-------+----------------------------+
| 3 | nova-scheduler | localhost.localdomain | internal | enabled | up | 2019-05-03T18:56:18.000000 |
| 6 | nova-consoleauth | localhost.localdomain | internal | enabled | up | 2019-05-03T18:56:22.000000 |
| 7 | nova-conductor | localhost.localdomain | internal | enabled | up | 2019-05-03T18:56:14.000000 |
| 1 | nova-conductor | localhost.localdomain | internal | enabled | up | 2019-05-03T18:56:15.000000 |
| 3 | nova-compute | localhost.localdomain | nova | enabled | up | 2019-05-03T18:56:18.000000 |
+----+------------------+-----------------------+----------+---------+-------+----------------------------+ [root@localhost ~]# openstack network agent list
+--------------------------------------+--------------------+-----------------------+-------------------+-------+-------+---------------------------+
| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
+--------------------------------------+--------------------+-----------------------+-------------------+-------+-------+---------------------------+
| 52f23bda-a645-4459-bcac-686d98d23345 | Open vSwitch agent | localhost.localdomain | None | :-) | UP | neutron-openvswitch-agent |
| 7113312f-b0b7-4ce8-ab15-428768b30855 | L3 agent | localhost.localdomain | nova | :-) | UP | neutron-l3-agent |
| a45fb074-3b24-4b9e-8c8a-43117f6195f2 | Metadata agent | localhost.localdomain | None | :-) | UP | neutron-metadata-agent |
| f207648b-03f3-4161-872e-5210f29099c6 | DHCP agent | localhost.localdomain | nova | :-) | UP | neutron-dhcp-agent |
+--------------------------------------+--------------------+-----------------------+-------------------+-------+-------+---------------------------+ [root@localhost ~]# openstack volume service list
+------------------+-----------------------------------+------+---------+-------+----------------------------+
| Binary | Host | Zone | Status | State | Updated At |
+------------------+-----------------------------------+------+---------+-------+----------------------------+
| cinder-scheduler | localhost.localdomain | nova | enabled | up | 2019-05-03T18:56:54.000000 |
| cinder-volume | localhost.localdomain@lvmdriver-1 | nova | enabled | up | 2019-05-03T18:56:53.000000 |
+------------------+-----------------------------------+------+---------+-------+----------------------------+ [root@localhost ~]# openstack baremetal driver list
+---------------------+----------------+
| Supported driver(s) | Active host(s) |
+---------------------+----------------+
| fake-hardware | localhost |
| ipmi | localhost |
+---------------------+----------------+ [root@localhost ~]# openstack baremetal node list
+--------------------------------------+--------+---------------+-------------+--------------------+-------------+
| UUID | Name | Instance UUID | Power State | Provisioning State | Maintenance |
+--------------------------------------+--------+---------------+-------------+--------------------+-------------+
| adda54fb-1038-4634-8d82-53922e875a1f | node-0 | None | power off | available | False |
| 6952e923-11ae-4506-b010-fd7a3c4278f5 | node-1 | None | power off | available | False |
| f3b8fe69-a840-42dd-9cbf-217be8a95431 | node-2 | None | power off | available | False |
+--------------------------------------+--------+---------------+-------------+--------------------+-------------+

部署裸金属实例

[root@localhost ~]# openstack server create --flavor baremetal --image cirros-0.4.0-x86_64-disk --key-name default --nic net-id=5c86f931-64da-4c69-a0f1-e2da6d9dd082 VM1
+-------------------------------------+-----------------------------------------------------------------+
| Field | Value |
+-------------------------------------+-----------------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | |
| OS-EXT-SRV-ATTR:host | None |
| OS-EXT-SRV-ATTR:hypervisor_hostname | None |
| OS-EXT-SRV-ATTR:instance_name | |
| OS-EXT-STS:power_state | NOSTATE |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | None |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | |
| adminPass | k3TgBf5Xjsqv |
| config_drive | |
| created | 2019-05-03T20:26:28Z |
| flavor | baremetal (8f6fd22b-9bec-4b4d-b427-7c333e47d2c2) |
| hostId | |
| id | 70e9f2b1-a292-4e95-90d4-55864bb0a71d |
| image | cirros-0.4.0-x86_64-disk (4ff12aca-b762-436c-b98c-579ad2a21649) |
| key_name | default |
| name | VM1 |
| progress | 0 |
| project_id | cbf936fc5e9d4cfcaa1dbc06cd9d2e3e |
| properties | |
| security_groups | name='default' |
| status | BUILD |
| updated | 2019-05-03T20:26:28Z |
| user_id | 405fad83a4b3470faf7d6c616fe9f7f4 |
| volumes_attached | |
+-------------------------------------+-----------------------------------------------------------------+ [root@localhost ~]# openstack baremetal node list
+--------------------------------------+--------+--------------------------------------+-------------+--------------------+-------------+
| UUID | Name | Instance UUID | Power State | Provisioning State | Maintenance |
+--------------------------------------+--------+--------------------------------------+-------------+--------------------+-------------+
| adda54fb-1038-4634-8d82-53922e875a1f | node-0 | None | power off | available | False |
| 6952e923-11ae-4506-b010-fd7a3c4278f5 | node-1 | None | power off | available | False |
| f3b8fe69-a840-42dd-9cbf-217be8a95431 | node-2 | 70e9f2b1-a292-4e95-90d4-55864bb0a71d | power off | deploying | False |
+--------------------------------------+--------+--------------------------------------+-------------+--------------------+-------------+ [root@localhost ~]# openstack server list --long
+--------------------------------------+------+--------+------------+-------------+-------------------+--------------------------+--------------------------------------+-------------+--------------------------------------+-------------------+-----------------------+------------+
| ID | Name | Status | Task State | Power State | Networks | Image Name | Image ID | Flavor Name | Flavor ID | Availability Zone | Host | Properties |
+--------------------------------------+------+--------+------------+-------------+-------------------+--------------------------+--------------------------------------+-------------+--------------------------------------+-------------------+-----------------------+------------+
| 70e9f2b1-a292-4e95-90d4-55864bb0a71d | VM1 | ACTIVE | None | Running | private=10.0.0.40 | cirros-0.4.0-x86_64-disk | 4ff12aca-b762-436c-b98c-579ad2a21649 | baremetal | 8f6fd22b-9bec-4b4d-b427-7c333e47d2c2 | nova | localhost.localdomain | |
+--------------------------------------+------+--------+------------+-------------+-------------------+--------------------------+--------------------------------------+-------------+--------------------------------------+-------------------+-----------------------+------------+ [root@localhost ~]# openstack baremetal node list
+--------------------------------------+--------+--------------------------------------+-------------+--------------------+-------------+
| UUID | Name | Instance UUID | Power State | Provisioning State | Maintenance |
+--------------------------------------+--------+--------------------------------------+-------------+--------------------+-------------+
| adda54fb-1038-4634-8d82-53922e875a1f | node-0 | None | power off | available | False |
| 6952e923-11ae-4506-b010-fd7a3c4278f5 | node-1 | None | power off | available | False |
| f3b8fe69-a840-42dd-9cbf-217be8a95431 | node-2 | 70e9f2b1-a292-4e95-90d4-55864bb0a71d | power on | deploying | False |
+--------------------------------------+--------+--------------------------------------+-------------+--------------------+-------------+ [root@localhost ~]# ssh [email protected]
$

此时 Ironic 作为 OpenStack Nova 驱动存在:

# nova.conf

[DEFAULT]
...
ompute_driver = ironic.IronicDriver

手动配置 Ironic

配置 Provisioning Network

首先配置一个 Physical Network 作为 Provisioning Network,用于提供 DHCP、PXE 功能,即裸金属节点部署网络。

  • 配置新的 Physical Network
# /etc/neutron/plugins/ml2/ml2_conf.ini

[ml2_type_flat]
flat_networks = public, physnet1 [ovs]
datapath_type = system
bridge_mappings = public:br-ex, physnet1:br-eth2
tunnel_bridge = br-tun
local_ip = 172.22.132.93
  • 创建 OvS Provider Bridge
$ sudo ovs-vsctl add-br br-eth2
$ sudo ovs-vsctl add-port br-eth2 eth2
  • 重启 OvS Agent
$ sudo systemctl restart [email protected]
$ sudo systemctl restart [email protected]
  • 创建运营商网络
$ neutron net-create sharednet1 \
--shared \
--provider:network_type flat \
--provider:physical_network physnet1 $ neutron subnet-create sharednet1 172.22.132.0/24 \
--name sharedsubnet1 \
--ip-version=4 --gateway=172.22.132.254 \
--allocation-pool start=172.22.132.180,end=172.22.132.200 \
--enable-dhcp

NOTE:要注意 Enable DHCP,为裸金属节点的 PXE 网卡提供 IP 地址。

配置 Cleaning Network

当使用 ironic node clean 功能时,需要使用 Cleaning Network,这里我们将 Cleaning Network 和 Provisioning Network 合并。

  • 修改配置
# /etc/ironic/ironic.conf

[neutron]
cleaning_network = sharednet1
  • 重启 Ironic 服务
$ sudo systemctl restart [email protected]
$ sudo systemctl restart [email protected]

构建 Deploy image 和 User Image

Deploy Image 和 User Image 都可以通过 Disk Image Builder 工具来完成,Deploy Image 在 DevStack 部署的时候已经创建好了,我们不再重复。

  • 安装 disk-image-builder
$ virtualenv dib
$ source dib/bin/activate
(dib) $ pip install diskimage-builder
  • 构建 User Image
$ cat <<EOF > k8s.repo
[kubernetes]
name=Kubernetes
baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF $ DIB_YUM_REPO_CONF=k8s.repo \
DIB_DEV_USER_USERNAME=kyle \
DIB_DEV_USER_PWDLESS_SUDO=yes \
DIB_DEV_USER_PASSWORD=r00tme \
disk-image-create \
centos7 \
dhcp-all-interfaces \
devuser \
yum \
epel \
baremetal \
-o k8s.qcow2 \
-p vim,docker,kubelet,kubeadm,kubectl,kubernetes-cni ...
Converting image using qemu-img convert
Image file k8s.qcow2 created... $ ls
dib k8s.d k8s.initrd k8s.qcow2 k8s.repo k8s.vmlinuz
  • 将 Images 上传至 Glance
# Kernel
$ openstack image create k8s.kernel \
--public \
--disk-format aki \
--container-format aki < k8s.vmlinuz # Initrd
$ openstack image create k8s.initrd \
--public \
--disk-format ari \
--container-format ari < k8s.initrd # Qcow2
$ export MY_VMLINUZ_UUID=$(openstack image list | awk '/k8s.kernel/ { print $2 }')
$ export MY_INITRD_UUID=$(openstack image list | awk '/k8s.initrd/ { print $2 }')
$ openstack image create k8s \
--public \
--disk-format qcow2 \
--container-format bare \
--property kernel_id=$MY_VMLINUZ_UUID \
--property ramdisk_id=$MY_INITRD_UUID < k8s.qcow2

创建 Ironic Node

这里的 Ironic Node 并非指代运行 Ironic 守护进程的节点,而是指代裸机,这一点叫法上的习惯性区别需要注意。

  • 确定是否加载了必要的(与 Ironic Node 对应的)Drivers
$ ironic driver-list
+---------------------+----------------+
| Supported driver(s) | Active host(s) |
+---------------------+----------------+
| agent_ipmitool | ironic-dev |
| fake | ironic-dev |
| ipmi | ironic-dev |
| pxe_ipmitool | ironic-dev |
+---------------------+----------------+

NOTE:若缺失,则可以通过 Set up the drivers for the Bare Metal service 的指示添加。

  • 创建 Ironic Node,通过手动录入的方式对节点进行注册
$ export DEPLOY_VMLINUZ_UUID=$(openstack image list | awk '/ipmitool.kernel/ { print $2 }')
$ export DEPLOY_INITRD_UUID=$(openstack image list | awk '/ipmitool.initramfs/ { print $2 }')
$ ironic node-create -d agent_ipmitool \
-n bare-node-1 \
-i ipmi_address=172.20.3.194 \
-i ipmi_username=maas \
-i ipmi_password=passwd \
-i ipmi_port=623 \
-i ipmi_terminal_port=9000 \
-i deploy_kernel=$DEPLOY_VMLINUZ_UUID \
-i deploy_ramdisk=$DEPLOY_INITRD_UUID
  • 继续录入节点的详细信息
$ export NODE_UUID=$(ironic node-list | awk '/bare-node-1/ { print $2 }')
$ ironic node-update $NODE_UUID add \
properties/cpus=4 \
properties/memory_mb=8192 \
properties/local_gb=100 \
properties/root_gb=100 \
properties/cpu_arch=x86_64

NOTE:上述信息也可以通过 Ironic Inspector 来进行录入,需要额外的配置。e.g.

# /etc/ironic-inspector/dnsmasq.conf

no-daemon
port=0
interface=eth1
bind-interfaces
dhcp-range=172.22.132.200,172.22.132.210
dhcp-match=ipxe,175
dhcp-boot=tag:!ipxe,undionly.kpxe
dhcp-boot=tag:ipxe,http://172.22.132.93:3928/ironic-inspector.ipxe
dhcp-sequential-ip $ [email protected]
$ [email protected]

Inspection 流程

Ironic 裸金属管理服务-LMLPHP

  • 注册 Ironic Node 的网络信息
$ ironic port-create -n $NODE_UUID -a NODE_PXE_NIC_MAC_ADDRESS
  • 验证为 Ironic Node 录入的数据
$ ironic node-validate $NODE_UUID
+------------+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Interface | Result | Reason |
+------------+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| boot | False | Cannot validate image information for node 8e6fd86a-8eed-4e24-a510-3f5ebb0a336a because one or more parameters are missing from its instance_info. Missing are: ['ramdisk', 'kernel', 'image_source'] |
| console | False | Missing 'ipmi_terminal_port' parameter in node\'s driver_info. |
| deploy | False | Cannot validate image information for node 8e6fd86a-8eed-4e24-a510-3f5ebb0a336a because one or more parameters are missing from its instance_info. Missing are: ['ramdisk', 'kernel', 'image_source'] |
| inspect | True | |
| management | True | |
| network | True | |
| power | True | |
| raid | True | |
| storage | True | |
+------------+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

NOTE:Ironic 作为 Node Driver 的场景中国 boot、deploy False 是正常的。

  • 验证 Ironic Node 是否能够被纳管
$ ironic --ironic-api-version 1.34 node-set-provision-state $NODE_UUID manage
$ ironic --ironic-api-version 1.34 node-set-provision-state $NODE_UUID provide
$ ironic node-list
+--------------------------------------+--------+---------------+-------------+--------------------+-------------+
| UUID | Name | Instance UUID | Power State | Provisioning State | Maintenance |
+--------------------------------------+--------+---------------+-------------+--------------------+-------------+
| 0c20cf7d-0a36-46f4-ac38-721ff8bfb646 | bare-0 | None | power off | cleaning | False |
+--------------------------------------+--------+---------------+-------------+--------------------+-------------+

NOTE:直到 Ironic Node 的 State 从 cleaning => available 之后,该节点正式纳管成功,可以继续进行上述提到过的裸金属实例部署操作。

Ironic Conductor 的哈希隐射

每个 Conductor 实例在启动时都会被注册到数据库,注册的信息包含了本实例支持的 Drivers 列表,并且定期更新自己的时间戳,使得 Ironic 能够知道哪些 Conductor 和哪些驱动是可用的。当用户注册裸金属节点时需要指定相应的 Driver,Ironic 会根据裸金属节点的注册信息将其分配到支持对应 Driver 的 Conductor 实例上。

对于多个 Conductor 和多个裸金属节点之间的关联场景,由于需要做到有状态管理和避免管理冲突问题,Ironic 采用了一致性哈希算法,多个裸金属节点依据一致性哈希算法映射在一组 Conductor 上。当 Conductor 实例加入或者退出集群,裸金属阶段会重新映射到不同的 Conductor 上,此时会触发驱动的多种动作,比如 take-over 或者 clean-up。

Ironic 裸金属管理服务-LMLPHP

Ironic 裸金属管理服务-LMLPHP

Ironic Drivers 模型

Ironic 设计 Drivers 模型时尽量考虑到了功能模块的高内聚、松耦合、可复用性和可组合性。使用了一个 Drivers Set 对应一个裸金属节点的管理。

Ironic 裸金属管理服务-LMLPHP

Drivers 的类型可分为

  • power:电源管理驱动
  • boot:引导管理驱动
  • deploy:操作系统部署管理驱动
  • management:裸金属管理驱动
  • raid:RAID 管理驱动
  • inspect:裸金属自检驱动
  • console:Console 驱动
  • network:网络管理驱动
  • storage:存储管理驱动
  • vendor:厂商驱动,厂商根据特有的功能扩展其功能并通过 Ironic 暴露出 RESTful API

Ironic 裸金属管理服务-LMLPHP

Ironic Python Agent

Ironic Python Agent,简称 IPA,运行的物理载体是裸金属节点,软件载体是 ramdisk。用于控制和配置裸金属节点,执行擦盘和镜像注入等任务。这是通过引导自定义的 Linux 内核和运行 IPA 并连接到 Ironic Conductor 的 initramfs 镜像来完成的。

  • ironic-agent.kernel:自定义的 Linux 内核
  • ironic-agent.initramfs:运行 IPA 并连接到 Ironic Conductor 的镜像

IPA 的功能清单

  • 磁盘格式化
  • 磁盘分区
  • OS Bootloaders
  • 固件升级
  • RAID 配置

IPA 可以通过下面命令来生成

disk-image-create -c ironic-agent ubuntu dynamic-login stable-interface-names proliant-tools -o ironic-agent

工作流程:从 PXE 引导系统,然后进入 IPA,IPA 会把收集到的信息发送给 ironic-inspector,inspector 根据发来的信息得到 IPMI 的 IP/MAC 地址来和 ironic-api 通信注册节点,然后 ironic-api 就可以和 IPA 就可以进行通信来使用 agent_*driver 进入 Clean 阶段或进行部署了。

Ironic 裸金属管理服务-LMLPHP

Ironic Console

Ironic 支持两种 Console 类型:

  • Shellinabox
  • Socat

Shellinabox 可以将终端输出转换成 Ajax 实现的 http 服务,可以直接通过浏览器访问,呈现出类似 Terminal 的界面。Socat 与 Shellinabox 类似,都是充当一个管道作用,只不过 Socat 是将终端流重定向到 TCP 连接。Shellinabox 是比较早的方式,它的限制在于只能在 Ironic Conductor 节点上运行 WEB 服务,访问范围受限,所以社区又用 Socat 实现了一套。Socat 提供 TCP 连接,可以和 Nova 的 Serial Console 对接。要使用这两者,需要在 Ironic Conductor 节点安装相应的工具。Socat 在 yum 源里就可以找到,Shellinabox 不在标准源里,要从 EPEL 源里下载,它没有外部依赖,所以直接下载这个 rpm 包安装就可以了。Ironic 的驱动中,以 Socat 结尾的驱动是支持 Socat 的,比如 agent_ipmitool_socat,其它的则是 Shellinabox 方式。使用哪种终端方式,在创建节点时要确定好。这两种方式都是双向的,可以查看终端输出,也可以键盘输入。

Ironic 的镜像

Ironic 部署一台裸金属节点需要两种镜像类型,均可以通过 Disk Image Builder 工具构建:

  • Deploy Images
  • User Images

Deploy Images 内含了部署最重要的模块 IPA,它既完成目标主机在部署阶段提供 tgt+iSCSI 服务,又提供物理机发现阶段收集上报目标主机的物理信息。通过下列指令构建 deploy image 之后会生成两个文件:ironic-deploy.vmlinuz(ironic-deploy.kernel)和 ironic-deploy.initramfs。

disk-image-create ironic-agent centos7 -o ironic-deploy

User Images 是真正的用户目的操作系统镜像,通过下列指令构建 user image 之后会生成 my-image.qcow2、my-image.vmlinuz 和 my-image.initrd 三个文件,用于引导和启动操作系统。

image-create centos7 baremetal dhcp-all-interfaces grub2 -o my-image

参考文章

https://mp.weixin.qq.com/s/SbHqZ-lUVh9EOD_UhQNQ-A

https://mp.weixin.qq.com/s/-o1SYXT50nYU4FKqX0qs6Q

https://mp.weixin.qq.com/s/RND6MX-RnM6FcLus-gbM3w

https://mp.weixin.qq.com/s?__biz=MzIzMzk0MDgxNQ==&mid=2247485064&idx=1&sn=1e0f461a2f0f61f857a38842a11756ec&scene=21#wechat_redirect

https://k2r2bai.com/2017/08/16/openstack/ironic/#建立-Bare-metal-網路

05-06 22:59