O processo de boot no Linux sempre ocorreu integradamente com um programa específico para inicialização de sistemas (system init). O systemd, assunto que trataremos neste conteúdo, simboliza, de certa forma, uma evolução das soluções existentes para essa função.
No Windows, por exemplo, o mesmo processo é feito usando o Service Control Manager. Nele, existem subsistemas, como: o PreSMSS, que invoca o kernel, o SMSSInit, que se inicia quando o kernel repassa o controle da sessão para carregamento dos drivers e dispositivos, entre outros.
Em sistemas baseados em Unix, como é o caso do Linux, os desenvolvedores de sistemas optavam entre System V Init e Upstart. Conforme explico no presente artigo, o avanço tecnológico vem aproximando essas soluções da defasagem, fato que deu origem ao systemd.
Tendo em vista apresentar o systemd de modo descomplicado — embora o tema seja, de fato, complexo —, o texto a seguir fornece explicações mais didáticas, numa clara tentativa de não queimar etapas.
Portanto, foi necessário recorrer à essência dos sistemas init para esclarecer a importância do systemd e, posteriormente, falar de suas funcionalidades, comandos básicos de gerenciamento e a sua utilização no Debian. Entendido? Então vamos começar!
Introdução ao systemd
O systemd é um sistema de inicialização (init system) composto por um conjunto de programas executado em segundo plano (ou seja, um daemon). Atualmente, a maioria das distribuições Linux utilizam do systemd para execução do boot.
Na prática, o systemd assume o controle assim que o kernel é ativado pelo gerenciador de bootloader (Grub, tipicamente). A partir daí, são carregados todos os dispositivos (placa de rede, processador gráfico etc.) e processos que se iniciam com o sistema — estes são identificados pelo PID (process identifier).
Ainda que tenha sido lançado em 2009, sem se destacar pela maturidade, o systemd não demorou muito para se consolidar nesse universo. O Fedora, por exemplo, foi o primeiro dos projetos notáveis a utilizá-lo por padrão.
Hoje com 10 anos em atividade, o systemd, motivo de receio e “vítima” de resistência por parte dos desenvolvedores por um tempo, já mostrou o seu potencial para otimizar o processo de boot em vários aspectos.
Como surgiu o systemd?
Os grandes responsáveis pela criação do systemd foram os alemães Lennart Poettering e Kay Sievers, ambos engenheiros de software do grupo Red Hat, entre muitos outros especialistas que participaram do projeto (ao todo, mais de 1.300 autores).
Segundo Poettering, o systemd foi desenvolvido para se adaptar à irremediável evolução tecnológica. Ou seja, a intenção é fazer com que a consolidação do systemd como padrão nas distros baseadas em Linux se estenda por tempo indeterminado.
Porém essa não é a única vantagem, nem o único motivo pelo qual o sistema se popularizou. É importante ponderar as necessidades que o systemd se propôs a suprir e, também, a vasta gama de recursos que ele disponibiliza e seus antecessores, não.
Systemd versus sysvinit e Upstart
Desde a época em que foi lançado, o systemd trouxe uma rica quantidade de recursos e funcionalidades que, em comparação aos tradicionais sysvinit e Upstart, oferece muito mais possibilidades. Inclusive, ele não é considerado um sistema de init, somente.
Para se ter ideia do abismo entre o systemd e seus antecessores, recomendo a leitura desta publicação (em inglês) do blog atualizado pelo próprio Lennart Poettering, na qual o autor fez um breve comparativo das features disponíveis em cada um deles.
Em suma, foram listados 99 recursos presentes no systemd; oito deles são encontrados no System V init e no Upstart, 16. Não há nada que eles façam que o systemd não seja capaz de fazer e, de quebra, o systemd oferece quase 80 recursos a mais.
Modus operandi do systemd
Outra vantagem do systemd é a sua arquitetura e modo de funcionamento. Nele são usadas unidades de socket, que são arquivos de configuração que codificam informações relacionadas à comunicação entre processos (Inter Process Communication – IPC), a soquetes de rede ou a arquivos FIFO.
Qual a importância disso tudo? Tal capacidade permite que todos os daemons requisitados no boot sejam carregados simultaneamente, bem como possibilita a transmissão coordenada entre dois sockets, resultando a rápida inicialização do sistema operacional.
Para efeitos de comparação, o sysvinit, utilizado em distros mais antigas do Linux, carrega todos os serviços (um por vez, automática e ordenadamente), utilizando shell scripts durante o boot. Em razão disso, ele é um sistema lento e propício a problemas.
De que “problemas” estou falando? Vamos supor que determinado serviço não foi carregado pelo sysvinit. Diante da situação, o usuário precisa iniciá-lo manualmente, pois o sysvinit não pode ser acionado depois de concluído o boot.
A princípio pode até não parecer muito, mas, se colocarmos à mesa todos os dispositivos que conectamos no computador por meio de portas USB, LAN, HDMI, adaptador Bluetooth, entre outros, percebemos que as dores de cabeça seriam bastante recorrentes.
Você se lembra de quando mencionei o systemd como evolução (e revolução, ao mesmo tempo) desse tipo de sistema? Pois então, essa adaptabilidade às tecnologias atuais justifica o que eu disse.
Arquitetura do systemd
Basicamente, a estrutura do systemd parte da organização de suas tarefas em unidades (units). Abaixo, algumas classes de units que constituem o systemd:
- service: tais unidades são os serviços presentes no sistema operacional acessíveis ao usuário;
- timer: temporizadores usados para determinar ações para um serviço usando como base o tempo (não confundir com o cron);
- mount: arquivo de configuração que codifica informações sobre um diretório controlado e supervisionado pelo systemd;
- target: grupos de unidades que reúnem todas as units necessárias para iniciar um determinado serviço;
- snapshot: mecanismo usado para criar snapshots dinâmicos do estado atual do systemd manager, útil para retomar o estado após problemas com indisponibilidade, por exemplo;
- path: unidades especialmente utilizadas para monitorar arquivos e diretórios para eventos e, também, executar serviços;
- socket: arquivo de configuração que armazena informações acerca de um IPC ou soquete de rede ou arquivo FIFO; e
- swap: guarda informações relativas a dispositivos usados para swapping, bem como serviços que utilizam de memória Swap.
Cada serviço é alocado pelo systemd em um grupo de controle dedicado (control group, ou cgroup). No cgroup são organizas informações voltadas aos processos que fazem parte do grupo, como limite, supervisão e contabilização de recursos computacionais que eles consomem.
O controle desses grupos é feito a partir de utilitários que acompanham o systemd, tais como: journalctl, cgls, cgtop e systemctl — ainda falarei sobre este último, aqui. Mesmo com uma apresentação bem superficial dos seus componentes, é possível ter noção de quão robusto é o systemd.
Outros sistemas de inicialização
Evidentemente, ao enfatizar o impacto positivo do systemd, isso não significa que ele seja a única solução existente pós-sysvinit e Upstart. Muitos desenvolvedores têm optado por outros sistemas init, como OpenRC e runit, pelos mais variados motivos.
Nesse contexto, um sistema que vem “rivalizando” com o systemd é o OpenRC. Trata-se de um init criado pouco antes do systemd, em 2007, pela equipe do Gentoo, que detém o projeto atualmente.
Assim como o systemd, o OpenRC é compatível com o sysvinit, mas vai além: ele é compatível com FreeBSD e NetBSD. Além da portabilidade, o OpenRC tem como característica o uso de scripts para inicializar serviços, enquanto o systemd apenas aciona scripts — e quando estes são necessários.
Embora o systemd seja mais robusto, a sua complexidade tem levado muita gente a adotar o OpenRC, que é simples, minimalista e rápido. Enquanto o systemd é considerado monolítico, o OpenRC é visto como um sysvinit incrementado.
O que é melhor para você? Existem algumas variáveis para responder a pergunta, tais como:
- necessidades (requisitos do projeto);
- nível de experiência; e
- preferências.
Quando falamos em sistemas de init, assim como quando falamos sobre distribuições do Linux, não cabe debater qual é a melhor opção em aspectos gerais, mas refletir acerca dessas e outras particularidades.
Comandos básicos para controlar serviços no systemd
Gerenciar o sistema e os serviços é um dos atributos mais legais do systemd. Isso pode ser feito graças ao utilitário systemctl , que nos auxilia no controle do próprio systemd e, também, atua como gerenciador de serviços.
Por outras palavras, ele nos permite decidir o que fazer com os processos: monitorar, encerrar, iniciar, analisar, recarregar, checar status etc. Sem dúvida alguma, um recurso e tanto que o administrador tem em mãos.
Quer aprender a como gerenciar os serviços em sua distro do Linux com systemd? A seguir, apresento sete comandos básicos para você começar a praticar. Confira!
Listar todos os serviços disponíveis
Primeiramente, convém descobrirmos quais são os serviços detectados pelo systemd e que podem ser habilitados / desabilitados, não é mesmo? Faça isso digitando o comando:
# systemctl list-unit-files --type=service
Ativar um serviço e habilitá-lo (ou desabilitá-lo) no boot
Localizou algum serviço que você queira aplicar a função auto start (inicialização automática junto ao sistema)? Abaixo, as argumentações do comando systemctl para ativar serviços, bem como habilitar / desabilitar o próprio do auto start.
# systemctl is-active httpd.service # systemctl enable httpd.service # systemctl disable httpd.service
Realizar ações básicas para determinado serviço
O gerenciamento básico de serviços envolve ações como iniciar, reiniciar, parar, recarregar e verificar status de um elemento. Felizmente, o systemd é muito prático quanto a isso, bastando que digitemos o comando systemctl, seguido da opção e o nome do serviço. Exemplo:
# systemctl start httpd.service # systemctl restart httpd.service # systemctl stop httpd.service # systemctl reload httpd.service # systemctl status httpd.service
Utilizar a função kill
O comando kill é utilizado no Linux (e outros sistemas operacionais) para “matar” um processo. Geralmente, o acionamos quando um determinado serviço não se encerra, exigindo que a gente force o seu fechamento. No systemd, usamos o kill da seguinte maneira:
# systemctl kill httpd
Feito isso, confirme se o procedimento teve sucesso usando o comando systemctl status httpd.service (substitua o valor pelo serviço em questão).
Controlar uso de CPU (shares) de um serviço
Com o systemd é possível alocar cargas de trabalho (workload) para cada serviço. Estrategicamente, administradores de sistemas criam classes de serviços para equilibrar os níveis de processamento, aproveitando melhor os recursos computacionais.
A métrica usada para definir a quantidade de recursos que pode ser utilizada se chama “shares” (que significa compartilhamentos, numa tradução livre). Por padrão, os serviços recebem o valor de 1024 shares, que pode tanto ser aumentado quanto reduzido.
Para fazê-lo, use o comando de acordo com o exemplo:
.include /usr/lib/systemd/system/httpd.service
[Service] CPUShares=2500
Nesse caso, aumentamos em 2500 o valor de shares para o arquivo httpd.service, localizado no diretório declarado. Para que as alterações entrem em vigor, basta reiniciar o serviço.
systemctl daemon-reload systemctl restart httpd.service
Analisar consumo de recursos do CPU
Logicamente, o bom gerenciamento de recursos requer do sysadmin prévio conhecimento de como eles estão distribuídos no momento. Essas informações podem ser apresentadas por meio da ferramenta cgtop, a qual acompanha o systemd.
Ela serve, entre outras coisas, para exibir informações específicas dos cgroups existentes no sistema, como lista ordenada por nome, grupo, uso de memória ou CPU, por exemplo. Esta última é impressa a partir do seguinte comando:
-c, --order=cpu
Um breve manual de instruções está disponível neste link (em inglês).
Gerenciar uso de memória RAM de um serviço
Tão interessante quanto alocar o processamento a ser consumido por um serviço é delimitar o uso de memória RAM. Por exemplo, se determinado processo tem baixa prioridade, mas o seu consumo de RAM é acima do aceitável, digite:
.include /usr/lib/systemd/system/httpd.service [Service] MemoryLimit=1G
No exemplo acima, o systemd foi usado para ajustar o limite de memória RAM em 1 GB ao serviço declarado. O mesmo pode ser feito com o consumo de banda larga e swapping, por exemplo.
Systemd na distribuição Debian
Desde a aprovação do systemd como init padrão do projeto Debian, em 2014, a distro passou a fornecer o systemd numa versão limitada usada como prévia da tecnologia. Se você é usuário do Debian jessie (ou mais recente, como o Buster), siga as instruções para instalação:
# apt update # apt install systemd
Em seguida, é necessário fazer uma breve configuração do systemd. No menu principal do Grub, tecle “e” e, então, adicione o parâmetro “init=/lib/systemd/systemd” (sem aspas) na linha kernel. Se você não conseguir localizá-la, procure por algo do tipo:
linux /vmlinuz-3.13-1-amd64 root=/dev/mapper/root-root init=/lib/systemd/systemd ro quiet
Para finalizar o processo, faça a instalação do gerenciador de serviços systemd-sysv (vide comando, abaixo) e, então, reinicie a máquina.
# apt-get install systemd-sysv
Se a instalação foi realizada com sucesso, a partir de agora você poderá testar o systemd no Debian e, assim, compreender melhor o seu funcionamento dos comandos apresentados no conteúdo. Para mais informações, continue acompanhando as próximas publicações do blog!
Você está decidido a aprender Linux a fundo para se tornar um verdadeiro especialista? Aproveite e dê um passo importante na sua carreira: acesse agora mesmo a sua primeira aula!