真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

OpenStack容器服務Zun初探與原理分析

01

創(chuàng)新互聯(lián)公司從2013年創(chuàng)立,先為綦江等服務建站,綦江等地企業(yè),進行企業(yè)商務咨詢服務。為綦江企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務解決您的所有建站問題。

Zun服務簡介

Zun是OpenStack的容器服務(Containers as Service),類似于AWS的ECS服務,但實現(xiàn)原理不太一樣,ECS是把容器啟動在EC2虛擬機實例上,而Zun會把容器直接運行在compute節(jié)點上。

和OpenStack另一個容器相關的Magnum項目不一樣的是:Magnum提供的是容器編排服務,能夠提供彈性Kubernetes、Swarm、Mesos等容器基礎設施服務,管理的單元是Kubernetes、Swarm、Mesos集群,而Zun提供的是原生容器服務,支持不同的runtime如Docker、Clear Container等,管理的單元是container。

Zun服務的架構如圖:

OpenStack容器服務Zun初探與原理分析

Zun服務和Nova服務的功能和結構非常相似,只是前者提供容器服務,后者提供虛擬機服務,二者都是主流的計算服務交付模式。功能類似體現(xiàn)在如下幾點:

  • 通過Neutron提供網(wǎng)絡服務。

  • 通過Cinder實現(xiàn)數(shù)據(jù)的持久化存儲。

  • 都支持使用Glance存儲鏡像。

  • 其他如quota、安全組等功能。

組件結構結構相似則表現(xiàn)在:

  • 二者都是由API、調(diào)度、計算三大組件模塊構成,Nova由nova-api、nova-scheduler、nova-compute三大核心組件構成,而Zun由zun-api、zun-compute兩大核心組件構成,之所以沒有zun-scheduler是因為scheduler集成到zun-api中了。

  • nova-compute調(diào)用compute driver創(chuàng)建虛擬機,如Libvirt。zun-compute調(diào)用container driver創(chuàng)建容器,如Docker。

  • Nova通過一系列的proxy代理實現(xiàn)VNC(nova-novncproxy)、Splice(nova-spiceproxy)等虛擬終端訪問,Zun也是通過proxy代理容器的websocket實現(xiàn)遠程attach容器功能。

02

Zun服務部署

Zun服務部署和Nova、Cinder部署模式類似,控制節(jié)點創(chuàng)建數(shù)據(jù)庫、Keystone創(chuàng)建service以及注冊endpoints等,最后安裝相關包以及初始化配置。計算節(jié)點除了安裝zun-compute服務,還需要安裝要使用的容器,比如Docker。詳細的安裝過程可以參考官方文檔,如果僅僅是想進行POC測試,可以通過DevStack自動化快速部署一個AllInOne環(huán)境,供參考的local.conf配置文件如下:

OpenStack容器服務Zun初探與原理分析

如上配置會自動通過DevStack安裝Zun相關組件、Kuryr組件以及Docker。

03

Zun服務入門

3.1 Dashboard

安裝Zun服務之后,可以通過zun命令行以及Dashboard創(chuàng)建和管理容器。

有一個非常贊的功能是如果安裝了Zun,Dashboard能夠支持Cloud Shell,用戶能夠在DashBoard中進行交互式輸入OpenStack命令行。

OpenStack容器服務Zun初探與原理分析

原理的話就是通過Zun啟動了一個gbraad/openstack-client:alpine容器。

通過Dashboard創(chuàng)建容器和創(chuàng)建虛擬機的過程非常相似,都是通過panel依次選擇鏡像(image)、選擇規(guī)格(Spec)、選擇或者創(chuàng)建卷(volume)、選擇網(wǎng)絡(network/port)、選擇安全組(SecuiryGroup)以及scheduler hint,如圖:

OpenStack容器服務Zun初探與原理分析

其中Miscellaneous雜項中則為針對容器的特殊配置,比如設置環(huán)境變量(Environment)、工作目錄(Working Directory)等。

3.2 命令行操作

通過命令行創(chuàng)建容器也非常類似,使用過nova以及docker命令行的基本不會有困難,下面以創(chuàng)建一個MySQL容器為例:

