Register a Service Mesh Proxy Outside of a Service Registration

This topic describes how to declare a service mesh proxy in a service definition. The kind must be declared and information about the service they represent must be provided to function as a Consul service mesh proxy.

Configuration

Configure a service mesh proxy using the following syntax:

Basic syntax for configuring a service mesh proxy

Basic syntax for configuring a service mesh proxy

  1. name = <name of the service>
  2. kind = "connect-proxy"
  3. proxy = {
  4. destination_service_name = "<name of the service that the proxy represents>"
  5. <additional proxy parameters> = "<additional parameter values>"
  6. }
  7. port = <port where services can discover and connect to proxied services>
  1. {
  2. "name": "<name of the service>",
  3. "kind": "connect-proxy",
  4. "proxy": {
  5. "destination_service_name": "<name of the service that the proxy represents>",
  6. "<additional proxy parameters>" : "<additional parameter values>"
  7. },
  8. "port": <port where services can discover and connect to proxied services>
  9. }

The following table describes the parameters that must be added to the service definition to declare the service as a proxy.

ParameterDescriptionRequiredDefault
kindString value that declares the type for the service. This should always be set to connect-proxy to declare the services as a service mesh proxy.RequiredNone
proxyObject that contains the proxies parameters.
The destination_service_name parameter must be included in the proxy configuration. The destination_service_name parameter specifies the name of the services that the proxy represents.
This parameter replaces proxy_destination used in Consul 1.2.0 to 1.3.0. The proxy_destination parameter was deprecated in 1.5.0.
RequiredNone
portInteger value that specifies the port where other services in the mesh can discover and connect to proxied services.RequiredNone
addressSpecifies the IP address of the proxy.Optional
The address will be inherited from the node configuration.
address specified in the node configuration.

You can specify several additional parameters to configure the proxy to meet your requirements. See Proxy Parameters for additional information.

Example

In the following example, a proxy named redis-proxy is registered as a service mesh proxy. It proxies to the redis service and is available at port 8181. As a result, any service mesh clients searching for a mesh-capable endpoint for redis will find this proxy.

Minimal example of a service mesh proxy

Minimal example of a service mesh proxy

  1. kind = "connect-proxy"
  2. name = "redis-proxy"
  3. port = 8181
  4. proxy = {
  5. destination_service_name = "redis"
  6. }
  1. {
  2. "name": "redis-proxy",
  3. "kind": "connect-proxy",
  4. "proxy": {
  5. "destination_service_name": "redis"
  6. },
  7. "port": 8181
  8. }

Sidecar Proxy Configuration

Many service mesh proxies are deployed as sidecars. Sidecar proxies are co-located with the single service instance they represent and proxy all inbound traffic to.

Specify the following parameters in the proxy code block to configure a sidecar proxy in its own service registration:

See Sidecar Service Registration for additional information about configuring service mesh proxies as sidecars.

Complete Configuration Example

The following example includes values for all available options when registering a proxy instance.

Example that includes all configuration options when registering a proxy instance

Example that includes all configuration options when registering a proxy instance

  1. kind = "connect-proxy"
  2. name = "redis-proxy"
  3. port = 8181
  4. proxy = {
  5. config = {}
  6. destination_service_id = "redis1"
  7. destination_service_name = "redis"
  8. expose = {}
  9. local_service_address = "127.0.0.1"
  10. local_service_port = 9090
  11. local_service_socket_path = "/tmp/redis.sock"
  12. mesh_gateway = {}
  13. mode = "transparent"
  14. transparent_proxy = {}
  15. upstreams = []
  16. }
  1. {
  2. "name": "redis-proxy",
  3. "kind": "connect-proxy",
  4. "proxy": {
  5. "destination_service_name": "redis",
  6. "destination_service_id": "redis1",
  7. "local_service_address": "127.0.0.1",
  8. "local_service_port": 9090,
  9. "local_service_socket_path": "/tmp/redis.sock",
  10. "mode": "transparent",
  11. "transparent_proxy": {},
  12. "config": {},
  13. "upstreams": [],
  14. "mesh_gateway": {},
  15. "expose": {}
  16. },
  17. "port": 8181
  18. }

Proxy Parameters

The following table describes all parameters that can be defined in the proxy block.

