Question

Kubernetes, mySQL and files

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!


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.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.

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.

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

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.