Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker, containerd: image registry mirrors #1629

Merged
merged 3 commits into from Aug 2, 2021

Conversation

etungsten
Copy link
Contributor

@etungsten etungsten commented Jun 23, 2021

Issue number:
Resolves #1577

Description of changes:

Author: Erikson Tung <etung@amazon.com>
Date:   Wed Jun 23 15:22:11 2021 -0700

    migrations: migrate `settings.container-registry`, and related models
    
    Adds migrations for the new `container-registry` setting and the new
    docker daemon config file and the new config file for host-containers
    and bootstrap containers.

Author: Erikson Tung <etung@amazon.com>
Date:   Mon Jul 26 22:52:09 2021 -0700

    host-ctr: add support for container image registries
    
    Adds support for configuring container image registrys for
    host-containers and bootstrap containers. A lot of the logic is
    borrowed from containerd-cri plugin's implementation of image registry
    mirrors.

Author: Erikson Tung <etung@amazon.com>
Date:   Tue Jun 22 15:12:14 2021 -0700

    docker, containerd: container image registry mirrors
    
    Adds a new setting `settings.container-registry.mirrors` that lets users set
    pull-through caches for container image registries.

Testing done:

Built AMIs and launched an ECS host and an K8S host.

Set up a pull-through cache for docker hub on a separate host:

sudo docker run \
  -d \
  -p 80:5000 \
  --restart=always \
  --name=through-cache \
  -e REGISTRY_PROXY_REMOTEURL="https://registry-1.docker.io" \
  -e REGISTRY_PROXY_USERNAME=snip \
  -e REGISTRY_PROXY_PASSWORD=snip \
  registry

Set the image registry mirror to the pull-through cache host on both ECS and K8S hosts:

apiclient set --json '{"container-registry":{"mirrors":{"docker.io":["http://my-pull-through-cache-host-ip"]}}}'

Tried running a nginx task on in the ECS cluster, observed that the image was pulled from the cache
The pull-through cache registry is responding to the requests for manifests and blobs with HTTP status code 200:

time="2021-06-23T20:40:09.738518303Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=75a15a82-6b80-4508-ad7a-9cc17b1a1e84 http.request.method=GET http.request.remoteaddr="54.184.78.250:44052" http.request.uri="/v2/" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/json; charset=utf-8" http.response.duration=1.016725ms http.response.status=200 http.response.written=2 
54.184.78.250 - - [23/Jun/2021:20:40:09 +0000] "GET /v2/ HTTP/1.1" 200 2 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.494864674Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=de6ec364-34d4-4648-8f30-9613f5f23512 http.request.method=HEAD http.request.remoteaddr="54.184.78.250:44054" http.request.uri="/v2/library/nginx/manifests/mainline" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/vnd.docker.distribution.manifest.list.v2+json" http.response.duration=753.789996ms http.response.status=200 http.response.written=1862 
54.184.78.250 - - [23/Jun/2021:20:40:09 +0000] "HEAD /v2/library/nginx/manifests/mainline HTTP/1.1" 200 1862 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/manifests/sha256:47ae43cdfc7064d28800bc42e79a429540c7c80168e8c8952778c0d5af1c09db HTTP/1.1" 200 1862 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.509265258Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=b60c65c4-6909-4b6a-89dc-a5e95add0ec8 http.request.method=GET http.request.remoteaddr="54.184.78.250:44056" http.request.uri="/v2/library/nginx/manifests/sha256:47ae43cdfc7064d28800bc42e79a429540c7c80168e8c8952778c0d5af1c09db" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/vnd.docker.distribution.manifest.list.v2+json" http.response.duration=1.813035ms http.response.status=200 http.response.written=1862 
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/manifests/sha256:2f1cd90e00fe2c991e18272bb35d6a8258eeb27785d121aa4cc1ae4235167cfd HTTP/1.1" 200 1570 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.525015041Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=da96c670-692a-49aa-8eee-a20a3cf115cb http.request.method=GET http.request.remoteaddr="54.184.78.250:44058" http.request.uri="/v2/library/nginx/manifests/sha256:2f1cd90e00fe2c991e18272bb35d6a8258eeb27785d121aa4cc1ae4235167cfd" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/vnd.docker.distribution.manifest.v2+json" http.response.duration=1.788932ms http.response.status=200 http.response.written=1570 
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/blobs/sha256:b82f7f888feb03d38fed4dad68d7265a8b276f1f0c543d549fc6ef30b42c00eb HTTP/1.1" 200 667 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.550816892Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=83e13e41-e792-4393-a72e-5dba761a479f http.request.method=GET http.request.remoteaddr="54.184.78.250:44072" http.request.uri="/v2/library/nginx/blobs/sha256:b82f7f888feb03d38fed4dad68d7265a8b276f1f0c543d549fc6ef30b42c00eb" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/octet-stream" http.response.duration=5.145482ms http.response.status=200 http.response.written=667 
time="2021-06-23T20:40:10.553786666Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=844055df-4f8b-4f52-bbb6-cf76cd6e1699 http.request.method=GET http.request.remoteaddr="54.184.78.250:44066" http.request.uri="/v2/library/nginx/blobs/sha256:03e6a245275128e26fc650e724e3fc4510d81f8111bae35ece70242b0a638215" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/octet-stream" http.response.duration=5.994485ms http.response.status=200 http.response.written=895 
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/blobs/sha256:03e6a245275128e26fc650e724e3fc4510d81f8111bae35ece70242b0a638215 HTTP/1.1" 200 895 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.55698674Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=9b3cea70-112a-43ea-bcca-36e4f4107980 http.request.method=GET http.request.remoteaddr="54.184.78.250:44060" http.request.uri="/v2/library/nginx/blobs/sha256:4f380adfc10f4cd34f775ae57a17d2835385efd5251d6dfe0f246b0018fb0399" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/octet-stream" http.response.duration=23.66608ms http.response.status=200 http.response.written=7733 
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/blobs/sha256:4f380adfc10f4cd34f775ae57a17d2835385efd5251d6dfe0f246b0018fb0399 HTTP/1.1" 200 7733 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.560957612Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=2c20e6a6-e5e3-4d06-bd58-ef49fd6572ef http.request.method=GET http.request.remoteaddr="54.184.78.250:44068" http.request.uri="/v2/library/nginx/blobs/sha256:b21fed559b9f420d83f8e38ca08d1ac4f15298a3ae02c6de56f364bee2299f78" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/octet-stream" http.response.duration=7.948473ms http.response.status=200 http.response.written=602 
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/blobs/sha256:b21fed559b9f420d83f8e38ca08d1ac4f15298a3ae02c6de56f364bee2299f78 HTTP/1.1" 200 602 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.56643432Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=9bb0785e-9832-4ecf-89df-db7328c4f5ef http.request.method=GET http.request.remoteaddr="54.184.78.250:44070" http.request.uri="/v2/library/nginx/blobs/sha256:5430e98eba646ef4a34baff035f6f7483761c873711febd48fbcca38d7890c1e" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/octet-stream" http.response.duration=4.082108ms http.response.status=200 http.response.written=1397 
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/blobs/sha256:5430e98eba646ef4a34baff035f6f7483761c873711febd48fbcca38d7890c1e HTTP/1.1" 200 1397 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/blobs/sha256:b4d181a07f8025e00e0cb28f1cc14613da2ce26450b80c54aea537fa93cf3bda HTTP/1.1" 200 27145851 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.754292088Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=63d7ffbc-1b7d-47cb-8357-54672a3de54f http.request.method=GET http.request.remoteaddr="54.184.78.250:44062" http.request.uri="/v2/library/nginx/blobs/sha256:b4d181a07f8025e00e0cb28f1cc14613da2ce26450b80c54aea537fa93cf3bda" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/octet-stream" http.response.duration=220.138344ms http.response.status=200 http.response.written=27145851 
54.184.78.250 - - [23/Jun/2021:20:40:10 +0000] "GET /v2/library/nginx/blobs/sha256:edb81c9bc1f5416a41e5bea21748dc912772fedbd4bd90e5e3ebfe16b453edce HTTP/1.1" 200 26580118 "" "docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)"
time="2021-06-23T20:40:10.767215744Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=cdbbbb46-0c3e-42da-b1db-18717b747376 http.request.method=GET http.request.remoteaddr="54.184.78.250:44064" http.request.uri="/v2/library/nginx/blobs/sha256:edb81c9bc1f5416a41e5bea21748dc912772fedbd4bd90e5e3ebfe16b453edce" http.request.useragent="docker/20.10.4 go/go1.16.3 git-commit/363e9a88a11be517d9e8c65c998ff56f774eb4dc kernel/5.10.35 os/linux arch/amd64 UpstreamClient(Go-http-client/1.1)" http.response.contenttype="application/octet-stream" http.response.duration=233.865597ms http.response.status=200 http.response.written=26580118 