ParameterDescriptionRequiredDefault
destination_service_idString value that specifies the ID of a single service instance represented by the proxy.
This parameter is only applicable for sidecar proxies that run on the same node as the service.
Consul checks for the proxied service on the same agent.
The ID is unique and may differ from its name value.
Specifying this parameter helps tools identify which sidecar proxy instances are associated with which application instance, as well as enable fine-grained analysis of the metrics coming from the proxy.
Required when registering proxy as a sidecarNone
local_service_portInteger value that specifies the port that a sidecar proxy should use to connect to the local service instance.Required when registering proxy as a sidecarPort advertised by the service instance configured in destination_service_id
local_service_addressString value that specifies the IP address or hostname that a sidecar proxy should use to connect to the local service.Optional127.0.0.1
destination_service_nameString value that specifies the name of the service the instance is proxying. The name is used during service discovery to route to the correct proxy instances for a given service name.RequiredNone
local_service_socket_pathString value that specifies the path of a Unix domain socket for connecting to the local application instance.
This parameter value is created by the application and conflicts with local_service_address and local_service_port.
Supported when using Envoy for the proxy.
OptionalNone
modeString value that specifies the proxy mode. See Proxy Modes for additional information.Optionaldirect
transparent_proxyObject value that specifies the configuration specific to proxies in transparent mode.
See Proxy Modes and Transparent Proxy Configuration Reference for additional information.
This parameter was added in Consul 1.10.0.
OptionalNone
configObject value that specifies an opaque JSON configuration. The JSON is stored and returned along with the service instance when called from the API.OptionalNone
upstreamsAn array of objects that specify the upstream services that the proxy should create listeners for. Refer to Upstream Configuration Reference for details.OptionalNone
mesh_gatewayObject value that specifies the mesh gateway configuration for the proxy. Refer to Mesh Gateway Configuration Reference for details.OptionalNone
exposeObject value that specifies a configuration for exposing HTTP paths through the proxy.
This parameter is only compatible with Envoy proxies.
Refer to Expose Paths Configuration Reference for details.
OptionalNone

Upstream Configuration Reference

You can configure the service mesh proxy to create listeners for upstream services. The listeners enable the upstream service to accept requests. You can specify the following parameters to configure upstream service listeners.