OpenStack容器服務Zun初探與原理分析
  • 如上通過--mount參數(shù)指定了volume大小,由于沒有指定volume_id,因此Zun會新創(chuàng)建一個volume。需要注意的是,Zun創(chuàng)建的volume在容器刪除后,volume也會自動刪除(auto remove),如果需要持久化volume卷,則應該先通過Cinder創(chuàng)建一個volume,然后通過source選項指定volume_id,此時當容器刪除時不會刪除已有的volume卷。

  • 和虛擬機不一樣,虛擬機通過flavor配置規(guī)格,容器則直接指定cpu、memory、disk。

  • 如上沒有指定--image-driver參數(shù),則默認從dockerhub下載鏡像,如果指定glance,則會往glance下載鏡像。

另外mysql容器初始化時數(shù)據(jù)卷必須為空目錄,掛載的volume新卷格式化時會自動創(chuàng)建lost+found目錄,因此需要手動刪除,否則mysql容器會初始化失敗:

OpenStack容器服務Zun初探與原理分析

創(chuàng)建完成后可以通過zun list命令查看容器列表:

OpenStack容器服務Zun初探與原理分析

可以看到mysql的容器fixed IP為192.168.233.80,和虛擬機一樣,租戶IP默認與外面不通,需要綁定一個浮動IP(floating ip),

OpenStack容器服務Zun初探與原理分析

zun命令行目前還無法查看floating ip,只能通過neutron命令查看,獲取到floatingip并且安全組入訪允許3306端口后就可以遠程連接mysql服務了:

OpenStack容器服務Zun初探與原理分析

當然在同一租戶的虛擬機也可以直接通過fixed ip訪問mysql服務:

OpenStack容器服務Zun初探與原理分析

可見,通過容器啟動mysql服務和在虛擬機里面部署mysql服務,用戶訪問上沒有什么區(qū)別,在同一個環(huán)境中,虛擬機和容器可共存,彼此可相互通信,在應用層上可以完全把虛擬機和容器透明化使用,底層通過應用場景選擇虛擬機或者容器。

3.3 關于capsule

Zun除了管理容器container外,還引入了capsule的概念,capsule類似Kubernetes的pod,一個capsule可包含多個container,這些container共享network、ipc、pid namespace等。

通過capsule啟動一個mysql服務,聲明yaml文件如下:

OpenStack容器服務Zun初探與原理分析

創(chuàng)建mysql capsule:

OpenStack容器服務Zun初探與原理分析

可見capsule的init container用的就是kubernetes的pause鏡像。

3.4 總結

OpenStack的容器服務本來是在Nova中實現(xiàn)的,實現(xiàn)了Nova ComputeDriver,因此Zun的其他的功能如容器生命周期管理、image管理、service管理、action管理等和Nova虛擬機非常類似,可以查看官方文檔,這里不再贅述。

04

Zun實現(xiàn)原理

4.1 調(diào)用容器接口實現(xiàn)容器生命周期管理

前面提到過Zun主要由zun-api和zun-compute服務組成,zun-api主要負責接收用戶請求、參數(shù)校驗、資源準備等工作,而zun-compute則真正負責容器的管理,Nova的后端通過compute_driver配置,而Zun的后端則通過container_driver配置,目前只實現(xiàn)了DockerDriver。因此調(diào)用Zun創(chuàng)建容器,最終就是zun-compute調(diào)用docker創(chuàng)建容器。

下面以創(chuàng)建一個container為例,簡述其過程。

4.1.1 zun-api

首先入口為zun-api,主要代碼實現(xiàn)在zun/api/controllers/v1/containers.py以及zun/compute/api.py,創(chuàng)建容器的方法入口為post()方法,其調(diào)用過程如下:

zun/api/controllers/v1/containers.py

  1. policy enforce: 檢查policy,驗證用戶是否具有創(chuàng)建container權限的API調(diào)用。

  2. check security group: 檢查安全組是否存在,根據(jù)傳遞的名稱返回安全組的ID。

  3. check container quotas: 檢查quota配額。

  4. build requested network: 檢查網(wǎng)絡配置,比如port是否存在、network id是否合法,最后構建內(nèi)部的network對象模型字典。注意,這一步只檢查并沒有創(chuàng)建port。

  5. create container object:根據(jù)傳遞的參數(shù),構造container對象模型。

  6. build requeted volumes: 檢查volume配置,如果傳遞的是volume id,則檢查該volume是否存在,如果沒有傳遞volume id只指定了size,則調(diào)用Cinder API創(chuàng)建新的volume。

