1 背景
由于网速等众所周知的原因,从国内访问gcr等镜像仓库易出现失败的情况。
本文,我们通过官方registry + 设置上游代理的方式,搭建4种容器仓库的镜像服务器。
2 准备工作
- 外网主机1台
- 假设你的一级域名为xxx.com
- 二级域名解析4枚:quay.xxx.com、ghcr.xxx.com、gcr.xxx.com、k8s-gcr.xxx.com
- 楼上4个耳机域名,解析A记录到外网主机的公网IP上
3 搭建镜像代理
首先安装docker,不再赘述。
然后创建一个网络,因为后面要共享:
docker network create --subnet=172.19.0.0/16 reg-net
使用官方registry只支持1次设置1个代理,所以要分开启动。
写多个脚本很麻烦,也懒得安装compose,这里用个循环写在一起了:
#!/bin/bash PUID="1000" PGID="1000" VOLUME="$HOME/docker_data/registry" mkdir -p $VOLUME declare -A map map["gcr"]="https://gcr.io" map["ghcr"]="https://ghcr.io" map["k8s-gcr"]="https://k8s.gcr.io" map["quay"]="https://quay.io" for host in ${!map[@]} do name=$host domain=${map[$host]} docker ps -q -a --filter "name=$name" | xargs -I {} docker rm -f {} docker run \ --hostname $name \ --name $name \ --volume "$VOLUME:/var/lib/registry" \ -e DELETE_ENABLED=true \ -e PROXY_REMOTE_URL=$domain \ --env PUID=$PUID \ --env PGID=$PGID \ --network reg-net \ --detach \ --restart always \ yangchuansheng/registry-proxy done
启动nginx,这里用了swag,由于我用的都是子域名,要注意下配置ONLY_SUBDOMAINS:
#!/bin/bash NAME="nginx" PUID="1000" PGID="1000" DOMAIN="xxx.com" VOLUME_LOG="$HOME/docker_data/nginx/log" VOLUME_LETSENCRYPT="$HOME/docker_data/nginx/letsencrypt" mkdir -p $VOLUME_LETSENCRYPT mkdir -p $VOLUME_LOG SCRIPT_DIR="$( cd "$(dirname "$0")" ; pwd -P )" SITE_CONFS="$SCRIPT_DIR/site-confs" docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {} docker run \ --name $NAME \ --volume "$VOLUME_LETSENCRYPT":/config/etc/letsencrypt \ --volume "$VOLUME_LOG":/config/log/nginx \ --volume "$SITE_CONFS":/config/nginx/site-confs \ -p 80:80 \ -p 443:443 \ --network reg-net \ --ip 172.19.0.2 \ --env URL=$DOMAIN \ --env VALIDATION="http" \ --env SUBDOMAINS="gcr,ghcr,k8s-gcr,quay" \ --env ONLY_SUBDOMAINS=true \ --env TZ="Asia/Shanghai" \ --env DHLEVEL="1024" \ --env PUID=$PUID \ --env PGID=$PGID \ --detach \ --restart always \ linuxserver/swag
最后是nginx配置,我们可以用正则匹配到不同proxy,只写一次:
## Version 2021/04/27 - Changelog: https://github.com/linuxserver/docker-swag/commits/master/root/defaults/default error_page 502 /502.html; # redirect all traffic to https server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 301 https://$host$request_uri; } # main server block server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; root /config/www; index index.html index.htm index.php; server_name ~^(?<name>.+)\.xxx\.com$; # enable subfolder method reverse proxy confs include /config/nginx/proxy-confs/*.subfolder.conf; # all ssl related config moved to ssl.conf include /config/nginx/ssl.conf; proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; send_timeout 600; location / { proxy_pass http://$name:5000; proxy_buffering off; proxy_request_buffering off; } } # enable subdomain method reverse proxy confs include /config/nginx/proxy-confs/*.subdomain.conf; # enable proxy cache for auth proxy_cache_path cache/ keys_zone=auth_cache:10m;
4 测试
由于docker默认只支持修改dockerhub的镜像地址,所以这里我们直接用域名指定,先不改客户端配置。
如果你想在容器客户端上配置镜像,可以参考这篇文章《使用CentOS + containerd搭建Kubernetes集群(配置镜像仓库)》
分别测试,都成功!
gcr:
docker pull gcr.xxx.com/google_containers/nginx Using default tag: latest latest: Pulling from google_containers/nginx a3ed95caeb02: Download complete e30706b9b4ff: Downloading [=============================> ] 39.63MB/66.21MB 82286846aa71: Download complete d433c42f6001: Download complete 74d2508996ef: Downloading [===========================> ] 47.02MB/85.95MB 4fceae443db7: Download complete 577897efe0e1: Download complete 69d79999108f: Download complete 091f65bae2b8: Download complete
ghcr:
docker pull ghcr.xxx.com/linuxserver/swag Using default tag: latest latest: Pulling from linuxserver/swag a259f7071357: Pull complete b282233e8e89: Pull complete f58fd26cf7bd: Pull complete edb56b1d80db: Pull complete d225983fe978: Pull complete 34267e5824c6: Pull complete 5b39dafc9da1: Pull complete e581b9668a65: Pull complete f41e6a8baee3: Pull complete 3e5a1887e705: Pull complete Digest: sha256:3f34c33c788221f6aa8b7b0d8e5437c20a59a1466232cccf9a08ccc0933f4877 Status: Downloaded newer image for ghcr.xxx.com/linuxserver/swag:latest ghcr.xxx.com/linuxserver/swag:latest
quay:
docker pull quay.xxx.com/ansible/acme-test-container Using default tag: latest latest: Pulling from ansible/acme-test-container 75cb2ebf3b3c: Pull complete 2fdcfea9efdf: Pull complete d0dc56fb1743: Pull complete 06544e3182b9: Pull complete 9a839ef40fb8: Pull complete 3759b75a8d1c: Pull complete dc45525a5e23: Pull complete 79cc6c38d8ce: Pull complete 68360381c840: Pull complete 69a203922487: Pull complete 30813fa4ea46: Pull complete Digest: sha256:fa7a27634f2285b92a2109a765f012943cc8c688bb4232bfce89ee22d7e98183 Status: Downloaded newer image for quay.xxx.com/ansible/acme-test-container:latest quay.xxx.com/ansible/acme-test-container:latest
k8s:
docker pull k8s-gcr.xxx.com/kube-apiserver:v1.21.3 v1.21.3: Pulling from kube-apiserver b49b96595fd4: Pull complete b91f78c1d2c5: Pull complete 59e5d583c89f: Pull complete Digest: sha256:7950be952e1bf5fea24bd8deb79dd871b92d7f2ae02751467670ed9e54fa27c2 Status: Downloaded newer image for k8s-gcr.xxx.com/kube-apiserver:v1.21.3 k8s-gcr.xxx.com/kube-apiserver:v1.21.3
参考文章:https://fuckcloudnative.io/posts/docker-registry-proxy/