ParameterDescriptionRequiredDefault
destination_nameString value that specifies the name of the service or prepared query to route the service mesh to. The prepared query should be the name or the ID of the prepared query.RequiredNone
destination_namespaceString value that specifies the namespace containing the upstream service. EnterpriseOptionaldefault
destination_peerString value that specifies the name of the peer cluster containing the upstream service.OptionalNone
destination_partitionString value that specifies the name of the admin partition containing the upstream service. If destination_peer is set, destination_partition refers to the local admin partition in which the peering was established. EnterpriseOptionaldefault
local_bind_portInteger value that specifies the port to bind a local listener to. The application will make outbound connections to the upstream from the local port.RequiredNone
local_bind_addressString value that specifies the address to bind a local listener to. The application will make outbound connections to the upstream service from the local bind address.Optional127.0.0.1
local_bind_socket_pathString value that specifies the path at which to bind a Unix domain socket listener. The application will make outbound connections to the upstream from the local bind socket path.
This parameter conflicts with the local_bind_port or local_bind_address parameters.
Supported when using Envoy as a proxy.
OptionalNone
local_bind_socket_modeString value that specifies a Unix octal that configures file permissions for the socket.OptionalNone
destination_typeString value that specifies the type of discovery query the proxy should use for finding service mesh instances. The following values are supported:
  • service: Queries for upstream service types.
  • prepared_query: Queries for upstream prepared queries.
  • Optionalservice
    datacenterString value that specifies the datacenter to issue the discovery query to.OptionalDefaults to the local datacenter.
    configObject value that specifies opaque configuration options that will be provided to the proxy instance for the upstream.
    Valid JSON objects are also supported.
    The config parameter can specify timeouts, retries, and other proxy-specific features for the given upstream.
    See the built-in proxy configuration reference for configuration options when using the built-in proxy.
    If using Envoy as a proxy, see Envoy configuration reference
    OptionalNone
    mesh_gatewayObject that defines the mesh gateway configuration for the proxy. Refer to the Mesh Gateway Configuration Reference for configuration details.OptionalNone

    Upstream Configuration Examples

    Upstreams support multiple destination types. The following examples include information about each implementation. Note that the examples in this topic use snake case, which is a convention that separates words with underscores, because the format is supported in configuration files and API registrations.

    Example service destination upstream

    Example service destination upstream

    1. destination_type = "service"
    2. destination_name = "redis"
    3. datacenter = "dc1"
    4. local_bind_address = "127.0.0.1"
    5. local_bind_port = 1234
    6. local_bind_socket_path = "/tmp/redis_5678.sock"
    7. local_bind_socket_mode = "0700"
    8. mesh_gateway = {
    9. mode = "local"
    10. }
    1. {
    2. "destination_type": "service",
    3. "destination_name": "redis",
    4. "datacenter": "dc1",
    5. "local_bind_address": "127.0.0.1",
    6. "local_bind_port": 1234,
    7. "local_bind_socket_path": "/tmp/redis_5678.sock",
    8. "local_bind_socket_mode": "0700",
    9. "mesh_gateway": {
    10. "mode": "local"
    11. }
    12. },

    Example prepared query upstream

    Example prepared query upstream

    1. destination_type = "prepared_query"
    2. destination_name = "database"
    3. local_bind_address = "127.0.0.1"
    4. local_bind_port = 1234
    5. config = {}
    1. {
    2. "destination_type": "prepared_query",
    3. "destination_name": "database",
    4. "local_bind_address": "127.0.0.1",
    5. "local_bind_port": 1234,
    6. "config": {}
    7. },

    Example of dialing remote upstreams across admin partitions

    Example of dialing remote upstreams across admin partitions

    1. destination_partition = "finance"
    2. destination_namespace = "default"
    3. destination_type = "service"
    4. destination_name = "billing"
    5. local_bind_port = 9090
    1. {
    2. "destination_partition": "finance",
    3. "destination_namespace": "default",
    4. "destination_type": "service",
    5. "destination_name": "billing",
    6. "local_bind_port": 9090
    7. }

    Example of dialing remote upstreams across peers

    Example of dialing remote upstreams across peers

    1. destination_peer = "cloud-services"
    2. destination_partition = "finance"
    3. destination_namespace = "default"
    4. destination_type = "service"
    5. destination_name = "api"
    6. local_bind_port = 9090
    1. {
    2. "destination_peer": "cloud-services",
    3. "destination_partition": "finance",
    4. "destination_namespace": "default",
    5. "destination_type": "service",
    6. "destination_name": "api",
    7. "local_bind_port": 9090
    8. }

    Proxy Modes

    You can configure which mode a proxy operates in by specifying "direct" or "transparent" in the mode parameter. The proxy mode determines the how proxies direct traffic. This feature was added in Consul 1.10.0.

    • transparent: In this mode, inbound and outbound application traffic is captured and redirected through the proxy. This mode does not enable the traffic redirection. It directs Consul to configure Envoy as if traffic is already being redirected.
    • direct: In this mode, the proxy’s listeners must be dialed directly by the local application and other proxies.

    You can also specify an empty string (""), which configures the proxy to operate in the default mode. The default mode is inherited from parent parameters in the following order of precedence:

    1. Proxy service’s Proxy configuration
    2. The service-defaults configuration for the service.
    3. The global proxy-defaults.

    The proxy will default to direct mode if a mode cannot be determined from the parent parameters.

    Transparent Proxy Configuration Reference

    The following examples show additional configuration for transparent proxies.

    Note that the examples in this topic use snake case, which is a convention that separates words with underscores, because the format is supported in configuration files and API registrations.

    Configure a proxy listener for outbound traffic on port 22500

    1. {
    2. "outbound_listener_port": 22500,
    3. "dialed_directly": true
    4. }
    • outbound_listener_port (int: 15001) - The port the proxy should listen on for outbound traffic. This must be the port where outbound application traffic is captured and redirected to.

    • dialed_directly (bool: false) - Determines whether this proxy instance’s IP address can be dialed directly by transparent proxies. Transparent proxies typically dial upstreams using the “virtual” tagged address, which load balances across instances. A database cluster with a leader is an example where dialing individual instances can be helpful. Cannot be used with upstreams which define a destination_peer.

      Note: Dynamic routing rules such as failovers and redirects do not apply to services dialed directly. Additionally, the connection is proxied using a TCP proxy with a connection timeout of 5 seconds.

    Mesh Gateway Configuration Reference

    The following examples show all possible mesh gateway configurations.

    Note that the examples in this topic use snake case, which is a convention that separates words with underscores, because the format is supported in configuration files and API registrations.

    Using a Local/Egress Gateway in the Local Datacenter

    1. {
    2. "mode": "local"
    3. }

    Direct to a Remote/Ingress in a Remote Datacenter

    1. {
    2. "mode": "remote"
    3. }

    Prevent Using a Mesh Gateway

    1. {
    2. "mode": "none"
    3. }

    Default Mesh Gateway Mode

    1. {
    2. "mode": ""
    3. }
    • mode (string: "") - This defines the mode of operation for how upstreams with a remote destination datacenter get resolved.
      • “local” - Mesh gateway services in the local datacenter will be used as the next-hop destination for the upstream connection.
      • “remote” - Mesh gateway services in the remote/target datacenter will be used as the next-hop destination for the upstream connection.
      • “none” - No mesh gateway services will be used and the next-hop destination for the connection will be directly to the final service(s).
      • “” - Default mode. The default mode will be "none" if no other configuration enables them. The order of precedence for setting the mode is
        1. Upstream
        2. Proxy Service’s Proxy configuration
        3. The service-defaults configuration for the service.
        4. The global proxy-defaults.

    Expose Paths Configuration Reference

    The following examples show possible configurations to expose HTTP paths through Envoy.

    Exposing paths through Envoy enables a service to protect itself by only listening on localhost, while still allowing non-mesh-enabled applications to contact an HTTP endpoint. Some examples include: exposing a /metrics path for Prometheus or /healthz for kubelet liveness checks.

    Note that the examples in this topic use snake case, which is a convention that separates words with underscores, because the format is supported in configuration files and API registrations.

    Expose listeners in Envoy for HTTP and GRPC checks registered with the local Consul agent

    1. {
    2. "expose": {
    3. "checks": true
    4. }
    5. }

    Expose an HTTP listener in Envoy at port 21500 that routes to an HTTP server listening at port 8080

    1. {
    2. "expose": {
    3. "paths": [
    4. {
    5. "path": "/healthz",
    6. "local_path_port": 8080,
    7. "listener_port": 21500
    8. }
    9. ]
    10. }
    11. }

    Expose an HTTP2 listener in Envoy at port 21501 that routes to a gRPC server listening at port 9090

    1. {
    2. "expose": {
    3. "paths": [
    4. {
    5. "path": "/grpc.health.v1.Health/Check",
    6. "protocol": "http2",
    7. "local_path_port": 9090,
    8. "listener_port": 21501
    9. }
    10. ]
    11. }
    12. }
    • checks (bool: false) - If enabled, all HTTP and gRPC checks registered with the agent are exposed through Envoy. Envoy will expose listeners for these checks and will only accept connections originating from localhost or Consul’s advertise address. The port for these listeners are dynamically allocated from expose_min_port to expose_max_port. This flag is useful when a Consul client cannot reach registered services over localhost. One example is when running Consul on Kubernetes, and Consul agents run in their own pods.
    • paths array<Path>: [] - A list of paths to expose through Envoy.
      • path (string: "") - The HTTP path to expose. The path must be prefixed by a slash. ie: /metrics.
      • local_path_port (int: 0) - The port where the local service is listening for connections to the path.
      • listener_port (int: 0) - The port where the proxy will listen for connections. This port must be available for the listener to be set up. If the port is not free then Envoy will not expose a listener for the path, but the proxy registration will not fail.
      • protocol (string: "http") - Sets the protocol of the listener. One of http or http2. For gRPC use http2.

    Unix Domain Sockets

    The following examples show additional configuration for Unix domain sockets.

    Added in v1.10.0.

    To connect to a service via local Unix Domain Socket instead of a port, add local_bind_socket_path and optionally local_bind_socket_mode to the upstream config for a service:

    1. upstreams = [
    2. {
    3. destination_name = "service-1"
    4. local_bind_socket_path = "/tmp/socket_service_1"
    5. local_bind_socket_mode = "0700"
    6. }
    7. ]
    1. "upstreams": [
    2. {
    3. "destination_name": "service-1",
    4. "local_bind_socket_path": "/tmp/socket_service_1",
    5. "local_bind_socket_mode": "0700"
    6. }
    7. ]

    This will cause Envoy to create a socket with the path and mode provided, and connect that to service-1.

    The mode field is optional, and if omitted will use the default mode for Envoy. This is not applicable for abstract sockets. See the Envoy documentation for details.

    These options conflict with the local_bind_socket_port and local_bind_socket_address options. For a given upstream the proxy can bind either to an IP port or a Unix socket, but not both.

    Similarly to expose a service listening on a Unix Domain socket to the service mesh, use either the socket_path field in the service definition or the local_service_socket_path field in the proxy definition. These fields are analogous to the port and service_port fields in their respective locations.

    1. services {
    2. name = "service-2"
    3. socket_path = "/tmp/socket_service_2"
    4. }
    1. "services": {
    2. "name": "service-2",
    3. "socket_path": "/tmp/socket_service_2"
    4. }

    Or in the proxy definition:

    1. services {
    2. name = "socket_service_2"
    3. connect {
    4. sidecar_service {
    5. proxy {
    6. name = "service-2"
    7. local_service_socket_path = "/tmp/socket_service_2"
    8. ...
    9. }
    10. }
    11. }
    12. }
    1. "services": {
    2. "name": "socket_service_2",
    3. "connect": {
    4. "sidecar_service": {
    5. "proxy": {
    6. "name": "service-2",
    7. "local_service_socket_path": "/tmp/socket_service_2"
    8. ...
    9. }
    10. }
    11. }
    12. }

    There is no mode field since the service is expected to create the socket it is listening on, not the Envoy proxy. Again, the socket_path and local_service_socket_path fields conflict with address/port and local_service_address/local_service_port configuration options.