quinta-feira, 25 de agosto de 2011

Apt-Mirror e Apt-Cacher: Criando Localmente um Repositório do Ubuntu

Olá povo! Ano passado eu estava conversando com um amigo sobre a idéia de fazer um Install Fest em um evento de tecnologia que existe aqui em Palmas, o Encoinfo. Conversávamos sobre distribuições a serem instaladas e num ponto da nossa conversa, eu toquei no assunto de quanta largura de banda teríamos disponível para fazer nosso Install Fest. Meu amigo me disse "não o suficiente pra fazer o update e instalações de aplicativos em todas as máquinas". Daí, pensamos um pouco e a coisa ficou por isso mesmo.

Esta semana, em vista do aumento do número de máquinas com Ubuntu na instituição que trabalho, me veio à mente o problema que teríamos se todas as máquinas resolvessem atualizar o sistema de uma vez só. Isso geraria um tráfego sem noção de dados. Então, me perguntei: será que é difícil criar um repositório local para o Apt?

Feita a pergunta, aqui estamos. Depois de uma pequena pesquisa, encontrei dois métodos que permitem resolver os dois problemas acima: Apt-Mirror e Apt-Cacher.

Os dois resolvem os problemas acima, minimizando a banda utilizada pelas diversas máquinas, mas a forma com que cada um funciona é diferente.

Vamos ao post!

Criando um repositório local de pacotes do Ubuntu


Primeiramente, essa dica não serve só para o Ubuntu. Eu a implementei em minha máquina, que usa o Linux Mint. Ela é uma derivada do Ubuntu, que usa o mesmo repositório para a maioria dos pacotes...


Apt-Mirror

O primeiro método que vamos implementar é o de espelhamento do repositório inteiro. Este método irá fazer o download de todos os pacotes, independente de você usar ou não os mesmo. A vantagem é que qualquer coisa que esteja armazenada no repositório estará, também, no nosso.

P.S.: Só para avisar, é necessário ter pelo menos uns 20 a 30Gb de espaço para cada release e arquitetura que você for copiar.

Primeiramente, vamos instalar os seguintes pacotes:

  • apt-mirror (sudo apt-get install apt-mirror)
  • apache2 (sudo apt-get install apache2)

Depois, é necessário configurar algumas opções do apt-mirror para que ele saiba o que copiar. A configuração é feita no arquivo /etc/apt/mirror.list. Abaixo coloquei um exemplo de arquivo, onde eu estou indicando para a ferramenta copiar os repositórios 32 e 64 do Ubuntu 11.04, junto com o repositório do Linux Mint Katya e alguns repositórios extras:

############# config ##################

set base_path    /mnt/Big500Gb/repositorio

set mirror_path  $base_path/mirror
set skel_path    $base_path/skel
set var_path     $base_path/var
set cleanscript $var_path/clean.sh
set nthreads     20
set _tilde 0

############# end config ##############

# Ubuntu 11.04 "Natty" + Linux Mint Katya 32 bits

deb-i386 http://packages.linuxmint.com/ katya main upstream import

deb-i386 http://archive.ubuntu.com/ubuntu/ natty main restricted universe multiverse
deb-i386 http://archive.ubuntu.com/ubuntu/ natty-updates main restricted universe multiverse
deb-i386 http://security.ubuntu.com/ubuntu/ natty-security main restricted universe multiverse
deb-i386 http://archive.canonical.com/ubuntu/ natty partner
deb-i386 http://extras.ubuntu.com/ubuntu/ natty main

# Ubuntu 11.04 "Natty" + Linux Mint Katya 64 bits

deb-amd64 http://packages.linuxmint.com/ katya main upstream import

deb-amd64 http://archive.ubuntu.com/ubuntu/ natty main restricted universe multiverse
deb-amd64 http://archive.ubuntu.com/ubuntu/ natty-updates main restricted universe multiverse
deb-amd64 http://security.ubuntu.com/ubuntu/ natty-security main restricted universe multiverse
deb-amd64 http://archive.canonical.com/ubuntu/ natty partner
deb-amd64 http://extras.ubuntu.com/ubuntu/ natty main

# Extras

#Medibuntu
deb-i386 http://packages.medibuntu.org/ natty free non-free
deb-amd64 http://packages.medibuntu.org/ natty free non-free

