Complimentary Gartner® Report! 'A CTO's Guide to Open-Source Software: Answering the Top 10 FAQs.'Read more

Postgres Store

BindPlane OP stores organizations, accounts, agent metadata, configurations and more in Postgres when configured to use Postgres as the primary datastore.

Using Postgres is a prerequisite for operating BindPlane in High Availability.

This guide will cover the deployment of BindPlane OP and Postgres 16 on Linux (Debian 12) and Kubernetes.

Prerequisites

You must have a BindPlane license key before following this guide. If you do not have a license, you can request one on the Download page.

If deploying BindPlane to Kubernetes, you must have Helm installed.

Linux

1. Architecture

This guide will reference two virtual machines, one for the BindPlane control-plane (bindplane) and one for the Postgres installation (bindplane-postgres). It is best practice to deploy Postgres to a dedicated machine, allowing multiple BindPlane instances to make use of it if you decide to use High Availability.

The network in this example contains the required DNS entries to support reaching the machines by their short hostname bindplane and bindplane-postgres. If you do not have DNS in your environment, use IP addresses instead of hostnames when configuring BindPlane to connect to Postgres.

2. Postgres Installation and Configuration

Start by installing Postgres. This guide is using Debian 12, but you can use your preferred distribution, just know that the commands to install and manage Postgres may differ.

Configure the Postgres apt repository.

bash
1sudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
2wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

Install Postgres 16 from the Postgres repository.

bash
1sudo apt-get update
2sudo apt-get install postgresql-16

Enable and start the Postgres service.

bash
1sudo systemctl start postgresql.service
2sudo systemctl enable --now postgresql.service

Configure Postgres to listen on all interfaces.

Edit the Postgres configuration file and find listen_addresses.

bash
1sudo vim /etc/postgresql/16/main/postgresql.conf

Uncomment listen_addresses and set the value to 0.0.0.0. It should look like this:

txt
1listen_addresses = '0.0.0.0'

note

If your system has iptables or firewalld enabled, make sure to allow port 5432/tcp.

Next we need to update the Authentication configuration.

Configure Postgres to allow remote connections.

bash
1sudo vim /etc/postgresql/16/main/pg_hba.conf

Find the lines that looks like this:

txt
1# IPv4 local connections:
2host    all             all             127.0.0.1/32            scram-sha-256
3# IPv6 local connections:
4host    all             all             ::1/128                 scram-sha-256

Update the configuration by replacing 127.0.0.1/32 and ::1/128. It should look like this:

txt
1# IPv4 all connections:
2host    all             all             0.0.0.0/0               scram-sha-256
3# IPv6 all connections:
4host    all             all             ::/0                    scram-sha-256

User setup and Database creation

Connect to the Postgres installation by switching to the postgres user and running the psql client command.

bash
1sudo su - postgres
2psql

Execute the setup queries found in the User and Database section in the Postgres Going to Production documentation.

Restart the service.

bash
1sudo systemctl restart postgresql.service

With Postgres installed and configured, you can move onto installing and configuring BindPlane.

3. BindPlane Installation and Configuration

Install BindPlane by following the instructions on the Download page.

bash
1curl \
2    -fsSlL https://storage.googleapis.com/bindplane-op-releases/bindplane/latest/install-linux.sh \
3    -o install-linux.sh
4
5bash install-linux.sh \
6    --version 1.72.1 \
7    --init && rm install-linux.sh

Once the package is installed, select y to initialize the configuration.

  1. Select your license type and input your license
  2. Server Host: 0.0.0.0
  3. Server Port: 3001
  4. Remote URL: http://bindplane:3001, the remote URL should match your hostname or IP address.
  5. Authentication Method: Single User
  6. Username: admin
  7. Password: Your secure password
  8. Storage Type: postgres
  9. Postgres Host: bindplane-postgres, this value should match your Postgres server's hostname or IP address.
  10. Postgres Port: 5432
  11. Postgres Database Name: bindplane
  12. Postgres SSL Mode: disable, see Postgres TLS for TLS configuration, as a follow up to this guide.
  13. Maximum Number of Database Connections: 100
  14. Postgres Username: bindplane
  15. Postgres Password: Your password
  16. Event Bus Type: Local
  17. Automatically restart: y

