Índice
1. Problema
Aunque podamos encontrar Docker compatible con Apple Silicon desde su versión 3.3.1, existen aún múltiples imágenes generadas exclusivamente para arquitectura Intel, o mejor dicho, x86.
Como ya se recoge en la página oficial, las imágenes que no hayan sido contempladas para ARM se ejecutarán bajo simulación de x86, pero no aseguran un buen rendimiento y/o errores de ejecución o emulación, delegando a los desarrolladores la responsabilidad de hacer compatible las imágenes con múltiple arquitectura.
En líneas generales, trabajar imágenes preparadas solo en x86 en los nuevos procesadores Apple Silicon es casi imposible. Un ejemplo es la ejecución de Kafka bajo las imágenes de cp-confluent. Levantar un simple contenedor de Kafka con Zookeper puede llevar minutos y es muy probable que nos encontremos errores aleatorios de emulación de QEMU. Estos problemas ya son reconocidos por Confluent, pero aún no hay noticias para la versión de ARM.
En este tutorial se muestran los pasos para preparar una imagen de Docker nativa de ARM y ejecutar Kafka bajo contenedores.
Actualización (15/02/2021)
Existen otras alternativas para conseguir imágenes de Kafka nativas para ARM a mano de Wurstmeister. Se recomienda probar con estas imágenes antes de proceder con este tutorial y evitar la compilación manual de las imágenes si es posible. Las imágenes se pueden encontrar aquí.
2. Entorno
El tutorial está escrito usando el siguiente entorno:
- Hardware: Macbook Pro (Finales 2021) Apple Silicon, M1 Pro (10N), 32GB RAM, 1TB SSD.
- Sistema Operativo: Mac OS Monterrey 12.1
- JDK 11.0.14-Zulu.
- Maven: 3.8.4
- Docker Desktop 4.4.2 (73305) (Apple Silicon version)
- Socat
- Clonar los proyectos de confluentinc para crear las imágenes de Kafka:
Estos proyectos utilizan maven para la creación de las imágenes de Docker a partir de las dependencias especificadas en el pom.xml y la arquitectura utilizada en el ordenador local.
Primero debemos compilar la imagen de common-docker antes de poder construir la imagen de Kafka y Zookeper.
2. Por consola nos colocamos en la raíz del proyecto common-docker.
3. La versión utilizada para este tutorial es la versión 7.0.0 (el tutorial en el que se basa esta guía utiliza la versión 7.0.1, pero como está recogido en GitHub, contiene un bug que impide ejecutar Kafka de manera correcta), por lo que nos colocamos en esa versión con:
git checkout tags/v7.0.0
4. Algunas dependencias y propiedades se deben actualizar para que puedan ser descargadas correctamente. Para ello, sobre escribimos en el pom.xml los siguientes parámetros con estas propiedades:
<ubi.openssl.version>1.1.1k-5.el8_5</ubi.openssl.version> <ubi.netcat.version>7.70-6.el8</ubi.netcat.version> <ubi.python36.version>3.6.8-38.module+el8.5.0+12207+5c5719bc</ubi.python36.version> <ubi.krb5.workstation.version>1.18.2-14.el8</ubi.krb5.workstation.version> <ubi.zulu.openjdk.version>11.0.14</ubi.zulu.openjdk.version> <docker.skip-security-update-check>true</docker.skip-security-update-check>
5. Añadimos en el pom.xml el repositorio de confluent
<repositories> <repository> <id>confluent</id> <url>https://packages.confluent.io/maven/</url> </repository> </repositories>
6. Creamos la imagen de common-docker con el siguiente comando:
mvn clean package \ -DskipTests -Pdocker \ -Ddocker.registry=nxt/
(Este paso requiere bastante tiempo, por lo que podéis aprovechar para tomar un café)
NOTA: Es posible que docker-maven-plugin falle debido al bug con el SOC de Apple Silicon. Para solventar este problema, podemos abrir el puerto TCP a través de socat, como ya describió Alejandro Perez García en Adictos, o bien subir manualmente la versión de fabric8 a partir de la versión 0.38.1 en el pom.xml.
7. Una vez creada la imagen de common-docker, podemos irnos a la raíz del proyecto de kafka-images.
8. Nos colocamos en la versión 7.0.0
git checkout tags/v7.0.0
9. Repetimos el paso 5 con el pom.xml del proyecto de kafka-images.
10. Creamos la imagen de Docker con el siguiente comando:
mvn clean package \ -DskipTests -Pdocker \ -DCONFLUENT_PACKAGES_REPO='https://packages.confluent.io/rpm/7.0' \ -DCONFLUENT_VERSION=7.0.0 \ -Ddocker.registry=nxt/
11. Si todo ha funcionado correctamente, deberíamos poder ver nuestras imágenes a través del comando docker images | grep confluentinc
Las imágenes que utilizaremos para ejecutar kafka junto con zookeper son:
- nxt/confluentinc/cp-kafka:7.0.0-ubi8
- nxt/confluentinc/cp-zookeeper:7.0.0-ubi8
Por defecto, las imágenes se crean bajo esos nombres, pero a través de docker tag podemos cambiarlo por el nombre que queramos.
4. Conclusiones
La mejora obtenida con estas imágenes nativas son más que evidentes si se comparan con las imágenes de x86, pasando de minutos a segundos solo para levantar los contenedores y poder trabajar con ellos. Sin embargo, esta solución debería ser temporal hasta que dispongamos de imágenes oficiales por los desarrolladores de confluent.
Buenas,
en que parte del pom te refieres en esta parte ?
NOTA: Es posible que docker-maven-plugin falle debido al bug con el SOC de Apple Silicon. Para solventar este problema, podemos abrir el puerto TCP a través de socat, como ya describió Alejandro Perez García en Adictos, o bien subir manualmente la versión de fabric8 a partir de la versión 0.38.1 en el pom.xml.
Tengo este ERROR cp-base-new:
[INFO] ————————————————————————
[INFO] Reactor Summary for common-docker 7.0.0:
[INFO]
[INFO] common-docker ……………………………….. SUCCESS [ 2.272 s]
[INFO] utility-belt ………………………………… SUCCESS [ 1.949 s]
[INFO] docker-utils ………………………………… SUCCESS [ 4.301 s]
[INFO] cp-base-new …………………………………. FAILURE [ 14.700 s]
[INFO] cp-jmxterm ………………………………….. SKIPPED
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 23.483 s
[INFO] Finished at: 2022-02-24T13:55:11-03:00
[INFO] ————————————————————————
[ERROR] Failed to execute goal com.spotify:dockerfile-maven-plugin:1.4.13:build (package) on project cp-base-new: Could not build image: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: java.lang.UnsatisfiedLinkError: could not load FFI provider com.spotify.docker.client.shaded.jnr.ffi.provider.jffi.Provider: ExceptionInInitializerError: Can’t overwrite cause with java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: Can’t load library: /var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/T/jffi5512377056960059468.dylib
[ERROR] at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2393)
Buenas,
Tiene pinta que falla por el plugin de docker-maven-plugin de fabric8io, ¿has probado habilitando el puerto a través de socat? O subiendo la versión del plugin (puedes hacerlo desde la propiedad dependencies del proyecto de maven).