# High Availability

### Architecture

When Bindplane is deployed as a Deployment, it has the following architecture.

* Bindplane with multiple replicas
  * Deployed as a Deployment.
* Prometheus time series database
  * Deployed as a StatefulSet.
  * Prometheus is deployed and managed by the chart using [observIQ's Prometheus image](https://github.com/observiq/bindplane-op-enterprise/pkgs/container/bindplane-prometheus).
* One or more Transform agent pods, for [live preview](broken://pages/QeJXTHAiy3fbDC0oMrLz)
* PostgreSQL storage backend

{% hint style="info" %}
**NOTE**

Bindplane uses Prometheus as a storage backend for collector throughput metrics. It is unnecessary to manage Prometheus outside of the Helm chart.
{% endhint %}

{% hint style="info" %}
**NOTE**

PostgreSQL is not deployed by the Bindplane Helm chart and must be deployed as a [prerequisite](#prerequisites).
{% endhint %}

### Prerequisites

#### Licensing

An Enterprise license is required when operating Bindplane in High Availability. Learn more [here](https://bindplane.com/solutions/).

#### PostgreSQL

PostgreSQL must be deployed and reachable from the cluster.

Postgres requirements

* Database named `bindplane`
* User with full permission to the `bindplane` database
* Reachable from Bindplane's Kubernetes cluster

#### Event Bus

Bindplane requires an external event bus when operating with more than one pod. See the [Event Bus](/deployment/kubernetes/server/components/event-bus.md) documentation for details.

### Installation

Add the Bindplane Helm chart to your workstation.

```bash
helm repo add "bindplane" \
    "https://observiq.github.io/bindplane-op-helm"

helm repo update
```

Create a `values.yaml` file, which will be used to configure\
your Helm deployment.

* `license`: Your Enterprise license.\
  Add the initial options. Make sure to set the following:
* `config.username`: Your basic auth username for the Administrator project.
* `config.password`: Your basic auth password for the Administrator project.
* `config.sessions_secret`: A random uuid. You can use `uuidgen` to create one.
* `config.eventbus.type`: The event bus type to use. This example will use Google Pub/Sub.
  * See the [Helm Event Bus Configuration](/production-checklist/bindplane/high-availability/event-bus.md) doc for available options.
* `backend.postgres.host`: The Hostname or IP address of the PostgreSQL server.
* `backend.postgres.port`: The PostgreSQL server's port.
* `backend.postgres.username`: The username the Bindplane server should use to connect to Postgres.
* `backend.postgres.password`: The password the Bindplane server should use to connect to Postgres.

```yaml
config:
  # An Enterprise license is required for
  # Bindplane when using PostgreSQL and an event bus.
  license: ''

  # These options should be configured by
  # the user.
  username: ''
  password: ''
  sessions_secret: ''

replicas: 3

# Eventbus is required when operating Bindplane
# using a distributed architecture.
eventbus:
  type: 'pubsub'
  pubsub:
    projectid: ''
    topic: ''

# Postgres is deployed outside of this chart
# shared by all Bindplane pods.
backend:
  type: postgres
  postgres:
    host: ''
    port: 5432
    database: 'bindplane'
    username: ''
    password: ''

resources:
  # Allow cpu bursting.
  # Request fixed amount of memory, 1Gb.
  requests:
    cpu: '500m'
    memory: '1024Mi'
  limits:
    memory: '1024Mi'

transform_agent:
  replicas: 2
```

Deploy Bindplane to the `bindplane` namespace using Helm and your previously\
created `values.yaml` configuration file.

```bash
helm repo update

helm upgrade \
    --values="values.yaml" \
    --namespace=bindplane \
    --create-namespace \
    --install \
    bindplane \
    bindplane/bindplane
```

After a few moments, check the namespace by running `kubectl -n bindplane get pod`.\
You will see three pods.

* Bindplane
* Prometheus
* [Live Preview](broken://pages/QeJXTHAiy3fbDC0oMrLz) transform agent.

```
NAME                                            READY   STATUS    RESTARTS   AGE
pod/bindplane-657d79f559-69wmw                  1/1     Running   0          55s
pod/bindplane-657d79f559-h8j2l                  1/1     Running   0          55s
pod/bindplane-657d79f559-tdl8j                  1/1     Running   0          19m
pod/bindplane-prometheus-0                      1/1     Running   0          22m
pod/bindplane-transform-agent-b44d78f5b-dgn2h   1/1     Running   0          22m
pod/bindplane-transform-agent-b44d78f5b-k9jdg   1/1     Running   0          22m

NAME                                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/bindplane                   ClusterIP   10.53.39.91    <none>        3001/TCP   24m
service/bindplane-prometheus        ClusterIP   10.53.35.68    <none>        9090/TCP   24m
service/bindplane-transform-agent   ClusterIP   10.53.34.233   <none>        4568/TCP   24m

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/bindplane                   3/3     3            3           24m
deployment.apps/bindplane-transform-agent   2/2     2            2           24m

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/bindplane-657d79f559                  3         3         3       19m
replicaset.apps/bindplane-685bd7f59b                  0         0         0       24m
replicaset.apps/bindplane-transform-agent-b44d78f5b   2         2         2       24m

NAME                                    READY   AGE
statefulset.apps/bindplane-prometheus   1/1     24m
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.bindplane.com/deployment/kubernetes/server/installation/high-availability.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
