Skip to content

Commit 258bbc0

Browse files
committed
Adding TLS to memcached client
1 parent 76d6166 commit 258bbc0

File tree

7 files changed

+154
-30
lines changed

7 files changed

+154
-30
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ replace git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110
250250
// Use fork of gocql that has gokit logs and Prometheus metrics.
251251
replace github.com/gocql/gocql => github.com/grafana/gocql v0.0.0-20200605141915-ba5dc39ece85
252252

253+
replace github.com/bradfitz/gomemcache => github.com/aws-observability/gomemcache v0.0.0-20240306233126-1bbebfb3ba1c
254+
253255
// Replace memberlist with Grafana's fork which includes some fixes that haven't been merged upstream yet
254256
replace github.com/hashicorp/memberlist => github.com/grafana/memberlist v0.3.1-0.20220714140823-09ffed8adbbe
255257

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
596596
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
597597
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
598598
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
599+
github.com/aws-observability/gomemcache v0.0.0-20240306233126-1bbebfb3ba1c h1:mynlyHS6sYNrE1tw3i253/M4YHJOlTKBUdHvozOluGQ=
600+
github.com/aws-observability/gomemcache v0.0.0-20240306233126-1bbebfb3ba1c/go.mod h1:tudJZmQ+rri4slsqtM2BP7WI7eYE034wnvhkiIpO58Q=
599601
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
600602
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
601603
github.com/aws/aws-sdk-go v1.50.32 h1:POt81DvegnpQKM4DMDLlHz1CO6OBnEoQ1gRhYFd7QRY=
@@ -649,8 +651,6 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
649651
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
650652
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
651653
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
652-
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
653-
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
654654
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
655655
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
656656
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=

pkg/chunk/cache/memcached_client.go

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/prometheus/client_golang/prometheus/promauto"
1919
"github.com/sony/gobreaker"
2020
"github.com/thanos-io/thanos/pkg/discovery/dns"
21+
"github.com/thanos-io/thanos/pkg/tls"
2122

