• 通过 HTTPS 进行双向 TLS
    • 开始之前
      • 生成证书和 configmap
    • 在没有 Istio sidecar 的情况下部署 HTTPS 服务
      • 使用 Istio sidecar 和禁用双向 TLS 创建 HTTPS 服务
      • 用 Istio sidecar 创建一个 HTTPS 服务,并使用双向 TLS
    • 清除

    通过 HTTPS 进行双向 TLS

    这个任务展示了 Istio 双向 TLS 是如何与 HTTPS 服务一起工作的。它包括:

    • 在没有 Istio sidecar 的情况下部署 HTTPS 服务

    • 关闭 Istio 双向 TLS 认证情况下部署 HTTPS 服务

    • 部署一个启动双向 TLS 的 HTTPS 服务。对于每个部署,请连接到此服务并验证其是否有效。

    当 Istio sidecar 使用 HTTPS 服务部署时,代理将自动从 L7 降至 L4(无论是否启用了双向 TLS),这就意味着它不会终止原来的 HTTPS 通信。这就是为什么 Istio 可以在 HTTPS 服务上工作。

    开始之前

    按照下面的快速开始设置 Istio。注意,在安装步骤第5步中,身份验证应该被禁用

    生成证书和 configmap

    您需要安装 openssl 来运行以下命令:

    1. $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/nginx.key -out /tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"
    2. $ kubectl create secret tls nginxsecret --key /tmp/nginx.key --cert /tmp/nginx.crt
    3. secret "nginxsecret" created

    创建用于 HTTPS 服务的 configmap

    1. $ kubectl create configmap nginxconfigmap --from-file=samples/https/default.conf
    2. configmap "nginxconfigmap" created

    在没有 Istio sidecar 的情况下部署 HTTPS 服务

    本节将创建一个基于 nginx 的 HTTPS 服务。

    Zip

    1. $ kubectl apply -f @samples/https/nginx-app.yaml@
    2. service "my-nginx" created
    3. replicationcontroller "my-nginx" created

    然后,创建另一个 pod 来调用这个服务。

    Zip

    1. $ kubectl apply -f <(bin/istioctl kube-inject -f @samples/sleep/sleep.yaml@)

    获取 pods

    1. $ kubectl get pod
    2. NAME READY STATUS RESTARTS AGE
    3. my-nginx-jwwck 1/1 Running 0 1h
    4. sleep-847544bbfc-d27jg 2/2 Running 0 18h

    SSH 进入包含 sleep pod 的 istio-proxy 容器。

    1. $ kubectl exec -it $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy /bin/bash

    调用 my-nginx

    1. $ curl https://my-nginx -k
    2. ...
    3. <h1>Welcome to nginx!</h1>
    4. ...

    你可以把上面的三个命令合并成一个:

    1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl https://my-nginx -k
    2. ...
    3. <h1>Welcome to nginx!</h1>
    4. ...

    使用 Istio sidecar 和禁用双向 TLS 创建 HTTPS 服务

    在”开始之前”部分中,Istio 控制平面被部署在双向 TLS 禁用的情况下。所以您只需要使用 sidecar 重新部署 NGINX HTTPS 服务。

    删除这个 HTTPS 服务

    Zip

    1. $ kubectl delete -f @samples/https/nginx-app.yaml@

    用一个 sidecar 来部署它

    Zip

    1. $ kubectl apply -f <(bin/istioctl kube-inject -f @samples/https/nginx-app.yaml@)

    确保这个 pod 已经启动并运行

    1. $ kubectl get pod
    2. NAME READY STATUS RESTARTS AGE
    3. my-nginx-6svcc 2/2 Running 0 1h
    4. sleep-847544bbfc-d27jg 2/2 Running 0 18h

    运行

    1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://my-nginx -k
    2. ...
    3. <h1>Welcome to nginx!</h1>
    4. ...

    如果从 istio-proxy 容器运行,它也应该正常运行

    1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl https://my-nginx -k
    2. ...
    3. <h1>Welcome to nginx!</h1>
    4. ...



    这个例子是从 Kubernetes 的例子中引用的。

    用 Istio sidecar 创建一个 HTTPS 服务,并使用双向 TLS

    您需要使用启用了双向 TLS 的 Istio 控制平面。如果您已经安装了 Istio 控制平面,并安装了双向 TLS,请删除它:

    1. $ kubectl delete -f install/kubernetes/istio-demo.yaml

    等待一切都完成了,也就是说在控制平面名称空间(istio-system)中没有 pod。

    1. $ kubectl get pod -n istio-system
    2. No resources found.

    然后,部署启用了双向 TLS 的 Istio 控制平面:

    1. $ kubectl apply -f install/kubernetes/istio-demo-auth.yaml

    确保一切正常运转:

    1. $ kubectl get po -n istio-system
    2. NAME READY STATUS RESTARTS AGE
    3. grafana-6f6dff9986-r6xnq 1/1 Running 0 23h
    4. istio-citadel-599f7cbd46-85mtq 1/1 Running 0 1h
    5. istio-cleanup-old-ca-mcq94 0/1 Completed 0 23h
    6. istio-egressgateway-78dd788b6d-jfcq5 1/1 Running 0 23h
    7. istio-ingressgateway-7dd84b68d6-dxf28 1/1 Running 0 23h
    8. istio-mixer-post-install-g8n9d 0/1 Completed 0 23h
    9. istio-pilot-d5bbc5c59-6lws4 2/2 Running 0 23h
    10. istio-policy-64595c6fff-svs6v 2/2 Running 0 23h
    11. istio-sidecar-injector-645c89bc64-h2dnx 1/1 Running 0 23h
    12. istio-statsd-prom-bridge-949999c4c-mv8qt 1/1 Running 0 23h
    13. istio-telemetry-cfb674b6c-rgdhb 2/2 Running 0 23h
    14. istio-tracing-754cdfd695-wqwr4 1/1 Running 0 23h
    15. prometheus-86cb6dd77c-ntw88 1/1 Running 0 23h

    然后重新部署 HTTPS 服务和 sleep 服务

    ZipZipZipZip

    1. $ kubectl delete -f <(bin/istioctl kube-inject -f @samples/sleep/sleep.yaml@)
    2. $ kubectl apply -f <(bin/istioctl kube-inject -f @samples/sleep/sleep.yaml@)
    3. $ kubectl delete -f <(bin/istioctl kube-inject -f @samples/https/nginx-app.yaml@)
    4. $ kubectl apply -f <(bin/istioctl kube-inject -f @samples/https/nginx-app.yaml@)

    确保 pod 已启动并正在运行

    1. $ kubectl get pod
    2. NAME READY STATUS RESTARTS AGE
    3. my-nginx-9dvet 2/2 Running 0 1h
    4. sleep-77f457bfdd-hdknx 2/2 Running 0 18h

    运行

    1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://my-nginx -k
    2. ...
    3. <h1>Welcome to nginx!</h1>
    4. ...

    因为工作流”sleep –> sleep-proxy –> nginx-proxy –> nginx”,整个过程是7层流量,在 sleep-proxy 和 nginx-proxy 之间有一个 L4 双向 TLS 加密。在这种情况下,一切都很好。

    但是,如果您从 istio-proxy 容器运行这个命令,它将无法工作。

    1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl https://my-nginx -k
    2. curl: (35) gnutls_handshake() failed: Handshake failed
    3. command terminated with exit code 35

    原因是对于工作流”sleep-proxy –> nginx-proxy –> nginx”,nginx-proxy 可以从 sleep-proxy 中获得双向的 TLS 流量。在上面的命令中,sleep-proxy 不提供客户端证书,因此它不会起作用。此外,即使是 sleep-proxy 可以在上面的命令中提供客户端证书,它也不会工作,因为流量会从 nginx-proxy 降级到 nginx。

    清除

    ZipZip

    1. $ kubectl delete -f @samples/sleep/sleep.yaml@
    2. $ kubectl delete -f @samples/https/nginx-app.yaml@
    3. $ kubectl delete configmap nginxconfigmap
    4. $ kubectl delete secret nginxsecret