24 may. 2016

Crear un contenedor Docker como entorno de desarrollo para sails.js

Este artículo toca el tema de usar un contenedor Docker como entorno de Desarrollo.

La idea es tener las dependencias del proyecto en el contenedor y poder desarrollar la aplicación fuera del contenedor por medio de persistencia como un volumen.

Este artículo se basa en la info del siguiente repositorio en github.

En este artículo se usa el framework sails.js, pero  no en profundidad, simplemente crear el proyecto y ejecutarlo. Para más información pueden revisar el siguiente tutorial.

Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.
  20. Proveer un cluster con docker swarm y docker-machine.
  21. Instalar Jenkins por medio de Docker y crear una imagen Docker de Jenkins
  22. Automatizar la construcción de imágenes Docker con github.
  23. Crear una imagen Docker para MongoDB3.

Se tiene un directorio ProyectoNuevo el cual es el proyecto sails.js creado con el comando:
sails new ProyectoNuevo

ProyectoNuevo
├── api
│   ├── controllers
│   ├── models
│   ├── policies
│   │   └── sessionAuth.js
│   ├── responses
│   │   ├── badRequest.js
│   │   ├── created.js
│   │   ├── forbidden.js
│   │   ├── notFound.js
│   │   ├── ok.js
│   │   └── serverError.js
│   └── services
├── app.js
├── assets
│   ├── favicon.ico
│   ├── images
│   ├── js
│   │   └── dependencies
│   │       └── sails.io.js
│   ├── robots.txt
│   ├── styles
│   │   └── importer.less
│   └── templates
├── config
│   ├── blueprints.js
│   ├── bootstrap.js
│   ├── connections.js
│   ├── cors.js
│   ├── csrf.js
│   ├── env
│   │   ├── development.js
│   │   └── production.js
│   ├── globals.js
│   ├── http.js
│   ├── i18n.js
│   ├── locales
│   │   ├── de.json
│   │   ├── en.json
│   │   ├── es.json
│   │   ├── fr.json
│   │   └── _README.md
│   ├── local.js
│   ├── log.js
│   ├── models.js
│   ├── policies.js
│   ├── routes.js
│   ├── session.js
│   ├── sockets.js
│   └── views.js
├── Gruntfile.js
├── package.json
├── README.md
├── tasks
│   ├── config
│   │   ├── clean.js
│   │   ├── coffee.js
│   │   ├── concat.js
│   │   ├── copy.js
│   │   ├── cssmin.js
│   │   ├── jst.js
│   │   ├── less.js
│   │   ├── sails-linker.js
│   │   ├── sync.js
│   │   ├── uglify.js
│   │   └── watch.js
│   ├── pipeline.js
│   ├── README.md
│   └── register
│       ├── build.js
│       ├── buildProd.js
│       ├── compileAssets.js
│       ├── default.js
│       ├── linkAssetsBuild.js
│       ├── linkAssetsBuildProd.js
│       ├── linkAssets.js
│       ├── prod.js
│       └── syncAssets.js
└── views
    ├── 403.ejs
    ├── 404.ejs
    ├── 500.ejs
    ├── homepage.ejs
    └── layout.ejs

El directorio donde se encuentra el proyecto se llama sailsjs con el siguiente contenido:

sailsjs
├── Dockerfile
├── ProyectoNuevo
└── run.sh

El contenido de ProyectoNuevo se mostró arriba.

El archivo run.sh contiene un script para levantar sails por medio de sails lift:

#!/bin/bash

cd /app/ProyectoNuevo
sails lift


El archivo Dockerfile contiene lo siguiente:


#Se usa la imagen de nodejs de google
FROM google/nodejs
#El mantenedor de la imagen
MAINTAINER Ernesto Crespo <ecrespo@gmail.com>
#El usuario del contenedor
USER root
#Se define el directorio de trabajo
WORKDIR /app
#Se copia el ProyectoNuevo a /app/
ADD ProyectoNuevo /app/
#Se instala sails en el contenedor
RUN npm -g install sails
#Se copia el script run.sh al directorio de trabajo
ADD run.sh /app/run.sh
#Se coloca el script con permiso de ejecución
RUN chmod a+x /app/run.sh

#Se expone el puerto 8080
EXPOSE 8080
#Se ejecuta el script
CMD ["/app/run.sh"] 


Para construir la imagen se ejecuta:

docker build -t sails-prueba . 

Para correr la imagen se ejecuta:

docker run -p 8080:8080 -v $PWD:/app  -ti sails-prueba

A continuación se muestra una imagen luego de la ejecución del comando:

Se lista los contenedores:

Se está ejecutando el contenedor de sails junto al de mongodb ya explicado en el capítulo anterior.

Ahora se abre el navegador en localhost al puerto 8080:




La idea al colocar el directorio persistente es que se pueda ir modificando el directorio del proyecto, levantar el contenedor sin necesidad de reconstruir la imagen del mismo. 

22 may. 2016

Crear una imagen Docker para MongoDB 3

En Docker hub, la gente de MongoDB tiene una imagen oficial para varias versiones de mongo.

Pero para los que quieren crear y probar imágenes les dejo una imagen creada a partir de Debian.


Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.
  20. Proveer un cluster con docker swarm y docker-machine.
  21. Instalar Jenkins por medio de Docker y crear una imagen Docker de Jenkins
  22. Automatizar la construcción de imágenes Docker con github.
El archivo Dockerfile se encuentra en github en el siguiente enlace. Su contenido es el siguiente:

FROM debian
MAINTAINER Ernesto Crespo <ecrespo@gmail.com> 
USER root
WORKDIR /code
RUN echo "deb http://ftp.debian.org/debian jessie main contrib non-free" > /etc/apt/sources.list
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
RUN echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/3.0 main" |  tee /etc/apt/sources.list.d/mongodb-org-3.0.list
RUN apt-get update && apt-get install -y mongodb-org
RUN apt-get install -y sudo vim less mc locate
RUN apt-get clean
RUN mkdir -p /data/db
RUN echo "mongodb ALL=NOPASSWD: ALL" >> /etc/sudoers

EXPOSE 27017
ENTRYPOINT ["/usr/bin/mongod"]

Para construir la imagen se ejecuta:

docker build -t <nombreImagen> .

En este caso fue:
docker build -t mongo3-custom .

Para quien quiera bajar la imagen ejecuta:

docker pull ecrespo/mongo3-custom

Para correr un contenedor usando persistencia de datos en /srv/data/db se ejecuta:

docker run -p 27017:27017 -v /srv/data/db:/data/db:rw --name mongo_instance_001 -d mongo-custom3 --smallfiles

Para ver el log del contenedor se ejecuta docker logs <idcontenedor|nombrecontenedor>


Para ver el contenedor corriendo se ejecuta docker ps:


Para acceder a mongo se ejecuta:
mongo



Para ver la información del contenedor se ejecuta el comando docker inspect:

docker inspect mongo_instance_001
[
    {
        "Id": "d981736358770a23b5123ca1e6490c35bacf40ecf571b265bf98296420b97131",
        "Created": "2016-05-22T00:01:48.049849422Z",
        "Path": "/usr/bin/mongod",
        "Args": [
            "--smallfiles"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 3984,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2016-05-22T17:47:36.658752846Z",
            "FinishedAt": "2016-05-22T16:53:45.66317329Z"
        },
        "Image": "sha256:a17c12c4f560fbc39e8e30bf561c76d86947e2926112bc87d12744e63be7eaa7",
        "ResolvConfPath": "/var/lib/docker/containers/d981736358770a23b5123ca1e6490c35bacf40ecf571b265bf98296420b97131/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/d981736358770a23b5123ca1e6490c35bacf40ecf571b265bf98296420b97131/hostname",
        "HostsPath": "/var/lib/docker/containers/d981736358770a23b5123ca1e6490c35bacf40ecf571b265bf98296420b97131/hosts",
        "LogPath": "/var/lib/docker/containers/d981736358770a23b5123ca1e6490c35bacf40ecf571b265bf98296420b97131/d981736358770a23b5123ca1e6490c35bacf40ecf571b265bf98296420b97131-json.log",
        "Name": "/mongo_instance_001",
        "RestartCount": 0,
        "Driver": "aufs",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "/srv/data/db:/data/db:rw"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {
                "27017/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "27017"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "StorageOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": -1,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "BlkioIOps": 0,
            "BlkioBps": 0,
            "SandboxSize": 0
        },
        "GraphDriver": {
            "Name": "aufs",
            "Data": null
        },
        "Mounts": [
            {
                "Source": "/srv/data/db",
                "Destination": "/data/db",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "d98173635877",
            "Domainname": "",
            "User": "root",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "27017/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "--smallfiles"
            ],
            "Image": "mongo-custom3",
            "Volumes": null,
            "WorkingDir": "/code",
            "Entrypoint": [
                "/usr/bin/mongod"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "9aff46c57baeb071a5762c2fcdac37ab5612901c15d78f61f5188185757699bd",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "27017/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "27017"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/9aff46c57bae",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "f548e847fd8d031f26ebe687c24c709332efa10a2d5752679e6458cf1fbad356",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "b0796b4ed424447971b67d367f762d83141a38e0aacb0a8bc37e70a965d36ac0",
                    "EndpointID": "f548e847fd8d031f26ebe687c24c709332efa10a2d5752679e6458cf1fbad356",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02"
                }
            }
        }
    }
]




Se muestra la información del nombre del contenedor, el puerto que se tiene para acceder al mismo, su IP, su dirección mac entre otras cosas.

11 may. 2016

Automática construcción de imagenes Docker con github

En esté artículo se explica como construir una imagen Docker automáticamente usando github con el hub de docker.

Este artículo se basa en la documentación existente en el sitio de docker hub para construcción automatizada.

Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.
  20. Proveer un cluster con docker swarm y docker-machine.
  21. Instalar Jenkins por medio de Docker y crear una imagen Docker de Jenkins

Lo primero que se tiene que hacer es ir a la cuenta en docker hub, darle clic a cuentas enlazadas y servicios, ahí se selecciona github, como lo muestra la figura:

Al seleccionar github pasa a la parte de la cuenta de github de darle permisos:

Al darle aceptar ya aparecerá la cuenta asociada:


Ahora en github se va al setting del repositorio que se quiere asociar, a la parte de webhooks y service como lo muestra la figura:



Se agrega el servicio Docker:


Se prueba el servicio:


Por lo que se ve, la configuración pasa la prueba.

Ya de ahora en adelante cada vez que se haga un git push a github, docker hub se encarga de actualizar la imagen.

Para terminar se muestra el contenido del archivo Dockerfile de jenkins y el contenido del repositorio de github actualizado:



10 may. 2016

Instalar Jenkins por medio de Docker y crear una imagen Docker de Jenkins

Tal como se hizo en el artículo de gitlab ahora se procede a explicar la instalación de Jenkins, la diferencia es que aparte del procedimiento vía una imagen de Docker, se creará una imagen propia de Jenkins.


Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.
  20. Proveer un cluster con docker swarm y docker-machine.
Este artículo se basa en una parte en el procedimiento del repositorio oficial de Jenkins en Docker Hub

Basicamente para instalar jenkins de la imagen Docker oficial se ejecuta:

docker run -p 8080:8080 -p 50000:50000 jenkins

Pero en este caso se va a usar un archivo Dockerfile donde se instalará maven2, openjdk, docker, ant y jenkins. A fin de tener un soporte suficiente para los plugins que trae jenkins.

El archivo Dockerfile es el siguiente:

FROM debian
MAINTAINER Ernesto Crespo <ecrespo@gmail.com>
RUN apt-get update
RUN apt-get install -y apt-transport-https
RUN apt-get install -y git
RUN apt-get install -y openssh-server openssh-client
RUN apt-get install -y openjdk-7-jdk maven2 ant 
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys  58118E89F3A912897C070ADBF76221572C52609D
RUN sh -c 'echo "deb https://apt.dockerproject.org/repo debian-jessie main" > /etc/apt/sources.list.d/docker.list'
RUN apt-get install -y wget 
RUN wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | apt-key add -
RUN sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
RUN apt-get update
RUN apt-get install -y docker-engine
RUN apt-get install -y jenkins 
RUN apt-get install -y vim less locate
RUN sh -c 'service docker start'
RUN sh -c 'service jenkins start'
RUN apt-get clean
EXPOSE 8080 50000 22
ENTRYPOINT ["java","-jar","/usr/share/jenkins/jenkins.war"]
CMD [""]

Como se ve, se está usando una imagen Debian y se le instala lo necesario para tener jenkins con algunas herramientas adicionales como Docker, maven2, ant y jenkins. 

Para construir la imagen se ejecuta:

docker build -t docker-jenkins . 

Esto genera la imagen como se ve a continuación: 

docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
docker-jenkins         latest              844985a7b6ad        54 minutes ago      855.3 MB

Para crear el contenedor se ejecuta:

docker run -p 8080:8080 -p 50000:50000 -p 8022:22 -P  -d docker-jenkins

Esto genera la siguiente figura abriendo el navegador en localhost:8080:


Acá se ejecuta docker exec a fin de ver el contenido del archivo que contiene la llave para autenticar el jenkins:

docker exec -ti naughty_darwin /bin/bash

