• 本文章代理仅作为获取镜像使用!其他一切概不负责,不提供技术支持、镜像加速等服务!

直接简单的方法就是搞个魔法服务器,自己部署registry,详细过程参考这位大佬的教程Docker 镜像加速教程,自己也参考了很多非常感谢🙏。然后我们来说一说穷人的解决方法!经过实际测试发现由Docker出品的registry是可以通过http_proxy和https_proxy两个环境变量进行代理的,所以方法也就不言而喻了。但是为了解决DNS污染和实现Docker部署,还需要做点小改动:简单来说就是利用容器编排工具启动两个container,一个运行register,另一个运行提供代理的软件;最后通过反向代理将服务暴露出去并提供自动https等功能。

registry

本blog完整的代码位于github,觉得可以的话给个小星星也好~

proxy部分

clash直接提供了容器部署,并且也有网页版的dashboard容器,支持所需要的代理类型,所以直接拿来使用。刚开始测试的时候使用docker内部DNS来访问clash容器,不知道为什么及其不稳定,并且考虑到还有使用clash的dns服务器的需要,就直接为clash分配固定ip。部分docker-compose文件配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
version: "3.4"

services:
clash:
image: dreamacro/clash-premium
restart: always
networks:
default:
ipv4_address: "172.38.1.240"
ports:
- "7890"
- "53"
- "9090"
volumes:
- /path/to/clash/config.yaml:/root/.config/clash/config.yaml
- ./resolvs/clash-resolv.conf:/etc/resolv.conf:ro
clash_dashboard:
image: haishanh/yacd
restart: always
depends_on:
- clash
networks:
- default
ports:
- "80"
registry_k8s: 第二章里
registry_gcr: 第二章里
registry_ghcr: 第二章里
registry_quay: 第二章里


networks:
default:
ipam:
config:
- subnet: 172.38.1.0/24

对应的clash这么写,有修改端口的话要对应处一起改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
---
#---------------------------------------------------#
## 配置文件需要放置在 $HOME/.config/clash/*.yaml

## 这份文件是clashX的基础配置文件,请尽量新建配置文件进行修改。
## !!!只有这份文件的端口设置会随ClashX启动生效

## 如果您不知道如何操作,请参阅 官方Github文档 https://github.com/Dreamacro/clash/blob/dev/README.md
#---------------------------------------------------#

# (HTTP and SOCKS5 in one port) 这里就是代理用到的目标端口
mixed-port: 7890
# RESTful API for clash 管理面板接入的端口
external-controller: 0.0.0.0:9090
# 这个必须允许,不然其他容器访问不到
allow-lan: true
mode: rule
log-level: warning
secret: "clash_password"


dns:
enable: true
listen: 0.0.0.0:53
ipv6: false
# enhanced-mode: fake-ip
# nameserver 裡 DoH / DoT 的域名使用 default-nameserver 請求
default-nameserver:
- 119.29.29.29
- 114.114.114.114
- 223.5.5.5
# 國內域名使用 nameserver 請求
nameserver:
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
# 國外域名使用 fallback 請求
fallback:
- tls://one.one.one.one:853
- tls://dns.google:853
- https://dns.adguard.com/dns-query
- https://doh.dns.sb/dns-query

# PUT YOUR CONFIG BELOW
# 这里放该放的配置,懂的都懂。

这里为了解决DNS污染问题,启用了clash的DNS服务器功能,并且重新挂载了registry容器的/etc/resolv.conf文件,添加了clash所在的ip作为DNS服务器。如果不需要的话就取消挂载即可。

registry配置

