[zh]Sync content/zh/docs/tasks/security/authentication/mtls-migration/index.md (#11884)

* Update index.md

* Update index.md

* Update index.md

* Update index.md

* Update index.md
This commit is contained in:
yanrongshi 2022-09-17 20:58:16 +08:00 committed by GitHub
parent 7355f05564
commit 5b6b008ee3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 48 additions and 63 deletions

View File

@ -11,24 +11,27 @@ test: yes
本任务阐述如何将 Istio 服务的请求从明文模式平滑过渡至双向 TLS 模式,并确保在整个迁移过程中不干扰在线流量的正常通信。
针对多服务跨网络通信的应用场景,通常希望逐步将所有服务迁移到 Istio 网格中。如此一来,在迁移过程中,将出现只有部分服务注入了 Envoy sidecar 的情况。对于一个已注入 sidecar 的服务而言,一旦开启服务的双向 TLS 通信模式,那么传统客户端(即:没有 Envoy 的客户端)将无法与之通信,因为这些客户端没有注入 Envoy sidecar 和客户端证书。为了解决这个问题Istio 认证策略提供了一种 “PERMISSIVE” 模式。当启用 “PERMISSIVE” 模式时,服务可以同时接收 HTTP 和双向 TLS 请求。
在调用其他工作负载时Istio 会自动配置工作负载 sidecar 以使用[双向 TLS](/zh/docs/tasks/security/authentication/authn-policy/#auto-mutual-tls)。
默认情况下Istio 使用 `PERMISSIVE` 模式配置目标工作负载。
当启用 `PERMISSIVE` 模式时,服务可以接受明文和双向 TLS 流量。
为了只允许双向 TLS 流量,需要将配置更改为 `STRICT` 模式。
这样,便可以将 Istio 服务的通信模式配置为双向 TLS与此同时不干扰其与传统服务之间的通信。此外可以使用
[Grafana dashboard](/zh/docs/tasks/observability/metrics/using-istio-dashboard/) 检查哪些服务仍然向 "PERMISSIVE" 模式的服务发送明文请求,然后选择在这些服务迁移结束后关闭目标服务的 "PERMISSIVE" 模式,将其锁定为只接收双向 TLS 请求。
可以使用
[Grafana dashboard](/zh/docs/tasks/observability/metrics/using-istio-dashboard/) 检查哪些服务仍然向 `PERMISSIVE` 模式的服务发送明文请求,然后选择在这些服务迁移结束后,将其锁定为只接收双向 TLS 请求。
## 开始之前{#before-you-begin}
* 理解 Istio [认证策略](/zh/docs/concepts/security/#authentication-policies)以及相关的[双向 TLS 认证](/zh/docs/concepts/security/#mutual-TLS-authentication)概念。
* 理解 Istio [认证策略](/zh/docs/concepts/security/#authentication-policies)以及相关的[双向 TLS 认证](/zh/docs/concepts/security/#mutual-tls-authentication)概念。
* 准备一个 Kubernetes 集群并部署好 Istio不要开启全局双向 TLS (如:可以使用[安装步骤](/zh/docs/setup/getting-started)中提供的 demo 配置 profile或者将安装选项 `global.mtls.enabled` 设置为 false
* * 阅读[认证策略任务](/zh/docs/tasks/security/authentication/authn-policy),了解如何配置认证策略
* demo 准备
* 创建如下命名空间并在其中都部署上 [httpbin]({{< github_tree >}}/samples/httpbin) 和 [sleep]({{< github_tree >}}/samples/sleep),注入 sidecar。
* `foo`
* `bar`
* 有一个安装了 Istio 的 Kubernetes 集群,但没有启用全局双向 TLS例如使用[安装步骤](/zh/docs/setup/getting-started)中描述的 `default` 配置文件)。
* 创建如下命名空间并在其中部署 [sleep]({{< github_tree >}}/samples/sleep),不注入 sidecar
* `legacy`
在此任务中,您可以通过创建示例工作负载并修改策略以在工作负载之间强制执行 STRICT 双向 TLS 来尝试迁移过程。
## 设置集群{#set-up-the-cluster}
* 创建两个命名空间:`foo` 和 `bar`,并在这两个命名空间上部署 [httpbin]({{< github_tree >}}/samples/httpbin)、[sleep]({{< github_tree >}}/samples/sleep) 和 Sidecar。
{{< text bash >}}
$ kubectl create ns foo
@ -37,75 +40,51 @@ test: yes
$ 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/sleep/sleep.yaml@) -n bar
{{< /text >}}
* 创建另一个命名空间 `legacy`,并在没有 Sidecar 的情况下部署 [sleep]({{< github_tree >}}/samples/sleep)
{{< text bash >}}
$ kubectl create ns legacy
$ kubectl apply -f @samples/sleep/sleep.yaml@ -n legacy
{{< /text >}}
* (使用 curl 命令)从每个 sleep pod (命名空间为 `foo``bar` 或 `legacy`)分别向 `httpbin.foo` 发送 http 请求。所有请求都应成功响应,返回 HTTP code 200。
* (使用 curl 命令)从每个 Sleep Pod (命名空间为 `foo``bar` 或 `legacy`)分别向 `httpbin.foo` 发送 http 请求。所有请求都应成功响应,返回 HTTP code 200。
{{< text bash >}}
$ for from in "foo" "bar" "legacy"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.foo: %{http_code}\n"; done
$ 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
sleep.foo to httpbin.foo: 200
sleep.foo to httpbin.bar: 200
sleep.bar to httpbin.foo: 200
sleep.bar to httpbin.bar: 200
sleep.legacy to httpbin.foo: 200
sleep.legacy to httpbin.bar: 200
{{< /text >}}
* 验证没有在系统中设置认证策略或目标规则(控制面板除外):
{{< tip >}}
如果任何 curl 命令失败,请确保可能干扰 httpbin 服务请求的现有身份验证策略或目标规则。
{{< text bash >}}
$ kubectl get policies.authentication.istio.io --all-namespaces
NAMESPACE NAME AGE
istio-system grafana-ports-mtls-disabled 3m
$ kubectl get peerauthentication --all-namespaces
No resources found
{{< /text >}}
{{< text bash >}}
$ kubectl get destinationrule --all-namespaces
NAMESPACE NAME HOST AGE
istio-system istio-multicluster-destinationrule *.global 35s
istio-system istio-policy istio-policy.istio-system.svc.cluster.local 35s
istio-system istio-telemetry istio-telemetry.istio-system.svc.cluster.local 33s
No resources found
{{< /text >}}
## 配置客户端发送双向 TLS 请求{#configure-clients-to-send-mutual-TLS-traffic}
{{< /tip >}}
设置 `DestinationRule`,配置 Istio 服务发送双向 TLS 请求。
{{< text bash >}}
$ cat <<EOF | kubectl apply -n foo -f -
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "example-httpbin-istio-client-mtls"
spec:
host: httpbin.foo.svc.cluster.local
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
EOF
{{< /text >}}
`sleep.foo``sleep.bar` 开始向 `httpbin.foo` 发送双向 TLS 请求。因为 `sleep.legacy` 没有注入 sidecar`DestinationRule` 不会对其起作用,所以 `sleep.legacy` 仍然向 `httpbin.foo` 发送明文请求。
现在,我们确认一下,所有发送至 `httpbin.foo` 的请求仍会响应成功。
{{< text bash >}}
$ for from in "foo" "bar" "legacy"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.foo: %{http_code}\n"; done
sleep.foo to httpbin.foo: 200
sleep.bar to httpbin.foo: 200
sleep.legacy to httpbin.foo: 200
{{< /text >}}
也可以指定一部分客户端使用 [`DestinationRule`](/zh/docs/reference/config/networking/destination-rule/) 中设置的 `ISTIO_MUTUAL` 双向 TLS 通信模式。
检查 [Grafana to monitor](/zh/docs/tasks/observability/metrics/using-istio-dashboard/) 验证设置起效后,再扩大作用范围,最终应用到所有的 Istio 客户端服务。
## 锁定为双向 TLS{#lock-down-to-mutual-TLS}
## 通过命名空间锁定到双向 TLS{#lock-down-to-mutual-tls-by-namespace}
当所有客户端服务都成功迁移至 Istio 之后,注入 Envoy sidecar便可以锁定 `httpbin.foo` 只接收双向 TLS 请求。
{{< text bash >}}
$ cat <<EOF | kubectl apply -n foo -f -
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
$ kubectl apply -n foo -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: "default"
spec:
@ -130,7 +109,7 @@ sleep.legacy to httpbin.bar: 200
如果你安装 Istio 时带有参数 `values.global.proxy.privileged=true`,那么你可以使用 `tcpdump` 来验证流量是否被加密。
{{< text bash >}}
$ kubectl exec -nfoo "$(kubectl get pod -nfoo -lapp=httpbin -ojsonpath={.items..metadata.name})" -c istio-proxy -it -- sudo tcpdump dst port 80 -A
$ 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
{{< /text >}}
@ -162,11 +141,17 @@ EOF
$ 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
{{< /text >}}
## 清除{#cleanup}
## 清除{#clean-up-the-example}
清除所有资源
1. 删除网格范围的身份验证策略
{{< text bash >}}
$ kubectl delete ns foo bar legacy
Namespaces foo bar legacy deleted.
{{< /text >}}
{{< text bash >}}
$ kubectl delete peerauthentication -n istio-system default
{{< /text >}}
1. 删除用于测试的命名空间。
{{< text bash >}}
$ kubectl delete ns foo bar legacy
Namespaces foo bar legacy deleted.
{{< /text >}}