1. 程式人生 > >Openstack容器化部署研究之:Kolla離線製作Openstack服務的Docker容器映象

Openstack容器化部署研究之:Kolla離線製作Openstack服務的Docker容器映象

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容器映象:

[[email protected] 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