zun/compute/api.py

  1. schedule container: 使用FilterScheduler調(diào)度container,返回宿主機的host對象。這個和nova-scheduler非常類似,只是Zun集成到zun-api中了。目前支持的filters如CPUFilter、RamFilter、LabelFilter、ComputeFilter、RuntimeFilter等。

  2. image validation: 檢查鏡像是否存在,這里會遠程調(diào)用zun-compute的image_search方法,其實就是調(diào)用docker search。這里主要為了實現(xiàn)快速失敗,避免到了compute節(jié)點才發(fā)現(xiàn)image不合法。

  3. record action: 和Nova的record action一樣,記錄container的操作日志。

  4. rpc cast container_create: 遠程異步調(diào)用zun-compute的container_create()方法,zun-api任務結束。

4.1.2 zun-compute

zun-compute負責container創(chuàng)建,代碼位于zun/compute/manager.py,過程如下:

  1. wait for volumes avaiable: 等待volume創(chuàng)建完成,狀態(tài)變?yōu)閍vaiable。

  2. attach volumes:掛載volumes,掛載過程后面再介紹。

  3. checksupportdisk_quota: 如果使用本地盤,檢查本地的quota配額。

  4. pull or load image: 調(diào)用Docker拉取或者加載鏡像。

  5. 創(chuàng)建docker network、創(chuàng)建neutron port,這個步驟下面詳細介紹。

  6. create container: 調(diào)用Docker創(chuàng)建容器。

  7. container start: 調(diào)用Docker啟動容器。

以上調(diào)用Dokcer拉取鏡像、創(chuàng)建容器、啟動容器的代碼位于zun/container/docker/driver.py,該模塊基本就是對社區(qū)Docker SDK for Python的封裝。

OpenStack容器服務Zun初探與原理分析

Zun的其他操作比如start、stop、kill等實現(xiàn)原理也類似,這里不再贅述。

4.2 通過websocket實現(xiàn)遠程容器訪問

我們知道虛擬機可以通過VNC遠程登錄,物理服務器可以通過SOL(IPMI Serial Over LAN)實現(xiàn)遠程訪問,容器則可以通過websocket接口實現(xiàn)遠程交互訪問。

Docker原生支持websocket連接,參考APIAttach to a container via a websocket,websocket地址為/containers/{id}/attach/ws,不過只能在計算節(jié)點訪問,那如何通過API訪問呢?

和Nova、Ironic實現(xiàn)完全一樣,也是通過proxy代理轉發(fā)實現(xiàn)的,負責container的websocket轉發(fā)的進程為zun-wsproxy。

當調(diào)用zun-compute的container_attach()方法時,zun-compute會把container的websocket_url以及websocket_token保存到數(shù)據(jù)庫中.

OpenStack容器服務Zun初探與原理分析

zun-wsproxy則可讀取container的websocket_url作為目標端進行轉發(fā):

OpenStack容器服務Zun初探與原理分析

通過Dashboard可以遠程訪問container的shell:

OpenStack容器服務Zun初探與原理分析

當然通過命令行zun attach也可以attach container。

4.3 使用Cinder實現(xiàn)容器持久化存儲

前面介紹過Zun通過Cinder實現(xiàn)container的持久化存儲,之前我的另一篇文章介紹了Docker使用OpenStack Cinder持久化volume原理分析及實踐,介紹了john griffith開發(fā)的docker-cinder-driver以及OpenStack Fuxi項目,這兩個項目都實現(xiàn)了Cinder volume掛載到Docker容器中。另外cinderclient的擴展模塊python-brick-cinderclient-ext實現(xiàn)了Cinder volume的local attach,即把Cinder volume掛載到物理機中。

