Para este tutorial es necesario tener instalado docker en sus maquinas, en este tutorial se utilizó windows 10 con wsl ubuntu:18.04.
Se recomienta tener conocimientos en docker, Platzi tiene un curso de Docker que les ayudara.
1.Bajamos la imagen de postgres, en este caso se utilizó postgres alpine, es una version bastante liviana y es funcional para este caso:
dockerpullpostgres:alpine
2.Construimos los dos contenedores de postgres que necesitaremos (master y replica)
2.1.Contenedor de master
nombre del contenedor: postgres-db-master
contraseña: password-master
puerto: 5435
docker run -d --name postgres-db-master\
-ePOSTGRES_PASSWORD=password-master\
-p5435:5432 postgres:alpine
2.2.Contenedor de replica (slave)
nombre del contenedor: postgres-db-replica
contraseña: password-replica
puerto: 5434
docker run -d --name postgres-db-replica \
-e POSTGRES_PASSWORD=password-replica \
-p 5434:5432postgres:alpine
docker ps
En este punto tenemos dos contenedores de docker corriendo con postgres:alpine, cada uno exponiendo un puerto para poder acceder a él, tener presentes los puertos que definimos y las contraseñas tanto para master como para replica. En caso de que pierdan la información podemos verificarla con docker inspect <name-container>
Por ejemplo: podemos verificar el hostport y el password de master con los siguientes comandos:
docker inspect postgres-db-master -f'{{ json .NetworkSettings.Ports }}' | jq '.'
jq se utiliza para dar formato, lo podemos instalar con sudo apt install jq
docker inspect postgres-db-master -f'{{ json .Config.Env }}' | jq '.'
Lo mismo pueden hacer para replica remplazando el nombre del contenedor.
Conexion de master
Conexion de replica
Conexion exitosa:
5.1. Para acceder al contenedor de master utilizamos el siguiente comando:
docker exec -it postgres-db-masterbash
5.2. Modificamos con vi el archivo postgresql.conf tal como el profesor explico en la clase pero en este caso en un contenedor de docker.
vi var/lib/postgresql/data/postgresql.conf
Debera abrirse el editor de vi:
Con las flechas bajamos y realizamos las siguientes modificaciones:
Para salir del editor y guardar los cambios presionamos Esc y luego shift + z + z
5.3. Ahora debemos permitir la conexión remota entre master y replica. Para esto debemos añadir la ip de replica en la lista de servicios permitidos en master, esto para evitar que la base de datos replica tenga que autenticarse. Añadirmos la ip en el archivo pg_hba.conf. Para editarlo usamos el siguiente comando:
vi var/lib/postgresql/data/pg_hba.conf
Debera abrirse el editor de vi:
Con las flechas bajamos y añadimos la ip de replica:
Esta ip la podemos verificar con docker inspect (podemos abrir otra consola para hacer le inspect):
docker network inspect bridge -f'{{json .Containers}}' | jq '.'
bridge es la red a donde por defecto se conectan los contenedores y podemos verificarla con:
docker network ls
En caso de que quieran ver todo el inspect de la red bridge lo pueden hacer con:
docker network inspect bridge
5.4. Ahora debemos reiniciar el contenedor de master, previamente debemos salir de la consola interactiva escribiendo exit.
docker restart postgres-db-master
6.1. Debemos copiar toda la información de master en replica, de modo que las dos esten identicas, y luego la iniciamos en modo slave.
Es importante que los siguientes dos comandos se ejecuten rapidamente uno seguido del otro, ya que si no el contenedor se va a caer. Por lo que recomiendo tener ambos comandos a la mano.
En caso de que se caiga el contenedor lo que deben hacer es reiniciar el contenedor nuevamente (docker restart postgres-db-replica), acceder en forma interactiva (docker exec -it postgres-db-replica bash) e intentar de nuevo el borrado y copiado.
Antes de copiar tenemos que borrar lo que hay en el directorio /var/lib/postgresql/data/*, si no borramos nos saldra un error diciendo que la el directorio no esta vacio.
rm -rf /var/lib/postgresql/data/*
Luego realizamos el copiado con el siguiente comando, aqui debemos definir el gateway de la red donde estan conectados los contenedores (master y replica) y el puerto de master:
pg_basebackup -U postgres -R -D /var/lib/postgresql/data/ \
--host=172.17.0.1 --port=5435
El backslash indica solamente salto de linea.
Para verificar el gateway podemos hacerle un inspect a bridge o usar el siguiente comando:
docker network inspect bridge -f'{{json .IPAM.Config}}' | jq '.'
6.2. Una vez copiados los datos desde master a replica, necesitamos configurar replica para que funcione como slave, para esto entramos a editar postgresql.conf y ponemos en on el parametro hot_standby
vi var/lib/postgresql/data/postgresql.conf
Nuevamente para salir del editor y guardar los cambios presionamos Esc y luego shift + z + z
En este punto hemos configurado las dos bases de datos como maestro-esclavo, para comprobarlo regresamos a pgadmin nos desconectamos del server de replica,
y nos conectamos de nuevo,
tal como esperabamos ya que hemos copiado toda la configuración de master a replica por lo que la contraseña de replica ahora es la misma de master.
7.1 Si lo intentamos desde master, nos debe permitir crear la base de datos y adicionalmente la base de datos debe aparecer en replica.
Espero les sirva de ayuda este tutorial.
Mil millones de graciasjsneider05, gracias a tu tutorial pude hacer el ejercicio de replicación de dbs con docker.
Debo añadir que estuve muchas horas atascado con el siguiente error justo al momento de ejecutar el
pg_basebackup
.ERROR
pg_basebackup:error:FATAL: no pg_hba.conf entry for replication connection from host "172.17.0.1", user "postgres", SSL off
Si a alguien más le ocurre, lo que sucede es que (tal como lo dice el error) el usuario postgres no tiene derechos de replication sobre el servidor master.
Así que el problema (guiandome por ej ejemplo de jsneider) está en esta linea de archivo pg_hba.conf
En la columna ‘user’ hay que agregar el usuario ‘postgres’ de esta forma:
host replication postgres 172.17.0.3/16 trust
He visto que muchas personas crean un usuario llamado ‘replicator’ le dan derechos de REPLICATION y lo usan en vez del usuario postgres, pero ya que el profesor lo usó así, queria seguir con la dinamica.
Luché mucho con el problema porque en teoría el usuario postgres tiene el poder de hacer lo que quiera y sí es así, pero en este caso hay que se más explicito.
Tengo aún una duda que no logué responder
¿Por qué debemos usar el GATEWAY de la red para traernos la información del contenerdor maestro? ¿Porqué no podemos conectarnos directamente?, lo pregunto porque no se puede hacer directamente, sale este error:
//Command pg_basebackup -U postgres -R-D /var/lib/postgresql/data/ --host=172.17.0.2 --port=5450// Error pg_basebackup: error: could not connect to server: Connection refused Is the server running on host "172.17.0.2"and accepting TCP/IP connections on port 5450? //Pd: Ya verifiqué que el todo esté corriendo bien y que host y el puerto son correctos y aún así no funciona, solo funciona si pongo la IP del gateway.
Gracias de antemano.
https://www.youtube.com/watch?v=5BeC1aD4z8E En este video realizan la replicación de otra forma, básicamente lo que hacen es que en lugar de usar el comando
pg_basebackup
para copiar los datos de una dbs a otra, lo hacen manualmente con la ayuda de ‘bind mount’ de docker, es muy interesante porque así podemos entender un poco mejor como es que funciona el proceso de copiado por debajo y es bastante sencillo.Hola, existe alguna otra forma de eliminar el directorio y colocar el siguiente comando, lo hago lo más rápido posible siempre, pero mi Contenedor se reinicia y me saca de la sesión y después ya no permite ingresar.
Todo muy bien, aprendí demasiado jaja
Genial! Me resirvió, aprendí bastante jeje, tuve que tomar el curso de docker para entender todo esto. Muchas gracias por el aporte
Excelente tuto, solo un detalle al borrar la ‘data’ y copiar la de ‘master’, el contenedor se me cayo despues de copiar, pero al reiniciarlo y continuar con los pasos pude seguir con el tutorial.
Necesito aprender Docker
No sé si esto funciona, sin embargo, reconozco el esfuerzo de la implementación con Docker del compañero y por otra parte siento que se aleja de los objetivos del Curso de PostgreSQL en cuanto a la manera de implementarlo. Por otro lado pienso que el contenido del mismo en cuanto a las replicas no esta a la altura.
Muchas gracias por el aporte de como implementar replicas con Docker. Por otro lado pienso que el compañero perezgarridogilb no entendio el objetivo del tutorial, lo invito a que nos comparta como seria un contenido que este a la altura o a aportar sobre este ya existente.
Me refería al contenido del curso por estar desactualizado, no al del aporte del compañero
Excelente, gracias @jsneider05
👍
Todo esta muy bien explicado. Era justo lo que necesitaba
¡Excelente aporte! Muchas gracias portomarte el tiempo de compartirlo