Por que martelar nas unhas com um microscópio se você possui o Alpine Linux?

Ao chamado de meu coração e trabalhando como engenheiro de sistemas em Design Digital, muitas vezes tenho que lidar com produtos sofisticados de software e projetos de arquitetura. Isso causa um desejo de minimizar e simplificar tudo o que está à mão e leva ao prazer das decisões humanas que apenas fazem seu trabalho , sem registro e SMS .


Então eu me encontrei com o Alpine Linux.


Janela inesperada


Você pode gostar desta distribuição pelos seguintes motivos:


  • Se você gosta de minimalismo e ferramentas orientadas para realizar a tarefa sem apitos e decorações desnecessárias;
  • Se você perceber que as distribuições “mainstream” existentes são um pouco (?) Inchadas e redundantes;
  • Se você deseja resolver um problema existente de uma maneira simples.

Por “mainstream”, refiro-me ao trio CentOS-Debian-Ubuntu (é claro, o mundo não acaba aí), perdoe-me todos aqueles que acreditam nessas distribuições maravilhosas. Quando são usados, periodicamente, na fronteira da percepção, surge um pensamento agudo - "talvez possa ser mais fácil?"


Nós realmente precisamos disso?


Desativação do modo $ holywar
Realmente para a solução de sua pequena tarefa, tudo isso é necessário:


  • Systemd maravilhoso. Um sistema de inicialização (nem um pouco) que pode dar a impressão de um sistema de controle de vaivém?

    Nenen!
    Ninguém diz que você não consegue entender como gerenciá-lo, mas seu crescimento desenfreado pode começar a assustar, e o número de conceitos excede claramente o conjunto mínimo necessário. Tudo isso é realmente necessário para a implementação de uma tarefa simples e uma reinicialização muito frequente do servidor?

  • Subsistema de log / auditoria construído em um monte como journald -> rsyslogd + auditd?


    Sem dúvida, isso é ótimo!

    Pode-se adivinhar por que isso é feito dessa maneira, mas essa cadeia é realmente necessária para minha tarefa simples?


  • Duplicação da funcionalidade de execução periódica de tarefas no systemd e no crond?

    Oh aquele Cron!
    Estou realmente sentindo falta do mecanismo clássico dele? Talvez sua sintaxe possa não ser completamente óbvia, mas os timers em sd são tão óbvios?

  • Coexistência de vários subsistemas de gerenciamento de rede em diferentes combinações: rede clássica / networkd / NetworkManager?

    Você precisa gerenciar muito a rede!
    Essa combinação, sim, no sistema do servidor e com várias interfaces de gerenciamento para todos os gostos. Embora não, vamos adicionar aqui também o netplan, que "resolve" o problema de configuração dos subsistemas listados. Deseja iniciar seu serviço ou alterar frequentemente a órbita devido à reconfiguração das interfaces de rede?

  • Serviços como tuned e firewalld?

    Como sem eles?
    Eles são necessários para a sua tarefa? Em princípio, é bom considerar o firewalld como uma tentativa de escapar da sintaxe do iptables, mas como resultado, em vez de uma sintaxe, você entenderá outra e ficará perplexo com o tamanho dos comandos do firewall-cmd. E você realmente precisa de um intérprete python e seus processos no sistema base? Não, eu amo python, mas não neste caso.

  • Serviço de correio local. Tem certeza de que o usará?



Desde que nos lembramos do minimalismo, podemos comparar muito aproximadamente nossas principais distribuições em sua instalação mínima :


  • O líder em redundância em espaço em disco e número de pacotes é o Ubuntu 18.04 ( 2,8 GB de espaço em disco, 342 pacotes, 31 serviços de sistema ativos, 15 processos na entrada). A família systemd aqui é representada na extensão máxima - systemd, networkd, timesyncd, resolved, logind, há dbus.
  • O CentOS 7.5.1804 perde por disco e número de pacotes, mas o líder em serviços provavelmente redundantes (1,1 GB de espaço em disco, 299 pacotes, 34 serviços systemd ativos, 19 processos na entrada, incluindo NetworkManager, firewalld, tuned, postfix, polkitd, auditd, journald + rsyslogd, dbus).
  • O Debian 9.4.0 tentou arduamente não inflar: 940 MB, 334 pacotes, 25 serviços systemd ativos, 14 processos no login. Obviamente, também existe um sistema aqui (assim como journald, timesyncd e o dbus que o acompanha), mas sem muito fanatismo em relação ao gerenciamento de rede.

holywar: não é possível alterar o modo para 'desativar': permissão negada


Eu quero um estranho


