viernes, 10 de junio de 2016

RESUMEN DE COMANDOS DOCKER


Resumen de comandos Docker.


Actividad
Comando
Ejemplo
Contenedores


Arrancar o comenzar contenedor
docker start <id o nombre>
docker start micontenedor
Reiniciar contenedor
docker restart <id o nombre>
docker restart micontenedor
Parar contenedor
docker stop <id o nombre>
docker stop micontenedor
Eliminar contenedor
docker rm <id o nombre>
docker rm micontenedor
Crear y ejecutar contenedor interactivo
docker run –i –t <image> /bin/bash
docker run –i –t Ubuntu /bin/bash
Crear y ejecutar contenedor como servicio o demonio
docker run –d <image> <cmd>
docker run –d Ubuntu ping docker.com
Listar todos los contenedores en ejecución
docker ps

Listar todos los contenedores
docker ps –a

Abrir una ventana de comandos o Shell en un contenedor en ejecución
docker exec –i –t <id o nombre> bash
docker exec –i –t micontenedor bash
Mostrar detalles de un contenedor
docker inspect <id o nombre>
docker inspect micontenedor
Mostrar eventos de un contenedor
docker events <id o nombre>
docker events postgres
Mostrar los puertos a exponer de un contenedor
docker port <id o nombre>
docker port postgres
Mostrar ficheros modificados
docker diff <id o nombre>
docker diff micontenedor
Mostrar los procesos de un contenedor
docker top <id o nombre>
docker top micontenedor
Mostrar registro de eventos o log de un contenedor
docker logs <id o nombre>
docker logs micontenedor
Ver el registro de eventos interactivo (tipo tail –f)
docker logs –f <id o nombre>
docker logs –f micontenedor
Copiar ficheros de un contenedor
docker cp ‘<id>’:<origen> <destino>
docker cp micontenedor:/etc/hosts /tmp/hosts
Exportar contenedor
docker export <id o nombre>
docker export micontenedor >micontenedor.tar
Guardar cambios de contenedor como imagen nueva
docker commit <id o nombre> <nombre de imagen>
docker commit micontenedor jalapuente/imagen2
Imágenes


Listar todas las imágenes locales
docker images

Obtener una imagen del repositorio oficial
docker pull <nombre>
docker pull ubuntu
Obtener una imagen no oficial
docker pull <espacio de nombres>/<nombre>
docker pull jalapuente/mysql
Subir una imagen a un repositorio oficial (Docker Hub)
docker push <espacio de nombres>/<nombre>
docker pull jalapuente/mysql
Crear una imagen de un fichero Dockerfile
docker build <path>
docker build .
Borrar una imagen
docker rmi <nombre>
docker rmi Ubuntu
Mostrar historial de una imagen
docker history <nombre>
docker history Ubuntu
Mostrar detalles de una imagen
docker inspect <nombre>
docker inspect postgres
Nombrar una imagen y establecer versión de una imagen
docker tag <id> <espacio de nombres>/<nombre>:<version>
docker tag 65f515144e5f jalapuente/mysql:version1
Buscar una imagen
docker search <consulta>
docker search django
Fuente: Elaboración propia.


jueves, 9 de junio de 2016

FUNCIONAMIENTO DE NUESTRO PROPIO REGISTRO DOCKER

Tener un registro público de las imágenes Docker es de gran utilidad. A veces, sin embargo, vamos a querer construir y almacenar las imágenes que contienen información o datos que no queremos hacer públicos. 

Hay dos opciones en esta situación:
• Hacer uso de repositorios privados sobre  Docker Hub.
• Ejecutar nuestro propio registro detrás del cortafuegos o firewall.

El equipo de Docker, Inc., tiene el código fuente que utilizan para ejecutar un registro Docker de código abierto, lo que nos permite construir nuestro propio registro interno. El registro no tiene actualmente una interfaz de usuario y sólo está disponible como un servicio API.

Crear un registro desde un contenedor

