Open njordr opened 6 years ago
I'll let @relistan comment on the general architecture, but, from a code perspective:
HealthCheckArgs
for your service. You will notice that the host
resolves to m.DefaultCheckHost
, which, unless specified explicitly via SIDECAR_ADVERTISE_IP
, comes from here, which is determined in here to be the first private IPv4 address (that is not excluded via SIDECAR_EXCLUDE_IPS
) returned by net.InterfaceAddrs()
.templateCheckArgs
, you'll see that, in the case of tcp
, it calls svc.PortForServicePort(p, "tcp")
, which means that it will inspect the ServicePort_80=xxxx
label on your service container, so the health check will be directed at host:xxxx
, where host
is the host which runs Envoy and xxxx
is the fixed port which Envoy will redirect to the dynamic port that Docker assigns to the published port 80 when you run your service with docker run -p80 ...
.HttpGetCmd
(for HTTP health checks), which simply calls http.Get(args)
when invoked from here, where args
contains the instantiation of the HealthCheckArgs
template, as described above.HAPROXY_DISABLE
set to false
in the log you pasted above?HAPROXY_BIND_IP
(unfortunately, the variable name has not been refactored when we added the Envoy integration, but it's being used by Envoy as well. See here and here). Its default value is 192.168.168.168
, but you can set it to another private routable IP. Note that when Sidecar is running in host networking mode, it calls ip addr add $HAPROXY_BIND_IP/32 dev lo
here ONLY if you set this variable explicitly when running the container because s6 doesn't know about the default value set in the sidecar executable. @relistan is there a reason why we don't set ENV HAPROXY_BIND_IP="192.168.168.168"
in the Sidecar Dockerfile?@njordr What I think you are saying is that you want to have the ServicePort
be the same/native port but bound on a different address so that you don't have port conflicts? If so:
You still need to bind your ports in Docker, but you can configure Docker not to bind them on all addresses (defaults to 0.0.0.0
). Generally you'd have them bound on localhost or some other internal network. You can either do this in the daemon configuration, for all containers, or specify it per container. My guess is setting the default is what you will want.
You can tell Envoy or HAproxy to bind on an IP specifically (not 0.0.0.0). In this way you can use the same ports and not conflict between the proxy and Docker.
Did I understand correctly what you wanted?
Also, as @mihaitodor says, the health check is going to refuse to run against a port that is not exposed/bound.
@mihaitodor I don't know why it's not in the Dockerfile
@relistan Thanks for the info. I think what you suggest could solve my problems, merged with the advises from @mihaitodor
I'll try in the week-end and let you know :)
@njordr it looks like you are in Dublin. If you want, I'd be happy to grab a coffee and talk through what you're trying to work out.
@relistan I'm happy to grab a coffee too
Hey.
I'm trying to figure out if I can/how I can use sidecar with docker swarm
I created a cluster (single host) with 4 services:
Portainer server bind port 9000 nginx bind port 80 and 443
All the services are on the ingress network for two reason:
Expected result:
Desiderata:
Actual result:
HealthCheckArgs="http://{{ host }}:{{ tcp 80 }}/"
, host variable retrieves a different IP from the one assigned (in this case it tries to check the service on IP 10.255.0.5 but the service is on IP 10.255.0.10). you can see that in the log belowtime="2018-09-12T19:29:39Z" level=info msg="Adding health check: HttpGet (ID: 59844989cd37), Args: http://10.255.0.5:-1/",
I could have misunderstood sidecar architecture/swarm functionalities so this probably is not a bug :)
Here are sidecar debug logs