Você pode (tentar) se livrar manualmente de uma parte do acima exposto, mas de repente tudo já foi inventado para nós? Idealmente, quero ver na distribuição de um sistema operacional de servidor de uso geral:


  • Curiosamente, o gerenciador de inicialização, que nos alcançará no kernel;
  • O próprio kernel do sistema operacional (linux neste caso);
  • O sistema de inicialização que o kernel iniciará quando estiver pronto. É desejável, em simplicidade, não muito longe do machado;
  • O conjunto mínimo de processos que o sistema de inicialização iniciará. Bem, por exemplo:
    • Inicialização final do dispositivo e definição de parâmetros adicionais do kernel;
    • Fornecer registro no diário (é possível com revistas de texto? Bem, por favor);
    • Configuração de rede (seria bom, com menos camadas de controle);
    • Sincronização de tempo (ntpd / chronyd);
    • Vários consoles locais;
    • Opcional - execução periódica de tarefas (crond);
    • Opcional - acesso remoto ao sistema (sshd);
    • Seria bom salvar e restaurar a configuração do firewall.

E é isso, o resto depende do gerenciador de pacotes. Menos código e configuração executável - menos bugs, menos bugs - menos bugs. E o sistema também está funcionando e acessível através da rede. A idéia parece boa, agora vamos ver o quão perto a distribuição Alpine Linux está dela.


Sobre Alpine


O que pode encantar a Alpine, especialmente depois do CentOS? Minimalismo desesperado!
Bem, e, claro, a falta de necessidade de certificação " Linux Systemd Certified Voldemort ".


O que os autores fizeram:


  • Reduzido o número de componentes básicos utilizados;
  • Escolhemos módulos menores e mais transparentes;
  • Simplificado o processo de configuração do sistema.

Ou seja:


  • Processo de instalação extremamente conciso usando o utilitário setup-alpine console;
  • O Extlinux do projeto syslinux foi usado como carregador;
  • Uma pequena ferramenta de construção do mkinitfs para criar um sistema de arquivos temporário usado na inicialização;
  • Sistema de inicialização Openrc com a definição de dependências entre serviços, níveis de execução e uma pitada de script;
  • Substituindo a biblioteca GNU libc padrão por uma musl libc mais leve;
  • Em vez do pacote GNU coreutils, a maioria dos utilitários de sistema padrão em uma versão um pouco truncada faz parte do pacote busybox, com o qual você pode estar familiarizado em soluções incorporadas;
  • Por padrão, o ash shell é usado como parte do busybox. Claro, ninguém se preocupa em colocar o bash, se necessário , bem e systemd ;
  • Gerenciador de pacotes apk nativo e infraestrutura de distribuição de pacotes proprietária.

Além disso, os autores implementaram várias medidas destinadas a aumentar o nível de segurança do sistema básico:


  • Aplicamos os patches grsecurity / PaX do kernel (as opiniões diferem sobre sua eficácia, mas ainda assim); Não mais, graças ao colega pelos comentários. Em 26 de junho, a versão 3.8.0 foi lançada .
  • Os pacotes foram coletados usando modos que reduzem a probabilidade de exploração de várias possíveis vulnerabilidades.

Como resultado, obtemos um sistema equipado com vários mecanismos de proteção adicionais, o que nos permite resolver o problema existente e ocupa cerca de 130 MB . No sistema em execução, 41 pacotes estão instalados e 13 processos do usuário estão em execução, você pode ativar o ssh.


E nada mais. Resta adicionar o que você precisa (e colocar o iptables com a capacidade de restaurar a configuração na inicialização).


Abra ligeiramente a tampa


Observe: o Alpine pode ser útil como campo de treinamento ao se familiarizar com o Linux! É subjetivamente mais fácil ver a lógica dos componentes do que tentar cobrir o CentOS ou Ubuntu:


  • O gerenciador de inicialização do nosso sistema instalado é simples, sua configuração é dividida em 12 linhas:

Configuração do carregador de inicialização


  • Sim, e o arquivo / boot não está muito cheio:

saída ls / boot


  • E aqui está o carregador de inicialização lançado sem papel de parede elegante:

Executando o gerenciador de inicialização


  • O kernel é inicializado, pega o initramfs, cumpre suas próprias etapas de inicialização e chama o comando init (que, de fato, também vem com o busybox). O Init usa o arquivo / etc / inittab:

Conteúdo de / etc / inittab


  • E aqui está explicitamente explicitado o que precisa ser iniciado para inicializar o sistema:
    • Execute 6 processos getty aguardando em 6 consoles virtuais pelo login do usuário local.
    • Execute o sistema de inicialização do openrc para alcançar alternativamente os níveis de inicialização necessários (o openrc não usa os níveis de inicialização clássicos de 0 a 6, mas seus próprios níveis / grupos sysinit - boot - padrão).