Watch the BindPlane log file for any issues:

bash
1sudo tail -F /var/log/bindplane/bindplane.log

BindPlane will log the following lines which indicate Postgres is configured and working.

json
1{"level":"info","timestamp":"2024-09-18T00:34:22.670Z","message":"Using postgres store"}
2{"level":"info","timestamp":"2024-09-18T00:34:23.091Z","message":"Starting rollout updater"}
3{"level":"info","timestamp":"2024-09-18T00:34:23.093Z","message":"Metrics provider is NOP"}

If the Using postgres store log is not immediately followed by an error log, Postgres is configured correctly.

4. Verification

Log into the BindPlane OP web interface at http://bindplane:3001. Replace bindplane with your hostname or IP address.

If you can create a configuration successfully, Postgres is working as intended.

Kubernetes

1. Architecture

This guide will use minikube to deploy Postgres and BindPlane using high availability. In production, it is recommended to deploy Postgres to a virtual machine, a SaaS provider (CloudSQL, RDS, etc) or to use a Postgres operator such as zalando/postgres-operator.

Start by configuring minikube or your Kubernetes provider of choice.

bash
1minikube start \
2    --nodes 1 \
3    --cpus 4 \
4    --memory 12g

2. Postgres Installation and Configuration

warning

The Postgres YAML manifest provided in this guide is not production ready. It does not use secure authentication. It does not provide volume persistence, meaning data will be lost when the Postgres pod is updated or replaced.

Begin by deploying the Postgres deployment to Kubernetes. You can inspect the YAML manifest here.

bash
1kubectl apply -f \
2    https://raw.githubusercontent.com/observIQ/bindplane-op-helm/main/test/helper/postgres/postgres.yaml

If not using the provided Postgres example deployment, make sure to follow the User and Database section in the Postgres Going to Production documentation when provisioning your database host.

Once the pod is deployed, the postgres namespace will look like this:

bash
1$ kubectl -n postgres get all
2
3NAME             READY   STATUS    RESTARTS   AGE
4pod/postgres-0   1/1     Running   0          23s
5
6NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
7service/postgres   ClusterIP   10.100.109.54   <none>        5432/TCP   23s
8
9NAME                        READY   AGE
10statefulset.apps/postgres   1/1     23s

The service postgres will route traffic to the pod postgres-0. Postgres is accessible using the username postgres and password password.

3. BindPlane Installation and Configuration

Setup your Helm client to support deploying the BindPlane OP Helm Chart

bash
1helm repo add bindplane \
2    https://observiq.github.io/bindplane-op-helm
3
4helm repo update
5helm search repo

Create the BindPlane license secret, where $BINDPLANE_LICENSE is your BindPlane license key.

bash
1kubectl create secret generic bindplane \      
2  --from-literal=license=$BINDPLANE_LICENSE

Create a Helm values.yaml file.

yaml
1config:
2  username: admin
3  password: password
4  sessions_secret: 4484766F-5016-4077-B8E0-0DE1D637854B
5  server_url: http://bindplane.local:80
6  licenseUseSecret: true
7
8backend:
9  type: postgres
10  postgres:
11    host: postgres.postgres.svc.cluster.local
12    database: bindplane
13    username: postgres
14    password: password
15    maxConnections: 20
16    
17eventbus:
18  type: nats
19
20replicas: 2
21
22resources:
23  requests:
24    memory: 100Mi
25    cpu: 100m
26  limits:
27    memory: 100Mi
28
29nats:
30  resources:
31    requests:
32      memory: 100Mi
33      cpu: 100m
34    limits:
35      memory: 100Mi

This configuration will deploy BindPlane with two replicas, configured to connect to Postgres using the clusterIP service at postgres.postgres.svc.cluster.local. In this configuration, BindPlane is not exposed by ingress, but can be reached using port forwarding.

