• 没有 TLS 的 Ingress gateway
    • 生成客户端和服务器证书和密钥
    • 部署 NGINX 服务器
    • 配置 Ingress Gateway
    • 清理

    没有 TLS 的 Ingress gateway

    使用 HTTPS 保护网关任务描述了如何配置 HTTPS入口访问 HTTP 服务。此示例介绍如何配置对 HTTPS 服务的入口访问,即配置 Ingress Gateway 以执行 SNI 直通,而不是终止 TLS 请求的传入。

    用于此任务的示例 HTTPS 服务是一个简单的 NGINX 服务器。在以下步骤中,首先在 Kubernetes 集群中部署 NGINX 服务。然后配置网关以通过主机 nginx.example.com 提供对此服务的入口访问。

    生成客户端和服务器证书和密钥

    以与使用 HTTPS 保护网关任务相同的方式生成证书和密钥。

    • 克隆 https://github.com/nicholasjackson/mtls-go-example 存储库:
    1. $ git clone https://github.com/nicholasjackson/mtls-go-example
    • 将目录更改为克隆的存储库:
    1. $ pushd mtls-go-example
    • nginx.example.com 生成证书。使用以下命令的任何密码:
    1. $ ./generate.sh nginx.example.com password

    遇见所有的问题请输入 y 来回答。

    • 将证书移动到 nginx.example.com 目录:
    1. $ mkdir ~+1/nginx.example.com && mv 1_root 2_intermediate 3_application 4_client ~+1/nginx.example.com
    • 返回根目录:
    1. $ popd

    部署 NGINX 服务器

    • 创建一个 Kubernetes Secret来保存服务器的证书。
    1. $ kubectl create secret tls nginx-server-certs --key nginx.example.com/3_application/private/nginx.example.com.key.pem --cert nginx.example.com/3_application/certs/nginx.example.com.cert.pem
    • 为 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
    • 创建 Kubernetes ConfigMap保持 NGINX 服务器的配置:
    1. $ kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf
    • 部署 NGINX 服务器:
    1. $ kubectl apply -f - <<EOF
    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. run: my-nginx
    28. spec:
    29. containers:
    30. - name: my-nginx
    31. image: nginx
    32. ports:
    33. - containerPort: 443
    34. volumeMounts:
    35. - name: nginx-config
    36. mountPath: /etc/nginx
    37. readOnly: true
    38. - name: nginx-server-certs
    39. mountPath: /etc/nginx-server-certs
    40. readOnly: true
    41. volumes:
    42. - name: nginx-config
    43. configMap:
    44. name: nginx-configmap
    45. - name: nginx-server-certs
    46. secret:
    47. secretName: nginx-server-certs
    48. EOF
    • 要测试 NGINX 服务器是否已成功部署,请从其 sidecar 代理向服务器发送请求,而不检查服务器的证书(使用 curl-k 选项)。确保正确打印服务器的证书,即 common name 等于 nginx.example.com
    1. $ kubectl exec -it $(kubectl get pod -l run=my-nginx -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl -v -k --resolve nginx.example.com:443:127.0.0.1 https://nginx.example.com
    2. ...
    3. SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
    4. server certificate verification SKIPPED
    5. server certificate status verification SKIPPED
    6. common name: nginx.example.com (matched)
    7. server certificate expiration date OK
    8. server certificate activation date OK
    9. certificate public key: RSA
    10. certificate version: #3
    11. subject: C=US,ST=Denial,L=Springfield,O=Dis,CN=nginx.example.com
    12. start date: Wed, 15 Aug 2018 07:29:07 GMT
    13. expire date: Sun, 25 Aug 2019 07:29:07 GMT
    14. issuer: C=US,ST=Denial,O=Dis,CN=nginx.example.com
    15. > GET / HTTP/1.1
    16. > User-Agent: curl/7.35.0
    17. > Host: nginx.example.com
    18. ...
    19. < HTTP/1.1 200 OK
    20. < Server: nginx/1.15.2
    21. ...
    22. <!DOCTYPE html>
    23. <html>
    24. <head>
    25. <title>Welcome to nginx!</title>
    26. ...

    配置 Ingress Gateway

    • 为端口 443 定义一个带有 server 部分的 Gateway 。注意 PASSTHROUGH tls mode 指示网关按原样传递入口流量,而不终止 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 # 使用 istio 默认的 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
    • 配置通过 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. sni_hosts:
    15. - nginx.example.com
    16. route:
    17. - destination:
    18. host: my-nginx
    19. port:
    20. number: 443
    21. EOF
    • 按照确定入口IP和端口中的说明定义 SECURE_INGRESS_PORTINGRESS_HOST 环境变量。

    • 从群集外部访问 NGINX 服务。请注意,服务器返回正确的证书并成功验证(打印 SSL certificate verify ok )。

    1. $ curl -v --resolve nginx.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST --cacert nginx.example.com/2_intermediate/certs/ca-chain.cert.pem https://nginx.example.com:$SECURE_INGRESS_PORT
    2. Server certificate:
    3. subject: C=US; ST=Denial; L=Springfield; O=Dis; CN=nginx.example.com
    4. start date: Aug 15 07:29:07 2018 GMT
    5. expire date: Aug 25 07:29:07 2019 GMT
    6. common name: nginx.example.com (matched)
    7. issuer: C=US; ST=Denial; O=Dis; CN=nginx.example.com
    8. SSL certificate verify ok.
    9. < HTTP/1.1 200 OK
    10. < Server: nginx/1.15.2
    11. ...
    12. <html>
    13. <head>
    14. <title>Welcome to nginx!</title>

    清理

    • 删除创建的 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
    6. $ kubectl delete virtualservice nginx
    • 删除包含证书的目录和用于生成证书的存储库:
    1. $ rm -rf nginx.example.com mtls-go-example
    • 删除此示例中使用的生成的配置文件:
    1. $ rm -f ./nginx.conf