Kolla:Openstack容器化部署简介

Kolla是Openstack的容器化部署项目。

本文主要对Kolla项目进行简单介绍,对其诞生的意义、内部的大概实现做出介绍,以便于读者快速理解项目以投入使用、快速进行自定义开发。

以下主要针对Kolla的Mitaka版本。开始写这篇文章时,Mitaka还尚未发布,因此使用的其实是master版本。

为什么要做容器化部署

Openstack之美

参考下图,OpenStack的架构设计是很漂亮的:清晰定义的服务,完美的原子操作,独立运行的可能,组件尽量无状态易于扩展。这是一个几乎做到极致的分布式架构。
the beauty of openstack

Openstack之殇

但是现实是残酷的:

  • 服务之间往往有严重的依赖,使得部署复杂,修改麻烦,服务的管理困难;
  • 配置复杂,有时候可能仅仅是一个微小的配置错误,就会导致整个集群功能异常;
  • 而且随着OpenStack的发展,架构及配置只会越来越复杂。

运维成本很高,效率低,严重影响了使用体验。

The Reality of OpenStack
生产环境一旦部署完成很难去做大的升级。所以虽然每半年社区更新一个版本(目前马上M版本),但是真正生产环境可能还是I甚至E版本。对于每个组件,只做微小bug的升级,而且升级流程会非常谨慎。对于私有云产品也许还可以,但对于有大量用户严格SLA的公有云产品这是无法容忍的。这也是为什么说Openstack厂商离AWS、阿里云甚至UCloud这些大的公有云厂商还有很大的距离。
举个例子,如果我们要升级keystone这个基础组件——它是Openstack的认证组件,负载整个Openstack集群的鉴权,因此非常重要。
我们首先需要去判断这个版本的keystone和环境中使用的其它组件的当前版本是否完全兼容。而事实证明官方文档介绍很少,也是靠不住的,社区等着你发现bug做贡献呢;开发人员做出的估计有些也是不靠谱的,可以自行统计下每个组件的代码量;甚至简单的测试都不足够可靠,用例库也是逐渐总结出来的。这也说明了引入灰度上线和回滚机制是很有必要的。但是以现有的运维工具,回滚比较困难而且代价很大。因此一般在升级前都要做严格的升级测试,会有资源和人力的成本。

容器的崛起

虽然使用已有的一些OpenStack自动化部署工具,如puppet、fuel等,但往往只能部分解决这些问题,如不支持回滚、太重而导致资源浪费、体积太大速度缓慢等。
而docker在解决所有这些问题上具有很大的优势:

  • 服务直接的相互隔离
  • 轻量级,节省资源,体积小便捷易携带迁移
  • 容易描述的运行时关系
  • 容易升级回滚,可灰度上线,对服务完整的生命周期管理
  • 不只局限于OpenStack,对其它服务如HA等也适用
  • 而通过与Kubernetes、服务发现等容器技术栈的高级工具组合,能提供更强大的解决方案

当然还有容器的火爆发展,OpenStack社区怎么可能错过。

下图对以上所有做了个很好的总结:
Kolla Backgroud

基础知识

Kolla中使用到的技术栈总结如下。

  • Docker,容器化基础工具
  • Ansible,配置管理,主要用于生成配置文件
  • Jinja,模板工具
  • Kubernetes/Mesos,Openstack社区或者说很多开源社区的特点就是:大而全的策略,可以预言:容器领域内所有火的组件慢慢都会在Kolla中出现,而且它们确实能组合出强大的功能。

Docker简介

Docker是通过Linux内核如LXC、namespace等实现的容器化技术。关于Docker的详细请参考docker系列文章或官方文档。
docker内部组件
通过Docker镜像,可以方便的对image进行版本管理。而且因为image的分层特性,体积较小,容易携带和分享。Docker的这些特性使得它非常适合于CI(持续集成/持续)/CD(持续部署/交付)系统,替换原来较重效率低得物理机或虚拟机方案。
docker
在Kolla中,用到了超权限容器(super privileged containers),因为部分组件直接访问宿主机的资源而不是使用自己的命名空间,如libvirt需要访问宿主机的网络空间来创建虚拟机。但是除非必要,对容器需要严格的权限控制以保证安全。参考

Ansible简介

Ansible 组成

Ansible主要由以下部分组成:

  • Inventory: 资产配置库,定义可管控的主机列表
  • Modules: core modules(自带模块)、custom modules(自定义模块)
  • Playbooks: 按照所设定编排的顺序执行完成安排任务

ansible架构

Inventory

资产配置文件,用来定义你要管理的主机,文件采用 INI 格式。

  • 被管理的机器可以通过其IP或域名指定
  • 未分组的机器需保留在hosts的顶部
  • 分组可以使用[]指定
  • 分组也能嵌套
  • 也可以通过数字和字母模式来指定一系列连续主机,支持从一些外围组件获取动态的Inventory,如Ansible Tower。

