我在Windows的"Docker Desktop"上运行Kubernetes。
我有一个用于具有 3 个副本的部署的负载均衡器服务。 我想通过一些方式访问特定的pod(例如通过URL路径:<服务IP>:8090/pod1(。服务IP>
有没有办法实现这个用例?
部署.yaml :
apiVersion: v1 kind: Service metadata: name: my-service1 labels: app: stream spec: ports: - port: 8090 targetPort: 8090 name: port8090 selector: app: stream # clusterIP: None type: LoadBalancer --- apiVersion: apps/v1beta2 kind: Deployment metadata: name: stream-deployment labels: app: stream spec: replicas: 3 selector: matchLabels: app: stream strategy: type: Recreate template: metadata: labels: app: stream spec: containers: - image: stream-server-mock:latest name: stream-server-mock imagePullPolicy: Never env: - name: STREAMER_IP valueFrom: fieldRef: fieldPath: status.podIP - name: STREAMER_ADDRESS value: stream-server-mock:8090 ports: - containerPort: 8090
我的最终目标是实现 Pod 的水平自动缩放。
到目前为止,应用程序如何设计/和工作(没有 kubernetes(:
有3个组件:REST服务器,流服务器(3个实例( 在不同端口上的不同 JVM 上本地(,和 RabbitMQ。
1 - The client sends a request to "REST-Server" for a stream url.
2 - The REST-Server puts in the RabbitMQ queue.
3 - One of the Stream-Server picks it up and populates its IP and sends back to REST-Server through RabbitMQ.
4 - The client receives the IP and establishes a direct WS connection using the IP.
我面临的问题是:
1 - When the client requests for a stream IP, one of the pods (lets say POD1) picks it up and sends its URL (which is service URL, comes through LoadBalancer Service).
2 - Next time when the client tries to connect (WebSocket Connection) using the Service IP, it wont be the same pod which accepted the request.
它应该是接受请求的同一 pod,并且必须可由客户端访问。
如果不需要使用部署,则可以使用 StatefulSets。
对于副本 3,您将有 3 个名为
- 流部署-0
- 流部署-1
- 流部署-2
您可以按$(podname).$(service name).$(namespace).svc.cluster.local
访问每个容器
有关详细信息,请查看此
您可能还希望设置入口以从集群外部指向每个 Pod。
正如aerokite提到的,你可以使用StatefulSets。但是,如果您不想修改部署,则只需使用无外设服务即可。如文档中指定:
对于无外设服务,不会分配群集 IP。
对于定义选择器的无外设服务,终结点控制器 在 API 中创建终结点记录,并修改 DNS 配置以返回直接指向 支持服务的 Pod。
这意味着,每当您查询服务的DNS名称(即my-svc.my-namespace.svc.cluster-domain.example(时,您得到的都是所有Pod IP的列表(与获取集群IP的常规服务不同(。然后,您可以使用自己的机制选择 Pod。
关于您的新问题,如果这是您唯一的问题,您可以使用会话相关性。如果将service.spec.sessionAffinity
设置为ClientIP
,则来自特定客户端的连接每次将始终转到同一个 Pod。您不需要其他修改,例如上面提到的无头服务。
IMO,实现这一目标的唯一方法是:
- 不要使用具有 3 个副本的部署,而是使用 3 个部署,每个部署包含 1 个副本(或仅创建 Pod(;部署 1 -> pod1,部署 2 -> pod2,部署 3 -> pod3
- 在单独的服务上公开所有部署,服务1 ->部署1,服务2 ->部署2,服务3 ->部署3
- 为每个部署创建入口资源并使用服务路由到每个容器。例如:
- 入口网址/服务1
- 入口网址/服务2
- 入口网址/服务3