StatefulSet with nodeAffinity

Hi, folks!

Is it possible for pods from a StatefulSet to be scheduled on specific nodes, such as: two pods on node-01, two pods on node-02 and one pod on node-03?

The goal is to setup an Elasticsearch cluster persisting the data directly on the hosts, so the ES data nodes need to have a direct relationship with the PVCs of a specific node.

Thanks in advance. :muscle:

1 Like

Make sure you have the labels.

kubectl label nodes node-01 node=node-01
kubectl label nodes node-02 node=node-02
kubectl label nodes node-03 node=node-03

After that use nodeAffinity to schedule workload on specific node

For node-01 with 2 replicas:

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch-node-01
spec:
  serviceName: "elasticsearch-service-node-01"
  replicas: 2
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: node
                    operator: In
                    values:
                      - node-01
      containers:
      - name: elasticsearch-container
        image: elasticsearch:latest
  volumeClaimTemplates:
  - metadata:
      name: elasticsearch-volume
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "standard"
      resources:
        requests:
          storage: 1Gi
EOF

For node-02 with 2 replicas:

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch-node-02
spec:
  serviceName: "elasticsearch-service-node-02"
  replicas: 2
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: node
                    operator: In
                    values:
                      - node-02
      containers:
      - name: elasticsearch-container
        image: elasticsearch:latest
  volumeClaimTemplates:
  - metadata:
      name: elasticsearch-volume
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "standard"
      resources:
        requests:
          storage: 1Gi
EOF

For node-03 with 1 replica:

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch-node-03
spec:
  serviceName: "elasticsearch-service-node-03"
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: node
                    operator: In
                    values:
                      - node-03
      containers:
      - name: elasticsearch-container
        image: elasticsearch:latest
  volumeClaimTemplates:
  - metadata:
      name: elasticsearch-volume
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "standard"
      resources:
        requests:
          storage: 1Gi
EOF
1 Like