如何通过Kubernetes服务(如网关API)路由到特定的Pod

时间:2019-09-19 08:43:20

标签: kubernetes kubernetes-ingress kubernetes-pod

我正在Windows的“ Docker桌面”上运行Kubernetes。

对于具有3个副本的部署,我有一个LoadBalancer服务。 我想通过(例如通过URL路径::8090 / pod1)来访问SPECIFIC pod。

有什么办法可以实现这个用例?


deployment.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

我的最终目标是实现吊舱的水平自动缩放。

应用程序到目前为止的设计/工作方式(无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,并且必须可由客户端访问。

3 个答案:

答案 0 :(得分:3)

如果不需要使用部署,则可以使用StatefulSets

对于副本3,您将有3个名为的吊舱

  1. stream-deployment-0
  2. stream-deployment-1
  3. stream-deployment-2

您可以以root

的身份访问每个窗格

有关详细信息,请检查this

您可能还需要设置一个入口,以从群集外部指向每个吊舱。

答案 1 :(得分:1)

如aerokite所述,您可以使用StatefulSets。但是,如果您不想修改您的部署,则只需使用Headless Services。如文档中所指定:

  

对于无头服务,未分配群集IP。

     

对于定义选择器的无头服务,端点控制器   在API中创建端点记录,并修改DNS   返回直接指向记录的记录(地址)的配置   支持该服务的Pod。

这意味着每当您查询服务的DNS名称(即my-svc.my-namespace.svc.cluster-domain.example)时,所获得的都是所有Pod IP的列表(不同于常规服务,其中您将获得群集IP)。然后,您可以使用自己的机制选择Pod。

关于您的新问题,如果这是唯一的问题,则可以使用会话关联。如果将service.spec.sessionAffinity设置为ClientIP,则来自特定客户端的连接将始终每次都转到同一Pod。您不需要进行其他修改,例如上面提到的无头服务。

答案 2 :(得分:0)

IMO,实现此目标的唯一方法是:

  1. 不要使用具有3个副本的部署,而应使用具有1个副本的3个部署(或仅创建pod);部署1->部署1,部署2->部署2,部署3->部署3
  2. 将所有部署暴露在单独的服务上,服务1->部署1,服务2->部署2,服务3->部署3
  3. 使用每个部署的服务创建一个入口资源并路由到每个Pod。例如:
    • ingress-url / service1
    • ingress-url / service2
    • ingress-url / service3