connect: allow overriding envoy listener bind_address (#6033)

* connect: allow overriding envoy listener bind_address

* Update agent/xds/config.go

Co-Authored-By: Kyle Havlovitz <kylehav@gmail.com>

* connect: allow overriding envoy listener bind_port

* envoy: support unix sockets for grpc in bootstrap

Add AgentSocket BootstrapTplArgs which if set overrides the AgentAddress
and AgentPort to generate a bootstrap which points Envoy to a unix
socket file instead of an ip:port.

* Add a test for passing the consul addr as a unix socket

* Fix config formatting for envoy bootstrap tests

* Fix listeners test cases for bind addr/port

* Update website/source/docs/connect/proxies/envoy.md
pull/6081/head
Michael Schurter 2019-07-05 08:06:47 -07:00 committed by Paul Banks
parent dcb9800442
commit b5aab27c21
24 changed files with 573 additions and 72 deletions

View File

@ -29,10 +29,20 @@ type ProxyConfig struct {
LocalConnectTimeoutMs int `mapstructure:"local_connect_timeout_ms"` LocalConnectTimeoutMs int `mapstructure:"local_connect_timeout_ms"`
// Protocol describes the service's protocol. Valid values are "tcp", // Protocol describes the service's protocol. Valid values are "tcp",
// "http" and "grpc". Anything else is treated as tcp. The enables protocol // "http" and "grpc". Anything else is treated as tcp. This enables
// aware features like per-request metrics and connection pooling, tracing, // protocol aware features like per-request metrics and connection
// routing etc. // pooling, tracing, routing etc.
Protocol string `mapstructure:"protocol"` Protocol string `mapstructure:"protocol"`
// BindAddress overrides the address the proxy's listener binds to. This
// enables proxies in network namespaces to bind to a different address
// than the host address.
BindAddress string `mapstructure:"bind_address"`
// BindPort overrides the port the proxy's listener binds to. This
// enable proxies in network namespaces to bind to a different port
// than the host port being advertised.
BindPort int `mapstructure:"bind_port"`
} }
// ParseProxyConfig returns the ProxyConfig parsed from the an opaque map. If an // ParseProxyConfig returns the ProxyConfig parsed from the an opaque map. If an

View File

