Cómo ejecutar el contenedor Docker en CoreOS etcd Cluster
CoreOS es un nuevo y emocionante sistema operativo, diseñado teniendo en cuenta los conceptos de clúster, principalmente, las necesidades de seguridad y alta disponibilidad. En realidad, CoreOS significa tres cosas, es el nombre de la empresa detrás del sistema operativo, el nombre del sistema operativo en sí y el nombre de la plataforma del clúster.
CoreOS es un sistema operativo ligero basado en Linux que viene con soporte completo de Docker. CoreOS nos permite ejecutar fácilmente una plataforma de clúster completa, para ello CoreOS se basa en otros componentes principalmente, etcd, docker y fleet.
Estibador
CoreOS utiliza contenedores de Docker para garantizar un tiempo de ejecución aislado para sus servicios y aplicaciones subyacentes. También trae Docker listo para usar para implementar y ejecutar aplicaciones en un clúster de CoreOS.
Etcd
Etcd es un almacén de clave-valor distribuido (tipo de base de datos de clave-valor) diseñado para alta disponibilidad y principalmente para almacenar configuraciones para ejecutar aplicaciones en el clúster. CoreOS viene con etcdctl, que es una herramienta de línea de comandos para interactuar con etcd. En términos generales, etcd es un servicio que se ejecuta en cada máquina del clúster para manejar la coordinación entre el software que se ejecuta en el clúster.
Flota
Fleet es una especie de administrador de servicios para el clúster CoreOS. Con la flota podemos gestionar nuestro clúster de forma tan sencilla como si gestionáramos una sola máquina. Por ejemplo, imaginamos que necesitamos para iniciar un servicio específico para una aplicación, gestionamos nuestro servicio enviándolo al clúster y decidimos la máquina host para nuestro servicio. Además de eso, con fleet podemos definir un conjunto de políticas para nuestros servicios, etc. Fleet también viene con fleetctl, una herramienta de línea de comandos para interactuar con él.
Configurar un clúster en CoreOS
Debo mencionar que el clúster de CoreOS podría ejecutarse en diferentes plataformas como DigitalOcean, Amazon, Google Compute Engine, etc. pero, en este artículo, usaré vagrant y virtualbox para configurar y ejecutar un clúster local. Por lo tanto, vagrant y virtualbox son los dos requisitos para el artículo actual, sin duda, hay toneladas de buenos artículos sobre cómo instalarlos en su máquina.
Una vez que haya instalado vagrant y virtualbox, necesitamos descargar un repositorio mantenido con el equipo de CoreOS, así que continúe y descargue este repositorio https://github.com/coreos/coreos-vagrant como se ilustra en la imagen a continuación, de lo contrario, puede clonarlo si está familiarizado con git.
Con git clone:
➜ coreos-vagrant git:(master) git clone https://github.com/coreos/coreos-vagrant.git
Una vez descargado, descomprima el archivo y abra la carpeta con su editor de texto preferido. Caminemos por este repositorio y hagamos algunos cambios para activar nuestro clúster.
token de descubrimiento etcd
para arrancar rápidamente un clúster de CoreOS, etcd necesita un servicio de descubrimiento para conectar instancias, almacenando una lista de direcciones de pares, metadatos y el tamaño inicial del clúster, etc. CoreOS proporciona un servicio gratuito para manejar esta necesidad. Generemos un token para un clúster de tamaño 4:
➜ coreos-vagrant git:(master) curl -w "n" 'https://discovery.etcd.io/new?size=4' https://discovery.etcd.io/c8ac80bef794eff84e4d52c5af310db0
configuración de nube
La URL de descubrimiento anterior se puede proporcionar a cada máquina CoreOS a través de configuración de nube, una herramienta de configuración mínima que está diseñada para conectar una máquina a la red y unirse al clúster.
El repositorio descargado proporciona un archivo de modelo para la configuración de la nube denominado user-data.sample. Entonces, comenzamos cambiando el nombre de este archivo a datos del usuario y cambiar la etiqueta de descubrimiento a nuestra URL de generar descubrimiento, que es en mi caso: https://discovery.etcd.io/c8ac80bef794eff84e4d52c5af310db0
➜ coreos-vagrant git:(master) ✗ cat user-data #cloud-config coreos: etcd2: #generate a new token for each unique cluster from https://discovery.etcd.io/new discovery: https://discovery.etcd.io/c8ac80bef794eff84e4d52c5af310db0 # multi-region and multi-cloud deployments need to use $public_ipv4 advertise-client-urls: http://$public_ipv4:2379 initial-advertise-peer-urls: http://$private_ipv4:2380 # listen on both the official ports and the legacy ports # legacy ports can be omitted if your application doesn't depend on them listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001 listen-peer-urls: http://$private_ipv4:2380,http://$private_ipv4:7001 fleet: public-ip: $public_ipv4 flannel: interface: $public_ipv4 units: - name: etcd2.service command: start - name: fleet.service command: start - name: flanneld.service drop-ins: - name: 50-network-config.conf content: | [Service] ExecStartPre=/usr/bin/etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }' command: start - name: docker-tcp.socket command: start enable: true content: | [Unit] Description=Docker Socket for the API [Socket] ListenStream=2375 Service=docker.service BindIPv6Only=both [Install] WantedBy=sockets.target
Vagrantfile
De nuevo tenemos que cambiar el cambio $ num_instances en este archivo asignando el valor 5.
Iniciar el clúster
Para iniciar el clúster, simplemente abra una terminal, señale el repositorio descargado y ejecute:
➜ coreos-vagrant git:(master) ✗ vagrant up Bringing machine 'core-01' up with 'virtualbox' provider... Bringing machine 'core-02' up with 'virtualbox' ...
Ahora podemos ssh las máquinas creadas, como a continuación:
➜ coreos-vagrant git:(master) ✗ vagrant ssh core-02 Last login: Fri Dec 23 17:22:51 UTC 2016 from 10.0.2.2 on ssh CoreOS stable (1185.5.0) core@core-03 ~ $
Ahora podemos verificar la cantidad de instancias de nuestro clúster:
core@core-02 ~ $ etcdctl member list cce1ee23391bec4: name=397f492f266c4acab61e83ecc2adb388 peerURLs=http://172.17.8.103:2380 clientURLs=http://172.17.8.103:2379 isLeader=false 3e5d3e6bfe52303b: name=fb1c3d855e764520bb675ecf1fcbad22 peerURLs=http://172.17.8.102:2380 clientURLs=http://172.17.8.102:2379 isLeader=false 47f62622394dbef2: name=43bc777f8b654d19abddc2978a74cd0c peerURLs=http://172.17.8.101:2380 clientURLs=http://172.17.8.101:2379 isLeader=true a8b3dab66f0a5fc5: name=57fcfc8813bd4bf49947e660574b525f peerURLs=http://172.17.8.104:2380 clientURLs=http://172.17.8.104:2379 isLeader=false core@core-02 ~ $
También podemos comprobar las máquinas dentro del clúster:
core@core-02 ~ $ fleetctl list-machines --full=true MACHINE IP METADATA 397f492f266c4acab61e83ecc2adb388 172.17.8.103 - 43bc777f8b654d19abddc2978a74cd0c 172.17.8.101 - 57fcfc8813bd4bf49947e660574b525f 172.17.8.104 - c773afd96d37462288c97c1b8695fad2 172.17.8.105 - fb1c3d855e764520bb675ecf1fcbad22 172.17.8.102 -
Aplicación de muestra de Node js
Ahora voy a crear una aplicación de muestra de nodejs para demostrar cómo podemos ejecutar contenedores de Docker dentro de nuestro clúster.
// archivo – app.js
➜ sampleNodeJsApp git:(master) ✗ cat app.js var express = require('express'); var app = express(); var PORT = 3000; app.get('/ping', function (req, res) { res.write('Hi there I'm up and running!!'); res.end(); }) app.listen(PORT, function () { console.log('Server listening on port: ', PORT); })
// archivo – package.json
➜ sampleNodeJsApp git:(master) ✗ cat package.json { "name": "sampleNodeJsApp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.14.0" } }
// archivo – Dockerfile
➜ sampleNodeJsApp git:(master) ✗ cat Dockerfile FROM node:latest RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY package.json /usr/src/app/package.json RUN npm i COPY . /usr/src/app/ EXPOSE 8080 CMD [ "node", "app.js" ]
Construyendo la imagen de Docker:
➜ sampleNodeJsApp git:(master) ✗ docker build -t linoxide/sample-nodejs-app:v0.0.1 .
Empujar la imagen de la ventana acoplable al hub de la ventana acoplable
➜ sampleNodeJsApp git:(master) ✗ docker push linoxide/sample-nodejs-app:v0.0.1
Archivos unitarios
La implementación de Coreos funciona utilizando los archivos Unit llamados, por lo tanto, para poder implementar la aplicación de muestra nodejs ya creada, necesitamos crear dos archivos; el primer archivo lo llamaré sample-nodejs-app-deployment @ .service este archivo extraerá nuestra imagen de la ventana acoplable de compilación y envío (ver arriba) y disparará un contenedor de la ventana acoplable; el segundo archivo lo llamaré ejemplo-nodejs-app-service @ .service este archivo expone la implementación de nuestra aplicación.
Tenga en cuenta que estos archivos deben crearse dentro de una de nuestras máquinas de clúster:
// archivo – sample-nodejs-app-deployment @ .service
core @ core-02 ~ $ servicio cat sample-nodejs-app-deployment @.
[Unit]
Descripción = Aplicación de muestra de NodeJs dentro de un contenedor de Docker en el clúster de CoreOS
Después = etcd2.service
Después = docker.service
Requiere=sample-nodejs-app-service@%i.service
[Service]
TimeoutStartSec = 0
KillMode = ninguno
EnvironmentFile = / etc / environment
ExecStartPre = – / usr / bin / docker kill sample-nodejs-app-deployment% i
ExecStartPre = – / usr / bin / docker rm sample-nodejs-app-deployment% i
ExecStartPre = / usr / bin / docker pull linoxide / sample-nodejs-app: v0.0.1
ExecStart = / usr / bin / docker run –name sample-nodejs-app-deployment% i -p% i: 3000
-P -e COREOS_PRIVATE_IPV4 = $ {COREOS_PRIVATE_IPV4}
linoxide / sample-nodejs-app: v0.0.1
ExecStop = / usr / bin / docker detener muestra-nodejs-app-deployment% i
[X-Fleet]
Conflicts=sample-nodejs-app-deployment@*.service
// archivo – sample-nodejs-app-service @ .service
core @ core-02 ~ $ cat sample-nodejs-app-service @. service
[Unit]
Descripción = Anunciar el servicio sample-nodejs-app-deployment @% i
BindsTo=sample-nodejs-app-deployment@%i.service
[Service]
EnvironmentFile = / etc / environment
ExecStart = / bin / sh -c «mientras sea verdadero; hacer etcdctl set /noun / services / sample-nodejs-app-deployment% i $ {COREOS_PUBLIC_IPV4}:% i –ttl 60; sleep 45; done»
ExecStop = / usr / bin / etcdctl rm /noun / services / sample-nodejs-app-deployment% i
[X-Fleet]
MachineOf=sample-nodejs-app-deployment@%i.service
Envíe sample-nodejs-app-deployment @ .service y sample-nodejs-app-service @ .service
core@core-02 ~ $ fleetctl submit sample-nodejs-app-deployment@.service sample-nodejs-app-service@.service Unit sample-nodejs-app-deployment@.service inactive Unit sample-nodejs-app-service@.service inactive
Enumere todos los servicios:
core@core-02 ~ $ fleetctl list-unit-files UNIT HASH DSTATE STATE TARGET sample-nodejs-app-deployment@.service 8b9612b inactive inactive - sample-nodejs-app-service@.service d929f3f inactive inactive -
Ahora ambos servicios están disponibles dentro del clúster. Pero, como puede notar, están en un estado inactivo. Carguemos ambos servicios. Vamos a pasar el puerto 3000, dentro de fleetctl en el nombre del servicio como se ilustra a continuación, este puerto se utilizará para ejecutar el contenedor docker con puerto hacia adelante en este puerto.
core@core-02 ~ $ fleetctl load sample-nodejs-app-deployment@3000.service WARNING: Unit sample-nodejs-app-deployment@.service in registry differs from local template unit file sample-nodejs-app-deployment@.service Unit sample-nodejs-app-deployment@3000.service inactive Unit sample-nodejs-app-deployment@3000.service loaded on 397f492f.../172.17.8.103 core@core-02 ~ $ fleetctl load sample-nodejs-app-service@3000.service Unit sample-nodejs-app-service@3000.service inactive Unit sample-nodejs-app-service@3000.service loaded on 397f492f.../172.17.8.103
Una vez cargados los servicios, podemos iniciarlos usando fleetctl start:
core@core-02 ~ $ fleetctl start sample-nodejs-app-deployment@3000.service WARNING: Unit sample-nodejs-app-deployment@3000.service in registry differs from local template unit file sample-nodejs-app-deployment@.service Unit sample-nodejs-app-deployment@3000.service launched on 397f492f.../172.17.8.103 core@core-02 ~ $ fleetctl start sample-nodejs-app-service@3000.service Unit sample-nodejs-app-service@3000.service launched on 397f492f.../172.17.8.103
Observe la dirección IP 172.17.8.103 donde está alojada la aplicación node js. Entonces, intentemos eso, abra su navegador e intentemos llegar al punto final ‘/ ping’: 172.17.8.103:3000/ping
Todo está funcionando bien.
Conclusión
En este artículo, hemos visto primero cómo poner en funcionamiento un clúster CoreOS local usando vagrant y virtualbox; segundo, hemos visto cómo ejecutar una aplicación web en un contenedor Docker dentro de nuestro clúster.