1up4developers logo

1up4developers

Nadando contra o Waterfall. tail -f /mind/realworld >> /blog

Introdução a Linux Control Groups (CGroups)

| | Comments


Em tempos de Metodologias Àgeis, iniciativas como DevOps, adoção de Cloud Computing e derivados (SaaS, IaaS e PaaS), aplicações que demorariam meses, senão anos para estar na www, hoje em questão de dias, e por que não horas, é possível estar disponíveis ao usuário final.

Com a necessidade de ter os aplicativos de forma mais rápida em produção, a adoção e criação de PaaS (Platform as A Service) tem sido a nova “onda do verão” e tecnologias como LXC, Docker e CGroups atuam como o cerne dessa “wave”.

O que são CGroups?

CGroups é uma feature do Kernel que provê mecanismos para organização de Processos em forma de grupos e limita recursos de máquina como Consumo de CPU, memória e I/O para estes.

Curioso pra ver como funciona?

Situação de Exemplo

Para este exemplo teremos duas aplicações Sinatra e nosso objetivo será dedicar um grupo para cada aplicação limitando o consumo de memória para cada uma elas.

Para rodar o exemplo estarei utilizando um Ubuntu 12.04 64 bits.

Pré-Requisitos

Antes de mais nada precisamos instalar algumas dependências:

1
sudo apt-get install cgroup-bin libcgroup1

Com a instalação dos pacotes acima veremos que um novo filesystem foi montado em /sys/fs/cgroup

1
2
3
4
5
6
7
8
9
ls -al /sys/fs/cgroup

drwxr-xr-x 7 root root 140 Aug  6 09:38 .
drwxr-xr-x 6 root root   0 Aug  6 09:37 ..
drwxr-xr-x 6 root root   0 Aug  6 09:38 cpu
drwxr-xr-x 6 root root   0 Aug  6 09:38 cpuacct
drwxr-xr-x 6 root root   0 Aug  6 09:38 devices
drwxr-xr-x 6 root root   0 Aug  6 09:38 freezer
drwxr-xr-x 6 root root   0 Aug  6 09:38 memory

CGroups estão organizados por subsistemas conhecidos também como “resource controllers” responsáveis por gerenciar memória, cpu, dispositivos, entre outras coisas. Na organização acima cada diretório representa um Resource Controller.

CGConfig Service

Para gerenciar CGroups iremos utilizar a utilitário cgconfig instalado como o pacote libcgroup1. É interessante checar se o serviço está rodando antes de continuar :

1
sudo service cgconfig status

Caso não esteja inicie o serviço

1
sudo service cgconfig start

Existem duas formas de configurar CGroups com cgconfig, diretamente no arquivo de configuração /etc/cgconfig.conf’ ou via linha de comando, que será o meio que iremos utilizar.

Criando Grupos

Para criar um grupo, utilizamos o comando cgcreate passando como argumento quais controllers estarão associados a ele.

1
2
sudo cgcreate -g cpu,cpuacct,devices,memory,freezer:/sinatra1
sudo cgcreate -g cpu,cpuacct,devices,memory,freezer:/sinatra2

O argumento /sinatra* indica o caminho relativo do grupo dentro de cada Resource Controller. Ex : /sys/fs/cgroup/<resource_controller>/

Executando programas em um Grupo

Para executar determinado processo em um grupo utilizamos o comando cgexec passando como argumentos quais controllers estarão associados ao processo e o caminho do grupo que ele estará associado.

1
2
sudo cgexec -g *:/sinatra1 sh -c 'cd <path_to_sinatra1> && exec rackup -p 4567 -D'
sudo cgexec -g *:/sinatra2 sh -c 'cd <path_to_sinatra2> && exec rackup -p 4568 -D'

O asterisco (*) acima significa que o processo estará associado a todos os controllers.

Para checar a hierarquia criada:

1
2
3
4
ps xawf -eo pid,cgroup,args | grep ruby
 1476              \_  5:freezer:              \_ grep --color=auto ruby
 1418  5:freezer:/sinatra1?4:memo /usr/bin/ruby1.9.1 /usr/local/bin/rackup -p 4567 -D
 1454  5:freezer:/sinatra2?4:memo /usr/bin/ruby1.9.1 /usr/local/bin/rackup -p 4568 -D

Para setar os valores em determinado controller utilizamos o comando cgset. No caso abaixo estamos limitando o consumo de memória para o grupo sinatra1 em 256MB e para o grupo sinatra2 em 128MB.

1
2
sudo cgset -r memory.limit_in_bytes='256M' sinatra1
sudo cgset -r memory.limit_in_bytes='128M' sinatra2

Para checar a alteração:

1
2
cat /sys/fs/cgroup/memory/sinatra1/memory.limit_in_bytes
cat /sys/fs/cgroup/memory/sinatra2/memory.limit_in_bytes

Conclusão

O intuito deste artigo foi demonstrar um dos possíveis usos de CGroups. Caso a aplicação sinatra1 cair por estouro de memória ou alguma outra falha que não seja a destruição da máquina, a aplicação sinatra2 continuará funcionando.

Há mais a se explorar, poderíamos inserir limitação de I/O, consumo de banda, entre outras coisas. Poderíamos até criar nossa própria implementação de LXC, mas isso é assunto para um próximo encontro.

Os links abaixo exploram mais detalhes sobre o assunto :

Divirtam-se!

Comments