1、前言

作为拥抱Docker容器技术的代表,Kolla已成为当前Openstack生态圈中最为热门的项目之一。Kolla项目目前已被拆分为三个部分,即用以Build Docker镜像的Kolla项目和用以编排部署Docker镜像的Kolla-ansible和Kolla-k8s项目,目前较为成熟并具备生产级别部署的是Kolla和Kolla-ansible项目。虽然Kolla-k8s还在成熟开发过程中,但是不可否认,由于Kolla-k8s结合了时下最为热门和成熟的Kebernetes容器编排引擎,其未来很有可能会是Kolla项目的重心,也是Kolla能够在容器时代突围而出的潜力之星。

2、为何要以离线方式制作Openstack的Docker容器镜像

Docker容器镜像的制作主要由Kolla项目来完成,而事实上,DockerHub(https://hub.docker.com/u/kolla/)和Kolla项目组(http://tarballs.openstack.org/kolla/images/)都维护有自己的Openstack Docker容器镜像,用户可以直接从上述两个网站下载Openstack的Docker容器镜像,并通过kolla-ansible进行部署。除此之外,Kolla项目提供了kolla-build命令进行Docker容器镜像编译,用户从Github上(https://github.com/openstack/kolla/)下载安装之后即可使用kolla-build命令进行镜像编译。正常情况下,kolla-build命令默认编译全部已被Kolla项目组容器化的Openstack项目,但是就目前国内的网络环境而言,对于普通用户,使用kolla-build命令几乎不可能以在线方式正常编译全部Openstack容器镜像。关于为何需要采取离线方式自己制作Openstack容器镜像,个人认为有以下几个原因:

  1. 理清Kolla制作镜像的机制原理,这是熟悉Kolla项目的极佳过程;
  2. 灵活按需自定义Docker镜像,按照自己需求修改Dockerfile文件以自定义Openstack的Docker容器镜像;
  3. 比起使用他人制作的镜像,自己定义的镜像更具安全感和成就感;
  4. 最关键也是最重要一点,国内以在线方式使用Kolla几乎没法进行镜像编译

3、需要哪些背景知识

理论上讲,通过Kolla项目来制作Openstack的Docker镜像其实非常简单,如果不是因为国内特殊的网络环境,只需kolla-build一个不带任何参数的命令即可搞定。反过来想,应该感谢GFW,不然也不会花心思去研究kolla-build背后的秘密。要通过Kolla项目进行离线Docker容器镜像的制作,笔者认为应该具备如下几方面的知识:

  1. 本地yum源的制作,以及远程yum仓库的本地同步原理和配置。可参考如下博文:http://blog.csdn.net/madmanvswarrior/article/details/49952245。
  2. jinja2模板的基本语法,Kolla大量采用jinja2模板进行变量传递,因此需要掌握基本的jinja2相关知识,例如模板的定义和渲染等基本知识,以及如何在jinja2模板中引用变量和编写Python命令行等。参考:http://docs.jinkan.org/docs/jinja2/
  3. Docker Registry/Repository知识,提到Docker镜像,Docker仓库必不可少,因此如何制作Docker私有仓库,以及如何与私有仓库进行pull/push操作是必须掌握的。可参考如下博文:http://blog.csdn.net/wangtaoking1/article/details/44180901
  4. Dockerfile是必须掌握的,Dockerfile中最基本的命令,如RUN、COPY、CMD等等,Kolla项目的Dockerfile遵循Docker官方的Dockerfile最佳实践指南。参考:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#run
  5. 如果是RHEL/Centos系统,则最好了解Docker在Centos下的默认存储驱动DeviceMapper,Docker为了保证开箱即用,在Centos中的DeviceMapper默认采用的是loop-lvm模式,对于生产系统,官方推荐采用direct-lvm模式,因此不管是否生产系统都都建议手动配置为direct-lvm模式。参考:  http://blog.csdn.net/qq_26923057/article/details/52351731
  6. 基本的Python语言知识。要想更深层次的了解Kolla,你需要一定的Python知识,Kolla项目的kolla/kolla/image/build.py是Kolla编译镜像的关键,熟读此脚本是理解Kolla的关键。脚本在此:https://github.com/openstack/kolla/blob/stable/ocata/kolla/image/build.py

 4、离线Docker镜像制作过程

 在进行离线镜像编译之前,首先需要考虑的是同步哪些yum源至本地呢?这得先从Kolla编译Openstack的Docker容器镜像层次关系来说起,以在线使用Kolla来制作Nova镜像为例,假设使用kolla-build nova命令来以默认方式编译nova镜像,而且成功编译nova镜像,则在Docker中将会看到以下几个镜像存在:centos-binary-base、centos-binary-openstack-base、centos-binary-nova-base和centos-binary-nova-api/scheduler/compute等nova子服务镜像,在这些镜像中,对于最后的Openstack部署而言,真正有用的其实只有centos-binary-nova-api、centos-binary-nova-scheduler、centos-binary-nova-compute等镜像。但是对于任何一个Openstack项目,类似centos-binary-base、centos-binary-openstack-base、centos-binary-nova-base的基础镜像都会存在,其中,centos-binary-base是最顶层的父镜像,基础服务组件(如mariaDB、RabbitMQ等)和Openstack项目组件都会继承该镜像,而centos-binary-openstack-base是centos-binary-base的子镜像,也是所有Openstack服务的父镜像,centos-binary-nova-base镜像继承centos-binary-openstack-base镜像,centos-binary-nova-api镜像又继承centos-binary-nova-base镜像,因此上述镜像的继承关系如下:

centos-binary-base -> centos-binary-openstack-base ->centos-binary-nova-base -> centos-binary-nova-api

为了使得相同的yum源可以贯穿整个Openstack系统,yum源的设置全被定义在生成centos-binary-base镜像的Dockerfile.j2文件中。在Kolla项目中,该文件的路径为kolla/docker/base/Dockerfile.j2,在Github中的位置为https://github.com/openstack/kolla/blob/stable/ocata/docker/base/Dockerfile.j2。想要知道应该同步哪些yum源至本地,阅读该文件即可获取Kolla项目中的全部yum源设置。如下是笔者从中提取的整个Kolla项目使用到的yum源(基于Centos):

centos-base.repo

centos-ceph-jewel.repo

centos-openstack-ocata.repo

centos-qemu-ev.repo

elasticsearch.repo

elrepo.repo

epel.repo

extras.repo

influxdb.repo

mariadb.repo

percona.repo

treasuredata.repo

updates.repo

zookeeper.repo

grafana.repo

kibana.repo

找到Kolla项目使用到的yum源后,可以通过reposync命令将这些源全部同步到本地目录,具体同步过程可参考:http://blog.csdn.net/madmanvswarrior/article/details/49952245。将远程yum源同步至本地后,可以通过createrepo命令创建本地repo仓库,之后通过httpd服务提供这些repo仓库的访问,即不同位置的客户端可以通过HTTP下载这些本地repo仓库中的安装包。Kolla在Docker镜像编译过程中具有很强的灵活性,具体参见:https://github.com/openstack/kolla/blob/stable/ocata/doc/image-building.rst。Kolla支持用户自定义的Repos进行镜像编译,用户只需将制作完成且可用的repo文件、RPM或者URL以列表形式赋值给/etc/kolla/kolla-build.conf中的rpm_setup_conf变量即可,如下:

rpm_setup_config = centos-base.repo,centos-ceph-jewel.repo,centos-openstack-ocata.repo,\

centos-qemu-ev.repo,docker.repo,elasticsearch.repo,elrepo.repo,epel.repo,extras.repo,influxdb.repo,\

mariadb.repo,percona.repo,treasuredata.repo,updates.repo,zookeeper.repo,grafana.repo,kibana.repo

需要注意的是,上述全部repo文件必须位于kolla/docker/base目录中(与Base镜像的Dockerfile文件位于相同路径),因为在Kolla编译镜像时,这些repo文件将会被Dockerfile的COPY命令拷贝到centos-binary-base镜像的/etc/yum.repos.d目录中,具体细节可参考kolla/kolla/image/build.py中的build_rpm_setup()函数实现代码:

def build_rpm_setup(self, rpm_setup_config):

       """Generates a list of docker commands based on providedconfiguration.

        :paramrpm_setup_config: A list of .rpm or .repo paths or URLs

        :return: A list ofdocker commands

        """

        rpm_setup = list()

 

        for config inrpm_setup_config:

//处理以.rpm结尾的源

            ifconfig.endswith('.rpm'):

                # RPM filescan be installed with yum from file path or url

                cmd ="RUN yum -y install {}".format(config)

//处理以.repo结尾的源

            elifconfig.endswith('.repo'):

//如果.repo文件位于网络上,则通过curl命令下载

                ifconfig.startswith('http'):

                    # Curlhttp://url/etc.repo to

                   /etc/yum.repos.d/etc.repo

                    name =config.split('/')[-1]

                    cmd ="RUN curl -L {} -o /etc/yum.repos.d/{}".format(

                        config, name)

//如果.repo文件位于Dockerfile的context目录中,则直接拷贝

                else:

                    # Copy.repo file from filesystem

                    cmd ="COPY {} /etc/yum.repos.d/".format(config)

            else:

                raiseexception.KollaRpmSetupUnknownConfig(

                    'RPM setupmust be provided as .rpm or .repo files.'

                    'Attempted configuration was {}'.format(config)

                )

           rpm_setup.append(cmd)

        return rpm_setup

将全部.repo文件放入kolla/docker/base目录,并为/etc/kolla/kolla-build.conf的rpm_setup_conf设置变量值后,如果希望在kolla编译镜像时处于完全离线状态,则需仔细检查kolla/docker/base/Dockerfile.j2文件中是否还有需要访问互联网进行下载的命令,例如curl命令,如果存在则事先将其下载到本地,并将原互联网目标地址设置为本地地址,这样在Kolla编译镜像时,将直接从本地进行下载,而不会再访问互联网。此外,还有个特别需要注意的地方,在Kolla编译镜像时,Docker容器需要通过宿主机的IPV4转发功能才能访问位于本地网络中的资源,因此注意在正式编译镜像前在宿主机上执行如下命令:

echo " net.ipv4.ip_forward = 1 ">> /etc/sysctl.conf"&&sysctl -p

在kolla4.0.1以后,如果未设置IP转发,则在编译时会有明确告警提示。此时可以ctrl+c停止并重新执行上述命令后再进行编译。Kolla在编译镜像时,支持命令行参数和配置文件参数,建议使用/etc/kolla/kolla-build.conf配置文件参数,如下是笔者在kolla-build.conf中自定义的参数情况:

[DEFAULT]

debug = true            //默认为false,建议打开

namespace = localkolla     //命名空间,默认为kolla

cache = true

profile = main          //可用值为infra,main,aux,default,gate

push = true            //编译完成后推送镜像至指定registry中

registry = 192.168.128.13:4000 //私有Registry地址

logs_dir = /etc/kolla/log    //镜像编译时的log存储位置

maintainer = warrior      //镜像作者

rpm_setup_config = centos-base.repo,centos-ceph-jewel.repo,centos-openstack-ocata.repo,\

centos-qemu-ev.repo,docker.repo,elasticsearch.repo,elrepo.repo,epel.repo,extras.repo,influxdb.repo,\

iso.repo,mariadb.repo,percona.repo,treasuredata.repo,updates.repo,zookeeper.repo,\

grafana.repo,kibana.repo    //自定义的repo文件

定义了上述参数后,可以直接执行不带任何参数的kolla-build命令,Kolla将自动读取kolla-build.conf中的设置的参数值进行镜像编译。kolla-build命令必须在安装了Kolla之后才能使用,如果仅是clone了Kolla源代码,则可以直接运行kolla/tools/build.py文件,其结果和运行kolla-build命令是一样的,kolla/tools/build.py和kolla-build命令最终调用的都是kolla/kolla/image/build.py文件。如下是采用离线方式,利用Kolla进行编译后的Openstack部分项目的Docker容器镜像:

[root@kolla-docker yum.repos.d]# docker images --format "table{{.Repository}}\t{{.Tag}}"

REPOSITORY                                                               TAG

192.168.128.13:4000/localkolla/centos-binary-cinder-volume                4.0.1

192.168.128.13:4000/localkolla/centos-binary-cinder-api                   4.0.1

192.168.128.13:4000/localkolla/centos-binary-designate-api                4.0.1

192.168.128.13:4000/localkolla/centos-binary-designate-central            4.0.1

192.168.128.13:4000/localkolla/centos-binary-designate-pool-manager       4.0.1

192.168.128.13:4000/localkolla/centos-binary-designate-worker             4.0.1

192.168.128.13:4000/localkolla/centos-binary-designate-backend-bind9      4.0.1

192.168.128.13:4000/localkolla/centos-binary-designate-sink               4.0.1

192.168.128.13:4000/localkolla/centos-binary-designate-mdns               4.0.1

192.168.128.13:4000/localkolla/centos-binary-cinder-backup                4.0.1

192.168.128.13:4000/localkolla/centos-binary-cinder-scheduler             4.0.1

192.168.128.13:4000/localkolla/centos-binary-trove-guestagent             4.0.1

192.168.128.13:4000/localkolla/centos-binary-ironic-inspector             4.0.1

192.168.128.13:4000/localkolla/centos-binary-ironic-pxe                   4.0.1

192.168.128.13:4000/localkolla/centos-binary-trove-api                    4.0.1

192.168.128.13:4000/localkolla/centos-binary-ironic-conductor             4.0.1

192.168.128.13:4000/localkolla/centos-binary-ironic-api                   4.0.1

192.168.128.13:4000/localkolla/centos-binary-panko-api                    4.0.1

192.168.128.13:4000/localkolla/centos-binary-trove-taskmanager            4.0.1

192.168.128.13:4000/localkolla/centos-binary-trove-conductor              4.0.1

192.168.128.13:4000/localkolla/centos-binary-mistral-api                  4.0.1

192.168.128.13:4000/localkolla/centos-binary-octavia-api                  4.0.1

192.168.128.13:4000/localkolla/centos-binary-ceilometer-api               4.0.1

192.168.128.13:4000/localkolla/centos-binary-mistral-executor             4.0.1

192.168.128.13:4000/localkolla/centos-binary-glance-registry              4.0.1

192.168.128.13:4000/localkolla/centos-binary-mistral-engine               4.0.1

192.168.128.13:4000/localkolla/centos-binary-octavia-worker               4.0.1

 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