[英]how to know external endpoints or the ip of Loadbalancer Service inside a pod
[英]GKE - Bypass Pod LoadBalancer (Pod's external IP) to Pod's container's IP at runtime for WebSocket purpose
我有以下情况:
我有几个微服务,现在只有 2 个是相关的。 - 网络套接字服务 API - 调度服务
我们有 3 个用户,分别称为 1、2 和 3。这些用户将自己连接到后端的 Web 套接字端点。 我们的微服务在 Kubernetes 上运行,每个服务都可以在 Pod 内多次复制。 对于这种情况,我们有 1 个用于调度程序的运行容器,以及 3 个用于 Web 套接字 api 的运行容器。 每个 pod 都有它的负载均衡器,这将是每次的入口点。
在我们的情况下,我们将拥有以下“架构”:
现在我们有了系统的表示(和图例),我们的 3 个用户将想要使用该应用程序并进行连接。
如我们所见,Pod 的负载均衡器将用户的 Web 套接字连接转发到不同的容器。 每个容器,一旦获得新连接,就会通知 Dispatcher Service,而这个容器会将其保存在自己的数据库中。
现在,3 个用户连接到 2 个不同的容器,并且 Dispatcher 服务知道这一点。
用户 1 想给用户 2 发送消息。容器 A 将收到一条消息并告诉调度服务: Please, send this to the user 2
。
由于调度程序知道用户 2 连接到哪个容器,我想直接向我的容器发送请求,而不是将其发送到 Pod。 将它发送到 Pod 会导致向负载均衡器发送请求,负载均衡器实际上将请求分派到最可用的容器实例......
我怎样才能设法获得容器 IP? 另一个容器可以从另一个 Pod 访问它吗?
对我来说,最好的方法是,一旦应用程序启动,它就会获取当前容器的 IP,然后在注册请求中将其发送给调度员,这样调度员就会知道 ContainerID=IP
谢谢!
有我的web-socket-service-api.yaml
apiVersion: v1
kind: Service
metadata:
name: web-socket-service-api
spec:
ports:
# Port that accepts gRPC and JSON/HTTP2 requests over HTTP.
- port: 8080
targetPort: 8080
protocol: TCP
name: grpc
# Port that accepts gRPC and JSON/HTTP2 requests over HTTP.
- port: 8081
targetPort: 8081
protocol: TCP
name: rest
# Port that accepts WebSockets.
- port: 8082
targetPort: 8082
protocol: TCP
name: websocket
selector:
app: web-socket-service-api
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: web-socket-service-api
spec:
replicas: 3
template:
metadata:
labels:
app: web-socket-service-api
spec:
containers:
- name: web-socket-service-api
image: gcr.io/[PROJECT]/web-socket-service-api:latest
ports:
- containerPort: 8080
- containerPort: 8081
- containerPort: 8082
就我对您的设计的理解而言,您的Dispatcher本质上是您的Websocket Service Pod 的消息代理。 让所有 Websocket pod 连接到代理并让代理路由消息。 这是一项有状态服务,您应该在 Kubernetes 中为此使用StatefulSet 。 根据您的要求,可能的解决方案是为此使用 MQTT 代理,例如mosquitto 。 大多数 MQTT 代理都支持 websocket。
每个服务都可以在 Pod 中多次复制。 对于这种情况,我们有 1 个用于调度程序的运行容器,以及 3 个用于 Web 套接字 api 的运行容器。
这不是 Kubernetes 的使用方式。 使用 pod 的多个副本,而不是 pod 中的多个容器。 我建议您为您的Websocket 服务创建一个具有您想要的多个副本的部署。
每个 pod 都有它的负载均衡器,这将是每次的入口点。
在Kubernetes你应该创建一个服务是负载均衡流量一套吊舱。
您的解决方案
对我来说,最好的方法是,一旦应用程序启动,它就会获取当前容器的 IP,然后在注册请求中将其发送给调度员,这样调度员就会知道 ContainerID=IP
是的,我基本同意。 这与我在这里描述的相似。 但我会让Websocket 服务建立到Broker/Dispatcher的连接。
任何 pod,都有一些关于它自己的信息。 其中一项信息是它自己的 IP 地址。 举个例子:
apiVersion: v1
kind: Pod
metadata:
name: envars-fieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_POD_IP;
sleep 10;
done;
env:
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
在容器内,MY_POD_IP 将包含 pod 的 IP 地址。 你可以让调度员知道。
$ kubectl logs envars-fieldref
10.52.0.3
$ kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
envars-fieldref 1/1 Running 0 31s 10.52.0.3 gke-klusta-lemmy-3ce02acd-djhm <none> <none>
请注意,依赖 pod IP 地址不是一个好主意。 但这应该可以解决问题。
此外,向 pod 或容器发送请求也是一回事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.