Ran an nginx pod in my K8S cluster that has a single node:

kubectl --kubeconfig bottlerocket.kubeconfig run nginx --image=nginx

The image got pulled from the pull-through cache registry just like above:

18.236.180.8 - - [23/Jun/2021:19:36:37 +0000] "HEAD /v2/library/nginx/manifests/latest?ns=docker.io HTTP/1.1" 200 1862 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:37.944166513Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=a2678ced-2d46-4fe3-9595-56d04ab029c4 http.request.method=HEAD http.request.remoteaddr="18.236.180.8:50412" http.request.uri="/v2/library/nginx/manifests/latest?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/vnd.docker.distribution.manifest.list.v2+json" http.response.duration=728.409568ms http.response.status=200 http.response.written=1862 
18.236.180.8 - - [23/Jun/2021:19:36:37 +0000] "GET /v2/library/nginx/manifests/sha256:47ae43cdfc7064d28800bc42e79a429540c7c80168e8c8952778c0d5af1c09db?ns=docker.io HTTP/1.1" 200 1862 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:37.960599554Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=abbec0a6-6372-4aef-9ef3-d0c71d9c8a9b http.request.method=GET http.request.remoteaddr="18.236.180.8:23923" http.request.uri="/v2/library/nginx/manifests/sha256:47ae43cdfc7064d28800bc42e79a429540c7c80168e8c8952778c0d5af1c09db?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/vnd.docker.distribution.manifest.list.v2+json" http.response.duration=4.318429ms http.response.status=200 http.response.written=1862 
time="2021-06-23T19:36:38.220117889Z" level=info msg="Adding new scheduler entry for library/nginx@sha256:2f1cd90e00fe2c991e18272bb35d6a8258eeb27785d121aa4cc1ae4235167cfd with ttl=167h59m59.999997602s" go.version=go1.11.2 instance.id=1470de18-b2bd-4f24-b811-4f48dd848efb service=registry version=v2.7.1 
18.236.180.8 - - [23/Jun/2021:19:36:37 +0000] "GET /v2/library/nginx/manifests/sha256:2f1cd90e00fe2c991e18272bb35d6a8258eeb27785d121aa4cc1ae4235167cfd?ns=docker.io HTTP/1.1" 200 1570 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:38.220422328Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=e4effd51-2b0f-4092-878b-c6c744d2815c http.request.method=GET http.request.remoteaddr="18.236.180.8:23923" http.request.uri="/v2/library/nginx/manifests/sha256:2f1cd90e00fe2c991e18272bb35d6a8258eeb27785d121aa4cc1ae4235167cfd?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/vnd.docker.distribution.manifest.v2+json" http.response.duration=242.563687ms http.response.status=200 http.response.written=1570 
time="2021-06-23T19:36:38.57423413Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=207b8564-62f8-4ddd-941d-0af91e6d30d3 http.request.method=GET http.request.remoteaddr="18.236.180.8:23923" http.request.uri="/v2/library/nginx/blobs/sha256:4f380adfc10f4cd34f775ae57a17d2835385efd5251d6dfe0f246b0018fb0399?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/octet-stream" http.response.duration=335.486858ms http.response.status=200 http.response.written=7733 
18.236.180.8 - - [23/Jun/2021:19:36:38 +0000] "GET /v2/library/nginx/blobs/sha256:4f380adfc10f4cd34f775ae57a17d2835385efd5251d6dfe0f246b0018fb0399?ns=docker.io HTTP/1.1" 200 7733 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:38.659022282Z" level=info msg="Adding new scheduler entry for library/nginx@sha256:4f380adfc10f4cd34f775ae57a17d2835385efd5251d6dfe0f246b0018fb0399 with ttl=167h59m59.999998257s" go.version=go1.11.2 instance.id=1470de18-b2bd-4f24-b811-4f48dd848efb service=registry version=v2.7.1 
time="2021-06-23T19:36:38.956560519Z" level=info msg="Adding new scheduler entry for library/nginx@sha256:5430e98eba646ef4a34baff035f6f7483761c873711febd48fbcca38d7890c1e with ttl=167h59m59.999997352s" go.version=go1.11.2 instance.id=1470de18-b2bd-4f24-b811-4f48dd848efb service=registry version=v2.7.1 
time="2021-06-23T19:36:38.976072094Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=be13ba01-f5ab-4f85-ae70-d7e6225b55f8 http.request.method=GET http.request.remoteaddr="18.236.180.8:23923" http.request.uri="/v2/library/nginx/blobs/sha256:5430e98eba646ef4a34baff035f6f7483761c873711febd48fbcca38d7890c1e?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/octet-stream" http.response.duration=368.70882ms http.response.status=200 http.response.written=1397 
18.236.180.8 - - [23/Jun/2021:19:36:38 +0000] "GET /v2/library/nginx/blobs/sha256:5430e98eba646ef4a34baff035f6f7483761c873711febd48fbcca38d7890c1e?ns=docker.io HTTP/1.1" 200 1397 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:39.213741826Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=f01a0bd3-1985-4c4b-a888-728486d11566 http.request.method=GET http.request.remoteaddr="18.236.180.8:18627" http.request.uri="/v2/library/nginx/blobs/sha256:03e6a245275128e26fc650e724e3fc4510d81f8111bae35ece70242b0a638215?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/octet-stream" http.response.duration=580.83924ms http.response.status=200 http.response.written=895 
18.236.180.8 - - [23/Jun/2021:19:36:38 +0000] "GET /v2/library/nginx/blobs/sha256:03e6a245275128e26fc650e724e3fc4510d81f8111bae35ece70242b0a638215?ns=docker.io HTTP/1.1" 200 895 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:39.281922202Z" level=info msg="Adding new scheduler entry for library/nginx@sha256:03e6a245275128e26fc650e724e3fc4510d81f8111bae35ece70242b0a638215 with ttl=167h59m59.999983565s" go.version=go1.11.2 instance.id=1470de18-b2bd-4f24-b811-4f48dd848efb service=registry version=v2.7.1 
time="2021-06-23T19:36:39.30334434Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=0a70ac32-9cac-40b9-9810-12ba77fe6607 http.request.method=GET http.request.remoteaddr="18.236.180.8:56809" http.request.uri="/v2/library/nginx/blobs/sha256:b21fed559b9f420d83f8e38ca08d1ac4f15298a3ae02c6de56f364bee2299f78?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/octet-stream" http.response.duration=660.705942ms http.response.status=200 http.response.written=602 
18.236.180.8 - - [23/Jun/2021:19:36:38 +0000] "GET /v2/library/nginx/blobs/sha256:b21fed559b9f420d83f8e38ca08d1ac4f15298a3ae02c6de56f364bee2299f78?ns=docker.io HTTP/1.1" 200 602 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:39.311026941Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=b98667dd-0051-4aef-a026-b7b18b610932 http.request.method=GET http.request.remoteaddr="18.236.180.8:38323" http.request.uri="/v2/library/nginx/blobs/sha256:b82f7f888feb03d38fed4dad68d7265a8b276f1f0c543d549fc6ef30b42c00eb?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/octet-stream" http.response.duration=660.928532ms http.response.status=200 http.response.written=667 
18.236.180.8 - - [23/Jun/2021:19:36:38 +0000] "GET /v2/library/nginx/blobs/sha256:b82f7f888feb03d38fed4dad68d7265a8b276f1f0c543d549fc6ef30b42c00eb?ns=docker.io HTTP/1.1" 200 667 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:39.316264076Z" level=info msg="Adding new scheduler entry for library/nginx@sha256:b21fed559b9f420d83f8e38ca08d1ac4f15298a3ae02c6de56f364bee2299f78 with ttl=167h59m59.999995972s" go.version=go1.11.2 instance.id=1470de18-b2bd-4f24-b811-4f48dd848efb service=registry version=v2.7.1 
time="2021-06-23T19:36:39.395778065Z" level=info msg="Adding new scheduler entry for library/nginx@sha256:b82f7f888feb03d38fed4dad68d7265a8b276f1f0c543d549fc6ef30b42c00eb with ttl=167h59m59.999997262s" go.version=go1.11.2 instance.id=1470de18-b2bd-4f24-b811-4f48dd848efb service=registry version=v2.7.1 
time="2021-06-23T19:36:39.717275884Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=887d2a5f-905d-41ec-9e89-44153fe491d9 http.request.method=GET http.request.remoteaddr="18.236.180.8:25135" http.request.uri="/v2/library/nginx/blobs/sha256:edb81c9bc1f5416a41e5bea21748dc912772fedbd4bd90e5e3ebfe16b453edce?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/octet-stream" http.response.duration=1.101527344s http.response.status=200 http.response.written=26580118 
18.236.180.8 - - [23/Jun/2021:19:36:38 +0000] "GET /v2/library/nginx/blobs/sha256:edb81c9bc1f5416a41e5bea21748dc912772fedbd4bd90e5e3ebfe16b453edce?ns=docker.io HTTP/1.1" 200 26580118 "" "containerd/1.4.6+bottlerocket"
time="2021-06-23T19:36:39.891635154Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=44.234.86.205 http.request.id=0c9a9d08-e289-4d07-ac2d-6c2df642f4d2 http.request.method=GET http.request.remoteaddr="18.236.180.8:24956" http.request.uri="/v2/library/nginx/blobs/sha256:b4d181a07f8025e00e0cb28f1cc14613da2ce26450b80c54aea537fa93cf3bda?ns=docker.io" http.request.useragent="containerd/1.4.6+bottlerocket" http.response.contenttype="application/octet-stream" http.response.duration=1.26689776s http.response.status=200 http.response.written=27145851 
18.236.180.8 - - [23/Jun/2021:19:36:38 +0000] "GET /v2/library/nginx/blobs/sha256:b4d181a07f8025e00e0cb28f1cc14613da2ce26450b80c54aea537fa93cf3bda?ns=docker.io HTTP/1.1" 200 27145851 "" "containerd/1.4.6+bottlerocket"

