sql >> Base de Datos >  >> RDS >> PostgreSQL

Implementación de PostgreSQL en un contenedor Docker

Introducción

Docker modernizó la forma en que construimos e implementamos la aplicación. Nos permite crear contenedores livianos, portátiles y autosuficientes que pueden ejecutar cualquier aplicación fácilmente.

Este blog pretendía explicar cómo usar Docker para ejecutar la base de datos PostgreSQL. No cubre la instalación o configuración de Docker. Consulte las instrucciones de instalación de la ventana acoplable aquí. Se pueden encontrar algunos antecedentes adicionales en nuestro blog anterior sobre MySQL y Docker.

Antes de entrar en detalles, repasemos algo de terminología.

  • Dockerfile
    Contiene el conjunto de instrucciones/comandos para instalar o configurar la aplicación/software.
  • Imagen acoplable
    La imagen de Docker se crea a partir de una serie de capas que representan instrucciones del Dockerfile. La imagen de Docker se utiliza como plantilla para crear un contenedor.
  • Enlace de contenedores y redes definidas por el usuario
    Docker usó el puente como un mecanismo de red predeterminado y usó --links para vincular los contenedores entre sí. Para acceder al contenedor de PostgreSQL desde un contenedor de aplicación, se deben vincular ambos contenedores en el momento de la creación. Aquí, en este artículo, estamos utilizando redes definidas por el usuario, ya que la función de enlace pronto quedará obsoleta.
  • Persistencia de datos en Docker
    De forma predeterminada, los datos dentro de un contenedor son efímeros. Siempre que se reinicie el contenedor, se perderán los datos. Los volúmenes son el mecanismo preferido para conservar los datos generados y utilizados por un contenedor Docker. Aquí, estamos montando un directorio de host dentro del contenedor donde se almacenan todos los datos.

Comencemos a construir nuestra imagen PostgreSQL y usarla para ejecutar un contenedor.

Archivo Docker de PostgreSQL

# example Dockerfile for https://docs.docker.com/engine/examples/postgresql_service/


FROM ubuntu:14.04

# Add the PostgreSQL PGP key to verify their Debian packages.
# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8

# Add PostgreSQL's repository. It contains the most recent stable release
#     of PostgreSQL, ``9.3``.
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list

# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3
#  There are some warnings (in red) that show up during the build. You can hide
#  them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y python-software-properties software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3

# Note: The official Debian and Ubuntu images automatically ``apt-get clean``
# after each ``apt-get``

# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was ``apt-get installed``
USER postgres

# Create a PostgreSQL role named ``postgresondocker`` with ``postgresondocker`` as the password and
# then create a database `postgresondocker` owned by the ``postgresondocker`` role.
# Note: here we use ``&&\`` to run commands one after the other - the ``\``
#       allows the RUN command to span multiple lines.
RUN    /etc/init.d/postgresql start &&\
    psql --command "CREATE USER postgresondocker WITH SUPERUSER PASSWORD 'postgresondocker';" &&\
    createdb -O postgresondocker postgresondocker

# Adjust PostgreSQL configuration so that remote connections to the
# database are possible.
RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf

# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf

# Expose the PostgreSQL port
EXPOSE 5432

# Add VOLUMEs to allow backup of config, logs and databases
VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

# Set the default command to run when starting the container
CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

Si observa detenidamente el Dockerfile, consta de comandos que se utilizan para instalar PostgreSQL y realizar algunos cambios de configuración en el sistema operativo ubuntu.

Creación de una imagen de PostgreSQL

Podemos construir una imagen PostgreSQL desde Dockerfile usando el comando docker build.

# sudo docker build -t postgresondocker:9.3 .

Aquí, podemos especificar la etiqueta (-t) a la imagen como nombre y versión. El punto (.) al final especifica el directorio actual y utiliza el Dockerfile presente en el directorio actual. El nombre del archivo Docker debe ser "Dockerfile". Si desea especificar un nombre personalizado para su archivo docker, debe usar -f en el comando de compilación docker.

# sudo docker build -t postgresondocker:9.3 -f <your_docker_file_name>

Salida:(si es posible, use la ventana de texto de la barra de desplazamiento opcional)

Sending build context to Docker daemon  4.096kB
Step 1/11 : FROM ubuntu:14.04
14.04: Pulling from library/ubuntu
324d088ce065: Pull complete 
2ab951b6c615: Pull complete 
9b01635313e2: Pull complete 
04510b914a6c: Pull complete 
83ab617df7b4: Pull complete 
Digest: sha256:b8855dc848e2622653ab557d1ce2f4c34218a9380cceaa51ced85c5f3c8eb201
Status: Downloaded newer image for ubuntu:14.04
 ---> 8cef1fa16c77
Step 2/11 : RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
 ---> Running in ba933d07e226
.
.
.
fixing permissions on existing directory /var/lib/postgresql/9.3/main ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
creating configuration files ... ok
creating template1 database in /var/lib/postgresql/9.3/main/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating collations ... ok
creating conversions ... ok
creating dictionaries ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
loading PL/pgSQL server-side language ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok
syncing data to disk ... ok

