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/