Kubernetes: construyendo imágenes de Docker en un clúster

Puede usar kaniko para construir imágenes de Docker en un contenedor sin Docker. Veamos cómo ejecutar kaniko localmente y en un clúster de Kubernetes.


imagen
El siguiente será un libro múltiple


Supongamos que decide crear imágenes de Docker en un clúster de Kubernetes (bueno, debe hacerlo). Lo que es conveniente, echemos un vistazo a un ejemplo real, de manera más clara.


También hablaremos sobre Docker-in-Docker y su alternativa, kaniko, con la que puedes construir imágenes de Docker sin usar Docker. Finalmente, aprenderemos cómo configurar el ensamblaje de imágenes en el clúster de Kubernetes.


Una descripción general de Kubernetes se encuentra en el libro "Kubernetes in Action" ("Kubernetes in Action") .


Ejemplo real


En la web nativa, tenemos muchas imágenes privadas de Docker que deben almacenarse en algún lugar. Entonces implementamos un Docker Hub privado. El Docker Hub público tiene dos características en las que estamos particularmente interesados.


Primero, queríamos crear una cola que recolectara imágenes de Docker en Kubernetes de forma asincrónica. En segundo lugar, implemente el envío de las imágenes recopiladas al registro privado de Docker .


Por lo general, la CLI de Docker se usa directamente para implementar estas funciones:


$ docker build ... $ docker push ... 

Pero en el clúster de Kubernetes, alojamos contenedores basados ​​en imágenes pequeñas y elementales de Linux, en las que Docker no está contenido de manera predeterminada. Si ahora queremos usar Docker (por ejemplo, Docker docker build... ) en un contenedor, necesitamos algo como Docker-in-Docker.


¿Qué le pasa a Docker-in-Docker?


Para recopilar imágenes de contenedor en Docker, necesitamos un demonio Docker en ejecución en el contenedor, es decir, Docker-in-Docker. El demonio Docker es un entorno virtualizado, y el contenedor en Kubernetes se virtualiza por sí solo. Es decir, si desea ejecutar el demonio Docker en un contenedor, debe usar la virtualización anidada. Para hacer esto, ejecute el contenedor en modo privilegiado para obtener acceso al sistema host. Pero esto plantea problemas de seguridad: por ejemplo, debe trabajar con diferentes sistemas de archivos (host y contenedor) o utilizar la memoria caché de compilación del sistema host. Es por eso que no queríamos tocar Docker-in-Docker.


Conocido con kaniko


No solo Docker-in-Docker ... Hay otra solución: kaniko . Esta es una herramienta escrita en Go , que recopila imágenes de contenedores de un Dockerfile sin Docker. Luego los envía al registro Docker especificado. Se recomienda configurar kaniko: use una imagen de ejecutor preparada que se pueda ejecutar como un contenedor Docker o un contenedor en Kubernetes.


Solo tenga en cuenta que kaniko todavía está en desarrollo y no es compatible con todos los comandos de Dockerfile, por ejemplo --chownflag para el COPY .


Lanzamiento Kaniko


Si desea ejecutar kaniko, debe especificar varios argumentos para el contenedor kaniko. Primero inserte el Dockerfile con todas sus dependencias en el contenedor kaniko. Localmente (en Docker), se -v <__>:<__> parámetro -v <__>:<__> , y Kubernetes tiene volúmenes .


Después de insertar la dependencia Dockerfile en el contenedor kaniko, agregue el argumento --context , indicará la ruta al directorio adjunto (dentro del contenedor). El siguiente argumento es --dockerfile . Indica la ruta al Dockerfile (incluido el nombre). Otro argumento importante es el --destination con la URL completa del registro de Docker (incluido el nombre y la etiqueta de imagen).


Lanzamiento local


Kaniko comienza de varias maneras. Por ejemplo, en la computadora local usando Docker (para no meterse con el clúster de Kubernetes). Ejecute kaniko con el siguiente comando:


 $ docker run \ -v $(pwd):/workspace \ gcr.io/kaniko-project/executor:latest \ --dockerfile=<path-to-dockerfile> \ --context=/workspace \ --destination=<repo-url-with-image-name>:<tag> 

