[zh] Sync /traffic-management/egress/egress-gateway/ (#14492)

* [zh] Sync /traffic-management/egress/egress-gateway/

* apply suggestions from hanxiaop
This commit is contained in:
Michael 2024-01-19 15:57:48 +08:00 committed by GitHub
parent 1d2b80dfd9
commit 139dab32de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 656 additions and 260 deletions

View File

@ -23,7 +23,7 @@ Istio 使用 [Ingress 和 Egress Gateway](/zh/docs/reference/config/networking/g
Egress Gateway 是一个与 Ingress Gateway 对称的概念,它定义了网格的出口。
Egress Gateway 允许您将 Istio 的功能(例如,监视和路由规则)应用于网格的出站流量。
## 使用场景{#use-case}
## 使用场景 {#use-case}
设想一个对安全有严格要求的组织,要求服务网格所有的出站流量必须经过一组专用节点。
专用节点运行在专门的机器上,与集群中运行应用程序的其他节点隔离。
@ -33,20 +33,56 @@ Egress Gateway 允许您将 Istio 的功能(例如,监视和路由规则)
Service 无法访问互联网。通过定义 Egress gateway将公有 IP 分配给
Egress Gateway 节点,用它引导所有的出站流量,可以使应用节点以受控的方式访问外部服务。
{{< boilerplate before-you-begin-egress >}}
{{< boilerplate gateway-api-gamma-support >}}
* [启用 Envoy 访问日志](/zh/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging)
## 开始之前 {#before-you-begin}
{{< warning >}}
此任务中的指令在 `default` 命名空间中为 Egress gateway 创建目标规则。
并假设客户端 `SOURCE_POD` 也在 `default` 命名空间中运行。如果没有,
目标规则则不会在[目标规则查找路径](/zh/docs/ops/best-practices/traffic-management/#cross-namespace-configuration)上找到,
并且客户端请求将失败。
{{< /warning >}}
* 参照[安装指南](/zh/docs/setup/)中的说明搭建 Istio。
{{< tip >}}
如果您安装 `demo` [配置文件](/zh/docs/setup/additional-setup/config-profiles/)
则会启用 Egress Gateway 和访问日志。
{{< /tip >}}
* 部署 [sleep]({{< github_tree >}}/samples/sleep) 示例应用,用作发送请求的测试源。
{{< text bash >}}
$ kubectl apply -f @samples/sleep/sleep.yaml@
{{< /text >}}
{{< tip >}}
您可以使用任何安装了 `curl` 的 Pod 作为测试源。
{{< /tip >}}
* 将 `SOURCE_POD` 环境变量设置为源 Pod 的名称:
{{< text bash >}}
$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
{{< /text >}}
{{< warning >}}
此任务中的指令在 `default` 命名空间中为 Egress Gateway 创建目标规则。
并假设客户端 `SOURCE_POD` 也在 `default` 命名空间中运行。如果没有,
目标规则将不会在[目标规则查找路径](/zh/docs/ops/best-practices/traffic-management/#cross-namespace-configuration)上找到,
并且客户端请求将失败。
{{< /warning >}}
* 如果尚未启用,则[启用 Envoy 的访问日志](/zh/docs/tasks/observability/logs/access-log/#enable-envoy-s-access-logging)。
例如,使用 `istioctl`
{{< text bask >}}
$ istioctl install <flags-you-used-to-install-Istio> --set meshConfig.accessLogFile=/dev/stdout
{{< /text >}}
## 部署 Istio Egress Gateway {#deploy-Istio-egress-gateway}
1. 检查 Istio Egress Gateway 是否已布署:
{{< tip >}}
当使用 Gateway API 配置 Egress Gateway 时,这些 Egress Gateway
会被[自动部署](/zh/docs/tasks/traffic-management/ingress/gateway-api/#deployment-methods)。
如果您在下文中使用 `Gateway API` 指令,则可以跳过这部分。
{{< /tip >}}
1. 检查 Istio Egress Gateway 是否已部署:
{{< text bash >}}
$ kubectl get pod -l istio=egressgateway -n istio-system
@ -125,21 +161,25 @@ Egress Gateway 节点,用它引导所有的出站流量,可以使应用节
输出结果应该与[发起 TLS 的 Egress 流量](/zh/docs/tasks/traffic-management/egress/egress-tls-origination/)中示例中的输出结果相同,
都还没有发起 TLS。
1. 为 `edition.cnn.com` 端口 80 创建 egress `Gateway`。并为指向
Egress Gateway 的流量创建一个 destination rule
1. 为 `edition.cnn.com` 端口 80 创建 Egress `Gateway`。并为指向
Egress Gateway 的流量创建一个目标规则
{{< tip >}}
要通过 Egress Gateway 引导多个主机,您可以在 `Gateway` 中包含主机列表,
或使用 `*` 匹配所有主机。应该将 `DestinationRule` 中的 `subset` 字段用于其他主机。
{{< /tip >}}
{{< tabset category-name="config-api" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< tip >}}
要通过 Egress Gateway 引导多个主机,您可以在 `Gateway` 中包含主机列表,
或使用 `*` 匹配所有主机。应该将 `DestinationRule` 中的 `subset` 字段重用于其他主机。
{{< /tip >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
spec:
spec:
selector:
istio: egressgateway
servers:
@ -149,28 +189,60 @@ Egress Gateway 节点,用它引导所有的出站流量,可以使应用节
protocol: HTTP
hosts:
- edition.cnn.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-cnn
spec:
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: cnn
EOF
{{< /text >}}
EOF
{{< /text >}}
1. 定义一个 `VirtualService`,将流量从 Sidecar 引导至 Egress Gateway
再从 Egress Gateway 引导至外部服务:
{{< /tab >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cnn-egress-gateway
annotations:
networking.istio.io/service-type: ClusterIP
spec:
gatewayClassName: istio
listeners:
- name: http
hostname: edition.cnn.com
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
EOF
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
4) 配置路由规则,将流量从边车导向到 Egress Gateway再从 Egress Gateway 导向到外部服务:
{{< tabset category-name="config-api" >}}
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-cnn-through-egress-gateway
spec:
spec:
hosts:
- edition.cnn.com
gateways:
@ -198,10 +270,54 @@ Egress Gateway 节点,用它引导所有的出站流量,可以使应用节
port:
number: 80
weight: 100
EOF
{{< /text >}}
EOF
{{< /text >}}
1. 再次发送 HTTP 请求到 [https://edition.cnn.com/politics](https://edition.cnn.com/politics)。
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: direct-cnn-to-egress-gateway
spec:
parentRefs:
- kind: ServiceEntry
group: networking.istio.io
name: cnn
hostnames:
- edition.cnn.com
rules:
- backendRefs:
- name: cnn-egress-gateway-istio
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: forward-cnn-from-egress-gateway
spec:
parentRefs:
- name: cnn-egress-gateway
hostnames:
- edition.cnn.com
rules:
- backendRefs:
- kind: Hostname
group: networking.istio.io
name: edition.cnn.com
port: 80
EOF
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
5) 重新发送 HTTP 请求到 [http://edition.cnn.com/politics](https://edition.cnn.com/politics)。
{{< text bash >}}
$ kubectl exec "$SOURCE_POD" -c sleep -- curl -sSL -o /dev/null -D - http://edition.cnn.com/politics
@ -218,38 +334,81 @@ Egress Gateway 节点,用它引导所有的出站流量,可以使应用节
输出应与第 2 步中的输出相同。
1. 检查 `istio-egressgateway` Pod 的日志,并查看与我们的请求对应的行。
如果 Istio 部署在 `istio-system` 命名空间中,则打印日志的命令是:
6) 检查 Egress Gateway Pod 的日志,找到与请求对应的那一行。
{{< text bash >}}
$ kubectl logs -l istio=egressgateway -c istio-proxy -n istio-system | tail
{{< /text >}}
{{< tabset category-name="config-api" >}}
您应该会看到一行类似于下面这样的内容:
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text plain >}}
[2019-09-03T20:57:49.103Z] "GET /politics HTTP/2" 301 - "-" "-" 0 0 90 89 "10.244.2.10" "curl/7.64.0" "ea379962-9b5c-4431-ab66-f01994f5a5a5" "edition.cnn.com" "151.101.65.67:80" outbound|80||edition.cnn.com - 10.244.1.5:80 10.244.2.10:50482 edition.cnn.com -
{{< /text >}}
如果 Istio 部署在 `istio-system` 命名空间中,则打印日志的命令是:
请注意,您只是将流量从 80 端口重定向到 Egress Gateway。到端口 443 的 HTTPS
流量直接进入 **edition.cnn.com**
{{< text bash >}}
$ kubectl logs -l istio=egressgateway -c istio-proxy -n istio-system | tail
{{< /text >}}
### 清理 HTTP gateway {#cleanup-http-gateway}
您应该会看到一行类似于下面这样的内容:
{{< text plain >}}
[2019-09-03T20:57:49.103Z] "GET /politics HTTP/2" 301 - "-" "-" 0 0 90 89 "10.244.2.10" "curl/7.64.0" "ea379962-9b5c-4431-ab66-f01994f5a5a5" "edition.cnn.com" "151.101.65.67:80" outbound|80||edition.cnn.com - 10.244.1.5:80 10.244.2.10:50482 edition.cnn.com -
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
使用 Istio 生成的 Pod 标签访问与 Egress Gateway 对应的日志:
{{< text bash >}}
$ kubectl logs -l istio.io/gateway-name=cnn-egress-gateway -c istio-proxy | tail
{{< /text >}}
您应该会看到一行类似于下面这样的内容:
{{< text plain >}}
[2024-01-09T15:35:47.283Z] "GET /politics HTTP/1.1" 301 - via_upstream - "-" 0 0 2 2 "172.30.239.55" "curl/7.87.0-DEV" "6c01d65f-a157-97cd-8782-320a40026901" "edition.cnn.com" "151.101.195.5:80" outbound|80||edition.cnn.com 172.30.239.16:55636 172.30.239.16:80 172.30.239.55:59224 - default.forward-cnn-from-egress-gateway.0
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
请注意,您只是将流量从 80 端口重定向到 Egress Gateway。到端口 443 的 HTTPS
流量直接进入 **edition.cnn.com**
### 清理 HTTP Gateway {#cleanup-http-gateway}
在继续下一步之前删除先前的定义:
{{< tabset category-name="config-api" >}}
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text bash >}}
$ kubectl delete gateway istio-egressgateway
$ kubectl delete serviceentry cnn
$ kubectl delete gateway istio-egressgateway
$ kubectl delete virtualservice direct-cnn-through-egress-gateway
$ kubectl delete destinationrule egressgateway-for-cnn
{{< /text >}}
## 用 Egress gateway 发起 HTTPS 请求 {#egress-gateway-for-https-traffic}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl delete serviceentry cnn
$ kubectl delete gtw cnn-egress-gateway
$ kubectl delete httproute direct-cnn-to-egress-gateway
$ kubectl delete httproute forward-cnn-from-egress-gateway
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
## 用 Egress Gateway 发起 HTTPS 请求 {#egress-gateway-for-https-traffic}
接下来尝试使用 Egress Gateway 发起 HTTPS 请求TLS 由应用程序发起)。
您需要在相应的 `ServiceEntry`、Egress `Gateway``VirtualService`
中指定 `TLS` 协议的端口 443。
您需要在相应的 `ServiceEntry` 和 Egress `Gateway` 中指定 `TLS` 协议的端口 443。
1. 为 `edition.cnn.com` 定义 `ServiceEntry`
@ -285,18 +444,22 @@ $ kubectl delete destinationrule egressgateway-for-cnn
目标规则和一个虚拟服务,用来引导流量通过 Egress Gateway
并通过 Egress Gateway 与外部服务通信。
{{< tip >}}
要通过 Egress Gateway 引导多个主机,您可以在 `Gateway` 中包含主机列表,
或使用 `*` 匹配所有主机。 应该将 `DestinationRule` 中的 `subset` 字段用于其他主机。
{{< /tip >}}
{{< tabset category-name="config-api" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< tip >}}
要通过 Egress Gateway 引导多个主机,您可以在 `Gateway` 中包含主机列表,
或使用 `*` 匹配所有主机。应该将 `DestinationRule` 中的 `subset` 字段用于其他主机。
{{< /tip >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
spec:
spec:
selector:
istio: egressgateway
servers:
@ -308,21 +471,21 @@ $ kubectl delete destinationrule egressgateway-for-cnn
- edition.cnn.com
tls:
mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-cnn
spec:
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: cnn
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-cnn-through-egress-gateway
spec:
spec:
hosts:
- edition.cnn.com
gateways:
@ -353,10 +516,73 @@ $ kubectl delete destinationrule egressgateway-for-cnn
port:
number: 443
weight: 100
EOF
{{< /text >}}
EOF
{{< /text >}}
1. 发送 HTTPS 请求到 [https://edition.cnn.com/politics](https://edition.cnn.com/politics)
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cnn-egress-gateway
annotations:
networking.istio.io/service-type: ClusterIP
spec:
gatewayClassName: istio
listeners:
- name: tls
hostname: edition.cnn.com
port: 443
protocol: TLS
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: direct-cnn-to-egress-gateway
spec:
parentRefs:
- kind: ServiceEntry
group: networking.istio.io
name: cnn
hostnames:
- edition.cnn.com
rules:
- backendRefs:
- name: cnn-egress-gateway-istio
port: 443
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: forward-cnn-from-egress-gateway
spec:
parentRefs:
- name: cnn-egress-gateway
hostnames:
- edition.cnn.com
rules:
- backendRefs:
- kind: Hostname
group: networking.istio.io
name: edition.cnn.com
port: 443
EOF
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
4) 发送 HTTPS 请求到 [https://edition.cnn.com/politics](https://edition.cnn.com/politics)
输出结果应该和之前一样。
{{< text bash >}}
@ -367,21 +593,50 @@ $ kubectl delete destinationrule egressgateway-for-cnn
...
{{< /text >}}
1. 检查 Egress Gateway 代理的日志。如果 Istio 部署在 `istio-system` 命名空间中,
则打印日志的命令是:
5) 检查 Egress Gateway 代理的日志。
{{< text bash >}}
$ kubectl logs -l istio=egressgateway -n istio-system
{{< /text >}}
{{< tabset category-name="config-api" >}}
您应该会看到类似于下面的内容:
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text plain >}}
[2019-01-02T11:46:46.981Z] "- - -" 0 - 627 1879689 44 - "-" "-" "-" "-" "151.101.129.67:443" outbound|443||edition.cnn.com 172.30.109.80:41122 172.30.109.80:443 172.30.109.112:59970 edition.cnn.com
{{< /text >}}
如果 Istio 部署在 `istio-system` 命名空间中,则打印日志的命令是:
{{< text bash >}}
$ kubectl logs -l istio=egressgateway -n istio-system
{{< /text >}}
您应该会看到类似于下面的内容:
{{< text plain >}}
[2019-01-02T11:46:46.981Z] "- - -" 0 - 627 1879689 44 - "-" "-" "-" "-" "151.101.129.67:443" outbound|443||edition.cnn.com 172.30.109.80:41122 172.30.109.80:443 172.30.109.112:59970 edition.cnn.com
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
使用 Istio 生成的 Pod 标签访问与 Egress Gateway 对应的日志:
{{< text bash >}}
$ kubectl logs -l istio.io/gateway-name=cnn-egress-gateway -c istio-proxy | tail
{{< /text >}}
您应该会看到类似于下面的内容:
{{< text plain >}}
[2024-01-11T21:09:42.835Z] "- - -" 0 - - - "-" 839 2504306 231 - "-" "-" "-" "-" "151.101.195.5:443" outbound|443||edition.cnn.com 172.30.239.8:34470 172.30.239.8:443 172.30.239.15:43956 edition.cnn.com -
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
### 清理 HTTPS Gateway {#cleanup-https-gateway}
{{< tabset category-name="config-api" >}}
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text bash >}}
$ kubectl delete serviceentry cnn
$ kubectl delete gateway istio-egressgateway
@ -389,6 +644,21 @@ $ kubectl delete virtualservice direct-cnn-through-egress-gateway
$ kubectl delete destinationrule egressgateway-for-cnn
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl delete serviceentry cnn
$ kubectl delete gtw cnn-egress-gateway
$ kubectl delete tlsroute direct-cnn-to-egress-gateway
$ kubectl delete tlsroute forward-cnn-from-egress-gateway
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
## 其他安全注意事项 {#additional-security-considerations}
注意Istio 中定义的 egress `Gateway` 本身并没有为其所在的节点提供任何特殊处理。
@ -401,7 +671,7 @@ Istio 只是通过 Sidecar 代理实现了这种流向。攻击者只要绕过 S
出于安全考虑,集群管理员和云供应商必须确保网格所有的出站流量都要经过 Egress Gateway。
这需要通过 Istio 之外的机制来满足这一要求。例如,集群管理员可以配置防火墙,
拒绝 Egress Gateway 以外的所有流量。
[Kubernetes 网络策略](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/) 也能禁止所有不是从
[Kubernetes 网络策略](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/)也能禁止所有不是从
Egress Gateway 发起的出站流量([下一节](#apply-Kubernetes-network-policies)有一个这样的例子)。
此外,集群管理员和云供应商还可以对网络进行限制,让运行应用的节点只能通过 gateway 来访问外部网络。
要实现这一限制,可以只给 gateway Pod 分配公网 IP并且可以配置 NAT 设备,
@ -409,12 +679,12 @@ Egress Gateway 发起的出站流量([下一节](#apply-Kubernetes-network-pol
## 应用 Kubernetes 网络策略 {#apply-Kubernetes-network-policies}
本节中展示了如何创建 [Kubernetes 网络策略](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/) 来阻止绕过
本节中展示了如何创建 [Kubernetes 网络策略](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/)来阻止绕过
Egress Gateway 的出站流量。为了测试网络策略,首先创建一个 `test-egress` 命名空间,
并在其中部署 [sleep]({{< github_tree >}}/samples/sleep) 示例应用,
然后尝试发送一个会通过安全网关的外部服务请求。
1. 参考[用 Egress gateway 发起 HTTPS 请求](#egress-gateway-for-http-traffic)一节中的步骤。
1. 参考[用 Egress Gateway 发起 HTTPS 请求](#egress-gateway-for-http-traffic)一节中的步骤。
1. 创建 `test-egress` 命名空间:
@ -428,10 +698,16 @@ Egress Gateway 的出站流量。为了测试网络策略,首先创建一个 `
$ kubectl apply -n test-egress -f @samples/sleep/sleep.yaml@
{{< /text >}}
1. 将 [sleep]({{< github_tree >}}/samples/sleep) 样例部署到 `test-egress` 命名空间。
{{< 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
$ 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 >}}
@ -440,34 +716,59 @@ Egress Gateway 的出站流量。为了测试网络策略,首先创建一个 `
发送 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
$ kubectl exec "$(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
组件部署在 `istio-system` 命名空间中,则命令是:
1. 给 Istio 组件(控制平面和 Gateway所在的命名空间打上标签。
如果您将 Istio 部署在 `istio-system` 命名空间中,则命令是:
{{< text bash >}}
$ kubectl label namespace istio-system istio=system
{{< /text >}}
{{< tabset category-name="config-api" >}}
1. 给 `kube-system` 命名空间打标签:
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text bash >}}
$ kubectl label namespace istio-system istio=system
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< text bash >}}
$ kubectl label namespace istio-system istio=system
$ kubectl label namespace default gateway=true
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
7) 给 `kube-system` 命名空间打标签:
{{< text bash >}}
$ kubectl label ns kube-system kube-system=true
{{< /text >}}
1. 创建一个 `NetworkPolicy`,来限制 `test-egress` 命名空间的出站流量,
只允许目标为 `kube-system` DNS端口 53的请求以及目标为 `istio-system`
命名空间的所有请求:
8) 创建一个 `NetworkPolicy`,来限制 `test-egress` 命名空间的出站流量,
只允许目标为控制平面、网关和 `kube-system` DNS 服务(端口 53的所有请求。
{{< text bash >}}
$ cat <<EOF | kubectl apply -n test-egress -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
{{< warning >}}
[网络政策](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/)由
Kubernetes 集群中的网络插件实现。根据您的测试集群,以下步骤中的流量可能不会被阻止。
{{< /warning >}}
{{< tabset category-name="config-api" >}}
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< 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:
spec:
podSelector: {}
policyTypes:
- Egress
@ -483,15 +784,47 @@ Egress Gateway 的出站流量。为了测试网络策略,首先创建一个 `
- namespaceSelector:
matchLabels:
istio: system
EOF
{{< /text >}}
EOF
{{< /text >}}
{{< warning >}}
[网络政策](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/)由您的
Kubernetes 集群中的网络插件实现。根据您的测试集群,以下情况可能不会阻止下面的步骤。
{{< /warning >}}
{{< /tab >}}
1. 重新发送前面的 HTTPS 请求到 [https://edition.cnn.com/politics](https://edition.cnn.com/politics)。
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< 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
- to:
- namespaceSelector:
matchLabels:
gateway: "true"
EOF
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
9) 重新发送前面的 HTTPS 请求到 [https://edition.cnn.com/politics](https://edition.cnn.com/politics)。
这次请求就不会成功了,这是因为流量被网络策略拦截了。`sleep` Pod 无法绕过 `istio-egressgateway`
要访问 `edition.cnn.com`,只能通过 Istio Sidecar 代理,让流量经过 `istio-egressgateway`
才能完成。这种配置表明,即使一些恶意的 Pod 绕过了 Sidecar也会被网络策略拦截而无法访问到外部站点。
@ -511,77 +844,140 @@ Egress Gateway 的出站流量。为了测试网络策略,首先创建一个 `
connect to 151.101.65.67 port 443 failed: Connection timed out
{{< /text >}}
1. 接下来在 `test-egress` 命名空间的 `sleep` Pod 上注入 Sidecar启用
10) 接下来在 `test-egress` 命名空间的 `sleep` Pod 上注入 Sidecar启用
`test-egress` 命名空间的自动注入:
{{< text bash >}}
$ kubectl label namespace test-egress istio-injection=enabled
{{< /text >}}
1. 重新部署 `sleep`
11) 重新部署 `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`
12) 检查生成的 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 >}}
{{< tabset category-name="config-api" >}}
1. 在 `default` 命名空间中创建一个与 `sleep` Pod 类似的目标规则,用来引导
`test-egress` 命名空间内的流量经过 Egress Gateway
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text bash >}}
$ kubectl apply -n test-egress -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
{{< 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 >}}
`default` 命名空间中创建一个与 `sleep` Pod 类似的目标规则,用来引导
`test-egress` 命名空间内的流量经过 Egress Gateway
{{< text bash >}}
$ kubectl apply -n test-egress -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-cnn
spec:
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: cnn
EOF
{{< /text >}}
EOF
{{< /text >}}
1. 向 [https://edition.cnn.com/politics](https://edition.cnn.com/politics)
发送 HTTP 请求,这次会成功,原因是网络策略允许流量流向 `istio-system` 中的
`istio-egressgateway`。`istio-egressgateway` 最终把流量转发到 `edition.cnn.com`
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< 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 >}}
{{< /tab >}}
{{< /tabset >}}
13) 向 [https://edition.cnn.com/politics](https://edition.cnn.com/politics)
发送 HTTP 请求,这次会成功,原因是网络策略允许流量流向 Egress Gateway。
Gateway 最终把流量转发到 `edition.cnn.com`
{{< text bash >}}
$ kubectl exec "$(kubectl get pod -n test-egress -l app=sleep -o jsonpath={.items..metadata.name})" -n test-egress -c sleep -- curl -sS -o /dev/null -w "%{http_code}\n" https://edition.cnn.com/politics
200
{{< /text >}}
1. 检查 Egress gateway 中的代理统计数据。如果 Istio 部署在 `istio-system`
命名空间,那么打印日志的命令就是:
14) 检查 Egress Gateway 代理的日志。
{{< text bash >}}
$ kubectl logs -l istio=egressgateway -n istio-system
{{< /text >}}
{{< tabset category-name="config-api" >}}
您应该会看到一行类似于下面这样的内容:
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text plain >}}
[2020-03-06T18:12:33.101Z] "- - -" 0 - "-" "-" 906 1352475 35 - "-" "-" "-" "-" "151.101.193.67:443" outbound|443||edition.cnn.com 172.30.223.53:39460 172.30.223.53:443 172.30.223.58:38138 edition.cnn.com -
{{< /text >}}
如果 Istio 部署在 `istio-system` 命名空间,那么打印日志的命令就是:
{{< text bash >}}
$ kubectl logs -l istio=egressgateway -n istio-system
{{< /text >}}
您应该会看到一行类似于下面这样的内容:
{{< text plain >}}
[2020-03-06T18:12:33.101Z] "- - -" 0 - "-" "-" 906 1352475 35 - "-" "-" "-" "-" "151.101.193.67:443" outbound|443||edition.cnn.com 172.30.223.53:39460 172.30.223.53:443 172.30.223.58:38138 edition.cnn.com -
{{< /text >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
使用 Istio 生成的 Pod 标签访问与 Egress Gateway 对应的日志:
{{< text bash >}}
$ kubectl logs -l istio.io/gateway-name=cnn-egress-gateway -c istio-proxy | tail
{{< /text >}}
您应该会看到一行类似于下面这样的内容:
{{< text plain >}}
[2024-01-12T19:54:01.821Z] "- - -" 0 - - - "-" 839 2504837 46 - "-" "-" "-" "-" "151.101.67.5:443" outbound|443||edition.cnn.com 172.30.239.60:49850 172.30.239.60:443 172.30.239.21:36512 edition.cnn.com -
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
### 清理网络策略 {#cleanup-network-policies}
1. 删除本节中建立的资源:
{{< text bash >}}
$ kubectl delete -f @samples/sleep/sleep.yaml@ -n test-egress
$ kubectl delete destinationrule egressgateway-for-cnn -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 >}}
{{< tabset category-name="config-api" >}}
{{< tab name="Istio APIs" category-value="istio-apis" >}}
{{< text bash >}}
$ kubectl delete -f @samples/sleep/sleep.yaml@ -n test-egress
$ kubectl delete destinationrule egressgateway-for-cnn -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 >}}
{{< /tab >}}
{{< tab name="Gateway API" category-value="gateway-api" >}}
{{< 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 label namespace default gateway-
$ kubectl delete namespace test-egress
{{< /text >}}
{{< /tab >}}
{{< /tabset >}}
1. 请参考[清理 HTTPS Gateway](#cleanup-https-gateway) 一节的内容。
@ -596,8 +992,8 @@ Egress Gateway 的出站流量。为了测试网络策略,首先创建一个 `
URI:spiffe://cluster.local/ns/istio-system/sa/istio-egressgateway-service-account
{{< /text >}}
1. HTTPS 透传流量情况(由应用而不是 egress 发起 TLS需要使用 `openssl` 命令测试流量。
`openssl``-servername` 选项可以用来设置 SNI
1. HTTPS 透传流量情况(由应用而不是 egress 发起 TLS需要使用 **openssl** 命令测试流量。
**openssl**`-servername` 选项可以用来设置 SNI
{{< text bash >}}
$ kubectl exec "$SOURCE_POD" -c sleep -- openssl s_client -connect edition.cnn.com:443 -servername edition.cnn.com