Crear un registro en un contenedor Docker es muy simple. Simplemente hay que ejecutar el contenedor provisto por Docker, así:

$ docker run -p 5000:5000 registry:2

Esto ejecutará un contenedor que utiliza la versión 2.0 de la aplicación de registro y comunica por el puerto 5000 de la máquina local.

Probando el nuevo registro

Vamos a probar el nuevo registro y ver como podemos hacer uso del mismo. Vamos a intentar subir una de nuestras imágenes “jalapuente/apache2” a nuestro nuevo registro. En primer lugar, vamos a identificar el ID de la imagen utilizando el comando “docker images”.

$ docker images jalapuente/apache2
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
jalapuente/apache2   latest              1316d227367f        2 weeks ago         223.7 MB

Después apuntamos nuestro ID de imagen, 1316d227367f, será la etiqueta del nuevo registro. Para especificar el nuevo destino del registro, hay que prefijar el nombre de la imagen con el nombre de host y el puerto de nuestro nuevo registro. En nuestro caso, nuestro nuevo registro tiene un nombre de host de midocker.

$ docker tag 1316d227367f midocker:5000/jalapuente/apache2

Después de etiquetar nuestra imagen, podemos enviarla al nuevo registro con el comando docker push :

$ docker push midocker:5000/jalapuente/apache2 .

La imagen se publica entonces en nuestro registro local y estará disponible para poder construir nuevos contenedores, utilizando el comando “docker run”.

$ docker run –t –i midocker:5000/jalapuente/apache2 /bin/bash


Ésta es la implementación más simple del Registro de Docker detrás de un cortafuegos. 

miércoles, 8 de junio de 2016

ELIMINANDO UNA IMAGEN

Podemos eliminar las imágenes cuando no los necesitamos más. Para ello, se utiliza el comando 
docker rmi.

$ docker rmi jalapuente/apache2

Aquí hemos borrado la imagen jalapuente/apache2.

Nota Esto sólo elimina la imagen a nivel local. Si hemos subido previamente esa imagen a Docker Hub, todavía va a existir allí.

Si quieres eliminar el repositorio de una imagen en la Docker Hub, tendrás que iniciar sesión y eliminarlo allí utilizando el enlace Eliminar repositorio.

Eliminación de un repositorio.
También podemos eliminar más de una imagen mediante la especificación de una lista en la línea de comandos.

$ docker rmi jalapuente/apache2 jalapuente/web

o, al igual que comando docker rm podíamos borrar todos los contenedores, podríamos hacer lo mismo con todas las imágenes con el comando docker rmi:

$ docker rmi `docker images -a -q`

  

SUBIR IMÁGENES A DOCKER HUB

Una vez que tenemos una imagen, podemos subirlo a Docker Hub. Esto nos permite que esté disponible para que otros la utilicen. Por ejemplo, podríamos compartirla con las demás personas de nuestra organización o ponerla a disposición de todo el mundo.
Docker Hub también tiene la opción de almacenar nuestros repositorios privados. Estos son una característica de pago que nos permite almacenar una imagen en un depósito privado que sólo está disponible para nosotros o para las personas que deseamos que tengan acceso. Esto nos permite tener imágenes privadas que contienen información privada o código fuente que no deseamos compartir públicamente.

Subimos las imágenes a Docker Hub utilizando el comando “docker push”.

Ejemplo de “docker push”:

$ docker push static_web

Si tratamos de subir la imagen así, nos dará un error que nos indica que es imposible subir la imagen al repositorio raíz y los repositorios raíz son administrados sólo por el equipo de Docker, Inc y rechazarán nuestro intento de escribir en ellos. 

Aquí tenemos otro ejemplo:

$ docker push jalapuente/static_web

Esta vez, nuestro comando “docker push” ha funcionado correctamente, y hemos escrito a un repositorio de usuario, jalapuente/static_web. Queremos escribir en nuestro propio ID de usuario, que hemos creado antes, y una imagen debidamente nombrada (por ejemplo, tu usuario / tu imagen).

