Recently, I started envoy proxy, pulled the envoyproxy/envoy:latest image, and conducted a local test. However, when the proxy failed, I recorded the whole process.
Configure agent
Refer to envoyproxy official Front end agent sample configuration As a blueprint, it has changed to its own configuration. The contents are as follows:
static_resources: listeners: - address: socket_address: address: 0.0.0.0 port_value: 9901 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 codec_type: AUTO stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: backend domains: - "*" routes: - match: prefix: "/" route: cluster: service1 http_filters: - name: envoy.filters.http.router clusters: - name: service1 type: STRICT_DNS connect_timeout: 0.25s lb_policy: ROUND_ROBIN load_assignment: cluster_name: service1 endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 8000 admin: access_log_path: /tmp/admin_access.log address: socket_address: address: 0.0.0.0 port_value: 8001 layered_runtime: layers: - name: static_layer_0 static_layer: envoy: resource_limits: listener: example_listener_name: connection_limit: 10000
The meaning of the above configuration is to listen to http requests on port 9901 and forward the requests to port 8000 of this machine, and the upstream host listens to and processes the requests on port 8000.
The container startup command is as follows:
$ docker run -d --rm --name envoy -p 9901:9901 -p 8001:8001 -v /config/path/in/host/test.yaml:/etc/envoy.yaml envoyproxy/envoy -c /etc/envoy.yaml
Two ports are opened. 9901 is responsible for forwarding service traffic, and 8001 handles the dashboard request of envoy's control plane.
upstream service logic
The request is forwarded to the local port 8000. upstream is implemented with go. The code is very simple. A hello world is echoed and the request header is printed at the same time
package main import ( "flag" "fmt" "net/http" "strings" "time" ) func greet(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World! %s", time.Now()) fmt.Println("[headers]") for k, v := range r.Header { var header string for _, v1 := range v { header = header + v1 + ", " } header = strings.TrimRight(header, ", ") fmt.Printf("\t%s: %s\n", k, header) } } func main() { var port string flag.StringVar(&port, "port", ":8000", "-port=:8000") flag.Parse() http.HandleFunc("/", greet) if err := http.ListenAndServe(port, nil); err != nil { fmt.Println(err.Error()) } }
Everything is ready, run the service and start the test
phenomenon
Through the local curl request, it is found that the prompt cannot connect to the upstream host
$ curl http://localhost:9901/ upstream connect error or disconnect/reset before headers. reset reason: connection failure
analysis
It is preliminarily determined that the container is isolated from the network and cannot access the host. So docker exec - it envy / bin / bash, after installing the network package, requested 8000 port, but it was impossible, which verified the guess of network isolation.
I checked it on the Internet. It's on the Internet Stack Overflow Under this answer, different solutions are given for different operating system environments. However, we should first understand the network parameter of docker
network parameters
The common optional values of the network parameter are none, host and bridge
none: as the name suggests, disable the container network. At this time, the container cannot access the external network and the external can not access the container. Your - p parameter will also be ignored
Bridge: bridge, which is also the default mode. The container will bridge with the host and communicate through a bridged docker0 network card
Host: that is to revoke network isolation. In this mode, you do not need to specify the - p parameter. What port the container listens to will be directly bound to the same port of the host. At this time, the container and the host are not isolated
After comprehensive consideration, although the host mode can solve the problem, it is not what I want, and the necessary isolation is still needed, so the bridge mode is preferred.
For the bridge mode, in the linux environment, docker deamon will create a docker0 network card to be used as a bridge to realize the communication between the container and the host, but The isolation technology in mac system is different from that in linux Therefore, this network card will not be created.
Because bridge is the default network option, we do not need to modify the docker startup command.
So how does the mac access the host's services from within the container?
mac system container access host
I have installed Docker desktop for mac locally and brought my own docker daemon. The version is 3.6.0 and the built-in docker engine is 20.10.8.
Before version 17.12, you can access the host through the host name docker.for.mac.localhost. After version 17.12, you can access the host through docker.for.mac.host.internal.
Log in to the container and verify by ping as follows:
root@eed301853eb6:/# ping docker.for.mac.localhost PING docker.for.mac.localhost (192.168.65.2) 56(84) bytes of data. 64 bytes from 192.168.65.2: icmp_seq=1 ttl=37 time=4.02 ms 64 bytes from 192.168.65.2: icmp_seq=2 ttl=37 time=0.361 ms ^C --- docker.for.mac.localhost ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.361/2.191/4.022/1.831 ms root@eed301853eb6:/# ping docker.for.mac.host.internal PING docker.for.mac.host.internal (192.168.65.2) 56(84) bytes of data. 64 bytes from 192.168.65.2: icmp_seq=1 ttl=37 time=1.31 ms 64 bytes from 192.168.65.2: icmp_seq=2 ttl=37 time=1.55 ms ^C --- docker.for.mac.host.internal ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 1.310/1.433/1.556/0.123 ms
The resolved IP address is my local address
Adjust envoy configuration
According to the above analysis, adjust the upstream host address under clusters in the envoy configuration and replace 127.0.0.1 with docker.for.mac.localhost or docker.for.mac.host.internal to realize the agent's access to the host.