Skip to content

Commit

Permalink
Fix memory leak
Browse files Browse the repository at this point in the history
We were leaking memory steadily in
`golang.org/x/net/http2.(*ClientConn).frameScratchBuffer` every time we
retrieved a new set of credentials.

I believe this is because we were never closing the response body when we were
retrieving a lease from vault. From my testing, it seems that the rate at which
memory was leaking was also exacerbated by the fact that we were creating a new
`*vault.Config` every time we retrieved credentials from vault. Presumably this
was because we were creating a new pool of connections (and therefore a new set
of scratch buffers) for each config, although I haven't fully validated this hypothesis.

See: golang/go#38049.

Ensuring that the response body is closed after decoding the json from it and
using one `*vault.Config` seems to stop the leak.

I've also added the UW operational endpoint so that we can profile these issues
live in future.
  • Loading branch information
ribbybibby committed May 5, 2020
1 parent 2d19ad9 commit 81b38fd
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 11 deletions.
22 changes: 13 additions & 9 deletions credentials.go
Expand Up @@ -35,14 +35,21 @@ type CredentialsRenewer struct {
KubePath string
KubeRole string
TokenPath string
VaultConfig *vault.Config
}

// Start the renewer
func (cr *CredentialsRenewer) Start() {
// Create Vault client
client, err := vault.NewClient(cr.VaultConfig)
if err != nil {
cr.Errors <- err
return
}

for {
// Create Vault client
client, err := vault.NewClient(vault.DefaultConfig())
if err != nil {
// Reload vault configuration from the environment
if err := cr.VaultConfig.ReadEnvironment(); err != nil {
cr.Errors <- err
return
}
Expand Down Expand Up @@ -83,16 +90,13 @@ func (cr *CredentialsRenewer) Start() {
return
}
resp, err := client.RawRequest(req)
if err == nil {
defer func() {
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
}()
} else {
if err != nil {
cr.Errors <- err
return
}
err = json.NewDecoder(resp.Body).Decode(&l)
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
if err != nil {
cr.Errors <- err
return
Expand Down
19 changes: 18 additions & 1 deletion go.mod
Expand Up @@ -2,4 +2,21 @@ module github.com/utilitywarehouse/vault-kube-aws-credentials

go 1.13

require github.com/hashicorp/vault/api v1.0.4
require (
github.com/frankban/quicktest v1.9.0 // indirect
github.com/golang/protobuf v1.4.1 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/vault/api v1.0.4
github.com/mitchellh/mapstructure v1.3.0 // indirect
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
github.com/prometheus/client_golang v1.6.0 // indirect
github.com/utilitywarehouse/go-operational v0.0.0-20190722153447-b0f3f6284543
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 // indirect
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c // indirect
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
)

0 comments on commit 81b38fd

Please sign in to comment.