利用 harbor + nginx 搭建带缓存的 docker mirror
Harbor 可以直接配置作为 Docker Mirror,但是这样的话整个 Harbor 就只能作为 mirror 使用了不能再作为自定义的镜像仓库,同时也失去了很多的配置能力
本文利用 Harbor 的 Proxy Cache 功能搭配 nginx 转发来实现让 harbor 可以充当内部镜像服务器的同时也可以作为 docker mirror 使用。
配置 Harbor 镜像
定义 Harbor Registry
进入 Administration → Registries,创建 Endpoint
如果你的 Harbor 可以直连 Docker Hub,在 Provider 选择 Docker Hub 即可,如果你的用量较大也可以设置 Access ID 和 Access Secret(Access ID 就是你的用户名,Access Secret 就是你设置的 Access Token;不设置每 6h 可以 pull 100 次,设置了可以 200 次,具体参见 https://docs.docker.com/docker-hub/download-rate-limit/ )
如果你的 Harbor 无法直连 Docker Hub,则需要使用一个中转(例如利用 https://github.com/ImSingee/hammal 自建,或者在网上找其他可以使用的镜像服务)
中转搭建或选择好后,创建 Endpoint 时 Provider 选择 Docker Registry,然后在 Endpoint URL 处输入你的中转站点的网址
创建一个 harbor project
进入 Harbor 的 Projects 页面,创建一个新的 harbor project(假设命名为 docker-mirror),勾选 proxy cache 并选择上面创建好的 Registry Endpoint
创建好后,可以进入 Configuration 进一步配置保留策略,来防止长期不用的镜像占用空间
利用 nginx 模拟 docker mirror
按照上述创建好 harbor 以后,已经可以利用类似 docker pull harbor.example.com/docker-mirror/library/alpine
这样的方式来读取到缓存的 dockerhub 包了
但是在所有的 Dockerfile 中都使用上述地址比较繁琐,因此我们利用 nginx 来模拟一个 docker mirror 的实现,使得我们可以不去修改 image 名字而直接配置 docker mirror 就可以了。
创建 Robot Account
即使前面创建 Project 时设置 access level 为 public 这一步也是必要的
进入 Administration → Robot Accounts 创建一个新的机器人账号,为它授予我们 docker mirror harbor project 的 List Repositories 和 Pull Repositories 权限,记住展示的账号(`robot$` 开头)与 token
进入 Base64 Encode and Decode - Online 将账号和token 按照 robot$username:token
的形式输入,Encode 得到 Base64 备用(即准备利用 Basic Auth 进行认证)
配置 nginx
增加如下的 nginx server 配置
server {
listen 443 ssl;
server_name my-docker-mirror.example.com;
ssl_certificate /certs/cert.pem;
ssl_certificate_key /certs/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
location = /v2/ {
proxy_pass http://HARBOR/v2/;
proxy_set_header Host HARBOR;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Authorization 'Basic TOKEN';
}
location ~ ^/v2/(.*)$ {
proxy_pass http://HARBOR/v2/docker/$1;
proxy_set_header Host HARBOR;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Authorization 'Basic TOKEN';
}
}
server_name 是你的自定义域名,后续将 docker mirror 的域名配置为这个即可
docker mirror 必须为 HTTPS(尽管文档说可以支持 HTTP,但我测试并不行),因此必须准备好证书
proxy_pass 与 proxy_set_header Host 中的
HARBOR
是你原来 harbor 的域名proxy_set_header Authorization 中的
TOKEN
替换为上面步骤中生成的 base64
配置 Docker
https://docs.docker.com/docker-hub/mirror/#configure-the-docker-daemon
记得一定将 docker mirror 配置成类似 https://my-docker-mirror.example.com
的形式,scheme 必须为 https 且不可省略
虽然文档中说了可以用 http,也说了可以省略 scheme 会自动用 https,但是实际可能版本问题,至少在我的版本下,不写 scheme 直接无法启动、写 http 也会强制使用 https