@ -59,6 +59,39 @@ func TestParseProxyConfig(t *testing.T) {
LocalConnectTimeoutMs: 5000, LocalConnectTimeoutMs: 5000,
}, },
}, },
{
name: "bind address override, string",
input: map[string]interface{}{
"bind_address": "127.0.0.2",
},
want: ProxyConfig{
LocalConnectTimeoutMs: 5000,
Protocol: "tcp",
BindAddress: "127.0.0.2",
},
},
{
name: "bind port override, string",
input: map[string]interface{}{
"bind_port": "8888",
},
want: ProxyConfig{
LocalConnectTimeoutMs: 5000,
Protocol: "tcp",
BindPort: 8888,
},
},
{
name: "bind port override, int",
input: map[string]interface{}{
"bind_port": 8889,
},
want: ProxyConfig{
LocalConnectTimeoutMs: 5000,
Protocol: "tcp",
BindPort: 8889,
},
},
{ {
name: "local connect timeout override, string", name: "local connect timeout override, string",
input: map[string]interface{}{ input: map[string]interface{}{

View File

@ -234,10 +234,23 @@ func (s *Server) makePublicListener(cfgSnap *proxycfg.ConfigSnapshot, token stri
if l == nil { if l == nil {
// No user config, use default listener // No user config, use default listener
addr := cfgSnap.Address addr := cfgSnap.Address
if addr == "" {
// Override with bind address if one is set, otherwise default
// to 0.0.0.0
if cfg.BindAddress != "" {
addr = cfg.BindAddress
} else if addr == "" {
addr = "0.0.0.0" addr = "0.0.0.0"
} }
l = makeListener(PublicListenerName, addr, cfgSnap.Port)
// Override with bind port if one is set, otherwise default to
// proxy service's address
port := cfgSnap.Port
if cfg.BindPort != 0 {
port = cfg.BindPort
}
l = makeListener(PublicListenerName, addr, port)
filter, err := makeListenerFilter(false, cfg.Protocol, "public_listener", LocalAppClusterName, "", true) filter, err := makeListenerFilter(false, cfg.Protocol, "public_listener", LocalAppClusterName, "", true)
if err != nil { if err != nil {

View File

@ -33,6 +33,28 @@ func TestListenersFromSnapshot(t *testing.T) {
create: proxycfg.TestConfigSnapshot, create: proxycfg.TestConfigSnapshot,
setup: nil, // Default snapshot setup: nil, // Default snapshot
}, },
{
name: "listener-bind-address",
create: proxycfg.TestConfigSnapshot,
setup: func(snap *proxycfg.ConfigSnapshot) {
snap.Proxy.Config["bind_address"] = "127.0.0.2"
},
},
{
name: "listener-bind-port",
create: proxycfg.TestConfigSnapshot,
setup: func(snap *proxycfg.ConfigSnapshot) {
snap.Proxy.Config["bind_port"] = 8888
},
},
{
name: "listener-bind-address-port",
create: proxycfg.TestConfigSnapshot,
setup: func(snap *proxycfg.ConfigSnapshot) {
snap.Proxy.Config["bind_address"] = "127.0.0.2"
snap.Proxy.Config["bind_port"] = 8888
},
},
{ {
name: "http-public-listener", name: "http-public-listener",
create: proxycfg.TestConfigSnapshot, create: proxycfg.TestConfigSnapshot,

View File

@ -0,0 +1,116 @@
{
"versionInfo": "00000001",
"resources": [
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "db:127.0.0.1:9191",
"address": {
"socketAddress": {
"address": "127.0.0.1",
"portValue": 9191
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "db",
"stat_prefix": "upstream_db_tcp"
}
}
]
}
]
},
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "prepared_query:geo-cache:127.10.10.10:8181",
"address": {
"socketAddress": {
"address": "127.10.10.10",
"portValue": 8181
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "prepared_query:geo-cache",
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
}
}
]
}
]
},
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "public_listener:127.0.0.2:8888",
"address": {
"socketAddress": {
"address": "127.0.0.2",
"portValue": 8888
}
},
"filterChains": [
{
"tlsContext": {
"commonTlsContext": {
"tlsParams": {
},
"tlsCertificates": [
{
"certificateChain": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
},
"privateKey": {
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
}
}
],
"validationContext": {
"trustedCa": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
}
}
},
"requireClientCertificate": true
},
"filters": [
{
"name": "envoy.ext_authz",
"config": {
"grpc_service": {
"envoy_grpc": {
"cluster_name": "local_agent"
},
"initial_metadata": [
{
"key": "x-consul-token",
"value": "my-token"
}
]
},
"stat_prefix": "connect_authz"
}
},
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "local_app",
"stat_prefix": "public_listener_tcp"
}
}
]
}
]
}
],
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
"nonce": "00000001"
}

View File

@ -0,0 +1,116 @@
{
"versionInfo": "00000001",
"resources": [
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "db:127.0.0.1:9191",
"address": {
"socketAddress": {
"address": "127.0.0.1",
"portValue": 9191
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "db",
"stat_prefix": "upstream_db_tcp"
}
}
]
}
]
},
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "prepared_query:geo-cache:127.10.10.10:8181",
"address": {
"socketAddress": {
"address": "127.10.10.10",
"portValue": 8181
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "prepared_query:geo-cache",
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
}
}
]
}
]
},
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "public_listener:127.0.0.2:9999",
"address": {
"socketAddress": {
"address": "127.0.0.2",
"portValue": 9999
}
},
"filterChains": [
{
"tlsContext": {
"commonTlsContext": {
"tlsParams": {
},
"tlsCertificates": [
{
"certificateChain": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
},
"privateKey": {
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
}
}
],
"validationContext": {
"trustedCa": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
}
}
},
"requireClientCertificate": true
},
"filters": [
{
"name": "envoy.ext_authz",
"config": {
"grpc_service": {
"envoy_grpc": {
"cluster_name": "local_agent"
},
"initial_metadata": [
{
"key": "x-consul-token",
"value": "my-token"
}
]
},
"stat_prefix": "connect_authz"
}
},
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "local_app",
"stat_prefix": "public_listener_tcp"
}
}
]
}
]
}
],
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
"nonce": "00000001"
}

View File