Zun沒有復用以上的代碼模塊,而是重新實現(xiàn)了volume attach的功能,不過實現(xiàn)原理和上面的方法完全一樣,主要包含如下過程:

  1. connect volume: connect volume就是把volume attach(映射)到container所在的宿主機上,建立連接的的協(xié)議通過initialize_connection信息獲取,如果是LVM類型則一般通過iscsi,如果是Ceph rbd則直接使用rbd map。

  2. ensure mountpoit tree: 檢查掛載點路徑是否存在,如果不存在則調(diào)用mkdir創(chuàng)建目錄。

  3. make filesystem:如果是新的volume,掛載時由于沒有文件系統(tǒng)因此會失敗,此時會創(chuàng)建文件系統(tǒng)。

  4. do mount: 一切準備就緒,調(diào)用OS的mount接口掛載volume到指定的目錄點上。

Cinder Driver的代碼位于`zun/volume/driver.py的Cinder類中,方法如下:

OpenStack容器服務Zun初探與原理分析

其中cinder.attach_volume()實現(xiàn)如上的第1步,而_mount_device()實現(xiàn)了如上的2-4步。

4.4 集成Neutron網(wǎng)絡實現(xiàn)容器網(wǎng)絡多租戶

4.4.1 關于容器網(wǎng)絡

前面我們通過Zun創(chuàng)建容器,使用的就是Neutron網(wǎng)絡,意味著容器和虛擬機完全等同的共享Neutron網(wǎng)絡服務,虛擬機網(wǎng)絡具有的功能,容器也能實現(xiàn),比如多租戶隔離、floating ip、安全組、防火墻等。

Docker如何與Neutron網(wǎng)絡集成呢?根據(jù)官方Docker network plugin API介紹,插件位于如下目錄:

  • /run/docker/plugins

  • /etc/docker/plugins

  • /usr/lib/docker/plugins

OpenStack容器服務Zun初探與原理分析

由此可見Docker使用的是kuryr網(wǎng)絡插件。

Kuryr也是OpenStack中一個較新的項目,其目標是“Bridge between container framework networking and storage models to OpenStack networking and storage abstractions.”,即實現(xiàn)容器與OpenStack的網(wǎng)絡與存儲集成,當然目前只實現(xiàn)了網(wǎng)絡部分的集成。

而我們知道目前容器網(wǎng)絡主要有兩個主流實現(xiàn)模型:

  • CNM:Docker公司提出,Docker原生使用的該方案,通過HTTP請求調(diào)用,模型設計可參考The Container Network Model Design,network插件可實現(xiàn)兩個Driver,其中一個為IPAM Driver,用于實現(xiàn)IP地址管理,另一個為Docker Remote Drivers,實現(xiàn)網(wǎng)絡相關的配置。

  • CNI:CoreOS公司提出,Kubernetes選擇了該方案,通過本地方法或者命令行調(diào)用。

因此Kuryr也分成兩個子項目,kuryr-network實現(xiàn)CNM接口,主要為支持原生的Docker,而kury-kubernetes則實現(xiàn)的是CNI接口,主要為支持Kubernetes,Kubernetes service還集成了Neutron LBaaS,下次再單獨介紹這個項目。

由于Zun使用的是原生的Docker,因此使用的是kuryr-network項目,實現(xiàn)的是CNM接口,通過remote driver的形式注冊到Docker libnetwork中,Docker會自動向插件指定的socket地址發(fā)送HTTP請求進行網(wǎng)絡操作,我們的環(huán)境是http://127.0.0.1:23750,即kuryr-libnetwork.service監(jiān)聽的地址,Remote API接口可以參考Docker Remote Drivers。

4.4.2 kuryr實現(xiàn)原理

前面4.1節(jié)介紹到zun-compute會調(diào)用docker driver的create()方法創(chuàng)建容器,其實這個方法不僅僅是調(diào)用python docker sdk的create_container()方法,還做了很多工作,其中就包括網(wǎng)絡相關的配置。

首先檢查Docker的network是否存在,不存在就創(chuàng)建,network name為Neutron network的UUID,

OpenStack容器服務Zun初探與原理分析

然后會調(diào)用Neutron創(chuàng)建port,從這里可以得出結論,容器的port不是Docker libnetwork也不是Kuryr創(chuàng)建的,而是Zun創(chuàng)建的。

回到前面的Remote Driver,Docker libnetwork會首先POST調(diào)用kuryr的/IpamDriver.RequestAddressAPI請求分配IP,但顯然前面Zun已經(jīng)創(chuàng)建好了port,port已經(jīng)分配好了IP,因此這個方法其實就是走走過場。如果直接調(diào)用docker命令指定kuryr網(wǎng)絡創(chuàng)建容器,則會調(diào)用該方法從Neutron中創(chuàng)建一個port。

接下來會POST調(diào)用kuryr的/NetworkDriver.CreateEndpoint方法,這個方法最重要的步驟就是binding,即把port attach到宿主機中,binding操作單獨分離出來為kuryr.lib庫,這里我們使用的是veth driver,因此由kuryr/lib/binding/drivers/veth.py模塊的port_bind()方法實現(xiàn),該方法創(chuàng)建一個veth對,其中一個為tap-xxxx,xxxx為port ID前綴,放在宿主機的namespace,另一個為t_cxxxx放到容器的namespace,t_cxxxx會配置上IP,而tap-xxxx則調(diào)用shell腳本(腳本位于/usr/local/libexec/kuryr/)把tap設備添加到ovs br-int橋上,如果使用HYBRID_PLUG,即安全組通過Linux Bridge實現(xiàn)而不是OVS,則會創(chuàng)建qbr-xxx,并創(chuàng)建一個veth對關聯(lián)到ovs br-int上。

從這里可以看出,Neutron port綁定到虛擬機和容器基本沒有什么區(qū)別,如下所示:

OpenStack容器服務Zun初探與原理分析

唯一不同的就是虛擬機是把tap設備直接映射到虛擬機的虛擬設備中,而容器則通過veth對,把另一個tap放到容器的namespace中。

有人會說,br-int的流表在哪里更新了?這其實是和虛擬機是完全一樣的,當調(diào)用port update操作時,neutron server會發(fā)送RPC到L2 agent中(如neutron-openvswitch-agent),agent會根據(jù)port的狀態(tài)更新對應的tap設備以及流表。

因此其實kuryr只干了一件事,那就是把Zun申請的port綁定到容器中。

05

總結

OpenStack Zun項目非常完美地實現(xiàn)了容器與Neutron、Cinder的集成,加上Ironic裸機服務,OpenStack實現(xiàn)了容器、虛擬機、裸機共享網(wǎng)絡與存儲。未來我覺得很長一段時間內(nèi)裸機、虛擬機和容器將在數(shù)據(jù)中心混合存在,OpenStack實現(xiàn)了容器和虛擬機、裸機的完全平等、資源共享以及功能對齊,應用可以根據(jù)自己的需求選擇容器、虛擬機或者裸機,使用上沒有什么區(qū)別,用戶只需要關心業(yè)務針對性能的需求以及對硬件的特殊訪問,對負載(workload)是完全透明的。

參考文獻

  • docker python sdk: https://docker-py.readthedocs.io/en/stable/

  • Zun’s documentation: https://docs.openstack.org/zun/latest/

  • https://docs.docker.com/engine/api/v1.39/#operation/ContainerAttachWebsocket

  • http://int32bit.me/2017/10/04/Docker使用OpenStack-Cinder持久化volume原理分析及實踐/

  • https://specs.openstack.org/openstack/cinder-specs/specs/mitaka/use-cinder-without-nova.html

  • https://docs.docker.com/engine/extend/plugin_api/

  • https://github.com/docker/libnetwork/blob/master/docs/design.md

  • https://github.com/docker/libnetwork/blob/master/docs/ipam.md

  • https://github.com/docker/libnetwork/blob/master/docs/remote.md

  • https://docs.openstack.org/kuryr-libnetwork/latest/

  • https://docs.openstack.org/magnum/latest/user/

  • https://github.com/docker/libnetwork

  • https://www.nuagenetworks.net/blog/container-networking-standards/

  • http://blog.kubernetes.io/2016/01/why-Kubernetes-doesnt-use-libnetwork.html


分享題目:OpenStack容器服務Zun初探與原理分析
標題URL:http://weahome.cn/article/psssdh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部