在全局启用 istio 和 mTLS 的情况下公开虚拟服务

Exposing virtual service with istio and mTLS globally enabled

我的服务网格上有这个配置:

这里是 gw 和 vs yaml

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: http-gateway
spec:
  selector:
    istio: ingressgateway # Specify the ingressgateway created for us
  servers:
  - port:
      number: 80 # Service port to watch
      name: http-gateway
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: simple-web
spec:
  gateways:
  - http-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /simple-web
    rewrite:
      uri: /
    route:
    - destination:
        host: simple-web
        port:
          number: 8080

vs 和 gw 都在同一个命名空间中。 部署是使用以下命令创建和公开的:

k create deployment --image=yeasy/simple-web:latest simple-web
k expose deployment simple-web --port=8080 --target-port=80 --name=simple-web

然后用 k get pods 我收到这个:

pod/simple-web-9ffc59b4b-n9f85   2/2     Running

发生的事情是,从外部指向入口网关负载平衡器,我收到 503 HTTP 错误。 如果我尝试从 ingressgateway pod 卷曲,我可以访问 simple-web 服务。 为什么我无法访问启用了 mTLS 的网站?正确的配置是什么?

我刚刚安装了 istio-1.3.2 和 k8s 1.15.1 来重现你的问题,并且它没有任何修改就可以工作。这就是我所做的:

0.- 创建一个名为 istio 的命名空间并自动启用 sidecar 注入。

1.- $ kubectl run nginx --image nginx -n istio

2.- $ kubectl expose deploy nginx --port 8080 --target-port 80 --name simple-web -n istio

3.- $kubectl craete -f gw.yaml -f vs.yaml

注意:这些是您的文件。

测试:

$ curl a.b.c.d:31380/simple-web -I
HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 11 Oct 2019 10:04:26 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 24 Sep 2019 14:49:10 GMT
etag: "5d8a2ce6-264"
accept-ranges: bytes
x-envoy-upstream-service-time: 4


[2019-10-11T10:04:26.101Z] "HEAD /simple-web HTTP/1.1" 200 - "-" "-" 0 0 6 4 "10.132.0.36" "curl/7.52.1" "4bbc2609-a928-9f79-9ae8-d6a3e32217d7" "a.b.c.d:31380" "192.168.171.73:80" outbound|8080||simple-web.istio.svc.cluster.local - 192.168.171.86:80 10.132.0.36:37078 - -

并确保 mTLS 已启用,这是来自 ingress-gateway 描述命令:

--controlPlaneAuthPolicy MUTUAL_TLS

所以,我不知道哪里出了问题,但您可能想完成这些步骤并丢弃一些东西。

注意:我在端口 31380 上攻击 istio 网关的原因是因为我的 k8s 现在在虚拟机上,我不想启动 GKE 集群进行测试。

编辑

刚刚使用您的映像部署了另一个部署,将其公开为 simple-web-2,然后再次运行。可能是我对 istio 很幸运:

$ curl a.b.c.d:31380/simple-web -I
HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 11 Oct 2019 10:28:45 GMT
content-type: text/html
content-length: 354
last-modified: Fri, 11 Oct 2019 10:28:46 GMT
x-envoy-upstream-service-time: 4

[2019-10-11T10:28:46.400Z] "HEAD /simple-web HTTP/1.1" 200 - "-" "-" 0 0 5 4 "10.132.0.36" "curl/7.52.1" "df0dd00a-875a-9ae6-bd48-acd8be1cc784" "a.b.c.d:31380" "192.168.171.65:80" outbound|8080||simple-web-2.istio.svc.cluster.local - 192.168.171.86:80 10.132.0.36:42980 - -

你的k8s环境是什么?

EDIT2

# istioctl authn tls-check curler-6885d9fd97-vzszs simple-web.istio.svc.cluster.local -n istio
HOST:PORT                                   STATUS     SERVER     CLIENT     AUTHN POLICY     DESTINATION RULE
simple-web.istio.svc.cluster.local:8080     OK         mTLS       mTLS       default/         default/istio-system

正如@suren 在他的回答中提到的,这个问题在 istio 版本 1.3.2 中不存在。所以解决方案之一是使用较新的版本。

如果您选择将 Istio 升级到更新版本,请查看文档 1.3 Upgrade Notice and Upgrade Steps,因为 Istio 仍在开发中,并且每个版本都会发生巨大变化。

正如@Manuel Castro 在评论中提到的,这很可能是 Avoid 503 errors while reconfiguring service routes 中解决的问题,而较新的版本可以更好地处理它们。

Creating both the VirtualServices and DestinationRules that define the corresponding subsets using a single kubectl call (e.g., kubectl apply -f myVirtualServiceAndDestinationRule.yaml is not sufficient because the resources propagate (from the configuration server, i.e., Kubernetes API server) to the Pilot instances in an eventually consistent manner. If the VirtualService using the subsets arrives before the DestinationRule where the subsets are defined, the Envoy configuration generated by Pilot would refer to non-existent upstream pools. This results in HTTP 503 errors until all configuration objects are available to Pilot.

应该可以通过暂时禁用 mTLS 或在部署期间使用 permissive mode 来避免此问题。