ACR使用Artifact Cache取得外部信任Registry映像檔快取備份

ACR使用Artifact Cache取得外部信任Registry映像檔快取備份

Azure Container Registry 最近 GA 了一個 Artifact Cache 功能,我測試之後,Artifact Cache 完全可以解決我們長期(困擾3-5年以上)以來在混合雲環境存取外部Registry映像檔存取問題。公司有非常安全網路規劃,因此地端內網非常不易接觸外網資源,例舉來說:

a: 地端伺服器 <--> Firewall <--> MPLS <--> ACR (v)
b: 地端伺服器 <--> Firewall <--> MPLS <--> hub.docker.com (x)
c: 地端伺服器 <--> Firewall <--> MPLS <--> mcr.microsoft.com (x)

之前整合 ExpressRoute 以 YARP 架設內網 MCR 代理伺服器有大概提過我們的網路架構。以上面來說,(a:) 這條路表示地端伺服器想存取 ARC,因為是 Azure 本身的服務,因此是受公司網路團隊信任的,因此存取很順暢不會有問題。但當我想存取 docker hub 等 Azure 外部 Registry 時,就非常麻煩。連微軟 Microsoft Artifact Registry 服務都一樣的難。

那 Artifact Cache 等於把 ACR 加上一組 Registry Proxy 的概念:

d: 地端伺服器 <--> Firewall <--> MPLS <--> ACR <--> Cache <-- public and private repositories

我們在 ARC 上定義好一個 Cache 規則,例如:

hello-word-Rule: myregistry.azurecr.io/hello-world <-- docker.io/library/hello-world

當我們指定提取 hello-world 時,例如:

docker pull myregistry.azurecr.io/hello-world:latest

在我們的 ACR 上並不有存在 hello-world,但 ACR 會發現有條 hello-word-Rule 的規則符合 pull 請求,因此 Artifact Cache 機制被觸發,ACR 的 Artifact Cache 會幫我們去把外部 Registry 上的 Images 給 pull 回來 ACR 裡面並且 tag 成我們要求的名稱,再透過 ARC 回傳給我們。

把請求整個展開:

地端伺服器 <--> Firewall <--> MPLS <--> ACR(myregistry.azurecr.io/hello-world) <--> Cache <-- docker.io/library/hello-world

注意,Artifact Cache 只能從 source 做 pull。因此方向只有 <--

也就是說,地端伺服器存取對像只有 ACR,並且它並不知道有存取外部 Registry 這件事。當然,第一次反應速度會慢一些,除非 source hello-world 有更新,不然當完成 ACR 快取,那就和存取 ACR 本身上面的映像檔沒有兩樣了。

az acr Cache CLI 沒說的事

某些 Registry 撰文當下還無法使用 Azure Web UI 去建立 Cache 規則,必須使用 Azure CLI 才能。

例如,我想快取 registry.k8s.io 的映像檔,目前只能下 Azure CLI:

az acr Cache create -r MyRegistry -n k8s-pause-Cache -s registry.k8s.io/pause -t pause
  • 參數說明可透過 --help 自行參考,例如 az acr Cache create --help
  • 目前 Azure CLI 也導入了 AI 助理,可以嘗試使用 az find 來查詢不一樣方向的資訊,例如 az find "az acr cache create"

這裡我花了點時間測試,主要是我找不到 Images 的 tag 要下在那裡,怎麼下怎麼錯。最後反覆看官網的 hello-world 及本機實作,最後才看懂。ACR Artifact Cache 規則是不帶 tag 的,tag 是最後你在下 docker pull 指定即可。另外從建立指令也可以看出來,ACR Artifact Cache 一條規則是對應到外部 Registry 的某個 Images,至於要抓這個 Images 的那一個版本,由 pull 指令執行當下決定即可。

registry.k8s.io 番外篇1

因為我想把整個地端 Kubernetes 的 Image Repository 改為 ACR,然後透過 ACR Artifact Cache 來存取 registry.k8s.io。可以參考文件Reverting the registry name in kubeadm進行調整。

地端伺服器 <--> Firewall <--> MPLS <--> ACR 
地端伺服器 <--> Firewall <--> MPLS <--> ACR <--> Cache <-- docker.io
地端伺服器 <--> Firewall <--> MPLS <--> ACR <--> Cache <-- mcr.microsoft.com
地端伺服器 <--> Firewall <--> MPLS <--> ACR <--> Cache <-- registry.k8s.io

也就是說,現在地端容器環境,不論是 Kubernetes、Linux Container、Windows Container 環境,只要你能與 ACR 連線,那麼透過 ACR + Artifact Cache 你就能與全世界的 Registry 建立連線並讀取你所需要映像檔。

這段我還在PoC,希望能有下篇能分享。

registry.k8s.io 番外篇2

在建立 registry.k8s.io 快取規則時發現,registry.k8s.io 不像 docker.io 或 mcr.microsoft.com 有介面可以查詢 Images 的資訊。在討論串發現一個好物 https://explore.ggcr.dev

它能提供一個 registry.k8s.io 的 JSON 資訊清單,這對我們整理 Cache 規則已經非常足夠。

找尋 Kubernetes 預設系統 images 清單

當然,如果你有一台已經安裝 Kubernetes 的主機,就連進去看一下預設 kube-system 的 Pods。

$ kubectl get pods -n kube-system

但這還看不到 Images 明細。官網有篇教學說明,教你如何取得 Pods 的 Images 資訊。例如:

$ kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' | sort

但那些指令參數 … 老實說,記不了。還有一招更快方法,開啟 Docker Desktop - Kubernetes 然後查詢一下 images:

C:\> docker images
REPOSITORY                               TAG       IMAGE ID       CREATED         SIZE
registry.k8s.io/kube-apiserver           v1.27.2   c5b13e4f7806   5 months ago    121MB
registry.k8s.io/kube-scheduler           v1.27.2   89e70da428d2   5 months ago    58.4MB
registry.k8s.io/kube-controller-manager  v1.27.2   ac2b7465ebba   5 months ago    112MB
registry.k8s.io/kube-proxy               v1.27.2   b8aa50768fd6   5 months ago    71.1MB
registry.k8s.io/coredns/coredns          v1.10.1   ead0a4a53df8   8 months ago    53.6MB
registry.k8s.io/etcd                     3.5.7-0   86b6af7dd652   8 months ago    296MB
registry.k8s.io/pause                    3.9       e6f181688397   12 months ago   744kB

簡單清楚吧。有了這份資訊,我們可以開始設定 Artifact Cache 規則,這樣未來不論是新安裝 Kubernetes 或 Image Repository 更換為 ACR 之後都能正常存取。

另外,在查詢 Kubernetes 文件時,在 Container Images 也有一些資訊。但資訊沒有 https://explore.ggcr.dev 那麼充足就是了。

registry.k8s.io/kube-apiserver:v1.28.3          
registry.k8s.io/kube-controller-manager:v1.28.3 
registry.k8s.io/kube-proxy:v1.28.3              
registry.k8s.io/kube-scheduler:v1.28.3          
registry.k8s.io/conformance:v1.28.3

還有一篇 kubernetes Blog 的 Bootstrap an Air Gapped Cluster With Kubeadm 有段指令碼我覺得可以參考備用:

大致如下:

KUBE_RELEASE="v1.27.3"
# ...

images=(
    "registry.k8s.io/kube-apiserver:${KUBE_RELEASE}"
    "registry.k8s.io/kube-controller-manager:${KUBE_RELEASE}"
    "registry.k8s.io/kube-scheduler:${KUBE_RELEASE}"
    "registry.k8s.io/kube-proxy:${KUBE_RELEASE}"
    "registry.k8s.io/pause:3.9"
    "registry.k8s.io/etcd:3.5.7-0"
    "registry.k8s.io/coredns/coredns:v1.10.1"
)
# ...

這也學習到,kubernetes 核心的 4 個容器是會跟著 kubernetes 版號來進行更新的。其他幾個就需要再查查是否有新版本。

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。