无 TLS 终止的 Ingress Gateway

    本任务中的 HTTPS 示例服务是一个简单的 NGINX 服务。在接下来的步骤中,您首先在 Kubernetes 集群中创建一个 NGINX 服务。接着,通过网关给这个服务配置一个域名是 的访问入口。

    对于此任务,您可以使用自己喜欢的工具来生成证书和密钥。以下命令使用

    1. 创建根证书和私钥来为您的服务签名证书:

    2. nginx.example.com 创建证书和私钥:

      1. $ openssl req -out nginx.example.com.csr -newkey rsa:2048 -nodes -keyout nginx.example.com.key -subj "/CN=nginx.example.com/O=some organization"
      2. $ openssl x509 -req -sha256 -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in nginx.example.com.csr -out nginx.example.com.crt
      1. $ kubectl create secret tls nginx-server-certs --key nginx.example.com.key --cert nginx.example.com.crt
    1. 为 NGINX 服务创建一个配置文件:

      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
    2. 创建一个 Kubernetes 的 ConfigMap 资源来保存 NGINX 服务的配置:

    3. 部署 NGINX 服务

      1. $ cat <<EOF | istioctl kube-inject -f - | 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. metadata:
      17. name: my-nginx
      18. spec:
      19. selector:
      20. matchLabels:
      21. replicas: 1
      22. template:
      23. metadata:
      24. labels:
      25. run: my-nginx
      26. spec:
      27. containers:
      28. - name: my-nginx
      29. image: nginx
      30. ports:
      31. - containerPort: 443
      32. volumeMounts:
      33. - name: nginx-config
      34. mountPath: /etc/nginx
      35. readOnly: true
      36. - name: nginx-server-certs
      37. mountPath: /etc/nginx-server-certs
      38. readOnly: true
      39. volumes:
      40. - name: nginx-config
      41. configMap:
      42. name: nginx-configmap
      43. - name: nginx-server-certs
      44. secret:
      45. secretName: nginx-server-certs
      46. EOF
    4. 要测试 NGINX 服务是否已成功部署,需要从其 Sidecar 代理发送请求,并忽略检查服务端的证书(使用 curl-k 选项)。确保正确打印服务端的证书,即 common name (CN) 等于 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. <!DOCTYPE html>
      18. <html>
      19. <head>
      20. <title>Welcome to nginx!</title>
      21. ...
      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. 为通过 Gateway 进入的流量配置路由:

    2. 根据中的指令来定义环境变量 SECURE_INGRESS_PORTINGRESS_HOST

    3. 从集群外访问 NGINX 服务。注意,服务端返回了正确的证书,并且该证书已成功验证(输出了 _SSL certificate verify ok_)。

      1. $ curl -v --resolve "nginx.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" --cacert 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. 删除已创建的 Kubernetes 资源:

      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. $ kubectl delete gateway mygateway
      1. $ rm example.com.crt example.com.key nginx.example.com.crt nginx.example.com.key nginx.example.com.csr
    2. 删除本示例中生成的配置文件: