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

perf: optimise docker authentication config lookup #2646

Merged
merged 1 commit into from
Jul 16, 2024

Conversation

stevenh
Copy link
Collaborator

@stevenh stevenh commented Jul 14, 2024

Improve the performance of retrieving docker authentication configuration by performing requests in parallel and only performing lookups once.

For a simple double layer image with standard Google Cloud Registry configuration this reduced the time spent doing authentication config lookups from ~4.6s to ~400ms.

Improve the performance of retrieving docker authentication
configuration by performing requests in parallel and only performing
lookups once.

For a simple double layer image with standard Google Cloud Registry
configuration this reduced the time spent doing authentication config
lookups from ~4.6s to ~400ms.
@stevenh stevenh requested a review from a team as a code owner July 14, 2024 19:45
Copy link

netlify bot commented Jul 14, 2024

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit db54320
🔍 Latest deploy log https://app.netlify.com/sites/testcontainers-go/deploys/66942af29a40b6000848947a
😎 Deploy Preview https://deploy-preview-2646--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@mdelapenya
Copy link
Member

Thanks for adding this contribution! Could you share how you measured the lookups? I'm interested in doing some internal tests before merging this. (at first sight, it LGTM)

@stevenh
Copy link
Collaborator Author

stevenh commented Jul 15, 2024

Thanks for adding this contribution! Could you share how you measured the lookups? I'm interested in doing some internal tests before merging this. (at first sight, it LGTM)

To get accurate results I temporarily instrumented getAuthConfigsFromDockerfile but you can get a good idea from running any test which builds a multi layer image from a Dockerfile.

func getAuthConfigsFromDockerfile(c *ContainerRequest) map[string]registry.AuthConfig {
	start := time.Now()
	defer func() { fmt.Printf("getAuthConfigsFromDockerfile took: %s\n", time.Since(start)) }()

I was seeing 5 seconds to build an image which was fully cached, so I got curious and found that 90% of that time was spent in getAuthConfigsFromDockerfile with each call to GetRegistryCredentials taking 70-400ms.

In my case I had Google GCR configured so my ~/.docker/config.json contains:

{
  "_credsStore": "desktop.exe",
  "auths": {
    "https://index.docker.io/v1/": {}
  },
  "credHelpers": {
    "asia.gcr.io": "gcloud",
    "eu.gcr.io": "gcloud",
    "gcr.io": "gcloud",
    "marketplace.gcr.io": "gcloud",
    "staging-k8s.gcr.io": "gcloud",
    "us-west1-docker.pkg.dev": "gcloud",
    "us.gcr.io": "gcloud"
  },
  "credsStore": "desktop.exe",
  "experimental": "enabled"
}

Because my Dockerfile had two layers it was doing the auth lookups twice, hence the once.

Copy link
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

Ok, thanks for the explanation, it was very illustrative and I could experiment myself the issue. Indeed I'm pretty sure there are some other places were parallelisation could definitively help in performance.

LGTM, thanks!

@mdelapenya mdelapenya self-assigned this Jul 16, 2024
@mdelapenya mdelapenya added the chore Changes that do not impact the existing functionality label Jul 16, 2024
@mdelapenya mdelapenya merged commit 70856f4 into testcontainers:main Jul 16, 2024
211 checks passed
@stevenh stevenh deleted the perf/docker-auth branch July 16, 2024 10:56
@stevenh
Copy link
Collaborator Author

stevenh commented Jul 16, 2024

Ok, thanks for the explanation, it was very illustrative and I could experiment myself the issue. Indeed I'm pretty sure there are some other places were parallelisation could definitively help in performance.

LGTM, thanks!

Cool, I'll keep an eye out 😃

mdelapenya added a commit that referenced this pull request Aug 5, 2024
* main:
  feat: add grafana-lgtm module (#2660)
  Added valkey module (#2639)
  fix: container.Endpoint and wait.FortHTTP to use lowest internal port (#2641)
  chore: test cleanups (#2657)
  docs: fix compilation of examples (#2656)
  feat: add custom container registry substitutor (#2647)
  fix: couchbase containers intermittently hang on startup (#2650)
  chore(deps): bump Ryuk to 0.8.1 (#2648)
  fix: retry on label error (#2644)
  perf: optimise docker authentication config lookup (#2646)
mdelapenya pushed a commit that referenced this pull request Aug 16, 2024
Check and return errors in the process of determining authentication
configs so that unexpected failures don't occur latter in the process
of build an image or creating a container.

BuildOptions will now return an empty result on error instead of an
incomplete one, to ensure that consumers don't use partial data.

Fix builds with different config or override environments failing when
the authentication configuration changes, which was introduced by #2646.

Report errors from GetRegistryCredentials calls to avoid unexpected
failures latter on in the authentication process.

Split out the functionality to read a Dockerfile from an io.Reader into
ExtractImagesFromReader, as required when processing from a tar archive.

Deprecated function ContainerRequest.GetAuthConfigs will now panic if
an error occurs, so that callers understand that an failure occurred.

Remove unused parameter t from prepareRedisImage.

BREAKING CHANGE Add support for determining the required authentication
in when building an image from a ContextArchive, this requires ContextArchive
support io.Seeker.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore Changes that do not impact the existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants