Como e quando usar rótulos do Docker/anotações de contêiner OCI
3 de novembro de 2021
0 minutos de leituraA maioria das imagens de contêiner é criada com Dockerfiles que combinam instruções como FROM, RUN, COPY, ENTRYPOINT etc. para criar as camadas de uma imagem compatível com OCI. Uma instrução surpreendentemente pouco usada, porém, é LABEL. Neste artigo, vamos explorar os rótulos ("anotações" na especificação de imagem OCI): o que são, alguns usos padronizados e práticas que você pode adotar para reforçar a segurança dos seus contêineres.
No restante deste artigo, vamos chamá-los de rótulos — em vez de anotações —, pois esse é o termo mais usado. Vamos começar!
O que são rótulos de imagem do Docker?
Os rótulos de imagem do Docker permitem adicionar metadados de chave-valor à própria imagem. Esses dados não ficam disponíveis para um contêiner que executa a imagem, mas são úteis para registrar, por exemplo, onde está o código-fonte da imagem, quem oferece suporte a ela ou qual build de CI a criou.
Entenda os metadados de imagens Docker/OCI
Se você já criou algum tipo de pacote de software, sabe que, em geral, esses pacotes incluem o software, a configuração e, às vezes, dados funcionais, além de metadados sobre o próprio pacote.
Por exemplo, embora os arquivos Java .jar sejam basicamente arquivos .zip, todos têm um diretório META-INF no nível superior, que contém vários arquivos e diretórios. De acordo com a especificação Java 2 Platform, eles “... são reconhecidos e interpretados pela Java 2 Platform para configurar aplicativos, extensões, carregadores de classes e serviços”. Se abrirmos um .jar criado pela popular ferramenta de build Maven, normalmente encontraremos, entre outras coisas, um diretório maven com conteúdo como o pom.xml efetivo do Maven e o pom.properties usados para criar o .jar. (A propósito, “POM” significa Project Object Model do Maven.)
RPM, APT, NPM e a maioria das outras ferramentas de empacotamento também armazenam metadados semelhantes, usados pelas ferramentas durante a instalação ou execução do software incluído, ou para fins utilitários em repositórios e sistemas de monitoramento em tempo de execução.