For host-containers and bootstrap-containers:
Started host-container that just runs nginx:

bash-5.0# apiclient set host-containers.nginx.source="docker.io/library/nginx:latest"
bash-5.0# apiclient set host-containers.nginx.enabled=true 

As soon as the host-container started, I observed traffic through the pull-through cache from my instance:

time="2021-07-27T16:24:08.039378021Z" level=info msg="response completed" go.version=go1.11.2 http.request.host=34.222.201.232 http.request.id=e0293cee-59bd-4e5e-987c-f1c9321591b3 http.request.method=HEAD http.request.remoteaddr="34.222.177.43:49756" http.request.uri="/v2/library/nginx/manifests/latest?ns=docker.io" http.request.useragent="containerd/1.4.3+unknown" http.response.contenttype="application/vnd.docker.distribution.manifest.list.v2+json" http.response.duration=729.030479ms http.response.status=200 http.response.written=1862 
34.222.177.43 - - [27/Jul/2021:16:24:07 +0000] "HEAD /v2/library/nginx/manifests/latest?ns=docker.io HTTP/1.1" 200 1862 "" "containerd/1.4.3+unknown"
34.222.177.43 - - [27/Jul/2021:16:24:55 +0000] "HEAD /v2/library/nginx/manifests/latest?ns=docker.io HTTP/1.1" 200 1862 "" "containerd/1.4.3+unknown"
...

