CockroachDB es una base de datos SQL distribuida compatible con el protocolo de PostgreSQL. Replica cada rango de datos en varios nodos mediante el algoritmo de consenso Raft, de modo que el clúster sigue aceptando lecturas y escrituras aunque caiga un nodo, sin perder transacciones confirmadas. En este tutorial desplegarás un clúster seguro de tres nodos en Ubuntu 24.04 con certificados TLS y systemd, crearás una base de datos con su usuario y comprobarás que el clúster sobrevive a la caída de un nodo.
Requisitos previos
Para seguir esta guía necesitas:
- Tres servidores con Ubuntu 24.04 LTS (x86_64), por ejemplo tres VPS de CubePath, conectados por una red privada. En esta guía se usan las IP
10.0.0.11,10.0.0.12y10.0.0.13, que llamaremos nodo 1, nodo 2 y nodo 3. Sustitúyelas por las tuyas. - Un usuario no root con privilegios
sudoen cada servidor, y acceso SSH desde el nodo 1 a los otros dos. - Al menos 2 vCPU y 4 GB de RAM por nodo.
- Relojes sincronizados: CockroachDB detiene un nodo si su reloj se desvía demasiado del resto. Ubuntu 24.04 sincroniza la hora con
systemd-timesyncdpor defecto; compruébalo contimedatectl(debe indicarSystem clock synchronized: yes).
Importantedesde la versión 24.3, CockroachDB se distribuye con una licencia única que requiere una clave de licencia (existe una licencia Enterprise Free para empresas pequeñas y una de prueba). Sin clave, el clúster funciona durante un periodo de gracia y después se limita. Consulta las condiciones actuales en la web de Cockroach Labs antes de usarlo en producción.
Paso 1: Instalar el binario en los tres nodos
CockroachDB se distribuye como un binario único. Consulta la última versión estable en la página de releases de Cockroach Labs y guárdala en una variable. Ejecuta todo este paso en los tres nodos:
COCKROACH_VERSION=v25.3.2
curl -fsSLO "https://binaries.cockroachdb.com/cockroach-${COCKROACH_VERSION}.linux-amd64.tgz"
tar -xzf "cockroach-${COCKROACH_VERSION}.linux-amd64.tgz"
Copia el binario al PATH y las bibliotecas GEOS que usan las funciones espaciales al directorio donde CockroachDB las busca:
sudo cp "cockroach-${COCKROACH_VERSION}.linux-amd64/cockroach" /usr/local/bin/
sudo mkdir -p /usr/local/lib/cockroach
sudo cp "cockroach-${COCKROACH_VERSION}.linux-amd64/lib/"libgeos*.so /usr/local/lib/cockroach/
Verifica la instalación:
cockroach version
Build Tag: v25.3.2
Build Time: 2026/09/10 15:22:41
Distribution: CCL
Platform: linux amd64 (x86_64-pc-linux-gnu)
Crea un usuario de sistema sin shell para ejecutar el servicio y su directorio de datos:
sudo useradd --system --home-dir /var/lib/cockroach --shell /usr/sbin/nologin cockroach
sudo mkdir -p /var/lib/cockroach /etc/cockroach/certs
sudo chown -R cockroach:cockroach /var/lib/cockroach /etc/cockroach
sudo chmod 700 /etc/cockroach/certs
Paso 2: Abrir los puertos entre nodos
CockroachDB usa el puerto 26257 para el tráfico entre nodos y las conexiones SQL, y el 8080 para la consola web (DB Console). Permite ambos solo desde la red privada. Ejecuta en los tres nodos, adaptando la subred:
sudo ufw allow from 10.0.0.0/24 to any port 26257 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 8080 proto tcp
sudo ufw status
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
26257/tcp ALLOW 10.0.0.0/24
8080/tcp ALLOW 10.0.0.0/24
Paso 3: Generar los certificados TLS
Un clúster seguro necesita una autoridad certificadora (CA) propia, un certificado por nodo y un certificado de cliente para el usuario root. Genera todo en el nodo 1, dentro de tu directorio personal. La clave de la CA (ca.key) se guarda aparte y nunca se copia a los nodos:
mkdir -p ~/cockroach-ca ~/certs
cockroach cert create-ca --certs-dir="$HOME/certs" --ca-key="$HOME/cockroach-ca/ca.key"
Crea el certificado de cliente de root, que usarás para administrar el clúster desde el nodo 1:
cockroach cert create-client root --certs-dir="$HOME/certs" --ca-key="$HOME/cockroach-ca/ca.key"
Genera el certificado de cada nodo en un directorio propio. Cada certificado incluye la IP privada del nodo, localhost y 127.0.0.1:
for ip in 10.0.0.11 10.0.0.12 10.0.0.13; do
mkdir -p "$HOME/node-certs/$ip"
cp "$HOME/certs/ca.crt" "$HOME/node-certs/$ip/"
cockroach cert create-node "$ip" localhost 127.0.0.1 \
--certs-dir="$HOME/node-certs/$ip" --ca-key="$HOME/cockroach-ca/ca.key"
done
Comprueba que el directorio de cada nodo tiene la CA y su par de claves:
ls ~/node-certs/10.0.0.12
ca.crt node.crt node.key
Instala los certificados del nodo 1 en su ubicación definitiva:
sudo cp ~/node-certs/10.0.0.11/* /etc/cockroach/certs/
sudo chown cockroach:cockroach /etc/cockroach/certs/*
sudo chmod 600 /etc/cockroach/certs/node.key
Copia los certificados de los nodos 2 y 3 a sus servidores. Sustituye your_user por tu usuario:
scp ~/node-certs/10.0.0.12/* [email protected]:/tmp/
scp ~/node-certs/10.0.0.13/* [email protected]:/tmp/
En el nodo 2 y en el nodo 3, mueve los archivos a /etc/cockroach/certs con los permisos correctos:
sudo mv /tmp/ca.crt /tmp/node.crt /tmp/node.key /etc/cockroach/certs/
sudo chown cockroach:cockroach /etc/cockroach/certs/*
sudo chmod 600 /etc/cockroach/certs/node.key
Paso 4: Crear el servicio systemd
Crea la unidad en los tres nodos:
sudo nano /etc/systemd/system/cockroachdb.service
Pega el siguiente contenido. Cambia --advertise-addr por la IP privada del nodo en el que estás; --join es igual en todos:
[Unit]
Description=CockroachDB node
Requires=network-online.target
After=network-online.target
[Service]
Type=notify
User=cockroach
Group=cockroach
WorkingDirectory=/var/lib/cockroach
ExecStart=/usr/local/bin/cockroach start \
--certs-dir=/etc/cockroach/certs \
--store=/var/lib/cockroach/data \
--advertise-addr=10.0.0.11 \
--join=10.0.0.11,10.0.0.12,10.0.0.13 \
--cache=.25 \
--max-sql-memory=.25
TimeoutStopSec=300
Restart=always
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
--cache y --max-sql-memory reservan un 25 % de la RAM cada uno para la caché de almacenamiento y para las consultas, que es el valor recomendado para servidores dedicados a CockroachDB.
Recarga systemd y arranca el servicio en los tres nodos:
sudo systemctl daemon-reload
sudo systemctl enable --now cockroachdb
Como el clúster aún no está inicializado, los nodos arrancan y esperan. En el log verás un aviso de que el nodo aguarda a cockroach init:
sudo journalctl -u cockroachdb -n 5 --no-pager
... node has not been initialized; waiting for 'cockroach init' or join to an initialized cluster
Paso 5: Inicializar el clúster
Ejecuta cockroach init una única vez, desde el nodo 1, usando los certificados de cliente de root:
cockroach init --certs-dir="$HOME/certs" --host=10.0.0.11
Cluster successfully initialized
Comprueba que los tres nodos forman parte del clúster y están vivos:
cockroach node status --certs-dir="$HOME/certs" --host=10.0.0.11
id | address | sql_address | build | started_at | updated_at | locality | is_available | is_live
-----+-----------------+-----------------+----------+----------------------------+----------------------------+----------+--------------+----------
1 | 10.0.0.11:26257 | 10.0.0.11:26257 | v25.3.2 | 2026-09-25 10:14:02.3 UTC | 2026-09-25 10:15:11.8 UTC | | true | true
2 | 10.0.0.12:26257 | 10.0.0.12:26257 | v25.3.2 | 2026-09-25 10:14:03.1 UTC | 2026-09-25 10:15:12.4 UTC | | true | true
3 | 10.0.0.13:26257 | 10.0.0.13:26257 | v25.3.2 | 2026-09-25 10:14:03.7 UTC | 2026-09-25 10:15:12.9 UTC | | true | true
(3 rows)
Si tienes una clave de licencia, aplícala ahora desde una sesión SQL como root con SET CLUSTER SETTING enterprise.license = 'your_license_key';.
Paso 6: Crear una base de datos y un usuario
Abre la shell SQL como root:
cockroach sql --certs-dir="$HOME/certs" --host=10.0.0.11
Crea una base de datos, un usuario con contraseña para la aplicación y dale permisos sobre ella. Sustituye your_strong_password:
CREATE DATABASE shop;
CREATE USER app_user WITH PASSWORD 'your_strong_password';
GRANT ALL ON DATABASE shop TO app_user;
Crea una tabla. En CockroachDB conviene usar UUID generado con gen_random_uuid() como clave primaria en lugar de enteros secuenciales, porque las claves consecutivas concentran todas las escrituras en el mismo rango de datos:
USE shop;
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
customer STRING NOT NULL,
total DECIMAL(10,2) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
GRANT ALL ON TABLE orders TO app_user;
INSERT INTO orders (customer, total) VALUES ('ana', 59.90), ('luis', 120.00), ('marta', 15.50);
Revisa la configuración de replicación que se aplica a la base de datos. Por defecto, cada rango tiene 3 réplicas repartidas entre los nodos:
SHOW ZONE CONFIGURATION FROM DATABASE shop;
target | raw_config_sql
----------------+-------------------------------------------
RANGE default | ALTER RANGE default CONFIGURE ZONE USING
| range_min_bytes = 134217728,
| range_max_bytes = 536870912,
| gc.ttlseconds = 14400,
| num_replicas = 3,
| constraints = '[]',
| lease_preferences = '[]'
Sal con \q. Todas las transacciones de CockroachDB son SERIALIZABLE por defecto. Cuando dos transacciones chocan, una de ellas recibe un error de reintento (código 40001), así que tu aplicación debe reintentar la transacción en ese caso; los drivers de PostgreSQL y ORM habituales permiten hacerlo con un bucle sencillo.
Paso 7: Conectar desde una aplicación
Como CockroachDB habla el protocolo de PostgreSQL, puedes usar psql o cualquier driver de PostgreSQL. La cadena de conexión con verificación del certificado del servidor queda así:
postgresql://app_user:[email protected]:26257/shop?sslmode=verify-full&sslrootcert=/path/to/ca.crt
Copia ca.crt (nunca ca.key) al servidor de la aplicación. Para repartir la carga y no depender de un solo nodo, coloca delante un balanceador TCP como HAProxy que distribuya las conexiones entre los tres nodos en el puerto 26257.
Para verificarlo desde el nodo 1 con el cliente integrado:
cockroach sql --url "postgresql://[email protected]:26257/shop?sslmode=verify-full&sslrootcert=$HOME/certs/ca.crt" \
--execute "SELECT count(*) FROM orders;"
El cliente pedirá la contraseña y devolverá 3 aunque te conectes al nodo 2: todos los nodos sirven todos los datos.
Paso 8: Probar la tolerancia a fallos
Con 3 réplicas, el clúster tolera la caída de un nodo. Detén el servicio en el nodo 3:
sudo systemctl stop cockroachdb
Desde el nodo 1, escribe y lee datos:
cockroach sql --certs-dir="$HOME/certs" --host=10.0.0.11 --database=shop \
--execute "INSERT INTO orders (customer, total) VALUES ('pablo', 42.00);" \
--execute "SELECT count(*) FROM orders;"
INSERT 0 1
count
---------
4
(1 row)
cockroach node status mostrará el nodo 3 con is_live a false. Vuelve a arrancarlo:
sudo systemctl start cockroachdb
El nodo se reincorpora y recibe automáticamente los cambios que se perdió. Si un nodo permanece caído más de 5 minutos (valor de server.time_until_store_dead), el clúster crea réplicas nuevas en los nodos restantes cuando hay suficientes para ello.
Paso 9: Acceder a la consola web y hacer copias de seguridad
La DB Console muestra el estado de los nodos, la replicación y las consultas lentas. Para entrar necesitas un usuario SQL con contraseña y el rol admin. Crea uno desde la shell SQL como root:
CREATE USER dbadmin WITH PASSWORD 'your_admin_password';
GRANT admin TO dbadmin;
Como el puerto 8080 solo está abierto a la red privada, accede mediante un túnel SSH desde tu equipo:
ssh -L 8080:10.0.0.11:8080 your_user@your_server_ip
Después abre https://localhost:8080 en el navegador. El certificado lo firma tu CA propia, por lo que el navegador mostrará un aviso que puedes aceptar.
Para una copia de seguridad completa de la base de datos, usa BACKUP. El destino nodelocal://1 escribe en el directorio extern del almacén del nodo 1; en producción usa un bucket compatible con S3:
BACKUP DATABASE shop INTO 'nodelocal://1/backups';
SHOW BACKUPS IN 'nodelocal://1/backups';
Para restaurar, usa RESTORE DATABASE shop FROM LATEST IN 'nodelocal://1/backups'; después de eliminar o renombrar la base de datos existente.
Solución de problemas
x509: certificate is valid for ..., not 10.0.0.X: el certificado del nodo no incluye la IP o el nombre con el que te conectas. Regenera su certificado concockroach cert create-nodeañadiendo esa dirección y reinicia el servicio.- Un nodo se detiene con un error de reloj (
clock synchronization error): el reloj del nodo se ha desviado más de lo permitido. Revisatimedatectly la sincronización NTP. cockroach inittarda o falla: comprueba consudo ufw statusque el puerto 26257 está abierto entre los tres nodos y que--joincontiene las IP correctas.- El servicio no arranca por permisos:
node.keydebe pertenecer acockroachy tener permisos600, o CockroachDB lo rechaza.
Conclusión
Has desplegado un clúster seguro de CockroachDB con tres nodos en Ubuntu 24.04, con comunicación TLS, servicio systemd, un usuario de aplicación y copias de seguridad, y has comprobado que sigue funcionando al perder un nodo.
Como siguientes pasos, puedes:
- Poner HAProxy delante de los nodos (
cockroach gen haproxygenera una configuración de partida). - Programar copias de seguridad periódicas con
CREATE SCHEDULE FOR BACKUPhacia almacenamiento S3. - Añadir más nodos con el mismo
--joinpara aumentar capacidad; el clúster reequilibra los datos solo.
