中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-08-04 22:59:05 來源:ITPUB博客 閱讀:520 作者:int32bit 欄目:云計算

01

Zun服務簡介

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

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

Zun服務的架構如圖:

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


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

  • 通過Neutron提供網絡服務。

  • 通過Cinder實現數據的持久化存儲。

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

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

組件結構結構相似則表現在:

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

  • nova-compute調用compute driver創建虛擬機,如Libvirt。zun-compute調用container driver創建容器,如Docker。

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

02

Zun服務部署

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

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

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

03

Zun服務入門

3.1 Dashboard

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

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

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

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

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

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

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

3.2 命令行操作

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

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

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

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

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

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

創建完成后可以通過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服務,用戶訪問上沒有什么區別,在同一個環境中,虛擬機和容器可共存,彼此可相互通信,在應用層上可以完全把虛擬機和容器透明化使用,底層通過應用場景選擇虛擬機或者容器。

3.3 關于capsule

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

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

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

創建mysql capsule:

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

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

3.4 總結

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

04

Zun實現原理

4.1 調用容器接口實現容器生命周期管理

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

下面以創建一個container為例,簡述其過程。

4.1.1 zun-api

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

zun/api/controllers/v1/containers.py

  1. policy enforce: 檢查policy,驗證用戶是否具有創建container權限的API調用。

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

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

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

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

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

zun/compute/api.py

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

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

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

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

4.1.2 zun-compute

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

  1. wait for volumes avaiable: 等待volume創建完成,狀態變為avaiable。

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

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

  4. pull or load image: 調用Docker拉取或者加載鏡像。

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

  6. create container: 調用Docker創建容器。

  7. container start: 調用Docker啟動容器。

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

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

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

4.2 通過websocket實現遠程容器訪問

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

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

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

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

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

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

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

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

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

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

4.3 使用Cinder實現容器持久化存儲

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

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

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

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

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

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

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

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

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

4.4 集成Neutron網絡實現容器網絡多租戶

4.4.1 關于容器網絡

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

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

  • /run/docker/plugins

  • /etc/docker/plugins

  • /usr/lib/docker/plugins

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

由此可見Docker使用的是kuryr網絡插件。

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

而我們知道目前容器網絡主要有兩個主流實現模型:

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

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

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

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

4.4.2 kuryr實現原理

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

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

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

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

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

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

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

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

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

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

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

05

總結

OpenStack Zun項目非常完美地實現了容器與Neutron、Cinder的集成,加上Ironic裸機服務,OpenStack實現了容器、虛擬機、裸機共享網絡與存儲。未來我覺得很長一段時間內裸機、虛擬機和容器將在數據中心混合存在,OpenStack實現了容器和虛擬機、裸機的完全平等、資源共享以及功能對齊,應用可以根據自己的需求選擇容器、虛擬機或者裸機,使用上沒有什么區別,用戶只需要關心業務針對性能的需求以及對硬件的特殊訪問,對負載(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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绥中县| 罗江县| 广汉市| 奇台县| 宜丰县| 五华县| 遂溪县| 黑龙江省| 阿拉善盟| 黔西| 桂平市| 武宁县| 邯郸市| 旬邑县| 奈曼旗| 兴安县| 洛隆县| 怀远县| 汕尾市| 昌黎县| 绥滨县| 宁乡县| 弥勒县| 武山县| 北安市| 武川县| 西乌珠穆沁旗| 镇平县| 广水市| 通州市| 阿巴嘎旗| 新泰市| 大化| 兰州市| 峨山| 花垣县| 凤台县| 囊谦县| 新化县| 北京市| 尚志市|