As imagens de contêiner também armazenam metadados em suas camadas. Ao listar o “histórico” de uma imagem, você frequentemente verá camadas de tamanho zero byte. Elas não contêm alterações no sistema de arquivos; em vez disso, contêm metadados usados em tempo de execução, geralmente adicionados por comandos do Dockerfile:
USER: usuário com o qual o processo será executadoENV: variável (e seu valor) a ser definida no ambiente dos processosARG: argumento de build passado para o contêiner de build e usado como uma variável de ambiente no escopo do buildCMD: comando e/ou parâmetros para iniciar o processo (ENTRYPOINT tem função semelhante)LABEL: pares de chave-valor que não são usados pelo mecanismo de execução
A maioria desses itens é conhecida e usada em todos os Dockerfiles. Como os metadados de rótulos não são necessários para executar os contêineres, porém, eles costumam ser ignorados.
Por que usar rótulos em imagens de contêiner?
Há muitos motivos para usar rótulos nas suas imagens, como documentar versões, incluir informações de contato dos responsáveis pelo projeto ou até dados sobre o uso em tempo de execução. Um dos casos de uso mais comuns é registrar informações sobre como a imagem foi criada, que podem ser usadas na cadeia de suprimentos de software do artefato de imagem.
Tipos de metadados de rótulos do Docker/anotações de imagem OCI
Rótulos padronizados
Os metadados sobre a criação e a origem de imagens são tão comuns que a equipe da OCI publica um conjunto padronizado de chaves, todas com o prefixo “org.opencontainers.image.”, incluindo:
source: URL para acessar o código-fonte usado para criar a imagemrevision: identificador da revisão do controle de versão do software empacotadobase.digest: digest (hash) da imagem usada como basebase.name: referência da imagem usada como baseversion: versão do software empacotado
Rótulos personalizados
Como são apenas pares de chave-valor, seu projeto ou sua organização pode especificar praticamente qualquer coisa. Algumas ideias (todas poderiam usar um prefixo como “com.mycorp.myteam.”):
ci-build: URL da execução do projeto de CI que criou a imagemreleasenotes: notas da versão do software empacotadohealthz: endpoint HTTP para verificações de integridadedocker.run: exemplo de comando do Docker para executar a imagemk8s.deployment: YAML em Base64 para uma implantação do Kubernetes que usa esta imagem
O último exemplo é interessante porque, sim, você pode armazenar praticamente qualquer conteúdo que consiga codificar em Base64 como valor de uma chave de rótulo. Isso significa que você pode extrair a imagem e executar algo como o comando a seguir para obter um arquivo YAML de implantação de exemplo, que depois pode ser usado em um cluster Kubernetes:
Você pode até direcionar a saída diretamente para kubectl e fazer a implantação na hora, sem precisar de gráficos Helm ou arquivos YAML separados no repositório Git!
Como aproveitar os rótulos do Docker/anotações OCI
Como você pode imaginar, os rótulos podem receber qualquer valor acessível pelo seu sistema de CI e ajudar a relacionar imagens e/ou contêineres em execução às respectivas origens, documentações etc., bastando inspecionar seus rótulos. Por exemplo, digamos que sua organização publique imagens com o rótulo padrão da OCI org.opencontainers.image.source, que contém a URL do repositório de controle de código-fonte de origem da imagem. Para descobrir quais imagens de repositórios estão em execução em um determinado host Docker, você poderia executar algo assim:
A saída mostra os IDs de dois contêineres em execução. Um deles tem o rótulo, então seu valor foi exibido.
As coisas ficam um pouco mais complicadas em um cluster Kubernetes, onde você provavelmente não terá acesso aos sockets do mecanismo de contêiner nos nós do cluster. Infelizmente, não há uma API para acessar esses rótulos com kubectl, então precisamos usar uma abordagem mais criativa. O script Bash a seguir encontra as imagens em execução no namespace do contexto atual, consulta o registro de imagens para obter os metadados e retorna as informações dos rótulos:
Vale destacar que estou usando a excelente ferramenta regctl, do projeto de código aberto regclient. Ela permite obter informações sobre imagens diretamente de um registro, sem precisar baixá-las para meu ambiente local para inspecioná-las. Assim, também posso executar esse script onde quiser, sem precisar de um mecanismo de execução de contêineres.
Agora, vamos executar isso em um cluster e procurar os repositórios das imagens em execução nele:
Como você pode ver, no momento há duas imagens no meu cluster em execução em pods que têm o rótulo org.opencontainers.image.source.
Embora esses exemplos sejam relativamente simples, tenho certeza de que você pode desenvolver os conceitos e criar seus próprios scripts ou chamadas de API para atender às necessidades da sua organização.
Integração com a Snyk
Um dos aspectos mais interessantes para a segurança é que a análise de imagens da Snyk agora oferece suporte à associação automática da imagem analisada ao Dockerfile correspondente, usando rótulos de imagem.
A integração da Snyk com repositórios de código-fonte já consegue detectar e analisar estaticamente os Dockerfiles encontrados no seu código, além de imagens importadas dos seus registros de contêineres. Até pouco tempo, porém, era preciso fazer essa associação cruzada por conta própria. Você tinha que adicionar manualmente a referência ao Dockerfile na imagem ou implementar sua própria automação para fazer isso por meio de chamadas de API.
Agora, basta incluir o rótulo padrão da OCI org.opencontainers.image.source com a URL do repositório que contém o Dockerfile. Quando a imagem for importada, a Snyk fará a associação cruzada automaticamente.

Exemplo de projeto de análise de imagem vinculado automaticamente
Conclusão
Em resumo, o rótulo/anotação de imagem, muitas vezes esquecido, é uma ferramenta poderosa que permite inserir metadados diretamente nas imagens. Usar chaves padronizadas pode ajudar não apenas a documentar a origem de uma imagem, mas também permitir que ferramentas de implantação e segurança entendam melhor o ambiente implantado.
Você já pode começar a aproveitar o recurso de vinculação automática de imagens da Snyk: basta adicionar o rótulo padrão da OCI org.opencontainers.image.source aos Dockerfiles que estão sendo analisados na sua conta. Ainda não tem uma conta Snyk? Cadastre-se gratuitamente e comece a usar o recurso agora mesmo!
Quero saber como você está usando rótulos. Essas ideias são novas ou seus projetos já os utilizam? Que outras formas interessantes vocês estão usando para anotar imagens? Há novas integrações que você gostaria de ver, com a Snyk ou outras ferramentas? Marque-me (@ericsmalling) no Twitter e compartilhe suas ideias. Vou adorar saber o que você pensa!
Segurança de contêineres que prioriza os desenvolvedores
O Snyk encontra e corrige automaticamente vulnerabilidades em imagens de contêiner e workloads do Kubernetes.
