Execução de scripts shell, compreensão do processo de inicialização do Linux, gerenciamento de serviços e pacotes em alto e baixo nível, diferenciação entre containers e máquinas virtuais, e implementação prática de containers Docker com automação de scripts.
Enunciado:
1. Escreva o script mvl.sh que recebe dois argumentos: origem e destino. Este script move origem para destino e salva em log.txt a data e horário que a operação foi executada.
2. Escreva o script cpl.sh que recebe dois argumentos: origem e destino. Este script copia origem para destino e salva em log.txt a data e horário que a operação foi executada.
3. Crie dois arquivos a.txt e b.txt contendo ‘a’ e ‘b’, respectivamente, e o diretório TESTE. Execute os scripts para copiar a.txt e mover b.txt para TESTE. Exiba o conteúdo de log.txt.
Scripts profissionais devem validar seus inputs. Vamos criar uma versão mais robusta que verifica se o número correto de argumentos foi passado e se o arquivo de origem realmente existe.
Explicação:
- if [ "$#" -ne 2 ]: $# contém o número de argumentos. -ne significa "não igual". Se não for 2, o script exibe uma mensagem de uso e sai com código de erro 1.
- if [ ! -e "$1" ]: O operador -e verifica se um arquivo ou diretório existe. O ! nega a condição. Se o arquivo de origem não existir, o script avisa e sai.
- exit 1: É uma convenção em shell script que uma saída com valor 0 significa sucesso, e qualquer outro valor (como 1) significa um erro.
Enunciado: Descreva e explique cada passo da inicialização do Linux.
O processo de boot do Linux é uma sequência coreografada de eventos que transforma uma máquina desligada em um sistema operacional funcional. Ele pode ser dividido nas seguintes fases principais:
/boot/grub/grub.cfg) para saber onde o Kernel e o initramfs estão localizados no disco.vmlinuz-...) e o initramfs (Initial RAM File System)./) real. Por exemplo, se o seu / está em um disco LVM ou RAID, os drivers para LVM/RAID estão no initramfs. Após carregar os drivers necessários, o Kernel descarta o initramfs e monta o sistema de arquivos raiz definitivo.init do SysV. Em sistemas modernos, é o systemd.systemd é um gerenciador de sistema e serviços. Ele é o processo "pai" de todos os outros processos no sistema. Sua principal tarefa é orquestrar a inicialização dos serviços (daemons) necessários para o funcionamento do sistema, como rede, login, serviços de sistema, etc. O systemd é projetado para iniciar serviços em paralelo, o que acelera significativamente o tempo de boot em comparação com o SysVinit, que os iniciava sequencialmente.systemd trabalha com o conceito de "targets", que são análogos aos "runlevels" do SysVinit. Um target é um ponto de sincronização que agrupa um conjunto de serviços.systemd lê o target padrão (geralmente um link simbólico em /etc/systemd/system/default.target) para determinar o estado final que o sistema deve alcançar. Os targets mais comuns são multi-user.target (um sistema multiusuário com rede, mas sem interface gráfica) e graphical.target (que depende do multi-user.target e adiciona os serviços para a interface gráfica e a tela de login). Ao atingir o target, o sistema é considerado totalmente inicializado e pronto para uso.Enunciado:
1. Desabilite o serviço de gerenciamento de rede na inicialização do sistema, mostre que o serviço foi desabilitado, habilite o serviço e mostre que foi habilitado.
2. Procure no repositório de sua distribuição Linux o servidor Mysql, instale o pacote contendo o servidor Mysql.
3. Habilite o servidor Mysql para inicializar junto com o sistema operacional, reinicie o Linux, mostre que o servidor Mysql inicia junto com o sistema operacional.
4. Inicie o servidor Mysql, mostre que o servidor foi iniciado e pare o servidor Mysql.
5. Desinstale o servidor Mysql e mostre que o servidor foi desinstalado.
O comando disable apenas remove o link simbólico que faz o serviço iniciar no boot. Um administrador ou outro serviço ainda pode iniciá-lo manualmente. Para uma desativação mais forte, use mask.
sudo systemctl mask ssh.service
O comando mask cria um link simbólico de /etc/systemd/system/ssh.service para /dev/null. Isso torna impossível iniciar o serviço de qualquer forma, até que ele seja "desmascarado" com sudo systemctl unmask ssh.service. É uma medida de segurança útil para garantir que um serviço vulnerável ou indesejado nunca seja executado.
Enunciado:
1. Faça o download do pacote .deb do navegador google chrome (procure por “google chrome download” no google) e instale o navegador na sua distribuição.
2. Execute o navegador pela linha de comando e desinstale o navegador.
Enquanto apt é um gerenciador de alto nível que resolve dependências, dpkg é a ferramenta de baixo nível que de fato instala pacotes .deb. Vamos usá-lo para instalar o Google Chrome.
É muito comum que a instalação com dpkg -i falhe devido a dependências não satisfeitas. O dpkg não sabe como baixar outros pacotes. Quando isso acontece, o sistema de pacotes fica em um estado "quebrado".
O gerenciador de alto nível apt pode consertar isso. O comando a seguir instrui o apt a encontrar e instalar quaisquer dependências que estejam faltando para os pacotes já instalados (ou semi-instalados).
Após rodar este comando, a instalação do Chrome seria concluída com sucesso.
Enunciado: Explique a diferença entre um container e uma máquina virtual e aponte as vantagens e desvantagens de cada um.
A distinção fundamental entre Máquinas Virtuais (VMs) e Containers reside no nível de abstração que cada tecnologia aplica.
Uma VM emula uma máquina física completa. Um software chamado Hypervisor (Tipo 1, como VMware ESXi, roda direto no hardware; ou Tipo 2, como VirtualBox, roda sobre um SO existente) cria e gerencia ambientes de hardware virtualizados (vCPU, vRAM, vDisk). Dentro de cada VM, é necessário instalar um sistema operacional completo (Guest OS), com seu próprio Kernel, bibliotecas e, finalmente, a aplicação. Isso resulta em um isolamento extremamente forte, pois cada VM é uma entidade completamente separada, com seu próprio Kernel.
Estrutura da Stack: Infraestrutura Física → Hypervisor → [Guest OS + Bibliotecas + Aplicação]
Um container não emula hardware. Em vez disso, ele virtualiza o próprio sistema operacional. Todos os containers em um mesmo host compartilham o Kernel do sistema operacional hospedeiro. Um Container Engine (como o Docker) é responsável por criar ambientes de espaço de usuário isolados. Cada container empacota apenas a aplicação e suas dependências (bibliotecas e binários), mas não um Kernel inteiro. Esse compartilhamento do Kernel torna os containers incrivelmente leves e rápidos.
Estrutura da Stack: Infraestrutura Física → Host OS (com seu Kernel) → Container Engine → [Bibliotecas + Aplicação]
| Critério de Comparação | Máquina Virtual (VM) | Container |
|---|---|---|
| Nível de Abstração | Hardware | Sistema Operacional |
| Isolamento de Segurança | Forte (Kernel separado para cada VM) | Fraco (Kernel do Host é compartilhado, uma vulnerabilidade no Kernel pode afetar todos os containers) |
| Tamanho da Unidade | Grande (Gigabytes), pois inclui um SO completo. | Pequeno (Megabytes), pois inclui apenas a aplicação e suas dependências. |
| Tempo de Inicialização | Lento (Minutos), pois precisa bootar um SO inteiro. | Rápido (Segundos ou menos), pois inicia apenas um processo no SO existente. |
| Consumo de Recursos | Alto (RAM e CPU são pré-alocados e reservados). | Baixo (Recursos são compartilhados e usados sob demanda). |
| Portabilidade | Moderada (dependente da compatibilidade do Hypervisor). | Alta (pode rodar em qualquer sistema com um Container Engine compatível). |
| Caso de Uso Principal | Executar múltiplos sistemas operacionais diferentes em um único host; isolar ambientes multi-tenant; rodar aplicações legadas. | Arquitetura de microsserviços; pipelines de CI/CD; empacotar e distribuir aplicações de forma consistente entre ambientes. |
Enunciado: Escreva o arquivo test.py que exibe a mensagem “Teste” na tela e o arquivo test.sh que executa test.py e mostra a data e hora da execução.
Podemos tornar o script Python diretamente executável, sem precisar chamar python3 explicitamente. Isso é feito adicionando uma linha especial no topo do arquivo chamada "shebang".
Explicação: A linha #!/usr/bin/env python3 diz ao sistema operacional para usar o interpretador python3 (encontrado no ambiente do usuário) para executar este arquivo. Após dar permissão de execução (chmod +x), o arquivo se comporta como qualquer outro programa ou script.
Enunciado:
1. Escreva um Dockerfile que crie uma imagem do Ubuntu versão 18.04, atualize os repositórios do SO, instale o python3.10, copie os arquivos locais test.py e test.sh do Exercício 6 para a imagem e altere as permissões para que seja possível executar o script test.sh dentro da imagem.
2. Implemente o arquivo test.py para exibir a mensagem “PYTHON” na tela e o arquivo test.sh para exibir a mensagem “SHELL SCRIPT” e executar o arquivo test.py. Execute o container docker a partir da imagem criada e verifique as mensagens exibidas pelos scripts.
Ao executar docker build, todo o diretório atual (o "contexto de build") é enviado para o daemon do Docker. Se houver arquivos grandes e desnecessários (como logs, outros pacotes, etc.), isso pode tornar o build lento. Podemos evitar isso com um arquivo .dockerignore.
Agora, ao executar docker build, os arquivos e padrões listados em .dockerignore não serão enviados ao daemon, resultando em um build mais rápido e eficiente, especialmente em projetos grandes.