Ahora podríamos ver nuestra imagen cargada en Docker Hub.

martes, 7 de junio de 2016

INSTRUCCIONES EN EL FICHERO DOCKERFILE

Ya hemos visto algunas de las instrucciones disponibles para utilizar en el fichero Dockerfile, como RUN y EXPOSE. Pero también hay una gran variedad de instrucciones que podemos utilizar en nuestro Dockerfile. Estos incluyen CMD, ENTRYPOINT, ADD, COPY, VOLUME, WORKDIR, USER, ONBUILD, LABEL, STOPSIGNAL, ARG y ENV. 

Vamos a ver la lista completa.

CMD

La instrucción CMD especifica el comando a ejecutar cuando se inicia un contenedor. Es similar a la instrucción RUN, pero en lugar de ejecutarse el comando cuando se está construyendo el contenedor, se especificará el comando a ejecutar cuando se inicia el contenedor, al igual que la especificación de un comando para ejecutar al iniciar un contenedor con el comando “docker run”.

Por último, es importante entender que podemos anular la instrucción CMD usando el comando “docker run”. Si especificamos un CMD en nuestro Dockerfile y uno en la línea de comando del comando “docker run”, la línea de comandos anulará la instrucción CMD del Dockerfile.

ENTRYPOINT

En estrecha relación con la instrucción CMD, y que puede crear confusión con el mismo, está la instrucción ENTRYPOINT. Entonces vamos a ver cuál es la diferencia entre los dos y porque necesitamos a ambos para poder anular la instrucción CMD en la línea de comando de “docker run”. A veces, esto no es suficiente cuando queremos que un contenedor se comporte de una determinada manera. La instrucción ENTRYPOINT, ofrece un comando que no se anulará con la misma facilidad. Sin embargo, cualquier argumento que especifique en la línea de comandos del comando “docker run” serán pasados como argumentos para el comando especificado en el ENTRYPOINT o punto de entrada. Vamos a ver un ejemplo de una instrucción ENTRYPOINT.

ENTRYPOINT [“/usr/sbin/nginx”]

Como con la instrucción CMD, también podemos especificar parámetros añadiéndolos a la matriz. Por ejemplo:

ENTRYPOINT[“/usr/sbin/nginx”,”-g”,”daemon off;”]

En caso de requerirlo en tiempo de ejecución, nosotros podríamos llegar a sobrescribir la instrucción ENTRYPOINT usando junto con el comando “docker run” el parámetro “--entrypoint”.

WORKDIR

La instrucción WORKDIR ofrece una manera de establecer el directorio de trabajo para el contenedor y para la instrucción ENTRYPOINT y / o CMD para que sea ejecutado cuando un contenedor se inicia desde la imagen.
Podemos utilizarlo para establecer el directorio de trabajo para una serie de instrucciones o para el contenedor final. Por ejemplo, para establecer el directorio de trabajo para una instrucción específica podría ser:

WORKDIR /opt/webapp/db
RUN bundle install
WORKDIR /opt/webapp
ENTRYPOINT [“rackup”]

Aquí hemos cambiado al directorio de trabajo /opt/webapp/db y hemos ejecutado bundle install y luego cambiamos el directorio de trabajo a /opt/webapp antes de especificar nuestra instrucción ENTRYPOINT de rackup.

Podemos reemplazar el directorio de trabajo en tiempo de ejecución con el parámetro -w, por ejemplo:

$ docker run –ti –w /var/log ubuntu pwd /var/log

Esto configurará el directorio de trabajo por defecto del contenedor a /var/log

ENV

La instrucción ENV es usada para configurar variables de entorno durante el proceso de construcción de la imagen. Por ejemplo:

ENV RAPP_PATH /home/rapp

Estas nuevas variables de entorno, podrán ser usadas por cualquier instrucción RUN posterior.
Podemos especificar varias variables de entorno con una sóla instrucción ENV, como por ejemplo:

