双向 TLS 迁移

    在调用其他工作负载时,Istio 会自动配置工作负载 sidecar 以使用双向 TLS。 默认情况下,Istio 使用 模式配置目标工作负载。 当启用 PERMISSIVE 模式时,服务可以接受明文和双向 TLS 流量。 为了只允许双向 TLS 流量,需要将配置更改为 STRICT 模式。

    您可以使用 检查哪些服务仍然向 PERMISSIVE 模式的服务发送明文请求,然后选择在这些服务迁移结束后,将其锁定为只接收双向 TLS 请求。

    • 理解 Istio 以及相关的双向 TLS 认证概念。

    • 阅读,了解如何配置认证策略。

    • 有一个安装了 Istio 的 Kubernetes 集群,但没有启用全局双向 TLS(例如,使用安装步骤中描述的 default 配置文件)。

    在此任务中,您可以通过创建示例工作负载并修改策略以在工作负载之间强制执行 STRICT 双向 TLS 来尝试迁移过程。

    • ZipZip

    • 创建另一个命名空间 legacy,并在没有 Sidecar 的情况下部署 sleep

      1. $ kubectl create ns legacy
      2. $ kubectl apply -f @samples/sleep/sleep.yaml@ -n legacy
    • (使用 curl 命令)从每个 Sleep Pod (命名空间为 foobarlegacy)分别向 httpbin.foo 发送 http 请求。所有请求都应成功响应,返回 HTTP code 200。

      1. $ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
      2. sleep.foo to httpbin.foo: 200
      3. sleep.bar to httpbin.foo: 200
      4. sleep.bar to httpbin.bar: 200
      5. sleep.legacy to httpbin.bar: 200

      如果任何 curl 命令失败,请确保可能干扰 httpbin 服务请求的现有身份验证策略或目标规则。

      1. $ kubectl get peerauthentication --all-namespaces
      2. No resources found

    当所有客户端服务都成功迁移至 Istio 之后,注入 Envoy sidecar,便可以锁定 httpbin.foo 只接收双向 TLS 请求。

    1. $ kubectl apply -n foo -f - <<EOF
    2. apiVersion: security.istio.io/v1beta1
    3. kind: PeerAuthentication
    4. metadata:
    5. name: "default"
    6. spec:
    7. mtls:
    8. mode: STRICT
    9. EOF
    1. sleep.foo to httpbin.foo: 200
    2. sleep.foo to httpbin.bar: 200
    3. sleep.bar to httpbin.foo: 200
    4. sleep.legacy to httpbin.foo: 000
    5. command terminated with exit code 56
    6. sleep.legacy to httpbin.bar: 200

    如果您安装 Istio 时带有参数 values.global.proxy.privileged=true,那么您可以使用 tcpdump 来验证流量是否被加密。

    1. $ kubectl exec -nfoo "$(kubectl get pod -nfoo -lapp=httpbin -ojsonpath={.items..metadata.name})" -c istio-proxy -- sudo tcpdump dst port 80 -A
    2. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    3. listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

    当分别从 sleep.legacysleep.foo 发送请求时,您将在输出中看到纯文本和加密文本。

    若无法将所有服务迁移至 Istio (注入 Envoy sidecar),则必须开启 PERMISSIVE 模式。 然而,开启 PERMISSIVE 模式时,系统默认不对明文请求进行认证或授权检查。 推荐使用 来为不同的请求路径配置不同的授权策略。

    现在,foobar 命名空间都强制执行仅双向 TLS 流量,因此您应该会看到来自 sleep.legacy 的请求访问两个命名空间的服务都失败了。

    1. $ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
    1. 删除网格范围的身份验证策略。

      1. $ kubectl delete peerauthentication -n foo default
      2. $ kubectl delete peerauthentication -n istio-system default
    2. 删除用于测试的命名空间。

      1. Namespaces foo bar legacy deleted.