如何在 kubernetes 中调试与 istio 的 mTLS 通信?

问题描述

我是 Istio 的新手,因此这可能是一个简单的问题,但我对 Istio 有一些困惑。我使用 Istio 1.8.0 和 1.19 来处理 k8s。对于多个问题,如果您能帮助我,我将不胜感激阐明最佳方法

  1. 在我注入 Istio 之后,我想我无法直接在 pod 内访问服务到服务,但正如您在下面看到的那样,我可以。也许我误解了,但这是预期的行为吗?同时,我如何调试服务是否通过使用 mTLS 的 envoy 代理相互通信?我正在使用 STRICT 模式,我是否应该在运行微服务的命名空间中部署对等身份验证以避免这种情况?

     kubectl get peerauthentication --all-namespaces
     NAMESPACE      NAME      AGE
     istio-system   default   26h
    
  2. 如何限制流量,让 api-dev 服务不能访问 auth-dev,但可以访问 backend-dev?

  3. 某些微服务需要与数据库通信,而数据库也在 database 命名空间中运行。我们也有一些我们不想注入 istio 也使用相同的数据库?那么,数据库是否也应该部署在我们进行 istio 注入的同一个命名空间中?如果是,那么是否意味着我需要为其余服务部署另一个数据库实例?


    $ kubectl get ns --show-labels
    NAME              STATUS   AGE    LABELS
    database          Active   317d   name=database
    hub-dev           Active   15h    istio-injection=enabled
    dev               Active   318d   name=dev


    capel0068340585:~ semural$ kubectl get pods -n hub-dev
    NAME                                     READY   STATUS    RESTARTS   AGE
    api-dev-5b9cdfc55c-ltgqz                  3/3     Running   0          117m
    auth-dev-54bd586cc9-l8jdn                 3/3     Running   0          13h
    backend-dev-6b86994697-2cxst              2/2     Running   0          120m
    cronjob-dev-7c599bf944-cw8ql              3/3     Running   0          137m
    mp-dev-59cb8d5589-w5mxc                   3/3     Running   0          117m
    ui-dev-5884478c7b-q8lnm                   2/2     Running   0          114m
    redis-hub-master-0                        2/2     Running   0           2m57s
    
    $ kubectl get svc -n hub-dev
    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    api-dev                ClusterIP   xxxxxxxxxxxxx      <none>        80/TCP    13h
    auth-dev               ClusterIP   xxxxxxxxxxxxx      <none>        80/TCP    13h
    backend-dev            ClusterIP   xxxxxxxxxxxxx      <none>        80/TCP    14h
    cronjob-dev            ClusterIP   xxxxxxxxxxxxx      <none>        80/TCP    14h
    mp-dev                 ClusterIP   xxxxxxxxxxxxx      <none>        80/TCP    13h
    ui-dev                 ClusterIP   xxxxxxxxxxxxx      <none>        80/TCP    13h
    redis-hub-master       ClusterIP   xxxxxxxxxxxxx      <none>        6379/TCP  3m47s
    


----------


    $ kubectl exec -ti ui-dev-5884478c7b-q8lnm -n hub-dev sh
    Defaulting container name to oneapihub-ui.
    Use 'kubectl describe pod/ui-dev-5884478c7b-q8lnm -n hub-dev' to see all of the containers in this pod.
    /usr/src/app $ curl -vv  http://hub-backend-dev
    *   Trying 10.254.78.120:80...
    * TCP_NODELAY set
    * Connected to backend-dev (10.254.78.120) port 80 (#0)
    > GET / HTTP/1.1
    > Host: backend-dev
    > User-Agent: curl/7.67.0
    > Accept: */*
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 404 Not Found
    < content-security-policy: default-src 'self'

    <
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <Meta charset="utf-8">
    <title>Error</title>
    </head>
    <body>
    <pre>Cannot GET /</pre>
    </body>
    </html>
    * Connection #0 to host oneapihub-backend-dev left intact
    /usr/src/app $

解决方法

  1. 根据 documentation,如果您使用 STRICT mtls,则工作负载应仅接受加密流量。

对等身份验证

对等身份验证策略指定 Istio 对目标工作负载强制执行的双向 TLS 模式。支持以下模式:

  • 允许:工作负载接受双向 TLS 和纯文本流量。 这种模式在迁移过程中最有用,当工作负载没有 sidecar 不能使用双向 TLS。一旦工作负载迁移 Sidecar 注入,您应该将模式切换为 STRICT。
  • 严格:工作负载只接受双向 TLS 流量。
  • DISABLE:双向 TLS 已禁用。从安全角度来说,你 除非您提供自己的安全性,否则不应使用此模式 解决方案。

模式未设置时,继承父作用域的模式。具有未设置模式的全网对等身份验证策略默认使用 PERMISSIVE 模式。

也值得一看here,因为 banzaicloud 在此处对其进行了很好的描述。


您可以启用严格的 mtls 模式 globally,但也可以启用特定的 namespaceworkload


  1. 您可以使用 istio Authorization Policy 来做到这一点。

Istio 授权策略支持对网格中工作负载的访问控制。

有一个例子。

以下是将操作设置为“拒绝”以创建拒绝策略的另一个示例。它拒绝“dev”命名空间对“foo”命名空间中所有工作负载的“POST”方法的请求。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 action: DENY
 rules:
 - from:
   - source:
       namespaces: ["dev"]
   to:
   - operation:
       methods: ["POST"]

  1. 您可以在不注入的情况下设置数据库,然后使用 ServiceEntry 对象将其添加到 Istio 注册中心,以便它能够与其余的 istio 服务进行通信。

ServiceEntry 允许在 Istio 的内部服务注册表中添加额外的条目,以便网格中自动发现的服务可以访问/路由到这些手动指定的服务。服务条目描述服务的属性(DNS 名称、VIP、端口、协议、端点)。这些服务可能是网格外部的(例如,Web API)或不属于平台服务注册表的网格内部服务(例如,与 Kubernetes 中的服务通信的一组 VM)。此外,还可以使用workloadSelector 字段动态选择服务条目的端点。这些端点可以是使用 WorkloadEntry 对象或 Kubernetes pod 声明的 VM 工作负载。在单个服务下同时选择 Pod 和 VM 的能力允许将服务从 VM 迁移到 Kubernetes,而无需更改与服务关联的现有 DNS 名称。

istio 文档中有示例:


回答关于如何调试 mtls 通信的主要问题

最基本的测试是尝试从未注入的 pod 调用到注入的 pod,例如使用 curl。这有 istio documentation

您也可以使用 istioctl x describe,有关它的更多信息 here


不确定 curl -vv http://hub-backend-dev 有什么问题,但由于是 404,我怀疑这可能是您的 istio 依赖项的问题,例如错误的虚拟服务配置。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...