ENV RAPP_PATH=/home/rapp RAPP_FLAGS=”-arch i386”

También podemos utilizar estas variables de entorno en otras instrucciones:

ENV DESTINO_DIR /opt/app
WORKDIR $DESTINO_DIR

Hemos especificado una nueva variable de entorno, DESTINO_DIR, y hemos usado su valor para definir el directorio de trabajo con la instrucción WORKDIR, el cual quedará establecido como /opt/app.

Estas variables de entorno serán persistentes en los contenedores creados desde la imagen. Pero si nosotros ejecutamos el comando ENV dentro del contenedor construido alteraremos su valor.
También podemos pasar variables de entorno con el comando “docker run” utilizando el parámetro –e. Estas variables sólo se utilizaran en tiempo de ejecución.

USER

La instrucción USER especifica un usuario en el que la imagen se ejecutará, por ejemplo:

      USER nginx

Esto hará que los contenedores creados a partir de la imagen se ejecuten por el usuario nginx. Podemos especificar un nombre de usuario o un UID y grupo o GID. O incluso una combinación de los mismos, por ejemplo:

USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group

También podemos sobrescribir ésto en tiempo de ejecución especificando el parámetro –u con el comando “docker run”

VOLUME

La instrucción VOLUME añade volúmenes a cualquier contenedor creado a partir de una imagen. Un volumen es un directorio especialmente designado dentro de uno o más contenedores que no utiliza el sistema de archivos del contenedor, aunque se integra en el mismo para proporcionar varias funciones útiles para que los datos sean persistentes y se puedan compartir con facilidad:
• Los volúmenes pueden ser compartidos y reutilizados entre los contenedores.
• Un contenedor no tiene que estar en ejecución para compartir sus volúmenes.
• Los cambios en un volumen se hacen directamente.
• Los cambios en un volumen no se incluirán al actualizar una imagen.
• Los volúmenes persisten incluso cuando dejan de usarlo los contenedores.
Esto nos permite añadir datos (como el código fuente), una base de datos, o cualquier otro contenido en una imagen sin comprometer la imagen y nos permite compartir los datos entre los contenedores. Esto se puede utilizar para hacer pruebas con los contenedores y el código de una aplicación, administrar registros, o manejar bases de datos dentro de un contenedor.
La instrucción VOLUME se puede utilizar de la siguiente forma:

VOLUME [“/opt/app”]

Esta instrucción crea un punto de montaje en “/opt/app” a cualquier contenedor creado desde esta imagen.
También podemos especificar múltiples volúmenes especificando un array:

VOLUME [“/opt/app”,”/datos”]

ADD

La instrucción ADD agrega archivos y directorios de nuestro entorno de compilación en nuestra imagen; por ejemplo, al instalar una aplicación. La instrucción ADD especifica un origen y un destino para los archivos, así por ejemplo:

ADD licencia.lic /opt/application/licencia.lic

Esta instrucción ADD copiará el archivo licencia.lic desde el directorio de construcción de la imagen a “/opt/application/licencia.lic” dentro de la propia imagen. El origen del archivo puede ser una URL, nombre de archivo o directorio, siempre y cuando esté accesible dentro del entorno de construcción. No se pueden añadir archivos desde fuera del directorio de construcción.
Cuando añadimos archivos con la instrucción ADD, Docker utiliza el carácter final de la ruta del destino para determinar cuál es la fuente. Si el destino termina en /, entonces se considera que la fuente es un directorio. Si no termina en un /, considera que la fuente es un archivo.
La fuente del archivo también puede ser un URL; por ejemplo:

ADD http://wordpress.org/latest.zip /root/wordpress.zip

Por último, la instrucción ADD tiene algo de especial para el manejo de archivos tar locales. Si un archivo tar (tipos de archivo válidos son gzip, bzip2, xz) se especifica como el archivo de origen, entonces Docker automáticamente lo descomprimirá:

ADD latest.tar.gz /var/www/wordpress/