For bootstrap-containers, I defined a bootstrap container that just runs nginx along with the image registry config in my userdata.
Launched instance and bootstrap container started as expected and I observed corresponding traffic through the pull through cache.

Tested migrations and they work as expected

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
packages/docker-engine/docker-engine.spec Outdated Show resolved Hide resolved
sources/models/shared-defaults/kubernetes-containerd.toml Outdated Show resolved Hide resolved
sources/models/src/aws-ecs-1/mod.rs Show resolved Hide resolved
packages/containerd/containerd-config-toml_k8s Outdated Show resolved Hide resolved
@etungsten etungsten marked this pull request as draft June 23, 2021 21:29
@etungsten
Copy link
Contributor Author

Taking into draft since I forgot to write a new migration for the setting.

@etungsten etungsten force-pushed the image-registry-cache branch 2 times, most recently from 41fc9ed to 676865a Compare June 23, 2021 22:50
README.md Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

Push below and above addresses @tjkirch's comments.

@tjkirch
Copy link
Contributor

tjkirch commented Jun 23, 2021

LGTM assuming migrations test OK.

@etungsten etungsten marked this pull request as ready for review June 23, 2021 23:19
README.md Outdated
@@ -407,6 +407,19 @@ These settings can be changed at any time.
Supported values are `debug`, `info`, `warn`, `error`, and `crit`, and the default is `info`.
* `settings.ecs.enable-spot-instance-draining`: If the instance receives a spot termination notice, the agent will set the instance's state to `DRAINING`, so the workload can be moved gracefully before the instance is removed. Defaults to `false`.

