|
| 1 | +--- |
| 2 | +meta: |
| 3 | + title: Connecting Scaleway Managed Databases to Kubernetes Kapsule clusters |
| 4 | + description: This page explains how to connect Scaleway Managed Databases to Kubernetes Kapsule clusters |
| 5 | +content: |
| 6 | + h1: Connecting Scaleway Managed Databases to Kubernetes Kapsule clusters |
| 7 | + paragraph: This page explains how to connect Scaleway Managed Databases to Kubernetes Kapsule clusters |
| 8 | +tags: managed database kubernetes cluster kapsule k8s |
| 9 | +dates: |
| 10 | + validation: 2025-03-26 |
| 11 | + posted: 2025-03-26 |
| 12 | +--- |
| 13 | + |
| 14 | +This guide explains how to set up and connect a Scaleway Managed Database for PostgreSQL or MySQL with a Scaleway Kubernetes Kapsule cluster. |
| 15 | + |
| 16 | +We will walk you through the entire process using both the Scaleway CLI and Terraform approaches. |
| 17 | + |
| 18 | +<Macro id="requirements" /> |
| 19 | + |
| 20 | +- A Scaleway account logged into the [console](https://console.scaleway.com) |
| 21 | +- [Owner](/iam/concepts/#owner) status or [IAM permissions](/iam/concepts/#permission) allowing you to perform actions in the intended Organization |
| 22 | +- A valid [API key](/iam/how-to/create-api-keys/) |
| 23 | +- [Scaleway CLI](https://github.com/scaleway/scaleway-cli) installed and configured |
| 24 | +- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) installed |
| 25 | +- [Terraform](https://www.terraform.io/downloads.html) or [OpenTofu](https://opentofu.org/) installed (for Terraform approach) |
| 26 | + |
| 27 | +## Method 1 - Using the Scaleway CLI |
| 28 | + |
| 29 | +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). |
| 30 | + |
| 31 | +### Creating a Private Network |
| 32 | + |
| 33 | +Create a Private Network that both your Kubernetes cluster and database will use: |
| 34 | + |
| 35 | + ``` |
| 36 | + scw vpc private-network create name=kube-db-network |
| 37 | + ``` |
| 38 | + |
| 39 | + <Message type="note"> |
| 40 | + Note the Private Network ID from the output for later use. |
| 41 | + </Message> |
| 42 | + |
| 43 | +### Creating a Managed Database Instance |
| 44 | + |
| 45 | +1. Run the following command to create a Managed PostgreSQL (or MySQL) Database Instance: |
| 46 | + |
| 47 | + ``` |
| 48 | + scw rdb instance create \ |
| 49 | + name=my-kube-database \ |
| 50 | + node-type=db-dev-s \ |
| 51 | + engine=PostgreSQL-15 \ |
| 52 | + is-ha-cluster=true \ |
| 53 | + user-name=admin \ |
| 54 | + password=StrongP@ssw0rd123 \ |
| 55 | + private-network-id=<private-network-id> |
| 56 | + ``` |
| 57 | + |
| 58 | + This creates a high-availability PostgreSQL 15 database attached to the Private Network. The database is only accessible within the Private Network. |
| 59 | + |
| 60 | +2. **Optional** If you prefer a public endpoint as well: |
| 61 | + |
| 62 | + ``` |
| 63 | + scw rdb instance create \ |
| 64 | + name=my-kube-database \ |
| 65 | + node-type=db-dev-s \ |
| 66 | + engine=PostgreSQL-15 \ |
| 67 | + is-ha-cluster=true \ |
| 68 | + user-name=admin \ |
| 69 | + password=StrongP@ssw0rd123 |
| 70 | + ``` |
| 71 | + <Message type="important"> |
| 72 | + Adding a public endpoint is less secure, but can be useful for management purposes in some cases. |
| 73 | + **Ensure to choose a strong password for your database user.** |
| 74 | + </Message> |
| 75 | + |
| 76 | +3. Add the Private Network endpoint to the database: |
| 77 | + |
| 78 | + ``` |
| 79 | + scw rdb endpoint create \ |
| 80 | + instance-id=<database-instance-id> \ |
| 81 | + private-network-id=<private-network-id> |
| 82 | + ``` |
| 83 | + |
| 84 | +### Creating a Kubernetes Kapsule Cluster |
| 85 | + |
| 86 | +1. Run the following Scaleway CLI command to create a Kubernetes Kapsule cluster attached to the same Private Network: |
| 87 | + |
| 88 | + ``` |
| 89 | + scw k8s cluster create \ |
| 90 | + name=my-kube-cluster \ |
| 91 | + type=kapsule \ |
| 92 | + version=1.28.2 \ |
| 93 | + cni=cilium \ |
| 94 | + pools.0.name=default \ |
| 95 | + pools.0.node-type=DEV1-M \ |
| 96 | + pools.0.size=2 \ |
| 97 | + pools.0.autoscaling=true \ |
| 98 | + pools.0.min-size=2 \ |
| 99 | + pools.0.max-size=5 \ |
| 100 | + private-network-id=<private-network-id> |
| 101 | + ``` |
| 102 | + |
| 103 | +2. Wait for the cluster to be ready, then get the `kubeconfig`: |
| 104 | + |
| 105 | + ``` |
| 106 | + scw k8s kubeconfig install \ |
| 107 | + cluster-id=<cluster-id> |
| 108 | + ``` |
| 109 | + |
| 110 | +### Creating a Kubernetes secret for database credentials |
| 111 | + |
| 112 | +Use `kubectl` to create a Kubernetes secret to store the database credentials: |
| 113 | + |
| 114 | + ``` |
| 115 | + kubectl create secret generic db-credentials \ |
| 116 | + --from-literal=DB_HOST=<private-network-db-hostname> \ |
| 117 | + --from-literal=DB_PORT=5432 \ |
| 118 | + --from-literal=DB_NAME=rdb \ |
| 119 | + --from-literal=DB_USER=admin \ |
| 120 | + --from-literal=DB_PASSWORD=StrongP@ssw0rd123 |
| 121 | + ``` |
| 122 | + |
| 123 | +### Deploying a sample application |
| 124 | + |
| 125 | +1. Create a Kubernetes deployment that will connect to the database. Save this as `db-app.yaml`: |
| 126 | + |
| 127 | + ``` |
| 128 | + ADD DB APP YAML FILE |
| 129 | + ``` |
| 130 | + |
| 131 | +2. Apply it to your cluster: |
| 132 | + |
| 133 | + ``` |
| 134 | + kubectl apply -f db-app.yaml |
| 135 | + ``` |
| 136 | + |
| 137 | +3. Check that your application can connect to the database: |
| 138 | + |
| 139 | + ``` |
| 140 | + kubectl logs -f deployment/postgres-client |
| 141 | + ``` |
| 142 | + |
| 143 | +## Method 2 - Using Terraform |
| 144 | + |
| 145 | +For a more infrastructure-as-code approach, you can use Terraform or OpenTofu (open-source Terraform fork) to set up the same resources. |
| 146 | +Install Terraform and ensure the Scaleway Terraform provider is set up with `terraform init -provider=scaleway/scaleway`. |
| 147 | + |
| 148 | +### Setting-up Terraform files |
| 149 | + |
| 150 | +1. Create a new directory and set up your files: |
| 151 | + |
| 152 | + ``` |
| 153 | + mkdir scaleway-kube-db |
| 154 | + cd scaleway-kube-db |
| 155 | + ``` |
| 156 | + |
| 157 | +2. Create a `providers.tf` file: |
| 158 | + |
| 159 | + ``` |
| 160 | + ADD CONTENT FROM PROVIDERS.TF FILE |
| 161 | + ``` |
| 162 | + |
| 163 | +3. Create a `variables.tf` file: |
| 164 | + |
| 165 | + ``` |
| 166 | + ADD CONTENT FROM VARIABLES.TF FILE |
| 167 | + ``` |
| 168 | + |
| 169 | +4. Create a `main.tf` file for the infrastructure: |
| 170 | + |
| 171 | + ``` |
| 172 | + ADD CONTENT FROM MAIN.TF FILE |
| 173 | + ``` |
| 174 | + |
| 175 | +### Creating a `terraform.tfvars` file |
| 176 | + |
| 177 | +Create a file to store your variables securely: |
| 178 | + |
| 179 | + ``` |
| 180 | + ADD CONTENT FROM TERRAFORM.TFVARS FILE |
| 181 | + ``` |
| 182 | + |
| 183 | +### Applying the Terraform configuration |
| 184 | + |
| 185 | +Initialize and apply the Terraform configuration: |
| 186 | + |
| 187 | + ``` |
| 188 | + terraform init |
| 189 | + terraform apply |
| 190 | + ``` |
| 191 | + |
| 192 | + After confirming the plan, Terraform will create all the resources and output the database endpoint. |
| 193 | + |
| 194 | +## Connecting a real application |
| 195 | + |
| 196 | +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): |
| 197 | + |
| 198 | +### Creating a Dockerfile for the application |
| 199 | + |
| 200 | +### Creating the application files |
| 201 | + |
| 202 | +### Creating Kubernetes manifests for the application |
| 203 | + |
| 204 | +### Building and pushing the Docker image |
| 205 | + |
| 206 | + <Message type="note"> |
| 207 | + Replace `${YOUR_DOCKER_REGISTRY}` with your Docker registry (e.g., Docker Hub username). |
| 208 | + </Message> |
| 209 | + |
| 210 | + ``` |
| 211 | + docker build -t ${YOUR_DOCKER_REGISTRY}/node-postgres-app:latest . |
| 212 | + docker push ${YOUR_DOCKER_REGISTRY}/node-postgres-app:latest |
| 213 | + ``` |
| 214 | + |
| 215 | +### Deploying the application to Kubernetes |
| 216 | + |
| 217 | +1. Apply the Kubernetes manifests: |
| 218 | + |
| 219 | + ``` |
| 220 | + kubectl apply -f deployment.yaml |
| 221 | + kubectl apply -f service.yaml |
| 222 | + ``` |
| 223 | + |
| 224 | +2. Check the service to get the external IP: |
| 225 | + |
| 226 | + ``` |
| 227 | + kubectl get service node-postgres-app |
| 228 | + ``` |
| 229 | + |
| 230 | +3. Visit the application at the external IP to see it in action. |
| 231 | + |
| 232 | +## Security best practices |
| 233 | + |
| 234 | +### Use Private Networks |
| 235 | + |
| 236 | +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. |
| 237 | + |
| 238 | +### Implement proper TLS |
| 239 | + |
| 240 | +If you need to use a public endpoint, ensure you're using TLS with certificate verification: |
| 241 | + |
| 242 | +For PostgreSQL, add this to your connection string: |
| 243 | + |
| 244 | + ``` |
| 245 | + sslmode=verify-full sslrootcert=/path/to/scaleway-ca.pem |
| 246 | + ``` |
| 247 | + |
| 248 | +### Restrict database access with network policies |
| 249 | + |
| 250 | +Implement Kubernetes Network Policies to control which pods can access the database: |
| 251 | + |
| 252 | +### Use secrets management |
| 253 | + |
| 254 | +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. |
| 255 | + |
| 256 | +### Regularly rotate credentials |
| 257 | + |
| 258 | +Implement a process to regularly rotate database credentials. This can be automated using tools like Vault or custom operators. |
0 commit comments