Gerenciamento de pacotes: apt, yum e snap

1. Introdução ao gerenciamento de pacotes no contexto DevOps

1.1. O papel dos gerenciadores de pacotes na automação de infraestrutura

No ecossistema DevOps, o gerenciamento de pacotes é uma das atividades mais fundamentais para garantir ambientes consistentes, seguros e reproduzíveis. Ferramentas como apt, yum e snap permitem instalar, atualizar e remover softwares de forma automatizada, eliminando a necessidade de compilações manuais ou downloads dispersos. Em pipelines CI/CD, scripts de provisionamento e Dockerfiles, o uso correto desses gerenciadores reduz drasticamente a variabilidade entre ambientes de desenvolvimento, teste e produção.

1.2. Diferenças entre distribuições Linux

Cada família de distribuições Linux adota um gerenciador de pacotes padrão:

  • Debian/Ubuntu: utilizam apt (Advanced Package Tool), que opera sobre pacotes .deb.
  • RHEL/CentOS/Fedora: utilizam yum (Yellowdog Updater Modified) e, mais recentemente, dnf como substituto, ambos sobre pacotes .rpm.
  • Universal: snap é um sistema de pacotes confinados, desenvolvido pela Canonical, que funciona em múltiplas distribuições, incluindo Ubuntu, Fedora, Debian e até mesmo algumas versões do RHEL.

1.3. Por que o conhecimento é crítico para Docker e Kubernetes

Em Docker, imagens base como ubuntu:22.04 ou centos:7 exigem comandos apt ou yum para instalar dependências. Em Kubernetes, nós do cluster precisam de pacotes como kubelet, kubeadm e kubectl, além de ferramentas de rede e armazenamento. Saber gerenciar repositórios, evitar camadas desnecessárias e entender o ciclo de vida dos pacotes impacta diretamente a segurança, o tamanho das imagens e a estabilidade do cluster.

2. apt (Advanced Package Tool) – Ecossistema Debian/Ubuntu

2.1. Comandos essenciais

O apt gerencia pacotes .deb a partir de repositórios listados em /etc/apt/sources.list e em arquivos dentro de /etc/apt/sources.list.d/.

# Atualizar índice de pacotes
sudo apt update

# Atualizar todos os pacotes instalados
sudo apt upgrade -y

# Instalar um pacote específico
sudo apt install -y nginx

# Remover um pacote (mantendo arquivos de configuração)
sudo apt remove nginx

# Remover completamente (incluindo configurações)
sudo apt purge nginx

# Remover dependências não utilizadas
sudo apt autoremove -y

2.2. Gerenciamento de repositórios

Para adicionar um repositório oficial do Docker no Ubuntu:

# Adicionar chave GPG
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Adicionar repositório ao sources.list.d
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

2.3. Uso em Dockerfiles: boas práticas

FROM ubuntu:22.04

# Evitar prompts interativos
ENV DEBIAN_FRONTEND=noninteractive

