istio: VM mesh expansion, ISTIO_INBOUND_PORTS conflicts with Docker container outbound traffic
Bug description No outbound traffic is possible from Docker containers on ports that are defined in ISTIO_INBOUND_PORTS.
Use case: running Docker containers on mesh expansion VMs.
In our case we are running an application that listens on port 80 but also has to reach out for the GCE metadata service (also runs on Port 80) to get the user token of the VM service account. This is the default behaviour doing authentication for most GCP related service libraries.
It seems that this outbound traffic interferes with ISTIO_INBOUND_PORTS when the same port is used for egress. Doing outbound calls works fine when directly done on the VM but not from the containers, I would suspect that the additional iptables rules needed for docker are not reflected in the Istio iptables rule set or some configuration is missing from our side.
This behaviour is reproducible with any external service running on ports that are also defined in ISTIO_INBOUND_PORTS. Currently it looks like that outbound traffic on these ports gets redirected back to the origin.
This setup was definitely working until Istio 1.5.1
[ ] Docs [ ] Installation [ x] Networking [ ] Performance and Scalability [ ] Extensions and Telemetry [ ] Security [ ] Test and Release [x ] User Experience [ ] Developer Infrastructure
Expected behavior Outbound traffic from containers does not get affected by ISTIO_INBOUND_PORTS settings.
Steps to reproduce the bug
- Setup a VM expanding the mesh
- Set ISTIO_INBOUND_PORTS=80
- Do a curl directly from the VM => that should succeed
# curl -v http://whatismyip.akamai.com
* Rebuilt URL to: http://whatismyip.akamai.com/
* Trying 88.221.25.251...
* TCP_NODELAY set
* Connected to whatismyip.akamai.com (88.221.25.251) port 80 (#0)
> GET / HTTP/1.1
> Host: whatismyip.akamai.com
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
- Do a curl from a docker container on the VM => that will fail
# docker run --rm -it curlimages/curl -v http://whatismyip.akamai.com
* Trying 88.221.25.251:80...
* Connected to whatismyip.akamai.com (88.221.25.251) port 80 (#0)
> GET / HTTP/1.1
> Host: whatismyip.akamai.com
> User-Agent: curl/7.72.0-DEV
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 503 Service Unavailable
< content-length: 91
< content-type: text/plain
< date: Mon, 05 Oct 2020 11:16:48 GMT
< server: istio-envoy
< x-envoy-decorator-operation: gitlab.gitlab-omnibus.svc.cluster.local:80/*
<
* Connection #0 to host whatismyip.akamai.com left intact
- change ISTIO_INBOUND_PORTS to a non conflicting port
ISTIO_INBOUND_PORTS=8080
- restart the istio-sidecar
systemctl restart istio
- retry the curl from the container => should work this time
# docker run --rm -it curlimages/curl -v http://whatismyip.akamai.com
* Trying 88.221.144.73:80...
* Connected to whatismyip.akamai.com (88.221.144.73) port 80 (#0)
> GET / HTTP/1.1
> Host: whatismyip.akamai.com
> User-Agent: curl/7.72.0-DEV
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 12
< Expires: Mon, 05 Oct 2020 11:20:20 GMT
< Cache-Control: max-age=0, no-cache, no-store
< Pragma: no-cache
< Date: Mon, 05 Oct 2020 11:20:20 GMT
< Connection: keep-alive
Version (include the output of istioctl version --remote
and kubectl version --short
and helm version
if you used Helm)
client version: 1.7.3
control plane version: 1.7.3
data plane version: 1.7.3 (4 proxies), 1.7.0 (3 proxies)
Client Version: v1.19.2
Server Version: v1.16.13-gke.401
How was Istio installed?
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
meshExpansion:
enabled: true
Environment where bug was observed (cloud vendor, OS, etc) GKE, GCE (ubuntu-minimal-1804-bionic-v20200520)
debug log error case with colliding ports The 127.0.0.1 and the match with the inbound is confusing
2020-10-05T11:32:32.274711Z debug envoy filter original_dst: New connection accepted
2020-10-05T11:32:32.274768Z debug envoy filter tls inspector: new connection accepted
2020-10-05T11:32:32.275324Z debug envoy filter http inspector: new connection accepted
2020-10-05T11:32:32.275440Z debug envoy conn_handler [C2] new connection
2020-10-05T11:32:32.275554Z debug envoy http [C2] new stream
2020-10-05T11:32:32.275615Z debug envoy http [C2][S8257163499414696093] request headers complete (end_stream=true):
':authority', 'whatismyip.akamai.com'
':path', '/'
':method', 'GET'
'user-agent', 'curl/7.72.0-DEV'
'accept', '*/*'
2020-10-05T11:32:32.275623Z debug envoy http [C2][S8257163499414696093] request end stream
2020-10-05T11:32:32.275763Z debug envoy filter AuthenticationFilter::decodeHeaders with config
policy {
peers {
mtls {
mode: PERMISSIVE
}
}
}
skip_validate_trust_domain: true
2020-10-05T11:32:32.275776Z debug envoy filter [C2] validateX509 mode PERMISSIVE: ssl=false, has_user=false
2020-10-05T11:32:32.275781Z debug envoy filter Payload has not peer authentication data
2020-10-05T11:32:32.275787Z debug envoy filter Set principal from peer:
2020-10-05T11:32:32.275792Z debug envoy filter Origin authenticator succeeded
2020-10-05T11:32:32.275802Z debug envoy filter Saved Dynamic Metadata:
2020-10-05T11:32:32.275823Z debug envoy router [C2][S8257163499414696093] cluster 'inbound|80|http-omnibus|gitlab.gitlab-omnibus.svc.cluster.local' match for URL '/'
2020-10-05T11:32:32.275886Z debug envoy router [C2][S8257163499414696093] router decoding headers:
':authority', 'whatismyip.akamai.com'
':path', '/'
':method', 'GET'
':scheme', 'http'
'user-agent', 'curl/7.72.0-DEV'
'accept', '*/*'
'x-forwarded-proto', 'http'
'x-request-id', 'ad3ca040-3ba4-459d-aaf7-0109c1602ddf'
'x-b3-traceid', 'ae769085a794d03e15b364c0de615bb1'
'x-b3-spanid', '15b364c0de615bb1'
'x-b3-sampled', '0'
2020-10-05T11:32:32.275899Z debug envoy pool queueing request due to no available connections
2020-10-05T11:32:32.275906Z debug envoy pool creating a new connection
2020-10-05T11:32:32.275953Z debug envoy client [C3] connecting
2020-10-05T11:32:32.275960Z debug envoy connection [C3] connecting to 127.0.0.1:80
2020-10-05T11:32:32.276015Z debug envoy connection [C3] connection in progress
2020-10-05T11:32:32.276070Z debug envoy connection [C3] delayed connection error: 111
2020-10-05T11:32:32.276077Z debug envoy connection [C3] closing socket: 0
2020-10-05T11:32:32.276094Z debug envoy client [C3] disconnect. resetting 0 pending requests
2020-10-05T11:32:32.276102Z debug envoy pool [C3] client disconnected, failure reason:
2020-10-05T11:32:32.276113Z debug envoy router [C2][S8257163499414696093] upstream reset: reset reason connection failure
2020-10-05T11:32:32.276172Z debug envoy http [C2][S8257163499414696093] Sending local reply with details upstream_reset_before_response_started{connection failure}
2020-10-05T11:32:32.276217Z debug envoy http [C2][S8257163499414696093] encoding headers via codec (end_stream=false):
':status', '503'
'content-length', '91'
'content-type', 'text/plain'
'date', 'Mon, 05 Oct 2020 11:32:31 GMT'
'server', 'istio-envoy'
'x-envoy-decorator-operation', 'gitlab.gitlab-omnibus.svc.cluster.local:80/*'
# iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 1 packets, 67 bytes)
pkts bytes target prot opt in out source destination
49221 2947K DOCKER all -- any any anywhere anywhere ADDRTYPE match dst-type LOCAL
1 60 ISTIO_INBOUND tcp -- any any anywhere anywhere
Chain INPUT (policy ACCEPT 1 packets, 60 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 49 packets, 3789 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- any any anywhere !localhost/8 ADDRTYPE match dst-type LOCAL
10 600 ISTIO_OUTPUT tcp -- any any anywhere anywhere
Chain POSTROUTING (policy ACCEPT 50 packets, 3849 bytes)
pkts bytes target prot opt in out source destination
626 40773 MASQUERADE all -- any !docker0 172.17.0.0/16 anywhere
0 0 MASQUERADE tcp -- any any 172.17.0.2 172.17.0.2 tcp dpt:https
0 0 MASQUERADE tcp -- any any 172.17.0.2 172.17.0.2 tcp dpt:http
0 0 MASQUERADE tcp -- any any 172.17.0.2 172.17.0.2 tcp dpt:ssh
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 any anywhere anywhere
0 0 DNAT tcp -- !docker0 any anywhere gitlab-omnibus.c.rd-k8s-common.internal tcp dpt:https to:172.17.0.2:443
273 16380 DNAT tcp -- !docker0 any anywhere gitlab-omnibus.c.rd-k8s-common.internal tcp dpt:http to:172.17.0.2:80
4629 278K DNAT tcp -- !docker0 any anywhere gitlab-omnibus.c.rd-k8s-common.internal tcp dpt:2222 to:172.17.0.2:22
Chain ISTIO_INBOUND (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN tcp -- any any anywhere anywhere tcp dpt:15008
1 60 ISTIO_IN_REDIRECT tcp -- any any anywhere anywhere tcp dpt:http
0 0 ISTIO_IN_REDIRECT tcp -- any any anywhere anywhere tcp dpt:2222
Chain ISTIO_IN_REDIRECT (6 references)
pkts bytes target prot opt in out source destination
1 60 REDIRECT tcp -- any any anywhere anywhere redir ports 15006
Chain ISTIO_OUTPUT (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- any lo localhost anywhere
0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner UID match istio-proxy
0 0 RETURN all -- any lo anywhere anywhere ! owner UID match istio-proxy
9 540 RETURN all -- any any anywhere anywhere owner UID match istio-proxy
0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner UID match root
0 0 RETURN all -- any lo anywhere anywhere ! owner UID match root
1 60 RETURN all -- any any anywhere anywhere owner UID match root
0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner GID match admin
0 0 RETURN all -- any lo anywhere anywhere ! owner GID match admin
0 0 RETURN all -- any any anywhere anywhere owner GID match admin
0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner GID match root
0 0 RETURN all -- any lo anywhere anywhere ! owner GID match root
0 0 RETURN all -- any any anywhere anywhere owner GID match root
0 0 RETURN all -- any any anywhere localhost
0 0 ISTIO_REDIRECT all -- any any anywhere 10.12.48.0/20
0 0 RETURN all -- any any anywhere anywhere
Chain ISTIO_REDIRECT (1 references)
pkts bytes target prot opt in out source destination
0 0 REDIRECT tcp -- any any anywhere anywhere redir ports 15001
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 23 (11 by maintainers)
KUBE_VIRT_INTERFACES=docker0
setting this will make things work in general. Needs some more investigation though.Hi!
It seems that when using
KUBE_VIRT_INTERFACES='docker0'
in thecluster.env
then the manual hack in the iptables is not required anymore.However now we start suffering from https://github.com/istio/istio/issues/34015. As you mentioned in https://github.com/istio/istio/issues/34015#issuecomment-894374998
Envoy doesn’t show a particularly useful error, but I did reproduce it with a simple original-dst proxy: https://github.com/howardjohn/go-proxy/blob/main/orig-dst/main.go
Basically it works IFF the source address is not set to 127.0.0.6. I think this only works if the destination is local, otherwise its failing with
connect: invalid argument
Not stale