Introdução
A Chainguard é uma empresa que desenvolve ferramentas para criação de imagens de contêineres seguras e minimalistas. Entre suas principais soluções open source estão:
- Melange: Uma ferramenta para criar pacotes de software reprodutíveis e auditáveis.
- Apko: Um criador de imagens de contêiner baseadas em pacotes APK, com ênfase em segurança e controle.
- Wolfi: Uma distribuição Linux mínima e não-GNU projetada especificamente para ambientes de contêiner.
Chainguard Apko
O que é?
O Apko é uma ferramenta para criar imagens de contêineres minimalistas e seguras usando pacotes APK sem camadas desnecessárias, melhorando a segurança e o desempenho. O Docker, por exemplo, combina etapas de construção como executar comandos para copiar arquivos, construir e implementar aplicativos. O Apko, por outro lado, é apenas uma ferramenta de composição que se concentra na produção de imagens base leves e "planas" que são reprodutíveis e contêm arquivos SBOM gerados automaticamente para cada construção bem-sucedida.
Principais recursos do Apko:
- Geração de imagens OCI a partir de arquivos YAML.
- Totalmente integrada ao ecossistema Wolfi.
- Controle granular sobre dependências.
- Ferramenta declarativa para construção de imagens OCI baseada no apk.
- Parte do kit de ferramentas utilizado para criar imagens Wolfi/Chainguard.
- As imagens são definidas em arquivos YAML.
- Builds são totalmente reprodutíveis.
- Gera automaticamente SBOMs (Bill of Materials) para cada imagem.
- Suporte para builds agnósticos de plataforma via Docker + imagem apko.
Início rápido com Apko
Baixe a imagem apko
docker pull cgr.dev/chainguard/apko
Isso fará o download da versão mais recente da imagem apko distroless, que é reconstruída todas as noites para maior atualização.
Verifique se você consegue executar o apko com:
docker run --rm cgr.dev/chainguard/apko version
Criando uma imagem de teste
Vamos criar uma imagem de teste usando um dos exemplos fornecidos no repositório oficial do apko, usaremos o exemplo wolfi-base.yaml
para demonstração.
Vamos criar uma pasta para salvar os arquivos de imagem e mover para esse diretório:
mkdir ~/apko
cd ~/apko
Em seguida, crie um arquivo chamado wolfi-base.yaml para salvar sua definição de imagem. Você pode usar vim
para isso:
vim wolfi-base.yaml
A wolfi-base.yaml
imagem de exemplo é definida da seguinte forma:
contents:
keyring:
- https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
repositories:
- https://packages.wolfi.dev/os
packages:
- ca-certificates-bundle
- wolfi-base
entrypoint:
command: /bin/sh -l
archs:
- x86_64
O contents
nó é usado para definir fontes de pacotes permitidas e quais pacotes devem ser incluídos na imagem. Aqui, usaremos apenas pacotes do repositório principal do Wolfi APK. Na seção packages
, precisamos do pacote wolfi-base , que é um metapacote para configurar um sistema Wolfi mínimo.
O command
campo dentro do entrypoint
nó define o comando image entry point /bin/sh -l
, que o levará a um prompt de shell sempre que a imagem for executada. Finalmente, o archs
nó especifica que essa imagem será construída para a x86-64
arquitetura.
Salve e feche o arquivo depois de terminar de incluir esses conteúdos. Com o vim
, você pode fazer isso use o :wq
.
A única coisa que resta fazer agora é executar o apko para construir esta imagem.
docker run --rm -v ${PWD}:/work -w /work cgr.dev/chainguard/apko build wolfi-base.yaml wolfi-base:test wolfi-test.tar
O seguinte comando de construção irá:
- configurar um compartilhamento de volume no diretório atual, sincronizando seu conteúdo com o diretório de trabalho da imagem do apko; dessa forma, os artefatos gerados estarão disponíveis no seu sistema host.
- executar a
cgr.dev/chainguard/apko
imagem com obuild
comando, marcando a imagem comowolfi-base:test-amd64
e salvando a compilação comowolfi-test.tar
.
a sua saida pode se parecer com
Na saída, você pode notar que a imagem foi criada com sucesso wolfi-test.tar
no contêiner, que é compartilhado com sua pasta local no host graças ao volume que você criou ao executar o docker runcomando.
Teste a imagem com o Docker
Para testar a imagem gerada com o Docker, você precisará usar o comando docker load
e importar o arquivo .tar
docker load < wolfi-test.tar
Obeterá uma saída como esta:
você pode verificar se a imagem esta disponível com o comando
docker image list
voce deve conseguir encontrar a imagem wolfi-base:test-amd64
na lista de imagens disponíveis.
Agora, você pode executar a imagem com o comando:
docker run -it wolfi-base:test-amd64
Isso o levará a um contêiner executando a imagem apko-built wolfi-base:test-amd64
.
Chainguard Melange
O que é?
O Melange é uma ferramenta que ajuda a criar pacotes reprodutíveis com foco na rastreabilidade e segurança. Ele usa arquivos de configuração YAML para definir como o software será empacotado e construído.
Principais recursos:
- Compatível com APK (pacotes do Alpine Linux).
- Reprodutibilidade: builds são auditáveis e podem ser recriados em qualquer ambiente.
- Integração com Wolfi para criar um ecossistema de pacotes seguro.
- Ferramenta declarativa para construção de pacotes apk.
- Parte do kit de ferramentas utilizado para criar imagens Wolfi/Chainguard.
- Pipelines de build são definidos (via QEMU).
- Suporte para builds agnósticos de plataforma via Docker + imagem apko.
Início rápido com Apko
- Baixando a imagem melange:
docker pull cgr.dev/chainguard/melange:latest
Baixando a imagem Melange
Isso fará o download da versão mais recente da imagem de mesclagem, que é reconstruída todas as noites para maior frescor.
docker pull cgr.dev/chainguard/melange:latest
Verifique se você consegue executar o Melange com o comando:
docker run --rm cgr.dev/chainguard/melange version
Clonando o Repositório de Demonstração
Para demonstrar os recursos do Melange com um aplicativo minimalista que tem funcionalidade do mundo real, consiste em um aplicativo de linha de comando PHP que consulta a API de conselhos do Slip e gera um conselho aleatório. O aplicativo é um script de arquivo único criado com Minicli.
Vamos clonar o repositório de demonstração e navegar até o diretório melange-php-demos/hello-minicli
:
git clone git@github.com:chainguard-dev/melange-php-demos.git
cd melange-php-demos/hello-minicli
Execute o seguinte comando, que usará a imagem oficial do Composer para gerar um arquivo composer.json
e baixar minicli/minicli
:
docker run --rm -it -v "${PWD}":/app composer require minicli/minicli
Após receber a confirmação de que o download foi concluído, você precisará de uma segunda dependência para consultar a API do Advice Slip. Execute o comando a seguir para incluir minicli/curly
, um curl wrapper para Minicli:
docker run --rm -it -v "${PWD}":/app composer require minicli/curly
Agora você pode executar o aplicativo para ter certeza de que ele está funcional. Você pode fazer isso usando o Docker e a imagem PHP do Chainguard:
docker run --rm -it -v "${PWD}":/app cgr.dev/chainguard/php /app/minicli advice
Você deve receber um conselho aleatório como:
Gratitude is said to be the secret to happiness.
O arquivo YAML Melange
O arquivo melange.yaml
é onde você declara os detalhes e especificações do seu pacote APK. Para código que gera binários autocontidos, é aqui que você normalmente construirá seus artefatos de aplicativo com ferramentas de compilador. No caso de linguagens interpretadas, você provavelmente construirá seu aplicativo baixando dependências de fornecedores, configurando caminhos relevantes e configurando o ambiente para produção.
O arquivo de especificação do Melange contém três seções principais:
- package: define especificações do pacote, como nome, licença e dependências de tempo de execução. Dependências de tempo de execução serão trazidas para o sistema automaticamente como dependências quando o APK for instalado.
- environment: define como o ambiente deve ser preparado para a construção, incluindo pacotes necessários e seus repositórios de origem. Qualquer coisa que seja necessária apenas no momento da construção vai aqui, e não deve fazer parte das dependências do tempo de execução.
- pipeline: define o pipeline de construção para este pacote.
Uma das melhores vantagens de usar Melange é poder controlar todas as etapas do seu pipeline de construção e incluir apenas o que é necessário. Dessa forma, você poderá construir imagens de contêiner menores e mais seguras removendo dependências desnecessárias.
É assim que o melange.yaml
incluído em nossa demonstração se parece, para sua referência:
package:
name: hello-minicli
version: 0.1.0
description: "Minicli melange demo"
target-architecture:
- all
copyright:
- license: MIT
dependencies:
runtime:
- php
- php-curl
environment:
contents:
keyring:
- https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
- ./melange.rsa.pub
repositories:
- https://packages.wolfi.dev/os
packages:
- ca-certificates-bundle
- busybox
- curl
- git
- php
- php-phar
- php-iconv
- php-openssl
- php-curl
- composer
pipeline:
- name: Build Minicli application
runs: |
MINICLI_HOME="${{targets.destdir}}/usr/share/minicli"
EXEC_DIR="${{targets.destdir}}/usr/bin"
mkdir -p "${MINICLI_HOME}" "${EXEC_DIR}"
cp ./composer.json "${MINICLI_HOME}"
/usr/bin/composer install -d "${MINICLI_HOME}" --no-dev
cp ./minicli "${EXEC_DIR}"
chmod +x "${EXEC_DIR}/minicli"
Nosso pipeline de construção configurará dois diretórios distintos, separando as dependências do aplicativo de seu ponto de entrada executável. O script executável minicli
será copiado para /usr/bin
, enquanto os arquivos do fornecedor estarão localizados em /usr/share/minicli
.
Construindo o Minicli APK com Melange
Antes de construir o pacote, você precisará criar um keypair temporário para assiná-lo. Você pode usar o seguinte comando para isso:
docker run --rm -v "${PWD}":/work cgr.dev/chainguard/melange keygen
Isso gerará um arquivo melange.rsa
e melange.rsa.pub
no diretório atual.
Saída:
2024/08/01 16:55:31 INFO generating keypair with a 4096 bit prime, please wait...
2024/08/01 16:55:33 INFO wrote private key to melange.rsa
2024/08/01 16:55:33 INFO wrote public key to melange.rsa.pub
Em seguida, crie o APK definido no arquivo melange.yaml
com o seguinte comando:
docker run --privileged --rm -v "${PWD}":/work \
cgr.dev/chainguard/melange build melange.yaml \
--arch amd64,aarch64 \
--signing-key melange.rsa
Isso configurará um volume compartilhando sua pasta atual com o local /work
dentro do contêiner. Nós construiremos pacotes para as plataformas amd64
e aarch64
e os assinaremos usando a chave melange.rsa
criada no comando anterior.
Quando a compilação estiver concluída, você deverá encontrar uma pasta packages
contendo os APKs gerados (e os arquivos de índice APK associados):
Saída:
packages
├── aarch64
│ ├── APKINDEX.json
│ ├── APKINDEX.tar.gz
│ └── hello-minicli-0.1.0-r0.apk
└── x86_64
├── APKINDEX.json
├── APKINDEX.tar.gz
└── hello-minicli-0.1.0-r0.apk
3 directories, 6 files
Você construiu com sucesso um pacote de software multiarquitetura com Melange!
Construindo uma Imagem de Contêiner com Apko
Com os pacotes APK e o índice APK em vigor, agora você pode criar uma imagem de contêiner e instalar seus APK(s) nela.
O arquivo apko.yaml
a seguir criará uma imagem de contêiner adaptada ao aplicativo que construímos nas etapas anteriores. Como definimos as dependências do PHP como dependências de tempo de execução dentro do APK, você não precisa exigir esses pacotes novamente aqui. O comando container entrypoint será definido como /usr/bin/minicli
, onde o executável do aplicativo está localizado.
Uma coisa importante a ser notada é como referenciamos o hello-minicli
APK como um pacote local dentro da seção repositories
do arquivo YAML. A notação @local
diz ao Apko para procurar por APKs no diretório especificado, neste caso /work/packages
.
Esta é a aparência do arquivo apko.yaml
incluído em nossa demonstração, para sua referência:
contents:
keyring:
- https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
- ./melange.rsa.pub
repositories:
- https://packages.wolfi.dev/os
- '@local /work/packages'
packages:
- wolfi-base
- ca-certificates-bundle
- hello-minicli@local
accounts:
groups:
- groupname: nonroot
gid: 65532
users:
- username: nonroot
uid: 65532
run-as: 65532
entrypoint:
command: /usr/bin/minicli advice
O comando a seguir configurará um volume compartilhando sua pasta atual com o local /work
no contêiner Apko, executando o comando apko build
para gerar uma imagem com base no seu arquivo de definição apko.yaml
.
docker run --rm --workdir /work -v ${PWD}:/work cgr.dev/chainguard/apko \
build apko.yaml hello-minicli:test hello-minicli.tar --arch host
Isso criará uma imagem OCI com base na arquitetura do seu sistema host (especificada pelo sinalizador --arch host
). Se você receber avisos neste ponto, eles provavelmente estão relacionados aos tipos de SBOMs que estão sendo carregados e podem ser ignorados com segurança.
O comando irá gerar alguns novos arquivos no diretório do aplicativo:
-
hello-minicli.tar
— a imagem OCI empacotada que pode ser importada com um comandodocker load
-
sbom-%host-architecture%.spdx.json
— um arquivo SBOM para sua arquitetura de host no formatospdx-json
Em seguida, carregue sua imagem no Docker:
docker load < hello-minicli.tar
Saída:
7cbaefdf1c30: Loading layer 13.7MB/13.7MB
Loaded image: hello-minicli:test-%host-architecture%
Observe que o %host-architecture%
variará, e pode haver várias imagens carregadas no seu daemon Docker. Certifique-se de editar a variável no comando docker run
a seguir para corresponder à sua arquitetura de destino.
Agora você pode executar seu programa Minicli com:
docker run --rm hello-minicli:test-%host-architecture%
A demonstração deve gerar um aviso como:
Only those who attempt the impossible can achieve the absurd.
Você construiu com sucesso uma imagem de contêiner minimalista com seu pacote APK instalado nela. Esta imagem é totalmente compatível com OCI e pode ser assinada com Cosign para atestado de procedência.
Conclusão
Neste guia, empacotamos um aplicativo de linha de comando PHP com Melange. Também criamos uma imagem de contêiner para instalar e executar nosso APK personalizado, usando a ferramenta Apko. Para mais informações sobre o Apko, confira nosso guia Getting Started with Apko.
Os arquivos de demonstração estão disponíveis no repositório melange-php-demos, na subpasta hello-minicli
. Para obter informações adicionais sobre como depurar suas compilações e outros recursos, verifique os repositórios Melange e Apko no GitHub.
Chainguard Wolfi
O que é?
Wolfi é uma distribuição Linux não-GNU projetada para ambientes de contêiner, com pacotes otimizados para segurança e desenvolvimento moderno. Não possui shell ou gerenciador de pacotes.
Uma referência ao menor polvo do mundo.
Principais recursos:
- Focado em contêineres.
- Sem glibc, usando
musl
como libc. - Repositório de pacotes confiáveis.
-
Tiny Linux Distribution
Uma distribuição Linux minimalista.
"Undistro" porque não inclui itens que normalmente fazem parte de uma distribuição Linux (como o kernel, páginas de manual e vários outros pacotes que não fazem sentido para contêineres).
Baseado no apk (gerenciador de pacotes do Alpine).
Usa principalmente glibc, mas MUSL está no roadmap.
Os pacotes são definidos como YAML e construídos com o melange.
Principais Características das Imagens Chainguard
- Design minimalista, sem software desnecessário.
- Builds noturnos automatizados para garantir que as imagens estejam sempre atualizadas e contenham todos os patches de segurança disponíveis.
- SBOMs de alta qualidade (Bill of Materials) atestando a proveniência de todos os artefatos dentro da imagem.
- Assinaturas verificáveis fornecidas pelo Sigstore.
- Builds reprodutíveis com Cosign e apko (leia mais sobre reprodutibilidade).
As imagens Chainguard estão disponíveis principalmente no Chainguard Registry, mas uma seleção de imagens para desenvolvedores também está disponível no Docker Hub. Você pode encontrar a lista completa de imagens Chainguard disponíveis em nosso Directório de Imagens público ou no Chainguard Console.
Note que geralmente há uma variante -dev
de cada imagem Chainguard disponível. Por exemplo, a variante -dev
da imagem mariadb:latest
é mariadb:latest-dev
. Essas imagens normalmente contêm um shell e ferramentas como um gerenciador de pacotes para permitir que os usuários depurem e modifiquem a imagem mais facilmente.
Você pode analisar mais comparações de imagens do Chainguard e imagens externas verificando nosso painel de comparações de vulnerabilidades.
Por padrão, todas as imagens baseadas em Wolfi são construídas para x86_64.
Você pode confirmar a arquitetura disponível de uma determinada imagem Chainguard com Crane. Neste exemplo, usaremos a imagem mais recente do Ruby, mas você pode optar por usar uma imagem alternativa.
crane manifest cgr.dev/chainguard/ruby:latest | jq -r '.manifests[] | .platform'
{
"architecture": "amd64",
"os": "linux"
}
{
"architecture": "arm64",
"os": "linux"
}
Top comments (0)