Esto descomprimiría el archivo latest.tar.gz en el directorio /var/www/wordpress/. El archivo es extraído con el mismo comportamiento que ejecutar tar con la opción -x: la salida es la unión de todo lo que existe en el destino, más el contenido del archivo. Si un archivo o directorio con el mismo nombre ya existe en el destino, no se sobrescribirá.
Actualmente esto no funciona con un archivo tar especificado en una dirección URL.
Por último, si el destino no existe, Docker creará la ruta completa para nosotros, incluyendo cualquier directorio. Los nuevos archivos y directorios se crearán con un modo de permisos 0755 y un UID y GID de 0.
También es importante tener en cuenta que la memoria caché de compilación puede ser invalidada por las instrucciones ADD. Si los archivos o directorios agregados por una instrucción ADD cambiaran, entonces esto va a invalidar la caché para todas las siguientes instrucciones del Dockerfile.

COPY

La instrucción COPY está estrechamente relacionado con la instrucción ADD. La diferencia clave es que la instrucción COPY está pensado para la copia de archivos locales del entorno de construcción y no tiene ninguna capacidad de extracción o de descompresión de archivos.

Ejemplo:
COPY conf.d/  /etc/apache2/

Esto copiará los archivos desde el directorio conf.d al directorio /etc/apache2/.
El origen de los archivos debe ser la ruta a un archivo o directorio en relación con el entorno de construcción, el directorio de origen local en el que está localizado el fichero Dockerfile. No se puede copiar nada que esté fuera de este directorio, porque el entorno de construcción se carga en el demonio de Docker y la copia se lleva a cabo allí. El destino debe ser una ruta absoluta dentro del contenedor.

Los archivos y directorios creados por la copia tendrá un UID y GID de 0.
Si el origen es un directorio, todo el directorio se copia, incluidos los metadatos del sistema de archivos; si la fuente es cualquier otro tipo de archivo, se copia de forma individual junto con sus metadatos. En nuestro ejemplo, el destino termina con una barra inclinada /, por lo que se considera un directorio y copia en el directorio de destino.

Si el destino no existe, se crea junto con todos los directorios que faltan en su camino, al igual que funciona el comando mkdir -p.

LABEL

La instrucción LABEL añade metadatos a una imagen Docker. Los metadatos se presenta en forma de parejas clave/valor. Por ejemplo:

LABEL version= "1.0"
LABEL localizacion= “Murcia” tipo="CPD " rol = "Servidor Web"

La instrucción LABEL se escribe en el formato etiqueta = "valor". Se puede especificar un elemento de metadatos por instrucción LABEL o varios elementos separados por espacios en blanco. Se recomienda combinar todos sus metadatos en una sola instrucción LABEL para evitar la creación de múltiples capas con cada etiqueta de metadatos. Podemos inspeccionar las etiquetas en una imagen usando el comando “docker inspect”.

$ docker inspect jalapuente/apache

Y podemos ver los metadatos que acabamos de definir mediante el uso de la instrucción LABEL.

STOPSIGNAL

La instrucción de instrucciones STOPSIGNAL establece la señal de llamada al sistema que será enviado al contenedor cuando se le indica que se detenga. Esta señal puede ser un número válido permitido por el kernel, por ejemplo 9, o un nombre de señal en el SIGNAME formato, por ejemplo SIGKILL.

ARG

La instrucción ARG define variables que se pueden pasar en tiempo de compilación a través del comando “docker build”. Esto se hace utilizando el parámetro --build-arg. Sólo puede especificar argumentos en tiempo de compilación que han sido definidos en el fichero DOCKERFILE, aquí tenemos un ejemplo de uso:

ARG build ARG webapp_user = usuario

La segunda instrucción ARG establece valor por defecto, si no se especifica ningún valor para el argumento en tiempo de construcción, se utiliza el valor predeterminado. Aquí tenemos un ejemplo  de uso de estos argumentos en en la ejecución del comando “docker build”.

