domingo, 30 de octubre de 2022

Docker (12) : Retomar docker en 2022 (1). Problemas de espacio docker

 1. Instalar docker en Linux Mint

#1. Update references
sudo apt update

#2. Install docker
sudo apt install docker*

#3. Verify docker version
docker --version

#4. ONLY IF there are permission problems change "mod"
sudo chmod 666 /var/run/docker.sock

2. Descargar y ejecutar imágenes desde el "Docker Registry"

#1. Descargar una imagen desde el Docker Registry
docker pull busybox  # Recoge la imagen "busybox

#2. Listar las imágenes que hemos descargado
docker images

#3. Ejecutar una imagen (y después se detiene la ejecución) (mata el proceso). Tambien puede hacer el "pull" si no se ha desgardao aún
docker run busybox # Ejecuta la imagen busybox que previamente hemos descargado

#4. Ejecutar una imagen (busibox) pasándole un parámetro (echo "hello from busybox") y despues se mata el proceso
docker run busybox echo "hello from busybox"

#5. Mostrar los procesos en ejecución
docker ps # Si los procesos anteriores han dejado de ejecutarse, no mostrará ninguno

#6. Mostrar los procesos y su estado (tanto si se han matado o están activos)
docker ps -a

#7. Ejecutar una imagen en modo iterativo (No mata el proceso)
docker run -it busybox sh # Abre una shell (terminal) y podemos ejecutar comandos hasta que terminemos con el comando "exit"

#8. Ejecutar una imagen i despues eliminarla (opción --rm)
docker run --rm busybox echo "hello from busybox" # Se ejecuta y se elimina la imagen

#9. Descarga (Elimina) los contenedores cargados a partir de su ID 
docker rm 305297d7a235 ff0a5c3750b9 # Elimina 2 procesos. Sus ID se muestran con el comando "docker ps -a"

#10. Eliminar de una vez todos los contenedores que estan parados o no activos
docker rm $(docker ps -a -q -f status=exited)
#11. Eliminar imagenes por ID (los ID se obtienen desde "docker image")
docker rmi 305297d7a235 304694e7a432 

3. Conceptos de Docker

Image: Imagen que se suele descargar desde "Docker Registy" con "docker pull"

Container:  Se crea a partir de ejecutar una imagen con "docker run", se listan con "docker ps"

Daemon: Servicio en background (segundo plano)  de la máquina anfitrión (host) que se encarga de "building, running y distribución " de los Containers.

Client: Herramienta de línea de comando que que permite al usuario interactuar con el daemon.

Hub: Registro de todas las images.

4. Puertos, contenedores detached (creacion y parada), Imagenes

#1. Descargar una imagen desde el Docker Registry, ejecutarla en mode interactivo (-it) y borrarla despues (--rm)
docker run --rm -it prakhar1989/static-site

#2. Descargar la imagen y separar el terminal (-d "detach") y publicar los puertos aleatoriamente (-P), y renombrar la imagen (--name)
docker run -d -P --name static-site prakhar1989/static-site

#3. Mostrar los puertos de la imagen por su nombre
docker port static-site # Y contesta 80/tcp -> 0.0.0.0:32769 y 443/tcp -> 0.0.0.0:32768
                        # Podemos abrir en el navegador la aplicación http://localhost:32769  

#4. Ejecutar la imagen y asignarle un puerto (-p)
docker run -p 8888:80 prakhar1989/static-site   # Abrimos el navegador http://localhost:8888 

#5. Parar la ejecución por ID o por nombre
docker stop static-site

Las imágenes en docker se pueden clasificar de 2 formas distintas

Base/Child: Las imagenes BASE no tienen padre (normalmente son SO). Las CHILD se instalan sobre las BASE y le aportan funcionalidad (Tomcat, Firefox..)

Official/User: OFFICIAL se mantienen y soportan desde Docker, como ubuntu, phyton ... Las USER son imagenes de usuario y su formato es usuario/nombre-imagen

5. Ejemplo de descarga de un tomcat y desplegar un fichero war

Buscamos en google "docker tomcat" y seleccionamos la entrada "tomcat- Official Image | Docker Hub", y podemos seleccionar una de estos 2 entradas (jre17-temurin-jammy o tambien 10.1.1-jdk17-temurin-jammy) donde "temurin" es el nombre de la distribución de java 17 y "jammy" es una version de Ubuntu



5.1 Prueba de carga y eliminación de la imagen (No hacer caso, solo a modo de ejemplo)

Y podemos ejecutar comprobar que existe dicha imagen, probar tomcat y luego eliminar el contenedor y la imagen 

#1. Descargar una imagen del Docker Hub con prefijo tomcat: y sufijo el de la imagen
docker pull tomcat:10.1.1-jdk17-temurin-jammy

