How to Route to specific pod through Kubernetes Service (like a Gateway API)

限于喜欢 提交于 2019-12-09 00:57:21

问题


I am running Kubernetes on "Docker Desktop" in Windows.

I have a LoadBalancer Service for a deployment which has 3 replicas. I would like to access SPECIFIC pod through some means (such as via URL path : < serviceIP >:8090/pod1).

Is there any way to achieve this usecase?


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

My end goal is to achieve horizontal auto-scaling of pods.

How Application designed/and works as of now (without kubernetes) :

There are 3 components : REST-Server, Stream-Server (3 instances locally on different JVM on different ports), and 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.

The Problem what I face is :

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.

It should be the same pod which accepted the request, and must be accessible by the client.


回答1:


You can use StatefulSets if you are not required to use deployment.

For replica 3, you will have 3 pods named

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

You can access each pod as $(podname).$(service name).$(namespace).svc.cluster.local

For details, check this

You may also want to set up an ingress to point each pod from outside of the cluster.




回答2:


As mentioned by aerokite, you can use StatefulSets. However, if you don't want to modify your deployments, you can simply use Headless Services. As specified in the documentation:

For headless Services, a cluster IP is not allocated.

For headless Services that define selectors, the endpoints controller creates Endpoints records in the API, and modifies the DNS configuration to return records (addresses) that point directly to the Pods backing the Service.

This means that whenever you query the DNS name for your Service (i.e. my-svc.my-namespace.svc.cluster-domain.example), what you get is a list of all the Pod IPs (unlike regular services where you get the cluster IP). You can then select your Pods using your own mechanisms.

Regarding your new question, if that is your only issue, you can use session affinity. If you set service.spec.sessionAffinity to ClientIP, then connections from a particular client will always go to the same Pod each time. You don't need other modifications like the headless Services mentioned above.




回答3:


IMO, the only way to achieve this will be:

  1. Instead of using a deployment with 3 replicas, use 3 deployments with 1 replicas each (or just create pods only); deployment1 -> pod1, deployment2 -> pod2, deployment3 -> pod3
  2. Expose all the deployments on a separate service, service1 -> deployment1, service2 -> deployment2, service3 -> deployment3
  3. Create an ingress resource and route to each pod using the service for each deployment. For example:
    • ingress-url/service1
    • ingress-url/service2
    • ingress-url/service3


来源:https://stackoverflow.com/questions/58007073/how-to-route-to-specific-pod-through-kubernetes-service-like-a-gateway-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!