Wildcard 主机的 egress

控制 Egress 流量任务和 配置一个 Egress 网关示例描述如何配置特定主机的 Egress 流量,如:edition.cnn.com。本示例描述如何为通用域中的一组特定主机开启 Egress 流量, 譬如 *.wikipedia.org,无需单独配置每一台主机。

背景

假定您想要为 Istio 中所有语种的 wikipedia.org 站点开启 Egress 流量。每个语种的 wikipedia.org 站点均有自己的主机名,譬如:英语和德语对应的主机分别为 en.wikipedia.orgde.rikipedia.org。您希望通过通用配置项开启所有 Wikipedia 站点的 Egress 流量,无需单独配置每个语种的站点。

开始之前 (before-you-begin)

  • 使用 demo 配置文件安装 Istio 以及默认阻止出站流量策略:

    1. $ istioctl install --set profile=demo --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY

    您可以在 demo 配置文件以外的 Istio 配置上运行此任务, 只要您确保 部署 Istio Egress 网关开启 Envoy 的访问日志应用默认阻止出站流量策略

  • 部署 sleep 示例应用程序,以用作发送请求的测试源。 如果您开启了 Sidecar 自动注入, 运行以下命令以部署示例应用程序:

    Zip

    1. $ kubectl apply -f @samples/sleep/sleep.yaml@

    否则,在使用以下命令部署 sleep 应用程序之前,手动注入 Sidecar:

    Zip

    1. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@)

    您可以在任意 Pod 上使用 curl 作为测试源。

  • SOURCE_POD 环境变量设置为您的源 Pod 的名称:

    1. $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})

引导流量流向 Wildcard 主机

访问通用域中一组主机的第一个也是最简单的方法,是使用一个 wildcard 主机配置一个简单的 ServiceEntry, 直接从 Sidecar 调用服务。当直接调用服务时(譬如:不是通过一个 Egress 网关),一个 wildcard 主机的配置与任何其他主机(如:全域名主机)没有什么不同,只是当通用域中有许多台主机时,这样比较方便。

请注意,恶意应用程序很容易绕过以下配置。为了实现安全的出口流量控制,可以通过出口网关引导流量。

请注意,DNS 解析不能用于通配符主机。这就是为什么 NONE 分辨率(因为它是默认)用于以下服务条目。

  1. *.wikipedia.org 定义一个 ServiceEntry 以及相应的 VirtualService

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: ServiceEntry
    4. metadata:
    5. name: wikipedia
    6. spec:
    7. hosts:
    8. - "*.wikipedia.org"
    9. ports:
    10. - number: 443
    11. name: https
    12. protocol: HTTPS
    13. EOF
  2. 发送 HTTPS 请求至 https://en.wikipedia.org and https://de.wikipedia.org:

    1. $ kubectl exec -it $SOURCE_POD -c sleep -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"'
    2. <title>Wikipedia, the free encyclopedia</title>
    3. <title>Wikipedia Die freie Enzyklopädie</title>

清除引导流量至 wildcard 主机

  1. $ kubectl delete serviceentry wikipedia

单一 hosting 服务器的 Wildcard 配置

当一台唯一的服务器为所有 wildcard 主机提供服务时,基于 Egress 网关访问 wildcard 主机的配置与普通主机类似, 除了:配置的路由目标不能与配置的主机相同,如:wildcard 主机,需要配置为通用域集合的唯一服务器主机。

  1. *.wikipedia.org 创建一个 Egress Gateway、一个目标规则以及一个虚拟服务,来 引导请求通过 Egress 网关并从 Egress 网关访问外部服务。

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: Gateway
    4. metadata:
    5. name: istio-egressgateway
    6. spec:
    7. selector:
    8. istio: egressgateway
    9. servers:
    10. - port:
    11. number: 443
    12. name: https
    13. protocol: HTTPS
    14. hosts:
    15. - "*.wikipedia.org"
    16. tls:
    17. mode: PASSTHROUGH
    18. ---
    19. apiVersion: networking.istio.io/v1alpha3
    20. kind: DestinationRule
    21. metadata:
    22. name: egressgateway-for-wikipedia
    23. spec:
    24. host: istio-egressgateway.istio-system.svc.cluster.local
    25. subsets:
    26. - name: wikipedia
    27. ---
    28. apiVersion: networking.istio.io/v1alpha3
    29. kind: VirtualService
    30. metadata:
    31. name: direct-wikipedia-through-egress-gateway
    32. spec:
    33. hosts:
    34. - "*.wikipedia.org"
    35. gateways:
    36. - mesh
    37. - istio-egressgateway
    38. tls:
    39. - match:
    40. - gateways:
    41. - mesh
    42. port: 443
    43. sniHosts:
    44. - "*.wikipedia.org"
    45. route:
    46. - destination:
    47. host: istio-egressgateway.istio-system.svc.cluster.local
    48. subset: wikipedia
    49. port:
    50. number: 443
    51. weight: 100
    52. - match:
    53. - gateways:
    54. - istio-egressgateway
    55. port: 443
    56. sniHosts:
    57. - "*.wikipedia.org"
    58. route:
    59. - destination:
    60. host: www.wikipedia.org
    61. port:
    62. number: 443
    63. weight: 100
    64. EOF
  2. 为目标服务器 www.wikipedia.org 创建一个 ServiceEntry

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: ServiceEntry
    4. metadata:
    5. name: www-wikipedia
    6. spec:
    7. hosts:
    8. - www.wikipedia.org
    9. ports:
    10. - number: 443
    11. name: tls
    12. protocol: TLS
    13. resolution: DNS
    14. EOF
  3. 发送请求至 https://en.wikipedia.orghttps://de.wikipedia.org

    1. $ kubectl exec -it $SOURCE_POD -c sleep -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"'
    2. <title>Wikipedia, the free encyclopedia</title>
    3. <title>Wikipedia Die freie Enzyklopädie</title>
  4. 检查 Egress 网关代理访问 *.wikipedia.org 的计数器统计值。如果 Istio 部署在 istio-system 命名空间中,打印输出计数器的命令为:

    1. $ kubectl exec -it $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -n istio-system -- pilot-agent request GET clusters | grep '^outbound|443||www.wikipedia.org.*cx_total:'
    2. outbound|443||www.wikipedia.org::208.80.154.224:443::cx_total::2

清除单点服务器的 wildcard 配置

  1. $ kubectl delete serviceentry www-wikipedia
  2. $ kubectl delete gateway istio-egressgateway
  3. $ kubectl delete virtualservice direct-wikipedia-through-egress-gateway
  4. $ kubectl delete destinationrule egressgateway-for-wikipedia

清除

Zip

  1. $ kubectl delete -f @samples/sleep/sleep.yaml@
  • 从您的集群中卸载 Istio:

    1. $ istioctl uninstall --purge -y