#2. Ahora se ejecuta en modo detached y asignando el puerto 8080
docker run -d -p 8080:8080 tomcat:10.1.1-jdk17-temurin-jammy

#3. Probar el navegador http://localhost:8080 y no encuentra la página
#   Pero responde Tomcat
#4. Buscamos el container y obtenemos su ID (pr ejemplo e31e38ca842e)
docker ps -a

#5. Eliminamos el container
docker rm e31e38ca842e

#6. Eliminamos la imagen
docker rmi tomcat:10.1.1-jdk17-temurin-jammyPo

5.2 Proceso

1. Creamos una carpeta por ejemplo "docker-ximo", nos situamos en ella, copiamos el "fichero war" dentro de ella y creamos el fichero "Dockerfile" con este contenido

FROM tomcat:jdk17-temurin 
COPY mywar.war /usr/local/tomcat/webapps/ (Ver el fichero propuesto en el punto 6)

2. Creamos la imagen a partir del Dockerfile

docker build -t ximo-app .

3. Ejecutamos el contenedor de docker y averiguamos que puerto tiene y probamos en el navegador

docker run -itd  -P --name my-app-cont ximo-app

docker port my-app-cont

4. Observamos que hay problemas cuando usmos el navegador para acceder a http://localhost:49153/mywar/ ya que aunque se reconce la URL, no muestra nada pues hay recursos que pide y el host responde con 404 en cada uno. Seguramente puede que sea un tema de permisos de ficheros.

5. Al final el error procedia de la generación del WAR. La parte de usuario WEB se ha hecho en React y el fichero "paqckage.json" tenia esta referencia:

"homepage": "/W01-CSV",

Y se tendria que cambiar "/W01-CSV" por "/mywar" y volver a generar toda la parte de usuario en Visual Studio, y volver a copiar estos ficheros en la carpeta src/main/wevbapp de Eclipse

6. Modificar ficheros dentro de la imagen de Docker

Para ello actuamos tal como se indica en J->Hooq. Que adjuntamos un pequeño esquema

#1. Log into the container (by its ID) as root user (-u 0 option)
#   Note that "/bin/bash" can be changed with "/bin/sh"
docker exec -u 0 -it 4d58f2bd56b0 /bin/bash

#2. Install the nano editor
apt-get update
apt-get install nano

#3. Edit the file you want
nano myfile.txt
#4. You can use many bsh commands like ls, chmod etc ..
chmod 777 myfile.txt

NOTA: si se rearranca la imagen, hay que volver a instalar los paquetes en el contenedor. Por tanto, el fichero Dockerfile puede quedar como sigue:

FROM tomcat:jdk17-temurin 
COPY mywar.war /usr/local/tomcat/webapps/

RUN ["apt-get", "update"]
RUN ["apt-get", "-y", "install", "nano"]


7. Copiar ficheros entre contenedore docker y el ordenador físico (local)

7.1 Copiar ficheros desde el contenedor docker al ordenador físico

Los pasos son:

1. Ver el id del container con docker ps -a (por ejemplo id=d880ce60664d)

1. Entrar en el bash shell del container con 
docker exec -u 0 -it d880ce60664d /bin/bash

2. Crear un fichero (por ejemplo con ls>kk.ximo.txt) y anotar la carpeta donde hemos creado el fichero (por ejemplo /usr/local/tomcat)

3. Salir del bash shell con exit

4. Copiamos el fichero a nuestro ordenador con 
docker cp d880ce60664d:/usr/local/tomcat/kk-ximo.txt ~/fromDocker.txt

7.2 Copiar ficheros desde el ordenador físico al contenedor docker

Los pasos son:

1. Copiamos el fichero f_local.txt al contenedor nuesto ordenador con 
docker cp ~/f_local.txt d880ce60664d:/usr/local/tomcat/fromLocal.txt

8. Compartir carpetas entre el host y el contenedor docker

Creamos una carpeta por ejemplo afldr en el directorio acutal (el que se muestra la variable de entorno $PWD)  y queremos que el contenedor tenga esta carpeta mapeada a su carpeta interna  /opt/bfldr para ello ejecutamos

docker exec -u 0 -v $PWD/afldr:/opt/bfldr -it d880ce60664d /bin/bash

y podemos ejecutar dentro de la shell del contenedor: 

ls -al /opt/bfldr

dentro de la shell del contenedor y vemos que si que existe esa capeta

9. Problemas con el espacio de disco que consume docker. Cambiar la ubicacion de los ficheros de docker.NO VA BIEN!!!

NOTA: Lo bueno que tiene este proceso es que es reversible. Dejando los parámetros tal come estaba no pasa nada.

