Kubernetes 上的 EventStore:连接被拒绝
EventStore on Kubernetes: Connection refused
我正在 .NET 5.0 中开发开源云事件网关,由 EventStore 通道支持,但在连接 ProjectionsManager 服务时遇到问题。
我在它自己的命名空间中部署了一个 EventStore 服务,并且可以成功连接到它并订阅流。但是,当我尝试连接 ProjectionsManager 时,出现以下异常:
连接被拒绝 (eventstore.eventstore.svc.cluster.local:2113)
服务的完全限定名称 'eventstore.eventstore.svc.cluster.local' 是正确的,并且已被 IEventStoreConnection 成功使用。端口 2113 也是正确的,因为我可以通过使用 Kubectl 将端口转发到该端口上的我的 pod 来访问 Admin 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# 片段:
new ProjectionsManager(new ConsoleLogger(), new DnsEndPoint("eventstore.eventstore.svc.cluster.local", 2113), TimeSpan.FromMilliseconds(3000), httpSchema: "http");
顺便说一句,尝试连接 ProjectionsManager 的服务与 Istio sidecar 耦合,如果这很重要的话。
在此先感谢您的宝贵帮助 ;)
编辑
Istio sidecar 注入似乎是问题的原因。禁用它会使其按预期工作。知道为什么会发生这种情况以及如何通过启用注入来解决它吗?
我们在启用了 Istio sidecar 注入的 Kubernetes 集群上遇到了同样的问题 运行 EventStoreDB。
根据 Istio's documentation on protocol selection,Istio 将查看您在 Service
上定义的 port
的名称,这将决定 Istio 试图拦截哪个协议。如果不遵守格式,Istio 将尝试猜测协议(适用于 HTTP、HTTPS 和 gRPC)。
在您的情况下,您的端口 name
以 http-
开头(http-int
和 http-ext
)。因此,Istio 不会尝试检测所使用的协议,而是假定协议为 http
(HTTP/1.1).
但是,EventStoreDB 的 API 是一个 gRPC 端点。因此,您有两个选择:
- 重命名端口以
grpc-
开头。在那种情况下,任何 Istio 代理都会知道这个端口正在暴露 gRPC
- 直接将端口命名为其他名称(例如
api
或 eventstoredb
),让 Istio 检测使用的协议。
请注意,EventStoreDB 在同一端口(即 HTTP)上公开了一个管理 Web 界面。如果您通过端口转发访问它,那么您没有 Istio sidecar,因此端口名称不会影响流量。但是,如果您尝试通过 Istio Ingress Gateway 公开管理界面(我不推荐这样做,因为您会将数据库公开到 Internet),那么您在访问管理界面时可能会遇到问题。那么,第二种让 Istio 检测流量的方案可能是更灵活的方案。
最后一个选择是在 Service
上公开 2 个端口,一个用于 http
,另一个用于 grpc
,并让它们都重定向到 Service
上的同一个端口Pod
,但实际上我不确定 Kubernetes 是否允许这样做。
我正在 .NET 5.0 中开发开源云事件网关,由 EventStore 通道支持,但在连接 ProjectionsManager 服务时遇到问题。
我在它自己的命名空间中部署了一个 EventStore 服务,并且可以成功连接到它并订阅流。但是,当我尝试连接 ProjectionsManager 时,出现以下异常:
连接被拒绝 (eventstore.eventstore.svc.cluster.local:2113)
服务的完全限定名称 'eventstore.eventstore.svc.cluster.local' 是正确的,并且已被 IEventStoreConnection 成功使用。端口 2113 也是正确的,因为我可以通过使用 Kubectl 将端口转发到该端口上的我的 pod 来访问 Admin 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# 片段:
new ProjectionsManager(new ConsoleLogger(), new DnsEndPoint("eventstore.eventstore.svc.cluster.local", 2113), TimeSpan.FromMilliseconds(3000), httpSchema: "http");
顺便说一句,尝试连接 ProjectionsManager 的服务与 Istio sidecar 耦合,如果这很重要的话。
在此先感谢您的宝贵帮助 ;)
编辑
Istio sidecar 注入似乎是问题的原因。禁用它会使其按预期工作。知道为什么会发生这种情况以及如何通过启用注入来解决它吗?
我们在启用了 Istio sidecar 注入的 Kubernetes 集群上遇到了同样的问题 运行 EventStoreDB。
根据 Istio's documentation on protocol selection,Istio 将查看您在 Service
上定义的 port
的名称,这将决定 Istio 试图拦截哪个协议。如果不遵守格式,Istio 将尝试猜测协议(适用于 HTTP、HTTPS 和 gRPC)。
在您的情况下,您的端口 name
以 http-
开头(http-int
和 http-ext
)。因此,Istio 不会尝试检测所使用的协议,而是假定协议为 http
(HTTP/1.1).
但是,EventStoreDB 的 API 是一个 gRPC 端点。因此,您有两个选择:
- 重命名端口以
grpc-
开头。在那种情况下,任何 Istio 代理都会知道这个端口正在暴露 gRPC - 直接将端口命名为其他名称(例如
api
或eventstoredb
),让 Istio 检测使用的协议。
请注意,EventStoreDB 在同一端口(即 HTTP)上公开了一个管理 Web 界面。如果您通过端口转发访问它,那么您没有 Istio sidecar,因此端口名称不会影响流量。但是,如果您尝试通过 Istio Ingress Gateway 公开管理界面(我不推荐这样做,因为您会将数据库公开到 Internet),那么您在访问管理界面时可能会遇到问题。那么,第二种让 Istio 检测流量的方案可能是更灵活的方案。
最后一个选择是在 Service
上公开 2 个端口,一个用于 http
,另一个用于 grpc
,并让它们都重定向到 Service
上的同一个端口Pod
,但实际上我不确定 Kubernetes 是否允许这样做。