mirror of https://github.com/istio/istio.io.git
zh:sync example-egress-gateway (#2648)
This commit is contained in:
parent
ee2f55a5ad
commit
41dd7e9f18
|
|
@ -1,60 +1,58 @@
|
|||
---
|
||||
title: 配置 Egress 网关
|
||||
title: 配置 Egress gateway
|
||||
description: 描述如何通过专用网关服务将流量定向到外部服务来配置 Istio。
|
||||
weight: 43
|
||||
keywords: [traffic-management,egress]
|
||||
---
|
||||
|
||||
> 此任务使用新的 [v1alpha3 流量管理 API](/zh/blog/2018/v1alpha3-routing/) 。旧的 API 已被弃用并将在下一个 Istio 版本中删除。如果您需要使用旧版本,请按照[此处](https://archive.istio.io/v0.7/docs/tasks/traffic-management/)的文档操作。请注意,此任务引入了一个新概念,即 Egress 网关,这在以前的 Istio 版本中是不存在的。
|
||||
|
||||
[控制 Egress 流量](/zh/docs/tasks/traffic-management/egress/)任务演示了如何从网格内的应用程序访问外部(Kubernetes 集群外部)HTTP 和 HTTPS 服务。快速提醒:默认情况下,启用 Istio 的应用程序无法访问集群外的 URL。要启用此类访问,必须定义外部服务的[服务条目](/docs/reference/config/istio.networking.v1alpha3/#ServiceEntry),或者[直接访问外部服务](/docs/tasks/traffic-management/egress/#calling-external-services-directly)。
|
||||
[控制 Egress 流量](/zh/docs/tasks/traffic-management/egress/)任务演示了如何从网格内的应用程序访问外部(Kubernetes 集群外部)HTTP 和 HTTPS 服务。这里提醒一下:默认情况下,启用 Istio 的应用程序无法访问集群外的 URL。要启用此类访问,必须定义外部服务的 [`ServiceEntry`](/docs/reference/config/istio.networking.v1alpha3/#ServiceEntry),或者配置[直接访问外部服务](/docs/tasks/traffic-management/egress/#calling-external-services-directly)。
|
||||
|
||||
[Egress 流量的 TLS](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务演示了如何允许应用程序将 HTTP 请求发送到需要 HTTPS 的外部服务器。
|
||||
|
||||
此任务描述了通过名为 _Egress Gateway_ 的专用服务如何配置 Istio 引导出口流量。我们实现了与 [Egress 流量的 TLS](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务中描述的相同功能,这次我们通过添加 egress 网关来完成它。
|
||||
此任务描述了通过名为 `Egress Gateway` 的专用服务如何配置 Istio 引导出口流量。我们实现了与 [Egress 流量的 TLS](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务中描述的相同功能,唯一的区别就是,这里会使用 Egress gateway 来完成这一任务。
|
||||
|
||||
## 用例
|
||||
|
||||
考虑一个具有严格安全要求的组织。根据这些要求,离开服务网格的所有流量必须流经一组专用节点。这些节点将在专用计算机上运行,与用于在集群中运行应用程序的其余节点分开运行。特殊节点将用于 egress 流量的策略实施,并且将比其余节点进行更详细地监控。
|
||||
设想一个具有严格安全要求的组织。根据这些要求,服务网格的所有外发流量必须流经一组专用节点。这些节点和运行其他应用分别在不同的节点上运行。这些专用的节点将用于 Egress 流量的策略实施,并且将比其余节点进行更详细地监控。
|
||||
|
||||
Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.networking.v1alpha3/#Gateway)的概念。 Ingress 网关允许定义进入服务网格的入口点,所有入站流量都通过该入口点。 _Egress gateway_ 是一个对称的概念,它定义了网格的出口点。 Egress 网关允许将 Istio 功能(例如,监控和路由规则)应用于离开网格的流量。
|
||||
Istio 0.8 引入了 [Ingress 和 Egress gateway](/zh/docs/reference/config/istio.networking.v1alpha3/#gateway) 的概念。 Ingress 网关允许定义进入服务网格的入口点,所有入站流量都通过该入口点;`Egress gateway` 与之相对,它定义了网格的出口点。 Egress gateway 允许将 Istio 功能(例如,监控和路由规则)应用于 Egress 流量。
|
||||
|
||||
另一个用例是应用程序节点没有公共 IP 的集群,因此在其上运行的网格内服务无法访问 Internet。定义 egress 网关,通过它引导所有出口流量并将公共 IP 分配给 egress 网关节点,允许应用节点以受控方式访问外部服务。
|
||||
另一个用例是应用程序节点没有公共 IP 的集群,因此在其上运行的网格内服务无法访问 Internet。定义 Egress gateway ,通过它引导所有出口流量并将公共 IP 分配给 Egress gateway 节点,允许应用节点以受控方式访问外部服务。
|
||||
|
||||
## 开始之前
|
||||
|
||||
* 按照[安装指南](/zh/docs/setup/)中的说明设置 Istio 。
|
||||
|
||||
* 启动 [sleep]({{<github_tree>}}/samples/sleep),它将被用作外部调用的测试源。
|
||||
* 启动 [sleep]({{<github_tree>}}/samples/sleep) 应用,它将被用作外部调用的测试源。
|
||||
|
||||
如果您已经启用了 [automatic sidecar injection](/docs/setup/kubernetes/sidecar-injection/#automatic-sidecar-injection),请执行此操作
|
||||
如果已经启用了 [Sidecar 的自动注入](/zh/docs/setup/kubernetes/sidecar-injection/#sidecar-的自动注入),请执行此操作
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f @samples/sleep/sleep.yaml@
|
||||
{{< /text >}}
|
||||
|
||||
否则,您必须在部署 `sleep` 应用程序之前手动注入 sidecar:
|
||||
否则,就要在部署 `sleep` 应用程序之前手工进行 Sidecar 的注入:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@)
|
||||
{{< /text >}}
|
||||
|
||||
请注意,您可以在任意 pod 使用 `exec` 和 `curl`。
|
||||
这样就可以在任意 pod 使用 `exec` 和 `curl` 命令了。
|
||||
|
||||
* 创建一个 shell 变量来保存源 pod 的名称,以便将请求发送到外部服务。如果我们使用 [sleep]({{<github_tree>}}/samples/sleep) 示例,我们运行:
|
||||
* 创建一个环境变量来保存源 Pod 名称,以便将请求发送到外部服务。例如在 [sleep]({{<github_tree>}}/samples/sleep) 示例中运行:
|
||||
|
||||
{{< text bash >}}
|
||||
$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
|
||||
{{< /text >}}
|
||||
|
||||
## 定义 egress `Gateway` 并通过它定向 HTTP 流量
|
||||
## 定义 Egress gateway 并引导 HTTP 流量通过这一网关
|
||||
|
||||
首先定向没有 TLS 的 HTTP 流量
|
||||
|
||||
1. 为 `edition.cnn.com` 定义一个 `ServiceEntry`:
|
||||
1. 为 `edition.cnn.com` 定义一个 `ServiceEntry`:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: ServiceEntry
|
||||
metadata:
|
||||
|
|
@ -69,11 +67,11 @@ Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.net
|
|||
- number: 443
|
||||
name: https
|
||||
protocol: HTTPS
|
||||
resolution: DNS
|
||||
resolution: DNS
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 验证您的 `ServiceEntry` 是否已正确应用。发送 HTTPS 请求到 [http://edition.cnn.com/politics](http://edition.cnn.com/politics)。
|
||||
1. 验证 `ServiceEntry` 是否已正确应用。发送 HTTPS 请求到 [http://edition.cnn.com/politics](http://edition.cnn.com/politics)。
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
|
||||
|
|
@ -91,12 +89,12 @@ Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.net
|
|||
|
||||
输出应与 [Egress 流量的 TLS](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务中的输出相同,不带 TLS。
|
||||
|
||||
1. 创建 egress `Gateway` 为 _edition.cnn.com_ ,端口 80。除此之外还创建了一个 `DestinationRule` 和 `VirtualService` 来引导流量通过 egress 网关与外部服务通信。
|
||||
1. 为 `edition.cnn.com` 端口 80 创建 Egress gateway。除此之外还要创建一个 `DestinationRule` 和 `VirtualService` 来引导流量通过 Egress gateway 与外部服务通信。
|
||||
|
||||
如果在 Istio 中启用了[双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/),请使用以下命令。
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
|
|
@ -140,7 +138,7 @@ Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.net
|
|||
如果没有启用双向 TLS 认证:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
|
|
@ -167,10 +165,10 @@ Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.net
|
|||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 定义 `VirtualService` 来引导流量通过 egress 网关:
|
||||
1. 定义 `VirtualService` 来引导流量通过 Egress gateway :
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
|
|
@ -206,7 +204,7 @@ Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.net
|
|||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 将 HTTP 请求重新发送到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。
|
||||
1. 将 HTTP 请求重新发送到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
|
||||
|
|
@ -224,7 +222,7 @@ Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.net
|
|||
|
||||
输出应与步骤2中的输出相同。
|
||||
|
||||
1. 检查 `istio-egressgateway` pod 的日志,并查看与我们的请求对应的行。如果 Istio 部署在 `istio-system` 命名空间中,则打印日志的命令是:
|
||||
1. 检查 `istio-egressgateway` pod 的日志,并查看与我们的请求对应的行。如果 Istio 部署在 `istio-system` 命名空间中,则打印日志的命令是:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl logs $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') egressgateway -n istio-system | tail
|
||||
|
|
@ -236,9 +234,9 @@ Istio 0.8 引入了 [ingress 和 egress 网关](/docs/reference/config/istio.net
|
|||
[2018-06-14T11:46:23.596Z] "GET /politics HTTP/1.1" 301 - 0 0 3 1 "172.30.146.87" "curl/7.35.0" "ab7be694-e367-94c5-83d1-086eca996dae" "edition.cnn.com" "151.101.193.67:80"
|
||||
{{< /text >}}
|
||||
|
||||
请注意,我们只将流量从 80 端口重定向到 egress 网关,到 443 端口的 HTTPS 流量直接转到 _edition.cnn.com_ 。
|
||||
请注意,我们只将流量从 80 端口重定向到 Egress gateway ,到 443 端口的 HTTPS 流量直接转到 `edition.cnn.com` 。
|
||||
|
||||
### 清除 HTTP 流量的 egress 网关
|
||||
### 清除 HTTP 流量的 Egress gateway
|
||||
|
||||
在继续下一步之前删除先前的定义:
|
||||
|
||||
|
|
@ -249,14 +247,14 @@ $ kubectl delete virtualservice direct-cnn-through-egress-gateway
|
|||
$ kubectl delete destinationrule egressgateway-for-cnn
|
||||
{{< /text >}}
|
||||
|
||||
## Egress `Gateway` 执行 TLS
|
||||
## 用 Egress gateway 发起 TLS 连接
|
||||
|
||||
让我们用 egress `Gateway` 执行 TLS,类似于 [TLS Origination for Egress Traffic](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务。请注意,在这种情况下,TLS 将由 egress 网关服务器完成,而不是前一任务中的 sidecar。
|
||||
接下来尝试使用 Egress Gateway 发起 TLS 连接,效果类似于 [出口流量的 TLS](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务,具体区别是,在这种情况下,TLS 功能是由 Egress gateway 服务器完成的,而不是前一任务中的 Sidecar。
|
||||
|
||||
1. 为 `edition.cnn.com` 定义 `ServiceEntry`:
|
||||
1. 为 `edition.cnn.com` 定义 `ServiceEntry`:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: ServiceEntry
|
||||
metadata:
|
||||
|
|
@ -264,18 +262,18 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
spec:
|
||||
hosts:
|
||||
- edition.cnn.com
|
||||
ports:
|
||||
ports:
|
||||
- number: 80
|
||||
name: http-port
|
||||
protocol: HTTP
|
||||
- number: 443
|
||||
name: http-port-for-tls-origination
|
||||
protocol: HTTP
|
||||
resolution: DNS
|
||||
resolution: DNS
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 验证您的 `ServiceEntry` 是否已正确应用。发送 HTTPS 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。
|
||||
1. 验证您的 `ServiceEntry` 是否已正确生效。发送 HTTPS 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
|
||||
|
|
@ -287,14 +285,14 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
command terminated with exit code 35
|
||||
{{< /text >}}
|
||||
|
||||
如果你看到输出结果中包含 _301 Moved Permanently_ ,说明 `ServiceEntry` 配置正确。退出代码 _35_ 是由于 Istio 没有执行 TLS。 为了让 Egress 网关执行 TLS,请继续执行以下步骤进行配置。
|
||||
如果看到输出结果中包含 `301 Moved Permanently`,说明 `ServiceEntry` 配置正确。退出代码 `35` 是由于 Istio 没有执行 TLS。 为了让 Egress gateway 执行 TLS,还要继续执行以下步骤进行配置。
|
||||
|
||||
1. 为 _edition.cnn.com_ 创建 egress `Gateway`,端口 443。除此之外还创建了一个 `DestinationRule` 和 `VirtualService` 来引导流量通过 egress 网关与外部服务通信。
|
||||
1. 为 `edition.cnn.com` 创建 Egress Gateway,端口 443。除此之外还创建了一个 `DestinationRule` 和 `VirtualService`,这两个对象用来引导流量通过 Egress gateway 与外部服务通信。
|
||||
|
||||
如果在 Istio 中启用了 [双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/) ,请使用以下命令。
|
||||
如果在 Istio 中启用了 [双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/),请使用以下命令。
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
|
|
@ -338,7 +336,7 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
如果没有启用双向 TLS 认证:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
|
|
@ -365,10 +363,10 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 定义 `VirtualService` 来引导流量通过 egress 网关,并定义 `DestinationRule` 以执行 TLS:
|
||||
1. 定义 `VirtualService` 来引导流量通过 Egress gateway,并定义 `DestinationRule` 以执行 TLS:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
|
|
@ -419,7 +417,7 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 发送 HTTP 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics).
|
||||
1. 发送 HTTP 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics).
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
|
||||
|
|
@ -429,21 +427,21 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
...
|
||||
{{< /text >}}
|
||||
|
||||
输出应与 [TLS Origination for Egress Traffic](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务中的输出相同,TLS 来源:没有 _301 Moved Permanently_ 信息。
|
||||
输出应与 [出口流量的 TLS](/zh/docs/examples/advanced-gateways/egress-tls-origination/) 任务中的输出相同:没有 `301 Moved Permanently` 信息。
|
||||
|
||||
1. 检查 `istio-egressgateway` pod 的日志,并查看与我们的请求相对应的行。如果 Istio 部署在 `istio-system` 命名空间中,则打印日志的命令是:
|
||||
1. 检查 `istio-egressgateway` pod 的日志,并查看与我们的请求相对应的行。如果 Istio 部署在 `istio-system` 命名空间中,则打印日志的命令是:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl logs $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') egressgateway -n istio-system | tail
|
||||
{{< /text >}}
|
||||
|
||||
我们看到与我们的请求相关的行,类似于以下内容:
|
||||
这里会看到与之前请求相关的行,类似于以下内容:
|
||||
|
||||
{{< text plain>}}
|
||||
"[2018-06-14T13:49:36.340Z] "GET /politics HTTP/1.1" 200 - 0 148528 5096 90 "172.30.146.87" "curl/7.35.0" "c6bfdfc3-07ec-9c30-8957-6904230fd037" "edition.cnn.com" "151.101.65.67:443"
|
||||
{{< /text >}}
|
||||
|
||||
### 清除 TLS 发起的 egress 网关
|
||||
### 清除发起 TLS 的 Egress gateway
|
||||
|
||||
删除我们创建的 Istio 配置项:
|
||||
|
||||
|
|
@ -455,14 +453,14 @@ $ kubectl delete destinationrule originate-tls-for-edition-cnn-com
|
|||
$ kubectl delete destinationrule egressgateway-for-cnn
|
||||
{{< /text >}}
|
||||
|
||||
## 通过 egress 网关定向 HTTPS 流量
|
||||
## 通过 Egress gateway 进行 HTTPS 流量透传
|
||||
|
||||
在本节中,您将通过 egress 网关引导HTTPS流量(由应用程序发起的 TLS)。在相应的 `ServiceEntry` 中指定端口 443,协议 `TLS`,egress `Gateway` 和 `VirtualService`。
|
||||
在本节中,将通过 Egress gateway 进行 HTTPS 流量透传(由应用程序发起的 TLS)。在相应的 `ServiceEntry`、`Egress gateway` 以及 `VirtualService` 中指定端口 443,协议 `TLS`。
|
||||
|
||||
1. 为 `edition.cnn.com` 定义 `ServiceEntry`:
|
||||
1. 为 `edition.cnn.com` 定义 `ServiceEntry`:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: ServiceEntry
|
||||
metadata:
|
||||
|
|
@ -470,15 +468,15 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
spec:
|
||||
hosts:
|
||||
- edition.cnn.com
|
||||
ports:
|
||||
ports:
|
||||
- number: 443
|
||||
name: tls
|
||||
protocol: TLS
|
||||
resolution: DNS
|
||||
resolution: DNS
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 验证您的 `ServiceEntry` 是否已正确应用。发送 HTTPS 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。输出应与上一节中的输出相同。
|
||||
1. 验证 `ServiceEntry` 是否已正确生效。发送 HTTPS 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。输出应与上一节中的输出相同。
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - https://edition.cnn.com/politics
|
||||
|
|
@ -489,12 +487,12 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
...
|
||||
{{< /text >}}
|
||||
|
||||
1. 为 _edition.cnn.com_ 创建 egress `Gateway` ,端口 443,TLS 协议。除此之外还创建了一个 `DestinationRule` 和 `VirtualService` 来引导流量通过 egress 网关与外部服务通信。
|
||||
1. 为 `edition.cnn.com` 创建 Egress gateway,端口 443,TLS 协议。除此之外还创建了一个 `DestinationRule` 和 `VirtualService` 来引导流量通过 Egress gateway 与外部服务通信。
|
||||
|
||||
如果在 Istio 中启用了[双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/) ,请使用以下命令。
|
||||
如果在 Istio 中启用了[双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/),请使用以下命令。
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
|
|
@ -573,7 +571,7 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
如果没有启用双向 TLS 认证:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | istioctl create -f -
|
||||
$ kubectl apply -f - <<EOF
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
|
|
@ -638,7 +636,7 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 发送 HTTPS 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。输出应与之前相同。
|
||||
1. 发送 HTTPS 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。输出应与之前相同。
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - https://edition.cnn.com/politics
|
||||
|
|
@ -649,16 +647,16 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
...
|
||||
{{< /text >}}
|
||||
|
||||
1. 检查 egress 网关代理的统计信息,并查看与我们对 _edition.cnn.com_ 的请求相对应的计数器。如果 Istio 部署在 `istio-system` 命名空间中,则打印计数器的命令是:
|
||||
1. 检查 Egress gateway 代理的统计信息,并查看与我们对 `edition.cnn.com` 的请求相对应的计数器。如果 Istio 部署在 `istio-system` 命名空间中,则打印计数器的命令是:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -n istio-system -- curl -s localhost:15000/stats | grep edition.cnn.com.upstream_cx_total
|
||||
cluster.outbound|443||edition.cnn.com.upstream_cx_total: 1
|
||||
{{< /text >}}
|
||||
|
||||
您可能需要执行几个额外的请求,并验证每个请求上面的计数器增加1。
|
||||
如果再执行几个额外的请求,应该会看到每次请求之后上面的计数器都会加 1。
|
||||
|
||||
### 清除 HTTPS 流量的 egress 网关
|
||||
### 清除 HTTPS 流量的 Egress gateway
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl delete serviceentry cnn
|
||||
|
|
@ -667,17 +665,158 @@ $ kubectl delete virtualservice direct-cnn-through-egress-gateway
|
|||
$ kubectl delete destinationrule egressgateway-for-cnn
|
||||
{{< /text >}}
|
||||
|
||||
## 其他安全因素
|
||||
## 额外的安全考量
|
||||
|
||||
请注意,在 Istio 中定义 egress `Gateway` 本身并不为运行 egress 网关服务的节点提供任何特殊处理。集群管理员或云提供商可以在专用节点上部署 egress 网关,并引入额外的安全措施,使这些节点比网格的其余部分更安全。
|
||||
在 Istio 中定义的 Egress gateway,本身并不会对运行 Egress gateway 服务的节点进行任何特殊处理。集群管理员或云提供商可以在专用节点上部署 Egress gateway ,并引入额外的安全措施,使这些节点比网格的其余部分更安全。
|
||||
|
||||
另请注意,实际上 Istio 本身无法安全地强制将所有 egress 流量流经 egress 网关,Istio 仅通过其 sidecar 代理启用此类流量。如果恶意应用程序攻击连接到应用程序 pod 的 sidecar 代理,它可能会绕过 sidecar 代理。绕过 sidecar 代理后,恶意应用程序可能会尝试绕过 egress 网关直接与网格外面的服务通信,以逃避 Istio 的控制和监控。由集群管理员或云服务商通过 Istio 以外的机制来确保没有流量绕过 egress 网关直接与网格外面的服务通信。例如,防火墙可以拒绝其源不是 egress 网关的所有流量。 [Kubernetes 网络策略](https://kubernetes.io/docs/concepts/services-networking/network-policies/)也可以禁止所有不经过 egress 网关出口的 egress 流量。另一种可能的安全措施涉及以这样的方式配置网络:由于应用节点不能直接访问因特网,必须将 egress 流量引导到 egress 网关才能访问因特网。这种网络配置的一个例子是只给 egress 网关分配外网 IP。
|
||||
另外要注意的是,实际上 Istio 本身无法安全地强制将所有 Egress 流量流经 Egress gateway ,Istio 仅通过其 Sidecar 代理启用此类流量。攻击者只要绕过 Sidecar 代理,就可以不经 Egress gateway 直接与网格外面的服务进行通信,从而避免了 Istio 的控制和监控。集群管理员或云供应商必须确保所有外发流量都从 Egress gateway 途径发起。需要用 Istio 之外的机制来满足这一需求,例如以下几种做法:
|
||||
|
||||
* 使用防火墙拒绝所有来自 Egress gateway 以外的流量。
|
||||
* [Kubernetes 网络策略](https://kubernetes.io/docs/concepts/services-networking/network-policies/)也能禁止所有不是从 Egress gateway 发起的 Egress 流量([#下一节](#应用-Kubernetes-网络策略) 中举出了这样的例子)。
|
||||
* 管理员或者云供应商还可以对网络进行限制,让运行应用的节点只能通过 Gateway 来访问外部网络。要完成这一限制,可以只给 Gateway Pod 分配公网 IP,或者可以配置 NAT 设备,丢弃来自 Egress gateway 以外 Pod 的流量。
|
||||
|
||||
## 应用 Kubernetes 网络策略
|
||||
|
||||
本节中会创建 [Kubernetes 网络策略](https://kubernetes.io/docs/concepts/services-networking/network-policies/),阻止绕过 Egress gateway 的外发流量。要完成这一示例,首先创建一个 `test-egress` 命名空间,并在其中部署 [sleep]({{< github_tree >}}/samples/sleep) 示例应用。
|
||||
|
||||
1. 重复执行[“通过 Egress gateway 进行 HTTPS 流量透传”](#通过-Egress-gateway-进行-HTTPS-流量透传)一节的内容。
|
||||
|
||||
1. 创建 `test-egress` 命名空间:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl create namespace test-egress
|
||||
{{< /text >}}
|
||||
|
||||
1. 在 `test-egress` 命名空间中部署 [sleep]({{< github_tree >}}/samples/sleep) 示例应用:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl apply -n test-egress -f @samples/sleep/sleep.yaml@
|
||||
{{< /text >}}
|
||||
|
||||
1. 检查生成的 Pod,其中应该只有一个容器,也就是说没有注入 Istio sidecar:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl get pod $(kubectl get pod -n test-egress -l app=sleep -o jsonpath={.items..metadata.name}) -n test-egress
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
sleep-776b7bcdcd-z7mc4 1/1 Running 0 18m
|
||||
{{< /text >}}
|
||||
|
||||
1. 从 `test-egress` 命名空间的 `sleep` Pod 中向 [http://edition.cnn.com/politics](https://edition.cnn.com/politics) 发送 HTTPS 请求。因为没有任何限制,所以这一请求应该会成功:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $(kubectl get pod -n test-egress -l app=sleep -o jsonpath={.items..metadata.name}) -n test-egress -c sleep -- curl -s -o /dev/null -w "%{http_code}\n" https://edition.cnn.com/politics
|
||||
200
|
||||
{{< /text >}}
|
||||
|
||||
1. 给 Istio 组件(控制平面和 Gateway)所在的命名空间打上标签,例如 `istio-system`:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl label namespace istio-system istio=system
|
||||
{{< /text >}}
|
||||
|
||||
1. 给 `kube-system` 命名空间打标签:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl label ns kube-system kube-system=true
|
||||
{{< /text >}}
|
||||
|
||||
1. 创建一个 `NetworkPolicy`,来自 `test-egress` 命名空间的流量,只允许目标为 `kube-system` 的 DNS(端口 53)请求,以及目标为 `istio-system` 命名空间的所有请求:
|
||||
|
||||
{{< text bash >}}
|
||||
$ cat <<EOF | kubectl apply -n test-egress -f -
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-egress-to-istio-system-and-kube-dns
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kube-system: "true"
|
||||
ports:
|
||||
- protocol: UDP
|
||||
port: 53
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
istio: system
|
||||
EOF
|
||||
{{< /text >}}
|
||||
|
||||
1. 重新发送前面的 HTTPS 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。这次请求就不会成功了,这是因为流量被网络策略拦截了。测试 Pod 无法越过 `istio-egressgateway`。要访问 `edition.cnn.com`,只能通过 Istio sidecar 将流量转给 `istio-egressgateway` 才能完成。这一设置演示了即使绕过了 Sidecar,也会被网络策略拦截,而无法访问到外部站点。
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $(kubectl get pod -n test-egress -l app=sleep -o jsonpath={.items..metadata.name}) -n test-egress -c sleep -- curl -v https://edition.cnn.com/politics
|
||||
Hostname was NOT found in DNS cache
|
||||
Trying 151.101.65.67...
|
||||
Trying 2a04:4e42:200::323...
|
||||
Immediate connect fail for 2a04:4e42:200::323: Cannot assign requested address
|
||||
Trying 2a04:4e42:400::323...
|
||||
Immediate connect fail for 2a04:4e42:400::323: Cannot assign requested address
|
||||
Trying 2a04:4e42:600::323...
|
||||
Immediate connect fail for 2a04:4e42:600::323: Cannot assign requested address
|
||||
Trying 2a04:4e42::323...
|
||||
Immediate connect fail for 2a04:4e42::323: Cannot assign requested address
|
||||
connect to 151.101.65.67 port 443 failed: Connection timed out
|
||||
{{< /text >}}
|
||||
|
||||
1. 接下来在 `test-egress` 命名空间的 `sleep` Pod 上注入 Sidecar,启用 `test-egress` 命名空间的自动注入:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl label namespace test-egress istio-injection=enabled
|
||||
{{< /text >}}
|
||||
|
||||
1. 重新部署 `sleep`:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl delete deployment sleep -n test-egress
|
||||
$ kubectl apply -f @samples/sleep/sleep.yaml@ -n test-egress
|
||||
{{< /text >}}
|
||||
|
||||
1. 检查生成的 Pod,其中应该有了两个容器,其中包含了注入的 Sidecar(`istio-proxy`):
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl get pod $(kubectl get pod -n test-egress -l app=sleep -o jsonpath={.items..metadata.name}) -n test-egress -o jsonpath={.spec.containers[*].name}
|
||||
sleep istio-proxy
|
||||
{{< /text >}}
|
||||
|
||||
1. 向 [http://edition.cnn.com/politics](https://edition.cnn.com/politics) 发送 HTTP 请求,这次会成功,原因是网络策略允许流量流向 `istio-system` 中的 `istio-egressgateway`,`istio-egressgateway` 最终把流量转发到 `edition.cnn.com`。
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $(kubectl get pod -n test-egress -l app=sleep -o jsonpath={.items..metadata.name}) -n test-egress -c sleep -- curl -s -o /dev/null -w "%{http_code}\n" https://edition.cnn.com/politics
|
||||
200
|
||||
{{< /text >}}
|
||||
|
||||
1. 检查 Egress gateway 中的代理统计数据,查看对 `edition.cnn.com` 的请求计数。如果 Istio 部署在 `istio-system` 命名空间,那么打印计数器的命令就是:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -n istio-system -- curl -s localhost:15000/stats | grep edition.cnn.com.upstream_cx_total
|
||||
cluster.outbound|443||edition.cnn.com.upstream_cx_total: 2
|
||||
{{< /text >}}
|
||||
|
||||
### 清理网络策略
|
||||
|
||||
1. 删除本节中建立的资源:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl delete -f @samples/sleep/sleep.yaml@ -n test-egress
|
||||
$ kubectl delete networkpolicy allow-egress-to-istio-system-and-kube-dns -n test-egress
|
||||
$ kubectl label namespace kube-system kube-system-
|
||||
$ kubectl label namespace istio-system istio-
|
||||
$ kubectl delete namespace test-egress
|
||||
{{< /text >}}
|
||||
|
||||
1. 执行[“通过 Egress gateway 进行 HTTPS 流量透传”](#通过-Egress-gateway-进行-HTTPS-流量透传)一节中的[清理工作](#清除-HTTPS-流量的-Egress-gateway)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
1. 检查您是否在 Istio 中启用了[双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/),然后执行以下步骤:[验证 Istio 的双向 TLS 认证设置](/docs/tasks/security/mutual-tls/#verify-mutual-tls-configuration)。如果启用了双向 TLS,请确保创建相应的项目配置(请注意备注 _如果您在 Istio 中启用了双向 TLS 认证,则必须创建..._ )。
|
||||
1. 检查是否在 Istio 中启用了[双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/),然后执行以下步骤:[验证 Istio 的双向 TLS 认证设置](/zh/docs/tasks/security/mutual-tls/#检查-istio-双向-tls-认证的配置)。如果启用了双向 TLS,请确保创建相应的项目配置(请注意备注**如果您在 Istio 中启用了双向 TLS 认证,则必须创建...**)。
|
||||
|
||||
1. 如果[双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/)启用后, 验证 egress 网关的证书:
|
||||
1. 如果[双向 TLS 认证](/zh/docs/tasks/security/mutual-tls/)启用后, 验证 Egress gateway 的证书:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -i -n istio-system $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') -- cat /etc/certs/cert-chain.pem | openssl x509 -text -noout | grep 'Subject Alternative Name' -A 1
|
||||
|
|
@ -685,6 +824,30 @@ $ kubectl delete destinationrule egressgateway-for-cnn
|
|||
URI:spiffe://cluster.local/ns/istio-system/sa/istio-egressgateway-service-account
|
||||
{{< /text >}}
|
||||
|
||||
1. HTTPS 透传流量情况,需要使用 `openssl` 命令测试流量。`openssl` 的 `-servername` 选项可以用来设置 SNI:
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $SOURCE_POD -c sleep -- openssl s_client -connect edition.cnn.com:443 -servername edition.cnn.com
|
||||
CONNECTED(00000003)
|
||||
...
|
||||
Certificate chain
|
||||
0 s:/C=US/ST=California/L=San Francisco/O=Fastly, Inc./CN=turner-tls.map.fastly.net
|
||||
i:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign CloudSSL CA - SHA256 - G3
|
||||
1 s:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign CloudSSL CA - SHA256 - G3
|
||||
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
|
||||
---
|
||||
Server certificate
|
||||
-----BEGIN CERTIFICATE-----
|
||||
...
|
||||
{{< /text >}}
|
||||
|
||||
如果在上面命令的输出中看到了类似的证书信息,就表明路由是正确的。接下来检查 Egress gateway 代理,查找对应请求的计数器(由 `openssl` 和 `curl` 发送,目标是 `edition.cnn.com`):
|
||||
|
||||
{{< text bash >}}
|
||||
$ kubectl exec -it $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -n istio-system -- curl -s localhost:15000/stats | grep edition.cnn.com.upstream_cx_total
|
||||
cluster.outbound|443||edition.cnn.com.upstream_cx_total: 2
|
||||
{{< /text >}}
|
||||
|
||||
## 清理
|
||||
|
||||
关闭 [sleep]({{<github_tree>}}/samples/sleep) 服务:
|
||||
|
|
|
|||
Loading…
Reference in New Issue