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容器映象,個人認為有以下幾個原因:
- 理清Kolla製作映象的機制原理,這是熟悉Kolla專案的極佳過程;
- 靈活按需自定義Docker映象,按照自己需求修改Dockerfile檔案以自定義Openstack的Docker容器映象;
- 比起使用他人制作的映象,自己定義的映象更具安全感和成就感;
- 最關鍵也是最重要一點,國內以線上方式使用Kolla幾乎沒法進行映象編譯。
3、需要哪些背景知識
理論上講,通過Kolla專案來製作Openstack的Docker映象其實非常簡單,如果不是因為國內特殊的網路環境,只需kolla-build一個不帶任何引數的命令即可搞定。反過來想,應該感謝GFW,不然也不會花心思去研究kolla-build背後的祕密。要通過Kolla專案進行離線Docker容器映象的製作,筆者認為應該具備如下幾方面的知識:
- 本地yum源的製作,以及遠端yum倉庫的本地同步原理和配置。可參考如下博文:http://blog.csdn.net/madmanvswarrior/article/details/49952245。
- jinja2模板的基本語法,Kolla大量採用jinja2模板進行變數傳遞,因此需要掌握基本的jinja2相關知識,例如模板的定義和渲染等基本知識,以及如何在jinja2模板中引用變數和編寫Python命令列等。參考:http://docs.jinkan.org/docs/jinja2/
- Docker Registry/Repository知識,提到Docker映象,Docker倉庫必不可少,因此如何製作Docker私有倉庫,以及如何與私有倉庫進行pull/push操作是必須掌握的。可參考如下博文:http://blog.csdn.net/wangtaoking1/article/details/44180901
- Dockerfile是必須掌握的,Dockerfile中最基本的命令,如RUN、COPY、CMD等等,Kolla專案的Dockerfile遵循Docker官方的Dockerfile最佳實踐指南。參考:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#run
- 如果是RHEL/Centos系統,則最好了解Docker在Centos下的預設儲存驅動DeviceMapper,Docker為了保證開箱即用,在Centos中的DeviceMapper預設採用的是loop-lvm模式,對於生產系統,官方推薦採用direct-lvm模式,因此不管是否生產系統都都建議手動配置為direct-lvm模式。參考: http://blog.csdn.net/qq_26923057/article/details/52351731
- 基本的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