通过 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

相关内容

深入了解双向 TLS

对 Istio 的自动双向 TLS 认证功能进行体验和测试。

基于 Istio 的 Micro-Segmentation 授权

描述 Istio 的授权功能以及如何在各种用例中使用它。

使用外部 Web 服务

描述基于 Istio Bookinfo 示例的简单场景。

Citadel 的健康检查

如何在 Kubernetes 中启用 Citadel 的健康检查。

HTTP 服务的访问控制

展示为 HTTP 服务设置基于角色的访问控制方法。

Istio Service 健康检查

展示如何对 Istio service 进行健康检查。