这里的配置没啥好说的,直接查阅registry官方文档即可。为了防止被白嫖,配置了简单的密码登陆认证,对应的docker-compose部分如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
registry_k8s:
image: registry:2.7.1
restart: on-failure
depends_on:
- clash
networks:
- default
ports:
- 5000
volumes:
- ./registry-config.yaml/:/etc/docker/registry/config.yml:ro
- ./resolvs/registry-resolv.conf:/etc/resolv.conf:ro
environment:
- http_proxy=http://172.38.1.240:7890
- https_proxy=http://172.38.1.240:7890
- REGISTRY_PROXY_REMOTEURL=https://k8s.gcr.io
- REGISTRY_AUTH_HTPASSWD_REALM=token-realm
- REGISTRY_AUTH_HTPASSWD_PATH=/run/secrets/htpasswd
secrets:
- htpasswd
registry_gcr:
image: registry:2.7.1
restart: on-failure
depends_on:
- clash
networks:
- default
ports:
- 5000
volumes:
- ./registry-config.yaml/:/etc/docker/registry/config.yml:ro
- ./resolvs/registry-resolv.conf:/etc/resolv.conf:ro
environment:
- http_proxy=http://172.38.1.240:7890
- https_proxy=http://172.38.1.240:7890
- REGISTRY_PROXY_REMOTEURL=https://gcr.io
- REGISTRY_AUTH_HTPASSWD_REALM=token-realm
- REGISTRY_AUTH_HTPASSWD_PATH=/run/secrets/htpasswd
secrets:
- htpasswd
registry_ghcr:
image: registry:2.7.1
restart: on-failure
depends_on:
- clash
networks:
- default
ports:
- 5000
volumes:
- ./registry-config.yaml/:/etc/docker/registry/config.yml:ro
- ./resolvs/registry-resolv.conf:/etc/resolv.conf:ro
environment:
- http_proxy=http://172.38.1.240:7890
- https_proxy=http://172.38.1.240:7890
- REGISTRY_PROXY_REMOTEURL=https://ghcr.io
- REGISTRY_AUTH_HTPASSWD_REALM=token-realm
- REGISTRY_AUTH_HTPASSWD_PATH=/run/secrets/htpasswd
secrets:
- htpasswd
registry_quay:
image: registry:2.7.1
restart: on-failure
depends_on:
- clash
networks:
- default
ports:
- 5000
volumes:
- ./registry-config.yaml/:/etc/docker/registry/config.yml:ro
- ./resolvs/registry-resolv.conf:/etc/resolv.conf:ro
environment:
- http_proxy=http://172.38.1.240:7890
- https_proxy=http://172.38.1.240:7890
- REGISTRY_PROXY_REMOTEURL=https://quay.io
- REGISTRY_AUTH_HTPASSWD_REALM=token-realm
- REGISTRY_AUTH_HTPASSWD_PATH=/run/secrets/htpasswd
secrets:
- htpasswd


secrets:
htpasswd:
file: ./htpasswd

htpasswd生成也很简单,将USER_NAME和PASSWORD分别替换成用户名和密码就好了:

1
docker run --entrypoint htpasswd httpd:2 -Bbn USER_NAME PASSWORD > ./htpasswd

反向代理

由于服务器上还运行了其他的项目,所以不适合让registry独享一个反向代理,并且也懒得部署traefik,直接就用caddy梭哈梭哈~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: "3.4"

services:
caddy_frontend:
image: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy/caddy_data:/data
- ./caddy/caddy_conf:/config
networks:
- ext_network_other
- ext_network_registry

networks:
ext_network_other:
external: true
name: other_default
ext_network_registry:
external: true
name: registry_default

这里docker-compose命令行工具的版本不可以太低,否则无法使用external类型的network(ubunut20的apt装的就不行)。caddy配置也没啥,直接反向代理就行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
# LetsEncrypt account
email email@email.com
}

# Clash
https://dashboard.clash.you.domain {
reverse_proxy * http://clash_dashboard:80
}

https://api.clash.you.domain {
reverse_proxy * http://clash:9090
}

# k8s.gcr.io
https://k8s.registry.you.domain {
reverse_proxy * http://registry_k8s:5000
}

# gcr.io
https://gcr.registry.you.domain {
reverse_proxy * http://registry_gcr:5000
}

# ghcr.io
https://ghcr.registry.you.domain {
reverse_proxy * http://registry_ghcr:5000
}

# quay.io
https://quay.registry.you.domain {
reverse_proxy * http://registry_quay:5000
}

k3s更换源

k3s默认的CRI是containerd,换源方法有去修改/var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl,但是说实话这个格式的文件是真的难改。好在k3s提供了一个修改方法(文档点我):直接创建/etc/rancher/k3s/registries.yaml就好了,毕竟这是一个合格的yaml工程师的基础能力🐶。下面给个简单的修改例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
mirrors:
docker.io:
endpoint:
- "https://reg-mirror.qiniu.com"
k8s.gcr.io:
endpoint:
- "https://k8s.registry.you.domain"
gcr.io:
endpoint:
- "https://gcr.registry.you.domain"
ghcr.io:
endpoint:
- "https://ghcr.registry.you.domain"
quay.io:
endpoint:
- "https://quay.registry.you.domain"
configs:
"k8s.registry.you.domain":
auth:
username: USERNAME
password: PASSWORD
"gcr.registry.you.domain":
auth:
username: USERNAME
password: PASSWORD
"ghcr.registry.you.domain":
auth:
username: USERNAME
password: PASSWORD
"quay.registry.you.domain":
auth:
username: USERNAME
password: PASSWORD

docker.io国内有好用免费的,直接用就好了,其余的就靠自己解决了。注意若是没有部署https的话,endpoint需要显示申明http://xxx.registry.you.domain

  • 测试的时候,http_proxy=http://172.38.1.240:7890https_proxy=http://172.38.1.240:7890部分都用clash代替172.38.1.240,使得registry间歇性代理失败,很迷不知道为什么。
  • registry启动的时候会立即访问下被代理的registry源地址,若此时代理没有准备好的话registry似乎一直panic就活不过来了,必须等proxy好了以后手动重新创建容器。(未详细测试)
  • docker-compose里面添加dns字段并不能生效,似乎是个老feature了。解决方法就是直接修改挂载/etc/resolv.conf文件,虽然并不优雅。。。
  • 关于缓存清理等,看开头大佬的文章就好了。