====== 7. Despliegue básico en servidor ====== ===== Introducción a Docker ===== Docker es similar a VirtualBox solo que se gestiona con la línea de órdenes y consume muchísimos menos recursos el crear cada máquina virtual. En el entorno de Docker hay que diferenciar dos conceptos: * **Imagen**: Son como plantillas de una //máquina virtual// * **Contenedor**: Es la //máquina virtual// en ejecución pero el software que se ejecuta es el que se define en la **Imagen** {{:clase:daw:daw:2eval:docker_container_vs_images-300x196.png|}} Mas información: * [[http://www.genbetadev.com/programacion-en-la-nube/entendiendo-la-nube-el-significado-de-saas-paas-y-iaas|Entendiendo la nube: el significado de SaaS, PaaS y IaaS]] * [[http://www.redeszone.net/2016/02/24/docker-funciona-la-virtualizacion-contenedores/|Docker, qué es y cómo funciona la virtualización de contenedores]] * [[https://www.xataka.com/otros/docker-a-kubernetes-entendiendo-que-contenedores-que-mayores-revoluciones-industria-desarrollo|De Docker a Kubernetes: entendiendo qué son los contenedores y por qué es una de las mayores revoluciones de la industria del desarrollo]] * [[https://www.javiergarzas.com/2015/07/entendiendo-docker.html|Entendiendo Docker. Conceptos básicos: Imágenes, Contenedores, Links…]] ===== Datos de servidores ===== {{:clase:daw:daw:2eval:datos_proxmox.png?direct|}} ===== Instalación ===== Para instalar docker , lanzar las siguientes órdenes en Ubuntu: snap remove docker sudo apt-get remove docker docker-engine docker.io containerd runc sudo apt-get update sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo apt-key fingerprint 0EBFCD88 sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io Las instrucciones actualizadas están en [[https://docs.docker.com/engine/install/ubuntu/|Install Docker Engine on Ubuntu]] Para comprobar que todo funciona , lanzar la siguiente orden: sudo docker container run hello-world ===== Gestión de Imágenes ===== Las imágenes se descargan de una página llamada [[https://hub.docker.com|DockerHub]]. Es algo similar a GitHub pero para imágenes de Docker. ^ Orden ^ Explicación ^ | [[https://docs.docker.com/engine/reference/commandline/image_pull/|docker image pull]] | Bajar una imagen de DockerHub | | [[https://docs.docker.com/engine/reference/commandline/image_rm/|docker image rm]] | Borrar una imagen en local | | [[https://docs.docker.com/engine/reference/commandline/image_ls/|docker image ls]] | Ver las imagenes que hay en local | | [[https://docs.docker.com/engine/reference/commandline/image_save/|docker image save]] | Exportar una imagen a un fichero | | [[https://docs.docker.com/engine/reference/commandline/image_load/|docker image load]] | Importan una imagen desde un fichero | ==== docker image pull ==== Se usa para descargar una imagen de [[https://hub.docker.com|DockerHub]] en nuestra máquina. Tiene un único parametro que es el nombre de la imagen a descargar. El nombre de la imagen tiene el siguiente formato: **usuario/nombre de la imagen:tag de la imagen** Siendo: * usuario: El nombre del usuario que ha subido la imagen. Si la imagen es oficial de DockerHub no tendrá usuario y no se pondrá la / posterior * nombre de la imagen: Es obligatorio y es el nombre de la imagen a descargar * tag de la imagen: Es la versión de la imagen. Si no se pone la versión , no hay que poner los dos puntos anteriores y se descargará la que está etiquetada como "latest"o "lts. \\ \\ * Descarga la imagen llamada "mysql-server" creada por el usuario "mysql" pero la versión "8.0.22" docker image pull mysql/mysql-server:8.0.22 ==== Proxy ==== Al igual que con otras herramientas, para clase habrá que configurar el proxy: mkdir /etc/systemd/system/docker.service.d echo "[Service]" >> /etc/systemd/system/docker.service.d/http-proxy.conf echo "Environment=\"HTTP_PROXY=http://172.16.0.9:8080/\"" >> /etc/systemd/system/docker.service.d/http-proxy.conf systemctl daemon-reload * Si todo está correcto, la siguiente orden debe mostrar ''Environment=HTTP_PROXY=HTTP_PROXY=http://172.16.0.9:8080/"'' systemctl show --property Environment docker Mas información: * [[http://stackoverflow.com/questions/23111631/cannot-download-docker-images-behind-a-proxy|Cannot download Docker images behind a proxy]] ===== Gestión de Contenedores ===== ^ Orden ^ Explicación ^ | [[https://docs.docker.com/engine/reference/commandline/container_run/|docker container run]] | Crear un nuevo contenedor y ejecutarlo a partir de una imagen | | [[https://docs.docker.com/engine/reference/commandline/container_start/|docker container start]] | Iniciar un contenedor que está parado | | [[https://docs.docker.com/engine/reference/commandline/container_stop/|docker container stop]] | Parar un contenedor | | [[https://docs.docker.com/engine/reference/commandline/container_rm/|docker container rm]] | Borrar un contenedor que está parado | | [[https://docs.docker.com/engine/reference/commandline/container_ls/|docker container ls]] | Ver los contenedores que hay | | [[https://docs.docker.com/engine/reference/commandline/container_exec/|docker container exec]] | Ejecutar una orden en el contenedor. Normalmente es el Shell | | [[https://docs.docker.com/engine/reference/commandline/container_stats/|docker container stats]] | Mostrar uso de CPU,memoria,etc de los contenedores | | [[https://docs.docker.com/engine/reference/commandline/container_logs/|docker container logs]] | Muestra lo que sale por pantalla. Es decir lo que se llama en Linux ''stdout'' y ''stderr''. Normalmente los contenedores van sacando por pantalla lo que hacen. | Las dos órdenes mas complejas e importantes para la gestión de los contenedores son: * ''docker container run'' * ''docker container exec'' ==== docker container run ==== Pone en marcha la imagen creando un contenedor.Su forma mas sencilla de usar es ''docker run container nombre_imagen''. Aunque prácticamente siempre se usan la mayoría de los siguientes parámetros: * ''-d'': Indicar que es un servidor (demonio) * ''-it'': Si queremos interactuar en la consola con la aplicación (NO es un demonio). [[https://stackoverflow.com/questions/41916435/practically-what-is-the-difference-between-docker-run-dit-itd-vs-docker-run|Practically, what is the difference between docker run -dit(-itd) vs docker run -d?]] * ''--restart always'' : Añadiremos este flag si queremos que se vuelva a iniciar el contenedor si acaba dicho contenedor. Es útil ya que se iniciará el contenedor si se reinicia la máquina real. * ''--name nombreContanedor'': Indica el nombre que va a tener el contenedor. Es muy útil ya que así sabemos cual es cada una de las imágenes. * ''--hostname nombreHost'': Indica el nombre DNS que va a tener la máquina. * ''-p puertoExterno:puertoInterno'': Indica en que puerto de la máquina real se "//mapea//" el puerto que usa el software servidor del contenedor. * ''-e nombreVariableDeEntorno:valorVariableDeEntorno'': Permite indicar el valor de una variable de entorno. Es la forma mas común de configurar un contenedor. Se debe mirar la configuración de la imagen para saber las variables a usar ya que es específico de cada imagen. * ''-v carpetaMaquinaReal:carpetaInternaContenedor'': Indica que una carpeta de dentro del contenedor será realmente una carpeta real de nuestra máquina. Se usa para que no se pierdan los datos si borramos la máquina y la volvemos a crear. Si usamos una carpeta real , deberá tener todos los permisos ya que el usuario que usa el contenedor es distinto al nuestro. * Ejecuta [[https://hub.docker.com/_/mariadb|mariadb del tag 10.1]] * En modo demonio * Que si por algún motivo acaba el contenedor se vuelva a reiniciar * Los datos de "/var/lib/mysql" se guardarán en la carpeta local "/opt/mariadb". Está indicado en la documentación de la imagen. * Se indica que la variable de entorno MYSQL_ROOT_PASSWORD tiene el valor de **root**. Esto se hace para configurar la contraseña de root de la imagen. Está indicado en la documentación de la imagen * Se verá en el puerto 4000 * Se llamará el contenedor "prueba_mariadb" docker container run \ -dit \ --restart always \ -v /opt/mariadb:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=root \ -p 4000:3306 \ --name prueba_mariadb \ --hostname prueba_mariadb \ mariadb:10.1 Lo mas complicado de la orden ''docker container run'' son los parámetros ''-v'' y ''-p'' === Más opciones === Veamos ahora otras opciones de ''docker container exec'' * ''--rm'': Que se borre el contenedor si éste se para. * ''-w carpeta'': La carpeta en la que se estarán en el contenedor cuando se ejecute algo. Es como hacer un ''cd'' * Otra opción que suelen tener los contenedores, es poder pasar argumentos después del nombre de la imagen. Eso argumentos a veces son realmente argumentos al programa que se va a ejecutar y otras veces es directamente el nombre del programa que se va a ejecutar junto a sus argumentos. Veremos ejemplos de ésto en el siguiente tema docker container run \ -dit \ --restart always \ --rm \ -w /var/lib/mysql \ -v /opt/mariadb:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=root \ -p 4000:3306 \ --name prueba_mariadb \ --hostname prueba_mariadb \ mariadb:10.1 hemos añadido ''--rm'' para indicar que si el contenedor acaba y se para, que automáticamente también se borre. Y también hemos añadido ''-w /var/lib/mysql'' para //estar// en esa carpeta. Y así por ejemplo si lanzásemos ''docker container exec -it prueba_mariadb ls'', se verían los ficheros de la carpeta ''/var/lib/mysql''. ==== docker container exec ==== Permite lanzar órdenes dentro del contanedor. Podría verse como algo similar a conectarse por ssh al contenedor. * Muestra el contenido del fichero ''/etc/passwd'' que está dentro del contenedor docker container exec -it nombre_container cat /etc/passwd * Ejecutar bash dentro del contenedor par poder lanzar culaquier orden dentro de él. docker container exec -it nombre_container /bin/bash ===== Ejercicios ===== Para hacer estos ejercicios deberás tener instalado una máquina virtual de VirtualBox con [[https://releases.ubuntu.com/18.04.5/|Ubuntu Server 18.04.5]]. Aunque no es necesario si ya usas Linux en tu equipo. Al instalar Ubuntu recuerda marcar el servidor de SSH cuando te pida el software a instalar. Al instalar Ubuntu si estás en el centro recuerda también indicar el proxy ==== Ejercicio 1 ==== Dada las siguientes dos imágenes: * [[https://hub.docker.com/_/jenkins|jenkins]] * [[https://hub.docker.com/r/jenkins/jenkins|jenkins/jenkins]] Responde: * ¿Cual usarías?Explica porqué Indica las órdenes para realizar lo siguiente: * Baja a tu máquina la última versión de la imagen que has elegido. * Baja a tu máquina otra imagen con el tag "lts" de la imagen que has elegido. * Muestra las imágenes que tienes descargadas en tu máquina * Borra una de las imágenes que tienes * Muestra las imágenes que tienes descargadas en tu máquina * Guarda la imagen que tienes en un fichero * Borra la imagen que aun queda * Carga la imagen que habías guardado en un fichero * Muestra las imágenes que tienes descargadas en tu máquina ==== Ejercicio 2 ==== Con la imagen de Jenkins que te has bajado, crea un contenedor con los siguientes datos: * El puerto interno 8080 que se vea en la máquina en el puerto 11211 * Que los datos de configuración de Jenkins (en "/var/jenkins_home") se guarden en la carpeta "/opt/prueba_jenkins" de la máquina real en * Que el nombre del contenedor sea "prueba_jenkins" * Que el nombre DNS sea "jenkins" * Que sea un demonio Ahora vamos a configurar Jenkins: * Navega a la IP de tu máquina Linux, deberá ver la página del Jenkins que acabas de instalar. * Indica de 3 formas distinta como mostrar el contenido (usando cat) del fichero ''/var/jenkins_home/secrets/initialAdminPassword'' del contenedor. * Viéndolo desde la carpeta que está dentro del contenedor * Viéndolo desde la carpeta que está en la máquina real * Usando bash dentro del contenedor y una dentro del bash del contenedor, mostrar el contenido del fichero. * Pega el contenido del fichero "initialAdminPassword" en la página web y pulsa "continue" * Pulsa en "Install seuggested plugins" * Crea el usuario que se llamará "system_builder" y pulsa "Save and Continue" * Pulsa "Save and Finish" * Pulsa "Start using Jenkins" Se deberá mostrar una imagen similar a la siguiente: {{:clase:daw:daw:2eval:jenkins.png?600|}} ==== Ejercicio 3 ==== Indica los siguientes comandos: * Muestra la lista de contenedores. * Borra el contenedor de Jenkins. No te dejará. * Para el contendor de Jenkins * Muestra la lista de contenedores. No debe verse el de Jenkins. * Mira por internet la opción para ver "TODOS" los contendores.Y muestra ahora todos los contenedores. * Borra el contenedor de Jenkins. Ya te dejará. * Vuelve a crear el contenedor de Jenkins como en el ejercicio anterior. Navega a la página web del Jenkins y comprueba que ya está todo instalado. ¿Como es que no se ha borrado si hemos borrado el contenedor y vuelto a crearlo? ==== Ejercicio 4 ==== Indica los siguientes comandos: * Arranca un contenedor de [[https://hub.docker.com/_/mariadb/|MariaDB. Tag: 10.1 ]] pero no indiques nada referido a las carpetas. Haz lo siguiente: * Conéctate desde tu ordenador Windows al MariaDB y crea una tabla e inserta un dato. Indica los siguientes comandos: * Borra el contenedor de MariaDB * Arranca un contenedor de MariaDB pero no indiques nada referido a las carpetas Haz lo siguiente: * Conéctate desde tu ordenador Windows al MariaDB y comprueba que no está la tabla que habías creado. ==== Ejercicio 5 ==== Indica los siguientes comandos: * Arranca un contenedor de [[https://hub.docker.com/_/mariadb/|MariaDB. Tag: 10.1 ]] pero ahora indica que la carpeta "/var/lib/mysql" se guarde en "/opt/mariadb" de la máquina real Haz lo siguiente: * Conéctate desde tu ordenador Windows al MariaDB y crea una tabla e inserta un dato. Indica los siguientes comandos: * Borra el contenedor de MariaDB * Arranca un contenedor de MariaDB y vuelve a indicar que la carpeta "/var/lib/mysql" se guarde en "/opt/mariadb" de la máquina real Haz lo siguiente: * Conéctate desde tu ordenador Windows al MariaDB y comprueba que **SI** que está la tabla que habías creado. ==== Ejercicio 6 ==== Indica los siguientes comandos: * Arranca un contenedor de [[https://hub.docker.com/_/php/|PHP con apache. Tag: 7.2-apache]] e indica que la carpeta "/var/www/html" se guarde en "/opt/apache" de la máquina real y que el puerto 80 del contenedor se vea en el puerto 22322 de la máquina real. Crea el fichero index.php con el siguiente contenido Cópialo de forma que navegando a "http://localhost:22322" se vea el resultado que ha generado la página en php. Será similar a lo siguiente: {{:clase:daw:daw:2eval:php.png?600|}} ==== Ejercicio 7 ==== * Reinicia la máquina real. * Comprueba que navegando a "http://localhost:22322" se produce un error. * Borra el contenedor * Vuelve a crear el contenedor pero ahora añade que siempre se reinicie. * Reinicia la máquina real * Comprueba que navegando a "http://localhost:22322" ahora si que funciona.