#### Image registry settings
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talk about OS images in this readme too, so it might be worthwhile to call out that this is specific to container images.

Suggested change
#### Image registry settings
#### Container image registry settings

README.md Outdated
@@ -407,6 +407,19 @@ These settings can be changed at any time.
Supported values are `debug`, `info`, `warn`, `error`, and `crit`, and the default is `info`.
* `settings.ecs.enable-spot-instance-draining`: If the instance receives a spot termination notice, the agent will set the instance's state to `DRAINING`, so the workload can be moved gracefully before the instance is removed. Defaults to `false`.

#### Image registry settings

The following setting is optional and allows you to configure image registry mirrors and pull-through caches for your orchestrated containers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this only cover orchestrated containers and not host containers? Should it cover both?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this currently only covers orchestrated containers (containers via cri-containerd).

For host-containers it's not immediately clear to me how I can configure the containerd client to use registry mirrors. I suspect I'd have to modify resolver to accomplish that? I can create a separate issue to track registry mirrors for host-containers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this would be something that would have to be done in host-ctr. I'm not sure if we should have the setting called settings.container-registry.mirrors if it only controls orchestrated containers though; how would we change this to handle host containers in the future?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it's just a bug that host-ctr and host containers wouldn't support the mirror settings - same as if a component doesn't support the system-wide proxy settings.

README.md Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

Push above rebases onto develop and fixes conflicts

@etungsten
Copy link
Contributor Author

Push above addresses @bcressey 's comment.

  • "image-registry" -> "container-registry"

tested things and they still work.

@etungsten
Copy link
Contributor Author

Missed some dangling references to image_registries in models. Push above fixes that.

@etungsten
Copy link
Contributor Author

Rebases onto develop and fixes conflicts with migrations.

packages/containerd/containerd-config-toml_k8s Outdated Show resolved Hide resolved
packages/docker-engine/docker-engine.spec Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

Force push addresses @samuelkarp 's comments.

  • Changes the host-ctr-regsitry-config format from TOML to JSON
  • Adds unit tests for registryHosts
  • Adds checks for endpoints without an URL scheme and prefixes them with a default scheme
  • Adds comments explaining images from private ECR repositories cannot use registry configuration.

Force push fixes whitespacing issues with the JSON config template and other small typos.

