From 2242d1ec4a6f6f9248bf7ac2fcfc761fbb1f37dc Mon Sep 17 00:00:00 2001 From: Kyle Havlovitz Date: Thu, 29 Sep 2022 00:14:15 -0700 Subject: [PATCH] Add TCP keepalive settings to proxy config for mesh gateways --- agent/xds/clusters.go | 13 ++ agent/xds/clusters_test.go | 10 ++ agent/xds/config.go | 6 + .../mesh-gateway-tcp-keepalives.latest.golden | 140 ++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index d0be284afb..91089a38a4 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -1534,6 +1534,19 @@ func (s *ResourceGenerator) makeGatewayCluster(snap *proxycfg.ConfigSnapshot, op useEDS = false } + // Set TCP keepalive settings on the upstream gateway cluster if enabled. + if opts.isRemote && cfg.TcpKeepaliveEnable { + cluster.UpstreamConnectionOptions = &envoy_cluster_v3.UpstreamConnectionOptions{ + TcpKeepalive: &envoy_core_v3.TcpKeepalive{}, + } + if cfg.TcpKeepaliveTime != 0 { + cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveTime = makeUint32Value(cfg.TcpKeepaliveTime) + } + if cfg.TcpKeepaliveInterval != 0 { + cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveInterval = makeUint32Value(cfg.TcpKeepaliveInterval) + } + } + // If none of the service instances are addressed by a hostname we provide the endpoint IP addresses via EDS if useEDS { cluster.ClusterDiscoveryType = &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_EDS} diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index 26c3731a18..22f27c8a18 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -412,6 +412,16 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotMeshGateway(t, "hash-lb-ignored", nil, nil) }, }, + { + name: "mesh-gateway-tcp-keepalives", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotMeshGateway(t, "default", func(ns *structs.NodeService) { + ns.Proxy.Config["envoy_mesh_gateway_tcp_enable_keepalive"] = true + ns.Proxy.Config["envoy_mesh_gateway_tcp_keepalive_time"] = 120 + ns.Proxy.Config["envoy_mesh_gateway_tcp_keepalive_interval"] = 60 + }, nil) + }, + }, { name: "ingress-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { diff --git a/agent/xds/config.go b/agent/xds/config.go index 8f3bc93805..288eb8d0d9 100644 --- a/agent/xds/config.go +++ b/agent/xds/config.go @@ -132,6 +132,12 @@ type GatewayConfig struct { // ConnectTimeoutMs is the number of milliseconds to timeout making a new // connection to this upstream. Defaults to 5000 (5 seconds) if not set. ConnectTimeoutMs int `mapstructure:"connect_timeout_ms"` + + // TCP keepalive settings for connections between remote mesh gateways. + // See: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#envoy-v3-api-msg-config-core-v3-tcpkeepalive + TcpKeepaliveEnable bool `mapstructure:"envoy_mesh_gateway_tcp_enable_keepalive"` + TcpKeepaliveTime int `mapstructure:"envoy_mesh_gateway_tcp_keepalive_time"` + TcpKeepaliveInterval int `mapstructure:"envoy_mesh_gateway_tcp_keepalive_interval"` } // ParseGatewayConfig returns the GatewayConfig parsed from an opaque map. If an diff --git a/agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden new file mode 100644 index 0000000000..60f7c6a016 --- /dev/null +++ b/agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden @@ -0,0 +1,140 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "upstreamConnectionOptions": { + "tcpKeepalive": { + "keepaliveTime": 120, + "keepaliveInterval": 60 + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-west-2.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, + "upstreamConnectionOptions": { + "tcpKeepalive": { + "keepaliveTime": 120, + "keepaliveInterval": 60 + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "123.us-east-1.elb.notaws.com", + "portValue": 443 + } + } + }, + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 + } + ] + } + ] + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, + "upstreamConnectionOptions": { + "tcpKeepalive": { + "keepaliveTime": 120, + "keepaliveInterval": 60 + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "outlierDetection": { + + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file