Deploy BindPlane High Availability.

bash
1helm upgrade \
2    --install bindplane-ha \
3    bindplane/bindplane \
4    --values values.yaml

Once the chart is deployed, the following pods will be present:

  • bindplane-ha
    • Web interface
    • API
    • Agent connections
  • bindplane-ha-jobs
    • Manages the database initialization and migrations
    • Periodic jobs, such as cleaning up disconnected Kubernetes agents.
  • bindplane-ha-nats
  • bindplane-ha-prometheus
    • Acts as the storage for agent throughput measurement data
    • Contains the required configuration or supporting BindPlane
  • bindplane-ha-transform-agent
bash
1$ kubectl -n default get all
2
3NAME                                               READY   STATUS    RESTARTS       AGE
4pod/bindplane-ha-54cb7b5d97-q4x48                  1/1     Running   0              5m
5pod/bindplane-ha-54cb7b5d97-wwt6j                  1/1     Running   0              5m
6pod/bindplane-ha-jobs-55576897c-glncr              1/1     Running   0              5m
7pod/bindplane-ha-nats-0                            1/1     Running   0              5m
8pod/bindplane-ha-nats-1                            1/1     Running   0              5m
9pod/bindplane-ha-nats-2                            1/1     Running   0              5m
10pod/bindplane-ha-prometheus-0                      1/1     Running   0              5m
11pod/bindplane-ha-transform-agent-9fbf44f95-lwmsw   1/1     Running   0              5m
12
13NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
14service/bindplane-ha                         ClusterIP   10.97.69.212     <none>        3001/TCP   5m
15service/bindplane-ha-nats-cluster-headless   ClusterIP   None             <none>        6222/TCP   5m
16service/bindplane-ha-nats-headless           ClusterIP   None             <none>        4222/TCP   5m
17service/bindplane-ha-prometheus              ClusterIP   10.106.131.157   <none>        9090/TCP   5m
18service/bindplane-ha-transform-agent         ClusterIP   10.100.49.83     <none>        4568/TCP   5m
19service/kubernetes                           ClusterIP   10.96.0.1        <none>        443/TCP    25h
20
21NAME                                           READY   UP-TO-DATE   AVAILABLE   AGE
22deployment.apps/bindplane-ha                   2/2     2            2           5m
23deployment.apps/bindplane-ha-jobs              1/1     1            1           5m
24deployment.apps/bindplane-ha-transform-agent   1/1     1            1           5m
25
26NAME                                                     DESIRED   CURRENT   READY   AGE
27replicaset.apps/bindplane-ha-54cb7b5d97                  2         2         2       5m
28replicaset.apps/bindplane-ha-jobs-55576897c              1         1         1       5m
29replicaset.apps/bindplane-ha-transform-agent-9fbf44f95   1         1         1       5m
30
31NAME                                       READY   AGE
32statefulset.apps/bindplane-ha-nats         3/3     5m
33statefulset.apps/bindplane-ha-prometheus   1/1     5m

4. Verification

Access BindPlane over port forwarding.

bash
1kubectl -n default port-forward service/bindplane-ha 3001:3001

Once the tunnel is running, you can reach BindPlane at http://localhost:3001. If you can successfully create a configuration, Postgres is configured and working correctly.

Commonly Asked Questions

Migration from legacy Bbolt Store

If you are using bolt store and would like to switch to Postgres, reference the following documentation:

Does BindPlane work with SaaS hosted Postgres?

Yes, BindPlane supports the popular cloud providers such as Google Cloud CloudSQL, AWS RDS, and Azure Database. As long as the cloud provider is exposing a Postgres server, BindPlane can use it.

BindPlane does not officially support Postgres like systems, such as AlloyDB or CockroachDB.

Does BindPlane support Transport Layer Security (TLS)?

Yes, BindPlane supports TLS and mutual TLS when connecting to Postgres. After following this guide, reference the Postgres TLS guide.