Success. You can now start the database server using:

    /usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main
or
    /usr/lib/postgresql/9.3/bin/pg_ctl -D /var/lib/postgresql/9.3/main -l logfile start

Ver Cluster Port Status Owner    Data directory               Log file
9.3 main    5432 down   postgres /var/lib/postgresql/9.3/main /var/log/postgresql/postgresql-9.3-main.log
update-alternatives: using /usr/share/postgresql/9.3/man/man1/postmaster.1.gz to provide /usr/share/man/man1/postmaster.1.gz (postmaster.1.gz) in auto mode
invoke-rc.d: policy-rc.d denied execution of start.
Setting up postgresql-contrib-9.3 (9.3.22-0ubuntu0.14.04) ...
Setting up python-software-properties (0.92.37.8) ...
Setting up python3-software-properties (0.92.37.8) ...
Setting up software-properties-common (0.92.37.8) ...
Processing triggers for libc-bin (2.19-0ubuntu6.14) ...
Processing triggers for ca-certificates (20170717~14.04.1) ...
Updating certificates in /etc/ssl/certs... 148 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
Removing intermediate container fce692f180bf
 ---> 9690b681044b
Step 5/11 : USER postgres
 ---> Running in ff8864c1147d
Removing intermediate container ff8864c1147d
 ---> 1f669efeadfa
Step 6/11 : RUN    /etc/init.d/postgresql start &&    psql --command "CREATE USER postgresondocker WITH SUPERUSER PASSWORD 'postgresondocker';" &&    createdb -O postgresondocker postgresondocker
 ---> Running in 79042024b5e8
 * Starting PostgreSQL 9.3 database server
   ...done.
CREATE ROLE
Removing intermediate container 79042024b5e8
 ---> 70c43a9dd5ab
Step 7/11 : RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf
 ---> Running in c4d03857cdb9
Removing intermediate container c4d03857cdb9
 ---> 0cc2ed249aab
Step 8/11 : RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
 ---> Running in fde0f721c846
Removing intermediate container fde0f721c846
 ---> 78263aef9a56
Step 9/11 : EXPOSE 5432
 ---> Running in a765f854a274
Removing intermediate container a765f854a274
 ---> d205f9208162
Step 10/11 : VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
 ---> Running in ae0b9f30f3d0
Removing intermediate container ae0b9f30f3d0
 ---> 0de941f8687c
Step 11/11 : CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
 ---> Running in 976d283ea64c
Removing intermediate container 976d283ea64c
 ---> 253ee676278f
Successfully built 253ee676278f
Successfully tagged postgresondocker:9.3

Creación de redes de contenedores

Use el siguiente comando para crear una red definida por el usuario con un controlador de puente.

# sudo docker network create --driver bridge postgres-network

Confirmar creación de red

# sudo docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a553e5727617        bridge              bridge              local
0c6e40305851        host                host                local
4cca2679d3c0        none                null                local
83b23e0af641        postgres-network    bridge              local

Creación de contenedores

Necesitamos usar el comando "docker run" para crear un contenedor a partir de la imagen de la ventana acoplable. Estamos ejecutando el contenedor postgres en modo daemonize con la ayuda de la opción -d.

# sudo docker run --name postgresondocker --network postgres-network -d postgresondocker:9.3

Use el siguiente comando para confirmar la creación del contenedor.

# sudo docker container ls 
CONTAINER ID        IMAGE                  COMMAND                  CREATED              STATUS              PORTS               NAMES
06a5125f5e11        postgresondocker:9.3   "/usr/lib/postgresql…"   About a minute ago   Up About a minute   5432/tcp            postgresondocker

No hemos especificado ningún puerto para exponer, por lo que expondrá el puerto postgres predeterminado 5432 para uso interno. PostgreSQL solo está disponible desde dentro de la red de Docker, no podremos acceder a este contenedor de Postgres en un puerto de host.

Veremos cómo acceder al contenedor de Postgres en el puerto del host en una sección posterior de este artículo.

Conexión al contenedor PostgreSQL dentro de la red Docker

Intentemos conectarnos al contenedor de Postgres desde otro contenedor dentro de la misma red Docker que creamos anteriormente. Aquí, hemos utilizado el cliente psql para conectarnos a Postgres. Utilizamos el nombre del contenedor de Postgres como nombre de host, usuario y contraseña presentes en el archivo Docker.

# docker run -it --rm --network postgres-network postgresondocker:9.3 psql -h postgresondocker -U postgresondocker --password
Password for user postgresondocker: 
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.

postgresondocker=# 

La opción --rm en el comando de ejecución eliminará el contenedor una vez que finalicemos el proceso psql.

# sudo docker container ls 
CONTAINER ID        IMAGE                  COMMAND                  CREATED              STATUS              PORTS               NAMES
2fd91685d1ea        postgresondocker:9.3   "psql -h postgresond…"   29 seconds ago       Up 30 seconds       5432/tcp            brave_spence
06a5125f5e11        postgresondocker:9.3   "/usr/lib/postgresql…"   About a minute ago   Up About a minute   5432/tcp            postgresondocker

Persistencia de datos

