Docker镜像多架构构建
目前arm系统越来越常见,对镜像的多架构需求也越来越大。对于同一个镜像,最简单的办法就是在amd64或arm机器上build后通过不同的tag进行区分,比如nginx:v1-amd64
、nginx:v1-arm64
,但这种方式比较丑陋,而且没有对应架构的机器用来构建怎么办?
目前最新的办法就是使用buildx来进行构建,不过这个特性目前默认是没启用的,需要在docker的配置文件中添加"experimental": true
后重启docker服务生效。
目前arm系统越来越常见,对镜像的多架构需求也越来越大。对于同一个镜像,最简单的办法就是在amd64或arm机器上build后通过不同的tag进行区分,比如nginx:v1-amd64
、nginx:v1-arm64
,但这种方式比较丑陋,而且没有对应架构的机器用来构建怎么办?
目前最新的办法就是使用buildx来进行构建,不过这个特性目前默认是没启用的,需要在docker的配置文件中添加"experimental": true
后重启docker服务生效。
很久之前发现一个现象,在生产环境中配置了保留内存reserved_host_memory_mb
以及 没配置 内存超分比ram_allocation_ratio
的情况下,虚拟机使用的内存居然已经快将物理内存耗尽了。
比如物理机内存300G,方便举例忽略掉一些系统占用,当设置了reserved_host_memory_mb
为20G,那么理论上所有虚拟机最大占用内存量为280G,而查看居然已经使用了290G的内存,还是在虚拟机并没有将各自申请的内存全部使用掉的情况下(比如申请一台4G的虚拟机,但物理机操作系统层面并没有分配4G给对应的进程,除非虚拟机内部把内存占满)。
单单就nova而言,如果在集群启动时就指定了保留内存大小和超分比为1的话,是不应该出现上述情形的。除非后期对这2个参数进行过修改,但由于年代久远已经没法追溯,这也就成了一桩悬案。
不过在追踪这个问题的过程中,顺便也学习了下主机热迁移的过程,这里的代码是 N版 。
今天遇到一个诡异的问题,对某个有问题的计算节点进行疏散,结果有些虚拟机的根磁盘居然消!失!了?首先能够确定的是ceph不会自动删除,那么一定是某个地方触发了删除根磁盘的操作。
这如果发生在生产环境可是一个极其严重的问题,正好借此排查的机会梳理一下nova关于主机疏散的流程。
以下代码为N版,但大体流程相差应该不大。
这篇文章记录nova创建快照时候的过程,根据文档,创建快照其实是向/servers/{server_id}/action
发送了一个POST的请求,内容则是类似:
{
"createImage" : {
"name" : "image-name",
"metadata": {}
}
}
最近看了下关于OpenStack如何统计更新CPU、内存、硬盘等硬件资源的部分,由于历史原因下面的代码来自newton
版。
简单说,OpenStack先通过定时任务进行资源统计,入口代码位于nova\compute\manager.py
中ComputeManager
类的update_available_resource
函数。默认情况下每分钟更新一次:
@periodic_task.periodic_task(spacing=CONF.update_resources_interval)
def update_available_resource(self, context):
"""See driver.get_available_resource()
Periodic process that keeps that the compute host's understanding of
resource availability and usage in sync with the underlying hypervisor.
:param context: security context
"""
compute_nodes_in_db = self._get_compute_nodes_in_db(context,
use_slave=True)
nodenames = set(self.driver.get_available_nodes())
for nodename in nodenames:
self.update_available_resource_for_node(context, nodename)
self._resource_tracker_dict = {
k: v for k, v in self._resource_tracker_dict.items()
if k in nodenames}
# Delete orphan compute node not reported by driver but still in db
for cn in compute_nodes_in_db:
if cn.hypervisor_hostname not in nodenames:
LOG.info(_LI("Deleting orphan compute node %s"), cn.id)
cn.destroy()
首先获取所有节点,然后维护了一个名为_resource_tracker_dict
的字典用来记录host和ResourceTracker
实例的对应关系,所有的资源更新行为都在ResourceTracker
中进行处理。
上次学习了Nova创建虚拟机的过程,这次来看一下Glance是如何上传镜像的。相比于Nova,Glance源码使用了大量的代理模式和装饰器模式,阅读代码时候一个不仔细就会一脸懵X。根据上次说的Openstack套路,我们通过setup.cfg
直奔主题——glance/cmd/api.py
:
def main():
try:
config.parse_args()
config.set_config_defaults()
wsgi.set_eventlet_hub()
logging.setup(CONF, 'glance')
notifier.set_defaults()
if cfg.CONF.profiler.enabled:
_notifier = osprofiler.notifier.create("Messaging",
oslo_messaging, {},
notifier.get_transport(),
"glance", "api",
cfg.CONF.bind_host)
osprofiler.notifier.set(_notifier)
osprofiler.web.enable(cfg.CONF.profiler.hmac_keys)
else:
osprofiler.web.disable()
server = wsgi.Server(initialize_glance_store=True)
server.start(config.load_paste_app('glance-api'), default_port=9292)
server.wait()
except KNOWN_EXCEPTIONS as e:
print(e)
fail(e)