Rafael Ugolini es un desarrollador de software de pila completa con sede en Bruselas, Bélgica. Él trabaja en el desarrollo de software desde hace más de 10 años y últimamente se centra en el diseño de soluciones web y desarrollando utilizando Python y JavaScript. Rafael Ugolini es desarrollador de software sénior en Famoco.
Introducción
Docker es un gran proyecto que está ayudando a desarrolladores de todo el mundo a ejecutar aplicaciones en contenedores. Esto no sólo ayuda a enviar software más rápido, sino que también resulta en la famosa frase "funciona en mi máquina". En este artículo voy a explicar cómo crear una imagen modular de Couchbase que no requiere ninguna interacción Web UI para tener una base de datos lista para usar por ti.
Todo el código está disponible en línea aquí.
Dockerfile
El primer paso es crear el Dockerfile.
Versión de Couchbase
|
1 |
FROM couchbase/server:enterprise-4.6.1 |
Este ejemplo está basado en Couchbase Server Enterprise 4.6.1, pero puedes cambiar a la versión específica que estés ejecutando en tu entorno.
Configuración de la memoria
|
1 2 3 |
ENV MEMORY_QUOTA 256 ENV INDEX_MEMORY_QUOTA 256 ENV FTS_MEMORY_QUOTA 256 |
Todos los valores están en MB:
- MEMORY_QUOTA: cuota de ram del servicio de datos por nodo
- INDEX_MEMORY_QUOTA: cuota de ram del servicio de índices por nodo
- FTS_MEMORY_QUOTA: cuota de memoria ram por nodo del servicio de índices
Servicios
|
1 |
ENV SERVICES "kv,n1ql,index,fts" |
Estos son los servicios que estarán disponibles para el nodo creado:
- kv: Datos
- n1ql: Consulta
- índice: Índice
- fts: Búsqueda de texto completo
Credenciales
|
1 2 |
ENV USERNAME "Administrator" ENV PASSWORD "password" |
Nombre de usuario y contraseña a utilizar en Couchbase Server.
Opciones de clúster
|
1 2 |
ENV CLUSTER_HOST "" ENV CLUSTER_REBALANCE "" |
Estas opciones sólo se utilizan si desea añadir más de un nodo en el clúster.
- CLUSTER_HOST: nombre de host del cluster al que se unirá este nodo
- CLUSTER_REBALANCE: establece "true" si quieres que el cluster se reequilibre después de que el nodo se una.
Punto de entrada
|
1 2 3 |
COPY entrypoint.sh /config-entrypoint.sh ENTRYPOINT ["/config-entrypoint.sh"] |
La imagen de Couchbase Server ya viene con un script entrypoint.sh y no queremos sobreescribirlo. El truco aquí es copiar nuestra versión de entrypoint.sh a /config-entrypoint.sh, ejecutar Couchbase Server entrypoint.sh en segundo plano, y después de configurar el nodo adjuntar el script de nuevo al original PUNTO DE ENTRADA.
Punto de entrada
En PUNTO DE ENTRADA se utiliza en combinación con el script original de la imagen de Couchbase Server. Vamos a ir línea por línea para entender cómo funciona.
Inicializar Couchbase Server
|
1 2 3 4 |
# Monitor mode (used to attach into couchbase entrypoint) set -m # Send it to background /entrypoint.sh couchbase-server & |
En primer lugar utilizamos set -m para activar el control de trabajos, proceso que se ejecuta en segundo plano (como el original PUNTO DE ENTRADA) se ejecutan en un grupo de procesos separado. Esta opción está desactivada por defecto en modo no interactivo, como los scripts.
Funciones útiles
|
1 2 3 4 5 |
# Check if couchbase server is up check_db() { curl --silent https://127.0.0.1:8091/pools > /dev/null echo $? } |
Esta función se utiliza para comprobar cuando Couchbase Server comienza a responder llamadas HTTP.
|
1 2 3 4 5 6 7 |
# Variable used in echo i=1 # Echo with numbered_echo() { echo "[$i] $@" i=`expr $i + 1` } |
Esto es sólo una función util, añade un número antes de cualquier eco en el script para contar los pasos dados automáticamente.
|
1 2 3 4 5 6 7 8 |
# Parse JSON and get nodes from the cluster read_nodes() { cmd="import sys,json;" cmd="${cmd} print(','.join([node['otpNode']" cmd="${cmd} for node in json.load(sys.stdin)['nodes']" cmd="${cmd} ]))" python -c "${cmd}" } |
Con el fin de analizar la salida de los nodos en Couchbase Server API, estoy usando una función que se ejecuta ython para leer STDINtransformarlo a JSON y a los nodos Couchbase. Esto se utiliza para el reequilibrio.
Configurar el nodo
|
1 2 3 4 5 6 7 8 |
# Wait until it's ready until [[ $(check_db) = 0 ]]; do >&2 numbered_echo "Waiting for Couchbase Server to be available" sleep 1 done echo "# Couchbase Server Online" echo "# Starting setup process" |
El primer paso consiste en esperar a que el servidor esté listo y, a continuación, utilizar la función eco_numerado puedes ver cuánto tardó Couchbase Server en tener disponibles las llamadas a la API.
|
1 2 3 4 |
HOSTNAME=`hostname -f` # Reset steps i=1 |
A continuación, establecemos una variable NOMBRE HOST que se utilizará en todas las llamadas a la API que hagamos y también ponemos a cero el contador de eco_numerado poniéndolo a 1.
|
1 2 3 4 5 6 7 8 |
numbered_echo "Initialize the node" curl --silent "https://${HOSTNAME}:8091/nodes/self/controller/settings" \ -d path="/opt/couchbase/var/lib/couchbase/data" \ -d index_path="/opt/couchbase/var/lib/couchbase/data" numbered_echo "Setting hostname" curl --silent "https://${HOSTNAME}:8091/node/controller/rename" \ -d hostname=${HOSTNAME} |
Lo primero que hay que hacer es establecer la configuración de almacenamiento en disco y luego establecemos el nombre de host.
Unirse a un clúster
|
1 2 3 4 5 6 7 8 |
if [[ ${CLUSTER_HOST} ]];then numbered_echo "Joining cluster ${CLUSTER_HOST}" curl --silent -u ${USERNAME}:${PASSWORD} \ "https://${CLUSTER_HOST}:8091/controller/addNode" \ -d hostname="${HOSTNAME}" \ -d user="${USERNAME}" \ -d password="${PASSWORD}" \ -d services="${SERVICES}" > /dev/null |
Si CLUSTER_HOST el script intentará añadir el archivo contenedor al clúster.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
if [[ ${CLUSTER_REBALANCE} ]]; then # "Unexpected server error without the sleep 2 sleep 2 numbered_echo "Retrieving nodes" known_nodes=$( curl --silent -u ${USERNAME}:${PASSWORD} https://${CLUSTER_HOST}:8091/pools/default | read_nodes ) numbered_echo "Rebalancing cluster" curl -u ${USERNAME}:${PASSWORD} \ "https://${CLUSTER_HOST}:8091/controller/rebalance" \ -d knownNodes="${known_nodes}" fi else |
Después de añadir el nodo al cluster, el script también puede comprobar la variable CLUSTER_REBALANCE para ver si necesita reequilibrar el cluster automáticamente. Aquí es donde usamos la función de Python para leer los nodos de /pools/default punto final.
No unirse a un clúster
|
1 2 3 4 5 |
numbered_echo "Setting up memory" curl --silent "https://${HOSTNAME}:8091/pools/default" \ -d memoryQuota=${MEMORY_QUOTA} \ -d indexMemoryQuota=${INDEX_MEMORY_QUOTA} \ -d ftsMemoryQuota=${FTS_MEMORY_QUOTA} |
Ajustes de memoria para los servicios.
|
1 2 3 |
numbered_echo "Setting up services" curl --silent "https://${HOSTNAME}:8091/node/controller/setupServices" \ -d services="${SERVICES}" |
Servicios que utilizará el nodo.
|
1 2 3 4 5 6 7 |
numbered_echo "Setting up user credentials" curl --silent "https://${HOSTNAME}:8091/settings/web" \ -d port=8091 \ -d username=${USERNAME} \ -d password=${PASSWORD} > /dev/null fi |
Configure las credenciales para el nodo.
Finalizar
|
1 2 3 |
# Attach to couchbase entrypoint numbered_echo "Attaching to couchbase-server entrypoint" fg 1 |
Para finalizar el script, lo adjuntamos al original PUNTO DE ENTRADA.
Ejemplo
Para demostrar cómo utilizarlo, utilizaré la imagen registrada en Centro Docker con el código aquí.
Nodo único
|
1 2 3 4 5 6 7 |
docker run -ti --name couchbase-server-nosetup \ -h node1.cluster \ -p 8091-8093:8091-8093 \ -p 11210:11210 \ -p 4369:4369 \ -p 21100-21299:21100-21299 \ rugolini/couchbase-server-nosetup |
Esto ejecuta un único nodo utilizando la memoria mínima requerida y las credenciales por defecto (Administrador/contraseña) registrados en la imagen. Todos los puertos de red Servidor Couchbase usos también están expuestos.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
docker run -ti --name couchbase-server-nosetup \ -h node1.cluster \ -p 8091-8093:8091-8093 \ -p 11210:11210 \ -p 4369:4369 \ -e MEMORY_QUOTA=512 \ -e INDEX_MEMORY_QUOTA=512 \ -e FTS_MEMORY_QUOTA=512 \ -e USERNAME=admin \ -e PASSWORD=adminadmin \ -p 21100-21299:21100-21299 \ rugolini/couchbase-server-nosetup |
El comando anterior juega un poco con las variables de entorno disponibles en el Dockerfile.
Grupo
En este ejemplo, conectaremos 3 nodos en el cluster.
|
1 |
docker network create couchbase |
Primero debemos crear una red Couchbase donde conectaremos todos los nodos.
|
1 2 3 4 5 6 7 8 |
docker run -ti --name node1.cluster \ -p 8091-8093:8091-8093 \ -p 11210:11210 \ -p 4369:4369 \ -p 21100-21299:21100-21299 \ -h node1.cluster \ --network=couchbase \ rugolini/couchbase-server-nosetup |
A continuación, creamos el primer nodo.
|
1 2 3 4 5 6 |
docker run -ti --name node2.cluster \ --network=couchbase \ -h node2.cluster \ -e CLUSTER_HOST=node1.cluster \ -e CLUSTER_REBALANCE=true \ rugolini/couchbase-server-nosetup |
Dado que todos los puertos de red están expuestos en el primer nodo, no es necesario exponerlos aquí.
Atención a los detalles que CLUSTER_HOST se establece en nodo1.cluster que es el nombre de host del primer nodo y CLUSTER_REBALANCE también se establece en verdadero. Una vez añadido el nodo al clúster, se reequilibrará automáticamente.
|
1 2 3 4 5 |
docker run -ti --name node3.cluster \ --network=couchbase \ -h node3.cluster \ -e CLUSTER_HOST=node1.cluster \ rugolini/couchbase-server-nosetup |
El nodo3 también se añade al cluster, pero como CLUSTER_REBALANCE no se ha establecido, será necesario reequilibrar manualmente el clúster para que esté disponible.
Este post forma parte del Programa de Escritura de la Comunidad Couchbase