Playbook

Playbook为YMAL格式,语法简单:

  • 在ansible中几乎所有的yaml文件都是以list开始,每个item是键值对的list。
  • 所有的yaml文件都以---开头表示开始一个document,所有的列表元素以-开头,键值对用冒号,冒号后面的空格是必须的
  • 键值对中的值如果是bool类型的字符串true/false(首字母不论大小写),会load成python中对应的bool值
  • 在键值对中如果值中有冒号或者以两个大括号开头的变量定义,则必须用引号引起来

Playbook由若干Play组成,每一个Play是对一个或一组主机进行一系列动作,Play从上到下依次执行,从而完成部署、配置和编排。每个Play大致结构如下:

  • Host and Users – 指定操作的主机及使用的用户
  • Tasks – 每个Task有Name用于在执行时显示,及具体的Action调用module执行实际任务。
  • Handlers – 何时触发或notify触发别的动作,从而建立依赖关系一个Playbook文件可以通过include引入其他的yml文件,实现复用。

Roles

Ansible自1.2版本引入的新特性,用于层次性、结构化地组织Playbook。
Roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。而要使用Roles只需要在Playbook中使用roles指令即可。
简单来讲,Roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地引用它们的一种机制。

Best Practise

一个标准的目录结构如下图。
Ansible标准目录结构

Kolla

基于上面的因素,结合容器技术近几年的快速发展,Openstack社区诞生了Kolla项目。
Kolla的使命如下:

Kolla provides production-ready containers and deployment tools for operating OpenStack clouds.

Kolla通过提供容器和Ansible的playbook来完成使命。Kolla被尽力设计为开箱即用,但又支持深度的自定义。这使得具有很少OpenStack经验的人员也可以轻易的部署并使用OpenStack,并随着经验的增长进行个性化定义以满足更高的需求。
Kolla不只简化了部署,也简化了操作。

Kolla安装

建议使用Mitaka之后的版本,因为M版本相对之前版本变动较大,之前基本相当于演示版本。
因项目变化很快,不做详述,请参考官方文档:kolla quickstart

Kolla架构

Kolla architecture

其中绿色的组件是kolla提供的,蓝色组件由其它开源软件提供。
基本工作流如下:

  1. 开发人员提交代码到gerrit,被review通过后merge至git
  2. CD系统build出软件包(如RPM、DEB等)
  3. CD系统使用软件包生成docker镜像
  4. CD提交镜像到私有docker registry
  5. CD系统触发节点上的镜像升级
  6. Ansible下载最新镜像并更新容器,完成升级

代码结构

比较重要的目录如下。

  • ansible – ansible相关文件,包括资产配置文件、变量文件、扩展库、Roles、Playbooks
  • docker – docker 相关文件,主要包括 Dockerfile 和其它需要在 build 镜像时添加的文
  • etc – kolla 自己的配置文件
  • kolla – kolla 封装的工具,如 build.py 用于 build 镜像等
  • tools – 其它一些工具,部分已迁移至 kolla 目录,目前主要是一些开发测试用工具

以下详细介绍。

ansible

此目录下是一个标准的 ansible 项目,主要包含如下目录及文件。

  • action_plugins – action 扩展插件
  • group_vars – 全局变量
  • inventory – 资产配置文件,主要包含 all-in-one 和 multinode 两个,实际环境中使用时需要保证主机名的正确对应。
  • library – 扩展 ansible module
  • roles – 每个模块对应的 role
  • *.yml - 若干 Playbook,其中针对 zeus,编写了单独的 Playbook,执行需要通过-p 指

我们需要在 roles 目录下添加对应的 role,使用了官方推荐的目录结构,其中一个 role 的结构如 下:

  • defaults – 变量默认值
  • meta – 依赖
  • tasks–task列表,入口在main.yml,目前支持的action包括deploy、pull、upgrade、reconfigure,每个 action 对应一个 task 文件。
  • templates – 使用到的配置文件模板,及生成 config.json 需要的模板文件。

需要注意一个叫做 common 的 role,其它的 role 大多依赖它,其中包含的内容有:

  • kolla-toolbox – 其中装有所有 client,主要用来注册 endpoint 和操作数据库
  • heka – 用来收集日志,Docker 镜像 build 时需要去 s3 下载 rpm 包,已被墙
  • cron – 用来执行定时任务
    设置配置项 common_run: True,可以指定不执行 common 相关的任务,但没找到有选项去具体控制使用哪个组件。
    kolla-toolbox是我们必须的。所以只能使用代码注释的办法,注释掉 heka 和 cron 相关代码。

