skip to Main Content

I have a StatefulSet with 3 pods. The first is assigned to the master role, the rest have a read replica role.

redis-0 (master)
redis-1 (replica)
redis-2 (replica)

How can I create a Kubernetes Service that matches only the pods redis-1 and redis-2? Basically I want to service that points only to the pods acting as replicas?

Logically what I want is to select every pod in the STS except the first. In pseudocode:

selector: app=redis-sts && statefulset.kubernetes.io/pod-name!=redis-0

Alternatively, selecting all the relevant pods could be viable. Again in psuedocode:

selector: statefulset.kubernetes.io/pod-name=redis-1 || statefulset.kubernetes.io/pod-name=redis-2

Here is the relevant YAML with the selectors & service defined. Full YAML.

apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  ports:
  - port: 6379
  clusterIP: None
  selector:
    app: redis-sts
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis-sts
  serviceName: redis-service
  replicas: 3
  template:
    metadata:
      labels:
        app: redis-sts
    spec:
# ...

3

Answers


  1. You may use pod name labels of your redis statefulset to create the service to access a particular read replica pod.

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-1
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local
      selector:
        statefulset.kubernetes.io/pod-name: redis-1
      ports:
      - protocol: TCP
        port: 6379
        targetPort: 6379
    

    And then use the service name for the pod to access the specific pods.

    externalTrafficPolicy: Local will only proxy the traffic to the node that has the instance of your pod.

    Login or Signup to reply.
  2. The Service v1 API in 1.21 doesn’t support the newer "set" based LabelSelector (matchLabels or matchExpressions)

    You could write a controller to apply labels to the stateful set that can then meet the simple equality logic for Service selectors. There may be Redis operators that do this type of thing already.

    An idea from this stateful set label question is to use an initContainer that has the pod write access to add the label.

    Login or Signup to reply.
  3. i would suggest to not be depends on the Kubernetes service as if your master pod got killer or restarted read replica can get change anytime in redis cluster.

    https://github.com/harsh4870/Redis-Rejson-HA-Helm-Chart

    here is the helm chart which deploys the Redis the same way one master and two read replica but with sentinel.

    Your node or python code has to hit the service of Redis and in return redis sentinel will give you all the IP addresses for Mater and slave replicas.

    Using that IP you can always connect to the Read replica and Master as per need.

    If your cluster gets restarted or POD restarted master read replicas may get changed with time.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search