在全局启用 istio 和 mTLS 的情况下公开虚拟服务
Exposing virtual service with istio and mTLS globally enabled
我的服务网格上有这个配置:
- mTLS 全局启用且 meshpolicy 默认
- 在端口 8080 上公开为 clusterip 的简单 Web 部署
- 端口 80 的 http 网关和我服务上的虚拟服务路由
这里是 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
来避免此问题。
我的服务网格上有这个配置:
- mTLS 全局启用且 meshpolicy 默认
- 在端口 8080 上公开为 clusterip 的简单 Web 部署
- 端口 80 的 http 网关和我服务上的虚拟服务路由
这里是 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
来避免此问题。