双向 TLS 迁移
本任务演示如何确保您的工作负载在迁移到 Istio 时仅使用双向 TLS 进行通信。
Istio 会自动配置工作负载 sidecar 以使用 双向 TLS 来调用其他工作负载。默认情况下,Istio 使用 PERMISSIVE
模式配置目标工作负载。当启用 PERMISSIVE
模式时,服务可以接受明文和双向 TLS 流量。为了只允许双向 TLS 流量,需要将配置更改为 STRICT
模式。
您可以使用 Grafana 仪表盘 检查哪些工作负载仍在向 PERMISSIVE
模式下的工作负载发送明文流量,并在迁移完成后选择锁定它们。
开始之前
了解 Istio 身份验证策略 和相关的 双向 TLS 身份验证 概念。
阅读 身份验证策略任务,了解如何配置身份验证策略。
拥有已安装 Istio 的 Kubernetes 集群,但未启用全局双向 TLS(例如,使用 安装步骤 中描述的
default
配置文件)。
在此任务中,您可以通过创建示例工作负载并修改策略以在工作负载之间强制执行严格的双向 TLS 来尝试迁移过程。
设置集群
创建两个命名空间
foo
和bar
,并在两者上部署 httpbin 和 curl,以及它们的 sidecar。$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n foo $ kubectl create ns bar $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n bar $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n bar
创建另一个命名空间
legacy
,并在其中部署 curl,但没有 sidecar。$ kubectl create ns legacy $ kubectl apply -f @samples/curl/curl.yaml@ -n legacy
通过从
foo
、bar
和legacy
命名空间中的 curl pod(使用 curl)向httpbin.foo
和httpbin.bar
发送 http 请求来验证设置。所有请求都应成功,返回码为 200。$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=curl -n ${from} -o jsonpath={.items..metadata.name})" -c curl -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "curl.${from} to httpbin.${to}: %{http_code}\n"; done; done curl.foo to httpbin.foo: 200 curl.foo to httpbin.bar: 200 curl.bar to httpbin.foo: 200 curl.bar to httpbin.bar: 200 curl.legacy to httpbin.foo: 200 curl.legacy to httpbin.bar: 200
按命名空间锁定到双向 TLS
在将所有客户端迁移到 Istio 并注入 Envoy sidecar 后,您可以将 foo
命名空间中的工作负载锁定为仅接受双向 TLS 流量。
$ kubectl apply -n foo -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT
EOF
现在,您应该看到来自 curl.legacy
到 httpbin.foo
的请求失败。
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=curl -n ${from} -o jsonpath={.items..metadata.name})" -c curl -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "curl.${from} to httpbin.${to}: %{http_code}\n"; done; done
curl.foo to httpbin.foo: 200
curl.foo to httpbin.bar: 200
curl.bar to httpbin.foo: 200
curl.bar to httpbin.bar: 200
curl.legacy to httpbin.foo: 000
command terminated with exit code 56
curl.legacy to httpbin.bar: 200
如果您使用 values.global.proxy.privileged=true
安装了 Istio,则可以使用 tcpdump
来验证流量是否已加密。
$ kubectl exec -nfoo "$(kubectl get pod -nfoo -lapp=httpbin -ojsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port 80 -A
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
当分别从 curl.legacy
和 curl.foo
发送请求时,您将在输出中看到明文和密文。
如果您无法将所有服务迁移到 Istio(即,无法在所有服务中注入 Envoy sidecar),则需要继续使用 PERMISSIVE
模式。但是,当使用 PERMISSIVE
模式配置时,默认情况下不会对明文流量执行身份验证或授权检查。我们建议您使用 Istio 授权 为不同的路径配置不同的授权策略。
为整个网格锁定双向 TLS
您可以通过将策略放在 Istio 安装的系统命名空间中,将所有命名空间中的工作负载锁定为仅接受双向 TLS 流量。
$ kubectl apply -n istio-system -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT
EOF
现在,foo
和 bar
命名空间都只强制执行双向 TLS 流量,因此您应该看到来自 curl.legacy
的请求对两者都失败。
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=curl -n ${from} -o jsonpath={.items..metadata.name})" -c curl -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "curl.${from} to httpbin.${to}: %{http_code}\n"; done; done
清理示例
删除网格范围的身份验证策略。
$ kubectl delete peerauthentication -n foo default $ kubectl delete peerauthentication -n istio-system default
删除测试命名空间。
$ kubectl delete ns foo bar legacy Namespaces foo bar legacy deleted.