Istio mTLS仅在某些服务之间工作,即使tls-check打印每个人的状态都可以 [英] Istio mTLS working just between some services even though tls-check prints STATUS OK for everyone
问题描述
我正在尝试在已经使用istio的边车工作的网格中启用mTLS. 我遇到的问题是,我只能将工作连接提高到一个点,然后它才无法连接.
I am trying to enable mTLS in my mesh that I have already working with istio's sidecars. The problem I have is that I just get working connections up to one point, and then it fails to connect.
这是由于我失败的mTLS实现(简化)而立即设置服务的方式:
This is how the services are set up right now with my failing implementation of mTLS (simplified):
Istio IngressGateway-> NGINX pod-> API网关->服务A-> [数据库] ->服务B
Istio IngressGateway -> NGINX pod -> API Gateway -> Service A -> [ Database ] -> Service B
首先要注意的是,我使用NGINX Pod作为负载均衡器,以将请求发送到API网关或前端页面.我试着在没有istio IngressGateway的情况下保持该状态,但无法使其正常运行.然后,我尝试使用Istio IngressGateway并通过VirtualService直接连接到API网关,但对我来说还是失败.因此,我暂时将其保留下来,因为这是我的请求成功到达API网关的唯一途径.
First thing to note is that I was using a NGINX pod as a load balancer to proxy_pass my requests to my API Gateway or my frontend page. I tried keeping that without the istio IngressGateway but I wasn't able to make it work. Then I tried to use Istio IngressGateway and connect directly to the API Gateway with VirtualService but also fails for me. So I'm leaving it like this for the moment because it was the only way that my request got to the API Gateway successfully.
要注意的另一件事是,服务A首先连接到网格外部的数据库,然后向网格内部且启用了mTLS的服务B发出请求.
Another thing to note is that Service A first connects to a Database outside the mesh and then makes a request to Service B which is inside the mesh and with mTLS enabled.
NGINX,API网关,服务A和服务B在启用了mTLS的网格内,并且"istioctl authn tls-check" 显示状态为OK.
NGINX, API Gateway, Service A and Service B are within the mesh with mTLS enabled and "istioctl authn tls-check" shows that status is OK.
NGINX和API网关位于名为网关" 的命名空间中,数据库位于"auth" 中,服务A和服务B位于另一个名为的命名空间中"api" .
NGINX and API Gateway are in a namespace called "gateway", Database is in "auth" and Service A and Service B are in another one called "api".
Istio IngressGateway现在位于名称空间"istio-system" 中.
Istio IngressGateway is in namespace "istio-system" right now.
所以问题在于,如果我将 STRICT 模式设置为网关名称空间并将 PERMISSIVE 设置为api,但是一旦我设置了 STRICT ,一切都会正常api,我看到请求进入服务A,但随后无法将请求与500一起发送给服务B.
So the problem is that everything work if I set STRICT mode to the gateway namespace and PERMISSIVE to api, but once I set STRICT to api, I see the request getting into Service A, but then it fails to send the request to Service B with a 500.
这是我在服务A窗格中的istio-proxy容器中看到的失败时的输出:
This is the output when it fails that I can see in the istio-proxy container in the Service A pod:
api/serviceA[istio-proxy]: [2019-09-02T12:59:55.366Z] "- - -" 0 - "-" "-" 1939 0 2 - "-" "-" "-" "-" "10.20.208.248:4567" outbound|4567||database.auth.svc.cluster.local 10.20.128.44:35366 10.20.208.248:4567
10.20.128.44:35364 -
api/serviceA[istio-proxy]: [2019-09-02T12:59:55.326Z] "POST /api/my-call HTTP/1.1" 500 - "-" "-" 74 90 60 24 "10.90.0.22, 127.0.0.1, 127.0.0.1" "PostmanRuntime/7.15.0" "14d93a85-192d-4aa7-aa45-1501a71d4924" "serviceA.api.svc.cluster.local:9090" "127.0.0.1:9090" inbound|9090|http-serviceA|serviceA.api.svc.cluster.local - 10.20.128.44:9090 127.0.0.1:0 outbound_.9090_._.serviceA.api.svc.cluster.local
但是ServiceB中没有消息.
No messages in ServiceB though.
当前,我没有全局的MeshPolicy,我正在为每个命名空间设置Policy和DestinationRule
Currently, I do not have a global MeshPolicy, and I am setting Policy and DestinationRule per namespace
政策:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: gateway
spec:
peers:
- mtls:
mode: STRICT
---
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: auth
spec:
peers:
- mtls:
mode: STRICT
---
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: api
spec:
peers:
- mtls:
mode: STRICT
目的地规则:
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "mutual-gateway"
namespace: "gateway"
spec:
host: "*.gateway.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
---
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "mutual-api"
namespace: "api"
spec:
host: "*.api.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
---
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "mutual-auth"
namespace: "auth"
spec:
host: "*.auth.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
然后,我有一些DestinationRule来禁用数据库的mTLS(我想在同一名称空间中使用mTLS启用其他服务)和Kubernetes API
Then I have some DestinationRule to disable mTLS for Database (I have some other services in the same namespace that I want to enable with mTLS) and for Kubernetes API
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: "myDatabase"
namespace: "auth"
spec:
host: "database.auth.svc.cluster.local"
trafficPolicy:
tls:
mode: DISABLE
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: "k8s-api-server"
namespace: default
spec:
host: "kubernetes.default.svc.cluster.local"
trafficPolicy:
tls:
mode: DISABLE
然后我的IngressGateway就像这样:
Then I have my IngressGateway like so:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ingress-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway # use istio default ingress gateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- my-api.example.com
tls:
httpsRedirect: true # sends 301 redirect for http requests
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
privateKey: /etc/istio/ingressgateway-certs/tls.key
hosts:
- my-api.example.com
最后,我的VirtualServices:
And lastly, my VirtualServices:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ingress-nginx
namespace: gateway
spec:
hosts:
- my-api.example.com
gateways:
- ingress-gateway.istio-system
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: ingress.gateway.svc.cluster.local # this is NGINX pod
corsPolicy:
allowOrigin:
- my-api.example.com
allowMethods:
- POST
- GET
- DELETE
- PATCH
- OPTIONS
allowCredentials: true
allowHeaders:
- "*"
maxAge: "24h"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: api-gateway
namespace: gateway
spec:
hosts:
- my-api.example.com
- api-gateway.gateway.svc.cluster.local
gateways:
- mesh
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: api-gateway.gateway.svc.cluster.local
corsPolicy:
allowOrigin:
- my-api.example.com
allowMethods:
- POST
- GET
- DELETE
- PATCH
- OPTIONS
allowCredentials: true
allowHeaders:
- "*"
maxAge: "24h"
我不明白的一件事是为什么我必须为我的API网关创建VirtualService,以及为什么必须在网关块中使用网格".如果删除此块,则不会在API网关中收到我的请求,但是,如果我成功了,它就会起作用,并且我的请求甚至到达下一个服务(服务A),而不是下一个服务.
One thing that I don't understand is why do I have to create a VirtualService for my API Gateway and why do I have to use "mesh" in the gateways block. If I remove this block, I don't get my request in API Gateway, but if I do, it works and my requests even get to the next service (Service A), but not the next one to that.
感谢您的帮助.我真的很坚持.
Thanks for the help. I am really stuck with this.
ServiceA的侦听器转储:
Dump of listeners of ServiceA:
ADDRESS PORT TYPE
10.20.128.44 9090 HTTP
10.20.253.21 443 TCP
10.20.255.77 80 TCP
10.20.240.26 443 TCP
0.0.0.0 7199 TCP
10.20.213.65 15011 TCP
0.0.0.0 7000 TCP
10.20.192.1 443 TCP
0.0.0.0 4568 TCP
0.0.0.0 4444 TCP
10.20.255.245 3306 TCP
0.0.0.0 7001 TCP
0.0.0.0 9160 TCP
10.20.218.226 443 TCP
10.20.239.14 42422 TCP
10.20.192.10 53 TCP
0.0.0.0 4567 TCP
10.20.225.206 443 TCP
10.20.225.166 443 TCP
10.20.207.244 5473 TCP
10.20.202.47 44134 TCP
10.20.227.251 3306 TCP
0.0.0.0 9042 TCP
10.20.207.141 3306 TCP
0.0.0.0 15014 TCP
0.0.0.0 9090 TCP
0.0.0.0 9091 TCP
0.0.0.0 9901 TCP
0.0.0.0 15010 TCP
0.0.0.0 15004 TCP
0.0.0.0 8060 TCP
0.0.0.0 8080 TCP
0.0.0.0 20001 TCP
0.0.0.0 80 TCP
0.0.0.0 10589 TCP
10.20.128.44 15020 TCP
0.0.0.0 15001 TCP
0.0.0.0 9000 TCP
10.20.219.237 9090 TCP
10.20.233.60 80 TCP
10.20.200.156 9100 TCP
10.20.204.239 9093 TCP
0.0.0.0 10055 TCP
0.0.0.0 10054 TCP
0.0.0.0 10251 TCP
0.0.0.0 10252 TCP
0.0.0.0 9093 TCP
0.0.0.0 6783 TCP
0.0.0.0 10250 TCP
10.20.217.136 443 TCP
0.0.0.0 15090 HTTP
以json格式转储群集: https://pastebin.com/73zmAPWg
以json格式转储侦听器: https://pastebin.com/Pk7ddPJ2
从serviceA容器向serviceB的卷曲命令:
/opt/app # curl -X POST -v "http://serviceB.api.svc.cluster.local:4567/session/xxxxxxxx=?parameters=hi"
* Trying 10.20.228.217...
* TCP_NODELAY set
* Connected to serviceB.api.svc.cluster.local (10.20.228.217) port 4567 (#0)
> POST /session/xxxxxxxx=?parameters=hi HTTP/1.1
> Host: serviceB.api.svc.cluster.local:4567
> User-Agent: curl/7.61.1
> Accept: */*
>
* Empty reply from server
* Connection #0 to host serviceB.api.svc.cluster.local left intact
curl: (52) Empty reply from server
如果我禁用了mTLS,则请求会通过Curl从serviceA发送到serviceB
If I disable mTLS, request gets from serviceA to serviceB with Curl
推荐答案
调试Istio服务网格的一般技巧:
General tips for debugging Istio service mesh:
- 检查服务和吊舱的要求.
- 尝试从 Istio任务列表中尝试执行的任务.查看该任务是否有效,并找出与您的任务不同的地方.
- 按照 Istio故障排除部分中的说明进行操作.
- Check the requirements for services and pods.
- Try a similar task to what you are trying to perform from the list of Istio tasks. See if that task works and find the differences with your task.
- Follow the instructions in Istio troubleshooting section.
这篇关于Istio mTLS仅在某些服务之间工作,即使tls-check打印每个人的状态都可以的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!