Ingress Gateway without TLS Termination

    The example HTTPS service used for this task is a simple NGINX server. In the following steps you first deploy the NGINX service in your Kubernetes cluster. Then you configure a gateway to provide ingress access to the service via host .

    Istio includes beta support for the Kubernetes and intends to make it the default API for traffic management in the future. The following instructions allow you to choose to use either the Gateway API or the Istio configuration API when configuring traffic management in the mesh. Follow instructions under either the Gateway API or Istio classic tab, according to your preference.

    Note that the Kubernetes Gateway API CRDs do not come installed by default on most Kubernetes clusters, so make sure they are installed before using the Gateway API:

    This document uses of the Kubernetes Gateway API. Make sure to install the experimental CRDs before using the Gateway API:

    1. $ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v0.6.1" | kubectl apply -f -

    Setup Istio by following the instructions in the .

    1. Create a root certificate and private key to sign the certificate for your services:

      1. $ mkdir example_certs
      2. $ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt
    2. Create a certificate and a private key for nginx.example.com:

      1. $ openssl req -out example_certs/nginx.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/nginx.example.com.key -subj "/CN=nginx.example.com/O=some organization"
      2. $ openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/nginx.example.com.csr -out example_certs/nginx.example.com.crt
    1. Create a Kubernetes Secret to hold the server’s certificate.

      1. $ kubectl create secret tls nginx-server-certs \
      2. --key example_certs/nginx.example.com.key \
      3. --cert example_certs/nginx.example.com.crt
    2. Create a configuration file for the NGINX server:

      1. $ cat <<\EOF > ./nginx.conf
      2. events {
      3. }
      4. http {
      5. log_format main '$remote_addr - $remote_user [$time_local] $status '
      6. '"$request" $body_bytes_sent "$http_referer" '
      7. '"$http_user_agent" "$http_x_forwarded_for"';
      8. access_log /var/log/nginx/access.log main;
      9. error_log /var/log/nginx/error.log;
      10. server {
      11. listen 443 ssl;
      12. root /usr/share/nginx/html;
      13. index index.html;
      14. server_name nginx.example.com;
      15. ssl_certificate /etc/nginx-server-certs/tls.crt;
      16. ssl_certificate_key /etc/nginx-server-certs/tls.key;
      17. }
      18. }
      19. EOF
    3. Create a Kubernetes to hold the configuration of the NGINX server:

      1. $ cat <<EOF | kubectl apply -f -
      2. apiVersion: v1
      3. kind: Service
      4. metadata:
      5. name: my-nginx
      6. labels:
      7. run: my-nginx
      8. spec:
      9. ports:
      10. - port: 443
      11. protocol: TCP
      12. selector:
      13. run: my-nginx
      14. ---
      15. apiVersion: apps/v1
      16. kind: Deployment
      17. metadata:
      18. name: my-nginx
      19. spec:
      20. selector:
      21. matchLabels:
      22. run: my-nginx
      23. replicas: 1
      24. template:
      25. metadata:
      26. labels:
      27. sidecar.istio.io/inject: "true"
      28. spec:
      29. containers:
      30. - name: my-nginx
      31. image: nginx
      32. - containerPort: 443
      33. volumeMounts:
      34. - name: nginx-config
      35. mountPath: /etc/nginx
      36. readOnly: true
      37. - name: nginx-server-certs
      38. mountPath: /etc/nginx-server-certs
      39. readOnly: true
      40. volumes:
      41. - name: nginx-config
      42. configMap:
      43. name: nginx-configmap
      44. - name: nginx-server-certs
      45. secret:
      46. secretName: nginx-server-certs
      47. EOF
    4. To test that the NGINX server was deployed successfully, send a request to the server from its sidecar proxy without checking the server’s certificate (use the -k option of curl). Ensure that the server’s certificate is printed correctly, i.e., common name (CN) is equal to nginx.example.com.

      1. $ kubectl exec "$(kubectl get pod -l run=my-nginx -o jsonpath={.items..metadata.name})" -c istio-proxy -- curl -sS -v -k --resolve nginx.example.com:443:127.0.0.1 https://nginx.example.com
      2. ...
      3. SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
      4. ALPN, server accepted to use http/1.1
      5. Server certificate:
      6. subject: CN=nginx.example.com; O=some organization
      7. start date: May 27 14:18:47 2020 GMT
      8. expire date: May 27 14:18:47 2021 GMT
      9. issuer: O=example Inc.; CN=example.com
      10. SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
      11. > GET / HTTP/1.1
      12. > User-Agent: curl/7.58.0
      13. > Host: nginx.example.com
      14. ...
      15. < HTTP/1.1 200 OK
      16. < Server: nginx/1.17.10
      17. ...
      18. <!DOCTYPE html>
      19. <html>
      20. <head>
      21. <title>Welcome to nginx!</title>
      22. ...
    1. Define a Gateway exposing port 443 with passthrough TLS mode. This instructs the gateway to pass the ingress traffic “as is”, without terminating TLS:
    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: Gateway
    4. metadata:
    5. name: mygateway
    6. spec:
    7. selector:
    8. istio: ingressgateway # use istio default ingress gateway
    9. servers:
    10. - port:
    11. number: 443
    12. name: https
    13. protocol: HTTPS
    14. tls:
    15. mode: PASSTHROUGH
    16. hosts:
    17. - nginx.example.com
    18. EOF
    1. $ kubectl apply -f - <<EOF
    2. apiVersion: gateway.networking.k8s.io/v1beta1
    3. name: mygateway
    4. spec:
    5. gatewayClassName: istio
    6. listeners:
    7. - name: https
    8. hostname: "nginx.example.com"
    9. port: 443
    10. protocol: TLS
    11. tls:
    12. mode: Passthrough
    13. allowedRoutes:
    14. namespaces:
    15. from: All
    16. EOF
    1. Configure routes for traffic entering via the Gateway:
    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: VirtualService
    4. metadata:
    5. name: nginx
    6. spec:
    7. hosts:
    8. - nginx.example.com
    9. gateways:
    10. - mygateway
    11. tls:
    12. - match:
    13. - port: 443
    14. sniHosts:
    15. - nginx.example.com
    16. route:
    17. - destination:
    18. host: my-nginx
    19. port:
    20. number: 443
    21. EOF
    1. Determine the ingress IP and port:

    Follow the instructions in to set the SECURE_INGRESS_PORT and INGRESS_HOST environment variables.

    Use the following commands to set the SECURE_INGRESS_PORT and INGRESS_HOST environment variables:

    1. $ kubectl wait --for=condition=ready gtw mygateway
    2. $ export INGRESS_HOST=$(kubectl get gtw mygateway -o jsonpath='{.status.addresses[*].value}')
    3. $ export SECURE_INGRESS_PORT=$(kubectl get gtw mygateway -o jsonpath='{.spec.listeners[?(@.name=="https")].port}')
    1. Access the NGINX service from outside the cluster. Note that the correct certificate is returned by the server and it is successfully verified (SSL certificate verify ok is printed).

      1. $ curl -v --resolve "nginx.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" --cacert example_certs/example.com.crt "https://nginx.example.com:$SECURE_INGRESS_PORT"
      2. Server certificate:
      3. subject: CN=nginx.example.com; O=some organization
      4. start date: Wed, 15 Aug 2018 07:29:07 GMT
      5. expire date: Sun, 25 Aug 2019 07:29:07 GMT
      6. issuer: O=example Inc.; CN=example.com
      7. SSL certificate verify ok.
      8. < HTTP/1.1 200 OK
      9. < Server: nginx/1.15.2
      10. ...
      11. <html>
      12. <head>
      13. <title>Welcome to nginx!</title>
    1. Delete the gateway configuration and route:
    1. $ kubectl delete gateway mygateway
    2. $ kubectl delete virtualservice nginx
    1. $ kubectl delete gtw mygateway
    2. $ kubectl delete tlsroute nginx
    1. Remove the NGINX resources and configuration file:

      1. $ kubectl delete secret nginx-server-certs
      2. $ kubectl delete configmap nginx-configmap
      3. $ kubectl delete service my-nginx
      4. $ kubectl delete deployment my-nginx
      5. $ rm ./nginx.conf