2223
util_log "github.com/cortexproject/cortex/pkg/util/log"
2324
)
@@ -65,17 +66,23 @@ type memcachedClient struct {
6566

6667
// MemcachedClientConfig defines how a MemcachedClient should be constructed.
6768
type MemcachedClientConfig struct {
68-
Host string `yaml:"host"`
69-
Service string `yaml:"service"`
70-
Addresses string `yaml:"addresses"` // EXPERIMENTAL.
71-
Timeout time.Duration `yaml:"timeout"`
72-
MaxIdleConns int `yaml:"max_idle_conns"`
73-
MaxItemSize int `yaml:"max_item_size"`
74-
UpdateInterval time.Duration `yaml:"update_interval"`
75-
ConsistentHash bool `yaml:"consistent_hash"`
76-
CBFailures uint `yaml:"circuit_breaker_consecutive_failures"`
77-
CBTimeout time.Duration `yaml:"circuit_breaker_timeout"` // reset error count after this long
78-
CBInterval time.Duration `yaml:"circuit_breaker_interval"` // remain closed for this long after CBFailures errors
69+
Host string `yaml:"host"`
70+
Service string `yaml:"service"`
71+
Addresses string `yaml:"addresses"` // EXPERIMENTAL.
72+
Timeout time.Duration `yaml:"timeout"`
73+
MaxIdleConns int `yaml:"max_idle_conns"`
74+
MaxItemSize int `yaml:"max_item_size"`
75+
UpdateInterval time.Duration `yaml:"update_interval"`
76+
ConsistentHash bool `yaml:"consistent_hash"`
77+
CBFailures uint `yaml:"circuit_breaker_consecutive_failures"`
78+
CBTimeout time.Duration `yaml:"circuit_breaker_timeout"` // reset error count after this long
79+
CBInterval time.Duration `yaml:"circuit_breaker_interval"` // remain closed for this long after CBFailures errors
80+
TLSEnabled bool `yaml:"tls_enabled"`
81+
TLSCertPath string `yaml:"tls_cert_path"`
82+
TLSKeyPath string `yaml:"tls_key_path"`
83+
TLSCAPath string `yaml:"tls_ca_path"`
84+
TLSServerName string `yaml:"tls_ca_name"`
85+
TLSInsecureSkipVerify bool `yaml:"tls_insecure_skip_verify"`
7986
}
8087

8188
// RegisterFlagsWithPrefix adds the flags required to config this to the given FlagSet
@@ -91,6 +98,12 @@ func (cfg *MemcachedClientConfig) RegisterFlagsWithPrefix(prefix, description st
9198
f.DurationVar(&cfg.CBTimeout, prefix+"memcached.circuit-breaker-timeout", 10*time.Second, description+"Duration circuit-breaker remains open after tripping (if zero then 60 seconds is used).")
9299
f.DurationVar(&cfg.CBInterval, prefix+"memcached.circuit-breaker-interval", 10*time.Second, description+"Reset circuit-breaker counts after this long (if zero then never reset).")
93100
f.IntVar(&cfg.MaxItemSize, prefix+"memcached.max-item-size", 0, description+"The maximum size of an item stored in memcached. Bigger items are not stored. If set to 0, no maximum size is enforced.")
101+
f.BoolVar(&cfg.TLSEnabled, prefix+"tls-enabled", false, "Enable TLS in the memcached client. This flag needs to be enabled when any other TLS flag is set. If set to false, insecure connection to memcached server will be used.")
102+
f.StringVar(&cfg.TLSCertPath, prefix+"tls-cert-path", "", "Path to the client certificate file, which will be used for authenticating with the server. Also requires the key path to be configured.")
103+
f.StringVar(&cfg.TLSKeyPath, prefix+"tls-key-path", "", "Path to the key file for the client certificate. Also requires the client certificate to be configured.")
104+
f.StringVar(&cfg.TLSCAPath, prefix+"tls-ca-path", "", "Path to the CA certificates file to validate server certificate against. If not set, the host's root CA certificates are used.")
105+
f.StringVar(&cfg.TLSServerName, prefix+"tls-server-name", "", "Override the expected name on the server certificate.")
106+
f.BoolVar(&cfg.TLSInsecureSkipVerify, prefix+"tls-insecure-skip-verify", false, "Skip validating server certificate.")
94107
}
95108

96109
// NewMemcachedClient creates a new MemcacheClient that gets its server list
@@ -103,7 +116,14 @@ func NewMemcachedClient(cfg MemcachedClientConfig, name string, r prometheus.Reg
103116
selector = &memcache.ServerList{}
104117
}
105118

106-
client := memcache.NewFromSelector(selector)
119+
var client *memcache.Client
120+
if cfg.TLSEnabled {
121+
tlsConfig, _ := tls.NewClientConfig(logger, cfg.TLSCertPath, cfg.TLSKeyPath, cfg.TLSCAPath, cfg.TLSServerName, cfg.TLSInsecureSkipVerify)
122+
client = memcache.NewWithTLSFromSelector(tlsConfig, selector)
123+
} else {
124+
client = memcache.NewFromSelector(selector)
125+
}
126+
107127
client.Timeout = cfg.Timeout
108128
client.MaxIdleConns = cfg.MaxIdleConns
109129

@@ -141,7 +161,7 @@ func NewMemcachedClient(cfg MemcachedClientConfig, name string, r prometheus.Reg
141161
}),
142162
}
143163
if cfg.CBFailures > 0 {
144-
newClient.Client.DialContext = newClient.dialViaCircuitBreaker
164+
newClient.Client.DialTimeout = newClient.dialViaCircuitBreaker
145165
}
146166

