问题描述
我是 Istio 的新手,因此这可能是一个简单的问题,但我对 Istio 有一些困惑。我使用 Istio 1.8.0 和 1.19 来处理 k8s。对于多个问题,如果您能帮助我,我将不胜感激阐明最佳方法。
-
在我注入 Istio 之后,我想我无法直接在 pod 内访问服务到服务,但正如您在下面看到的那样,我可以。也许我误解了,但这是预期的行为吗?同时,我如何调试服务是否通过使用 mTLS 的 envoy 代理相互通信?我正在使用
STRICT
模式,我是否应该在运行微服务的命名空间中部署对等身份验证以避免这种情况?kubectl get peerauthentication --all-namespaces NAMESPACE NAME AGE istio-system default 26h
-
如何限制流量,让 api-dev 服务不能访问 auth-dev,但可以访问 backend-dev?
-
某些微服务需要与数据库通信,而数据库也在
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 $
解决方法
- 根据 documentation,如果您使用
STRICT
mtls,则工作负载应仅接受加密流量。
对等身份验证
对等身份验证策略指定 Istio 对目标工作负载强制执行的双向 TLS 模式。支持以下模式:
- 允许:工作负载接受双向 TLS 和纯文本流量。 这种模式在迁移过程中最有用,当工作负载没有 sidecar 不能使用双向 TLS。一旦工作负载迁移 Sidecar 注入,您应该将模式切换为 STRICT。
- 严格:工作负载只接受双向 TLS 流量。
- DISABLE:双向 TLS 已禁用。从安全角度来说,你 除非您提供自己的安全性,否则不应使用此模式 解决方案。
模式未设置时,继承父作用域的模式。具有未设置模式的全网对等身份验证策略默认使用 PERMISSIVE 模式。
也值得一看here,因为 banzaicloud 在此处对其进行了很好的描述。
您可以启用严格的 mtls 模式 globally,但也可以启用特定的 namespace 或 workload。
- 您可以使用 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"]
- 您可以在不注入的情况下设置数据库,然后使用 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 依赖项的问题,例如错误的虚拟服务配置。