Hello everyone!
Currently, I have a Kubernetes Cluster with a pool containing 3 nodes. (The default option when creating a cluster).
A total cluster capacity of 150GB of disk and 6GB of memory.

I’ve installed kubectl on my machine and pushed an image to it… (A .net Core API with a mySql database).... The .NET Api is working, but right now it can’t connect to a mysql database yet, because I need to make it works… And here comes my questions:

1- I can replicate this .net API, but I obviously can’t create “copies” of the database, it must be one, being accessed by all .net copies. How can I achieve that? Do I need to create a “Volume” to this .mysql database?

2- I will need to store the uploaded files of my .net project (are basically images and .pdf, nothing else). Can I store them on this 150GB of disk in my pool, or do I need to create a separate volume to store these uploaded images and PDF?

Thank you in advance!

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.

×
4 answers

I can replicate this .net API, but I obviously can’t create “copies” of the database, it must be one, being accessed by all .net copies.

The arrangement you are probably looking for is for your multiple .net API instances to connect to the same database

How can I achieve that? Do I need to create a “Volume” to this .mysql database?

Normally in Kuberentes, you create a service that maps to your MySQL cluster. Then, in .net, you can use the service name as the hostname to connect to. Basically what happens is that hostname resolves to the IP address of your MySQL server.

There is one thing I’m not super familiar with in a MySQL setup. Normally, if you have three MySQL servers, one is the master and the other two are read-only duplicates. I’m not sure how to handle this scenario in Kubernetes.

I would recommend considering the following alternatives to running your own MySQL service in Kubernetes:

  • Let others manage the database for you: Either use Digital ocean’s database service, or Amazon’s RDS, or Azure’s similar service. This way, you don’t have to deal with making your database reliable, they do it for you.
  • Do you really need a relational database at all? MongoDB, Azure Table Storage, and Amazon DynamoDB are sufficient for many applications and much cheaper.
  • If you really want to run a database yourself, consider a more cloud-friendly database solutions, such as CockroachDB.

I will need to store the uploaded files of my .net project (are basically images and .pdf, nothing else). Can I store them on this 150GB of disk in my pool, or do I need to create a separate volume to store these uploaded images and PDF?

Mounted volumes don’t sound like a good solution for what you’re trying to do. The problem is that you can only mount a volume to one pod at a time, so you’d have to implement replicating data to all volumes when you have multiple instances of your .net app.

I recommend looking into object stores such as Digital Ocean’s “Spaces”, or Amazon S3 or Azure Blob Storage. All of these are great solutions if you need a large amount of “disk” space to be shared by your different service instances. They’re also cheaper than volumes.

Hello,

you need:

  • define secrets and use its as environment variables
  • a volume for your assets app
  • a volume for your ConfigMaps (optional)
  • deploy your app
  • deploy your mysql database

some ideas:

Secrets

kubectl create secret generic mysql-database --from-literal=MYSQL_DATABASE="thedatabase"
kubectl create secret generic mysql-username --from-literal=MYSQL_USERNAME="theusername"
kubectl create secret generic mysql-password --from-literal=MYSQL_PASSWORD="thepassword"

MySQL volume

# mysql-volume.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: do-block-storage

My App Volume

# app-volume.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
  storageClassName: do-block-storage

MySQL Deployment

# mysql-deployment.yaml
# https://hub.docker.com/_/mysql
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      component: mysql
  template:
    metadata:
      labels:
        component: mysql
    spec:
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      volumes:
        - name: mysql-storage
          persistentVolumeClaim:
            claimName: mysql-pvc
      containers:
        - name: mysql
          image: mysql:5.7
          resources:
            requests:
              memory: "1Gi"
              cpu: "200m"
            limits:
              memory: "2Gi"
              cpu: "400m"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3306
          volumeMounts:
            - name: mysql-storage
              mountPath: /var/lib/mysql
          env:
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: mysql-username
                  key: MYSQL_USERNAME
            - name: MYSQL_DB
              valueFrom:
                secretKeyRef:
                  name: mysql-database
                  key: MYSQL_DATABASE
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-password
                  key: MYSQL_PASSWORD

MySQL ClusterIP Service

# mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ClusterIP
  selector:
    component: mysql
  ports:
  - name: mysql
    port: 3306

*My Application*
# my-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  revisionHistoryLimit: 100
  selector:
    matchLabels:
      component: my-app
  template:
    metadata:
      labels:
        component: my-app
    spec:
      terminationGracePeriodSeconds: 30
      containers:
      - name: my-app
        image: MY-DOCKER-IMAGE:MY-VERSION
        resources:
          requests:
            memory: "1Gi"
            cpu: "200m"
          limits:
            memory: "2Gi"
            cpu: "300m"
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: //healthz
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 3
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        - containerPort: 443
        # if use environment variables
        env:
          - name: MY_APP_SECRET
            valueFrom:
              secretKeyRef:
                name: my-app-secret
                key: MY_APP_SECRET
      # if pull images from private repository
      imagePullSecrets:
        - name: private-secret.registry

My App Service

# my-app.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: ClusterIP
  selector:
    component: my-app
  ports:
  - name: "http"
    port: 80
  - name: "https"
    port: 443

This manifest could give you an idea. I hope you find this information useful.

I spent a good 45 minutes answering this question yesterday, but the system marked it as spam :-(

But to summarise:

  • Look up Kubernetes services to learn how to communicate between .net and mysql
  • Consider NOT running your MySQL altogether and using a managed service instead (more reliable, less trouble)
  • For storing uploads, use an object store instead of mounted volumes
  • wow, I’m really sorry to know that!
    So far I have successfully created a volume and attached a node to it. Now I’m going to test how the communication between .NET and this volume works.

    By “Object Store” you mean DigitalOcean Spaces?

    Thank you very much nabsul!

The problem with volumes is that you can only attach a volume to one pod at a time. So if you have two or three instances of your .net app, they’ll have to have separate copies of your data.

Object store can be Digital ocean spaces, but it could also be S3 or Azure Blob Storage.

Submit an Answer