====== 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 =====
* **Producción**
* IP: 192.168.59.104
* Gateway: 192.168.59.1
* DNS:
* Nombre dominio: //**loquesea**//.daw2.pve3.fpmislata.com
* **Preproducción**
* IP: 172.16.0.205
* Gateway: 172.16.0.254
* DNS: 172.16.0.5
* Nombre dominio: //**loquesea**//.daw2.fp
==== Proxmox ====
Datos de conexión de Proxmox a los 2 entornos:
Están ocultos
* Proxmox
* Producción: https://sauron.pve3.fpmislata.com:8006
* Preproducción: https://proxmox1:8006/
===== 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''
* ''--pull=never'': Hace que si no existe la imagen no la descargue. Ya que por defecto lo hace y normalmente suele ocurrir cuando hemos escrito mal el nombre de la imagen.
* 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 \
--rm \
--pull=never \
-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''. Por último hemos dicho con ''--pull=never'' que si no existe la imagen no la descargue.
==== docker container exec ====
Permite lanzar órdenes dentro del contenedor. 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.