@etungsten etungsten force-pushed the image-registry-cache branch 2 times, most recently from a185a00 to 7d949ee Compare July 28, 2021 04:12
@etungsten
Copy link
Contributor Author

Push above reverts the change to the configuration file format from TOML to JSON.
The handlebars rust crate does not have feature parity with handlebarsjs. It currently does not support @last, @first, @index in #if or #unless helpers. Which makes it impossible to conditionally render a , for items in a list in JSON, so for multiple items in a list, the resulting JSON would be always invalid.

For example, for the following template:

{
    {{~#if settings.container-registry.mirrors}}
    "mirrors": {
        {{~#each settings.container-registry.mirrors}}
        "{{@key}}": {
            "endpoints": [{{join_array ", " this }}]
        }{{~#unless @last}}, {{/unless}}
        {{~/each}}
    }
    {{~/if}}
}

The , always gets rendered even though it shouldn't have.

{
    "mirrors": {
        "docker.io": {
            "endpoints": ["http://my-pull-through-cache-host-ip"]
        },
    }
}

I tried a bunch of variations of setting the condition, but it just comes down to #if/#unless not working with @index/@last/@first

We technically can write a new helper that conditionally renders the ,. But for simplicity's sake, I think we should just stick with TOML. The only downside is that we're taking on an additional go-toml dependency.

Tested changes and everything still work as described in the PR testing description.

@webern
Copy link
Member

webern commented Jul 28, 2021

We technically can write a new helper that conditionally renders the ,.

I already wrote one I though.

Release.toml Outdated Show resolved Hide resolved
Copy link
Contributor

@samuelkarp samuelkarp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. A couple nits, but nothing that need to block this.

sources/host-ctr/cmd/host-ctr/main_test.go Show resolved Hide resolved
sources/host-ctr/cmd/host-ctr/main.go Outdated Show resolved Hide resolved
sources/host-ctr/cmd/host-ctr/main.go Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

Push above addresses @arnaldo2792 and @samuelkarp 's comments. Will rebase shortly to fix conflicts

@etungsten
Copy link
Contributor Author

Push above rebases onto develop and fixes conflicts.

"(1.1.4, 1.2.0)" = [
"migrate_v1.2.0_container-registry-mirrors.lz4",
"migrate_v1.2.0_container-registry-config-restarts.lz4",
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we planning to fix up migrations in a different commit? If not then these migrations should be with the hostname ones.

@@ -0,0 +1,6 @@
{{~#if settings.container-registry.mirrors}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it might be better to call this file host-ctr.toml to make room for other potential settings - but I'm also happy to defer that until we need more settings.

sources/host-ctr/cmd/host-ctr/main.go Outdated Show resolved Hide resolved
sources/host-ctr/cmd/host-ctr/main_test.go Outdated Show resolved Hide resolved
sources/host-ctr/cmd/host-ctr/main_test.go Outdated Show resolved Hide resolved
sources/host-ctr/cmd/host-ctr/main_test.go Outdated Show resolved Hide resolved
Adds a new setting `settings.container-registry.mirrors` that lets users set
pull-through caches for container image registries.
@etungsten
Copy link
Contributor Author

Push above just rebases onto develop and fixes conflicts.

Adds support for configuring container image registrys for
host-containers and bootstrap containers. A lot of the logic is
borrowed from containerd-cri plugin's implementation of image registry
mirrors.
@etungsten
Copy link
Contributor Author

Push above addresses comments from @samuelkarp and @bcressey

  • I changed the name of the host-ctr config file from host-ctr-registry-config to host-ctr-toml to make it more generic.

Adds migrations for the new `container-registry` setting and the new
docker daemon config file and the new config file for host-containers
and bootstrap containers.
@etungsten
Copy link
Contributor Author

Fixed up Release.toml migrations grouping.

@etungsten etungsten merged commit 1984358 into bottlerocket-os:develop Aug 2, 2021
@etungsten etungsten deleted the image-registry-cache branch August 2, 2021 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support image registry mirrors/pull-through caches
6 participants