Cache parsed credential bundles in credbundle loaders#537
Open
botengyao wants to merge 1 commit into
Open
Conversation
Loader and ClientLoader re-read and re-parsed the credential bundle file on every TLS handshake so that pod-certificate rotations are picked up. The caching TODO dates back to the package's introduction, and since mTLS was established between all ate system components (agent-substrate#237), every inter-component handshake pays that cost: ~125us and ~120 allocations per handshake for an RSA bundle. Resolve the TODO by caching the parsed bundle behind a stat check: - Each handshake stats the bundle and serves the cached parse while file identity (os.SameFile: device and inode), mtime, and size all match the stat recorded at parse time. Any mismatch triggers a re-read and re-parse. - The kubelet rotates projected volume contents, including pod certificates, by writing a fresh timestamped directory and atomically swapping a symlink, so a rotation always changes file identity and is picked up on the next handshake. mtime and size additionally cover in-place rewrites. There is no TTL: freshness is derived from the file, never from time, and an unchanged bundle is never re-parsed. - Errors leave the previous entry in place and are returned to the caller, so failure behavior is unchanged from the uncached code, and later handshakes keep retrying until a parse succeeds. The cached path costs ~1us and 2 allocations per handshake, ~125x less than the uncached parse it replaces: BenchmarkLoaderCached-18 2421314 1001 ns/op 304 B/op 2 allocs/op BenchmarkParseUncached-18 19284 124843 ns/op 19544 B/op 120 allocs/op Parse remains exported and uncached, and the Loader/ClientLoader signatures are unchanged, so no call sites move.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves the
TODO: Introduce caching.oncredbundle.Loader/credbundle.ClientLoader. The TODO dates back to the package's introduction; since #237 established mTLS between all ate system components, every inter-component handshake is on this path.Problem
Loader/ClientLoaderre-read and re-parse the credential bundle from disk on every TLS handshake so that pod-certificate rotations get picked up. That costs ~125µs and ~120 allocations per handshake (RSA bundle) for a file that almost never changes.Approach: stat-validated cache
Each loader keeps the last successful parse together with the
os.FileInfotaken just before that parse. A handshake stats the file (~1µs) and serves the cached certificate while file identity (os.SameFile, i.e. device+inode on Unix), mtime, and size all match; any mismatch re-reads and re-parses.Invalidation and eviction:
tls.Config), replaced on rotation — nothing unbounded to evict.Benchmarks
Apple M5 Pro, RSA-2048 bundle:
BenchmarkLoaderCachedBenchmarkParseUncachedParsestays exported and uncached;Loader/ClientLoadersignatures are unchanged, so no call sites move.go test ./internal/credbundle/ -race: cache-hit proof via unchanged-stat corruption, atomic-rename rotation, in-place rewrite, missing-file error, error recovery, concurrent handshakes under the race detector)Loader/ClientLoader/certCachedescribe the caching, rotation, and failure semantics)