containerd CLI - ctr、nerdctl、crictl 與 Azure Container Registry 存取設定

containerd CLI - ctr、nerdctl、crictl 與 Azure Container Registry 存取設定

在安裝完containerD之後,有時需要直接與containerd溝通,這時就需要透過CLI,文件共介紹 ctr、nerdctl、crictl 三套 CLI,CLI 與 containerd 的關係,就像 dockerd 與 docker CLI 差不多意思。除了溝通之外,由於我們 Registry 是採用Azure Container Registry,因此另一個重點是要知道如何設定以存取預設 docker.io 以外的 Registry。

ctr CLI

ctr CLI 會跟著 containerd 一起安裝。

相關指令與參數可以透過 ctr --help 來取得。

我有找到一份整理 ctr CLI 不錯的說明文件:https://www.mankier.com/8/ctr

# 注意:不能省略 "docker.io/library/" 前綴
ctr images pull docker.io/library/redis:latest
ctr run docker.io/library/redis:latest redis

ctr 使用私有 Registry

如果要透過 ctr 去存取私有 Registry,需要去修改 containerd 的 /etc/containerd/config.toml 組態檔。

參考:Configure Registry Endpoint

ctr 就我的測試,就算 config.toml 都組態完成,目前還是無法存取私有 Registry。我有找到幾則 Github Issues 的討論。

感覺某些問題,因為 K8s 不是透過 ctr 來跟 containerd 溝通,因此 ctr 在私有 Registry 這部分沒有很認真在修正問題。

不過,如果單純用指令測試到是沒有問題:

sudo ctr -debug image pull -u UserName:Password ImageDetail

透過 -u 去指定私有 Registry 的帳密,就能進行私有 Registry的存取。

nerdctl CLI

nerdctl 強調高度相容原本 docker CLI。例如:

# 原始 docker CLI
docker pull redis:latest
docker run --name redis redis:latest

# 能省略 docker.io/library/ 前綴
nerdctl pull redis:latest
nerdctl run --name redis redis:latest

nerdctl 本身指令參考文件寫的蠻不錯的:Command reference。基本上拿來當 docker CLI 來用。

nerdctl 安裝需要一些步驟,下載之後解壓縮至 /usr/local/bin~/bin,即解即用。

wget nerdctl-1.3.1-linux-amd64.tar.gz
sudo tar Cxzvvf /usr/local/bin nerdctl-1.3.1-linux-amd64.tar.gz

我在 Ubuntu 上是解壓縮到 /usr/local/bin 來使用。

nerdctl 使用私有 Registry

私有 Registry 這方面 nerdctl registry文件寫的真好。

像我們是整合Azure Container Registry (ACR),我照著文件做都很正常,我就不贅述。

nerdctl login -u <USERNAME> <REGISTRY>.azurecr.io
  • nerdctl login 問跳出問密碼的提示,會把密碼明文儲存在 /root/.docker/config.json,這部分要注意一下。(nerdctl login 執行之後也會提醒你。)
  • 這個在下一篇 K8s 存取私有 Registry 會用到。

crictl CLI 安裝

預設會隨著 K8s 的環境安裝。如果還沒有 K8s 需手動下載並且解壓縮。

VERSION="v1.27.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz

它的 github 上的文件在過於簡單,我有另外翻譯一份 crictl CLI 繁體中文版

crictl 使用私有 Registry

這部分 crictl 使用 --creds 來傳遞明文參數的方式來指定帳密,以存取私有 Registry。

crictl pull --creds "UserName:Password" "ImageDetail"

我在 K8s 文件是沒有看到 crictl 過多的說明,但就它是隨著 K8s 而安裝,並且從 containerd 官方 cri 說明圖(下圖)來看,應該 kubelet 所呼叫的 cri 應該就是 crictl CLI。

containerd with cri

crictl 無正常 pull images

我在用 crictl pull 拉取 ACR Images 時我碰到以下的錯誤訊息:

$ crictl pull --creds "UserName:Password" "ImageDetail"  
WARN[0000] image connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
E0512 15:02:42.448271   75094 remote_image.go:171] "PullImage from image service failed" err="rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory\"" image="ImageDetail"
FATA[0000] pulling image: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory"

這問題我找了好久。從內部網路查起,再查 Proxy 設定、再查 ACR 是否有問題,再從重頭安裝一遍 containerd ... 結果都不是,最後在一個 cri-tools Issues 1089 找到解法,我目前有碰到幾台使用 containerd 1.6.20 與 crictl 1.26.0 的主機,都能正常解決。

建立 /etc/crictl.yaml

$ sudo vim /etc/crictl.yaml
runtime-endpoint: "unix:///run/containerd/containerd.sock"
timeout: 0
debug: false

儲存後立即生效。很明顯,它是把 WARN[0000] 解決。就 Issues 上的討論來看,目前 crictl 1.26.0 不會解決,因為它只把修正程式並放在 1.27.0 的版本上。

ctr、nerdctl、crictl 小結

如果你是要直接處理與 containerd 的互動,相當推薦 nerdctl,光相容 docker CLI 就先給 90 分了。如果像我們在一個隔離的環境,通常我們只有 ctrcrictl 能用,因此,也需要瞭解一下 ctrcrictl,這兩個指令在相互測試時也是很重要,以我們存取私有 Registry 來說,一開始 ctr 測試就很順利,但拿 crictl 測試就一直撞牆,而 crictl 指令測不過,代表最終部屬 Yaml 是正常的也沒用。還好,三組 CLI 指令、參數之間相互都有幾分的相似,因為相似容易錯亂,還好透過 --help 都能很方便直接查詢。

沒有留言:

張貼留言

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