Ditch RDS: Run Dev Databases Like the Code Ninja!

Ditch RDS: Run Dev Databases Like the Code Ninja!

Deploying a database to your development EKS (Elastic Kubernetes Service) namespace might sound unconventional to some, but it’s a game changing strategy for modern cloud-native development. While AWS RDS is a powerhouse for production workloads, it often brings unnecessary costs and complexity to development environments. By hosting databases directly in your EKS namespace, you can unlock greater flexibility, faster iterations, and a more production like testing environment all while saving money.

In this article, we’ll dive into why this approach makes sense, compare it to AWS RDS, explore practical use cases, and tackle common challenges. To top it off, we’ll provide YAML configurations (including Deployment, Service, and Persistent Volume Claim files), the option to deploy PGAdmin for database management, and even an updated JenkinsFile to automate your deployments. Ready to level up your dev game? Let’s dive in!

Why Should You Host Databases in EKS for Development?

  1. Cut Costs: AWS RDS is optimized for production with features like multi-AZ failover, automated backups, and scalability—which come at a premium. For development, running a lightweight database in EKS skips these extras and saves money.
  2. Faster Feedback Loops: Need to spin up a new environment for testing? EKS makes this a breeze. Developers can provision databases in isolated namespaces quickly, enabling faster iterations without waiting on shared RDS instances.
  3. Production-Like Testing: Hosting your development database in EKS mirrors your production setup more closely, reducing surprises during deployment.
  4. Easy Cleanup: Tearing down development namespaces in Kubernetes is as simple as a "kubectl delete namespace", unlike managing RDS cleanup, which can involve additional configuration and manual work.


Real World Experience:

In one of my previous organizations, the process for provisioning an RDS instance for development was a lengthy and restrictive one. It took a minimum of 72 hours to get approval for an RDS request, followed by another 24 hours for the instance to be fully provisioned. Due to strict security constraints, only platform administrators had direct access to the database, which meant developers had to rely on intermediaries to review or modify development data further delaying progress.

By enabling developers to deploy standalone databases directly into their EKS namespaces, we drastically reduced lead times for provisioning. Developers now had full control over their development environments, including direct database access, which allowed them to quickly review, test, and modify data as needed. This approach transformed our development workflows, increasing efficiency and empowering teams to work more autonomously.


Comparison: EKS-Hosted Databases vs. AWS RDS

Comparison Table

Use Cases for EKS-Hosted Databases

  1. Integration Testing: Isolated environments for teams or developers reduce conflicts and ensure smooth testing.
  2. Rapid Prototyping: Spin up databases quickly to experiment with schema or queries without impacting shared resources.
  3. Multi-Tenant Applications: Each tenant environment can have its own isolated namespace, complete with a dedicated database.


Challenges and Best Practices

While hosting databases in EKS provides flexibility and cost savings, it’s important to be aware of and address these challenges:

  1. Persistent Storage: Use Persistent Volume Claims (PVCs) to ensure data persistence across pod restarts or rescheduling. This is critical to avoid losing development data.
  2. Backup and Restore: Incorporate scripts or tools to back up your development databases regularly, so you can save data between iterations and restore it when needed.
  3. Resource Management: Monitor CPU and memory allocation for your database pods to avoid over-provisioning resources, which can increase costs or impact cluster performance.

By proactively managing these challenges, you can ensure a smoother development experience with EKS-hosted databases.


YAML Configurations

Below are complete YAML configurations for PostgreSQL, MySQL, MongoDB, and the option to deploy PGAdmin for database management.


1. PostgreSQL with PGAdmin

Persistent Volume Claim for PostgreSQL:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi        

Deployment for PostgreSQL:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:latest
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_USER
          value: admin
        - name: POSTGRES_PASSWORD
          value: password
        - name: POSTGRES_DB
          value: devdb
        volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: postgres-storage
      volumes:
      - name: postgres-storage
        persistentVolumeClaim:
          claimName: postgres-pvc
        

Service for PostgreSQL:

apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  type: ClusterIP
  ports:
  - port: 5432
    targetPort: 5432
  selector:
    app: postgres        

Deployment for PGAdmin:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pgadmin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pgadmin
  template:
    metadata:
      labels:
        app: pgadmin
    spec:
      containers:
      - name: pgadmin
        image: dpage/pgadmin4:latest
        ports:
        - containerPort: 80
        env:
        - name: PGADMIN_DEFAULT_EMAIL
          value: [email protected]
        - name: PGADMIN_DEFAULT_PASSWORD
          value: admin        