# Atualizar e instalar em uma única camada, limpar cache
RUN apt update && \
    apt install -y --no-install-recommends \
        curl \
        ca-certificates \
        gnupg \
        lsb-release && \
    rm -rf /var/lib/apt/lists/*

# Fixar versões específicas para reprodutibilidade
RUN apt install -y --no-install-recommends nginx=1.18.0-6ubuntu14.4

Boas práticas: combine apt update e apt install em um único RUN para evitar camadas desnecessárias; use --no-install-recommends para evitar pacotes supérfluos; sempre limpe /var/lib/apt/lists/* ao final.

3. yum e dnf – Ecossistema Red Hat/CentOS/Fedora

3.1. Comandos fundamentais

No CentOS 7, yum ainda é o padrão. No CentOS 8 e Fedora, dnf é o sucessor.

# Listar repositórios habilitados
yum repolist

# Instalar pacote
sudo yum install -y httpd

# Atualizar todos os pacotes
sudo yum update -y

# Remover pacote
sudo yum remove httpd

# Limpar cache
sudo yum clean all

3.2. Transição para dnf

O dnf substitui o yum com melhor gerenciamento de dependências e desempenho. A sintaxe é quase idêntica:

# Comandos equivalentes em dnf
sudo dnf install -y nginx
sudo dnf update -y
sudo dnf remove nginx
sudo dnf repolist

3.3. Configuração de repositórios EPEL

O EPEL (Extra Packages for Enterprise Linux) fornece pacotes adicionais para RHEL/CentOS. Essencial para instalar ferramentas como htop, jq e ansible.

# Instalar EPEL no CentOS 7
sudo yum install -y epel-release

# Verificar repositórios
yum repolist

# Instalar ferramenta a partir do EPEL
sudo yum install -y htop

Uso em imagens base para Kubernetes:

FROM centos:7

RUN yum install -y epel-release && \
    yum install -y --setopt=tsflags=nodocs \
        curl \
        wget \
        jq \
        openssl && \
    yum clean all && \
    rm -rf /var/cache/yum

4. snap – Gerenciamento universal de pacotes

4.1. Conceito de snaps

Snaps são pacotes confinados que incluem todas as dependências necessárias para execução. Eles são atualizados automaticamente e podem ser distribuídos em canais como stable, candidate, beta e edge. O isolamento é garantido pelo AppArmor e pelo sistema de confinamento do snapd.

4.2. Comandos principais

# Instalar snapd (se ainda não estiver presente)
sudo apt install -y snapd

# Instalar um snap a partir do canal stable
sudo snap install microk8s --classic

# Listar snaps instalados
snap list

# Verificar atualizações disponíveis
sudo snap refresh --list

# Atualizar todos os snaps
sudo snap refresh

# Reverter para versão anterior
sudo snap revert microk8s

# Remover snap
sudo snap remove microk8s

4.3. Casos de uso em DevOps

O snap é especialmente útil para instalar ferramentas DevOps de forma rápida e isolada:

# MicroK8s – Kubernetes de desenvolvimento
sudo snap install microk8s --classic

# Docker via snap (alternativa ao repositório oficial)
sudo snap install docker

# Certbot para certificados SSL
sudo snap install certbot --classic

Limitações em ambientes conteinerizados: dentro de containers Docker, o snapd geralmente não funciona porque requer acesso ao sistema de init (systemd) e privilégios especiais. Portanto, evite usar snap em Dockerfiles; prefira apt ou yum.

5. Estratégias de gerenciamento de pacotes em Dockerfiles

5.1. Combinação com multi-stage builds

# Estágio 1: compilação com pacotes de desenvolvimento
FROM ubuntu:22.04 AS builder

RUN apt update && \
    apt install -y --no-install-recommends \
        build-essential \
        libssl-dev \
        libffi-dev \
        python3-dev && \
    rm -rf /var/lib/apt/lists/*

# Estágio 2: imagem final mínima
FROM ubuntu:22.04

COPY --from=builder /usr/local/bin/myapp /usr/local/bin/myapp

RUN apt update && \
    apt install -y --no-install-recommends \
        ca-certificates \
        curl && \
    rm -rf /var/lib/apt/lists/*

5.2. Uso de snap em containers

A instalação de snap dentro de containers Docker é problemática devido à necessidade de privilégios elevados e acesso ao kernel. Em geral, evite snap em Dockerfiles. Prefira instalar as mesmas ferramentas via apt ou yum.

5.3. Cache de camadas e otimização

# Ordenar pacotes por frequência de alteração
# Pacotes raramente alterados primeiro
RUN apt update && \
    apt install -y --no-install-recommends \
        ca-certificates \
        curl \
        git \
        jq && \
    rm -rf /var/lib/apt/lists/*

# Pacotes que mudam com frequência depois
RUN apt update && \
    apt install -y --no-install-recommends \
        python3-pip \
        nodejs && \
    rm -rf /var/lib/apt/lists/*

6. Gerenciamento de pacotes em clusters Kubernetes

6.1. Instalação de dependências em nodes

Em clusters Kubernetes gerenciados (EKS, AKS, GKE), o provedor de nuvem gerencia os pacotes do sistema. Em clusters on-premise, use DaemonSets ou ferramentas como Ansible e cloud-init:

# Exemplo de cloud-init para Ubuntu node
#cloud-config
packages:
  - kubelet
  - kubeadm
  - kubectl
  - docker.io
  - nfs-common

runcmd:
  - apt-mark hold kubelet kubeadm kubectl

6.2. Diferença entre pacotes do sistema e imagens de containers

Pacotes do sistema operacional (instalados via apt/yum) são diferentes das dependências dentro de imagens de containers. No Kubernetes, os nós precisam de pacotes como kubelet e containerd no nível do host, enquanto as aplicações rodam em containers com suas próprias camadas de pacotes.

6.3. Atualizações rolling sem downtime

Para atualizar pacotes nos nós do cluster sem interromper workloads:

# Estratégia com kubectl drain
kubectl drain node-01 --ignore-daemonsets

# Atualizar pacotes no nó
ssh node-01
sudo apt update && sudo apt upgrade -y
sudo systemctl reboot

# Após reinicialização, tornar nó schedulable novamente
kubectl uncordon node-01

7. Comparação prática e boas práticas DevOps

7.1. Tabela comparativa

Característica apt yum/dnf snap
Formato de pacote .deb .rpm .snap (squashfs)
Distribuições Debian, Ubuntu, Mint RHEL, CentOS, Fedora Ubuntu, Fedora, Debian, etc.
Isolamento Baixo (dependências globais) Baixo (dependências globais) Alto (sandbox via AppArmor)
Atualizações Manual (apt upgrade) Manual (yum update) Automáticas por padrão
Uso em Dockerfiles Excelente Excelente Não recomendado
Performance Rápido Rápido (dnf mais rápido) Mais lento (snapd overhead)

7.2. Scripts de provisionamento

Para ambientes híbridos, crie scripts condicionais:

#!/bin/bash
# detect-distro.sh
if [ -f /etc/debian_version ]; then
    apt update && apt install -y curl git
elif [ -f /etc/redhat-release ]; then
    yum install -y epel-release
    yum install -y curl git
elif command -v snap &> /dev/null; then
    snap install curl git
fi

7.3. Versionamento e reprodutibilidade

Diferente de pip ou npm, os gerenciadores nativos não possuem lockfiles nativos. Para garantir reprodutibilidade:

# Congelar versões no Dockerfile
RUN apt install -y --no-install-recommends \
    curl=7.81.0-1ubuntu1.16 \
    git=1:2.34.1-1ubuntu1.10

Ou utilize ferramentas como apt list --installed para gerar um inventário.

8. Ferramentas complementares e tendências

8.1. Segurança automatizada

  • unattended-upgrades (Debian/Ubuntu): instala atualizações de segurança automaticamente.
  • yum-cron (RHEL/CentOS 7): similar para pacotes de segurança.
# Instalar unattended-upgrades
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

8.2. Integração com Terraform e Ansible

No Terraform, provisionamento de pacotes pode ser feito via user_data ou provisioners:

# Exemplo com Ansible playbook
- name: Instalar pacotes essenciais
  apt:
    name:
      - curl
      - git
      - jq
    state: present
    update_cache: yes

8.3. O futuro: imagens mínimas

Tendências como Alpine Linux (3MB) e imagens distroless (Google) reduzem a dependência de gerenciadores de pacotes tradicionais. Para Kubernetes, imagens mínimas são preferíveis por segurança e performance, mas ainda exigem conhecimento de apk add (Alpine) ou apt em imagens base Ubuntu slim.

# Exemplo com Alpine
FROM alpine:3.18

RUN apk add --no-cache curl=8.4.0-r0

Referências