sexta-feira, 21 de novembro de 2014

Espelhamento simples no Linux

É comum pequenos escritórios adotarem uma máquina na rede para servir como servidor de arquivos e, talvez, gateway de internet (com ou sem um proxy). Usei como base para o post Guia de configuração do Samba não-PDC um cenário assim.

Backup costuma ser negligenciado nesses locais e não é incomum boa parte dos dados importantes, quando não todos, estar unicamente num disco rígido de consumo, instalado numa máquina de fundo de quintal com uma fonte genérica ligada num estabilizador.

Existem três providências que podem melhorar consideravelmente a confiabilidade sem grande custo:

- Se for uma máquina Frankenstein, colocar uma fonte de alimentação decente. Uma fonte com PFC ativo barata fica entre R$ 100 ~ 200 e é suficiente. Jogue o estabilizador no lixo reciclável e ligue-a num protetor contra surtos.

- Coloque Linux no servidor. Dá para conseguir resultado similar usando Windows Server (com mais trabalho), mas trato aqui de uma configuração com Linux. A distribuição escolhida é o openSUSE 13.2.

- Instale um segundo disco rígido na máquina. Preferencialmente de igual tamanho ou maior do que o existente.

MD RAID1

Estamos falando de hardware de desktops. RAID por hardware é ficção. Entra, portanto, RAID por software. O esquema é o seguinte:

DISCO 1 - Porta SATA1

    +--------------------------------------------------------+
    |   /dev/sda1         /dev/sda2                          |
    |   +-------------+   +------------------------------ ~  |
    |   | Partição 1  |   |   Partição 2                     |
    |   |             |   |                                  |
    |   |    Swap     |   |   Linux RAID                     |
    |   |             |   |                                  |
    |   |             |   |                                  |
    |   +------------ +   +------------------------------ ~  |
    |                                      ^                 |
    +--------------------------------------|-----------------+
                                           |
DISCO 2 - Porta SATA2                  /dev/md0 -- RAID1
                                           |
    +--------------------------------------|-----------------+
    |   /dev/sdb1         /dev/sdb2        v                 |
    |   +-------------+   +------------------------------ ~  |
    |   | Partição 1  |   |   Partição 2                     |
    |   |             |   |                                  |
    |   |    Swap     |   |   Linux RAID                     |
    |   |             |   |                                  |
    |   |             |   |                                  |
    |   +------------ +   +------------------------------ ~  |
    |                                                        |
    +--------------------------------------------------------+

O particionamento é simples. Estou considerando BIOS+MBR. Cada disco tem uma partição swap no começo e depois uma partição ativa do tipo "Linux RAID". Quem lê o blog sabe que não encorajo o uso de partições swap, mas abro uma exceção aqui por um motivo: os servidores de escritório podem ser máquinas meio velhas, com pouca memória. Fique à vontade para não criar as partições swap se assim desejar (adapte quando necessário nos próximos passos). Funcionará da mesma forma. Em teoria, a partição "Linux RAID" não precisa ser ativa. Não é requerido pelo GRUB. BIOS doidos às vezes não iniciam, contudo, a partir de discos sem uma partição ativa. O YaST se encarrega de marcá-las como tal automaticamente para nós.

Na instalação, temos que usar o particionamento manual ("Particionador experiente...").

(clique para ampliar)







Repita os passos acima para /dev/sdb. Ficará:


Crie o arranjo:





Btrfs para mim está fora. Sugiro ficar entre EXT4 e XFS. Ou, se você for amante da retrocomputação, o EXT3. Para ter uma configuração robusta, use no fstab apenas UUIDs. Até o openSUSE 13.1, era usado o identificador atribuído pelo udev ou o nome do dispositivo do arranjo RAID. Mudaram a política no 13.2 nas partições (agora é UUID por padrão), porém no ponto de montagem do arranjo ainda precisamos alterar. Com os EXT, marco, em "Opções...", a opção "Desabilitar verificações regulares". O journal existe justamente para evitar ser preciso fazer verificações completas manuais no sistema de arquivos. Se o kernel detectar alguma inconsistência, ativará uma flag no mesmo. No próximo boot, quando o e2fsck for executado no modo preen, verá a flag e chaveará para a verificação completa. O RHEL desativa as verificações regulares forçadas nos EXT pelo menos desde sua versão 6. [Atualização - 14/12/2014] Conferi novamente e vi que o openSUSE 13.2 marca a opção por padrão. Estava considerando o comportamento do 13.1, que não marcava-a tampouco a também recomendada "Recurso de Índice de Diretório".

nofail é importante nas partições swap. Se algum dos discos roer a corda, a partição swap dele desaparecerá e o sistema iniciará sem reclamar. Observação: no momento, o systemd do openSUSE 13.2 (210-25.5.4) ignora a configuração e coloca o olho de Cylon (90 segundos) para volumes swap inexistentes. Me parece bug.

Depois de instalado

Um macete que fará a diferença: o GRUB será instalado pelo YaST no MBR do primeiro disco. Vamos instalá-lo também no segundo disco!

# grub2-install /dev/sdb

O GRUB é capaz de acessar diretamente o arranjo RAID1, o que poupa ter que manter uma partição /boot separada e garante resiliência total para o volume do sistema.

Espere o arranjo sincronizar antes de continuar. Acompanhe com:

# mdadm --detail /dev/md0
# cat /proc/mdstat

Depois de concluído:

# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sda2[0] sdb2[1]
      155187072 blocks super 1.0 [2/2] [UU]
      bitmap: 0/2 pages [0KB], 65536KB chunk

unused devices: <none>

O diretório raiz está num único volume sobre o arranjo (o dispositivo não particionado /dev/md0):

# findmnt /
TARGET SOURCE   FSTYPE OPTIONS
/      /dev/md0 xfs    rw,relatime,attr2,inode64,noquota

O dracut adiciona o módulo resume ao initramfs e configura o systemd para esperar pelos dispositivos onde existam volumes swap, o que quebra o boot se não estiverem presentes. Precisamos dizer para o módulo não ser incluído e para não esperar por eles:

# echo -e "omit_dracutmodules+=\" resume \"\nnowaitforswap=\"yes\"" >/etc/dracut.conf.d/99-swap.conf
# dracut -f --regenerate-all

Teste de fumaça

Em muitos tutoriais sobre RAID por software, falhas são simuladas usando mdadm --fail/--remove. Serei mais realista. Infelizmente, o chipset desta máquina não suporta AHCI e, logo, não posso remover o cabo à quente. Desligarei e desconectarei o primeiro disco.

Ao ligá-la sem /dev/sda, o BIOS dará boot através de /dev/sdb normalmente. O GRUB achará o arranjo, enxergará o sistema de arquivos e carregará o kernel e o initramfs como se nada tivesse acontecido. /dev/sdb passará a ser /dev/sda. Não se preocupe, pois não faz a mínima diferença para o arranjo.

O boot será um pouco mais demorado. Espere. Veja que o arranjo está reduzido.

# mdadm --detail /dev/md0
/dev/md0:
        Version : 1.0
  Creation Time : Wed Nov 19 10:29:29 2014
     Raid Level : raid1
     Array Size : 155187072 (148.00 GiB 158.91 GB)
  Used Dev Size : 155187072 (148.00 GiB 158.91 GB)
   Raid Devices : 2
  Total Devices : 1
    Persistence : Superblock is persistent

  Intent Bitmap : Internal

    Update Time : Thu Nov 20 08:19:34 2014
          State : clean, degraded
 Active Devices : 1
Working Devices : 1
 Failed Devices : 0
  Spare Devices : 0

           Name : any:0
           UUID : xxxxxxxx:xxxxxxxx:xxxxxxxx:xxxxxxxx
         Events : 792

    Number   Major   Minor   RaidDevice State
       0       0        0        0      removed
       1       8        2        1      active sync   /dev/sda2

Aí está. O sistema continua funcionando!

Então vamos adicionar um segundo disco. Plugue-o e mãos à obra. Ajuste temporariamente no setup da placa-mãe para iniciar a partir do disco que sobrou se necessário.

Se você estiver testando e usar o mesmo disco que foi removido, antes de continuar, recomendo que rode nele sgdisk -Z através de uma mídia live para evitar confusão. Considerarei que o disco novo seja /dev/sda (lsblk e udevadm info --name /dev/<disco> ajudam na identificação).

Primeiro, limpamos o particionamento por precaução:
(sgdisk faz parte do pacote gptfdisk no openSUSE)

# sgdisk -Z /dev/sda

Criamos as partições. Os tamanhos você pode ajustar. A segunda precisa ter no mínimo o tamanho da partição RAID do outro disco. Comandos úteis: fdisk -l, parted -l.

# parted -s /dev/sda -- mklabel msdos
# parted -s /dev/sda -- mkpart primary linux-swap 0% 1GB
# parted -s /dev/sda -- mkpart primary ext2 1GB 100%
# parted -s /dev/sda -- set 2 boot on set 2 raid on

Nota: eu não consegui (e também não tentei muito) pelo parted dividir as partições exatamente como o instalador faz sem usar setores como pontos de começo e fim. Usar setores ou os prefixos binários (MiB, GiB, etc.) ao criar partições pelo parted não é recomendado porque podem não ficar alinhadas (link). Por isso fico com porcentagem ou os prefixos decimais. Como já dito, não precisa ser milimétrico. Quem preferir use o fdisk ou o cfdisk; este, a partir da versão 2.25, usada no 13.2, é um particionador moderno. Partição swap é do tipo 82. RAID do tipo fd. A última deve ficar ativa. Use apenas partições primárias. Não existe motivo para criar unidades lógicas.

Removemos eventuais assinaturas presentes nas partições recém criadas:

# wipefs -a /dev/sda1
# wipefs -a /dev/sda2

Criamos o volume swap e adicionamos ao fstab:

# mkswap /dev/sda1
# echo "UUID=$(blkid -p -s UUID -o value /dev/sda1) swap                 swap       nofail                0 0" >>/etc/fstab
# swapon -a

Adicionamos a partição ao arranjo:

# mdadm /dev/md0 --add /dev/sda2
mdadm: added /dev/sda2

Aguardamos ser reconstruído:

# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sda2[2] sdb2[1]
      155187072 blocks super 1.0 [2/1] [_U]
      [>....................]  recovery =  1.8% (2820352/155187072) finish=34.7min speed=73007K/sec
      bitmap: 2/2 pages [8KB], 65536KB chunk

unused devices: <none>

Por fim, instalamos o GRUB no novo disco:

# grub2-install /dev/sda

Ao reiniciar, configure no setup para dar boot pelo primeiro disco caso preciso e pronto!

Nenhum comentário:

Postar um comentário