【问题标题】:EventStore on Kubernetes: Connection refusedKubernetes 上的 EventStore:连接被拒绝
【发布时间】:2020-11-25 15:01:39
【问题描述】:

我正在 .NET 5.0 中开发一个由 EventStore 通道支持的开源云事件网关,但在连接 ProjectionsManager 服务时遇到了问题。

我在自己的命名空间中部署了一个 EventStore 服务,并且可以成功连接到它,并订阅流。但是,当我尝试连接 ProjectionsManager 时,出现以下异常:

连接被拒绝(eventstore.eventstore.svc.cluster.local:2113)

服务的完全限定名称“eventstore.eventstore.svc.cluster.local”是正确的,并且已被 IEventStoreConnection 成功使用。端口 2113 也是正确的,因为我可以通过使用 Kubectl 将端口转发到该端口上的 pod 来访问管理 UI。

发生了什么事?在我所有的本地和基于 docker-compose 的测试中,一切都按预期工作。只有在 Kubernetes 中我才会遇到这个问题。

这是我的 EventStore yaml 文件的内容:

apiVersion: v1
kind: Namespace
metadata:
  name: eventstore
  labels:
    name: eventstore

---

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: eventstore
  namespace: eventstore
  labels:
    app: eventstore
spec:
  serviceName: eventstore
  replicas: 1
  selector:
    matchLabels:
      app: eventstore
  template:
    metadata:
      labels:
        app: eventstore
    spec:
      containers:
        - name: eventstore
          image: eventstore/eventstore:release-5.0.1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 1112
              name: tcp-int
            - containerPort: 1113
              name: tcp-ext
            - containerPort: 2112
              name: http-int  
            - containerPort: 2113
              name: http-ext  
          volumeMounts:
            - name: data
              mountPath: /var/lib/eventstore
          env:
            - name: EVENTSTORE_EXT_HTTP_PORT
              value: "2113"
            - name: EVENTSTORE_EXT_TCP_PORT
              value: "1113"
            - name: EVENTSTORE_INT_HTTP_PREFIXES
              value: http://*:2112/
            - name: EVENTSTORE_EXT_HTTP_PREFIXES
              value: http://*:2113/
            - name: EVENTSTORE_RUN_PROJECTIONS
              value: All
            - name: EVENTSTORE_START_STANDARD_PROJECTIONS
              value: "true"
            - name: EVENTSTORE_EXT_IP
              value: "0.0.0.0"
            - name: EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP
              value: "true"
            - name: EVENTSTORE_ENABLE_EXTERNAL_TCP
              value: "true"
      volumes:
        - name: data
          emptyDir: {}

---

apiVersion: v1
kind: Service
metadata:
  name: eventstore
  namespace: eventstore
  labels:
    app: eventstore
spec:
  ports:
    - port: 1112
      name: tcp-int
    - port: 1113
      name: tcp-ext
    - port: 2112
      name: http-int  
    - port: 2113
      name: http-ext  
  selector:
    app: eventstore

这是用于实例化 ProjectionsManager 的 C# sn-p:

new ProjectionsManager(new ConsoleLogger(), new DnsEndPoint("eventstore.eventstore.svc.cluster.local", 2113), TimeSpan.FromMilliseconds(3000), httpSchema: "http");

顺便说一句,尝试连接 ProjectionsManager 的服务与 Istio sidecar 耦合,如果这很重要的话。

提前感谢您的宝贵帮助;)

编辑

似乎 Istio sidecar 注入是问题的原因。禁用它可以使其按预期工作。关于为什么会发生这种情况以及如何在启用注入的情况下解决它的任何想法?

【问题讨论】:

  • 1.你的 istio 版本是多少? 2.如果你禁用了istio sidecar,你能检查它是否会工作吗?如果你启用了strict mtls,那么注入了 istio sidecar 的 pod 将无法与没有 istio sidecar 的 pod 通信。
  • 1.我的 Istio 版本是 1.7.3。 Kubernetes 是 1.19.3。 2. 如果我禁用 sidecar 注入,一切都会按预期进行。 3. 未启用严格的 MTLS,一切都处于许可模式。关于如何使其在启用 sidecar 注入的情况下工作的任何想法?
  • 您能否尝试为其添加destination rule,这将禁用此特定主机/命名空间的mtls?有一个example
  • 我创建了两个 DestinationRules,一个在 eventstore 命名空间中,一个在我的事件命名空间中,以确保它在两个命名空间中都应用。然而,它仍然不起作用。这是粘贴箱:pastebin.pl/view/6f6219b5
  • 顺便说一句,如果没有这些目标规则,我在 Kiali 中看到 MTLS 无论如何都没有被强制执行。您不认为我的问题与 EventStore 不接受我的 sidecar 转发的请求有关吗?

标签: kubernetes istio .net-5 eventstoredb


【解决方案1】:

我们在启用 Istio sidecar 注入的 Kubernetes 集群上运行 EventStoreDB 时遇到了同样的问题。

根据Istio's documentation on protocol selection,Istio 将查看您在Service 上定义的port 的名称,这将决定 Istio 试图拦截的协议。如果不遵守格式,Istio 将尝试猜测协议(适用于 HTTP、HTTPS 和 gRPC)。

在您的情况下,您的端口的namehttp- 开头(http-inthttp-ext)。因此,Istio 不会尝试检测所使用的协议,而是会假定协议是http (HTTP/1.1)。

不过,EventStoreDB 的 API 是一个 gRPC 端点。因此,您有两种选择:

  • 将端口重命名为以grpc- 开头。在这种情况下,任何 Istio 代理都会知道该端口正在暴露 gRPC
  • 直接将端口命名为其他名称(例如 apieventstoredb),以让 Istio 检测使用的协议。

请注意,EventStoreDB 在同一端口(即 HTTP)上公开了一个管理 Web 界面。如果您通过端口转发访问它,那么您没有 Istio sidecar 阻碍,因此端口的名称不会影响流量。但是,如果您尝试通过 Istio Ingress Gateway 公开管理界面(我不建议这样做,因为您会将数据库公开到 Internet),那么您可能会在访问管理界面时遇到问题。在这种情况下,让 Istio 检测流量的第二种解决方案可能是更灵活的解决方案。

最后一个选项是在Service 上公开两个端口,一个用于http,另一个用于grpc,并让它们都重定向到Pod 上的同一个端口,但我实际上不确定 Kubernetes 是否允许这样做。

【讨论】:

  • 你做主,非常感谢!立即测试它,它就像一个魅力!非常感谢!
猜你喜欢
  • 2018-03-14
  • 2020-11-06
  • 1970-01-01
  • 2021-10-22
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 2021-09-13
相关资源
最近更新 更多