From 42c2133a9851d25b2746f2bf873816712943c35f Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Wed, 26 Mar 2025 14:34:29 +0100 Subject: [PATCH 1/5] feat(rdb): connecting rdb to k8s --- menu/navigation.json | 4 + ...necting-managed-database-to-kubernetes.mdx | 258 ++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx diff --git a/menu/navigation.json b/menu/navigation.json index 11281e7850..ef1f1ec23e 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -2377,6 +2377,10 @@ { "label": "Setting up logical replication as a subscriber", "slug": "logical-replication-as-subscriber" + }, + { + "label": "Connecting Managed Databases to Kubernetes clusters", + "slug": "conecting-managed-databases-to-kubernetes-clusters" } ], "label": "API/CLI", diff --git a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx new file mode 100644 index 0000000000..7a82deff71 --- /dev/null +++ b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx @@ -0,0 +1,258 @@ +--- +meta: + title: Connecting Scaleway Managed Databases to Kubernetes Kapsule clusters + description: This page explains how to connect Scaleway Managed Databases to Kubernetes Kapsule clusters +content: + h1: Connecting Scaleway Managed Databases to Kubernetes Kapsule clusters + paragraph: This page explains how to connect Scaleway Managed Databases to Kubernetes Kapsule clusters +tags: managed database kubernetes cluster kapsule k8s +dates: + validation: 2025-03-26 + posted: 2025-03-26 +--- + +This guide explains how to set up and connect a Scaleway Managed Database for PostgreSQL or MySQL with a Scaleway Kubernetes Kapsule cluster. + +We will walk you through the entire process using both the Scaleway CLI and Terraform approaches. + + + +- A Scaleway account logged into the [console](https://console.scaleway.com) +- [Owner](/iam/concepts/#owner) status or [IAM permissions](/iam/concepts/#permission) allowing you to perform actions in the intended Organization +- A valid [API key](/iam/how-to/create-api-keys/) +- [Scaleway CLI](https://github.com/scaleway/scaleway-cli) installed and configured +- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) installed +- [Terraform](https://www.terraform.io/downloads.html) or [OpenTofu](https://opentofu.org/) installed (for Terraform approach) + +## Method 1 - Using the Scaleway CLI + +First, [install the Scaleway CLI](/scaleway-cli/quickstart/#how-to-install-the-scaleway-cli-locally), and use `scw init` to set your API key and `scw config set region par1` to set the default region (e.g. Paris). + +### Creating a Private Network + +Create a Private Network that both your Kubernetes cluster and database will use: + + ``` + scw vpc private-network create name=kube-db-network + ``` + + + Note the Private Network ID from the output for later use. + + +### Creating a Managed Database Instance + +1. Run the following command to create a Managed PostgreSQL (or MySQL) Database Instance: + + ``` + scw rdb instance create \ + name=my-kube-database \ + node-type=db-dev-s \ + engine=PostgreSQL-15 \ + is-ha-cluster=true \ + user-name=admin \ + password=StrongP@ssw0rd123 \ + private-network-id= + ``` + + This creates a high-availability PostgreSQL 15 database attached to the Private Network. The database is only accessible within the Private Network. + +2. **Optional** If you prefer a public endpoint as well: + + ``` + scw rdb instance create \ + name=my-kube-database \ + node-type=db-dev-s \ + engine=PostgreSQL-15 \ + is-ha-cluster=true \ + user-name=admin \ + password=StrongP@ssw0rd123 + ``` + + Adding a public endpoint is less secure, but can be useful for management purposes in some cases. + **Ensure to choose a strong password for your database user.** + + +3. Add the Private Network endpoint to the database: + + ``` + scw rdb endpoint create \ + instance-id= \ + private-network-id= + ``` + +### Creating a Kubernetes Kapsule Cluster + +1. Run the following Scaleway CLI command to create a Kubernetes Kapsule cluster attached to the same Private Network: + + ``` + scw k8s cluster create \ + name=my-kube-cluster \ + type=kapsule \ + version=1.28.2 \ + cni=cilium \ + pools.0.name=default \ + pools.0.node-type=DEV1-M \ + pools.0.size=2 \ + pools.0.autoscaling=true \ + pools.0.min-size=2 \ + pools.0.max-size=5 \ + private-network-id= + ``` + +2. Wait for the cluster to be ready, then get the `kubeconfig`: + + ``` + scw k8s kubeconfig install \ + cluster-id= + ``` + +### Creating a Kubernetes secret for database credentials + +Use `kubectl` to create a Kubernetes secret to store the database credentials: + + ``` + kubectl create secret generic db-credentials \ + --from-literal=DB_HOST= \ + --from-literal=DB_PORT=5432 \ + --from-literal=DB_NAME=rdb \ + --from-literal=DB_USER=admin \ + --from-literal=DB_PASSWORD=StrongP@ssw0rd123 + ``` + +### Deploying a sample application + +1. Create a Kubernetes deployment that will connect to the database. Save this as `db-app.yaml`: + + ``` + ADD DB APP YAML FILE + ``` + +2. Apply it to your cluster: + + ``` + kubectl apply -f db-app.yaml + ``` + +3. Check that your application can connect to the database: + + ``` + kubectl logs -f deployment/postgres-client + ``` + +## Method 2 - Using Terraform + +For a more infrastructure-as-code approach, you can use Terraform or OpenTofu (open-source Terraform fork) to set up the same resources. +Install Terraform and ensure the Scaleway Terraform provider is set up with `terraform init -provider=scaleway/scaleway`. + +### Setting-up Terraform files + +1. Create a new directory and set up your files: + + ``` + mkdir scaleway-kube-db + cd scaleway-kube-db + ``` + +2. Create a `providers.tf` file: + + ``` + ADD CONTENT FROM PROVIDERS.TF FILE + ``` + +3. Create a `variables.tf` file: + + ``` + ADD CONTENT FROM VARIABLES.TF FILE + ``` + +4. Create a `main.tf` file for the infrastructure: + + ``` + ADD CONTENT FROM MAIN.TF FILE + ``` + +### Creating a `terraform.tfvars` file + +Create a file to store your variables securely: + + ``` + ADD CONTENT FROM TERRAFORM.TFVARS FILE + ``` + +### Applying the Terraform configuration + +Initialize and apply the Terraform configuration: + + ``` + terraform init + terraform apply + ``` + + After confirming the plan, Terraform will create all the resources and output the database endpoint. + +## Connecting a real application + +Now let's deploy a more realistic application that uses the database. Here's a simple Node.js application with Express and pg (PostgreSQL client): + +### Creating a Dockerfile for the application + +### Creating the application files + +### Creating Kubernetes manifests for the application + +### Building and pushing the Docker image + + + Replace `${YOUR_DOCKER_REGISTRY}` with your Docker registry (e.g., Docker Hub username). + + + ``` + docker build -t ${YOUR_DOCKER_REGISTRY}/node-postgres-app:latest . + docker push ${YOUR_DOCKER_REGISTRY}/node-postgres-app:latest + ``` + +### Deploying the application to Kubernetes + +1. Apply the Kubernetes manifests: + + ``` + kubectl apply -f deployment.yaml + kubectl apply -f service.yaml + ``` + +2. Check the service to get the external IP: + + ``` + kubectl get service node-postgres-app + ``` + +3. Visit the application at the external IP to see it in action. + +## Security best practices + +### Use Private Networks + +Always use Private Networks when connecting a Kubernetes cluster to a database. This ensures that database traffic never traverses the public internet, reducing the attack surface significantly. + +### Implement proper TLS + +If you need to use a public endpoint, ensure you're using TLS with certificate verification: + +For PostgreSQL, add this to your connection string: + + ``` + sslmode=verify-full sslrootcert=/path/to/scaleway-ca.pem + ``` + +### Restrict database access with network policies + +Implement Kubernetes Network Policies to control which pods can access the database: + +### Use secrets management + +Consider using a secrets management solution like HashiCorp Vault or Kubernetes External Secrets to manage database credentials instead of storing them directly in Kubernetes Secrets. + +### Regularly rotate credentials + +Implement a process to regularly rotate database credentials. This can be automated using tools like Vault or custom operators. \ No newline at end of file From 00d54da9031c10018359987db66b2bf35deb83c1 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Wed, 26 Mar 2025 14:42:56 +0100 Subject: [PATCH 2/5] fix(rdb): fix title --- .../api-cli/connecting-managed-database-to-kubernetes.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx index 7a82deff71..4a2ce0c607 100644 --- a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx +++ b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx @@ -81,7 +81,7 @@ Create a Private Network that both your Kubernetes cluster and database will use private-network-id= ``` -### Creating a Kubernetes Kapsule Cluster +### Creating a Kubernetes Kapsule cluster 1. Run the following Scaleway CLI command to create a Kubernetes Kapsule cluster attached to the same Private Network: @@ -172,7 +172,7 @@ Install Terraform and ensure the Scaleway Terraform provider is set up with `ter ADD CONTENT FROM MAIN.TF FILE ``` -### Creating a `terraform.tfvars` file +### Creating a terraform.tfvars file Create a file to store your variables securely: From a8bca8f81b9d7f9a5d029fdca66ae25fe94fac5e Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Wed, 26 Mar 2025 17:03:11 +0100 Subject: [PATCH 3/5] feat(rdb): add docs --- ...naged-database-to-kubernetes-clusters.mdx} | 260 +++++++++++++++++- 1 file changed, 248 insertions(+), 12 deletions(-) rename pages/managed-databases-for-postgresql-and-mysql/api-cli/{connecting-managed-database-to-kubernetes.mdx => connecting-managed-database-to-kubernetes-clusters.mdx} (53%) diff --git a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes-clusters.mdx similarity index 53% rename from pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx rename to pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes-clusters.mdx index 4a2ce0c607..4c34c573a4 100644 --- a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes.mdx +++ b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes-clusters.mdx @@ -148,36 +148,146 @@ Install Terraform and ensure the Scaleway Terraform provider is set up with `ter ### Setting-up Terraform files 1. Create a new directory and set up your files: - ``` mkdir scaleway-kube-db cd scaleway-kube-db ``` 2. Create a `providers.tf` file: - ``` - ADD CONTENT FROM PROVIDERS.TF FILE + terraform { + required_providers { + scaleway = { + source = "scaleway/scaleway" + version = "~> 2.40" + } + } + } + + provider "scaleway" { + access_key = var.scaleway_access_key + secret_key = var.scaleway_secret_key + project_id = var.project_id + region = var.region + zone = var.zone + } ``` 3. Create a `variables.tf` file: - ``` - ADD CONTENT FROM VARIABLES.TF FILE + variable "scaleway_access_key" { + description = "Scaleway Access Key" + type = string + sensitive = true + } + + variable "scaleway_secret_key" { + description = "Scaleway Secret Key" + type = string + sensitive = true + } + + variable "project_id" { + description = "Scaleway Project ID" + type = string + } + + variable "region" { + description = "Scaleway region (e.g., fr-par)" + type = string + default = "fr-par" + } + + variable "zone" { + description = "Scaleway zone (e.g., fr-par-1)" + type = string + default = "fr-par-1" + } + + variable "db_password" { + description = "Password for database user" + type = string + sensitive = true + } + + variable "db_user" { + description = "Database username" + type = string + default = "admin" + } ``` 4. Create a `main.tf` file for the infrastructure: - ``` - ADD CONTENT FROM MAIN.TF FILE + # Create Private Network + resource "scaleway_vpc_private_network" "private_net" { + name = "kube-db-network" + region = var.region + } + + # Create Managed PostgreSQL Database + resource "scaleway_rdb_instance" "database" { + name = "my-kube-database" + node_type = "db-dev-s" + engine = "PostgreSQL-15" + is_ha_cluster = true + user_name = var.db_user + password = var.db_password + private_network { + pn_id = scaleway_vpc_private_network.private_net.id + } + } + + # Kubernetes Cluster (Kapsule) + resource "scaleway_k8s_cluster" "kapsule" { + name = "my-kube-cluster" + version = "1.28.2" + cni = "cilium" + private_network_id = scaleway_vpc_private_network.private_net.id + + autoscaler_config { + disable_scale_down = false + scale_down_delay_after_add = "10m" + scale_down_unneeded_time = "10m" + estimator = "binpacking" + expander = "random" + ignore_daemonsets_utilization = true + } + + pool { + name = "default-pool" + node_type = "DEV1-M" + size = 2 + autoscaling = true + min_size = 2 + max_size = 5 + autohealing = true + container_runtime = "containerd" + } + } + + # Output Database Connection Information + output "db_host" { + value = scaleway_rdb_instance.database.private_network[0].ip + } + + output "db_port" { + value = scaleway_rdb_instance.database.endpoint[0].port + } + + output "kubeconfig" { + value = scaleway_k8s_cluster.kapsule.kubeconfig + sensitive = true + } ``` - ### Creating a terraform.tfvars file -Create a file to store your variables securely: - +Create a `terraform.tfvars` file to store your variables securely: ``` - ADD CONTENT FROM TERRAFORM.TFVARS FILE + scaleway_access_key = "" + scaleway_secret_key = "" + project_id = "" + db_password = "" ``` ### Applying the Terraform configuration @@ -197,10 +307,136 @@ Now let's deploy a more realistic application that uses the database. Here's a s ### Creating a Dockerfile for the application +The Dockerfile is used to create a Docker image for your application. Here's a simple example: + + ```dockerfile + # Use the official Node.js 14 image. + # https://hub.docker.com/_/node + FROM node:14 + + # Create and change to the app directory. + WORKDIR /usr/src/app + + # Copy application dependency manifests to the container image. + # A wildcard is used to ensure both package.json AND package-lock.json are copied. + # Copying this separately prevents re-running npm install on every code change. + COPY package*.json ./ + + # Install production dependencies. + RUN npm install --only=production + + # Copy local code to the container image. + COPY . . + + # Run the web service on container startup. + CMD [ "node", "app.js" ] + + # Expose the port the app runs on + EXPOSE 8080 + ``` + ### Creating the application files +You need to create the necessary files for your Node.js application. Here’s a simple `app.js` and a `package.json` file as an example: + + **`app.js`**: + ```javascript + const express = require('express'); + const { Pool } = require('pg'); + const app = express(); + + const pool = new Pool({ + user: 'postgres', + host: 'node-postgres-db', // This matches the service name in Kubernetes + database: 'postgres', + password: 'password', // Ensure this matches the password set in the Kubernetes secret + port: 5432, + }); + + app.get('/', async (req, res) => { + try { + const result = await pool.query('SELECT NOW() as now'); + res.send(result.rows); + } catch (err) { + console.error(err); + res.status(500).send(err.toString()); + } + }); + + const PORT = process.env.PORT || 8080; + app.listen(PORT, () => { + console.log(`Server running on port ${PORT}`); + }); + ``` + + **`package.json`**: + ```json + { + "name": "node-postgres-app", + "version": "1.0.0", + "main": "app.js", + "dependencies": { + "express": "^4.17.1", + "pg": "^8.6.0" + } + } + ``` + ### Creating Kubernetes manifests for the application +You need to create two main Kubernetes manifests: one for the deployment and one for the service. + + **`deployment.yaml`**: + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: node-postgres-app + spec: + replicas: 1 + selector: + matchLabels: + app: node-postgres-app + template: + metadata: + labels: + app: node-postgres-app + spec: + containers: + - name: node-postgres-app + image: ${YOUR_DOCKER_REGISTRY}/node-postgres-app:latest + ports: + - containerPort: 8080 + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: postgres-secret + key: password + --- + apiVersion: v1 + kind: Secret + metadata: + name: postgres-secret + type: Opaque + data: + password: cGFzc3dvcmQ= # base64 encoded password, 'password' in this case + ``` + + **`service.yaml`**: + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: node-postgres-app + spec: + type: LoadBalancer + ports: + - port: 80 + targetPort: 8080 + selector: + app: node-postgres-app + ``` ### Building and pushing the Docker image @@ -227,7 +463,7 @@ Now let's deploy a more realistic application that uses the database. Here's a s kubectl get service node-postgres-app ``` -3. Visit the application at the external IP to see it in action. +3. Visit the application at the external IP to see it in action. If everything is set up correctly, you should see the current PostgreSQL time displayed when you access the application URL. ## Security best practices From 1882c110ec10459f56808951f4777ea6dbdc149c Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Thu, 27 Mar 2025 11:55:03 +0100 Subject: [PATCH 4/5] feat(rdb): add tutorial --- menu/navigation.json | 2 +- ...aged-databases-to-kubernetes-clusters.mdx} | 217 ++++++++++++------ 2 files changed, 153 insertions(+), 66 deletions(-) rename pages/managed-databases-for-postgresql-and-mysql/api-cli/{connecting-managed-database-to-kubernetes-clusters.mdx => connecting-managed-databases-to-kubernetes-clusters.mdx} (69%) diff --git a/menu/navigation.json b/menu/navigation.json index ef1f1ec23e..0934af70a8 100644 --- a/menu/navigation.json +++ b/menu/navigation.json @@ -2380,7 +2380,7 @@ }, { "label": "Connecting Managed Databases to Kubernetes clusters", - "slug": "conecting-managed-databases-to-kubernetes-clusters" + "slug": "connecting-managed-databases-to-kubernetes-clusters" } ], "label": "API/CLI", diff --git a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes-clusters.mdx b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx similarity index 69% rename from pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes-clusters.mdx rename to pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx index 4c34c573a4..1130aac3c0 100644 --- a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-database-to-kubernetes-clusters.mdx +++ b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx @@ -52,33 +52,32 @@ Create a Private Network that both your Kubernetes cluster and database will use is-ha-cluster=true \ user-name=admin \ password=StrongP@ssw0rd123 \ - private-network-id= + region=fr-par ``` - This creates a high-availability PostgreSQL 15 database attached to the Private Network. The database is only accessible within the Private Network. - -2. **Optional** If you prefer a public endpoint as well: + This creates a high-availability PostgreSQL 15 database with a public Endpoint. - ``` - scw rdb instance create \ - name=my-kube-database \ - node-type=db-dev-s \ - engine=PostgreSQL-15 \ - is-ha-cluster=true \ - user-name=admin \ - password=StrongP@ssw0rd123 - ``` - Adding a public endpoint is less secure, but can be useful for management purposes in some cases. - **Ensure to choose a strong password for your database user.** + At this point the database is exposed to the Internet. 3. Add the Private Network endpoint to the database: ``` scw rdb endpoint create \ - instance-id= \ - private-network-id= + \ + private-network.private-network-id= \ + private-network.enable-ipam=true region-fr-par + ``` + +4. Get the Insance details and look for the public endpoint ID under the "Endpoints" section. + ``` + scw rdb instance get + ``` + +4. Remove the public endpoint to ensure the database is only reachable from the Private Network and no longer exposed to the public Ineternet. + ``` + scw rdb endpoint delete instance-id= ``` ### Creating a Kubernetes Kapsule cluster @@ -103,8 +102,7 @@ Create a Private Network that both your Kubernetes cluster and database will use 2. Wait for the cluster to be ready, then get the `kubeconfig`: ``` - scw k8s kubeconfig install \ - cluster-id= + scw k8s kubeconfig install region=fr-par ``` ### Creating a Kubernetes secret for database credentials @@ -125,9 +123,51 @@ Use `kubectl` to create a Kubernetes secret to store the database credentials: 1. Create a Kubernetes deployment that will connect to the database. Save this as `db-app.yaml`: ``` - ADD DB APP YAML FILE + apiVersion: apps/v1 + kind: Deployment + metadata: + name: postgres-client + spec: + replicas: 1 + selector: + matchLabels: + app: postgres-client + template: + metadata: + labels: + app: postgres-client + spec: + containers: + - name: postgres-client + image: postgres:latest + command: ["sleep", "infinity"] + env: + - name: DB_HOST + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_HOST + - name: DB_PORT + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_PORT + - name: DB_NAME + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_NAME + - name: DB_USER + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_USER + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_PASSWORD ``` - 2. Apply it to your cluster: ``` @@ -227,43 +267,44 @@ Install Terraform and ensure the Scaleway Terraform provider is set up with `ter # Create Managed PostgreSQL Database resource "scaleway_rdb_instance" "database" { - name = "my-kube-database" - node_type = "db-dev-s" - engine = "PostgreSQL-15" - is_ha_cluster = true - user_name = var.db_user - password = var.db_password + name = "my-kube-database" + node_type = "db-dev-s" + engine = "PostgreSQL-15" + is_ha_cluster = true + user_name = var.db_user + password = var.db_password + private_network { - pn_id = scaleway_vpc_private_network.private_net.id + pn_id = scaleway_vpc_private_network.private_net.id + enable_ipam = true } } # Kubernetes Cluster (Kapsule) resource "scaleway_k8s_cluster" "kapsule" { - name = "my-kube-cluster" - version = "1.28.2" - cni = "cilium" - private_network_id = scaleway_vpc_private_network.private_net.id - - autoscaler_config { - disable_scale_down = false - scale_down_delay_after_add = "10m" - scale_down_unneeded_time = "10m" - estimator = "binpacking" - expander = "random" - ignore_daemonsets_utilization = true + name = "my-kube-cluster-${random_id.suffix.hex}" # Make the name unique + version = "1.28.2" + cni = "cilium" + private_network_id = scaleway_vpc_private_network.private_net.id + delete_additional_resources = true } - pool { - name = "default-pool" - node_type = "DEV1-M" - size = 2 - autoscaling = true - min_size = 2 - max_size = 5 - autohealing = true - container_runtime = "containerd" + # Kubernetes Node Pool + resource "scaleway_k8s_pool" "default_pool" { + cluster_id = scaleway_k8s_cluster.kapsule.id + name = "default-pool" + node_type = "DEV1-M" + size = 2 + autoscaling = true + min_size = 2 + max_size = 5 + autohealing = true + container_runtime = "containerd" } + + # Generate a random suffix for uniqueness + resource "random_id" "suffix" { + byte_length = 4 } # Output Database Connection Information @@ -272,7 +313,7 @@ Install Terraform and ensure the Scaleway Terraform provider is set up with `ter } output "db_port" { - value = scaleway_rdb_instance.database.endpoint[0].port + value = scaleway_rdb_instance.database.db_host_port } output "kubeconfig" { @@ -345,12 +386,13 @@ You need to create the necessary files for your Node.js application. Here’s a const { Pool } = require('pg'); const app = express(); + // Get DB credentials from environment variables const pool = new Pool({ - user: 'postgres', - host: 'node-postgres-db', // This matches the service name in Kubernetes - database: 'postgres', - password: 'password', // Ensure this matches the password set in the Kubernetes secret - port: 5432, + user: process.env.DB_USER, // 'admin' + host: process.env.DB_HOST, // '' + database: process.env.DB_NAME, // 'rdb' + password: process.env.DB_PASSWORD, + port: process.env.DB_PORT, // '5432' }); app.get('/', async (req, res) => { @@ -384,7 +426,28 @@ You need to create the necessary files for your Node.js application. Here’s a ### Creating Kubernetes manifests for the application -You need to create two main Kubernetes manifests: one for the deployment and one for the service. +1. Ensure the previously created secret is cleared: +``` +kubectl delete secret db-credentials +``` + +2. Recreate the Secret Using `kubectl create secret`. Run the following command without any base64 encoding: + ``` + kubectl create secret generic db-credentials \ + --from-literal=DB_HOST= \ + --from-literal=DB_PORT=5432 \ + --from-literal=DB_NAME=rdb \ + --from-literal=DB_USER=admin \ + --from-literal=DB_PASSWORD=StrongP@ssw0rd123 + ``` + Kubernetes will automatically handle the base64 encoding for you. + +3. Get the secret details: + ``` + kubectl get secret db-credentials -o yaml + ``` + +4. Create two main Kubernetes manifests: one for the deployment and one for the service. **`deployment.yaml`**: ```yaml @@ -403,24 +466,48 @@ You need to create two main Kubernetes manifests: one for the deployment and one app: node-postgres-app spec: containers: - - name: node-postgres-app + - name: node-postgres-app image: ${YOUR_DOCKER_REGISTRY}/node-postgres-app:latest ports: - - containerPort: 8080 + - containerPort: 8080 env: - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: postgres-secret - key: password + - name: DB_HOST + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_HOST + - name: DB_PORT + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_PORT + - name: DB_NAME + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_NAME + - name: DB_USER + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_USER + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: db-credentials + key: DB_PASSWORD --- apiVersion: v1 kind: Secret metadata: - name: postgres-secret + name: db-credentials type: Opaque data: - password: cGFzc3dvcmQ= # base64 encoded password, 'password' in this case + DB_HOST: + DB_PORT: + DB_NAME: + DB_USER: + DB_PASSWORD: ``` **`service.yaml`**: From 4e4b52f4ac1cb25c0b5742aa8647a7e3ab5a5aa7 Mon Sep 17 00:00:00 2001 From: Benedikt Rollik Date: Mon, 31 Mar 2025 14:13:36 +0200 Subject: [PATCH 5/5] Update pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx Co-authored-by: Rowena Jones <36301604+RoRoJ@users.noreply.github.com> --- .../connecting-managed-databases-to-kubernetes-clusters.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx index 1130aac3c0..533a48e822 100644 --- a/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx +++ b/pages/managed-databases-for-postgresql-and-mysql/api-cli/connecting-managed-databases-to-kubernetes-clusters.mdx @@ -55,7 +55,7 @@ Create a Private Network that both your Kubernetes cluster and database will use region=fr-par ``` - This creates a high-availability PostgreSQL 15 database with a public Endpoint. + This creates a high-availability PostgreSQL 15 database with a public endpoint. At this point the database is exposed to the Internet.