Kolla是Openstack的容器化部署项目。
本文主要对Kolla项目进行简单介绍,对其诞生的意义、内部的大概实现做出介绍,以便于读者快速理解项目以投入使用、快速进行自定义开发。
以下主要针对Kolla的Mitaka版本。开始写这篇文章时,Mitaka还尚未发布,因此使用的其实是master版本。
为什么要做容器化部署
Openstack之美
参考下图,OpenStack的架构设计是很漂亮的:清晰定义的服务,完美的原子操作,独立运行的可能,组件尽量无状态易于扩展。这是一个几乎做到极致的分布式架构。
Openstack之殇
但是现实是残酷的:
- 服务之间往往有严重的依赖,使得部署复杂,修改麻烦,服务的管理困难;
- 配置复杂,有时候可能仅仅是一个微小的配置错误,就会导致整个集群功能异常;
- 而且随着OpenStack的发展,架构及配置只会越来越复杂。
运维成本很高,效率低,严重影响了使用体验。
生产环境一旦部署完成很难去做大的升级。所以虽然每半年社区更新一个版本(目前马上M版本),但是真正生产环境可能还是I甚至E版本。对于每个组件,只做微小bug的升级,而且升级流程会非常谨慎。对于私有云产品也许还可以,但对于有大量用户严格SLA的公有云产品这是无法容忍的。这也是为什么说Openstack厂商离AWS、阿里云甚至UCloud这些大的公有云厂商还有很大的距离。
举个例子,如果我们要升级keystone这个基础组件——它是Openstack的认证组件,负载整个Openstack集群的鉴权,因此非常重要。
我们首先需要去判断这个版本的keystone和环境中使用的其它组件的当前版本是否完全兼容。而事实证明官方文档介绍很少,也是靠不住的,社区等着你发现bug做贡献呢;开发人员做出的估计有些也是不靠谱的,可以自行统计下每个组件的代码量;甚至简单的测试都不足够可靠,用例库也是逐渐总结出来的。这也说明了引入灰度上线和回滚机制是很有必要的。但是以现有的运维工具,回滚比较困难而且代价很大。因此一般在升级前都要做严格的升级测试,会有资源和人力的成本。
容器的崛起
虽然使用已有的一些OpenStack自动化部署工具,如puppet、fuel等,但往往只能部分解决这些问题,如不支持回滚、太重而导致资源浪费、体积太大速度缓慢等。
而docker在解决所有这些问题上具有很大的优势:
- 服务直接的相互隔离
- 轻量级,节省资源,体积小便捷易携带迁移
- 容易描述的运行时关系
- 容易升级回滚,可灰度上线,对服务完整的生命周期管理
- 不只局限于OpenStack,对其它服务如HA等也适用
- 而通过与Kubernetes、服务发现等容器技术栈的高级工具组合,能提供更强大的解决方案
当然还有容器的火爆发展,OpenStack社区怎么可能错过。
下图对以上所有做了个很好的总结:
基础知识
Kolla中使用到的技术栈总结如下。
- Docker,容器化基础工具
- Ansible,配置管理,主要用于生成配置文件
- Jinja,模板工具
- Kubernetes/Mesos,Openstack社区或者说很多开源社区的特点就是:大而全的策略,可以预言:容器领域内所有火的组件慢慢都会在Kolla中出现,而且它们确实能组合出强大的功能。
Docker简介
Docker是通过Linux内核如LXC、namespace等实现的容器化技术。关于Docker的详细请参考docker系列文章或官方文档。
通过Docker镜像,可以方便的对image进行版本管理。而且因为image的分层特性,体积较小,容易携带和分享。Docker的这些特性使得它非常适合于CI(持续集成/持续)/CD(持续部署/交付)系统,替换原来较重效率低得物理机或虚拟机方案。
在Kolla中,用到了超权限容器(super privileged containers),因为部分组件直接访问宿主机的资源而不是使用自己的命名空间,如libvirt需要访问宿主机的网络空间来创建虚拟机。但是除非必要,对容器需要严格的权限控制以保证安全。参考
Ansible简介
Ansible 组成
Ansible主要由以下部分组成:
- Inventory: 资产配置库,定义可管控的主机列表
- Modules: core modules(自带模块)、custom modules(自定义模块)
- Playbooks: 按照所设定编排的顺序执行完成安排任务
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
一个标准的目录结构如下图。
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提供的,蓝色组件由其它开源软件提供。
基本工作流如下:
- 开发人员提交代码到gerrit,被review通过后merge至git
- CD系统build出软件包(如RPM、DEB等)
- CD系统使用软件包生成docker镜像
- CD提交镜像到私有docker registry
- CD系统触发节点上的镜像升级
- 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.yml
或passwords.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 }} |
其中除了设置相关信息外,还做了这些事:
- 继承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的支持。 - 安装软件包
通过识别操作系统类型,安装对应的包。
如果研究下cinder-base的内容,可看到对源码安装的支持。 - 执行需要的命令
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]
#ceilometerkolla-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