Aws-cli: [v2] Distribuir binários para alpine / musl libc

Criado em 20 nov. 2019  ·  26Comentários  ·  Fonte: aws/aws-cli

docker run -it --rm docker:latest sh
wget "https://d1vvhvl2y92vvt.cloudfront.net/awscli-exe-linux-x86_64.zip" -O "awscliv2.zip"
# curl not installed
unzip awscliv2.zip
./aws/install
# sudo not install

Erros com:

/ # ./aws/install
./aws/install: line 78: /aws/dist/aws2: not found
You can now run: /usr/local/bin/aws2 --version
/ # aws2
sh: aws2: not found
confusing-error v2

Comentários muito úteis

A razão pela qual a imagem adoptopenjdk funciona é porque incluem as bibliotecas glibc ausentes. Alphine linux é baseado em 'musl glibc', uma alternativa leve para uma glibc desenvolvida. Os binários do aws cli v2 não funcionam com o musl, eles precisam de mais algumas bibliotecas para funcionar.

Em vez de usar a imagem Java, você também pode usar o Dockerfile abaixo como um exemplo de como executar o AWS CLI v2 no Alpine Linux:

FROM alpine:3.11

ENV GLIBC_VER=2.31-r0

# install glibc compatibility for alpine
RUN apk --no-cache add \
        binutils \
        curl \
    && curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-${GLIBC_VER}.apk \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk \
    && apk add --no-cache \
        glibc-${GLIBC_VER}.apk \
        glibc-bin-${GLIBC_VER}.apk \
    && curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip \
    && unzip awscliv2.zip \
    && aws/install \
    && rm -rf \
        awscliv2.zip \
        aws \
        /usr/local/aws-cli/v2/*/dist/aws_completer \
        /usr/local/aws-cli/v2/*/dist/awscli/data/ac.index \
        /usr/local/aws-cli/v2/*/dist/awscli/examples \
    && apk --no-cache del \
        binutils \
        curl \
    && rm glibc-${GLIBC_VER}.apk \
    && rm glibc-bin-${GLIBC_VER}.apk \
    && rm -rf /var/cache/apk/*

O acima irá baixar as bibliotecas glibc, baixar e instalar o AWS CLI v2 e remover algumas coisas que provavelmente não precisamos, como autocompletar. A imagem resultante tem cerca de 100 MB de tamanho

Todos 26 comentários

Tentei depurar o problema e não consegui descobrir por que ele falhou. Parece-me que o script de instalação é um pouco instável. Tentei adicionar o rótulo v2 também.

Os binários que publicamos não funcionam em imagens docker baseadas em alpine porque os estamos compilando com a glibc. O sh: aws2: not found é o que acontece quando você tenta executar este binário. Se você tentar em uma imagem como ubuntu:latest o instalador funcionará.

Além disso, acho que nunca lançaríamos um binário compatível com alpine como estamos fazendo para nosso binário Linux geral. Acho que estaríamos mais inclinados a apenas lançar uma imagem docker que vem com nosso binário construído em alpine.

Obrigado pela sua resposta. É possível documentar isso aqui https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html em "Pré-requisitos para Linux", ou tornar o erro mais amigável no sistema alpino caso de imagem?

Faremos questão de atualizar isso no guia do usuário. Também gosto da ideia de criar uma mensagem de erro mais amigável para esse caso.

@joguSD que chatice, alpine é o padrão para imagens docker. Especialmente com sistemas build / ci que desejam automatizar e não desejam baixar continuamente imagens docker muito grandes.

Pode usar uma imagem docker alpina oficial em uma compilação de vários estágios para copiar o binário em outra imagem docker.

@chadgrant - você pode dar um exemplo de seu dockerfile de vários estágios?

@ BarakBD-Globality Eu não tenho um, mas se a imagem aws-alpine alguma vez for criada, você pode simplesmente fazer:

FROM aws_alpine_image:latest as aws
FROM alpine:latest
COPY --from=aws /usr/local/bin/binary /usr/local/bin/binary

Pena que eles não suportam alpino. É uma imagem padrão.

Além disso, acho que nunca lançaríamos um binário compatível com alpine como estamos fazendo para nosso binário Linux geral. Acho que estaríamos mais inclinados a apenas lançar uma imagem docker que vem com nosso binário construído em alpine.

@joguSD houve alguma discussão ou moção sobre isso? Parece um grande negócio, considerando a prevalência do alpino. Pessoas como eu usam aws em seu cicd e outras automações, então se não estiver disponível para imagens baseadas em alpino, usar a versão 2 não é nem uma opção sem um trabalho significativo! Obrigado.

também não pode instalar em busybox

Curiosamente, se você usar isso como uma imagem de base, o AWS cli será instalado e funcionará corretamente.

FROM adoptopenjdk / openjdk11: alpine

Consegui fazer isso usando o seguinte Dockerfile

FROM adoptopenjdk/openjdk11:alpine

RUN apk add --no-cache \
        ca-certificates \
        unzip \
        curl \
        groff \
        less  \
        bash  \
        openssh-client

WORKDIR /home
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
    && unzip awscliv2.zip \
    && ./aws/install \
    && rm awscliv2.zip \
    && rm -R aws

A razão pela qual a imagem adoptopenjdk funciona é porque incluem as bibliotecas glibc ausentes. Alphine linux é baseado em 'musl glibc', uma alternativa leve para uma glibc desenvolvida. Os binários do aws cli v2 não funcionam com o musl, eles precisam de mais algumas bibliotecas para funcionar.

Em vez de usar a imagem Java, você também pode usar o Dockerfile abaixo como um exemplo de como executar o AWS CLI v2 no Alpine Linux:

FROM alpine:3.11

ENV GLIBC_VER=2.31-r0

# install glibc compatibility for alpine
RUN apk --no-cache add \
        binutils \
        curl \
    && curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-${GLIBC_VER}.apk \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk \
    && apk add --no-cache \
        glibc-${GLIBC_VER}.apk \
        glibc-bin-${GLIBC_VER}.apk \
    && curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip \
    && unzip awscliv2.zip \
    && aws/install \
    && rm -rf \
        awscliv2.zip \
        aws \
        /usr/local/aws-cli/v2/*/dist/aws_completer \
        /usr/local/aws-cli/v2/*/dist/awscli/data/ac.index \
        /usr/local/aws-cli/v2/*/dist/awscli/examples \
    && apk --no-cache del \
        binutils \
        curl \
    && rm glibc-${GLIBC_VER}.apk \
    && rm glibc-bin-${GLIBC_VER}.apk \
    && rm -rf /var/cache/apk/*

O acima irá baixar as bibliotecas glibc, baixar e instalar o AWS CLI v2 e remover algumas coisas que provavelmente não precisamos, como autocompletar. A imagem resultante tem cerca de 100 MB de tamanho

Então, qual é o caminho mais curto para obter um aws ecr get-login-password … | docker login … dentro de um contêiner do docker em execução? (o que implica: docker:dind )?

Eu adoraria evitar construir minha própria imagem docker:stable com suporte para docker:dind . Pelo menos eu poderia graças à solução https://github.com/aws/aws-cli/issues/4685#issuecomment -615872019. Obrigado por isso!

@bentolor Como docker:dind também usa alpine, suspeito que tudo o que você precisa fazer é alterar a primeira linha do Dockerfile mencionado acima. Em vez de FROM alpine:3.11 você deve usar FROM docker:dind . Significa que você está construindo sua própria imagem ...

obrigado, @blagerweij funciona muito bem

Também agradeço a @blagerweij : entendi bem e construí uma imagem docker pública e personalizada copiando e colando sua solução: https://hub.docker.com/r/bentolor/docker-dind-awscli

@bentolor Percebi em seu repositório que o Dockerfile usa FROM docker:stable vez de FROM docker:dind . Eu pensei que o objetivo era criar uma imagem para Docker no Docker com suporte AWS?

@blagerweij Veja a imagem abaixo da imagem oficial do Docker para ilustração.

O uso típico é:

  1. Um (ou seu ci) inicia uma instância docker:dind e então
  2. Inicia uma instância docker:stable separada, vinculada ao contêiner docker:dind iniciado
  3. Você começa a executar os comandos docker dentro do segundo contêiner que redireciona os comandos via conexão de soquete para o daemon do docker rodando dentro do primeiro docker:dind contêiner.

Portanto: embora seja verdade que a instância docker:dind eventualmente executa seus comandos do Docker, seu front-end CLI realmente vive em uma instância docker:stable . E é aí que se precisa fazer o login na AWS ;-)

Pelo menos esse é o padrão de uso que conheço (ou seja, ao usar o Gitlab CI para construir imagens do docker). Talvez haja também cenários de uso direto de docker:dind ?

Usage of <a href="docker:stable">docker:stable</a> vs. <a href="docker:didn">docker:didn</a>

Pode-se usar imagem alpina com glibc de https://hub.docker.com/r/frolvlad/alpine-glibc/
e instale o aws cli seguindo as etapas da documentação do aws. Funcionou para mim.

@blagerweij Usei seu script com o docker na imagem do docker. aws cli funciona bem. Acabei de receber um erro na compilação:
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link

@amiram Sim, também recebo essa mensagem, é um aviso que você pode simplesmente ignorar: Ele está esperando um link simbólico, mas o arquivo presente é um arquivo normal. Consulte https://github.com/envoyproxy/envoy/issues/9078#issuecomment -576837432

Alguém poderia renomear este problema para algo como: "Distribuir binários para alpine / musl"?

@joguSD @ jordanst3wart

Sim, estou feliz com "Distribuir binários para alpine / musl libc". Deixe-me saber se você tem algum problema

Eu só preciso do aws s3 cp para um projeto passion, então acabei de instalar o awscli V1 com pip:

FROM alpine:3.12
RUN pip install awscli        
RUN aws s3 ..

A razão pela qual a imagem adoptopenjdk funciona é porque incluem as bibliotecas glibc ausentes. Alphine linux é baseado em 'musl glibc', uma alternativa leve para uma glibc desenvolvida. Os binários do aws cli v2 não funcionam com o musl, eles precisam de mais algumas bibliotecas para funcionar.

Em vez de usar a imagem Java, você também pode usar o Dockerfile abaixo como um exemplo de como executar o AWS CLI v2 no Alpine Linux:

recorte

O acima irá baixar as bibliotecas glibc, baixar e instalar o AWS CLI v2 e remover algumas coisas que provavelmente não precisamos, como autocompletar. A imagem resultante tem cerca de 100 MB de tamanho

este ajuste buscará a versão mais recente automaticamente se você não quiser codificar permanentemente a versão glibc:

FROM alpine

# install glibc compatibility for alpine
RUN apk --no-cache add \
    binutils \
    curl \
    && GLIBC_VER=$(curl -s https://api.github.com/repos/sgerrand/alpine-pkg-glibc/releases/latest | grep tag_name | cut -d : -f 2,3 | tr -d \",' ') \
    && curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-${GLIBC_VER}.apk \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk \
    && apk add --no-cache \
    glibc-${GLIBC_VER}.apk \
    glibc-bin-${GLIBC_VER}.apk \
    && curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip \
    && unzip awscliv2.zip \
    && aws/install \
    && rm -rf \
    awscliv2.zip \
    aws \
    /usr/local/aws-cli/v2/*/dist/aws_completer \
    /usr/local/aws-cli/v2/*/dist/awscli/data/ac.index \
    /usr/local/aws-cli/v2/*/dist/awscli/examples \
    && apk --no-cache del \
    binutils \
    curl \
    && rm glibc-${GLIBC_VER}.apk \
    && rm glibc-bin-${GLIBC_VER}.apk \
    && rm -rf /var/cache/apk/*

você também pode usar o Dockerfile abaixo como um exemplo de como executar o AWS CLI v2 no Alpine Linux:

O Dockerfile / script fornecido funciona, mas exibe este erro, que não parece impedi-lo de funcionar:

aws/install: line 78: /aws/dist/aws: not found

Estranhamente, a execução de apk add mandoc antes de aws/install evita a exibição desse erro e excluir o pacote após a instalação não causa nenhum efeito prejudicial. Outros pacotes aleatórios não parecem ter esse efeito protetor.

Alguma ideia?

PS apk add less é necessário para que aws help funcione corretamente (caso contrário, reclamará da falta do pacote groff ).

Esta página foi útil?
0 / 5 - 0 avaliações