Skip to content

Commit 31c7ea7

Browse files
HishamHisham
Hisham
authored and
Hisham
committed
add capability to support non resolveable upstreams
1 parent 2456b35 commit 31c7ea7

File tree

4 files changed

+49
-18
lines changed

4 files changed

+49
-18
lines changed

Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ EXPOSE 8082
6363
ENV REGISTRIES="k8s.gcr.io gcr.io quay.io"
6464
# A space delimited list of registry:user:password to inject authentication for
6565
ENV AUTH_REGISTRIES="some.authenticated.registry:oneuser:onepassword another.registry:user:password"
66+
# A space delimited list of domain=IP1,IP2 to inject upstream -> server mapping for
67+
ENV UPSTREAM_MAPPINGS=""
6668
# Should we verify upstream's certificates? Default to true.
6769
ENV VERIFY_SSL="true"
6870
# Enable debugging mode; this inserts mitmproxy/mitmweb between the CONNECT proxy and the caching layer

README.md

+20-18
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ Caches the potentially huge blob/layer requests (for bandwidth/time savings), an
1010

1111
### NEW: avoiding DockerHub Pull Rate Limits with Caching
1212

13-
Starting November 2nd, 2020, DockerHub will
14-
[supposedly](https://www.docker.com/blog/docker-hub-image-retention-policy-delayed-and-subscription-updates/)
13+
Starting November 2nd, 2020, DockerHub will
14+
[supposedly](https://www.docker.com/blog/docker-hub-image-retention-policy-delayed-and-subscription-updates/)
1515
[start](https://www.docker.com/blog/scaling-docker-to-serve-millions-more-developers-network-egress/)
16-
[rate-limiting pulls](https://docs.docker.com/docker-hub/download-rate-limit/),
17-
also known as the _Docker Apocalypse_.
16+
[rate-limiting pulls](https://docs.docker.com/docker-hub/download-rate-limit/),
17+
also known as the _Docker Apocalypse_.
1818
The main symptom is `Error response from daemon: toomanyrequests: Too Many Requests. Please see https://docs.docker.com/docker-hub/download-rate-limit/` during pulls.
1919
Many unknowing Kubernetes clusters will hit the limit, and struggle to configure `imagePullSecrets` and `imagePullPolicy`.
2020

21-
Since version `0.6.0`, this proxy can be configured with the env var `ENABLE_MANIFEST_CACHE=true` which provides
21+
Since version `0.6.0`, this proxy can be configured with the env var `ENABLE_MANIFEST_CACHE=true` which provides
2222
configurable caching of the manifest requests that DockerHub throttles. You can then fine-tune other parameters to your needs.
23-
Together with the possibility to centrally inject authentication (since 0.3x), this is probably one of the best ways to bring relief to your distressed cluster, while at the same time saving lots of bandwidth and time.
23+
Together with the possibility to centrally inject authentication (since 0.3x), this is probably one of the best ways to bring relief to your distressed cluster, while at the same time saving lots of bandwidth and time.
2424

2525
Note: enabling manifest caching, in its default config, effectively makes some tags **immutable**. Use with care. The configuration ENVs are explained in the [Dockerfile](./Dockerfile), relevant parts included below.
2626

@@ -51,13 +51,13 @@ ENV MANIFEST_CACHE_DEFAULT_TIME="1h"
5151

5252
## What?
5353

54-
Essentially, it's a [man in the middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack): an intercepting proxy based on `nginx`, to which all docker traffic is directed using the `HTTPS_PROXY` mechanism and injected CA root certificates.
54+
Essentially, it's a [man in the middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack): an intercepting proxy based on `nginx`, to which all docker traffic is directed using the `HTTPS_PROXY` mechanism and injected CA root certificates.
5555

56-
The main feature is Docker layer/image caching, including layers served from S3, Google Storage, etc.
56+
The main feature is Docker layer/image caching, including layers served from S3, Google Storage, etc.
5757

5858
As a bonus it allows for centralized management of Docker registry credentials, which can in itself be the main feature, eg in Kubernetes environments.
5959

60-
You configure the Docker clients (_err... Kubernetes Nodes?_) once, and then all configuration is done on the proxy --
60+
You configure the Docker clients (_err... Kubernetes Nodes?_) once, and then all configuration is done on the proxy --
6161
for this to work it requires inserting a root CA certificate into system trusted root certs.
6262

6363
## master/:latest is unstable/beta
@@ -87,6 +87,8 @@ for this to work it requires inserting a root CA certificate into system trusted
8787
- `hostname`s listed here should be listed in the REGISTRIES environment as well, so they can be intercepted.
8888
- Env `AUTH_REGISTRIES_DELIMITER` to change the separator between authentication info. By default, a space: "` `". If you use keys that contain spaces (as with Google Cloud Registry), you should update this variable, e.g. setting it to `AUTH_REGISTRIES_DELIMITER=";;;"`. In that case, `AUTH_REGISTRIES` could contain something like `registry1.com:user1:pass1;;;registry2.com:user2:pass2`.
8989
- Env `AUTH_REGISTRY_DELIMITER` to change the separator between authentication info *parts*. By default, a colon: "`:`". If you use keys that contain single colons, you should update this variable, e.g. setting it to `AUTH_REGISTRIES_DELIMITER=":::"`. In that case, `AUTH_REGISTRIES` could contain something like `registry1.com:::user1:::pass1 registry2.com:::user2:::pass2`.
90+
- Env `UPSTREAM_MAPPINGS` to configure upstream server mappings (similar in functionality to /etc/hosts entries but with round-robin selection).
91+
Useful when configured resolvers are unable to resolve a host. e.g. `UPSTREAM_MAPPINGS="registry1=10.0.1.10:443,10.0.1.11 registry2=5.0.1.10"`
9092
- Timeouts ENVS - all of them can pe specified to control different timeouts, and if not set, the defaults will be the ones from `Dockerfile`. The directives will be added into `http` block.:
9193
- SEND_TIMEOUT : see [send_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout)
9294
- CLIENT_BODY_TIMEOUT : see [client_body_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout)
@@ -155,10 +157,10 @@ docker run --rm --name docker_registry_proxy -it \
155157

156158
### Google Container Registry (GCR) auth
157159

158-
For Google Container Registry (GCR), username should be `_json_key` and the password should be the contents of the service account JSON.
159-
Check out [GCR docs](https://cloud.google.com/container-registry/docs/advanced-authentication#json_key_file).
160+
For Google Container Registry (GCR), username should be `_json_key` and the password should be the contents of the service account JSON.
161+
Check out [GCR docs](https://cloud.google.com/container-registry/docs/advanced-authentication#json_key_file).
160162

161-
The service account key is in JSON format, it contains spaces ("` `") and colons ("`:`").
163+
The service account key is in JSON format, it contains spaces ("` `") and colons ("`:`").
162164

163165
To be able to use GCR you should set `AUTH_REGISTRIES_DELIMITER` to something different than space (e.g. `AUTH_REGISTRIES_DELIMITER=";;;"`) and `AUTH_REGISTRY_DELIMITER` to something different than a single colon (e.g. `AUTH_REGISTRY_DELIMITER=":::"`).
164166

@@ -274,7 +276,7 @@ Since `0.4` there is a separate `-debug` version of the image, which includes `n
274276
This allows very in-depth debugging. Use sparingly, and definitely not in production.
275277

276278
```bash
277-
docker run --rm --name docker_registry_proxy -it
279+
docker run --rm --name docker_registry_proxy -it
278280
-e DEBUG_NGINX=true -e DEBUG=true -e DEBUG_HUB=true -p 0.0.0.0:8081:8081 -p 0.0.0.0:8082:8082 \
279281
-p 0.0.0.0:3128:3128 -e ENABLE_MANIFEST_CACHE=true \
280282
-v $(pwd)/docker_mirror_cache:/docker_mirror_cache \
@@ -297,15 +299,15 @@ docker run --rm --name docker_registry_proxy -it
297299

298300
### Why not use Docker's own registry, which has a mirror feature?
299301

300-
Yes, Docker offers [Registry as a pull through cache](https://docs.docker.com/registry/recipes/mirror/), *unfortunately*
302+
Yes, Docker offers [Registry as a pull through cache](https://docs.docker.com/registry/recipes/mirror/), *unfortunately*
301303
it only covers the DockerHub case. It won't cache images from `quay.io`, `k8s.gcr.io`, `gcr.io`, or any such, including any private registries.
302304

303-
That means that your shiny new Kubernetes cluster is now a bandwidth hog, since every image will be pulled from the
305+
That means that your shiny new Kubernetes cluster is now a bandwidth hog, since every image will be pulled from the
304306
Internet on every Node it runs on, with no reuse.
305307

306-
This is due to the way the Docker "client" implements `--registry-mirror`, it only ever contacts mirrors for images
308+
This is due to the way the Docker "client" implements `--registry-mirror`, it only ever contacts mirrors for images
307309
with no repository reference (eg, from DockerHub).
308-
When a repository is specified `dockerd` goes directly there, via HTTPS (and also via HTTP if included in a
310+
When a repository is specified `dockerd` goes directly there, via HTTPS (and also via HTTP if included in a
309311
`--insecure-registry` list), thus completely ignoring the configured mirror.
310312

311313
### Docker itself should provide this.
@@ -315,7 +317,7 @@ Yeah. Docker Inc should do it. So should NPM, Inc. Wonder why they don't. 😼
315317
### TODO:
316318

317319
- [x] Basic Docker-for-Mac set-up instructions
318-
- [x] Basic Docker-for-Windows set-up instructions.
320+
- [x] Basic Docker-for-Windows set-up instructions.
319321
- [ ] Test and make auth work with quay.io, unfortunately I don't have access to it (_hint, hint, quay_)
320322
- [x] Hide the mitmproxy building code under a Docker build ARG.
321323
- [ ] "Developer Office" proxy scenario, where many developers on a fast LAN share a proxy for bandwidth and speed savings (already works for pulls, but messes up pushes, which developers tend to use a lot)

entrypoint.sh

+24
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,30 @@ else
3838
echo "Not using resolver config, keep existing '$confpath' -- mounted by user?"
3939
fi
4040

41+
# Generate nginx upstream blocks into file. Function similar to a /etc/hosts file but includes round-robin selection
42+
# e.g when UPSTREAM_MAPPINGS="registry1=10.0.1.10:443,10.0.1.11 registry2=5.0.1.10", the following file is generated
43+
# upstream registry1 {
44+
# server 10.0.1.10:443;
45+
# server 10.0.1.11;
46+
# }
47+
# upstream registry2 {
48+
# server 5.0.1.10;
49+
# }
50+
echo -n "" >> /etc/nginx/upstreams.conf
51+
52+
if [ ! -z "$UPSTREAM_MAPPINGS" ]; then
53+
54+
for UPSTREAM in ${UPSTREAM_MAPPINGS}; do
55+
echo "upstream ${UPSTREAM%=*} {" >> /etc/nginx/upstreams.conf
56+
comma_separated_hosts="${UPSTREAM#*=}"
57+
hosts=`echo $comma_separated_hosts | tr ',' ' '`
58+
for host in ${hosts}; do
59+
echo -e "\tserver $host;" >> /etc/nginx/upstreams.conf
60+
done
61+
echo "}" >> /etc/nginx/upstreams.conf
62+
done
63+
fi
64+
4165
# The list of SAN (Subject Alternative Names) for which we will create a TLS certificate.
4266
ALLDOMAINS=""
4367

nginx.conf

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ http {
7878

7979
gzip off;
8080

81+
# Entrypoint generates the upstreams.conf config.
82+
include /etc/nginx/upstreams.conf;
83+
8184
# Entrypoint generates the proxy_cache_path here, so it is configurable externally.
8285
include /etc/nginx/conf.d/cache_max_size.conf;
8386

0 commit comments

Comments
 (0)