Los contenedores Docker son de naturaleza efímera, es decir, los datos que utiliza o genera el contenedor no se almacenan implícitamente en ningún lugar. Perdemos los datos cada vez que el contenedor se reinicia o elimina. Docker proporciona volúmenes en los que podemos almacenar los datos persistentes. Es una función útil mediante la cual podemos aprovisionar otro contenedor utilizando el mismo volumen o datos en caso de desastre.

Creemos un volumen de datos y confirmemos su creación.

# sudo docker volume create pgdata
pgdata

# sudo docker volume ls
DRIVER              VOLUME NAME
local                   pgdata

Ahora tenemos que usar este volumen de datos mientras ejecutamos el contenedor de Postgres. Asegúrese de eliminar el contenedor de postgres anterior que se está ejecutando sin volúmenes.

# sudo docker container rm postgresondocker -f 
postgresondocker

# sudo docker run --name postgresondocker --network postgres-network -v pgdata:/var/lib/postgresql/9.3/main -d postgresondocker:9.3

Ejecutamos el contenedor de Postgres con un volumen de datos adjunto.

Cree una nueva tabla en Postgres para comprobar la persistencia de los datos.

# docker run -it --rm --network postgres-network postgresondocker:9.3 psql -h postgresondocker -U postgresondocker --password
Password for user postgresondocker: 
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.

postgresondocker=# \dt
No relations found.
postgresondocker=# create table test(id int);
CREATE TABLE
postgresondocker=# \dt 
            List of relations
 Schema | Name | Type  |      Owner       
--------+------+-------+------------------
 public | test | table | postgresondocker
(1 row)

Elimine el contenedor de Postgres.

# sudo docker container rm postgresondocker -f 
postgresondocker

Cree un nuevo contenedor de Postgres y confirme si la tabla de prueba está presente o no.

# sudo docker run --name postgresondocker --network postgres-network -v pgdata:/var/lib/postgresql/9.3/main -d postgresondocker:9.3


# docker run -it --rm --network postgres-network postgresondocker:9.3 psql -h postgresondocker -U postgresondocker --password
Password for user postgresondocker: 
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.

postgresondocker=# \dt
            List of relations
 Schema | Name | Type  |      Owner       
--------+------+-------+------------------
 public | test | table | postgresondocker
(1 row)
Descargue el documento técnico hoy Administración y automatización de PostgreSQL con ClusterControlObtenga información sobre lo que necesita saber para implementar, monitorear, administrar y escalar PostgreSQLDescargar el documento técnico

Exponer el servicio PostgreSQL al host

Es posible que haya notado que no hemos expuesto ningún puerto del contenedor de PostgreSQL anteriormente. Esto significa que PostgreSQL solo es accesible para los contenedores que están en la red postgres que creamos anteriormente.

Para usar el servicio PostgreSQL, necesitamos exponer el puerto del contenedor usando la opción --port. Aquí, hemos expuesto el puerto 5432 del contenedor de Postgres en el puerto 5432 del host.

# sudo docker run --name postgresondocker --network postgres-network -v pgdata:/var/lib/postgresql/9.3/main -p 5432:5432 -d postgresondocker:9.3
# sudo docker container ls
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
997580c86188        postgresondocker:9.3   "/usr/lib/postgresql…"   8 seconds ago       Up 10 seconds       0.0.0.0:5432->5432/tcp   postgresondocker

Ahora puede conectar PostgreSQL en localhost directamente.

# psql -h localhost -U postgresondocker --password
Password for user postgresondocker: 
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.

postgresondocker=#

Eliminación de contenedores

Para eliminar el contenedor, primero debemos detener el contenedor en ejecución y luego eliminar el contenedor usando el comando rm.

# sudo docker container stop postgresondocker 

# sudo docker container rm postgresondocker
postgresondocker

Utilice la opción -f (--force) para eliminar directamente el contenedor en ejecución.

# sudo docker container rm postgresondocker -f
postgresondocker

Con suerte, ahora tiene su propio entorno local dockerizado para PostgreSQL.

Nota: Este artículo proporciona una descripción general sobre cómo podemos usar PostgreSQL en Docker para el entorno de desarrollo/POC. La ejecución de PostgreSQL en un entorno de producción puede requerir cambios adicionales en las configuraciones de PostgreSQL o Docker.

Conclusión

Existe una forma sencilla de ejecutar la base de datos PostgreSQL dentro de un contenedor Docker. Docker encapsula efectivamente la implementación, la configuración y ciertos procedimientos de administración. Docker es una buena opción para implementar PostgreSQL con el mínimo esfuerzo. Todo lo que necesita hacer es iniciar un contenedor Docker preconstruido y tendrá una base de datos PostgreSQL lista para su servicio.

Referencias

  • Instalación de Docker:https://docs.docker.com/install
  • Volúmenes:https://docs.docker.com/storage/volumes
  • Redes definidas por el usuario:https://docs.docker.com/network/
  • Archivo Docker de Postgres:https://docs.docker.com/engine/examples/postgresql_service
  • MySQL en Docker:comprensión de los conceptos básicos:https://severalnines.com/blog/mysql-docker-containers-understanding-basics