Além disso, o estado do sistema depende da configuração do openrc, a saber:


  • Variáveis ​​definidas nos arquivos de diretório /etc/conf.d;
  • Execute scripts localizados no diretório /etc/init.d;
  • Vinculando scripts de inicialização a "grupos de inicialização":

Demônios e seu nível de ligação


Resta ler os scripts de inicialização e processá-los, levando em consideração os níveis e dependências de inicialização.
Usando o exemplo syslog (/etc/init.d/syslog), podemos ver como é o script de inicialização do openrc.


Como você pode ver, essas nem sempre são as de suas malas não amadas:


Exemplo de arquivo de configuração Openrc


As variáveis ​​usadas ao executar o script são definidas no arquivo correspondente /etc/conf.d/syslog. No nosso caso, a variável SYSLOGD_OPTS = "- Z" é definida no arquivo
Observe que o script define declarativamente as dependências desse serviço.


O Openrc itera honestamente os scripts de inicialização em uma determinada ordem, atinge o nível "padrão" - e aqui está, um sistema em funcionamento!


Demônios sob o capô


O que exatamente está oculto nos scripts de inicialização do openrc? Curiosamente - um conjunto de tarefas e demônios listados abaixo.


  • Primeiro, no nível sysinit:


    • dmesg - define o nível de log para mensagens do kernel;
    • devfs - monte e configure / dev;
    • mdev - o gerenciador de dispositivos é iniciado;
    • hwdrivers - os módulos do dispositivo são carregados com base nas informações de / sys e / dev;

  • Em seguida é o nível de inicialização:


    • modules - os módulos do kernel são carregados, cuja lista é definida em / etc / modules;
    • hwclock - relógios de hardware em tempo real são configurados;
    • sysctl - define os parâmetros do kernel que definimos em /etc/sysctl.conf;
    • swap - a partição swap está conectada;
    • bootmisc - diretórios temporários são limpos;
    • urandom - um gerador de números aleatórios está configurado;
    • mapas de teclas - o layout do teclado é inicializado;
    • hostname - define o nome da máquina, definido em / etc / hostname;
    • networking - busca e inicialização de interfaces usando informações de / etc / network / interfaces;
    • syslog - inicia o daemon de log do busybox;

  • E, finalmente, o nível padrão:


    • chrony - o serviço NTP é iniciado;
    • crond - o serviço de execução de tarefa agendada é iniciado;
    • acpid - o serviço de rastreamento de eventos de energia é iniciado;
    • sshd - o serviço de acesso remoto é iniciado.


Hooray, depois de concluir essas etapas, o sistema está pronto para começar! Não se esqueça das dependências nos serviços acima que foram especificados nos arquivos init.d:


  • sysfs - montagem / sys;
  • fsck - verifica e corrige sistemas de arquivos;
  • root - monte o sistema raiz para escrever / ler;
  • localmount - monte todos os sistemas de arquivos listados em / etc / fstab;
  • klogd - registrando eventos do kernel.

Abrimos um dos consoles locais onde o getty está esperando por nós, inserimos o logon, após o qual passamos a senha para o processo de logon e obtemos acesso ao ash shell em execução (quando iniciado, o conteúdo dos arquivos / etc / profile, /etc/profile.d/* e ~ /.profile para preparar o ambiente do usuário).


Hooray, nenhuma entidade adicional (sem dúvida útil em alguns casos, como o PAM) - e estamos no sistema!


Resta usar o gerenciador de pacotes apk e procurar os pacotes necessários para nossa tarefa. (Eles estão aí? Você pode avaliar isso através do portal da web ).


E também


  • Os autores da distribuição criaram seu próprio complemento de iptables chamado "Alpine Wall". E não trava constantemente como um processo separado no sistema;
  • Para quem gosta de gerenciar o servidor por meio da interface da web, o pacote Alpine Configuration Framework foi preparado. Sem PHP ou Perl, mas com Lua;
  • Para quem deseja um desktop, existe a possibilidade de instalar um ambiente gráfico (embora isso possa parecer doloroso no início);
  • Para conhecedores especiais, há uma “instalação” do Alpine na memória com a configuração armazenada no armazenamento externo (consulte a descrição da ferramenta lbu ).

Sumário


A distribuição alpina não é perfeita, mas seu laconicismo realmente me impressionou, especialmente no papel de um contêiner (apenas 6 processos - init, 4 * getty, syslogd). Para mim, parece que o sistema operacional mínimo do servidor deve ser (perdoe-me, CentOS!).


Além disso, é bastante adequado para o papel de uma plataforma de treinamento, que permite ver em que consiste um kit de distribuição moderno, sem mergulhar imediatamente no abismo de qualquer serviço e duplicar repetidamente a funcionalidade em ferramentas configuráveis ​​em vários níveis para todas as ocasiões.

Source: https://habr.com/ru/post/pt415279/


All Articles