GitHub 和 GitLab 等平台承载了无数开发者的心血,其中既有商业闭源项目,也有大量开源项目。这些开源作品不仅展示了开发者的技术与创意,更通过无私的分享和协作推动了整个技术生态的发展。得益于他们的公开,我们能够使用这些工具简化工作流程,提高效率,同时学习到更多先进的技术理念与实现方式。向所有为技术开源和共享做出贡献的开发者致敬,他们让编程世界变得更加丰富、开放和充满可能性。

CRProxy

搭建 CRProxy 需要的技术栈:docker、docker-compose、反向代理。

基础服务

Docker

  1. 部署容器

  2. 创建网络

1
docker network create service

crproxy

GitHub:https://github.com/DaoCloud/crproxy

  1. 容器运行 crproxy 服务
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
version: "3.4"

services:
crproxy:
image: ghcr.io/daocloud/crproxy/crproxy:v0.9.1
container_name: crproxy
restart: unless-stopped
networks:
- service
environment:
TZ: Asia/Shanghai
# command: |
# add docker.io username increase pulls from 100 to 200 per 6 hour period
# -u username:[email protected]
# support ignoring prefixes, e.g. docker pull mysql
# --default-registry docker.io
# cache storage example: aliyunoss
# --storage-driver oss
# --storage-parameters accesskeyid=xxxxx,accesskeysecret=xxxxxxx,region=oss-ap-xxxx-1,encrypt=true,bucket=xxxx
# user
# --simple-auth
# --simple-auth-user user1=pass1
# --simple-auth-user user2=pass2
networks:
service:
external: true

代理服务

代理服务选择繁多,支持 7 层代理满足条件;如 nginx、nginx-ui、traefik 等。

简化运维:

  • 支持证书自动续签

Traefik

文件

  • 容器文件:docker-compose.yaml
  • 服务文件:dynamic.yaml
  • 证书文件:acme.json
  • traefik 服务文件:traefik.yaml
