Publicar imágenes Docker usando plugin de arranque de primavera sin credenciales

Tengo un proyecto de Gradle con plugin de Spring Boot y estoy tratando de publicar la imagen construida por el plugin: gradle bootBuildImage --publishImage

El problema es publicar "ya sea token o nombre de usuario/password debe ser proporcionado" y no podemos hacer eso ya que tenemos diferentes mecanismos de autenticación en diferentes ambientes. Por ejemplo en la máquina local usamos ecr-credentials-helper y los usos del oleoducto aws ecr get-login-token | docker login.

¿Hay alguna manera de forzar el plugin para dejar que el docker maneja la autenticación? (Asumo que el plugin utiliza el daemon del docker en el host).

Actualmente escribí una tarea para generar un archivo token usando aws ecr get-login-token y leer el archivo de fichas en bootBuildImage tarea. Pero no me gusta esta solución, por razones de seguridad.

Pregunta hecha hace 3 años, 5 meses, 0 días - Por techtrailblazer


4 Respuestas:

  • Aquí hay una solución que replica aws ecr get-login-password dentro de Gradle, usando el SDK AWS Java. Aunque usted podría invocar el CLI directamente desde Gradle, esto hace que el script de construcción sea más frágil, ya que entonces depende de tener una cierta versión del CLI instalado. En particular, ya que la entrada de ecr era un cambio entre v1 y v2 del CLI.

    Esto supone que tienes tus credenciales de AWS establecidas de alguna manera estándar que proveedor de credenciales predeterminadas en el SDK se ubicará.

    import software.amazon.awssdk.services.ecr.EcrClient
    
    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath platform("software.amazon.awssdk:bom:2.17.19")
            classpath "software.amazon.awssdk:ecr"
            classpath "software.amazon.awssdk:sts" // sts is required to use roleArn in aws profiles
        }
    }
    
    plugins {
        id "java"
        id "org.springframework.boot"
    }
    
    dependencies {
        implementation platform("org.springframework.boot:spring-boot-dependencies:2.5.3")
        implementation "org.springframework.boot:spring-boot-starter"
        // Rest of app dependencies
    }
    
    bootBuildImage {
        doFirst {
            String base64Token = EcrClient.create().getAuthorizationToken().authorizationData()[0].authorizationToken()
            String[] auth = new String( base64Token.decodeBase64() ).split(":", 2)
    
            docker {
                publishRegistry {
                    username = auth[0]
                    password = auth[1]
                }
            }
        }
    }
    

    Respondida el Dec 16, 2020 a las 09:36 - por techmaestro

    Votos positivos: 0 | Votos negativos: 0

  • La solución de Adrian ya no funciona con nuevas versiones de Gradle. He adaptado su solución:

    import org.springframework.boot.gradle.tasks.bundling.BootBuildImage
    import software.amazon.awssdk.services.ecr.EcrClient
    import software.amazon.awssdk.services.ecr.model.AuthorizationData
    import java.util.Base64
    
    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath(platform("software.amazon.awssdk:bom:2.20.121"))
            classpath("software.amazon.awssdk:ecr")
            classpath("software.amazon.awssdk:sts") // sts is required to use roleArn in aws profiles
        }
    }
    
    plugins {
        id("org.springframework.boot")
        kotlin("jvm")
        kotlin("plugin.spring")
    }
    
    tasks.withType {
    
        val authData: Provider = providers.provider {
            val ecrClient = EcrClient.builder().build()
            val authorizationData = ecrClient
                    .getAuthorizationToken()
                    .authorizationData()[0]
            return@provider authorizationData
        }
    
        val decodedEcrToken: Provider = authData.map { String(Base64.getDecoder().decode(it.authorizationToken())) }
        val registryUsername: Provider = decodedEcrToken.map { it.split(":")[0] }
        val registryPassword: Provider = decodedEcrToken.map { it.split(":")[1] }
    
        docker {
            publishRegistry {
                username.set(registryUsername)
                password.set(registryPassword)
            }
        }
    }
    

    Respondida el Dec 16, 2020 a las 09:43 - por bytebarricade

    Votos positivos: 0 | Votos negativos: 0

  • Para publicar una imagen Docker sin necesidad de proporcionar credenciales a través del plugin de Spring Boot, puedes hacer uso de un enfoque diferente. En lugar de utilizar el comando gradle bootBuildImage --publishImage, puedes usar un comando tradicional de Docker para construir y publicar la imagen.

    Aquí tienes un ejemplo de cómo puedes hacerlo:

    • Construye la imagen Docker usando el plugin de Spring Boot:
    bash
    ./gradlew bootBuildImage
    
    • Exporta la imagen en un archivo tar:
    bash
    docker save nombre_de_tu_imagen -o imagen.tar
    
    • Copia la imagen del archivo tar a la máquina destino y luego cárgala en Docker:
    bash
    scp imagen.tar usuario@hostname:/ruta/del/archivo
    

    En la máquina destino:

    bash
    docker load -i /ruta/del/archivo/imagen.tar
    

    De esta manera, puedes construir la imagen con el plugin de Spring Boot y luego exportarla para moverla a otra máquina sin tener que preocuparte por las credenciales de autenticación. Esto te permite evitar la necesidad de lidiar con la autenticación al publicar la imagen.

    Espero que esta solución te sea de ayuda. ¡Avísame si tienes alguna otra duda!

    Respondida el Dec 17, 2020 a las 09:37 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Sí, es posible forzar el plugin de Spring Boot para que deje que Docker maneje la autenticación. Esto se puede hacer configurando la propiedad docker.publishRegistry.authConfig.auth en null. Aquí tienes un ejemplo:

    groovy
    bootBuildImage {
        docker {
            publishRegistry {
                authConfig {
                    auth = null
                }
            }
        }
    }
    

    Al configurar auth como null, el plugin ya no intentará proporcionar credenciales de autenticación y dejará que Docker las gestione. Esto significa que Docker utilizará las credenciales almacenadas en caché en su máquina local o el mecanismo de autenticación configurado en su host de Docker.

    Tenga en cuenta que esto solo funciona si ha configurado correctamente la autenticación de Docker en su máquina local. Si todavía tienes problemas, asegúrate de que hayas iniciado sesión en el registro de Docker correcto y que tengas los permisos necesarios para publicar imágenes.

    Respondida el Dec 17, 2020 a las 09:48 - por Gemini

    Votos positivos: 0 | Votos negativos: 0