147167
if len(cfg.Addresses) > 0 {
@@ -163,7 +183,7 @@ func (c *memcachedClient) circuitBreakerStateChange(name string, from gobreaker.
163183
level.Info(c.logger).Log("msg", "circuit-breaker state change", "name", name, "from-state", from, "to-state", to)
164184
}
165185

166-
func (c *memcachedClient) dialViaCircuitBreaker(_ context.Context, network, address string) (net.Conn, error) {
186+
func (c *memcachedClient) dialViaCircuitBreaker(network, address string, timeout time.Duration) (net.Conn, error) {
167187
c.Lock()
168188
cb := c.cbs[address]
169189
if cb == nil {
@@ -181,7 +201,7 @@ func (c *memcachedClient) dialViaCircuitBreaker(_ context.Context, network, addr
181201
c.Unlock()
182202

183203
conn, err := cb.Execute(func() (interface{}, error) {
184-
return net.DialTimeout(network, address, c.cbTimeout)
204+
return net.DialTimeout(network, address, timeout)
185205
})
186206
if err != nil {
187207
return nil, err

pkg/storage/tsdb/memcache_client_config.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@ type MemcachedClientConfig struct {
1717
MaxAsyncBufferSize int `yaml:"max_async_buffer_size"`
1818
MaxGetMultiConcurrency int `yaml:"max_get_multi_concurrency"`
1919
MaxGetMultiBatchSize int `yaml:"max_get_multi_batch_size"`
20-
MaxItemSize int `yaml:"max_item_size"`
21-
AutoDiscovery bool `yaml:"auto_discovery"`
2220
SetAsyncCircuitBreaker CircuitBreakerConfig `yaml:"set_async_circuit_breaker_config"`
21+
22+
MaxItemSize int `yaml:"max_item_size"`
23+
AutoDiscovery bool `yaml:"auto_discovery"`
24+
TLSEnabled bool `yaml:"tls_enabled"`
25+
TLSCertPath string `yaml:"tls_cert_path"`
26+
TLSKeyPath string `yaml:"tls_key_path"`
27+
TLSCAPath string `yaml:"tls_ca_path"`
28+
TLSServerName string `yaml:"tls_ca_name"`
29+
TLSInsecureSkipVerify bool `yaml:"tls_insecure_skip_verify"`
2330
}
2431

2532
func (cfg *MemcachedClientConfig) RegisterFlagsWithPrefix(f *flag.FlagSet, prefix string) {
@@ -33,6 +40,12 @@ func (cfg *MemcachedClientConfig) RegisterFlagsWithPrefix(f *flag.FlagSet, prefi
3340
f.IntVar(&cfg.MaxItemSize, prefix+"max-item-size", 1024*1024, "The maximum size of an item stored in memcached. Bigger items are not stored. If set to 0, no maximum size is enforced.")
3441
f.BoolVar(&cfg.AutoDiscovery, prefix+"auto-discovery", false, "Use memcached auto-discovery mechanism provided by some cloud provider like GCP and AWS")
3542
cfg.SetAsyncCircuitBreaker.RegisterFlagsWithPrefix(f, prefix+"set-async.")
43+
f.BoolVar(&cfg.TLSEnabled, prefix+"tls-enabled", false, "Enable TLS in the memcached client. This flag needs to be enabled when any other TLS flag is set. If set to false, insecure connection to memcached server will be used.")
44+
f.StringVar(&cfg.TLSCertPath, prefix+"tls-cert-path", "", "Path to the client certificate file, which will be used for authenticating with the server. Also requires the key path to be configured.")
45+
f.StringVar(&cfg.TLSKeyPath, prefix+"tls-key-path", "", "Path to the key file for the client certificate. Also requires the client certificate to be configured.")
46+
f.StringVar(&cfg.TLSCAPath, prefix+"tls-ca-path", "", "Path to the CA certificates file to validate server certificate against. If not set, the host's root CA certificates are used.")
47+
f.StringVar(&cfg.TLSServerName, prefix+"tls-server-name", "", "Override the expected name on the server certificate.")
48+
f.BoolVar(&cfg.TLSInsecureSkipVerify, prefix+"tls-insecure-skip-verify", false, "Skip validating server certificate.")
3649
}
3750

3851
func (cfg *MemcachedClientConfig) GetAddresses() []string {
@@ -72,5 +85,11 @@ func (cfg MemcachedClientConfig) ToMemcachedClientConfig() cacheutil.MemcachedCl
7285
ConsecutiveFailures: uint32(cfg.SetAsyncCircuitBreaker.ConsecutiveFailures),
7386
FailurePercent: cfg.SetAsyncCircuitBreaker.FailurePercent,
7487
},
88+
TlsEnabled: cfg.TLSEnabled,
89+
TLSCertPath: cfg.TLSCertPath,
90+
TLSKeyPath: cfg.TLSKeyPath,
91+
TLSCAPath: cfg.TLSCAPath,
92+
TLSServerName: cfg.TLSServerName,
93+
TLSInsecureSkipVerify: cfg.TLSInsecureSkipVerify,
7594
}
7695
}

vendor/github.com/bradfitz/gomemcache/memcache/memcache.go

Lines changed: 50 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/thanos-io/thanos/pkg/cacheutil/memcached_client.go

Lines changed: 41 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/modules.txt

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)