1
2
3
4
5
6
7
8
9
10
11
[root@lhins-cty2stvp src]# tree traefik/
traefik/
|-- docker-compose.yaml
`-- traefik
|-- basic-auth
| `-- traefik-secret
|-- etc
| |-- dynamic.yaml
| `-- traefik.yaml
`-- letsencrypt
`-- acme.json

服务

  1. docker-compose.yaml
  • ALICLOUD_ACCESS_KEY:域名托管平台 ak
  • ALICLOUD_SECRET_KEY:域名托管平台 sk
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
version: "3.4"

services:
traefik:
privileged: true
image: traefik:v3.1.2
container_name: traefik
restart: always
environment:
TZ: Asia/Shanghai
ALICLOUD_ACCESS_KEY: {}
ALICLOUD_SECRET_KEY: {}
stdin_open: true
volumes:
- ./traefik/letsencrypt:/letsencrypt
- ./traefik/etc:/etc/traefik
- ./traefik/basic-auth:/etc/basic-auth
- /etc/localtime:/etc/localtime
- /var/run/docker.sock:/var/run/docker.sock
tty: true
networks:
- service
ports:
# http
- "80:80"
# https
- "443:443"
command:
- --configFile=/etc/traefik/traefik.yml
labels:
- "traefik.enable=true"
- "traefik.docker.network=service"
- "traefik.http.routers.dashboard.tls=true"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entryPoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=myresolver"
- "traefik.http.routers.dashboard.rule=Host(`traefik.sysio.ai`)"
- "traefik.http.middlewares.dashboard-auth.basicauth.usersfile=/etc/basic-auth/traefik-secret"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker,SecHeaders@file"
- "traefik.http.routers.dashboard.tls.domains[0].main=sysio.ai"
- "traefik.http.routers.dashboard.tls.domains[0].sans=*.sysio.cn"
- "traefik.http.services.dashborad.loadbalancer.server.port=8080"
networks:
service:
external: true
  1. dynamic.yaml
方式一:

手动添加镜像源站地址,格式:sysio.ai/{镜像源站}/{镜像名称}:{tag}

  • sysio.ai/docker.io/busybox:latest
  • sysio.ai/registry.k8s.io/busybox:latest
  1. routers
1
2
3
4
5
6
7
daocloud:
rule: "Host(`sysio.ai`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
service: daocloud
  1. services
1
2
3
4
daocloud:
loadBalancer:
servers:
- url: "http://crproxy:8080"
方式二:

反向代理服务拼接源站地址,格式:{名称}/sysio.ai/{镜像名称}:{tag}

  • docker.sysio.ai/busybox:latest
  • k8s.sysio.ai/busybox:latest
  1. routers
1
2
3
4
5
6
7
8
9
docker:
rule: "Host(`docker.sysio.ai`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
middlewares:
- "docker"
service: docker
  1. services
1
2
3
4
docker:
loadBalancer:
servers:
- url: "http://crproxy:8080"
  1. middlewares
    1. 正则表达式处理 docker.sysio.ai -> sysio.ai/v2/docker.io
1
2
3
4
docker:
redirectRegex:
regex: "^https://docker.sysio.ai/v2/(.+)$"
replacement: "https://sysio.ai/v2/docker.io/${1}"

完整配置:

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
tls:
options:
default:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2
- TLS_AES_256_GCM_SHA384 # TLS 1.3
- TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3
curvePreferences:
- CurveP521
- CurveP384
sniStrict: true

http:
routers:
daocloud:
rule: "Host(`sysio.ai`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
service: daocloud

quay:
rule: "Host(`quay.sysio.ai`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
middlewares:
- "quay"
service: quay

ghcr:
rule: "Host(`ghcr.sysio.ai`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
middlewares:
- "ghcr"
service: ghcr

docker:
rule: "Host(`docker.sysio.ai`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
middlewares:
- "docker"
service: docker

elastic:
rule: "Host(`elastic.sysio.ai`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
middlewares:
- "elastic"
service: elastic

services:
daocloud:
loadBalancer:
servers:
- url: "http://crproxy:8080"

quay:
loadBalancer:
servers:
- url: "http://crproxy:8080"

ghcr:
loadBalancer:
servers:
- url: "http://crproxy:8080"

docker:
loadBalancer:
servers:
- url: "http://crproxy:8080"

elastic:
loadBalancer:
servers:
- url: "http://crproxy:8080"

middlewares:
SecHeaders:
headers:
frameDeny: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsSeconds: 15768000
sslRedirect: true
sslForceHost: true

quay:
redirectRegex:
regex: "^https://quay.sysio.ai/v2/(.+)$"
replacement: "https://sysio.ai/v2/quay.io/${1}"
permanent: true

ghcr:
redirectRegex:
regex: "^https://ghcr.sysio.ai/v2/(.+)$"
replacement: "https://sysio.ai/v2/ghcr.io/${1}"
permanent: true

docker:
redirectRegex:
regex: "^https://docker.sysio.ai/v2/(.+)$"
replacement: "https://sysio.ai/v2/docker.io/${1}"
permanent: true

elastic:
redirectRegex:
regex: "^https://elastic.sysio.ai/v2/(.+)$"
replacement: "https://sysio.ai/v2/docker.elastic.co/${1}"
permanent: true
  1. traefik.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
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
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /etc/traefik/dynamic.yaml
watch: true

api:
debug: true
insecure: true
dashboard: true

accessLog: {}

metrics:
prometheus:
addEntryPointsLabels: true
addRoutersLabels: true
entryPoint: metrics
headerLabels:
useragent: User-Agent

entryPoints:
metrics:
address: ":8082"
traefik:
address: ":8085"
dashboard:
address: ":8080"
# api:
# address: ":8081"
web:
address: ":80"
proxyProtocol:
insecure: true
forwardedHeaders:
insecure: true
trustedIPs:
- "0.0.0.0/0"
http:
redirections:
entryPoint:
to: "websecure"
scheme: "https"

websecure:
address: ":443"
proxyProtocol:
insecure: true
forwardedHeaders:
insecure: true
trustedIPs:
- "0.0.0.0/0"

certificatesResolvers:
myresolver:
acme:
dnsChallenge:
provider: alidns
delayBeforeCheck: 30
storage: /letsencrypt/acme.json

serversTransport:
insecureSkipVerify: true