Service for PGAdmin:

apiVersion: v1
kind: Service
metadata:
  name: pgadmin
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: pgadmin        

2. MySQL

Persistent Volume Claim for MySQL:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
        

Deployment for MySQL:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:latest
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpassword
        - name: MYSQL_DATABASE
          value: devdb
        volumeMounts:
        - mountPath: /var/lib/mysql
          name: mysql-storage
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc        

Service for MySQL:

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ClusterIP
  ports:
  - port: 3306
    targetPort: 3306
  selector:
    app: mysql        

3. MongoDB

Persistent Volume Claim for MongoDB:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi        

Deployment for MongoDB:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo:latest
        ports:
        - containerPort: 27017
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          value: admin
        - name: MONGO_INITDB_ROOT_PASSWORD
          value: password
        volumeMounts:
        - mountPath: /data/db
          name: mongodb-storage
      volumes:
      - name: mongodb-storage
        persistentVolumeClaim:
          claimName: mongodb-pvc        

Service for MongoDB:

apiVersion: v1
kind: Service
metadata:
  name: mongodb
spec:
  type: ClusterIP
  ports:
  - port: 27017
    targetPort: 27017
  selector:
    app: mongodb        

Automating with Jenkins

Here’s an example JenkinsFile that demonstrates how to automate the entire process outlined in this article from creating a namespace to deploying all the databases (PostgreSQL, MySQL, MongoDB) and PGAdmin into the dev namespace. Feel free to use this as a starting point, but modify it to deploy only the database(s) of your choice:

pipeline {
    agent any
    stages {
        stage('Setup Kubernetes Namespace') {
            steps {
                sh '''
                kubectl get namespace dev || kubectl create namespace dev
                '''
            }
        }
        stage('Deploy PostgreSQL') {
            steps {
                sh '''
                kubectl apply -f postgres/pvc.yaml --namespace=dev
                kubectl apply -f postgres/deployment.yaml --namespace=dev
                kubectl apply -f postgres/service.yaml --namespace=dev
                '''
            }
        }
        stage('Deploy PGAdmin') {
            steps {
                sh '''
                kubectl apply -f pgadmin/deployment.yaml --namespace=dev
                kubectl apply -f pgadmin/service.yaml --namespace=dev
                '''
            }
        }
        stage('Deploy MySQL') {
            steps {
                sh '''
                kubectl apply -f mysql/pvc.yaml --namespace=dev
                kubectl apply -f mysql/deployment.yaml --namespace=dev
                kubectl apply -f mysql/service.yaml --namespace=dev
                '''
            }
        }
        stage('Deploy MongoDB') {
            steps {
                sh '''
                kubectl apply -f mongodb/pvc.yaml --namespace=dev
                kubectl apply -f mongodb/deployment.yaml --namespace=dev
                kubectl apply -f mongodb/service.yaml --namespace=dev
                '''
            }
        }
    }
    post {
        success {
            echo "All selected databases and services have been deployed successfully!"
        }
        failure {
            echo "Database deployment failed. Please check the logs for more details."
        }
    }
}        

Conclusion

Congratulations! You’ve just taken a step closer to mastering the art of database deployment in Kubernetes. By ditching AWS RDS for development and hosting databases in your EKS namespace, you unlock a world of cost savings, speed, and flexibility. Whether it’s PostgreSQL, MySQL, or MongoDB, you now have the tools (and YAMLs!) to make your dev environment as dynamic as your ideas.

But don’t stop here, this is just the beginning! The tech world evolves at lightning speed, and the skills you’re sharpening today are building the foundation for even greater achievements tomorrow. So, experiment, automate with Jenkins, break things (in a safe dev environment), and learn from it all. Each step you take brings you closer to becoming the code ninja you’re meant to be.

Remember: the journey of learning never ends, and the possibilities are endless. Keep coding, keep deploying, and most importantly, keep being awesome!

References and Resources

Imtiaj Perbej

DevOps Engineer at Capital One SRE, Kubernetes, iAC.

2 个月

This article is incredibly insightful and well-written! It breaks down Kubernetes concepts in a way that’s easy to understand, even for beginners. The step-by-step explanations and practical examples really helped clarify how to get started with deployments and manage containers effectively. Great job on making such a complex topic approachable!

回复

要查看或添加评论,请登录

Frank Carrubba的更多文章

社区洞察

其他会员也浏览了