Si la autenticación está habilitada en el registro de Docker, kaniko primero debe iniciar sesión. Para hacer esto, conecte el config.jsonfile Docker config.jsonfile local con credenciales para el registro Docker al contenedor kaniko usando el siguiente comando:


 $ docker run \ -v $(pwd):/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json \ gcr.io/kaniko-project/executor:latest \ --dockerfile=<path-to-dockerfile> \ --context=/workspace \ --destination=<repo-url-with-image-name>:<tag> 

Lanzamiento en Kubernetes


En el ejemplo, queríamos ejecutar kaniko en un clúster de Kubernetes. Y también necesitábamos algo así como una cola para ensamblar imágenes. Si se produce un error al ensamblar o enviar la imagen al registro de Docker, sería bueno que el proceso se inicie automáticamente nuevamente. Para esto, hay un trabajo en Kubernetes. Configure backoffLimit especificando con qué frecuencia el proceso debe reintentarse.


La forma más fácil de incrustar un Dockerfile con dependencias en un contenedor kaniko es con el objeto PersistentVolumeClaim (en nuestro ejemplo, se llama kaniko-workspace ). Estará vinculado al contenedor como un directorio, y todos los datos ya deberían estar en kaniko-workspace . Digamos que en otro contenedor ya hay un Dockerfile con dependencias en el kaniko-workspace /my-build en kaniko-workspace .


No olvide que en AWS tiene problemas con PersistentVolumeClaim. Si crea un PersistentVolumeClaim en AWS, aparecerá solo en un nodo en el clúster de AWS y solo estará disponible allí. (upd: de hecho, al crear un PVC, se creará un volumen RDS en una zona de disponibilidad aleatoria de su clúster. En consecuencia, este volumen estará disponible para todas las máquinas en esta zona. Kubernetes controla que debajo de él usando este PVC se lanzará en un nodo en la zona de disponibilidad RDS volyuma. - Aprox. Por.) Entonces, si ejecuta Job kaniko y esta tarea está en otro nodo, no se iniciará porque PersistentVolumeClaim no está disponible. Esperemos que Amazon Elastic File System esté disponible en Kubernetes pronto y el problema desaparezca. (upd: EFS en Kubernetes es compatible con el aprovisionador de almacenamiento . - aprox .)


El recurso de trabajo para crear imágenes de Docker generalmente se ve así:


 apiVersion: batch/v1 kind: Job metadata: name: build-image spec: template: spec: containers: - name: build-image image: gcr.io/kaniko-project/executor:latest args: - "--context=/workspace/my-build" - "--dockerfile=/workspace/my-build/Dockerfile" - "--destination=<repo-url-with-image-name>:<tag>" volumeMounts: - name: workspace mountPath: /workspace volumes: - name: workspace persistentVolumeClaim: claimName: kaniko-workspace restartPolicy: Never backoffLimit: 3 

Si el registro Docker de destino requiere autenticación, pase el archivo config.json con las credenciales al contenedor kaniko. La forma más fácil es conectar PersistentVolumeClaim a un contenedor que ya tiene un archivo config.json . Aquí PersistentVolumeClaim se montará no como un directorio, sino como un archivo en la ruta /kaniko/.docker/config.json en el contenedor kaniko:


 apiVersion: batch/v1 kind: Job metadata: name: build-image spec: template: spec: containers: - name: build-image image: gcr.io/kaniko-project/executor:latest args: - "--context=/workspace/my-build" - "--dockerfile=/workspace/my-build/Dockerfile" - "--destination=<repo-url-with-image-name>:<tag>" volumeMounts: - name: config-json mountPath: /kaniko/.docker/config.json subPath: config.json - name: workspace mountPath: /workspace volumes: - name: config-json persistentVolumeClaim: claimName: kaniko-credentials - name: workspace persistentVolumeClaim: claimName: kaniko-workspace restartPolicy: Never backoffLimit: 3 

Si desea verificar el estado de un trabajo de compilación en kubectl , use kubectl . Para filtrar el estado por stdout , ejecute el comando:


 $ kubectl get job build-image -o go-template='{{(index .status.conditions 0).type}}' 

Resumen


Aprendiste del artículo cuando Docker-in-Docker no es adecuado para construir imágenes de Docker en Kubernetes. Tengo una idea de kaniko, una alternativa a Docker-in-Docker, con la que se ensamblan las imágenes de Docker sin Docker. También aprendimos cómo escribir recursos de Job para recopilar imágenes de Docker en Kubernetes. Y finalmente, vieron cómo averiguar el estado de una tarea en curso.

Source: https://habr.com/ru/post/es436126/


All Articles