對(duì)于一家業(yè)務(wù)遍布全球的企業(yè)來說,往往會(huì)遇到數(shù)據(jù)同步的困境,明明是一份代碼,國內(nèi)更新之后,還要同步一份到國外,反之亦然。尤其在當(dāng)前微服務(wù)技術(shù)發(fā)展下,應(yīng)用程序代碼的迭代速度越來越快,如何能保持一份代碼,減少人為同步的干擾,并且確保同步機(jī)制的高可用性、易維護(hù)性?本篇我們將為大家介紹,使用Azure Container registries的Web Hook功能,通過調(diào)用Azure Functions服務(wù),將國內(nèi)外container image自動(dòng)同步,方便出?;蛉肴A的客戶快速部署和更新container image。
準(zhǔn)備工作
我們先了解下本次涉及的Azure服務(wù):
·Azure Functions:Azure Functions是Azure平臺(tái)的serverless函數(shù)計(jì)算服務(wù),您只用將代碼上傳到Azure Functions就可以運(yùn)行,而無需創(chuàng)建和維護(hù)服務(wù)器。Azure Functions是為事件觸發(fā)所設(shè)計(jì),可以響應(yīng)數(shù)據(jù)變動(dòng)觸發(fā)、計(jì)劃事件觸發(fā)或HTTP請(qǐng)求觸發(fā)等。支持豐富的編程語言如C#,Java,JavaScript,Python,PowerShell等。Azure Functions的運(yùn)行時(shí)也已在GitHub上開源。
·Azure Container Registry:Azure Container Registry(ACR)是一個(gè)基于開源Docker Registry 2.0所構(gòu)建的一個(gè)托管的私有registry服務(wù),ACR不僅僅能夠存儲(chǔ)您的docker image,還能build image。這意味著您只用將Docker file傳給ACR,通過簡單的API操作,就能夠在Azure上直接Build鏡像(Windows docker image和Linux docker image均支持)
操作步驟
創(chuàng)建Function App
1.在Global Azure Portal界面,搜索Function App,然后點(diǎn)擊”Add”按鈕,添加一個(gè)Function。語言選擇”Python”,版本為3.8,在下一步Hosting界面,Plan選擇為”Consumption(Serverless)”,之后完成創(chuàng)建。
2.在創(chuàng)建的Function App的Setting設(shè)置項(xiàng)中,點(diǎn)擊Identity,然后將System assigned的Status設(shè)置為On,點(diǎn)擊保存,之后在role assignments中,添加AcrPush,AcrPull,AcrDelete,AcrImageSinger,AcrQuarantineWriter,AcrQuarantineReader權(quán)限。這一步的目的是:讓Function App有權(quán)限訪問Azure Container Registries,這樣從國內(nèi)ACR里讀取鏡像之后,有權(quán)限寫入到Global ACR中。
在VS Code中配置Azure Functions
1.在自己電腦上安裝VS Code,在Extensions中搜索”Azure Functions”,然后安裝Azure Functions插件。同時(shí)需要在自己電腦上安裝Python3.8和Nodejs的環(huán)境。安裝完成之后,在VS Code中,點(diǎn)擊Azure的圖標(biāo),Sign in to Azure,之后會(huì)自動(dòng)打開瀏覽器,在瀏覽器登錄頁面,輸入Azure的用戶名和密碼完成登錄。登錄完成,在VS Code左側(cè)將會(huì)看到Azure訂閱名,以及在第一步創(chuàng)建的Function
2.參考下圖創(chuàng)建Azure Functions本地package.創(chuàng)建本地package的目的是:我們可以在本地進(jìn)行代碼的編輯,以及調(diào)試,等調(diào)試通過之后,可以push到Azure Functionss進(jìn)行使用。在創(chuàng)建的時(shí)候,選擇“HTTP trigger”,trigger名字可以根據(jù)自己的需要寫,比如”acr_web_trigger”,Authorization Level選擇”Admin”。創(chuàng)建完成之后,我們會(huì)看到VS Code自動(dòng)打開__init__.py文件,在該文件中,提供了一些示例代碼.
3.使用下面的代碼替換自動(dòng)生成的代碼。
注:標(biāo)紅的代碼需要修改成您自己的值,
SUBSCRIPTION_ID為Global Azure的訂閱ID
TARGET_RESOURCE_GROUP為Global Azure的資源組
TARGET_IMG_REPO為Global Azure的ACR名字
passwd為國內(nèi)Azure ACR的密碼(在ACR中,點(diǎn)擊Access Keys,啟用Admin user,能看到兩個(gè)password,使用任意一個(gè)即可)
import logging,json
import azure.functions as func
from msrestazure.azure_active_directory import MSIAuthentication
credentials=MSIAuthentication()
SUBSCRIPTION_ID='5fb605ab-c16c-4184-8a02-fee38cc11b8c'
import azure.mgmt.containerregistry as acr
acrclient=acr.ContainerRegistryManagementClient(credentials=credentials,subscription_id=SUBSCRIPTION_ID)
def main(req:func.HttpRequest)->func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
acr_event=json.loads(req.get_body())
SRC_REGISTRY_NAME=acr_event['request']['host'].split('.')[0]
SOURCE_IMG=acr_event["target"]['repository']+':'+acr_event["target"]['tag']
SRC_REGISTRY_URI=acr_event['request']['host']
TARGET_IMG_TAG=[SOURCE_IMG]
TARGET_RESOURCE_GROUP='xiangliu_csa'
TAEGET_IMG_REPO='xiangliurepo2'
src_image_url=acr_event['request']['host']+'/'+acr_event["target"]['repository']+':'+acr_event["target"]['tag']
passwd=‘xxxxxxxxx‘
imp_src_cred=acrclient.models().ImportSourceCredentials(password=passwd,username=SRC_REGISTRY_NAME)
import_img_src=acrclient.models().ImportSource(source_image=SOURCE_IMG,registry_uri=SRC_REGISTRY_URI,credentials=imp_src_cred)
img_mode=acrclient.models().ImportMode.force
import_img_para=acrclient.models().ImportImageParameters(source=import_img_src,target_tags=TARGET_IMG_TAG,mode=img_mode)
imp_img=acrclient.registries.import_image(resource_group_name=TARGET_RESOURCE_GROUP,registry_name=TAEGET_IMG_REPO,parameters=import_img_para)
return func.HttpResponse(src_image_url+"copied successfully")
4.找到代碼中requirements.txt文件,在文件中添加下面的幾個(gè)依賴程序包
azure-functions
azure-mgmt-containerregistry==2.8.0
msrestazure
5.完成上述操作之后,點(diǎn)擊”Deploy to Function App”按鈕,然后選擇先前創(chuàng)建的Function名字”acrcopydemo”進(jìn)行部署。如果安裝了Azure Functionss Core Tools,您也可以通過下面的命令發(fā)布Azure Functionss代碼:func Azure Functionsapp publish acrcopydemo
發(fā)布完成之后,在Azure Functions中可以看到之前傳過來的代碼
在國內(nèi)Azure Container registries添加Webhooks
1.先在Global Azure的Function App處,找到先前創(chuàng)建的acrcopydemo,然后在Functions處,點(diǎn)擊”Get Function Url”,選擇”masterKey(host key)”將其復(fù)制
2.回到國內(nèi)Azure,在國內(nèi)Azure的Azure Container registries處,找到要同步的registries,然后點(diǎn)擊Webhooks—Add,添加一個(gè)Webhook。在Webhook中,Service URI為3.1復(fù)制的地址,Actions中勾選所有,點(diǎn)擊創(chuàng)建
3.使用docker客戶端登陸國內(nèi)ACR,上傳一個(gè)docker image,然后觀察Webhooks的執(zhí)行結(jié)果,如果執(zhí)行成功,將返回http 200的status code。同時(shí)切換到Global Azure的ACR界面,我們將看到docker image已經(jīng)成功同步過來。
總結(jié)
本文提供了利用Azure Functions來實(shí)現(xiàn)國內(nèi)外容器鏡像的同步的思路與步驟,除了本文所提及的這個(gè)應(yīng)用場景之外,稍加改動(dòng),也很容易就能實(shí)現(xiàn)將GitHub Repo或其他托管的docker image repo和ACR的同步。有關(guān)Azure Functions的介紹,您也可以點(diǎn)擊文末閱讀原文,了解更多詳情。