21 ago. 2016

Trabajar con un contenedor docker en Python usando docker-py

En este artículo se utilizará la librería docker-py para acceder a imágenes y contenedores Docker desde python.

La documentación de docker-py se encuentra en su sitio oficial.


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.
  24. Crear un contenedor Docker como entorno de desarrollo para Sails.js.
  25. Correr aplicaciones de escritorio desde un contenedor Docker.
  26. Usar dockerui para la gestión de imágenes y contenedores de Docker
  27. Crear una imagen Docker de RethinkDB
  28. Profiling de un script Python con cProfile
  29. Instalar gitlab-runner de gitlab-ci por medio de Docker
  30. Correr sonarqube desde un contenedor Docker
  31. Crear una imagen docker de Redis.

El primer script contiene lo siguiente:



#!/usr/bin/python





#Se importa el cliente docker.

from docker import Client



#Se asocia la instancia cliente de docker con el socket.

cli = Client(base_url='unix://var/run/docker.sock')



print ("Se muestra la imagen docker de debian")

print (cli.images(name="debian"))



#Se crea un contenedor basandose en la imagen de debian y ejecuta sleep por 30 seg

container = cli.create_container(image="debian",command='/bin/sleep 30')





print  ("se imprime la informacion del contenedor")

print(container)

print ("Se muestra la información de los contenedores que están corriendo.")

print (cli.containers())





Al ejecutar el script se tiene:

python app.py

Se muestra la imagen docker de debian
[{u'Created': 1449257280, u'Labels': None, u'VirtualSize': 125090240, u'ParentId': u'sha256:2e4b1470911604ccb99e3d2a9db8487661bb1d6db5b7aa9e4cf54a4b8bc7e33e', u'RepoTags': [u'debian:latest'], u'RepoDigests': None, u'Id': u'sha256:87b7eb6de0a6def7be27d485caf243354f8b5e19f41b0222b19f6f02b102dc61', u'Size': 125090240}]
se imprime la informacion del contenedor
{u'Id': u'766563f15d12562ff8fc6ff1a89ed76b1ebd914bfa9b8f753a4acf925778e720', u'Warnings': None}
Se muestra la informacion de los contenedores que estan corriendo.
[{u'Status': u'Up 43 minutes', u'Created': 1459285417, u'Image': u'jupyter/notebook', u'Labels': {}, u'NetworkSettings': {u'Networks': {u'bridge': {u'NetworkID': u'', u'MacAddress': u'02:42:ac:11:00:02', u'GlobalIPv6PrefixLen': 0, u'Links': None, u'GlobalIPv6Address': u'', u'IPv6Gateway': u'', u'IPAMConfig': None, u'EndpointID': u'ec791d0a8b52fee4fc46447b43304ce626629790e3a525cd4ae03e6a25bda3d5', u'IPPrefixLen': 16, u'IPAddress': u'172.17.0.2', u'Gateway': u'172.17.0.1', u'Aliases': None}}}, u'HostConfig': {u'NetworkMode': u'default'}, u'ImageID': u'sha256:1c02aa25b7b817d8b7a7557b4b62250db6c735da3e7fabb4b3a157e55256e2d4', u'State': u'running', u'Command': u'tini -- jupyter notebook', u'Names': [u'/berserk_darwin'], u'Mounts': [{u'RW': True, u'Source': u'/home/ernesto/dockers/notebook/notebook', u'Destination': u'/notebooks', u'Mode': u'', u'Propagation': u'rprivate'}], u'Id': u'dfcc1bd19dab02580cce30d1719d8514eb0af2ab1dec8b01e42b95376ce5e608', u'Ports': [{u'IP': u'0.0.0.0', u'Type': u'tcp', u'PublicPort': 8888, u'PrivatePort': 8888}]}]



El script app2.py tiene lo siguiente:

#!/usr/bin/python





#Se importa el cliente docker.

from docker import Client

#Se import io para el manejo del texto en la salida.

from io import BytesIO

#Se crea el archivo dockerfile

dockerfile = '''

 # Shared Volume

 FROM busybox

 MAINTAINER Ernesto Crespo, ecrespo@gmail.com

 VOLUME /data

 CMD ["/bin/sh"]

 '''

 #Se define el encode como utf-8

f = BytesIO(dockerfile.encode('utf-8'))

#Se crea la instancia del cliente docker al socket.

cli = Client(base_url='unix://var/run/docker.sock')



#Se construye la imagen y devuelve la salida de la misma.

response = [line for line in cli.build(

 fileobj=f, rm=True, tag='ecrespo/data'

 )]



print ("Se muestra la respuesta")

for i in response:

 print (i)



print ("Se muestra los contenedores que estan corriendo, en este caso uno de jupyter")

print (cli.containers())




EL resultado de ejecutar el scrip app2.py es el siguiente

Se muestra la respuesta
{"stream":"Step 1 : FROM busybox\n"}

{"stream":" ---\u003e 8c9d515b3079\n"}

{"stream":"Step 2 : MAINTAINER Ernesto Crespo, ecrespo@gmail.com\n"}

{"stream":" ---\u003e Using cache\n"}

{"stream":" ---\u003e 5efdc0a317b7\n"}

{"stream":"Step 3 : VOLUME /data\n"}

{"stream":" ---\u003e Using cache\n"}

{"stream":" ---\u003e b0132c6c3a87\n"}

{"stream":"Step 4 : CMD /bin/sh\n"}

{"stream":" ---\u003e Using cache\n"}

{"stream":" ---\u003e a7c85281e78c\n"}

{"stream":"Successfully built a7c85281e78c\n"}

Se muestra los contenedores que estan corriendo, en este caso uno de jupyter
[{u'Status': u'Up 56 minutes', u'Created': 1459285417, u'Image': u'jupyter/notebook',
 u'Labels': {}, u'NetworkSettings': {u'Networks': {u'bridge': {u'NetworkID': u'',
 u'MacAddress': u'02:42:ac:11:00:02', u'GlobalIPv6PrefixLen': 0, u'Links': None, 
u'GlobalIPv6Address': u'', u'IPv6Gateway': u'', u'IPAMConfig': None, 
u'EndpointID': u'ec791d0a8b52fee4fc46447b43304ce626629790e3a525cd4ae03e6a25bda3d5',
 u'IPPrefixLen': 16, u'IPAddress': u'172.17.0.2', u'Gateway': u'172.17.0.1',
u'Aliases': None}}}, u'HostConfig': {u'NetworkMode': u'default'},
 u'ImageID': u'sha256:1c02aa25b7b817d8b7a7557b4b62250db6c735da3e7fabb4b3a157e55256e2d4',
 u'State': u'running', u'Command': u'tini -- jupyter notebook', 
u'Names': [u'/berserk_darwin'], u'Mounts': [{u'RW': True,
 u'Source': u'/home/ernesto/dockers/notebook/notebook',
 u'Destination': u'/notebooks', u'Mode': u'', u'Propagation': u'rprivate'}],
 u'Id': u'dfcc1bd19dab02580cce30d1719d8514eb0af2ab1dec8b01e42b95376ce5e608',
 u'Ports': [{u'IP': u'0.0.0.0', u'Type': u'tcp', u'PublicPort': 8888,
 u'PrivatePort': 8888}]}]


Como se puede ver en la documentación y en los scripts ejecutados, se puede crear
 una aplicación que acceda al API de docker o trabajar con las imágenes y contenedores 
desde python. 

Publicar un comentario en la entrada

AddThis