From 688f2a376ad48dec6dcb28c9f8391c7846ed0e3b Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 3 Jun 2023 18:22:40 +0800 Subject: [PATCH] [zh] sync /egress/egress-kubernetes-services/ (#13251) --- .../egress-kubernetes-services/index.md | 71 ++++++++++++------- .../egress/egress-tls-origination/index.md | 64 +++++++++-------- 2 files changed, 78 insertions(+), 57 deletions(-) diff --git a/content/zh/docs/tasks/traffic-management/egress/egress-kubernetes-services/index.md b/content/zh/docs/tasks/traffic-management/egress/egress-kubernetes-services/index.md index bbb3bf2b86..ea40a90cb1 100644 --- a/content/zh/docs/tasks/traffic-management/egress/egress-kubernetes-services/index.md +++ b/content/zh/docs/tasks/traffic-management/egress/egress-kubernetes-services/index.md @@ -7,48 +7,59 @@ owner: istio/wg-networking-maintainers test: yes --- -Kubernetes [ExternalName](https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#externalname) 服务和带 [Endpoints](https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#services-without-selectors) 的 Kubernetes 服务使你可以创建一个外部服务的本地 DNS 别名。这个 DNS 别名与本地服务的 DNS 条目具有相同的形式,即 `..svc.cluster.local`。DNS 别名为您的工作负载提供“位置透明性”:工作负载可以以相同的方式调用本地和外部服务。如果您决定在某个时间在集群内部部署外部服务,您只需更新其 Kubernetes 服务以引用本地版本即可。工作负载将继续运行,而不会有任何变化。 +Kubernetes [ExternalName](https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#externalname) +服务和带 [Endpoints](https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#services-without-selectors) +的 Kubernetes 服务使您可以创建一个外部服务的本地 DNS 别名。这个 DNS 别名与本地服务的 DNS 条目具有相同的形式, +即 `..svc.cluster.local`。DNS 别名为您的工作负载提供“位置透明性”: +工作负载可以以相同的方式调用本地和外部服务。如果您决定在某个时间在集群内部部署外部服务, +您只需更新其 Kubernetes 服务以引用本地版本即可。工作负载将继续运行,而不会有任何变化。 -这部分内容表明这些访问外部服务的 Kubernetes 机制在 Istio 中依然有效。您只需要配置使用 TLS 模式即可,并不需要 Istio 的[双向 TLS](/zh/docs/concepts/security/#mutual-TLS-authentication)。因为外部服务不是 Istio 服务网格的一部分,所以它们无法执行 Istio 的双向 TLS。您在配置 TLS 模式时,一要按照外部服务的 TLS 模式的要求、二要遵从您的工作负载访问外部服务的方式。当您的工作负载发起的是 HTTP 请求但是外部服务需要 TLS,你可以通过 Istio 发起 TLS。当您的工作负载已经使用 TLS 来加密流量,您可以禁用 Istio 的双向 TLS。 +本页内容表明这些访问外部服务的 Kubernetes 机制在 Istio 中依然有效。 +您只需配置使用 TLS 模式即可,并不需要 Istio 的[双向 TLS](/zh/docs/concepts/security/#mutual-TLS-authentication)。 +因为外部服务不是 Istio 服务网格的一部分,所以它们无法执行 Istio 的双向 TLS。 +您在配置 TLS 模式时,一要按照外部服务的 TLS 模式的要求,二要遵从您的工作负载访问外部服务的方式。 +当您的工作负载发起的是 HTTP 请求但是外部服务需要 TLS 时,您可以通过 Istio 发起 TLS。 +当您的工作负载已经使用 TLS 来加密流量时,您可以禁用 Istio 的双向 TLS。 {{< warning >}} -本页介绍 Istio 如何与现有 Kubernetes 配置集成。对于新部署,我们建议 -遵循[访问出口服务](/zh/docs/tasks/traffic-management/egress/egress-control/)。 +本页介绍 Istio 如何与现有 Kubernetes 配置集成。对于新部署, +我们建议遵循[访问 Egress 服务](/zh/docs/tasks/traffic-management/egress/egress-control/)。 {{< /warning >}} -虽然此部分的示例使用 HTTP 协议,但是用于引导出口流量的 Kubernetes 服务也可以与其他协议一起使用。 +虽然本页的示例使用 HTTP 协议,但是用于引导 Egress 流量的 Kubernetes 服务也可以与其他协议一起使用。 {{< boilerplate before-you-begin-egress >}} -* 为没有 Istio 控制的源 pod 创建一个命名空间: +* 为没有 Istio 控制的源 Pod 创建一个命名空间: {{< text bash >}} $ kubectl create namespace without-istio {{< /text >}} -* 启动 [sleep]({{< github_tree >}}/samples/sleep) 在命名空间 `without-istio` 中的事例。 +* 在命名空间 `without-istio` 中启动 [sleep]({{< github_tree >}}/samples/sleep) 示例。 {{< text bash >}} $ kubectl apply -f @samples/sleep/sleep.yaml@ -n without-istio {{< /text >}} -* 发送请求,创建环境变量 `SOURCE_POD_WITHOUT_ISTIO` 来保存源 pod 的名称: +* 要发送请求,可以创建环境变量 `SOURCE_POD_WITHOUT_ISTIO` 来保存源 Pod 的名称: {{< text bash >}} - $ export SOURCE_POD_WITHOUT_ISTIO=$(kubectl get pod -n without-istio -l app=sleep -o jsonpath={.items..metadata.name}) + $ export SOURCE_POD_WITHOUT_ISTIO="$(kubectl get pod -n without-istio -l app=sleep -o jsonpath={.items..metadata.name})" {{< /text >}} -* 验证是否未注入 Istio Sidecar,即 pod 中有一个容器: +* 验证是否未注入 Istio Sidecar,即 Pod 中有一个容器: {{< text bash >}} - $ kubectl get pod $SOURCE_POD_WITHOUT_ISTIO -n without-istio + $ kubectl get pod "$SOURCE_POD_WITHOUT_ISTIO" -n without-istio NAME READY STATUS RESTARTS AGE sleep-66c8d79ff5-8tqrl 1/1 Running 0 32s {{< /text >}} ## Kubernetes ExternalName 服务访问外部服务{#ks-external-name-service-to-access-an-external-service} -1. 在默认命名空间中,为 `httpbin.org` 创建一个 Kubernetes [ExternalName](https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#externalname) 服务: +1. 在默认命名空间中,为 `httpbin.org` 创建一个 Kubernetes + [ExternalName](https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#externalname) 服务: {{< text bash >}} $ kubectl apply -f - < httpbin.org 80/TCP 4s {{< /text >}} -1. 从没有 Istio Sidecar 的源 pod 通过 Kubernetes 服务的主机名访问 `httpbin.org`。注意下面的 _curl_ 命令使用 [Kubernetes DNS 格式用于服务](https://v1-13.docs.kubernetes.io/docs/concepts/services-networking/dns-pod-service/#a-records):`..svc.cluster.local`。 +1. 从没有 Istio Sidecar 的源 Pod 通过 Kubernetes 服务的主机名访问 `httpbin.org`。注意下面的 **curl** 命令使用 + [Kubernetes DNS 格式用于服务](https://v1-13.docs.kubernetes.io/docs/concepts/services-networking/dns-pod-service/#a-records):`..svc.cluster.local`。 {{< text bash >}} - $ kubectl exec -it $SOURCE_POD_WITHOUT_ISTIO -n without-istio -c sleep -- curl my-httpbin.default.svc.cluster.local/headers + $ kubectl exec "$SOURCE_POD_WITHOUT_ISTIO" -n without-istio -c sleep -- curl -sS my-httpbin.default.svc.cluster.local/headers { "headers": { "Accept": "*/*", @@ -87,8 +99,9 @@ Kubernetes [ExternalName](https://kubernetes.io/zh-cn/docs/concepts/services-net } {{< /text >}} -1. 在这个例子中,未加密的 HTTP 请求被发送到 `httpbin.org`。仅出于示例目的,您禁用 TLS 模式,并允许外部服务的未加密流量。在现实生活中,我们建议 - 由 Istio 执行 [Egress TLS 起源](/zh/docs/tasks/traffic-management/egress/egress-tls-origination)。 +1. 在这个例子中,未加密的 HTTP 请求被发送到 `httpbin.org`。 + 仅出于示例目的,您禁用 TLS 模式,并允许外部服务的未加密流量。在现实生活中,我们建议 + 由 Istio 执行 [Egress TLS Origination](/zh/docs/tasks/traffic-management/egress/egress-tls-origination)。 {{< text bash >}} $ kubectl apply -f - <}} -1. 通过带有 Istio Sidecar 的源 pod 通过 Kubernetes 服务的主机名访问 `httpbin.org`。注意 Istio Sidecar 添加的 headers,例如,`X-Istio-Attributes` 和 `X-Envoy-Decorator-Operation`。另请注意 `Host` header 等于您的服务的主机名。 +1. 通过带有 Istio Sidecar 的源 Pod 通过 Kubernetes 服务的主机名访问 `httpbin.org`。 + 注意 Istio Sidecar 添加的 header,例如,`X-Istio-Attributes` 和 `X-Envoy-Decorator-Operation`。 + 另请注意 `Host` header 等于您的服务的主机名。 {{< text bash >}} $ kubectl exec "$SOURCE_POD" -c sleep -- curl -sS my-httpbin.default.svc.cluster.local/headers @@ -149,7 +164,8 @@ $ kubectl delete service my-httpbin EOF {{< /text >}} -1. 为您的服务创建 endpoints。从 [Wikipedia 范围列表](https://www.mediawiki.org/wiki/Wikipedia_Zero/IP_Addresses)中选择几个 IP。 +1. 为您的服务创建 endpoints。 + 从 [Wikipedia 范围列表](https://www.mediawiki.org/wiki/Wikipedia_Zero/IP_Addresses)中选择几个 IP。 {{< text bash >}} $ kubectl apply -f - <}} -1. 观察您的服务。请注意,它具有一个群集 IP,您可以使用它访问 `wikipedia.org`。 +1. 观察您的服务。请注意,它具有一个集群 IP,您可以使用它访问 `wikipedia.org`。 {{< text bash >}} $ kubectl get svc my-wikipedia @@ -175,14 +191,16 @@ $ kubectl delete service my-httpbin my-wikipedia ClusterIP 172.21.156.230 443/TCP 21h {{< /text >}} -1. 从没有 Istio sidecar 的源 Pod 通过您的向您的 Kubernetes 服务集群 IP 来发送 HTTPS 请求到 `wikipedia.org`。使用 `curl` 的 `--resolve` 选项通过集群 IP 访问 `wikipedia.org`: +1. 从没有 Istio Sidecar 的源 Pod 通过您的 Kubernetes 服务集群 IP 来发送 HTTPS 请求到 `wikipedia.org`。 + 使用 `curl` 的 `--resolve` 选项通过集群 IP 访问 `wikipedia.org`: {{< text bash >}} - $ kubectl exec -it $SOURCE_POD_WITHOUT_ISTIO -n without-istio -c sleep -- curl -s --resolve en.wikipedia.org:443:$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}') https://en.wikipedia.org/wiki/Main_Page | grep -o ".*" + $ kubectl exec "$SOURCE_POD_WITHOUT_ISTIO" -n without-istio -c sleep -- curl -sS --resolve en.wikipedia.org:443:"$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}')" https://en.wikipedia.org/wiki/Main_Page | grep -o ".*" Wikipedia, the free encyclopedia {{< /text >}} -1. 在这种情况下,工作负载将 HTTPS 请求(开放 TLS 连接)发送到 `wikipedia.org`。流量已经通过工作负载加密,因此您可以安全地禁用 Istio 的双向 TLS: +1. 在这种情况下,工作负载将 HTTPS 请求(开放 TLS 连接)发送到 `wikipedia.org`。 + 流量已经通过工作负载加密,因此您可以安全地禁用 Istio 的双向 TLS: {{< text bash >}} $ kubectl apply -f - <}} -1. 使用 Istio Sidecar 从源 Pod 中通过 Kubernetes 服务的群集 IP 访问 `wikipedia.org`: +1. 使用 Istio Sidecar 从源 Pod 中通过 Kubernetes 服务的集群 IP 访问 `wikipedia.org`: {{< text bash >}} - $ kubectl exec -it $SOURCE_POD -c sleep -- curl -s --resolve en.wikipedia.org:443:$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}') https://en.wikipedia.org/wiki/Main_Page | grep -o ".*" + $ kubectl exec "$SOURCE_POD" -c sleep -- curl -sS --resolve en.wikipedia.org:443:"$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}')" https://en.wikipedia.org/wiki/Main_Page | grep -o ".*" Wikipedia, the free encyclopedia {{< /text >}} -1. 检查访问是否确实由群集 IP 完成。在 `curl -v` 的输出中注意这句话 `Connected to en.wikipedia.org (172.21.156.230)`,其中提到了在您的服务输出中作为群集 IP 打印的 IP。 +1. 检查访问是否确实由集群 IP 完成。在 `curl -v` 的输出中注意这句话 + `Connected to en.wikipedia.org (172.21.156.230)`,其中提到了在您的服务输出中作为集群 IP 打印的 IP。 {{< text bash >}} - $ kubectl exec -it $SOURCE_POD -c sleep -- curl -v --resolve en.wikipedia.org:443:$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}') https://en.wikipedia.org/wiki/Main_Page -o /dev/null + $ kubectl exec "$SOURCE_POD" -c sleep -- curl -sS -v --resolve en.wikipedia.org:443:"$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}')" https://en.wikipedia.org/wiki/Main_Page -o /dev/null * Added en.wikipedia.org:443:172.21.156.230 to DNS cache * Hostname en.wikipedia.org was found in DNS cache * Trying 172.21.156.230... diff --git a/content/zh/docs/tasks/traffic-management/egress/egress-tls-origination/index.md b/content/zh/docs/tasks/traffic-management/egress/egress-tls-origination/index.md index 33f795f5e9..e8386e822a 100644 --- a/content/zh/docs/tasks/traffic-management/egress/egress-tls-origination/index.md +++ b/content/zh/docs/tasks/traffic-management/egress/egress-tls-origination/index.md @@ -14,13 +14,15 @@ test: yes 本示例将演示如何通过配置 Istio 去实现对发往外部服务的流量的 {{< gloss >}}TLS origination{{< /gloss >}}。 若此时原始的流量为 HTTP,则 Istio 会将其转换为 HTTPS 连接。 -## 案例{#use-case} +## 使用场景{#use-case} -假设有一个遗留应用正在使用 HTTP 和外部服务进行通信。而运行该应用的组织却收到了一个新的需求,该需求要求必须对所有外部的流量进行加密。 +假设有一个传统应用正在使用 HTTP 和外部服务进行通信。 +而运行该应用的组织却收到了一个新的需求,该需求要求必须对所有外部的流量进行加密。 此时,使用 Istio 便可通过修改配置实现此需求,而无需更改应用中的任何代码。 该应用可以发送未加密的 HTTP 请求,然后 Istio 将为应用加密请求。 -从应用源头发送未加密的 HTTP 请求并让 Istio 执行 TSL 升级的另一个好处是可以产生更好的遥测并为未加密的请求提供更多的路由控制。 +从应用源头发送未加密的 HTTP 请求并让 Istio 执行 TSL +升级的另一个好处是可以产生更好的遥测并为未加密的请求提供更多的路由控制。 ## 开始之前{#before-you-begin} @@ -40,9 +42,9 @@ test: yes $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) {{< /text >}} - 实际上任何可以 `exec` 和 `curl` 的 Pod 都可以用来完成这一任务。 + 请注意,实际上任何可以 `exec` 和 `curl` 的 Pod 都可以用来完成这一任务。 -* 创建一个环境变量来保存用于将请求发送到外部服务的 pod 的名称。 +* 创建一个环境变量来保存用于将请求发送到外部服务 Pod 的名称。 如果您使用 [sleep]({{< github_tree >}}/samples/sleep) 示例,请运行: {{< text bash >}} @@ -51,7 +53,8 @@ test: yes ## 配置对外部服务的访问{#configuring-access-to-an-external-service} -首先,使用与 [Egress 流量控制](/zh/docs/tasks/traffic-management/egress/)任务中的相同的技术,配置对外部服务 `edition.cnn.com` 的访问。 +首先,使用与 [Egress 流量控制](/zh/docs/tasks/traffic-management/egress/)任务中的相同技术, +配置对外部服务 `edition.cnn.com` 的访问。 但这一次我们将使用单个 `ServiceEntry` 来启用对服务的 HTTP 和 HTTPS 访问。 1. 创建一个 `ServiceEntry` 启用对 `edition.cnn.com` 的访问: @@ -91,14 +94,15 @@ test: yes 输出应与上面类似(某些细节用省略号代替)。 -请注意 _curl_ 的 `-L` 标志,该标志指示 _curl_ 将遵循重定向。 -在这种情况下,服务器将对到 `http://edition.cnn.com/politics` 的 HTTP 请求返回重定向响应 ([301 Moved Permanently](https://tools.ietf.org/html/rfc2616#section-10.3.2))。 +请注意 **curl** 的 `-L` 标志,该标志指示 **curl** 将遵循重定向。 +在这种情况下,服务器将对到 `http://edition.cnn.com/politics` 的 HTTP 请求返回重定向响应 + ([301 Moved Permanently](https://tools.ietf.org/html/rfc2616#section-10.3.2))。 而重定向响应将指示客户端使用 HTTPS 向 `https://edition.cnn.com/politics` 重新发送请求。 对于第二个请求,服务器则返回了请求的内容和 _200 OK_ 状态码。 -尽管 _curl_ 命令简明地处理了重定向,但是这里有两个问题。 +尽管 **curl** 命令简明地处理了重定向,但是这里有两个问题。 第一个问题是请求冗余,它使获取 `http://edition.cnn.com/politics` 内容的延迟加倍。 -第二个问题是 URL 中的路径(在本例中为 _politics_ )被以明文的形式发送。 +第二个问题是 URL 中的路径(在本例中为 **politics** )被以明文的形式发送。 如果有人嗅探您的应用与 `edition.cnn.com` 之间的通信,他将会知晓该应用获取了此网站中哪些特定的内容。 而出于隐私的原因,您可能希望阻止这些内容被披露。 @@ -106,7 +110,8 @@ test: yes ## 用于 egress 流量的 TLS 发起{#TLS-origination-for-egress-traffic} -1. 重新定义上一节的 `ServiceEntry` 和 `VirtualService` 以重写 HTTP 请求端口,并添加一个 `DestinationRule` 以执行 TLS 发起。 +1. 重新定义上一节的 `ServiceEntry` 和 `VirtualService` 以重写 HTTP 请求端口, + 并添加一个 `DestinationRule` 以执行 TLS 发起。 {{< text syntax=bash snip_id=apply_origination >}} $ kubectl apply -f - <}} - 上面的 `DestinationRule` 将对端口80和 `ServiceEntry` 上的HTTP请求执行TLS发起。然后将端口 80 上的请求重定向到目标端口 443。 + 上面的 `DestinationRule` 将对端口 80 和 `ServiceEntry` 上的 HTTP 请求执行 TLS 发起。 + 然后将端口 80 上的请求重定向到目标端口 443。 1. 如上一节一样,向 `http://edition.cnn.com/politics` 发送 HTTP 请求: @@ -152,10 +158,10 @@ test: yes ... {{< /text >}} - 这次将会收到唯一的 _200 OK_ 响应。 - 因为 Istio 为 _curl_ 执行了 TSL 发起,原始的 HTTP 被升级为 HTTPS 并转发到 `edition.cnn.com`。 - 服务器直接返回内容而无需重定向。 - 这消除了客户端与服务器之间的请求冗余,使网格保持加密状态,隐藏了您的应用获取 `edition.cnn.com` 中 _politics_ 的事实。 + 这次将会收到唯一的 **200 OK** 响应。 + 因为 Istio 为 **curl** 执行了 TSL 发起,原始的 HTTP 被升级为 HTTPS 并转发到 `edition.cnn.com`。 + 服务器直接返回内容而无需重定向。这消除了客户端与服务器之间的请求冗余,使网格保持加密状态, + 隐藏了您的应用获取 `edition.cnn.com` 中 **politics** 的事实。 请注意,您使用了一些与上一节相同的命令。 您可以通过配置 Istio,使以编程方式访问外部服务的应用无需更改任何代码即可获得 TLS 发起的好处。 @@ -174,18 +180,19 @@ test: yes 在某些环境中,严格的安全性要求可能规定所有流量都必须加密,即使在 Node 的本地网络上也是如此。 此时,使用在此示例中描述的 TLS 发起是不能满足要求的,应用应仅使用 HTTPS(TLS)而不是 HTTP。 -还要注意,即使应用发起的是 HTTPS 请求,攻击者也可能会通过检查 [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) 知道客户端正在对 `edition.cnn.com` 发送请求。 -_SNI_ 字段在 TLS 握手过程中以未加密的形式发送。 +还要注意,即使应用发起的是 HTTPS 请求,攻击者也可能会通过检查 +[Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) +知道客户端正在对 `edition.cnn.com` 发送请求。**SNI** 字段在 TLS 握手过程中以未加密的形式发送。 使用 HTTPS 可以防止攻击者知道客户端访问了哪些特点的内容,但并不能阻止攻击者得知客户端访问了 `edition.cnn.com` 站点。 ### 清理 TLS 发起配置{#cleanup-the-tls-origination-configuration} -1. 移除您创建的 Istio 配置项: +移除您创建的 Istio 配置项: - {{< text bash >}} - $ kubectl delete serviceentry edition-cnn-com - $ kubectl delete destinationrule edition-cnn-com - {{< /text >}} +{{< text bash >}} +$ kubectl delete serviceentry edition-cnn-com +$ kubectl delete destinationrule edition-cnn-com +{{< /text >}} ## 出口流量的双向 TLS 发起{#mutual-tls-origination-for-egress-traffic} @@ -196,7 +203,7 @@ _SNI_ 字段在 TLS 握手过程中以未加密的形式发送。 1. 部署支持双向 TLS 协议的外部服务 1. 将客户端(sleep Pod)配置为使用在步骤 1 中创建的凭据 -完成上述前置操作后,您可以将外部流量配置为经由该 sidecar,执行 TLS 发起。 +完成上述前置操作后,您可以将外部流量配置为经由该 Sidecar,执行 TLS 发起。 ### 生成客户端证书、服务器证书、客户端密钥和服务器密钥{#generate-client-and-server-certificates-and-keys} @@ -269,7 +276,7 @@ _SNI_ 字段在 TLS 握手过程中以未加密的形式发送。 $ kubectl logs -l app=sleep -c istio-proxy | grep 'my-nginx.mesh-external.svc.cluster.local' {{< /text >}} - You should see a line similar to the following: + 您应看到一行类似以下的输出: {{< text plain>}} [2022-05-19T10:01:06.795Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 0 "-" "curl/7.83.1-DEV" "96e8d8a7-92ce-9939-aa47-9f5f530a69fb" "my-nginx.mesh-external.svc.cluster.local:443" "10.107.176.65:443" @@ -304,12 +311,7 @@ _SNI_ 字段在 TLS 握手过程中以未加密的形式发送。 ## 清理常用配置{#cleanup-common-configuration} -删除 `sleep` 服务和部署: - -{{< text bash >}} -$ kubectl delete service sleep -$ kubectl delete deployment sleep -{{< /text >}} +删除 `sleep` Service 和 Deployment: {{< text bash >}} $ kubectl delete service sleep