5、Ingress 出口流量
Egress Gateway
默认情况下,Istio 网关中 Pod 的所有出站流量都会重定向到其 Sidecar 代理,集群外部 URL 的可访问性取决于代理的配置。默认情况下,Istio 将 Envoy 代理配置为允许传递未知服务的请求,这样当然是非常方便的,但是有的时候可能我们也需要更加严格的控制。
目录
[toc]
本节实战
实战名称 |
---|
🚩 实战:访问外部服务-2023.11.18(测试成功) |
🚩 实战:Egress 出口网关-2023.11.18(测试成功) |
访问外部服务
==🚩 实战:访问外部服务-2023.11.18(测试成功)==
实验环境:
k8sv1.27.6(containerd:istiov1.19.3(--setprofile=demo)
实验软件:
1.Envoy 转发流量到外部服务
Istio 有一个安装选项 global.outboundTrafficPolicy.mode
,它配置 Sidecar 对外部服务(没有在 Istio 的内部服务注册中定义的服务)的处理方式。如果这个选项设置为 ALLOW_ANY
, Istio 代理允许调用未知的服务。如果这个选项设置为 REGISTRY_ONLY
,那么 Istio 代理会阻止任何没有在网格中定义的 HTTP 服务或 Service Entry
的主机。ALLOW_ANY
是默认值,不控制对外部服务的访问。
- 我们可以运行以下命令来查看该配置的值:
kubectlgetistiooperatorinstalled-state-nistio-system-ojsonpath='{.spec.meshConfig.outboundTrafficPolicy.mode}'
正常该命令会输出 ALLOW_ANY
或没有任何输出(默认为 ALLOW_ANY
)。
如果之前已经设置为了 REGISTRY_ONLY
,则可以使用 istioctl
命令来修改:
istioctlinstall<flags-you-used-to-install-Istio>--setmeshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
- 我们可以从
SOURCE_POD
向外部 HTTPS 服务发出两个请求来进行验证:
$kubectlexec"$SOURCE_POD"-csleep--curl-sSIhttps:HTTP/1.1200OKHTTP/1.1200OK
如果得到 200 状态码,说明我们成功地从网格中发送了 Egress 流量,这是因为我们的网格中的 Sidecar 代理允许访问任何外部服务。当然这种方式虽然很简单,但是丢失了对外部服务流量的 Istio 监控和控制,比如外部服务的调用没有记录到 Mixer 的日志中。
测试结束。😘
2.控制对外部服务的访问
要控制对外部服务的访问,我们需要用到 Istio 提供的 ServiceEntry
这个 CRD 对象,它用来定义网格中的服务。接下来我们将来了解下如何在不丢失 Istio 的流量监控和控制特性的情况下,配置对外部 HTTP 服务(httpbin.org
)和外部 HTTPS 服务(www.baidu.com
) 的访问。
为了控制对外部服务的访问,我们需要将 global.outboundTrafficPolicy.mode
选项,从 ALLOW_ANY
模式改为 REGISTRY_ONLY
模式。
如果你使用的是 IstioOperator
来安装 Istio,则只需要在配置中添加以下字段即可:
spec:meshConfig:outboundTrafficPolicy:mode:REGISTRY_ONLY
- 当然也可以使用如下所示的
istio install
命令来修改:
$istioctlinstall--setprofile=demo--setmeshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLYThiswillinstalltheIstio1.19.3"demo"profile(with components:Istiocore,Istiod,Ingressgateways,andEgressgateways) into the cluster. Proceed?(y/N) y✔Istiocoreinstalled✔Istiodinstalled✔Ingressgatewaysinstalled✔Egressgatewaysinstalled✔InstallationcompleteMadethisinstallationthedefaultforinjectionandvalidation.
安装完成后可以使用下面的命令来查看出口流量策略的配置:
$kubectlgetistiooperatorinstalled-state-nistio-system-ojsonpath='{.spec.meshConfig.outboundTrafficPolicy.mode}'REGISTRY_ONLY
如果输出结果为 REGISTRY_ONLY
则说明我们已经成功修改了出口流量策略。
- 然后我们再从
SOURCE_POD
向外部 HTTPS 服务发出几个请求,来验证它们现在是否被阻止:
$kubectlexec"$SOURCE_POD"-csleep--curl-sSIhttps:commandterminatedwithexitcode35commandterminatedwithexitcode35
正常情况下,这里会返回 35 错误码,说明我们已经成功地阻止了对外部服务的访问。
配置更改后可能需要一小段时间才能生效,所以可能仍然可以得到成功的响应,等待一段时间后再重新执行上面的命令即可。
接下来我们就可以自己定义 ServiceEntry
对象来配置对外部服务的访问了。使用 服务条目资源(ServiceEntry
)可以将条目添加到 Istio 内部维护的服务注册表中,添加服务条目后,Envoy 代理可以将流量发送到该服务,就好像该服务条目是网格中的服务一样。通过配置服务条目,可以管理在网格外部运行的服务的流量。此外,还可以配置虚拟服务和目标规则,以更精细的方式控制到服务条目的流量,就像为网格中的其他任何服务配置流量一样。
- 这里我们创建一个如下所示的
ServiceEntry
对象:
#httpbin-ext.yamlapiVersion:networking.istio.io/v1alpha3kind:ServiceEntrymetadata:name:httpbin-extspec:hosts:- httpbin.orgports:- number:80name:httpprotocol:HTTPresolution:DNS# 主机的服务发现模式location:MESH_EXTERNAL# 指定服务是否应被视为网格外部的一部分还是网格的一部分
该资源对象中我们在 hosts
中指定了 httpbin.org
服务的主机名,然后在 ports
中指定了需要暴露的端口及其属性,表示该 ServiceEntry
对象代表对 http:[root@master1 istio-1.19.3]#kubectl exec "$SOURCE_POD"-c sleep -- curl -sS http:serviceentry.networking.istio.io/httpbin-extcreated$kubectlexec"$SOURCE_POD"-csleep--curl-sShttp:{"headers":{"Accept":"**","Host":"httpbin.org",...}}
与通过 HTTP 和 HTTPS 访问外部服务不同,我们不会看到任何与 Istio Sidecar 有关的请求头,并且发送到外部服务的请求既不会出现在 Sidecar 的日志中,也不会出现在 Mixer 日志中。 绕过 Istio Sidecar 意味着不能再监视对外部服务的访问了。
- 最后记得清理上面创建的资源对象。
kubectldelete-fhttpbin-ext.yamlkubectldelete-fhttpbin-ext-vs.yamlkubectldelete-fbaidu-ext.yaml
总结
这里我们学习了从 Istio 网格调用外部服务的三种方法:
- 配置 Envoy 以允许访问任何外部服务。
- 使用
ServiceEntry
将一个可访问的外部服务注册到网格中,这是推荐的方法。 - 配置 Istio Sidecar 以从其重新映射的 IP 表中排除外部 IP。
第一种方法通过 Istio Sidecar 代理来引导流量,包括对网格内部未知服务的调用。使用这种方法时,无法监控对外部服务的访问或无法利用 Istio 的流量控制功能。要轻松为特定的服务切换到第二种方法,只需为那些外部服务创建 ServiceEntry 即可,此过程使您可以先访问任何外部服务,然后再根据需要决定是否启用控制访问、流量监控、流量控制等功能。
第二种方法可以使用 Istio 服务网格所有的功能去调用集群内或集群外的服务。这里我们学习了如何监控对外部服务的访问并设置对外部服务的调用的超时规则。
第三种方法绕过了 Istio Sidecar 代理,使你的服务可以直接访问任意的外部服务。但是,以这种方式配置代理需要了解集群提供商相关知识和配置。 与第一种方法类似,您也将失去对外部服务访问的监控,并且无法将 Istio 功能应用于外部服务的流量。
Egress 出口网关
上面我们了解了位于服务网格内部的应用应如何访问网格外部的 HTTP 和 HTTPS 服务,我们学习了如何通过 ServiceEntry
对象配置 Istio 以受控的方式访问外部服务,这种方式实际上是通过 Sidecar 直接调用的外部服务,但是有时候我们可能需要通过专用的 Egress Gateway 服务来调用外部服务,这种方式可以更好的控制对外部服务的访问。
Istio 使用 Ingress 和 Egress Gateway 配置运行在服务网格边缘的负载均衡,Ingress Gateway 允许定义网格所有入站流量的入口。 Egress Gateway 是一个与 Ingress Gateway 对称的概念,它定义了网格的出口。Egress Gateway 允许我们将 Istio 的功能(例如,监视和路由规则)应用于网格的出站流量。
==使用场景==
比如有一个对安全要求非常严格的团队,要求服务网格所有的出站流量必须经过一组专用节点。专用节点运行在专门的机器上,与集群中运行应用程序的其他节点隔离,这些专用节点用于实施 Egress 流量的策略,并且受到比其余节点更严密地监控。
另一个使用场景是集群中的应用节点没有公有 IP,所以在该节点上运行的网格服务都无法访问互联网,那么我们就可以通过定义 Egress gateway,将公有 IP 分配给 Egress Gateway 节点,用它引导所有的出站流量,可以使应用节点以受控的方式访问外部服务。
==🚩 实战:Egress 出口网关-2023.11.18(测试成功)==
实验环境:
k8sv1.27.6(containerd:istiov1.19.3(--setprofile=demo)
实验软件:
链接:https:NAMEREADYSTATUSRESTARTSAGEistio-egressgateway-556f6f58f4-hkzdd1/1Running014d