Se busca el archivo dentro del contenedor:

cd /root/.jenkins/secrets/
cat initialAdminPassword 
4280c91df94a43308a731c008c6abb3d

Ya con eso se pregunta si se quiere seleccionar los plugins o si se instala los recomendados:


Luego se muestra la ventana del proceso de instalación de plugins:


Al terminar este proceso se pide crear un usuario administrador:

Luego de esto ya se muestra la página que se terminó el proceso de configuración:


A continuación se muestra la página inicial de Jenkins:

Para terminar se instalará unos plugins adicionales necesarios para próximo artículo (git, gitlab y docker):


El archivo Dockerfile utilizado para el artículo se encuentra en github en el siguiente enlace.

Para terminar se sube los cambios a docker hub:

Primero se hace login en docker hub:
docker login 
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ecrespo
Password: 
Login Succeeded

Luego se hace commit:

docker commit 91594bea7711 ecrespo/docker-jenkins
sha256:561e411227e6c0d5e74ef85f6d533c44cb1e66b68ef2da6eec66d228de173fc2

Se hace push:
docker push ecrespo/docker-jenkins

A continuación se muestra una imagen del sitio ecrespo/jenkins de docker hub:


La configuración del Jenkins con Gitlab se tocará en el siguiente artículo. 

9 may. 2016

Proveer un cluster con docker swarm y docker-machine.

Se puede usar docker-machine para proveer un cluster con docker swarm.

Este artículo se basa de los siguientes artículos en inglés:



Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.

Este artículo usará comandos ya explicados en el artículo sobre "Uso de docker-machine".

En el artículo anterior se usó virtualbox, se seguirá usando, pero también se puede usar servicios en la nube o un host local (los drivers soportados): amazon web services, Microsoft Azure, Digital Ocean, Exoscale, Google Compute Engine, Genérico, OpenStack entre otros. 


Se crea un host (virtualbox) para generar el token de swarm:

docker-machine create -d virtualbox local

Para configurar el shell que acceda a local se ejecuta:

eval "$(docker-machine env local)"

Cada host swarm tiene un token instalado dentro de la configuración del motor. Para crear el token se crea la imagen de swarm:

docker run swarm create
Unable to find image 'swarm:latest' locally
latest: Pulling from library/swarm

eada7ab697d2: Pull complete 
afaf40cb2366: Pull complete 
7495da266907: Pull complete 
a3ed95caeb02: Pull complete 
Digest: sha256:12e3f7bdb86682733adf5351543487f581e1ccede5d85e1d5e0a7a62dcc88116
Status: Downloaded newer image for swarm:latest
99cd781ad7e0f3682747d94edff87f49


El token es la salida que se muestra subrayada.

Creando los nodos del cluster:

Todos los nodos de un cluster deben tener el engine instalado, con el token del cluster se puede proveer un host con engine y configurarlo como un nodo swarm.

Para crear un manejador de nodo swarm se ejecuta el siguiente comando:

docker-machine create -d virtualbox --swarm --swarm-master --swarm-discovery token://99cd781ad7e0f3682747d94edff87f49 swarm-manager

Para ver las variables y luego configurar el shell:
docker-machine env swarm-manager
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.101:2376"
export DOCKER_CERT_PATH="/home/ernesto/.docker/machine/machines/swarm-manager"
export DOCKER_MACHINE_NAME="swarm-manager"
# Run this command to configure your shell: 
# eval "$(docker-machine env swarm-manager)"


eval "$(docker-machine env swarm-manager)"

Ahora se crea el primer nodo, el nodo-01, se le pasa también el token:

docker-machine create -d virtualbox --swarm --swarm-discovery token://99cd781ad7e0f3682747d94edff87f49 nodo-01

Y un nodo-02:

docker-machine create -d virtualbox --swarm --swarm-discovery token://99cd781ad7e0f3682747d94edff87f49 nodo-02

Conectar los nodos con la máquina:

Para conectar el ambiente del host con la máquina se usa el comando eval con la opción a docker-machine de env, algo así: 

eval "$(docker-machine env local)"

En este caso docker-machine provee una opción --swarm para conectar los nodos swarm:

docker-machine env --swarm swarm-manager
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.101:3376"
export DOCKER_CERT_PATH="/home/ernesto/.docker/machine/machines/swarm-manager"
export DOCKER_MACHINE_NAME="swarm-manager"
# Run this command to configure your shell: 
# eval "$(docker-machine env swarm-manager)"