#Google 
# Autenticação: wget -q https://dl-ssl.google.com/linux/linux_signing_key.pub -O- | sudo apt-key add -
deb-i386 http://dl.google.com/linux/deb/ stable non-free main
deb-amd64 http://dl.google.com/linux/deb/ stable non-free main

# Limpeza dos diretórios (remoção de pacotes não presentes nos índices atualizados)

clean http://packages.linuxmint.com/
clean http://archive.ubuntu.com/ubuntu/
clean http://security.ubuntu.com/ubuntu/
clean http://archive.canonical.com/ubuntu/
clean http://extras.ubuntu.com/ubuntu/
clean http://packages.medibuntu.org/
clean http://dl.google.com/linux/deb/

Note que aqui, ao contrário das linhas normais do apt, estamos indicando deb-i386 e deb-amd64. Isso é feito para indicar que estamos baixando os repositórios tanto de 32 quanto de 64 bits. Se você colocar somente deb, ele irá baixar somente os pacotes da versão da sua distribuição.

Se você observar o script, ele define o path onde o apt-mirror irá colocar os pacotes, define algumas pastas específicas como skel e var e indica onde o script que fará a limpeza do repositório se encontra. O script nós vamos copiar de outro local, com o comando:

cp /var/spool/apt-mirror/var/clean.sh /mnt/Big500Gb/repositorio/var/

Agora, podemos iniciar a cópia dos repositórios com o comando:

apt-mirror

Fique avisado que, dependendo da sua conexão à internet, este processo poderá demorar muito. Com base nas configurações deste arquivo, a quantidade de pacotes pode passar facilmente dos 70Gb. Então, esteja avisado!

Agora que já baixamos todos os pacotes, é necessário torná-los disponíveis para os outros PCs na rede. Para isso, nós usamos o Apache, pois os arquivos devem estar disponíveis através de uma conexão http.

No meu exemplo, o repositório está montado em um disco rígido separado para ele. Par tornar este repositório disponível, só precisamos criar um link simbólico para ele, apontanto para a pasta onde o Apache procura por documentos. Assim ...

$ sudo mkdir /var/www/repositorio
$ cd /var/www/repositorio/
$ sudo ln -s /mnt/Big500Gb/repositorio/mirror/archive.ubuntu.com/ubuntu/ ubuntu
$ sudo ln -s /mnt/Big500Gb/repositorio/mirror/archive.canonical.com/ubuntu/ partner
$ sudo ln -s /mnt/Big500Gb/repositorio/mirror/extras.ubuntu.com/ubuntu/ extras
$ sudo ln -s /mnt/Big500Gb/repositorio/mirror/security.ubuntu.com/ubuntu/ security
$ sudo ln -s /mnt/Big500Gb/repositorio/mirror/packages.medibuntu.org/ medibuntu
$ sudo ln -s /mnt/Big500Gb/repositorio/mirror/packages.linuxmint.com/ linuxmint
$ sudo ln -s /mnt/Big500Gb/repositorio/mirror/dl.google.com/linux/deb/ google

Note que cada um dos repositórios que foi clonado deve ser representado aqui. Para uma instalação normal do Ubuntu, somente a primeira linha é realmente necessária, pois é onde a maioria dos programas estão instalados. Clonar o repositório security também é interessante, já que sempre há atualizações nesta árvore, e ter ela na rede local diminuiria bastante o acesso aos repositórios oficiais.

Configurando o Cliente

Agora que configuramos nosso mirror, vamos agora configurar os clientes ubuntu para buscar pacotes nele. Para isso, vamos editar o arquivo /etc/apt/sources.list e configurar os repositórios. Originalmente, seu arquivo deve estar com a seguinte configuração:

deb http://packages.linuxmint.com/ katya main upstream import
deb http://archive.ubuntu.com/ubuntu/ natty main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ natty-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ natty-security main restricted universe multiverse
deb http://archive.canonical.com/ubuntu/ natty partner
deb http://extras.ubuntu.com/ubuntu natty main
deb http://packages.medibuntu.org/ natty free non-free

e irá ficar assim:

# deb http://packages.linuxmint.com/ katya main upstream import
# deb http://archive.ubuntu.com/ubuntu/ natty main restricted universe multiverse
# deb http://archive.ubuntu.com/ubuntu/ natty-updates main restricted universe multiverse
# deb http://security.ubuntu.com/ubuntu/ natty-security main restricted universe multiverse
# deb http://archive.canonical.com/ubuntu/ natty partner
# deb http://extras.ubuntu.com/ubuntu natty main
# deb http://packages.medibuntu.org/ natty free non-free

