istio: External Services example not working

Describe the bug Trying to run the external service example from the docs https://istio.io/docs/tasks/traffic-management/egress/#configuring-istio-external-services

When curling google from inside of the sleep container get the following reponse

* Rebuilt URL to: https://www.google.com/
* Hostname was NOT found in DNS cache
*   Trying 74.125.206.103...
* Connected to www.google.com (74.125.206.103) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
* Closing connection 0
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

Expected behavior See the out curl output of https://www.google.com Steps to reproduce the bug Follow steps in https://istio.io/docs/tasks/traffic-management/egress/#configuring-istio-external-services

Version Kubernetes version v1.10.5-gke.3 Istio version 1.0.0

Is Istio Auth enabled or not? mTLS disabled

Environment GKE

Cluster state Stable

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 30 (12 by maintainers)

Most upvoted comments

Managed to fix it after reading istio-pilot discover logs I found the following error:

 "pilot_conflict_outbound_listener_http_over_current_tcp": {
            "0.0.0.0:443": {
                "proxy": "sleep-546955b66d-2lg5b.default",
                "message": "Listener=0.0.0.0:443 AcceptedHTTP=foo.zone1.svc.cluster.local RejectedTCP=www.google.com HTTPServices=1"
            }
        },

foo.zone1.svc.cluster.local is a service which listens on 443 has a port name of grpc. Changing the port name from grpc seemed to fix this problem and now the HTTPS pass thorough works. A new listener for 10.0.0.20:443 now appears.

This seems like a bug as you could have many services wanting to have a name of grpc with port 443?

@maflaven This is because the SE+DR combination is incorrectly parsed in the Kiali’s duplicate validator at the moment. I’ll try to fix it tomorrow.

This is a bug. How is egress rule is connected to internal mesh port on some rando service?

@lukeforehand Great, you found the problem. First, the port names are important in Istio, see https://istio.io/docs/setup/kubernetes/prepare/requirements/. So you have to use port names according to the Istio expectations for all your services.

Second, as far as I can see, Istio treats GRPC as HTTP, according to https://github.com/istio/istio/blob/7d61672e25a28b0fa49ef2091f5b49703307572f/pilot/pkg/model/service.go#L259.

So if you use GRPC over TLS, you have to specify the port name as tls-<some suffix>. https- works too.

cc @rshriram

I changed all the port names to be unique, cleared out all the serviceentry’s, and re-tried with multiple rules and got it to work as expected. Deleted pods too, to be sure.

This still does not fix the error i reported above: Changed foo.zone1.svc.cluster.local port name from tcp to grpc-test and the error message is back

        "pilot_conflict_outbound_listener_http_over_current_tcp": {
            "0.0.0.0:443": {
                "proxy": "sleep-546955b66d-2lg5b.default",
                "message": "Listener=0.0.0.0:443 AcceptedHTTP=foo.zone1.svc.cluster.local RejectedTCP=www.google.com HTTPServices=1"
            }
        },

Which then breaks HTTPS external services. Easy to reproduce:

Make sure no ServiceEntrys, VirutalServices are defined for google.

create a service like:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - name: grpc-my-service
    port: 443
    protocol: TCP
    targetPort: grpc
EOF

then run as the docs say

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: google
spec:
  hosts:
  - www.google.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: google
spec:
  hosts:
  - www.google.com
  tls:
  - match:
    - port: 443
      sni_hosts:
      - www.google.com
    route:
    - destination:
        host: www.google.com
        port:
          number: 443
      weight: 100
EOF

and now external https forwarding will be broken. If you have the google entries installed first this will then do the reverse and break my-service