{
  "schema_version": 2,
  "id": "operate/kubernetes/re-databases/replica-redb",
  "title": "Create replica databases on Kubernetes",
  "url": "https://redis.io/docs/latest/operate/kubernetes/re-databases/replica-redb/",
  "summary": "How to create and automate database replicas using the database controller",
  "tags": [
    "docs",
    "operate",
    "kubernetes"
  ],
  "last_updated": "2026-09-28T16:14:52+01:00",
  "page_type": "content",
  "content_hash": "595209275f55dff40cc54fdd89999eb3b78797291f4bbb1b3828467269c4db4e",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "You can configure a replica of a database by creating an item in\nthe [`replicaSources`](https://redis.io/docs/latest/operate/kubernetes/reference/api/redis_enterprise_database_api#specreplicasources) section of the RedisEnterpriseDatabase (REDB) custom resource.\n\n> [!NOTE]\n> If the source cluster is reached through an ingress route (for example, an OpenShift route or any TLS pass-through that relies on SNI), set [`tlsSniName`](https://redis.io/docs/latest/operate/kubernetes/reference/api/redis_enterprise_database_api#specreplicasources) on each `replicaSources` item to the SNI hostname configured on the ingress. Without it, the syncer cannot route TLS to the source database's proxy and replication fails.\n\nA secret must be created with the `stringData` section containing the replica source URI as follows:\n\nCreate a secret with the replica source URI listed in the `stringData` field as follows:\n\n[code example]\n\nThe replica source URL can be retrieved by going to \"UI > database > configuration > Press the button Get Replica of source URL\"\nin the administrative UI. But, this information can also be retrieved directly from\nthe REST API as well.\n\nA replica of database CR simply uses the secret in the `replicaSources` section:\n\n[code example]\n\nIn the above, `name-of-replica` database will be created as a replica of the\nsource database as long as the source database exists on the source cluster\nand the secret contains the correct replica source URL for that database."
    },
    {
      "id": "retrieving-the-replica-source-url-via-kubectl",
      "title": "Retrieving the replica source URL via kubectl",
      "role": "content",
      "text": "You will need `kubectl`, `curl`, and `jq` installed for this procedure.\n\n1. Set your metadata:\n\n   [code example]\n\n1. Retrieve the cluster authentication:\n\n   [code example]\n\n1. Forward the port of the REST API service for your source cluster:\n\n   [code example]\n\n1. Request the information from the REST API:\n\n   [code example]\n\n   Note: URI now contains the replica source URI.\n\n1. Construct the secret for the replica:\n\n   [code example]\n\n1. Create the replica database:\n\n   [code example]"
    },
    {
      "id": "automating-the-creation-via-a-job",
      "title": "Automating the creation via a job",
      "role": "content",
      "text": "The following procedure uses a ConfigMap and a Job to construct the replica\nsource URL secret from the source database and configure the target database.\n\nThere are four parameters:\n\n- `source` - the name of the source database\n- `cluster` - the name of the cluster for the source database\n- `target` - the name of the target database\n- `targetCluster` - the name of the cluster for the target database\n\nThese parameters can be set by:\n\n[code example]\n\nwhere \"name-of-...\" is replaced with the database source, source cluster,\ndatabase target, and target cluster names.\n\nThe Job and ConfigMap below, when submitted, will create the secret and\nreplica database:\n\n[code example]"
    }
  ],
  "examples": [
    {
      "id": "overview-ex0",
      "language": "yaml",
      "code": "apiVersion: v1\nkind: Secret\nmetadata:\n   name: my-replica-source\nstringData:\n   uri: <replica-source-uri-goes-here>",
      "section_id": "overview"
    },
    {
      "id": "overview-ex1",
      "language": "yaml",
      "code": "apiVersion: app.redislabs.com/v1alpha1\nkind: RedisEnterpriseDatabase\nmetadata:\n   name: name-of-replica\nspec:\n   redisEnterpriseCluster:\n      name: name-of-cluster\n   replicaSources:\n   - replicaSourceType: SECRET\n     replicaSourceName: my-replica-source\n     # Required when the source cluster is reached via an ingress route\n     # tlsSniName: source-db.example.com",
      "section_id": "overview"
    },
    {
      "id": "retrieving-the-replica-source-url-via-kubectl-ex0",
      "language": "js",
      "code": "CLUSTER_NAME=test\n   SOURCE_DB=db1\n   TARGET_DB=db2\n   TARGET_CLUSTER_NAME=test",
      "section_id": "retrieving-the-replica-source-url-via-kubectl"
    },
    {
      "id": "retrieving-the-replica-source-url-via-kubectl-ex1",
      "language": "js",
      "code": "CLUSTER_USER=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.username | base64 -d`\n   CLUSTER_PASSWORD=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.password | base64 -d`",
      "section_id": "retrieving-the-replica-source-url-via-kubectl"
    },
    {
      "id": "retrieving-the-replica-source-url-via-kubectl-ex2",
      "language": "sh",
      "code": "kubectl port-forward pod/${CLUSTER_NAME}-0 9443",
      "section_id": "retrieving-the-replica-source-url-via-kubectl"
    },
    {
      "id": "retrieving-the-replica-source-url-via-kubectl-ex3",
      "language": "js",
      "code": "JQ='.[] | select(.name==\"'\n   JQ+=\"${SOURCE_DB}\"\n   JQ+='\") | (\"redis://admin:\" + .authentication_admin_pass + \"@\"+.name+\":\"+(.endpoints[0].port|tostring))'\n   URI=`curl -sf -k -u \"$CLUSTER_USER:$CLUSTER_PASSWORD\" \"https://localhost:9443/v1/bdbs?fields=uid,name,endpoints,authentication_admin_pass\" | jq \"$JQ\" | sed 's/\"//g'`",
      "section_id": "retrieving-the-replica-source-url-via-kubectl"
    },
    {
      "id": "retrieving-the-replica-source-url-via-kubectl-ex4",
      "language": "yaml",
      "code": "cat << EOF > secret.yaml\n   apiVersion: v1\n   kind: Secret\n   metadata:\n     name: ${SOURCE_DB}-url\n   stringData:\n     uri: ${URI}\n   EOF\n   kubectl apply -f secret.yaml",
      "section_id": "retrieving-the-replica-source-url-via-kubectl"
    },
    {
      "id": "retrieving-the-replica-source-url-via-kubectl-ex5",
      "language": "yaml",
      "code": "cat << EOF > target.yaml\n   apiVersion: app.redislabs.com/v1alpha1\n   kind: RedisEnterpriseDatabase\n   metadata:\n     name: ${TARGET_DB}\n   spec:\n     redisEnterpriseCluster:\n       name: ${TARGET_CLUSTER_NAME}\n     replicaSources:\n     - replicaSourceType: SECRET\n       replicaSourceName: ${SOURCE_DB}-url\n       # Required when the source cluster is reached via an ingress route\n       # tlsSniName: source-db.example.com\n   EOF\n   kubectl apply -f target.yaml",
      "section_id": "retrieving-the-replica-source-url-via-kubectl"
    },
    {
      "id": "automating-the-creation-via-a-job-ex0",
      "language": "sh",
      "code": "kubectl create configmap replica-of-database-parameters \\\n--from-literal=source=name-of-source \\\n--from-literal=cluster=name-of-cluster \\\n--from-literal=target=name-of-target \\\n--from-literal=targetCluster=name-of-cluster",
      "section_id": "automating-the-creation-via-a-job"
    },
    {
      "id": "automating-the-creation-via-a-job-ex1",
      "language": "yaml",
      "code": "apiVersion: batch/v1\nkind: Job\nmetadata:\n  name: replica-of-database\nspec:\n  backoffLimit: 4\n  template:\n    spec:\n      serviceAccountName: redis-enterprise-operator\n      restartPolicy: Never\n      volumes:\n        - name: scripts\n          configMap:\n            name: replica-of-database\n      containers:\n        - name: createdb\n          image: debian:stable-slim\n          env:\n            - name: MY_NAMESPACE\n              valueFrom:\n                fieldRef:\n                  fieldPath: metadata.namespace\n            - name: SCRIPT\n              value: create.sh\n            - name: SOURCE_DB\n              valueFrom:\n                configMapKeyRef:\n                  name: replica-of-database-parameters\n                  key: source\n            - name: TARGET_DB\n              valueFrom:\n                configMapKeyRef:\n                  name: replica-of-database-parameters\n                  key: target\n            - name: CLUSTER_SERVICE\n              value: .svc.cluster.local\n            - name: CLUSTER_NAME\n              valueFrom:\n                configMapKeyRef:\n                  name: replica-of-database-parameters\n                  key: cluster\n            - name: CLUSTER_PORT\n              value: \"9443\"\n            - name: TARGET_CLUSTER_NAME\n              valueFrom:\n                configMapKeyRef:\n                  name: replica-of-database-parameters\n                  key: targetCluster\n          volumeMounts:\n            - mountPath: /opt/scripts/\n              name: scripts\n          command:\n            - /bin/bash\n            - -c\n            - |\n              apt-get update; apt-get install -y curl jq apt-transport-https gnupg2\n              apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6A030B21BA07F4FB\n              curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -\n              echo \"deb https://apt.kubernetes.io/ kubernetes-xenial main\" | tee -a /etc/apt/sources.list.d/kubernetes.list\n              apt-get update\n              apt-get install -y kubectl\n              bash /opt/scripts/$SCRIPT\n---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: replica-of-database\ndata:\n  create.sh: |\n    CLUSTER_USER=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.username | base64 -d`\n    CLUSTER_PASSWORD=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.password | base64 -d`\n    CLUSTER_HOST=${CLUSTER_NAME}.${MY_NAMESPACE}${CLUSTER_SERVICE}\n    JQ='.[] | select(.name==\"'\n    JQ+=\"${SOURCE_DB}\"\n    JQ+='\") | (\"redis://admin:\" +  .authentication_admin_pass + \"@\"+.endpoints[0].dns_name+\":\"+(.endpoints[0].port|tostring))'\n    URI=`curl -sf -k -u \"$CLUSTER_USER:$CLUSTER_PASSWORD\" \"https://${CLUSTER_HOST}:${CLUSTER_PORT}/v1/bdbs?fields=uid,name,endpoints,authentication_admin_pass\" | jq \"$JQ\" | sed 's/\"//g'`\n    echo \"URL: ${URL}\"\n    echo \"\"\n    cat << EOF > /tmp/secret.yaml\n    apiVersion: v1\n    kind: Secret\n    metadata:\n      name: ${SOURCE_DB}-url\n    stringData:\n      uri: ${URI}\n    EOF\n    cat /tmp/secret.yaml\n    cat << EOF > /tmp/target.yaml\n    apiVersion: app.redislabs.com/v1alpha1\n    kind: RedisEnterpriseDatabase\n    metadata:\n      name: ${TARGET_DB}\n    spec:\n      redisEnterpriseCluster:\n        name: ${TARGET_CLUSTER_NAME}\n      replicaSources:\n      - replicaSourceType: SECRET\n        replicaSourceName: ${SOURCE_DB}-url\n        # Required when the source cluster is reached via an ingress route\n        # tlsSniName: source-db.example.com\n    EOF\n    echo \"---\"\n    cat /tmp/target.yaml\n    echo \"\"\n    kubectl -n ${MY_NAMESPACE} apply -f /tmp/secret.yaml\n    kubectl -n ${MY_NAMESPACE} apply -f /tmp/target.yaml",
      "section_id": "automating-the-creation-via-a-job"
    }
  ]
}
