Istio mTLS仅在某些服务之间工作,即使tls-check打印每个人的状态都可以 [英] Istio mTLS working just between some services even though tls-check prints STATUS OK for everyone

查看:71
本文介绍了Istio mTLS仅在某些服务之间工作,即使tls-check打印每个人的状态都可以的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在已经使用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:

  1. 检查服务和吊舱的要求.
  2. 尝试从 Istio任务列表中尝试执行的任务.查看该任务是否有效,并找出与您的任务不同的地方.
  3. 按照 Istio故障排除部分中的说明进行操作.
  1. Check the requirements for services and pods.
  2. 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.
  3. Follow the instructions in Istio troubleshooting section.

这篇关于Istio mTLS仅在某些服务之间工作,即使tls-check打印每个人的状态都可以的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