Search code examples
dockermicroservicesenvoyproxy

How to expose envoy using docker?


I have microservice containers running in docker. I want to setup envoy to serve as a single gateway for a number of APIs. In my docker-compose.yml I have a service personapi defined and the following section defining the gateway:

  apigateway:
    image: ${DOCKER_REGISTRY-}apigateway
    build:
      context: .
      dockerfile: src/envoy/Dockerfile
    ports:
      - "7999:10000"
    depends_on:
      - personapi

There is also the envoy.yaml file which is copied to the gateway image and contains the following:

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 127.0.0.1, port_value: 9901 }

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 127.0.0.1, port_value: 10000 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route: { cluster: some_service }
          http_filters:
          - name: envoy.filters.http.router
  clusters:
  - name: some_service
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: some_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: personapi
                port_value: 80

When I open the console for the gateway service, these two commands work:

  1. Connect to the person service and download the list of people directly
curl personapi/person
  1. Connect to envoy and use it to route to the person service
curl localhost:10000/person

Now on the host machine, when I try to connect to the gateway service on the port 7999 ( specified in the docker compose to map to apigateway port 10000 ) I get an empty response - not even a status code. There seem to be something listening, but it is refusing to answer any requests.

How do I expose envoy to the host machine running docker?


Solution

  • The issue you ran into here isn't specific to docker, but rather to how network interfaces work.

    In the one that did not work, you were binding the Envoy listener to 127.0.0.1. This is the loopback interface and you will only be able to call this from the same machine it's running on. In this example, you would need to docker exec into the container in order to be able to call this interface.

    In the one that did work, you bound to 0.0.0.0 which is the IPV4 way of saying "i'll accept connections from anywhere". That binding let you address the Envoy listener from outside the Docker container.