@ -0,0 +1,116 @@
{
"versionInfo": "00000001",
"resources": [
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "db:127.0.0.1:9191",
"address": {
"socketAddress": {
"address": "127.0.0.1",
"portValue": 9191
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "db",
"stat_prefix": "upstream_db_tcp"
}
}
]
}
]
},
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "prepared_query:geo-cache:127.10.10.10:8181",
"address": {
"socketAddress": {
"address": "127.10.10.10",
"portValue": 8181
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "prepared_query:geo-cache",
"stat_prefix": "upstream_prepared_query_geo-cache_tcp"
}
}
]
}
]
},
{
"@type": "type.googleapis.com/envoy.api.v2.Listener",
"name": "public_listener:0.0.0.0:8888",
"address": {
"socketAddress": {
"address": "0.0.0.0",
"portValue": 8888
}
},
"filterChains": [
{
"tlsContext": {
"commonTlsContext": {
"tlsParams": {
},
"tlsCertificates": [
{
"certificateChain": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
},
"privateKey": {
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
}
}
],
"validationContext": {
"trustedCa": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
}
}
},
"requireClientCertificate": true
},
"filters": [
{
"name": "envoy.ext_authz",
"config": {
"grpc_service": {
"envoy_grpc": {
"cluster_name": "local_agent"
},
"initial_metadata": [
{
"key": "x-consul-token",
"value": "my-token"
}
]
},
"stat_prefix": "connect_authz"
}
},
{
"name": "envoy.tcp_proxy",
"config": {
"cluster": "local_app",
"stat_prefix": "public_listener_tcp"
}
}
]
}
]
}
],
"typeUrl": "type.googleapis.com/envoy.api.v2.Listener",
"nonce": "00000001"
}

View File

