Ingress Gateways

    This task describes how to configure Istio to expose a service outside of the service mesh using an Istio Gateway.

    • Setup Istio by following the instructions in the Installation guide.

    • Make sure your current directory is the istio directory.

    • 启动 样例程序。

    如果您启用了 sidecar 自动注入,通过以下命令部署 httpbin 服务:

    否则,您必须在部署 httpbin 应用程序前进行手动注入,部署命令如下:

    Zip

    1. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@)
    • Determine the ingress IP and ports as described in the following subsection.

    Execute the following command to determine if your Kubernetes cluster is running in an environment that supports external load balancers:

    1. $ kubectl get svc istio-ingressgateway -n istio-system
    2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    3. istio-ingressgateway LoadBalancer 172.21.109.129 130.211.10.121 80:31380/TCP,443:31390/TCP,31400:31400/TCP 17h

    If the EXTERNAL-IP value is set, your environment has an external load balancer that you can use for the ingress gateway.If the EXTERNAL-IP value is <none> (or perpetually <pending>), your environment does not provide an external load balancer for the ingress gateway.In this case, you can access the gateway using the service’s .

    Choose the instructions corresponding to your environment:

    Follow these instructions if you have determined that your environment has an external load balancer.

    Set the ingress IP and ports:

    1. $ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    2. $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
    3. $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
    1. $ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

    Follow these instructions if you have determined that your environment does not have an external load balancer,so you need to use a node port instead.

    Set the ingress ports:

    1. $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
    2. $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')

    Setting the ingress IP depends on the cluster provider:

    • GKE:

    You need to create firewall rules to allow the TCP traffic to the ingressgateway service’s ports.Run the following commands to allow the traffic for the HTTP port, the secure port (HTTPS) or both:

    1. $ gcloud compute firewall-rules create allow-gateway-http --allow tcp:$INGRESS_PORT
    2. $ gcloud compute firewall-rules create allow-gateway-https --allow tcp:$SECURE_INGRESS_PORT
    • Minikube:
    1. $ export INGRESS_HOST=$(minikube ip)
    • Docker For Desktop:
    1. $ export INGRESS_HOST=127.0.0.1
    • Other environments (e.g., IBM Cloud Private etc):
    1. $ export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')

    Configuring ingress using an Istio Gateway

    An ingress describes a load balancer operating at the edge of the mesh that receives incoming HTTP/TCP connections.It configures exposed ports, protocols, etc.but, unlike Kubernetes Ingress Resources,does not include any traffic routing configuration. Traffic routing for ingress traffic is instead configuredusing Istio routing rules, exactly in the same way as for internal service requests.

    Let’s see how you can configure a Gateway on port 80 for HTTP traffic.

    • Create an Istio Gateway:
    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: Gateway
    4. metadata:
    5. spec:
    6. selector:
    7. istio: ingressgateway # use Istio default gateway implementation
    8. servers:
    9. - port:
    10. number: 80
    11. name: http
    12. hosts:
    13. - "httpbin.example.com"
    14. EOF
    • Configure routes for traffic entering via the Gateway:

    You have now created a configuration for the httpbin service containing two route rules that allow traffic for paths /status and/delay.

    The gateways listspecifies that only requests through your httpbin-gateway are allowed.All other external requests will be rejected with a 404 response.

    Internal requests from other services in the mesh are not subject to these rulesbut instead will default to round-robin routing. To apply these rules to internal calls as well,you can add the special value mesh to the list of gateways. Since the internal hostname for theservice is probabaly different (e.g., httpbin.default.svc.cluster.local) from the external one,you will also need to add it to the hosts list. Refer to thefor more details.

    • Access the httpbin service using curl:
    1. $ curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/status/200
    2. HTTP/1.1 200 OK
    3. server: envoy
    4. date: Mon, 29 Jan 2018 04:45:49 GMT
    5. content-type: text/html; charset=utf-8
    6. access-control-allow-origin: *
    7. access-control-allow-credentials: true
    8. content-length: 0
    9. x-envoy-upstream-service-time: 48

    Note that you use the -H flag to set the Host HTTP header to“httpbin.example.com”. This is needed because your ingress Gateway is configured to handle “httpbin.example.com”,but in your test environment you have no DNS binding for that host and are simply sending your request to the ingress IP.

    • Access any other URL that has not been explicitly exposed. You should see an HTTP 404 error:
    1. $ curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
    2. HTTP/1.1 404 Not Found
    3. date: Mon, 29 Jan 2018 04:45:49 GMT
    4. server: envoy
    5. content-length: 0

    Entering the httpbin service URL in a browser won’t work because you can’t pass the Host headerto a browser like you did with curl. In a real world situation, this is not a problembecause you configure the requested host properly and DNS resolvable. Thus, you use the host’s domain namein the URL, for example, https://httpbin.example.com/status/200.

    To work around this problem for simple tests and demos, use a wildcard * value for the host in the Gatewayand VirtualService configurations. For example, if you change your ingress configuration to the following:

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: Gateway
    4. metadata:
    5. name: httpbin-gateway
    6. spec:
    7. istio: ingressgateway # use Istio default gateway implementation
    8. - port:
    9. number: 80
    10. name: http
    11. protocol: HTTP
    12. hosts:
    13. - "*"
    14. ---
    15. apiVersion: networking.istio.io/v1alpha3
    16. kind: VirtualService
    17. metadata:
    18. name: httpbin
    19. spec:
    20. hosts:
    21. - "*"
    22. gateways:
    23. - httpbin-gateway
    24. http:
    25. - match:
    26. - uri:
    27. prefix: /headers
    28. route:
    29. - destination:
    30. port:
    31. number: 8000
    32. host: httpbin
    33. EOF

    You can then use $INGRESS_HOST:$INGRESS_PORT in the browser URL. For example, will display all the headers that your browser sends.

    Understanding what happened

    In the preceding steps, you created a service inside the service meshand exposed an HTTP endpoint of the service to external traffic.

    • Inspect the values of the INGRESS_HOST and INGRESS_PORT environment variables. Make surethey have valid values, according to the output of the following commands:
    1. $ kubectl get svc -n istio-system
    2. $ echo INGRESS_HOST=$INGRESS_HOST, INGRESS_PORT=$INGRESS_PORT
    • Check that you have no other Istio ingress gateways defined on the same port:
    1. $ kubectl get gateway --all-namespaces
    • Check that you have no Kubernetes Ingress resources defined on the same IP and port:
    • If you have an external load balancer and it does not work for you, try to.

    Cleanup

    Delete the Gateway and VirtualService configuration, and shutdown the service:

    Zip

    1. $ kubectl delete gateway httpbin-gateway
    2. $ kubectl delete virtualservice httpbin

    Configure Istio ingress gateway to act as a proxy for external services.

    Deploy a Custom Ingress Gateway Using Cert-Manager

    Describes how to deploy a custom ingress gateway using cert-manager manually.

    Describes how to configure Istio ingress with a network load balancer on AWS.

    Ingress Gateway without TLS Termination

    Describes how to configure SNI passthrough for an ingress gateway.

    Demonstrates how to obtain Let's Encrypt TLS certificates for Kubernetes Ingress automatically using Cert-Manager.

    Expose a service outside of the service mesh over TLS or mTLS using file-mounted certificates.