docker

此目录下主要为各模块对应的Dockerfile模板及其它build镜像时需要的文件。
Dockerfile模板使用的是Jinja2 模板,其中包含变量,用于根据参数判断,在部署时由ansible 根据参数及配置动态生成。
基础镜像在 base 目录下,其中主要是基本配置及安装基本软件包。其余镜像基本集成自base。
如果具体组件依赖不同,可自定义base镜像使用。
Docker镜像中用到两个比较重要的脚本:start.sh(base)和 extend_start.sh(具体镜像),其作用及实现原理见第 5 节。

Tools

使用 kolla 时,我们一般不直接使用 docker 及 ansible,而是使用封装后的命令:

  • kolla/cmd/build.py – 用于 build 镜像,对 docker build 进行了封装
  • tools/kolla-ansible – 对 ansible 的封装

依赖

推荐使用的依赖版本,其它版本可能会有各种问题。

  • 操作系统 – 推荐宿主机器使用centos7。centos6下经过一番折腾也能安装成功,但是各种问题真心不建议使用,或者升级内核。如果有需要可以在容器内运行centos6。
  • Docker版本 – 推荐从docker官网安装新版本。
  • Ansible – 1.9.4
  • Docker Python – 1.6.0

实例

添加配置项

  • roles/templates/*.j2 – 一般是在配置文件中使用,配置文件一般为Jinja模板,使用类似Django模板的语法
  • roles/defaults/main.yml – 配置默认值
  • group_vars/all.yml – 全局默认值
  • globals.ymlpasswords.yml中。

另外,在config.yml的对应任务中也可以看到,在实际生成配置文件时,还用到了其它一些文件,
如Nova下:

  • /etc/kolla/config/global.conf
  • /etc/kolla/config/database.conf
  • /etc/kolla/config/messaging.conf
  • /etc/kolla/config/nova.conf
  • /etc/kolla/config/nova/.conf

也可以在这些文件中添加配置,而覆盖ansible生成的配置,或添加缺少的配置。

Dockerfile

以cinder-api为例:

FROM {{ namespace }}/{{ image_prefix }}cinder-base:{{ tag }}
MAINTAINER {{ maintainer }}

{% if install_type == 'binary' %}
{% if base_distro in ['centos', 'fedora', 'oraclelinux', 'rhel'] %}

RUN yum install -y python-keystone \
&& yum clean all

{% elif base_distro in ['ubuntu'] %}

RUN apt-get install -y --no-install-recommends \
cinder-api \
&& apt-get clean

{% endif %}
{% endif %}

COPY extend_start.sh /usr/local/bin/kolla_cinder_extend_start
RUN chmod 755 /usr/local/bin/kolla_cinder_extend_start

{{ include_footer }}

USER cinder

其中除了设置相关信息外,还做了这些事:

  1. 继承cinder-base
    cinder-base位于kolla/docker/cinder/cinder-base目录下。
    cinder-base继承自openstack-base,openstack-base继承自base。
    base中主要安装基础包(如python)、设置源、执行set_configs.py(验证并通过config.json生成配置文件)、执行start.sh。
    openstack-base中主要做大多数服务通用的动作,如安装openstack的基础依赖包等。
    cinder-base中主要做cinder服务通用的动作,如安装cinder-common、设置sudoer文件等。
    同时我们看到对docker的tag的支持。
  2. 安装软件包
    通过识别操作系统类型,安装对应的包。
    如果研究下cinder-base的内容,可看到对源码安装的支持。
  3. 执行需要的命令
    base中设置了通过CMD执行start.sh。cinder-base中通过CMD执行extend_start.sh。
    其中服务的启动主要在start.sh中,而需要的其它工作如db_sync主要在extend_start中执行。

Playbook/Role

TODO

配置及部署

在部署时,我们主要配置哪些文件呢?

  • globals.yml
    其中配置必须的变量,但一般不包含密码。
  • passwords.yml
    其中配置需要的密码。
  • 资产配置文件
    ansible/inventory目录下,使用主机名指定,在实际使用时需要保证主机名的对应。也可根据实际需要进行主机、分组等的调整。另一个可能使用到的是禁用某个组件,如禁用ceilometer-compute:

    # disable by default
    [ceilometer-compute:children]
    #ceilometer
  • kolla-build.conf
    指定 build 使用的源,可以使用 rpm 包或 repo 文件。
    如不知道会使用 delorean 源,其内容为社区最近 build 出的 master 分支的 RPM 包: Delorean is a tool to build rpm packages on each commit of a set of git repositories. 建议根据需要指定使用rdo的源。
    在 build 时通过–config-file=参数指定使用的 kolla-build.conf。

项目现状

TODO

参考索引