Mutual TLS over HTTPS(0.8)

这个task展示Istio Mutual TLS如何同HTTPS服务一起工作。它包括:

  • 部署一个没有Istio sidecar的HTTPS服务。
  • 部署一个不开启互相TLS认证的Istio HTTPS服务
  • 部署一个开启互相TLS认证的HTTPS服务。对每个部署,连接此服务并验证它是否工作。

当Istio sidecar采用HTTPS服务部署时,代理自动从L7降级为L4(无论是否启用互相TLS),这意味着它不会终止原始HTTPS流量。这就是Istio可以使用HTTPS服务的原因。

Before you begin

按照 quick start 的步骤安装Istio。注意在第五步禁用身份验证。

Generate certificates and configmap

你需要运行这个命令安装openssl:

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

secret “nginxsecret” created

为HTTPS服务创建一个configmap:

kubectl create configmap nginxconfigmap --from-file=samples/https/default.conf

configmap “nginxconfigmap” created

Deploy an HTTPS service without Istio sidecar

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

kubectl apply -f samples/https/nginx-app.yaml

service “my-nginx” created
replicationcontroller “my-nginx” created

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

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

查看以下pods

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

将ssh放入sleep的pod的istio代理容器中。

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

调用my-nginx

curl https://my-nginx -k
...
<h1>Welcome to nginx!</h1>
...

实际上你可以将上述三个命令合并为一个:

kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl https://my-nginx -k
...
<h1>Welcome to nginx!</h1>
...
Create an HTTPS service with the Istio sidecar and mutual TLS disabled

在“Before you begin” 那节,Istio控制平面在禁用相互TLS的情况下进行部署。所以你只需要用sidecar重新部署nginx HTTPS服务。

删除HTTPS服务。

kubectl delete -f samples/https/nginx-app.yaml

带有sidecar部署

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

确认pod启动并运行

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

并运行

kubectl exec sleep-847544bbfc-d27jg -c sleep -- curl https://my-nginx -k
...
<h1>Welcome to nginx!</h1>
...

如果你从istio-proxy容器运行,它应该也可以工作

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

这个示例可以在 kubernetes examples 中查看。

Create an HTTPS service with Istio sidecar with mutual TLS enabled

你需要启动互相TLS的情况下部署istio控制平面。如果你安装了禁用互相TLS的istio控制平面,请删除它:

kubectl delete -f install/kubernetes/istio.yaml

等到所有停止,即,控制层命名空间(istio-system)没有pod。

kubectl get pod -n istio-system

No resources found.

然后部署启用互相TLS认证的istio控制平面:

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

确保所有都启动并运行:

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

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

kubectl delete -f <(bin/istioctl kube-inject -f samples/sleep/sleep.yaml)
kubectl apply -f <(bin/istioctl kube-inject -f samples/sleep/sleep.yaml)
kubectl delete -f <(bin/istioctl kube-inject -f samples/https/nginx-app.yaml)
kubectl apply -f <(bin/istioctl kube-inject -f samples/https/nginx-app.yaml)

确认pod启动并运行

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

运行

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

原因在于对于工作流“sleep -> sleep-proxy -> nginx-proxy -> nginx”,整个工作流是L7流量,而在sleep-proxy和nginx-proxy之间存在L4互相TLS加密。在这种情况下,一切都工作的很好。

但,如果你从istio-proxy容器运行这个命令,它将不再工作

kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c istio-proxy -- curl https://my-nginx -k

curl: (35) gnutls_handshake() failed: Handshake failed
command terminated with exit code 35

原因在于工作流“sleep-proxy -> nginx-proxy -> nginx”,nginx-proxy期望从sleep-proxy获取相互TLS的流量。上面的命令中,sleep-proxy不提供客户端证书。因此,它不会工作。此外,即使sleep-proxy提供上述命令的客户端证书,它也不会工作,因为从nginx到nginx-proxy的流量将降级到http。

Cleanup

kubectl delete -f samples/sleep/sleep.yaml
kubectl delete -f samples/https/nginx-app.yaml
kubectl delete configmap nginxconfigmap
kubectl delete secret nginxsecret

猜你喜欢

转载自blog.csdn.net/ybt_c_index/article/details/80742382