Para conectarse el nodo swarm llamado swarm-manager se ejecuta:

eval "$(docker-machine env swarm-manager)"


Ahora se puede ejecutar docker info para interacturar con los nodos:

$docker info 
Containers: 2
 Running: 2
 Paused: 0
 Stopped: 0
Images: 1
Server Version: 1.11.1-rc1
Storage Driver: aufs
 Root Dir: /mnt/sda1/var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 12
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: host bridge null
Kernel Version: 4.4.8-boot2docker
Operating System: Boot2Docker 1.11.1-rc1 (TCL 7.0); HEAD : 903a352 - Tue Apr 26 14:18:06 UTC 2016
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 995.9 MiB
Name: swarm-manager
ID: 6LXP:RTPR:4MRE:OGLK:EDED:EQBP:JQRH:RHLW:5YUG:SELK:MUDN:YVSA
Docker Root Dir: /mnt/sda1/var/lib/docker
Debug mode (client): false
Debug mode (server): true
 File Descriptors: 20
 Goroutines: 45
 System Time: 2016-05-09T20:36:18.825810618Z
 EventsListeners: 1
Username: ecrespo
Registry: https://index.docker.io/v1/
Labels:
 provider=virtualbox


O listar las máquinas con docker-machine ls:

 docker-machine ls
NAME            ACTIVE   DRIVER       STATE     URL                         SWARM
local                    virtualbox   Running   tcp://192.168.99.100:2376   
nodo-01                  virtualbox   Running   tcp://192.168.99.102:2376   swarm-manager
nodo-02                  virtualbox   Running   tcp://192.168.99.103:2376   swarm-manager
swarm-manager   *        virtualbox   Running   tcp://192.168.99.101:2376   swarm-manager (master)

Como pueden notar los nodos nodo-01 y nodo-02 están asociados a swarm-manager y este es el master.

A continuación dejo captura de pantalla de swarm-manager, nodo-01 y nodo-02:



A continuación les dejo unos enlaces de referencia:


6 may. 2016

Uso de docker-machine

Docker-machine se usa para equipos con Windows o MACOSX, o para equipos que no se le puede instalar docker (engine). Se usa como un cliente para un servidor docker.

Este artículo se basa en la documentación oficial en inglés que se encuentra en el siguiente enlace, y en el siguiente tutorial.

Los artículos anteriores sobre docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).

Para probar el uso de docker-machine, se tiene una máquina virtual con IP 192.168.1.102 donde se tiene unas imagenes de docker, y un equipo donde se instalará el docker-machine (qué será mí equipo local).

En el equipo se instalará docker-machine de la siguiente manera:

#curl -L https://github.com/docker/machine/releases/download/v0.4.0/docker-machine_linux-amd64 > /usr/local/bin/docker-machine


#chmod a+x  /usr/local/bin/docker-machine


Para probar que funciona se ejecuta la versión de docker-machine:

#docker-machine -v
docker-machine version 0.4.0 (9d0dc7a)


Crear un docker-machine en virtualbox:

$ docker-machine create --driver virtualbox test

En este caso se crea un contenedor docker que se conecta a virtualbox llamado test.

A continuación se muestra la salida del comandoanterior:

Como lo muestra la imagen, se crea el docker test, se baja una imagen iso llamada boot2docker.

En la siguiente imagen se muestra a virtualbox con la máquina virtual test:

Al acceder a la máquina virtual desde virtualbox se tiene lo siguiente:


Para ver como se conecta a la máquina se ejecuta el siguiente comando:
$docker-machine env test
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/ernesto/.docker/machine/machines/test"
export DOCKER_MACHINE_NAME="test"
## Run this command to configure your shell: 
## eval "$(docker-machine env test)"

Para configurar el shell se ejecuta el siguiente comando:
eval "$(docker-machine env test)"

Para listar las máquinas se ejecuta el siguiente comando:
docker-machine ls
NAME   ACTIVE   DRIVER       STATE     URL                         SWARM
test   *        virtualbox   Running   tcp://192.168.99.100:2376


Para ver la IP que está usando test se ejecuta:
$ docker-machine ip test
192.168.99.100

Correr un servidor nginx en el puerto 8000 en un contenedor:
docker run -d -p 8000:80 nginx

Para ver el servidor se ejecuta el siguiente comando:
curl $(docker-machine ip test):8000

Y el resultado es:


Para terminar se detiene el docker-machine y se elimina:

$docker-machine stop test
$ernesto@jewel:~$ docker-machine rm test
Successfully removed test

AddThis