作者簡介
王海龍,Rancher中國社群技術經理,負責Rancher中國技術社群的維護和運營。擁有6年的雲端計算領域經驗,經歷了OpenStack到Kubernetes的技術變革,無論底層作業系統Linux,還是虛擬化KVM或是Docker容器技術都有豐富的運維和實踐經驗。
前 言
Kubernetes 在 Changelog 中宣佈自 Kubernetes 1.20 之後將棄用 Docker 作為容器執行時之後,containerd成為下一個容器執行時的熱門選項。雖然 containerd 很早就已經是 Docker 的一部分,但是純粹使用 containerd 還是給大家帶來了諸多困擾,本文將介紹如何使用 containerd 配置映象倉庫和加速器。
本文將以K3s為例對containerd進行配置,如果您的環境未使用 K3s 而是使用的 Kubernetes,你也可以參考本文來配置 containerd 的映象倉庫,因為 containerd 的配置是通用的。
關於 K3s 和 containerd
K3s 是一個輕量級 Kubernetes 發行版,二進位制大小小於100MB,所需記憶體不到Kubernetes的一半。K3s 為了降低資源消耗,將預設的 runtime 修改為 containerd,同時也內建了 Kubernetes CLI 工具 crictl和ctr。
K3s 預設的 containerd 配置檔案目錄為/var/lib/rancher/k3s/agent/etc/containerd/config.toml
,但直接操作 containerd 的配置檔案去設定映象倉庫或加速器相比於操作 docker 要複雜許多。K3s 為了簡化配置 containerd 映象倉庫的複雜度,K3s 會在啟動時檢查/etc/rancher/k3s/
中是否存在 registries.yaml 檔案,如果存在該檔案,就會根據 registries.yaml 的內容轉換為 containerd 的配置並儲存到/var/lib/rancher/k3s/agent/etc/containerd/config.toml
,從而降低了配置 containerd 映象倉庫的複雜度。
使用 K3s 配置私有映象倉庫
K3s 映象倉庫配置檔案由兩大部分組成:mirrors
和configs
:
-
Mirrors 是一個用於定義專用映象倉庫的名稱和 endpoint 的指令
-
Configs 部分定義了每個 mirror 的 TLS 和證書配置。對於每個 mirror,你可以定義auth和/或tls
containerd 使用了類似 K8S 中 svc 與 endpoint 的概念,svc 可以理解為訪問名稱,這個名稱會解析到對應的 endpoint 上。也可以理解 mirror 配置就是一個反向代理,它把客戶端的請求代理到 endpoint 配置的後端映象倉庫。mirror 名稱可以隨意填寫,但是必須符合IP或域名的定義規則。並且可以配置多個 endpoint,預設解析到第一個 endpoint,如果第一個 endpoint 沒有返回資料,則自動切換到第二個 endpoint,以此類推。
比如以下配置示例:
mirrors:
"172.31.6.200:5000":
endpoint:
- "http://172.31.6.200:5000"
"rancher.ksd.top:5000":
endpoint:
- "http://172.31.6.200:5000"
"docker.io":
endpoint:
- "https://fogjl973.mirror.aliyuncs.com"
- "https://registry-1.docker.io"
可以通過 crictl pull 172.31.6.200:5000/library/alpine
和 crictl pull rancher.ksd.top:5000/library/alpine
獲取到映象,但映象都是從同一個倉庫獲取到的。
root@rancher-server:/etc/rancher/k3s# systemctl restart k3s.service
root@rancher-server:/etc/rancher/k3s# crictl pull 172.31.6.200:5000/library/alpine
Image is up to date for sha256:a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e
root@rancher-server:/etc/rancher/k3s# crictl pull rancher.ksd.top:5000/library/alpine
Image is up to date for sha256:a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e
root@rancher-server:/etc/rancher/k3s#
非安全(http)私有倉庫配置
配置非安全(http)私有倉庫,只需要在 endpoint 中指定 http 協議頭的地址即可。
在沒有 TLS 通訊的情況下,需要為 endpoints 指定http:// ,否則將預設為 https。
無認證
如果你使用的是非安全(http)私有倉庫,那麼可以通過下面的引數來配置 K3s 連線私有倉庫:
root@ip-172-31-13-117:~# cat >> /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"172.31.6.200:5000":
endpoint:
- "http://172.31.6.200:5000"
EOF
systemctl restart k3s
然後可以通過 crictl 去 pull 映象:
root@ip-172-31-13-117:~# crictl pull 172.31.6.200:5000/my-ubuntu
Image is up to date for sha256:9499db7817713c4d10240ca9f5386b605ecff7975179f5a46e7ffd59fff462ee
接下來,在看一下 containerd 的配置,可以看到檔案末尾追加了如下配置:
root@ip-172-31-13-117:~# cat /var/lib/rancher/k3s/agent/etc/containerd/config.toml
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."172.31.6.200:5000"]
endpoint = ["http://172.31.6.200:5000"]
[plugins.cri.registry.mirrors."rancher.ksd.top:5000"]
endpoint = ["http://172.31.6.200:5000"]
有認證
如果你的非安全(http)私有倉庫帶有認證,那麼可以通過下面的引數來配置 k3s 連線私有倉庫:
mirrors:
"35.182.134.80":
endpoint:
- "http://35.182.134.80"
configs:
"35.182.134.80":
auth:
username: admin # this is the registry username
password: Harbor12345 # this is the registry password
EOF
systemctl restart k3s
通過 crictl 去 pull 映象:
root@ip-172-31-13-117:~# crictl pull 35.182.134.80/ksd/ubuntu:16.04
Image is up to date for sha256:9499db7817713c4d10240ca9f5386b605ecff7975179f5a46e7ffd59fff462ee
Containerd 配置檔案末尾追加了如下配置:
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."35.182.134.80"]
endpoint = ["http://35.182.134.80"]
[plugins.cri.registry.configs."35.182.134.80".auth]
username = "admin"
password = "Harbor12345"
安全(https)私有倉庫配置
以下示例均啟用了認證,所以每個示例都配置了configs.auth,如果實際環境未配置認證,刪除configs.auth配置即可。
使用授信 ssl 證書
與非安全(http)私有倉庫配置類似,只需要配置 endpoint 對應的倉庫地址為 https 即可。
root@ip-172-31-13-117:~# cat >> /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"harbor.kingsd.top":
endpoint:
- "https://harbor.kingsd.top"
configs:
"harbor.kingsd.top":
auth:
username: admin # this is the registry username
password: Harbor12345 # this is the registry password
EOF
systemctl restart k3s
通過 crictl 去 pull 映象:
root@ip-172-31-13-117:~# crictl pull harbor.kingsd.top/ksd/ubuntu:16.04
Image is up to date for sha256:9499db7817713c4d10240ca9f5386b605ecff7975179f5a46e7ffd59fff462ee
Containerd 配置檔案末尾追加了如下配置:
root@ip-172-31-13-117:~# cat /var/lib/rancher/k3s/agent/etc/containerd/config.toml
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."harbor.kingsd.top"]
endpoint = ["https://harbor.kingsd.top"]
[plugins.cri.registry.configs."harbor.kingsd.top".auth]
username = "admin"
password = "Harbor12345"
使用自籤 ssl 證書
如果後端倉庫使用的是自簽名的 ssl 證書,那麼需要配置 CA 證書 用於 ssl 證書的校驗。
mirrors:
"harbor-ksd.kingsd.top":
endpoint:
- "https://harbor-ksd.kingsd.top"
configs:
"harbor-ksd.kingsd.top":
auth:
username: admin # this is the registry username
password: Harbor12345 # this is the registry password
tls:
ca_file: /opt/certs/ca.crt
EOF
systemctl restart k3s
通過 crictl 去 pull 映象:
root@ip-172-31-13-117:~# crictl pull harbor-ksd.kingsd.top/ksd/ubuntu:16.04
Image is up to date for sha256:9499db7817713c4d10240ca9f5386b605ecff7975179f5a46e7ffd59fff462ee
Containerd 配置檔案末尾追加了如下配置:
root@ip-172-31-13-117:~# cat /var/lib/rancher/k3s/agent/etc/containerd/config.toml
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."harbor-ksd.kingsd.top"]
endpoint = ["https://harbor-ksd.kingsd.top"]
[plugins.cri.registry.configs."harbor-ksd.kingsd.top".auth]
username = "admin"
password = "Harbor12345"
[plugins.cri.registry.configs."harbor-ksd.kingsd.top".tls]
ca_file = "/opt/certs/ca.crt"
ssl 雙向認證
如果映象倉庫配置了雙向認證,那麼需要為 containerd 配置 ssl 證書用於 映象倉庫對 containerd 做認證。
root@ip-172-31-13-117:~# cat >> /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"harbor-ksd.kingsd.top":
endpoint:
- "https://harbor-ksd.kingsd.top"
configs:
"harbor-ksd.kingsd.top":
auth:
username: admin # this is the registry username
password: Harbor12345 # this is the registry password
tls:
ca_file: /opt/certs/ca.crt # path to the ca file used in the registry
cert_file: /opt/certs/harbor-ksd.kingsd.top.cert # path to the cert file used in the registry
key_file: /opt/certs/harbor-ksd.kingsd.top.key # path to the key file used in the registry
EOF
systemctl restart k3s
通過 crictl 去 pull 映象:
root@ip-172-31-13-117:~# crictl pull harbor-ksd.kingsd.top/ksd/ubuntu:16.04
Image is up to date for sha256:9499db7817713c4d10240ca9f5386b605ecff7975179f5a46e7ffd59fff462ee
Containerd 配置檔案末尾追加了如下配置:
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."harbor-ksd.kingsd.top"]
endpoint = ["https://harbor-ksd.kingsd.top"]
[plugins.cri.registry.configs."harbor-ksd.kingsd.top".auth]
username = "admin"
password = "Harbor12345"
[plugins.cri.registry.configs."harbor-ksd.kingsd.top".tls]
ca_file = "/opt/certs/ca.crt"
cert_file = "/opt/certs/harbor-ksd.kingsd.top.cert"
key_file = "/opt/certs/harbor-ksd.kingsd.top.key"
加速器配置
Containerd 與 docker 都有預設倉庫,均為 docker.io 。如果配置中未指定 mirror 為 docker.io,containerd 後會自動載入 docker.io 配置。與 docker 不同的是,containerd 可以修改 docker.io 對應的 endpoint(預設為 https://registry-1.docker.io ) ,而 docker 無法修改。
Docker 中可以通過 registry-mirrors 設定映象加速地址。如果 pull 的映象不帶倉庫地址(專案名+映象名:tag),則會從預設映象倉庫去拉取映象。如果配置了映象加速地址,會先訪問映象加速倉庫,如果沒有返回資料,再訪問預設的映象倉庫。
Containerd 目前沒有直接配置映象加速的功能,但 containerd 中可以修改 docker.io 對應的 endpoint,所以可以通過修改 endpoint 來實現映象加速下載。因為 endpoint 是輪詢訪問,所以可以給 docker.io 配置多個倉庫地址來實現 加速地址+預設倉庫地址。如下配置示例:
mirrors:
"docker.io":
endpoint:
- "https://fogjl973.mirror.aliyuncs.com"
- "https://registry-1.docker.io"
EOF
systemctl restart k3s
Containerd 配置檔案末尾追加了如下配置:
root@ip-172-31-13-117:~# cat /var/lib/rancher/k3s/agent/etc/containerd/config.toml
[plugins.cri.registry.mirrors]
[plugins.cri.registry.mirrors."docker.io"]
endpoint = ["https://fogjl973.mirror.aliyuncs.com", "https://registry-1.docker.io"]
完整配置示例
"192.168.50.119":
endpoint:
- "http://192.168.50.119"
"docker.io":
endpoint:
- "https://fogjl973.mirror.aliyuncs.com"
- "https://registry-1.docker.io"
configs:
"192.168.50.119":
auth:
username: '' # this is the registry username
password: '' # this is the registry password
tls:
cert_file: '' # path to the cert file used in the registry
key_file: '' # path to the key file used in the registry
ca_file: '' # path to the ca file used in the registry
"docker.io":
auth:
username: '' # this is the registry username
password: '' # this is the registry password
tls:
cert_file: '' # path to the cert file used in the registry
key_file: '' # path to the key file used in the registry
ca_file: '' # path to the ca file used in the registry
參考連結
K3s私有映象倉庫配置:
https://docs.rancher.cn/docs/k3s/installation/private-registry/_index
Containerd配置映象倉庫:
https://github.com/containerd/cri/blob/master/docs/registry.md