基於OSS搭建跨區域部署的分散式Docker映象倉庫
基於OSS搭建跨區域部署的分散式Docker映象倉庫
Docker映象是Docker的核心價值之一,Docker映象倉庫(Registry)是用於Docker映象的管理和分發的基礎設施。現在已經有了Docker Hub等多家公有映象管理服務供應商,阿里雲容器Hub服務也是您在雲端的一個非常好的選擇。但是有些情況,為了更加靈活的部署控制和一些管控要求,您也許會考慮在雲端的部署一個私有映象倉庫。
為了滿足異地容災和就近訪問等需求,需要在不同的區域(region)部署分散式Docker應用;在不同的region中,為了提升部署速度並節省網路成本,需要在每個region部署私有Docker Registry。然而,這就會給分散式部署中的映象管理帶來很多挑戰。本文將結合阿里雲OSS的新特性來介紹跨域部署的Docker映象倉庫的解決方案。
阿里雲搭建Docker Registry入門
Docker Registry是儲存和網路密集型應用。Docker映象儲存需要使用大量的儲存資源,採用本地儲存無法滿足使用者對容量和可用性的需求;同時映象的上傳,下載需要高速的網路頻寬。Docker Registry自從2.1版本開始,就已經加入了對阿里雲開放儲存服務(OSS)的正式支援。這為Docker Registry提供一個支援海量儲存,高效能訪問,高可用,安全,低成本,無需運維的儲存後端。而且利用ECS構建私有倉庫可以使用OSS內部資料流量,降低公網網路流量成本。在集團內部和阿里雲的映象倉庫服務,我們都採用了OSS的物件儲存服務,來支援對內和對外的Docker映象管理和分發。
在阿里雲上ECS上搭建一個Docker Registry是非常方便的,最方便的方法是利用Docker映象的方式來進行安裝。
首先我們要在ECS上有一個Docker執行環境,你可以手工安裝Docker Engine到已有的ECS例項上;或者,利用Docker Machine的ECS驅動方便的建立一個新的Docker就緒的ECS例項。請參見入門指南
啟動一個使用OSS的儲存的Docker Registry也是非常簡單的,我推薦的方法是利用Docker Compose的方式配置和啟動:
一個包含最簡單的配置的docker-compose.yml
如下
registry:
restart: always
image: "registry:2.3"
ports:
- 5000:5000
environment:
- REGISTRY_STORAGE=oss
- REGISTRY_STORAGE_OSS_ACCESSKEYID=******
- REGISTRY_STORAGE_OSS_ACCESSKEYSECRET=******
- REGISTRY_STORAGE_OSS_REGION=oss-cn-beijing
- REGISTRY_STORAGE_OSS_BUCKET=aliyungo-beijing
- REGISTRY_STORAGE_OSS_INTERNAL=true
- REGISTRY_STORAGE_OSS_SECURE=false
這裡,我們將利用Docker Registry 2.3官方映象建立一個私有映象倉庫,通過環境變數的方式配置了OSS的Access Key ID, Access Key Secret, Region, Bucket等資訊。關於OSS配置的詳細資訊請參見官方文件
然後執行 docker-compose up -d
命令, 私有映象就啟動成功了。
我們可以在ECS例項上執行下面命令來驗證相關工作
docker pull node:5.7
docker tag node:5.7 127.0.0.1:5000/node:5.7
docker push 127.0.0.1:5000/node:5.7
執行結果如下,已經成功將映象推送成功
[root@iZ25cz6gdslZ ~]# docker pull node:5.7
5.7: Pulling from library/node
fdd5d7827f33: Already exists
a3ed95caeb02: Pull complete
0f35d0fe50cc: Already exists
627b6479c8f7: Already exists
67c44324f4e3: Already exists
b52090f6ca00: Pull complete
1df855d9e713: Pull complete
Digest: sha256:cde7a4fca0a3dd2330977078c3773164b172a0ec582bafced6db955dca02a5c4
Status: Downloaded newer image for node:5.7
[root@iZ25cz6gdslZ ~]# docker tag node:5.7 127.0.0.1:5000/node:5.7
[root@iZ25cz6gdslZ ~]# docker push 127.0.0.1:5000/node:5.7
The push refers to a repository [127.0.0.1:5000/node]
5f70bf18a086: Mounted from ubuntu
1967867932fe: Pushed
6b4fab929601: Pushed
550f16cd8ed1: Mounted from python
44267ec3aa94: Mounted from java
bd750002938c: Mounted from java
917c0fc99b35: Mounted from java
5.7: digest: sha256:64413fb300f4dd491397dbf16edbc8499c521640ac52e68bdfee8241a8d0dafe size: 2389
注意:一定要配置Docker Hub加速器呀,要不會有欲哭無淚的趕腳。
在生產環節中使用,您還需要新增Nginx等元件來增加TLS訪問,認證授權,負載均衡等能力。詳見官方參考),本文不再詳述。
分散式跨區域Docker Registry方案討論
回到正題,為了支援多區域部署Docker應用的需求,我們需要在每個region部署Docker Registry。然而如何在分散式的Docker Registry之間實現內容同步?我們有以下幾種可能的方案
-
當客戶端推送映象時,分別向不同region的Docker Registry推送。
- 好處:沒有任何外部依賴
- 不足:手工同步導致客戶端邏輯複雜;當擴充套件region之後需要手工同步已有映象
-
利用Docker Registry的通知機制,實現Web Hook;當一個Docker Registry收到映象推送完成事件之後,由Web Hook的實現向其他region的Docker Registry推送剛完成的映象
- 好處:沒有任何外部依賴,自動化同步
- 不足:基於事件的同步邏輯實現複雜,需要考慮網路中斷,region變更等多種邊界情況
-
利用儲存複製的機制,實現不同region的映象複製
- 好處:自動化同步,實現簡單
- 不足:需要底層儲存驅動支援
由於Docker Registry本身是無狀態的應用,非常適合採用資料複製的方案實現分散式部署。去年一系列公司提出了分散式Docker Registry的解決方案,大多基於其商業化的資料複製技術,比如NetApp在DockerCon的演講。
然而利用阿里雲OSS的新特性,Bucket跨區域複製和回源設定,我們也可以輕鬆實現一個大規模分散式的映象倉庫。在下面示例中:我們會把北京registry作為主registry,允許使用者推送、拉取映象;建立上海registry作為從registry,允許使用者拉取映象。其高層架構圖如下:
利用OSS跨區域複製輕鬆實現分散式映象倉庫
OSS的Bucket Cross-Region Replication是跨不同區域資料中心的自動化、非同步複製技術。它會將對源Bucket中的物件的改動(新建、覆蓋、刪除等)同步到目標Bucket。詳細資訊請參見幫助文件
首先,我們建立一個上海region的bucket,作為目標bucket
然後選擇北京region的bucket作為源bucket; 並配置跨區域複製規則到目標bucket
同步規則配置完成之後,等待幾分鐘同步完成的效果如下
在上海region的ECS例項上,我們利用上文的方法也建立一個Docker Registry,”docker-compose.yml”的配置如下,並配置上海region的OSS Bucket作為映象儲存
registry:
restart: always
image: registry:2.3
ports:
- 127.0.0.1:5000:5000
environment:
- REGISTRY_STORAGE=oss
- REGISTRY_STORAGE_OSS_ACCESSKEYID=******
- REGISTRY_STORAGE_OSS_ACCESSKEYSECRET=******
- REGISTRY_STORAGE_OSS_REGION=oss-cn-shanghai
- REGISTRY_STORAGE_OSS_BUCKET=aliyungo-shanghai
- REGISTRY_STORAGE_OSS_INTERNAL=true
- REGISTRY_STORAGE_OSS_SECURE=false
然後執行docker-compose up -d
命令啟動Docker Registry
我們可以通過下面的命令來驗證映象複製是否成功
# docker pull 127.0.0.1:5000/node:5.7
5.7: Pulling from node
fdd5d7827f33: Already exists
a3ed95caeb02: Pull complete
0f35d0fe50cc: Already exists
627b6479c8f7: Already exists
67c44324f4e3: Already exists
b52090f6ca00: Pull complete
1df855d9e713: Pull complete
Digest: sha256:64413fb300f4dd491397dbf16edbc8499c521640ac52e68bdfee8241a8d0dafe
Status: Downloaded newer image for 127.0.0.1:5000/node:5.7
大家可以看到,無需任何程式設計,我們已經簡單地實現了分散式資料的Docker Registry的自動化資料同步。使用者可以在北京registry上push新的映象,在上海registry上pull映象,沒有任何的手工維護工作。
需要注意的是:OSS的bucket複製是單向的,所以我們要在部署方案中確定registry的主從關係。只有在主registry的映象是可以讀寫的,而在從registry中,映象應是隻讀的。本文中主registy在北京region,而從registry在上海region。
目前為止,這個方案還不夠完美。由於Bucket複製是非同步的,採用的是最終一致性。物件從源複製到目的bucket需要一定的時間,這取決於複製物件的大小。我們知道Docker映象是採用分層儲存機制,每個layer包含相應的blob物件,後設資料和digest資訊。其中layer的blob物件可能非常大,資料複製完成時間會比較長。
所以,當我們在上海registry拉取映象時,如果blob物件沒有複製完成,則我們會遇到如下”unknown blob”錯誤
# docker pull 127.0.0.1:5000/redis:2
2: Pulling from redis
fdd5d7827f33: Already exists
a3ed95caeb02: Download complete
3868e1e933d6: Pulling fs layer
1d007c18c656: Pulling fs layer
ad75a8697e9c: Waiting
8de500daf5d7: Waiting
788fee3bdabf: Waiting
8f359895dbf8: Waiting
unknown blob
目前實現對於時效性不敏感的場景,這個方案已經足夠。當然,也需要應用層做一些調整,在映象未複製完成之前,需要反覆嘗試等待複製完成。
如果使用者希望能夠立刻從上海region的registry訪問剛在北京region推送的映象,有沒有更好的解決方案?
利用OSS回源設定實現映象按需熱遷移
對於上面的問題一個自然的想法就是:如果在上海registry請求尚未同步完成的Docker layer資料時,就從北京region的源bucket中讀取物件,並返回。
為了減少開發的複雜度,我們嘗試使用OSS的回源設定(詳見幫助文件)來自動化這個過程。當上海region的bucket中所需blob物件不存在時,讓OSS可以從北京region的bucket中自動進行回源讀取;在將layer內容返回給Docker請求的同時,自動將內容複製到上海region的目標bucket。
我們在上海region的bucket上配置回源規則如下
這裡我們使用映象方式:將回源地址指向北京bucket的公網訪問地址
當然我們還需要對registry中的OSS driver的Stat和URLFor實現做一些調整,當Registry檢查到檔案的後設資料不存在時,強制通過回源方式返回北京registry中的內容。對Docker Registry的修改可以從Github訪問
您也可以直接利用編譯過的”registry.aliyuncs.com/denverdino/registry:2.3″映象來替換官方映象。只需修改上海region部署所用的”docker-compose.yml”的image值修改即可。
registry:
restart: always
image: registry.aliyuncs.com/denverdino/registry:2.3
ports:
- 127.0.0.1:5000:5000
environment:
- REGISTRY_STORAGE=oss
- REGISTRY_STORAGE_OSS_ACCESSKEYID=******
- REGISTRY_STORAGE_OSS_ACCESSKEYSECRET=******
- REGISTRY_STORAGE_OSS_REGION=oss-cn-shanghai
- REGISTRY_STORAGE_OSS_BUCKET=aliyungo-shanghai
- REGISTRY_STORAGE_OSS_INTERNAL=true
- REGISTRY_STORAGE_OSS_SECURE=false
再次嘗試,我們已經近乎同時地從上海region的registry訪問剛剛在北京region推送的Docker映象了。在這裡,我們將非同步的物件複製,和同步的按需複製結合在一起,可以滿足絕大多數場景對分散式映象倉庫的要求。
大功告成!
總結
跨區域部署的Docker Registry可以在不同資料中心的使用者高效、簡單的利用Docker映象進行軟體交付、部署和運維;可以支援異地容災、分散式DevOps等場景。
在本文介紹的這個分散式、跨域部署的Docker Registry的方案中,無需額外的手工運維就可保證不同地域Docker映象倉庫的資料一致性。其技術要點如下:
- 使用OSS作為Docker映象儲存實現,不同region的registry配置到本地region的bucket上
- 利用OSS提供的跨區域bucket複製能力,在主從registry中實現自動資料複製
- 在從registry中,如果映象layer物件存在於本地的OSS bucket中,則直接利用bucket中物件返回;
如果映象layer物件還未同步成功,則回源到主registry的bucket中
感謝阿里雲OSS團隊一直以來的大力協助和支援。
歡迎大家使用阿里雲容器服務和阿里雲Docker映象倉庫服務。它能幫助你大大加速雲端Docker應用的交付流程。
相關文章
- kubernetes實戰篇之nexus oss伺服器部署及基於nexus的docker映象倉庫搭建伺服器Docker
- docker 映象倉庫 Harbor 部署 以及 跨資料複製Docker
- Docker搭建私有映象倉庫Docker
- 在宿主機上搭建docker映象倉庫Docker
- 基於 Docker 映象部署 go 專案DockerGo
- 用 Docker 部署前端?你有私有映象倉庫嗎Docker前端
- 搭建Harbor 映象倉庫
- 基於滴滴雲安裝 Docker 並上傳映象到滴滴雲 Docker 倉庫Docker
- Docker基礎-搭建本地私有倉庫Docker
- Docker 企業級映象倉庫 Harbor 的搭建與維護Docker
- CentOS部署Harbor映象倉庫CentOS
- 微服務探索之路03篇-docker私有倉庫Harbor搭建+Kubernetes(k8s)部署私有倉庫的映象微服務DockerK8S
- Docker映象倉庫清理的探索之路Docker
- 企業級docker-registry原生映象倉庫高可用部署Docker
- 建立 Docker 映象倉庫指令碼Docker指令碼
- docker 私有倉庫搭建Docker
- docker搭建私有倉庫Docker
- 基於Alpine和Ubuntu的Docker映象修改時區UbuntuDocker
- Docker搭建Harbor私有倉庫Docker
- Docker刪除倉庫中的映象問題Docker
- Docker入門-搭建docker私有倉庫Docker
- Harbor-私有映象倉庫的安裝部署
- Linux 上部署 docker,基於 docker 搭建 lnmp 環境LinuxDockerLNMP
- 如何將docker 映象上傳到docker hub倉庫Docker
- 使用OSS搭建私有云內網yum倉庫的方法內網
- Docker-------私有倉庫 Harbor 的搭建Docker
- 雲端計算 之 Docker--Docker 應用實戰案例--基於 registry 搭建私有倉庫Docker
- 建立映象釋出到映象倉庫【不依賴docker環境】Docker
- 搭建npm私有映象倉庫,天下苦於npm build久矣NPMUI
- 用Docker搭建cnpm私有倉庫以及私有倉庫的使用DockerNPM
- Docker Hub 倉庫使用,及搭建 Docker RegistryDocker
- quay.io/coreos/etcd 基於Docker映象的叢集搭建Docker
- docker筆記37-docker私有倉庫的搭建Docker筆記
- Docker進階與實踐之四:Docker映象倉庫Docker
- 區域網內部署 Docker RegistryDocker
- 基於Google雲端儲存的開放Maven映象中央倉庫GoMaven
- 8天入門docker系列 —— 第六天 搭建自己的私有映象倉庫RegistryDocker
- 容器技術之Docker私有映象倉庫harborDocker