ironic baremetal rescue process
1、用户调用Nova的rescue函数
nova/virt/ironic/driver.py
class IronicDriver(virt_driver.ComputeDriver):
......
......
#导入ironicclient模块
def __init__(self, virtapi, read_only=False):
super(IronicDriver, self).__init__(virtapi)
global ironic
if ironic is None:
ironic = importutils.import_module('ironicclient')
......
self.ironicclient = client_wrapper.IronicClientWrapper() def spawn(self, context, instance, image_meta, injected_files,
admin_password, allocations, network_info=None,
block_device_info=None):
......
#调用ironicclient.call方法,触发节点部署
try:
self.ironicclient.call("node.set_provision_state", node_uuid,
ironic_states.ACTIVE,
configdrive=configdrive_value)
......
try:
##Virt驱动程序在等待provision_state更改时循环,并根据需要更新Nova状态
timer.start(interval=CONF.ironic.api_retry_interval).wait()
LOG.info('Successfully provisioned Ironic node %s',
node.uuid, instance=instance)
ironic/api/controllers/v1/node.py
#ronic API接收set_provision_state调用,并执行do_node_rescue RPC调用
class NodeStatesController(rest.RestController):
def provision(self, node_ident, target, configdrive=None,
clean_steps=None, rescue_password=None):
.....
elif (target == ir_states.VERBS['rescue']):
if not (rescue_password and rescue_password.strip()):
msg = (_('A non-empty "rescue_password" is required when '
'setting target provision state to %s') %
ir_states.VERBS['rescue'])
raise wsme.exc.ClientSideError(
msg, status_code=http_client.BAD_REQUEST)
pecan.request.rpcapi.do_node_rescue(
pecan.request.context, rpc_node.uuid, rescue_password, topic)
ironic/conductor/manager.py
class ConductorManager(base_manager.BaseConductorManager):
......
def do_node_rescue(self, context, node_id, rescue_password):
......
#保存节点的救援密码
instance_info = node.instance_info
instance_info['rescue_password'] = rescue_password
node.instance_info = instance_info
node.save()#Ironic conductor在instance_info中设置了救援密码并将通知给相应的驱动 try:
task.driver.power.validate(task)
task.driver.rescue.validate(task)
task.driver.network.validate(task) try:
task.process_event(
'rescue',
callback=self._spawn_worker,
call_args=(self._do_node_rescue, task),#内部RPC方法来救援现有的节点部署
err_handler=utils.spawn_rescue_error_handler) def _do_node_rescue(self, task):
......
try:
next_state = task.driver.rescue.rescue(task) if next_state == states.RESCUEWAIT:
task.process_event('wait')
elif next_state == states.RESCUE:
task.process_event('done')
ironic/drivers/modules/agent.py
class AgentRescue(base.RescueInterface):
.....
#在节点上启动一个救援ramdisk
def rescue(self, task):
#重置电源状态
manager_utils.node_power_action(task, states.POWER_OFF)
#清理实例
task.driver.boot.clean_up_instance(task)
#取消节点的租户网络
task.driver.network.unconfigure_tenant_networks(task)
#为每个端口创建neutron端口以启动救援虚拟磁盘
task.driver.network.add_rescuing_network(task)
if CONF.agent.manage_agent_boot:
ramdisk_opts = deploy_utils.build_agent_options(task.node)
#使用PXE准备Ironic ramdisk的引导
task.driver.boot.prepare_ramdisk(task, ramdisk_opts)
#重置电源状态为POWER_ON
manager_utils.node_power_action(task, states.POWER_ON) return states.RESCUEWAIT
ironic/drivers/modules/pxe.py
class PXEBoot(base.BootInterface):
......
def prepare_ramdisk(self, task, ramdisk_params):
node = task.node
mode = deploy_utils.rescue_or_deploy_mode(node) if CONF.pxe.ipxe_enabled:
#将iPXE引导脚本呈现到HTTP根目录
pxe_utils.create_ipxe_boot_script()
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)#检索DHCP PXE启动选项
provider = dhcp_factory.DHCPFactory()
provider.update_dhcp(task, dhcp_opts)#发送或更新此节点的DHCP BOOT选项
pxe_info = _get_image_info(node, mode=mode)#为救援镜像生成TFTP文件的路径 manager_utils.node_set_boot_device(task, boot_devices.PXE,
persistent=persistent) if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
kernel_label = '%s_kernel' % mode
ramdisk_label = '%s_ramdisk' % mode
pxe_info.pop(kernel_label, None)
pxe_info.pop(ramdisk_label, None) if pxe_info:
_cache_ramdisk_kernel(task.context, node, pxe_info)
ipa和ironic-conductor交互,Agent ramdisk启动后,回调/v1/lookup获取节点信息, 发送心跳
ironic/drivers/modules/agent_base_vendor.py
class HeartbeatMixin(object):
......
def heartbeat(self, task, callback_url, agent_version):
......
try:
.....
elif (node.provision_state == states.RESCUEWAIT):
msg = _('Node failed to perform rescue operation.')
self._finalize_rescue(task) def _finalize_rescue(self, task):
node = task.node
try:
result = self._client.finalize_rescue(node)
ironic/drivers/modules/agent_client.py
class AgentClient(object):
#指示虚拟磁盘完成救援模式的进入
def finalize_rescue(self, node):
#根据config drive和rescue password调用finalize_rescue(RESCUEWAIT -> RESCUING),向ipa传入rescue_password
rescue_pass = node.instance_info.get('rescue_password')
params = {'rescue_password': rescue_pass}
return self._command(node=node,
method='rescue.finalize_rescue',
params=params) def _command(self, node, method, params, wait=False):
#向ipa发送命令
url = self._get_command_url(node)
body = self._get_command_body(method, params)
request_params = {
'wait': str(wait).lower()
try:
response = self.session.post(url, params=request_params, data=body)
ironic_python_agent/extensions/rescue.py
PASSWORD_FILE = '/etc/ipa-rescue-config/ipa-rescue-password'
class RescueExtension(base.BaseAgentExtension):
def finalize_rescue(self, rescue_password=""):
self.write_rescue_password(rescue_password)
self.agent.serve_api = False #关闭api接口
return def write_rescue_password(self, rescue_password=""):
LOG.debug('Writing hashed rescue password to %s', PASSWORD_FILE)
salt = self.make_salt()
hashed_password = crypt.crypt(rescue_password, salt)
try:
with open(PASSWORD_FILE, 'w') as f:
f.write(hashed_password)#把救援密码写入到/etc/ipa-rescue-config/ipa-rescue-password
ironic/drivers/modules/agent_base_vendor.py
class HeartbeatMixin(object):
#调用ramdisk来准备救援模式并验证结果
def _finalize_rescue(self, task):
node = task.node
try:
result = self._client.finalize_rescue(node)
task.process_event('resume')#恢复node的状态
task.driver.rescue.clean_up(task)#清理此节点的部署环境
task.driver.network.configure_tenant_networks(task)#将网络调整到之前的租户网络
task.process_event('done')#返回task状态为done
ironic baremetal rescue process的更多相关文章
- ironic baremetal node rescue/unrescue mode
环境ironic-api ironic-conductor,ironicclient均升级为Queens版本 官网说明API版本为1.38才支持rescue/unrescue,所以修改下openrc文 ...
- Ironic 的 Rescue 救援模式实现流程
目录 文章目录 目录 救援模式 实现 UML 图 救援模式 以往只有虚拟机支持救援模式,裸机是不支持的.直到 Queen 版本 Ironic 实现了这个功能.救援模式下,用户可以完成修复.Troubl ...
- ironic baremetal node status
参考: https://docs.openstack.org/ironic/latest/contributor/states.html https://docs.openstack.org/iron ...
- ironic rescue standard rescue and unrescue process
翻译官网救援/取消救援标准流程 1.用户在节点上调用Nova rescue 2.Nova ComputeManager调用virt驱动程序的rescue()方法,传入rescue_password作为 ...
- packstack安装ironic
KVM Centos7.3虚机 安装openstack Pike版本, 其它版本安装方法类似. packstack目前对NetworkManager 还不支持,我们修改下配置: systemctl d ...
- 手动集成 Ironic 裸金属管理服务(Rocky)
目录 文章目录 目录 前文列表 横向扩展裸金属管理服务节点 配置基础设施 安装 Ironic(BareMetal) 安装 Nova Compute(BareMetal) 配置 Neutron 提供 P ...
- Data Center Manager Leveraging OpenStack
这是去年的一个基于OpenStack的数据中心管理软件的想法. Abstract OpenStack facilates users to provision and manage cloud ser ...
- packstack-ironic
安装openstack Pike版本, 其它版本安装方法类似. centos7.6 packstack目前对NetworkManager 还不支持,我们修改下配置: systemctl disable ...
- Ironic , Openstack Baremetal Hypervisor
Ironic , Openstack Baremetal Hypervisor,首发于UnitedStack Inc.. 转自: http://ju.outofmemory.cn/entry/4876 ...
随机推荐
- Gym 100090M Jumping along the Hummocks
题意: 从 前往后跳,要么跳一步,跳到相邻的位置,要么跳到下一个数字相同的位置,求跳到最后的最少步数. dp,但是会tle,我用map优化了一下. #include <bits/stdc++.h ...
- Math.random()随机生成x~y间的数字
JS如何随机产生数字呢?这就用到了Math.random()方法,它能够随机产生0~1间的数字,这个数可能为0,但会小于1. 那么,如果我想要大于等于1小于10之间的随机整数呢?需要分为以下几步: 1 ...
- 问题 C: B 统计程序设计基础课程学生的平均成绩
题目描述 程序设计基础课程的学生成绩出来了,老师需要统计出学生个数和平均成绩.学生信息的输入如下: 学号(num) 学生姓名(name) ...
- 2018.8.1 Java中的反射和同步详解
为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他 ...
- python selenium 模块的安装及使用
安装 pip install selenium 或者到https://pypi.python.org/pypi/selenium 下载setup安装包,之后进入目录后运行python setup.py ...
- python 添加 threadpool
操作系统: Ubuntu 10.04 python安装依赖的软件包: python 出现 ImportError: No module named ** 我这里出现了: ImportError: No ...
- Linux内存管理 - buddy系统
本文目的在于分析Linux内存管理机制中的伙伴系统.内核版本为2.6.31.1. 伙伴系统的概念 在系统运行过程中,经常需要分配一组连续的页,而频繁的申请和释放内存页会导致内存中散布着许多不连续的页, ...
- UVa中国麻将(Chinese Mahjong,Uva 11210)
简单的回溯题 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm ...
- (一)、Python的简介与安装
Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,作为ABC 语言的一种继承. ...
- bootloader 关闭看门狗
#define pWTCON 0x53000000disable_watchdog: ldr r0, =pWTCON mov r1, #0x0 str r1, [r0]