---
Title: Create Active-Active databases with crdb-cli
alwaysopen: false
categories:
- docs
- operate
- kubernetes
description: This section shows how to set up an Active-Active Redis Enterprise database
on Kubernetes using the Redis Enterprise Software operator.
linkTitle: Create Active-Active with crdb-cli
weight: 99
url: '/operate/kubernetes/7.22/active-active/create-aa-crdb-cli/'
---
{{}} Versions 6.4.2 and later support the Active-Active database controller. This controller allows you to create Redis Enterprise Active-Active databases (REAADB) and Redis Enterprise remote clusters (RERC) with custom resources. We recommend using the [REAADB method for creating Active-Active databases]({{< relref "/operate/kubernetes/7.22/active-active/create-reaadb" >}}).{{}}
On Kubernetes, Redis Enterprise [Active-Active]({{< relref "/operate/rs/databases/active-active/" >}}) databases provide read-and-write access to the same dataset from different Kubernetes clusters. For more general information about Active-Active, see the [Redis Enterprise Software docs]({{< relref "/operate/rs/databases/active-active/" >}}).
Creating an Active-Active database requires routing [network access]({{< relref "/operate/kubernetes/7.22/networking/" >}}) between two Redis Enterprise clusters residing in different Kubernetes clusters. Without the proper access configured for each cluster, syncing between the databases instances will fail.
This process consists of:
1. Documenting values to be used in later steps. It's important these values are correct and consistent.
1. Editing the Redis Enterprise cluster (REC) spec file to include the `ActiveActive` section. This will be slightly different depending on the K8s distribution you are using.
1. Creating the database with the `crdb-cli` command. These values must match up with values in the REC resource spec.
## Prerequisites
Before creating Active-Active databases, you'll need admin access to two or more working Kubernetes clusters that each have:
- Routing for external access with an [ingress resources]({{< relref "/operate/kubernetes/7.22/networking/ingress" >}}) (or [route resources]({{< relref "/operate/kubernetes/7.22/networking/routes" >}}) on OpenShift).
- A working [Redis Enterprise cluster (REC)]({{< relref "/operate/kubernetes/7.22/reference/api/redis_enterprise_cluster_api" >}}) with a unique name.
- Enough memory resources available for the database (see [hardware requirements]({{< relref "/operate/rs/installing-upgrading/install/plan-deployment/hardware-requirements" >}})).
{{}} The `activeActive` field and the `ingressOrRouteSpec` field cannot coexist in the same REC. If you configured your ingress via the `ingressOrRouteSpec` field in the REC, create your Active-Active database with the RedisEnterpriseActiveActiveDatabase (REAADB) custom resource.{{}}
## Document required parameters
The most common mistake when setting up Active-Active databases is incorrect or inconsistent parameter values. The values listed in the resource file must match those used in the crdb-cli command.
- **Database name** ``:
- Description: Combined with ingress suffix to create the Active-Active database hostname
- Format: string
- Example value: `myaadb`
- How you get it: you choose
- The database name requirements are:
- Maximum of 63 characters
- Only letter, number, or hyphen (-) characters
- Starts with a letter; ends with a letter or digit.
- Database name is not case-sensitive
You'll need the following information for each participating Redis Enterprise cluster (REC):
{{}}
You'll need to create DNS aliases to resolve your API hostname ``,``, `` to the IP address for the ingress controller’s LoadBalancer (or routes in Openshift) for each database. To avoid entering multiple DNS records, you can use a wildcard in your alias (such as *.ijk.example.com).
{{}}
- **REC hostname** ``:
- Description: Hostname used to identify your Redis Enterprise cluster in the `crdb-cli` command. This MUST be different from other participating clusters.
- Format: `..svc.cluster.local`
- Example value: `rec01.ns01.svc.cluster.local`
- How to get it: List all your Redis Enterprise clusters
```bash
kubectl get rec
```
- **API hostname** ``:
- Description: Hostname used to access the Redis Enterprise cluster API from outside the K8s cluster
- Format: string
- Example value: `api.ijk.example.com`
- **Ingress suffix** ``:
- Description: Combined with database name to create the Active-Active database hostname
- Format: string
- Example value: `-cluster.ijk.example.com`
- [**REC admin credentials**]({{< relref "/operate/kubernetes/7.22/security/manage-rec-credentials" >}}) ` `:
- Description: Admin username and password for the REC stored in a secret
- Format: string
- Example value: username: `user@example.com`, password: `something`
- How to get them:
```sh
kubectl get secret \
-o jsonpath='{.data.username}' | base64 --decode
kubectl get secret \
-o jsonpath='{.data.password}' | base64 --decode
```
- **Replication hostname** ``:
- Description: Hostname used inside the ingress for the database
- Format: ``
- Example value: `myaadb-cluster.ijk.example.com`
- How to get it: Combine `` and ` values you documented above.
- **Replication endpoint** ``:
- Description: Endpoint used externally to contact the database
- Format: `:443`
- Example value: `myaadb-cluster.ijk.example.com:443`
- How to get it:`:443`
## Add `activeActive` section to the REC resource file
From inside your K8s cluster, edit your Redis Enterprise cluster (REC) resource to add the following to the `spec` section. Do this for each participating cluster.
The operator uses the API hostname (``) to create an ingress to the Redis Enterprise cluster's API; this only happens once per cluster. Every time a new Active-Active database instance is created on this cluster, the operator creates a new ingress route to the database with the ingress suffix (``). The hostname for each new database will be in the format ``.
### Using ingress controller
1. If your cluster uses an [ingress controller]({{< relref "/operate/kubernetes/7.22/networking/ingress" >}}), add the following to the `spec` section of your REC resource file.
Nginx:
```sh
activeActive:
apiIngressUrl:
dbIngressSuffix:
ingressAnnotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
method: ingress
```
HAproxy:
```sh
activeActive:
apiIngressUrl:
dbIngressSuffix:
ingressAnnotations:
kubernetes.io/ingress.class: haproxy
ingress.kubernetes.io/ssl-passthrough: "true"
method: ingress
```
2. After the changes are saved and applied, you can verify a new ingress was created for the API.
```sh
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
rec01 api.abc.cde.example.com 225161f845b278-111450635.us.cloud.com 80 24h
```
3. Verify you can access the API from outside the K8s cluster.
```sh
curl -k -L -i -u : https:///v1/cluster
```
If the API call fails, create a DNS alias that resolves your API hostname (``) to the IP address for the ingress controller's LoadBalancer.
4. Make sure you have DNS aliases for each database that resolve your API hostname ``,``, `` to the IP address of the ingress controller’s LoadBalancer. To avoid entering multiple DNS records, you can use a wildcard in your alias (such as `*.ijk.example.com`).
#### If using Istio Gateway and VirtualService
No changes are required to the REC spec if you are using [Istio]({{< relref "/operate/kubernetes/7.22/networking/istio-ingress" >}}) in place of an ingress controller. The `activeActive` section added above creates ingress resources. The two custom resources used to configure Istio (Gateway and VirtualService) replace the need for ingress resources.
{{}}
These custom resources are not controlled by the operator and will need to be configured and maintained manually.
{{}}
For each cluster, verify the VirtualService resource has two `- match:` blocks in the `tls` section. The hostname under `sniHosts:` should match your ``.
### Using OpenShift routes
1. Make sure your Redis Enterprise cluster (REC) has a different name (``) than any other participating clusters. If not, you'll need to manually rename the REC or move it to a different namespace.
You can check your new REC name with:
```sh
oc get rec -o jsonpath='{.items[0].metadata.name}'
```
If the rec name was modified, reapply [scc.yaml](https://github.com/RedisLabs/redis-enterprise-k8s-docs/blob/master/openshift/scc.yaml) to the namespace to reestablish security privileges.
```sh
oc apply -f scc.yaml
oc adm policy add-scc-to-group redis-enterprise-scc-v2 system:serviceaccounts:
```
Releases before 6.4.2-6 use the earlier version of the SCC, named `redis-enterprise-scc`.
1. Make sure you have DNS aliases for each database that resolve your API hostname ``,``, `` to the route IP address. To avoid entering multiple DNS records, you can use a wildcard in your alias (such as `*.ijk.example.com`).
1. If your cluster uses [OpenShift routes]({{< relref "/operate/kubernetes/7.22/networking/routes" >}}), add the following to the `spec` section of your Redis Enterprise cluster (REC) resource file.
```sh
activeActive:
apiIngressUrl:
dbIngressSuffix:
method: openShiftRoute
```
1. Make sure you have DNS aliases that resolve to the routes IP for both the API hostname (``) and the replication hostname (``) for each database. To avoid entering each database individually, you can use a wildcard in your alias (such as `*.ijk.example.com`).
1. After the changes are saved and applied, you can see that a new route was created for the API.
```sh
$ oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
rec01 api-openshift.apps.abc.example.com rec01 api passthrough None
```
## Create an Active-Active database with `crdb-cli`
The `crdb-cli` command can be run from any Redis Enterprise pod hosted on any participating K8s cluster. You'll need the values for the [required parameters]({{< relref "/operate/kubernetes/7.22/active-active/create-aa-crdb-cli#document-required-parameters" >}}) for each Redis Enterprise cluster.
```sh
crdb-cli crdb create \
--name \
--memory-size \
--encryption yes \
--instance fqdn=,url=https://,username=,password=,replication_endpoint=,replication_tls_sni= \
--instance fqdn=,url=https://,username=,password=,replication_endpoint=,replication_tls_sni=
```
To create a database that syncs between more than two instances, add additional `--instance` arguments.
See the [`crdb-cli` reference]({{< relref "/operate/rs/references/cli-utilities/crdb-cli" >}}) for more options.
## Test your database
The easiest way to test your Active-Active database is to set a key-value pair in one database and retrieve it from the other.
You can connect to your databases with the instructions in [Manage databases]({{< relref "/operate/kubernetes/7.22/re-databases/db-controller#connect-to-a-database" >}}). Set a test key with `SET foo bar` in the first database. If your Active-Active deployment is working properly, when connected to your second database, `GET foo` should output `bar`.