$ docker build -- build-arg constru=1234 -t jalapuente/webapp .

Cuando se construye la imagen jalapuente/webapp la variable constru se establecerá en 1234 y la variable webapp_user heredará el valor predeterminado de usuario.
Docker tiene un conjunto de variables ARG predefinidos que se pueden utilizar en tiempo de compilación, sin que exista una instrucción ARG correspondiente en el Dockerfile.

HTTP_PROXY http_proxy
HTTPS_PROXY https_proxy
FTP_PROXY ftp_proxy
NO_PROXY no_proxy

Para utilizar estas variables predefinidas, pasarlas con el parámetro “--build-arg <variable> = <valor>” al comando docker build.

ONBUILD

La instrucción ONBUILD añade disparadores (también conocidos como triggers) a las imágenes. Un disparador se ejecuta cuando se utiliza la imagen como base de otra imagen (por ejemplo, si tenemos una imagen que necesita agregar código fuente desde una ubicación específica que podría no estar disponible aún, o si necesitamos ejecutar un script que es específico para el entorno en el que se construye la imagen).

El disparador inserta una nueva instrucción en el proceso de construcción, como si se especifica inmediatamente después de la instrucción FROM. El desencadenante puede ser cualquier instrucción de construcción.

Por ejemplo:

ONBUILD ADD ./app/src
ONBUILD RUN cd  /app/src && make

Esto añadiría un disparador ONBUILD a la imagen que se está creando, lo que podemos ver ejecutando el comando docker inspect sobre la imagen.

$ docker inspect imagen
 … “OnBuild”: [“ADD ./app/src”, “RUN cd /app/src / && make”] …

Por ejemplo, vamos a construir un nuevo Dockerfile de una imagen Apache2 que llamaremos jalapuente/apache2.

FROM Ubuntu:14.04
MAINTAINER Javier Hernandez “jalapuente@example.com”
RUN apt-get update && apt-get install –y apache2
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ONBUILD ADD . /var/www/
EXPOSE 80
ENTRYPOINT [“/usr/sbin/apache2”]
CMD [“D”, “FOREGROUND”]

Ahora vamos a construir esta imagen.

$ docker build –t=”jalapuente/apache2”.

Ahora tenemos una imagen con una instrucción ONBUILD que utiliza la instrucción ADD para agregar el contenido del directorio que estamos construyendo desde el directorio /var/www/ a nuestra imagen. Esto podría ser fácilmente nuestra plantilla de aplicación web genérica para la construcción de aplicaciones web.


Vamos a utilizar esto mediante la construcción de una nueva imagen llamada webapp con el siguiente fichero Dockerfile:

FROM jalapuente/apache2
MAINTAINER Javier Hernandez jalapuente@example.com
ENV APPLICATION_NAME webapp
ENV ENVIRONMENT development

Si nosotros ahora ejecutáramos el comando para construir esta imagen:

$ docker build -t=”jalapuente/webapp” .

entre los pasos veríamos:

# Executing 1 build triggers Step onbuild-0: ADD . /var/www/

Se puede ver que inmediatamente después de la instrucción FROM, Docker ha insertado la instrucción ADD, especificado por el disparador ONBUILD y, a continuación, se procedió a ejecutar los pasos restantes. Esto permitiría añadir siempre la fuente local y especificar alguna configuración o construir información para cada aplicación; por lo tanto, esto se convierte en una de imagen plantilla bastante útil.

Los disparadores ONBUILD se ejecutan en el orden especificado en la imagen padre y sólo se heredan de una vez (es decir, por los niños y no los nietos). Si construimos otra imagen de esta nueva imagen, un nieto de la imagen jalapuente/apache2, los disparadores no serían ejecutados cuando se construye esa nueva imagen.


Existen varias instrucciones que no se pueden utilizar en ONBUILD, entre ellas FROM, MAINTAINER, y ONBUILD a si mismo. Esto se hace para evitar la recursividad en la compilación del fichero Dockerfile.