Question

DOKS - How to Create A Pod in a node where PV (do-block-storage) is mounted

DO Block storage only can mount into a single Node (VM). So, when I provision PV/PVC it creates a block storage.

I am implementing helm chart bitnami/mysql where I want to create the mysql pod only into the node the PVC is mounted.

How should I go about it? I have tried with Affinity but I have some issues with it as I can not label nodes. Here is my configuration values.yml file


global:
  storageClass: do-block-storage
architecture: standalone
primary:
  name: primary
  persistence:
    enabled: true
    existingClaim: backend-mysql-primary
    accessModes:
      - ReadWriteOnce
    size: 10Gi
    selector: {}
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - topologyKey: topology.kubernetes.io/region
          namespaces:
            - sportsdemy
          labelSelector:
            matchExpressions:
              - key: pvc
                operator: In
                values:
                  - backend-mysql-primary
   

This config throws the following error:

error validating "": error validating data: ValidationError(StatefulSet.spec.template.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[0]): missing required field "topologyKey" in io.k8s.api.core.v1.PodAffinityTerm

So it looks like a topologyKey is required but I am not sure how it is helpful here.

But I went ahead and tried to add the topologyKey from labels assigned to the node by DOKS. topology.kubernetes.io/region

Deployment is applying without issues but pod is assigned to any node:

0/2 nodes are available: 2 node(s) didn't match pod affinity rules. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
pod didn't trigger scale-up: 1 node(s) didn't match pod affinity rules

Here is the yml file for volumes:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: backend-mysql-primary
  namespace: sportsdemy
  labels:
    pvc: backend-mysql-primary

spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: do-block-storage

Goal: I have labeled my pv as pvc: backend-mysql-primary and want to a node where I have the PV.


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Bobby Iliev
Site Moderator
Site Moderator badge
May 12, 2023

Hi there,

The issue here is that Kubernetes is trying to schedule your Pod based on the affinity rules, but it can’t find any nodes that match the criteria. In your case, you’re trying to schedule the Pod on the node where the Persistent Volume Claim (PVC) is bound, but this is not directly possible with affinity rules because these rules operate based on labels on the nodes or other pods, not based on PVCs.

However, you can achieve something similar by using a workaround:

  1. First, create the PV and PVC and let it bind to a node. This node will be the one that the PV is attached to.
  2. Label the node where the PV is attached with a unique label. You can do this manually or automate it with a script. For example, you could label it with something like pvc: backend-mysql-primary. You can find the node where the PV is attached by describing the PV and looking for the NodeAffinity field.
  3. In your Helm chart, use a nodeAffinity rule in the Pod spec to schedule the Pod on the node with the label from step 2. Here’s an example of what the affinity part of your values file might look like:
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: pvc
          operator: In
          values:
          - backend-mysql-primary

Please note that this will only work if the PVC is already bound to the PV and the node has been labeled before you deploy the Helm chart. If you’re dynamically provisioning the PVC along with the Helm chart, you would need to ensure that the PVC is created and bound, and the node is labeled, before the Pod is scheduled.

Also, be aware that if the node goes down, the Pod won’t be able to be scheduled on another node, because the PV can only be attached to the node it was initially bound to.

You might want to consider using a Managed MySQL database cluster for a worry-free setup:

https://www.digitalocean.com/products/managed-databases-mysql

Best,

Bobby

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up