# Nosso servidor está rodando no ip 192.168.7.150, então:

deb http://192.168.0.150/repositorio/linuxmint katya main upstream import

deb http://192.168.0.150/repositorio/ubuntu/ natty main restricted universe multiverse
deb http://192.168.0.150/repositorio/ubuntu/ natty-updates main restricted universe multiverse
deb http://192.168.0.150/repositorio/security/ natty-security main restricted universe multiverse
deb http://192.168.0.150/repositorio/partner/ natty partner
deb http://192.168.0.150/repositorio/extras/ natty main

deb http://192.168.0.150/repositorio/medibuntu/ natty free non-free
deb http://192.168.0.150/repositorio/google/ stable non-free main

Depois que você adicionar os repositórios, rode um sudo apt-get update e então você já estará apto a baixar pacotes do mirror que implementamos.

Para finalizar, é necessário que coloquemos nosso serviço para rodar de tempos em tempos. Isso pode ser feito com o cron. Na instalação do apt-mirror, ele instalou também um script de cron na pasta /etc/cron.d/apt-mirror. Edite este arquivo e descomente a linha referente à tarefa do apt-mirror. Ele já vêm configurado para fazer o update às 4h da manhã, mas você pode mudar isso alterando o 4 para alguma hora de sua escolha.

P.S.: Só lembrando que se vc estiver fazendo isso em uma Install Fest, não se esqueça de voltar os repositórios das pessoas para o normal, senão elas não conseguirão mais acessar updates nem baixar novos aplicativos depois que sair do local.


Apt-Cacher

Acabamos de implementar nosso mirror, que possui todos os pacotes dos repositórios citados. Isso pode ser bastante útil para diminuir o tráfego de rede local ou mesmo para facilitar as Install Fests. No entanto, muitos pacotes que provavelmente nunca serão usados são carregados no mirror. Como citado anteriormente, isso irá consumir bastante espaço de armazenamento do seu servidor.

Caso você só queira diminuir a banda evitando que várias máquinas baixem o mesmo pacote várias vezes, podemos simplesmente fazer cache dos pacotes assim que eles forem baixados a primeira vez, e usar a versão local assim que for pedida novamente. Para esta função, o Apt-Cacher funciona perfeitamente.

O Apt-Cacher funciona desta forma. Ele simplesmente recebe as requisições de pacotes dos clientes, baixa os mesmos e envia para o cliente. Caso outro cliente solicite o pacote, o Apt-Cacher irá enviar a versão local ao invés de enviar a versão do repositório oficial.

Para o Apt-Cacher funcionar, precisaremos instalar os seguintes pacotes:

  • apt-cacher (sudo apt-get install apt-cacher)
  • apache2 (sudo apt-get install apache2)

Assim que os pacotes forem instalados, vamos iniciar o serviço do apt-cacher. Para isso, é necessário editar o arquivo /etc/default/apt-cacher e mudar a linha "AUTOSTART=0" para "AUTOSTART=1".

Agora, só precisamos iniciar o serviço:

$ sudo service apt-cacher restart

Configurando o Cliente

Assim que nosso servidor estiver rodando, iremos configurar nossos clientes. Para isso, vamos configurar o apt para utilizar o nosso servidor como proxy para as requisições de pacotes. Isto é feito criando um arquivo de configuração de proxy na pasta /etc/apt/apt.conf.d/:

$ cd /etc/apt/apt.conf.d/
$ sudo echo 'Acquire::http::Proxy "http://192.168.0.150:3142";' > 90-apt-proxy.conf
$ sudo echo 'Acquire::ftp::Proxy "http://192.168.0.150:3142";' >> 90-apt-proxy.conf

Agora, cada vez que o usuário for instalar um pacote ou atualização, ele irá utilizar o nosso proxy para isto, diminuindo a quantidade de tráfego da rede, limitando somente à tráfego interno.



Conclusão

Criar um mirror ou um servidor de cache para armazenar localmente pacotes muito utilizados pode ter um impacto enorme no uso da banda de internet. Não importa se é um mirror, que contém todos os pacotes possíveis e imagináveis ou se é só um cache que só pega os pacotes solicitados, as duas soluções são simples e bem fáceis de manter, pelo custo em banda que elas poupam.

Fontes:

Ubuntu-br - apt-cacher
Guia do Hardware - Criando um servidor APT local