使用 Harbor 作为 K3S 的镜像代理缓存后端
环境参考:使用 k3s 搭建高可用 k8s 集群 (on Alpine 3.13)
部署 Harbor
使用 helm 安装
helm repo add harbor https://helm.goharbor.io
helm upgrade --install harbor harbor/harbor \
-n harbor --create-namespace \
--set expose.tls.enabled=false \
--set expose.ingress.hosts.core=core.harbor.k8s.local \
--set expose.ingress.hosts.notary=notary.harbor.k8s.local \
--set externalURL=http://core.harbor.k8s.local
(可选)配置 Harbor 访问外网的 HTTP(S) 代理
不使用外网代理无法获取 gcr.io / k8s.gcr.io 的镜像
# 设置 HTTP_PROXY、HTTPS_PROXY 条目
kubectl edit -n harbor configmaps/harbor-core
# 重启 harbor-core 让设置生效
kubectl rollout restart -n harbor deployments/harbor-core
kubectl rollout status -n harbor deployments/harbor-core
创建 Harbor 代理缓存项目
使用用户名 admin
密码 Harbor12345
登入 Harbor 管理后台 http://core.harbor.k8s.local
-
右侧边栏
Administration
=>Registries
=>New Endpoint
创建 5 个 Endpoint:Provider Name Endpoint URL Access ID Docker Hub docker.io Quay quay.io https://quay.io 清空 Quay(无误) gcr.io https://gcr.io 清空 Quay(无误) k8s.gcr.io https://k8s.gcr.io 清空 Quay(无误) ghcr.io https://ghcr.io 清空 -
右侧边栏
Projects
=>New Project
创建 5 个项目:Project Name Access Level Proxy Cache docker.io Public ☑️ ☑️ Endpoint: docker.io quay.io Public ☑️ ☑️ Endpoint: quay.io gcr.io Public ☑️ ☑️ Endpoint: gcr.io k8s.gcr.io Public ☑️ ☑️ Endpoint: k8s.gcr.io ghcr.io Public ☑️ ☑️ Endpoint: ghcr.io
配置 K3S 仓库镜像
添加 ingress 的本地 hosts 解析条目 core.harbor.k8s.local
cat >>/etc/hosts <<EOF
127.0.0.1 core.harbor.k8s.local
EOF
创建 /etc/rancher/k3s/registries.yaml
cat >/etc/rancher/k3s/registries.yaml <<EOF
mirrors:
docker.io:
endpoint:
- http://core.harbor.k8s.local
rewrite:
"(^.+\$)": "docker.io/\$1"
quay.io:
endpoint:
- http://core.harbor.k8s.local
rewrite:
"(^.+\$)": "quay.io/\$1"
gcr.io:
endpoint:
- http://core.harbor.k8s.local
rewrite:
"(^.+\$)": "gcr.io/\$1"
k8s.gcr.io:
endpoint:
- http://core.harbor.k8s.local
rewrite:
"(^.+\$)": "k8s.gcr.io/\$1"
ghcr.io:
endpoint:
- http://core.harbor.k8s.local
rewrite:
"(^.+\$)": "ghcr.io/\$1"
EOF
# 注意:\$ 是为了 bash 转义 $ ,如果是手工编辑保存要把转义符 \ 去掉
# 需要重启 k3s server 让设置生效
rc-service k3s restart
# 确认配置已经生效
crictl info
实现的关键在于 rewrite
规则,在镜像名前面加上 harbor 项目名作为前缀,拉取镜像的请求才能被正确的路由。这一点至关重要。
值得一提的是 rewrite
特性并不是 containerd 官方版本的特性,由 rancher 魔改版本实现。rancher 给 containerd 提交了 Pull Request,撰写本文的时候还在讨论中,没有明确接受还是拒绝。