首页 文章

与Kubernetes服务的Istio出口

提问于
浏览
1

(使用Istio 0.5.1,kubectl 1.9.1 / 1.9.0用于客户端/服务器,minikube 0.25.0)

我试图让Istio EgressRules与Kubernetes Services合作,但遇到了一些麻烦 .

我尝试设置EgressRules 3种方式:

  • 指向其他域的ExternalName服务(如www.google.com)

  • 没有选择器但关联的Endpoint对象的服务(对于具有IP地址但没有DNS名称的服务)

  • (用于比较)没有Kubernetes服务,只是一个EgressRule

我想我可以使用kubernetes服务的FQDN作为基于HTTP的EgressRule目标服务(如 ext-service.default.svc.cluster.local ),这就是我尝试的ExternalName服务以及没有选择器但只有关联的Endpoints对象的服务 .

对于前者,我创建了以下 yaml 文件:

kind: Service
apiVersion: v1
metadata:
  name: ext-service
spec:
  type: ExternalName
  externalName: www.google.com
---
apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
  name: ext-egress-rule
spec:
  destination:
    service: ext-service.default.svc.cluster.local
  ports:
    - port: 443
      protocol: https

对于后者,我创建了这个 yaml 文件(我只是ping了google并 grab 了IP地址):

kind: Endpoints
apiVersion: v1
metadata:
  name: ext-service
subsets:
  - addresses:
      - ip: 216.58.198.78
    ports:
      - port: 443
---
kind: Service
apiVersion: v1
metadata:
  name: ext-service
spec:
  ports:
  - protocol: TCP
    port: 443
    targetPort: 443
---
apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
  name: ext-service-egress-rule
spec:
  destination:
    service: ext-service.default.svc.cluster.local
  ports:
    - port: 443
      protocol: https

在这两种情况下,在应用程序代码中,我访问:

http://ext-service.default.svc.cluster.local:443

我的假设是流量会像以下一样流动:

[[ app -> envoy proxy -> (tls origination) -> kubernetes service ]] -> external service

其中 [[ ... ]] 是服务网格的边界(以及Kubernetes集群)

结果:

  • ExternalName 服务几乎按预期工作,但它带我到谷歌的404页面(有时响应似乎是空的,不知道如何特别复制一个或另一个)

  • 使用Endpoint对象的服务不起作用,而是打印此消息(通过Golang发出请求时,但我认为不重要):

获取http://ext-service.default.svc.cluster.local:443:EOF

这有时也会给出空洞的回应 .

我想使用Kubernetes服务(即使它是针对外部流量)的原因有以下几点:

  • 您可以't use an IP address for the EgressRule'的目的地服务 . 从Egress Rules configuration:"The destination of an egress rule ... can be either a fully qualified or wildcard domain name" .

  • 对于不喜欢应用程序的外部服务,不能通过IP地址访问它们,而是通过kube-dns(或与Istio相关的类似名称)访问它们 .

  • (与之前相关)我喜欢Kubernetes服务提供的额外抽象层,因此我可以在不更改EgressRule的情况下更改基础目标(除非我正确地构建此框架) . EgressRule是否意味着完全取代Kubernetes服务以获得外部流量,而无需创建额外的Kubernetes服务?

在应用程序代码中使用 https:// 与证书上的任何内容都不匹配 . 它也是不可观察的 .

如果我使用以下EgressRule(没有任何Kubernetes服务),通过 http://www.google.com:443 访问Google工作正常,获得我期望的确切html表示:

apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
  name: google-egress-rule
spec:
  destination:
    service: www.google.com
  ports:
    - port: 443
      protocol: https

我看到有一个TCP EgressRule,但我宁愿不必为每个IP块指定规则 . 从TCP Egress:"In TCP egress rules as opposed to HTTP-based egress rules, the destinations are specified by IPs or by blocks of IPs in CIDR notation." .

此外,我仍然喜欢来自L7而不是L4的基于HTTP的可观察性,所以我更喜欢基于HTTP的出口 . (使用TCP Egresses,“由应用程序发起的HTTPS流量将被Istio视为不透明的TCP”) .

任何帮助获得Kubernetes服务作为EgressRule的“目的地服务”(或帮助理解为什么这不是必要的,如果是这种情况)的任何帮助表示赞赏 . 谢谢!

1 回答

  • 1

    解决方案是:

    • 定义Kubernetes ExternalName服务以指向www.google.com

    • 不要定义任何EgressRules

    • 创建RouteRule以设置主机标头 .

    在您的情况下,使用端口和协议定义ExternalName服务:

    kind: Service
    apiVersion: v1
    metadata:
      name: ext-service
    spec:
      type: ExternalName
      externalName: www.google.com
       ports:
       - port: 80
       # important to set protocol name
       name: http
    ---
    

    定义HTTP重写路由规则以设置主机头:

    apiVersion: config.istio.io/v1alpha2
    kind: RouteRule
    metadata:
      name: externalgoogle-rewrite-rule
      #namespace: default
    spec:
      destination:
        name: ext-service
      rewrite:
        authority: www.google.com
    ---
    

    然后使用 curl 访问它,例如: curl ext-service

    如果没有路由规则,请求将到达google.com,主机标头为 ext-service . 由于google.com没有这样的虚拟主机,因此Web服务器不知道转发此类请求的位置 . 这是你经历的:

    它把我带到了谷歌的404页面

相关问题