@ -27,6 +27,11 @@ type BootstrapTplArgs struct {
// TLS is enabled. // TLS is enabled.
AgentCAFile string AgentCAFile string
// AgentSocket is the path to a Unix Socket for communicating with the
// local agent's gRPC endpoint. Disabled if the empty (the default),
// but overrides AgentAddress and AgentPort if set.
AgentSocket string
// AdminAccessLogPath The path to write the access log for the // AdminAccessLogPath The path to write the access log for the
// administration server. If no access log is desired specify // administration server. If no access log is desired specify
// "/dev/null". By default it will use "/dev/null". // "/dev/null". By default it will use "/dev/null".
@ -122,12 +127,20 @@ const bootstrapTemplate = `{
{{- end }} {{- end }}
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [
{{- if .AgentSocket -}}
{
"pipe": {
"path": "{{ .AgentSocket }}"
}
}
{{- else -}}
{ {
"socket_address": { "socket_address": {
"address": "{{ .AgentAddress }}", "address": "{{ .AgentAddress }}",
"port_value": {{ .AgentPort }} "port_value": {{ .AgentPort }}
} }
} }
{{- end -}}
] ]
} }
{{- if .StaticClustersJSON -}} {{- if .StaticClustersJSON -}}

View File

@ -360,10 +360,17 @@ func (c *cmd) templateArgs() (*BootstrapTplArgs, error) {
// is an IP this will fail to parse as a URL with "parse 127.0.0.1:8500: first // is an IP this will fail to parse as a URL with "parse 127.0.0.1:8500: first
// path segment in URL cannot contain colon". On the other hand we also // path segment in URL cannot contain colon". On the other hand we also
// support both http(s)://host:port and unix:///path/to/file. // support both http(s)://host:port and unix:///path/to/file.
addrPort := strings.TrimPrefix(c.grpcAddr, "http://") var agentAddr, agentPort, agentSock string
addrPort = strings.TrimPrefix(c.grpcAddr, "https://") if grpcAddr := strings.TrimPrefix(c.grpcAddr, "unix://"); grpcAddr != c.grpcAddr {
// Path to unix socket
agentSock = grpcAddr
} else {
// Parse as host:port with option http prefix
grpcAddr = strings.TrimPrefix(c.grpcAddr, "http://")
grpcAddr = strings.TrimPrefix(c.grpcAddr, "https://")
agentAddr, agentPort, err := net.SplitHostPort(addrPort) var err error
agentAddr, agentPort, err = net.SplitHostPort(grpcAddr)
if err != nil { if err != nil {
return nil, fmt.Errorf("Invalid Consul HTTP address: %s", err) return nil, fmt.Errorf("Invalid Consul HTTP address: %s", err)
} }
@ -381,6 +388,8 @@ func (c *cmd) templateArgs() (*BootstrapTplArgs, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to resolve agent address: %s", err) return nil, fmt.Errorf("Failed to resolve agent address: %s", err)
} }
agentAddr = agentIP.String()
}
adminAddr, adminPort, err := net.SplitHostPort(c.adminBind) adminAddr, adminPort, err := net.SplitHostPort(c.adminBind)
if err != nil { if err != nil {
@ -414,8 +423,9 @@ func (c *cmd) templateArgs() (*BootstrapTplArgs, error) {
return &BootstrapTplArgs{ return &BootstrapTplArgs{
ProxyCluster: cluster, ProxyCluster: cluster,
ProxyID: c.proxyID, ProxyID: c.proxyID,
AgentAddress: agentIP.String(), AgentAddress: agentAddr,
AgentPort: agentPort, AgentPort: agentPort,
AgentSocket: agentSock,
AgentTLS: useTLS, AgentTLS: useTLS,
AgentCAFile: httpCfg.TLSConfig.CAFile, AgentCAFile: httpCfg.TLSConfig.CAFile,
AdminAccessLogPath: adminAccessLogPath, AdminAccessLogPath: adminAccessLogPath,

View File

@ -206,6 +206,21 @@ func TestGenerateConfig(t *testing.T) {
LocalAgentClusterName: xds.LocalAgentClusterName, LocalAgentClusterName: xds.LocalAgentClusterName,
}, },
}, },
{
Name: "grpc-addr-unix",
Flags: []string{"-proxy-id", "test-proxy",
"-grpc-addr", "unix:///var/run/consul.sock"},
Env: []string{},
WantArgs: BootstrapTplArgs{
ProxyCluster: "test-proxy",
ProxyID: "test-proxy",
AgentSocket: "/var/run/consul.sock",
AdminAccessLogPath: "/dev/null",
AdminBindAddress: "127.0.0.1",
AdminBindPort: "19000",
LocalAgentClusterName: xds.LocalAgentClusterName,
},
},
{ {
Name: "access-log-path", Name: "access-log-path",
Flags: []string{"-proxy-id", "test-proxy", "-admin-access-log-path", "/some/path/access.log"}, Flags: []string{"-proxy-id", "test-proxy", "-admin-access-log-path", "/some/path/access.log"},

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
}, },
{ {

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
}, },
{ {

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 9999 "port_value": 9999
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 9999 "port_value": 9999
} }
} }]
]
} }
] ]
}, },

View File

@ -0,0 +1,57 @@
{
"admin": {
"access_log_path": "/dev/null",
"address": {
"socket_address": {
"address": "127.0.0.1",
"port_value": 19000
}
}
},
"node": {
"cluster": "test-proxy",
"id": "test-proxy"
},
"static_resources": {
"clusters": [
{
"name": "local_agent",
"connect_timeout": "1s",
"type": "STATIC",
"http2_protocol_options": {},
"hosts": [{
"pipe": {
"path": "/var/run/consul.sock"
}
}]
}
]
},
"stats_config": {
"stats_tags": [
{
"tag_name": "local_cluster",
"fixed_value": "test-proxy"
}
],
"use_all_default_tags": true
},
"dynamic_resources": {
"lds_config": { "ads": {} },
"cds_config": { "ads": {} },
"ads_config": {
"api_type": "GRPC",
"grpc_services": {
"initial_metadata": [
{
"key": "x-consul-token",
"value": ""
}
],
"envoy_grpc": {
"cluster_name": "local_agent"
}
}
}
}
}

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
} }
] ]
}, },

View File

@ -19,14 +19,12 @@
"connect_timeout": "1s", "connect_timeout": "1s",
"type": "STATIC", "type": "STATIC",
"http2_protocol_options": {}, "http2_protocol_options": {},
"hosts": [ "hosts": [{
{
"socket_address": { "socket_address": {
"address": "127.0.0.1", "address": "127.0.0.1",
"port_value": 8502 "port_value": 8502
} }
} }]
]
}, },
{ {
"name": "zipkin", "name": "zipkin",

View File

@ -196,6 +196,10 @@ defaults that are inherited by all services.
filter](https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/http_filters/grpc_http1_bridge_filter#config-http-filters-grpc-bridge) filter](https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/http_filters/grpc_http1_bridge_filter#config-http-filters-grpc-bridge)
that translates HTTP/1.1 calls into gRPC, and instruments that translates HTTP/1.1 calls into gRPC, and instruments
metrics with `gRPC-status` trailer codes. metrics with `gRPC-status` trailer codes.
- `bind_address` - Override the address Envoy's public listener binds to. By
default Envoy will bind to the service address or 0.0.0.0 if there is not explicit address on the service registration.
- `bind_port` - Override the port Envoy's public listener binds to. By default
Envoy will bind to the service port.
- `local_connect_timeout_ms` - The number of milliseconds allowed to make - `local_connect_timeout_ms` - The number of milliseconds allowed to make
connections to the local application instance before timing out. Defaults to 5000 connections to the local application instance before timing out. Defaults to 5000
(5 seconds). (5 seconds).