1

I'm developing an application that is shipped as a cloud service, that is there are n instances of that application and each is completely separated from one another and each of those separated clones store the data in its own pgsql database.

Currently there is one single database server and I manually set up the docker images of this application and connect that image to newly created database on the common database server. This process is getting very time and effort consuming so I would like to automate that with Kubernetes.

I've designed a structure with one main server that will orchestrate and automate the creation of nodes, but one of many questions that arose is what is the best way to deal with data storage of such architecture?

Is it better to host one database server per pod, or should I set up one storage unit for the whole node and make pods connect to it? Is the thing that I would like to achieve even suitable for Kubernetes? That is to automate a deployment of a single docker image that will be replicated as a completely separate instances, each with it's own database.

erexo
  • 133
  • 6

1 Answers1

3

If you really have so many single application instances, setting up separate database instance for it composed in every Pod could be quite tedious task. Of course those Pods shouldn't be just bare Pods but they should be managed by some controller such as Deployment or Statefulset (which is more suitable for stateful applications such as databases). No matter if the number of replicas it creates and manages is only one, you should use the controller as it will handle Pod life-cycle for you.

Placing both application and database in a single Pod isn't recommended approach. According to microservices architecture approach, all the elements of your application such as its front-end part, back-end api and database shouldn't be tightly coupled i.e. placing all of those elements in a single Pod is definitely not recommended approach. It's still possible and technically feasible but has a lot of disadvantages.

It's much better to deploy each instance of your application as a separate Deployment if they should be totally independent from one another rather than run as a set of Pods being managed by one Deployment. Each of those Pods may connect to database instance, managed by separate StatefulSet.

When you already have your database server set up, it can be also used by your Pods. It's still acceptable approach as containers are generally not the best choice for running stateful apps and in many cases it might be even better to run them on bare metal or virtual machines.

If your database server has its fully quallified domain name (FQDN), you can simply define ExternalName Service type pointing to this domain name:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

When looking up the host my-service.prod.svc.cluster.local, the cluster DNS Service returns a CNAME record with the value my.database.example.com. Accessing my-service works in the same way as other Services but with the crucial difference that redirection happens at the DNS level rather than via proxying or forwarding. Should you later decide to move your database into your cluster, you can start its Pods, add appropriate selectors or endpoints, and change the Service’s type.

Then you can use your Service name (when working a in a single namespace) in your app to connect to your database behind it. Here you can see how front-end part of the application can be connected with its back-end. If your application supports config file where you can specify database url, you can pass it to your Pod via ConfigMap, without a need of changing your code and rebuild your docker image.

I hope it helps and clarifies a bit the available options.

mario
  • 525
  • 3
  • 8