NOTA: Ir con cuidado pues parece ser que esto no funciona bien en las versiones nuevas, pues en imágenes de Oracle no funcionan bien y cuabndo rearrancamos el oprdenador se pierde la configuración!

Si tenemos problemas de espacio, podemos trasladar los ficheros de docker a otro sistema de ficheros, tal como se inidca en Wiki CasaOs y tambien en Baeldung. Para elllo podemos actuar de tres maneras:

  • Cambiando el nombre de /var/lib/docker (por ejmplo /var/lib/docker.old) Haciendo un link desde /var/lib/docker a la nueva ubicación 
  • Cambiando directamente la nueva ubicación en el fichero docker.service
  • Modificando el fichero /etc/docker/daemon.json

1. Analizar donde tenemos los ficheros de docker

Para ver el espacio consumido por docker hacemos

docker system df

y nos muestra

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          1         1         8.578GB   0B (0%)    
Containers      1         1         141.1GB   0B (0%)    
Local Volumes   1         1         33.19GB   0B (0%)    
Build Cache     0         0         0B        0B          

Podemos ver que nos esta comiendo muchio disco

Para ver donde se encuentran los ficheros docker (imagenes y contenedores):

docker info | grep Root

(o también docker info -f '{{ .DockerRootDir }}')y contesta

Docker Root Dir: /var/lib/docker

También, los volúmenes están ocupando información para mostrar donde se guardan los volúmenes, hay que ver que volúmenes disponemos con 

docker volume ls

que me contesta:

DRIVER    VOLUME NAME       
local     ximo-oracle-volume

y luego, para cad columen ejecutamos

docker volume inspect nombre_volumen

y para el volumen ximo-oracle-volumen constesta:

[                                                                        
    {                                                                    
        "CreatedAt": "2023-09-20T12:59:48+02:00",                        
        "Driver": "local",                                               
        "Labels": null,                                                  
        "Mountpoint": "/var/lib/docker/volumes/ximo-oracle-volume/_data",
        "Name": "ximo-oracle-volume",                                    
        "Options": null,                                                 
        "Scope": "local"                                                 
    }                                                                    
                                                                      


2. Detener contedores en marcha

Para ello mostramos los contenedores en marcha con:

docker ps

Y paramos cada uno de ellos con 

docker stop container_id

3. Detener el servicio de docker


#sudo systemctl stop docker.service
#sudo systemctl stop docker.socket
sudo systemctl stop docker

4. Copiar el contenido de la carpeta docker al nuevo destino 

Para copiar el contenido original de /var/lib/docker al nuevo destino

sudo rsync -aqxP /var/lib/docker/ /new/path/docker

Donde las opciones dadas son:

  • -a: permite modo archivo
  • -q: no muestra los mensajes informativos
  • -x: evita traspasar los límites de del sistema de ficheros cuando copia directorios recuisivamente
  • -P: preserva los ficheros y directorios coopiados parcialmente.

5.  Renombrar la carpeta /var/lib/docker y crearle un link a la nueva

Y cambiamos el nombre de /var/lib/docker a /var/lib/docker.old

sudo mv /var/lib/docker /var/lib/docker.old

6.  OPCION 1: Crear un link a la nueva carpeta

Creamos un link que apunte /new/path/docker desde /var/lib/docker

sudo ln -s /new/path/docker /var/lib/docker

6. OPCIÓN 2: Cambiar el fichero /lib/systemd/system/docker.service y añadir la opccion --data-root  /new/path/docker al contenido a la línea indicada

Para ello comentamos la línea anterior y escribimos una nueva

#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root /media/eduard/COPIES_SEGURETAT/docker

6. OPCIÓN 3: Cambiar el fichero de configuración del Daemon /etc/docker/daemon.json

Para ello modificamos el fichero /etc/docker/daemon.json para que quede:

{                                        
   "data-root": "/new/path/docker"       
                                      

7. Rearrancar docker

sudo systemctl daemon-reload
sudo systemctl restart docker

Y comprobamos que está todo correcto

 ps aux | grep -i docker | grep -v grep

Y nos muestra para la primera opción

root     31912  1.1  0.2 1507076 74036 ?       Ssl  13:14   0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Y para la segunda opción

root     31912  1.1  0.2 1507076 74036 ?       Ssl  13:14   0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root /new/path/docker


Con lo que parece que vaya bien. Podemos ver las imagenes, contenedores, arrancarlos etc.

8. Errores aparecidos

1. Tanto en la primera opción como en la segunda opción cuando ejecutamos DBeaver e intentamos conectarnos a la BD oracle, entonces nuestro contenedor se para!

2. En la opción 3 (la de cambiar el /etc/docker/daemons.json) si rearrancamos la máquina, pierde toda la información.