Servidor de Aplicações em Contêineres

De MediaWiki do Campus São José
Revisão de 17h08min de 21 de novembro de 2017 por Joao.ms (discussão | contribs) (ue)
Ir para navegação Ir para pesquisar

A estrutura

  • Máquina virtual (VMWare):
    • Memória RAM: 15672 MB, virtualizado;
    • CPU: Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz, 8 núcleos virtualizados;
    • Armazenamento: um disco virtual de 20 GB para o sistema operacional de gerência e um disco virtual de 200 GB montado em /var/lib/docker;
  • Sistema Operacional de gerência (instalado em máquina virtual VMWare): Container Linux by CoreOS 1520.8.0 (Ladybug);
    • Versão da distribuição: 1520.8.0;
    • Nome da versão da distribuição: Ladybug;
    • Nome da distribuição: Container Linux by CoreOS;
  • Contêiner Docker com sistema base Debian 8 (Jessie), dispondo das seguintes aplicações:
    • Quartus 13.0sp1 com Modelsim Altera 10.1d;
    • Quartus 16.0 com Modelsim Altera 10.4d;
    • MatLab 2015a;
    • Octave 4.2.1;
    • Omnet++ 5.0;
    • Gdrive;
  • Contêiner Docker com sistema base Debian 9 (Stretch).
    • Aluno responsável: Gustavo Paulo Medeiros da Silva;
    • Professor orientador: Ramon Mayor Martins;
    • Aplicações: Node.js, csdr;
    • Site: IFSC-SDR

O CoreOS

Logomarca do Container Linux by CoreOS

O CoreOS (Container Linux by CoreOS) é um sistema operacional de código aberto voltado à execução de contêineres. Seu objetivo é permitir a execução de aplicações em qualquer ambiente. Fornece ferramentas de gerência de contêineres como Docker e Rocket, que é feito pela mesma equipe que criou o Container Linux. Possui suporte ao Kubernetes, que é uma poderosa ferramenta de gerência de contêineres, baseada na experiência que a Google teve. O CoreOS também tem seu código no GitHub.

Instalação do Container Linux

Para a instalação do CoreOS, baixe a ISO da versão de produção do sistema através deste link. A versão de produção é a mais indicada para ambientes que necessitam de uma maior estabilidade no sistema operacional. Após baixada a ISO, em caso de instalação em uma máquina física, pode-se gravá-la em um pendrive usando o comando "dd", ou outro gravador de imagens em dispositivos de sua preferência, ou realizar o boot diretamente dela, em caso de máquina virtual. Em seguida, dê boot do sistema, que começará a ser carregado e irá concluir em uma tela com o login já feito. Digite sudo su para se tornar root. Neste momento, os sistema está apenas carregado em memória. Antes de instalá-lo, primeiramente a rede deve ser corretamente configurada, já que o script de instalação baixa uma imagem que é o sistema a ser gravado no disco rígido. É possível utilizar o comando "ifconfig", o comando "ip" ou o serviço "systemd-networkd" para a configuração da rede, além do comando "route" para definir o gateway. De modo que a configuração seja mais rápida, optar-se-á pela utilização do comando "ifconfig" para a configuração da rede, como mostrado no exemplo abaixo:

ifconfig eth0 191.36.8.33/27
route add default gw 191.36.8.62
echo "nameserver 8.8.8.8" > /etc/resolv.conf

No uso do comando ifconfig, a interface de rede eth0 foi definida com o endereço IP 191.36.8.33 com máscara de sub-rede 255.255.255.224 ou /27. No uso do comando route, foi definido como roteador principal o endereço IP 191.36.8.62.
No uso do comando echo, foi gravado no arquivo resolv.conf, localizado em /etc, o servidor para a busca de nomes.
Após a configuração de rede, instale o Container Linux utilizando o seguinte script presente em /bin, como no exemplo abaixo:

coreos-install -C stable -d /dev/sda

O script coreos-install está localizado em /bin e é um shell script. Ao utilizar o argumento -C e o parâmetro stable, definiu-se o canal de atualizações bem como o estágio de desenvolvimento da imagem que será baixada, verificada e gravada no HD. O argumento -d vem de device e especifica o dispositivo o qual a imagem baixada será gravada. A identificação do dispositivo pode variar de ambiente para ambiente.
Após isso, reinicie o sistema utilizando o comando reboot. O sistema será rapidamente desligado e ligado novamente, é importante ser rápido quando a tela do grub ↓

Coreos-grub.png

aparecer para que se edite um parâmetro de boot a fim de modificar a senha de usuário.

Coreos-grub2.png

Adicione no final da linha linux$suf $gptprio_kernel $gptprio_cmdline $linux_cmdline o parâmetro init=/bin/bash, como mostrado na imagem abaixo. Lembrando que a disposição do teclado está para inglês estadunidense.

Coreos-grub3.png

Após adicionar o parâmetro no final da linha, pressione a tecla "F10" para dar o boot, que concluir-se-á com uma tela parecida com a imagem abaixo.

Coreos-grub4.png

Digite o comando mount -o remount / a fim de dar permissão de escrita.

Coreos-grub5.png

Agora, mude a senha do usuário "core" utilizando o comando passwd, como mostrado na imagem abaixo:

Coreos-grub6.png

Reinicie o sistema e você já poderá logar com o usuário "core" e a senha que você definiu anteriormente. Para tornar-se root, digite sudo su após estar logado.

Configuração da Rede

A configuração da rede pode dar-se de duas formas, via SystemD ou via Cloud Config. Nesse primeiro momento, será explicada a configuração via SystemD. Para tanto, inicialmente criaremos um arquivo com a extensão .network em /etc/systemd/network.

vi /etc/systemd/network/0-eth0.network

E escreveremos no arquivo as configurações de rede, como no modelo abaixo:

[Match]
Name=eth0

[Network]
DNS=191.36.8.2
Address=191.36.8.33/27
Gateway=191.36.8.62

Agora basta reiniciar o serviço que gerencia a rede:

systemctl restart systemd-networkd

O Docker

Logomarca do Docker

O Container Linux by CoreOS já vem com o Docker. Digitando docker version, obtemos a seguinte saída:

docker version
Client:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.7.6
 Git commit:   a82d35e
 Built:        Tue Sep  5 20:35:08 2017
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.7.6
 Git commit:   a82d35e
 Built:        Tue Sep  5 20:35:08 2017
 OS/Arch:      linux/amd64

Baixando uma imagem base

Para baixar uma imagem de sistema operacional base para um contêiner, digite:

docker pull nome_imagem:tag

Por exemplo, para baixar uma imagem base Debian Stretch:

docker pull debian:stretch

As tags podem ser obtidas no Docker Hub.

Criando um contêiner

Para a criação de um contêiner, utiliza-se o comando docker com o parâmetro run. Observe o exemplo abaixo:

docker run -it debian:stretch

O comando acima já é suficiente para a criação de um contêiner. Caso a imagem especificada não tenha sido baixada anteriormente, o Docker baixa a imagem e logo em seguida cria o contêiner. É possível definir mais parâmetros:

localhost core # docker run ···

-it → assim que o contêiner for criado, entrega ao terminal atual um console tty interativo;
--name=nome_do_conteiner → define o nome do contêiner. Caso este parâmetro seja omitido, o Docker selecionará randomicamente um nome.
--net nome_da_rede → especifica o nome da rede. Caso este parâmetro seja omitido, o Docker associará o contêiner à rede padrão chamada "docker0", de nome "bridge".
--ip <endereço IP> → especifica um endereço IP fixo para o contêiner. Caso este parâmetro seja omitido, o Docker atribuirá um endereço IP seguindo uma sequência em ordem crescente. Salientando que na interface padrão "docker0" NÃO é possível escolher o endereço IP do contêiner, apenas em interfaces criadas pelo usuário, algo que será explicado mais adiante.
-p porta_do_host:porta_do_conteiner → associa uma porta do sistema operacional gerente a uma porta do contêiner. Apesar de prático, este parâmetro bagunça muito as regras do IPTables o que faz com que, ao possuir um grande número de contêineres, fique mais difícil de fazer algum ajuste.
-v /pasta/no/sistema:/pasta/no/conteiner → associa um diretório do sistema operacional gerente a um diretório dentro do contêiner. Também é possível criar volumes.
-h nome_de_host → define o nome de host (hostname) do contêiner.
--privileged → dá ao contêiner acesso a todo o hardware do sistema operacional gerente. É recomendado o uso apenas em casos que realmente necessitem de tal recurso.
--cap-add=habilidade → dá ao contêiner habilidades de gerência como se fosse o sistema operacional gerente. Por exemplo, em caso de --cap-add=NETWORK, permite o contêiner modificar a rede do sistema operacional gerente. Este parâmetro deve ser usado muito cautelosamente.
-d → executa o contêiner em segundo plano.
--dns=endereço_IP → define um servidor DNS para o contêiner.
--dns-search → define o domínio de busca do servidor DNS.
--mac-address=" " → define o endereço MAC do dispositivo de rede do contêiner.
--restart=" " ' → quando definido --restart=always, sempre que o contêiner for interrompido, o Docker reiniciar-lo-á. Caso --restart=on-failure, quando contêiner for finalizado com saída diferente de 0, o Docker reiniciar-lo-á. Caso --restart=on-failure:n, o qual n é um número natural, após n vezes que o contêiner falhar e for reiniciado, o Docker interromperá os reinícios automáticos.
--device=/dev/dispositivo → permite o contêiner utilizar um determinado dispositivo.
-rm → cria um contêiner temporário, assim que o contêiner for parado, ele será automaticamente excluído.

Abaixo, segue um exemplo da criação de um contêiner:

docker run -d --name=Portainer -h portainer -v /var/run/docker.sock:/var/run/docker.sock -v /home/portainer:/data portainer/portainer

O exemplo acima cria um contêiner denominado Portainer, que tem dois pontos de montagem (-v), o primeiro montando o arquvio /var/run/docker.sock do sistema de gerência no arquivo /var/run/docker.sock dentro do contêiner. O segundo ponto de montagem, conecta o diretório /home/portainer do sistema de gerência com o diretório /data do contêiner. Por fim, como último argumento de linha de comando, é dado o nome da imagem, nesse caso portainer/portainer. Com o parâmetro -h,foi definido o nome de host. Note que foi omitida a tag da imagem, quando isso ocorre, é dada a tag latest, que corresponde à última versão da imagem (portainer/portainer:latest).


Outro exemplo:

docker run -it -d --name=servidor-web --net faixa10 --ip 10.10.10.110 -h servidor-web --restart=on-failure:10 --dns=191.36.8.2 --dns-search=sj.ifsc.edu.br --device=/dev/kvm:/dev/kvm --privileged -v /home/servidor-web:/var/www/html debian:jessie

No exemplo acima:

  • É criado um contêiner
    • -it → com tty interativo
    • -d → o contêiner, assim que criado, ficará em execução em segundo plano.
    • --name=servidor-web → o nome do contêiner é servidor-web
    • --net faixa10 → ele está associado à ponte denominada faixa10
    • --ip 10.10.10.110 → o endereço IP do contêiner é 10.10.10.110
    • -h servidor-web → o nome de host do contêiner é servidor-web.
    • --restart=on-failure:10 → o contêiner será reiniciado quando falhar, no entanto, caso ocorram 10 falhas consecutivas, o reinício automático é interrompido.
    • --dns=191.36.8.2 → o servidor de nomes 191.36.8.2 é usado. O endereço pode ser encontrado dentro do arquivo /etc/resolv.conf dentro do contêiner.
    • --dns-search=sj.ifsc.edu.br → o domínio de busca é sj.ifsc.edu.br.
    • --device=/dev/kvm:/dev/kvm → o contêiner terá acesso ao dispositivo de virtualização kvm.
    • --privileged → o contêiner terá permissões para acessar todos os dispositivos devidamente reconhecidos do sistema de gerência.
    • -v /home/servidor-web:/var/www/html → o diretório /home/servidor do sistema de gerência é associado com o diretório /var/www/html do contêiner.
    • debian:jessie → a imagem base utilizada é o Debian na versão Jessie.

Configuração da rede

O Docker trabalha com dispositivos de rede virtuais do tipo ponte, nulo e até mesmo a própria rede do sistema operacional de gerência. Ao ser instalado, ele cria automaticamente a ponte denominada docker0, que dentro do Docker recebe o nome de bridge.
É possível também criar interfaces de rede virtuais através do Docker com o comando docker network create. Por exemplo:

docker network create --driver bridge --subnet=10.10.10.0/24 --gateway=10.10.10.10 --opt "com.docker.network.bridge.name"="faixa10" faixa10

O comando acima manda o Docker criar uma ponte de nome "faixa10" e identificação de "faixa10" no sistema. Note que a ponte "docker0" tem nome de "bridge" no Docker, então, o que é visto no comando ifconfig ou ip é docker0, porém, ao usar o comando docker network ls, que lista as pontes usáveis para o Docker, o nome que aparece não é docker0, mas sim bridge. O último argumento da linha de comando é justamente o nome que aparece no sistema. Afim de tornar o uso da ponte mais prático, recomenda-se utilizar o mesmo nome para ambas identificações. Em resumo:

  • docker network create
    • --driver bridge → a interface de rede é do tipo ponte.
    • --subnet=10.10.10.0/24 → define o tamanho da sub-rede, que neste caso é 255.255.255.0, indo de 10.10.10.1 à 10.10.10.254 na faixa de IPs válidos nesta sub-rede.
    • --gateway=10.10.10.10 → define o endereço IP da ponte. A ponte é o roteador dos contêineres que serão associados à ela.
    • --opt "com.docker.network.bridge.name"="faixa10" → define o nome da ponte dentro do Docker, ou seja, o nome que aparece no comando docker network ls.
    • faixa10 → define o nome da ponte no sistema de gerência, ou seja, o nome que aparece no resultado dos comandos ifconfig ou ip -4 a.

Saída do comando docker network ls:

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3a2ca6e077dd        DMZ191              bridge              local               
e6105c781cdf        bridge              bridge              local               
44fcf67f5607        faixa10             bridge              local               
0b11f4caff4c        host                host                local               
88354106cf7f        none                null                local

Saída do comando ip -4 a:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
3: DMZ191: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    inet 191.36.8.33/27 scope global DMZ191
       valid_lft forever preferred_lft forever
4: faixa10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    inet 10.10.10.10/24 scope global faixa10
       valid_lft forever preferred_lft forever
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever

Nos comandos acima, é possível ver duas pontes criadas pelo usuário, a faixa10 e a DMZ191. A ponte DMZ191, permite criar contêineres com endereço IP da faixa do sistema de gerência. A ponte DMZ191 foi criada utilizando o comando abaixo:

docker network create --driver bridge --subnet=191.36.8.32/27 --gateway=191.36.8.33 --opt "com.docker.network.bridge.name"="DMZ191" DMZ191

No comando acima temos:

  • docker network create
    • --driver bridge → interface de rede do tipo ponte;
    • --subnet=191.36.8.32/27 → define o tamanho da sub-rede, que neste caso é 255.255.255.224, indo de 191.36.8.33 à 191.36.8.62 na faixa de IPs válidos nesta sub-rede.
    • --gateway=191.36.8.33 → define o endereço IP da ponte que, nesse caso, é o endereço IP do servidor em si.
    • --opt "com.docker.network.bridge.name"="DMZ191" → define o nome da ponte dentro do Docker, ou seja, o nome que aparece no comando docker network ls.
    • DMZ191 → define o nome da ponte no sistema de gerência, ou seja, o nome que aparece no resultado dos comandos ifconfig ou ip -4 a.

Após criada a ponte com o IP da faixa do host, basta adicionar a interface física do host na ponte através do comando abaixo:

brctl addif DMZ191 nome_da_interface

Por exemplo:

brctl addif DMZ191 ens33

E a saída do comando brctl show deve ficar assim:

brctl show
bridge name	bridge id		STP enabled	interfaces
DMZ191		8000.000c297ca02d	no		ens33

Caso o sistema de gerência esteja sendo executado em uma máquina virtual, o virtualizador DEVE pemitir que a interface entre em MODO PROMÍSCUO. No virtualizador que bloqueia o modo promíscuo, os pacotes são derrubados pois é impedido que dois endereços MAC (o da ponte, que contém o endereço IP, e o da interface, que faz a conexão externa) solicitem o mesmo pacote.

O exemplo abaixo cria um contêiner com endereço IP da mesma faixa do servidor o qual o contêiner ficará hospedado:

docker run -it -d --name=conteiner-dmz --net DMZ191 --ip 191.36.8.50 -h conteiner-dmz debian:jessie

No exemplo acima temos um contêiner de nome conteiner-dmz, que está associado à ponte DMZ191, possui endereço IP 191.36.8.150, nome de host conteiner-dmz, e usa a imagem do debian:jessie como base.
No entanto, se o sistema operacional de gerência for reiniciado, todas as configurações de ponte, como associação da interface de rede física na ponte que permite criar contêineres na faixa de endereços IP do host. Para tornar esse processo automatizado, basta criar um serviço do SystemD em /etc/systemd/system, que, neste exemplo, será chamado de ponte-roteador-DMZ1.service:

vi /etc/systemd/system/ponte-roteador-DMZ191.service

E adicionar o seguinte conteúdo ao arquivo:

[Unit]
Description=Faz as configuracoes de rede compartilhada DMZ191
After=systemd-networkd.service docker.service
Requires=systemd-networkd.service

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 10
ExecStart=/sbin/brctl addif DMZ191 ens33 ; /bin/route add default gw 191.36.8.62

[Install]
WantedBy=multi-user.target

No exemplo de serviço acima, são executados três comandos:

  • sleep 10 → realiza uma contagem de 10 segundos;
  • brctl addif DMZ191 ens33 → Adiciona a interface ens33 na ponte DMZ191;
  • route add default gw 191.36.8.62 → define o endereço IP 191.36.8.62 como roteador;

Para que esse serviço seja iniciado automaticamente durante o início do sistema operacional, digite:

systemctl enable ponte-roteador-DMZ191.service

É possível verificar se o início automático do serviço foi ativado com o seguinte comando:

systemctl status ponte-roteador-DMZ191

O comando acima retornará uma saída semelhante à saída parcial abaixo:

● ponte-roteador-DMZ191.service - Faz as configuracoes de rede compartilhada DMZ191
   Loaded: loaded (/etc/systemd/system/ponte-roteador-DMZ191.service; enabled; vendor preset: disabled)

A bandeira "enabled" presente na segunda linha da saída do comando "systemctl status ponte-roteador-DMZ191" indica que o início automático do serviço foi ativado.

Arquivo com as regras do IPTables

Para gerenciar as regras no IPTables, é possível utilizar um aquivo contendo essas regras. É possível usar o modelo abaixo para começar um arquivo de regras do IPTables:

# Generated by iptables-save v1.4.21 on Mon Jul 24 10:08:01 2017
*mangle
:PREROUTING ACCEPT [598596665:677097829571]
:INPUT ACCEPT [174957:66070167]
:FORWARD ACCEPT [599651413:677110534191]
:OUTPUT ACCEPT [17908:3643447]
:POSTROUTING ACCEPT [599669321:677114177638]
COMMIT
# Completed on Mon Jul 24 10:08:01 2017
# Generated by iptables-save v1.4.21 on Mon Jul 24 10:08:01 2017
*nat
:PREROUTING ACCEPT [477675:28199468]
:INPUT ACCEPT [673:193661]
:OUTPUT ACCEPT [375:26498]
:POSTROUTING ACCEPT [10042:607734]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER

################## Redirecionamentos de porta ####################



##################################################################

-A POSTROUTING -s 10.10.10.0/24 ! -o faixa10 -j MASQUERADE
-A POSTROUTING -s 192.168.16.0/24 ! -o faixa192 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

COMMIT
# Completed on Mon Jul 24 10:08:01 2017
# Generated by iptables-save v1.4.21 on Mon Jul 24 10:08:01 2017
*filter
:INPUT ACCEPT [176787:66261039]
:FORWARD ACCEPT [603170623:680968865198]
:OUTPUT ACCEPT [18726:3730253]
:DOCKER - [0:0]
:DOCKER-ISOLATION - [0:0]

COMMIT
# Completed on Mon Jul 24 10:08:01 2017

Salvando o modelo acima em um arquivo, basta adicionar os redirecionamentos, como explicado logo abaixo.
Para aplicar as novas regras, basta utilizar o comando iptables-restore:

iptables-restore arquivo_com_as_regras

Redirecionamento de Portas

O arquivo regras-iptables presente no diretório /home, neste caso, refere-se a um caso particular deste servidor, ou seja, para outros casos, este arquivo deve ser criado manualmente pelo usuário, podendo ficar em qualquer lugar do sistema de arquivos acessível pelo IPTables.
Para fazer o redirecionamento de uma porta do contêiner para o sistema de gerência e vice-versa, basta adicionar uma regra no arquivo regras-iptables presente no diretório /home. Abaixo, um exemplo:

→ Redirecionando apenas uma porta:

-A PREROUTING -d 191.36.8.33/32 -p tcp -m tcp --dport PORTA_DO_IP_EXTERNO -j DNAT --to-destination IP_DO_CONTÊINER:PORTA_DO_CONTÊINER

-A PREROUTING -d 191.36.8.33/32 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.10.10.200:80

No exemplo acima, a porta externa 443 foi redirecionada para a porta 80 do contêiner de endereço IP 10.10.10.200.

→ Redirecionando uma faixa de portas:

-A PREROUTING -d 191.36.8.33/32 -p tcp -m tcp --dport FAIXA_DE_PORTAS_EXTERNAS -j DNAT --to-destination IP_DO_CONTÊINER:FAIXA_DE_PORTAS_DO_CONTÊINER

-A PREROUTING -d 191.36.8.33/32 -p tcp -m tcp --dport 10000:20000 -j DNAT --to-destination 10.10.10.150:10000-20000

No exemplo acima, a faixa de portas externa 10000:20000 foi redirecionada para a faixa de portas 10000:20000 do contêiner de endereço IP 10.10.10.150.
A faixa de portas externas deve ter a mesma quantidade de portas que a faixa de portas do contêiner e as portas devem ser correspondentes, ou seja, as faixas devem ter as mesmas portas..
O argumento -p bagunça demasiadamente as regras do IPTables, criando três regras para cada redirecionamento.
Para aplicar as novas regras, basta utilizar o comando iptables-restore:

iptables-restore arquivo_com_as_regras

Automatização da aplicação das regras do IPTables via arquivo

Para automatizar o processo de aplicação das regras do IPtables é possível criar um serviço do SystemD para isso. Por exemplo, basta criar um arquivo em /etc/systemd/system chamado 'iptables-restore.service, como no modelo abaixo:

[Unit]
Description=Aplica regras no firewall
After=multi-user.target

[Service]
Type=simple
ExecStartPre=/usr/bin/sleep 15
ExecStart=/sbin/iptables-restore /var/lib/docker/home-conteiner/quartus-matlab/regras-iptables

[Install]
WantedBy=custom.target

O nome do arquivo .service é de livre escolha do usuário desde que não contenha caracteres inválidos.
Após criado, basta ativar o serviço:

systemctl enable iptables-restore

Depois de ativado, o serviço iniciar-se-á no boot do sistema operacional. Para iniciar o serviço imediatamente:

systemctl start iptables-restore

Aplicando as regras do IPTables via arquivo em intervalos de tempo

Para aplicar as regras do IPTables em intervalos de tempo, basta usar o temporizador do SystemD para isso. Para tanto, deve ser criado um aquivo .timer contendo o mesmo nome do arquivo .service, que neste caso ficaria iptables-restore.timer, como mostrado no exemplo abaixo:

vi /etc/systemd/system/iptables-restore.timer

E adicionando um conteúdo, como no modelo abaixo:

[Unit]
Description=Executar o serviço itables-restore.service a cada 1 miuto

[Timer]
OnBootSec=20
OnUnitActiveSec=1min

[Install]
WantedBy=multi-user.target

O temporizador definido acima ativa o serviço iptables-restore.service a cada 1 minuto, reaplicando as regras do IPTables definidas em um arquivo.
Após criado, basta ativá-lo:

systemctl enable iptables-restore.timer

Após ativo, o temporizador iniciar-se-á em cada boot do sistema operacional. Para iniciar o temporizador imediatamente:

systemctl start iptables-restore.timer

Scripts para criação de usuários

Devido à falta de informações suficientes providas pelo LDAP, não foi possível usar os usuários de rede dos alunos. De maneira a agilizar a criação e remoção de contas, foram criados scripts para realizar essas funções.
O script abaixo verifica o nome completo do aluno e retorna o seu nome de usuário. Caso retorne mais de um nome de usuário ou não retorne nenhum nome de usuário, o mesmo deve ter seu nome retirado da lista e ser criado manualmente:
Atualização: O script de criação de usuários já verifica quais os alunos que não retornaram nome de usuário e também aqueles que retornaram mais de um nome de usuário, ignorando-os e criando apenas os usuários dos alunos que retornaram apenas um nome de usuário.
Abaixo, a sintaxe de utilização do script de verificação:

root@quartus-matlab:/# ./ler-lista lista

No comando acima, o script obtém o nome completo dos usuário a partir do arquivo "lista". A lista do com o nome completo dos usuários tem o formato CSV (comma separated value), como no exemplo abaixo:

MATRÍCULA,NOME,SOBRENOME
123456789-0,MARIO,DE ANDRADE
246801357-9,JOAO,VITOR DOS PASSOS

Abaixo, o script de verificação:

#!/bin/bash

FILE=$1
while IFS=, read -r matricula nome sobrenome
do
  echo "Usuario $nome $sobrenome de matricula $matricula."
  ldap=$(ldapsearch -h 191.36.8.12 -b "dc=cefetsc,dc=edu,dc=br" -x "(&(cn=$nome)(sn=$sobrenome))"  | sed -n 's/dn: uid=\(.*\),ou=Alunos,dc=cefetsc,dc=edu,dc=br/\1/p')
  contagem=$(echo "$ldap" |wc -l)
  
  if [ -z "${ldap}" ]; then
  echo "O usário não foi encontrado através do cirtério de busca utilizado."
  echo " "

  elif (( "$contagem" > 1 )); then
  echo "Retornou mais de um nome de usuário."

  else

  echo "$ldap"
  echo " "

  fi
done < $1

Abaixo, o script para a criação de usuários, que ignora usuários já existentes no sistema, alunos que não retornaram nome e usuário e alunos que retornaram mais de um nome de usuário:

root@quartus-matlab:/# ./criar-usuarios lista curso

Abaixo, o script de criação dos usuários dos alunos via lista:

#!/bin/bash

FILE=$1
curso=$2
verificar=$(cut -d: -f1 /etc/passwd)

rm -r /var/log/criar-usuarios
mkdir /var/log/criar-usuarios

while IFS=, read -r matricula nome sobrenome
do
  echo "Usuario $nome $sobrenome de matricula $matricula"
  ldap=$(ldapsearch -h 191.36.8.12 -b "dc=cefetsc,dc=edu,dc=br" -x "(&(cn=$nome)(sn=$sobrenome))"  | grep uid: |cut -f2 -d " ")
  usuariolocal=$(echo "$verificar" |grep -w "^$ldap")
  contagem=$(echo "$ldap" |wc -l)

  if [ "$usuariolocal" = "$ldap" ]; then

    echo "O usuário $usuariolocal já existe no sistema!."
    echo ""
    echo "Nome completo: $nome $sobrenome" >> /var/log/criar-usuarios/existentes.log
    echo "Matrícula: $matricula" >> /var/log/criar-usuarios/existentes.log
    echo "Nome de usuário: $ldap" >> /var/log/criar-usuarios/existentes.log
    echo "" >> /var/log/criar-usuarios/existentes.log

  elif [ -z "${ldap}" ]; then
    echo "O usário não foi encontrado através do cirtério de busca utilizado."
    echo " "
    echo "Nome: $nome $sobrenome" >> /var/log/criar-usuarios/erro.log
    echo "Matrícula: $matricula" >>  /var/log/criar-usuarios/erro.log
    echo "" >> /var/log/criar-usuarios/erro.log

  elif (( "$contagem" > 1 )); then
    echo "Retornou mais de um nome de usuário."
    echo " "
    echo "Nome: $nome $sobrenome" >> /var/log/criar-usuarios/erro.log
    echo "Matrícula: $matricula" >>  /var/log/criar-usuarios/erro.log
    echo "" >> /var/log/criar-usuarios/erro.log

  elif [ -z "${1}" ]; then
    echo "Não foi provida nenhuma informação!"
    echo "Sintaxe de uso: criar-usuarios lista curso"

  else

    echo "Criando usuario $ldap para o aluno $nome $sobrenome do curso $curso."
    useradd -m -d /home/alunos/$ldap -s /bin/bash  -c "$nome $sobrenome,$curso,$matricula" $ldap

    echo "Usando a matricula $matricula como senha temporária do usuario $ldap."
    echo "$ldap:$matricula" |chpasswd
  
    echo "Obrigando usuário $ldap a mudar senha no proximo login."
    chage -d 0 $ldap

    echo "Adicionando usuário $ldap ao grupo alunos."
    addgroup $ldap alunos
  
    echo "Mudando a permissão da pasta /home/alunos/$ldap."
    chmod -R 700 /home/alunos/$ldap

    echo "Mudando grupo dono da pasta /home/alunos/$ldap."
    chown -R $ldap:alunos /home/alunos/$ldap

    echo "Dando permissão de leitura aos usuários do grupo professores."
    setfacl -m g:professores:r /home/alunos/$ldap
 
    echo "Conta $ldap do usuário $nome $sobrenome criada"
    echo " "
    echo "Nome: $nome $sobrenome" >> /var/log/criar-usuarios/novos.log
    echo "Matrícula: $matricula" >> /var/log/criar-usuarios/novos.log
    echo "Nome de usuário: $ldap" >> /var/log/criar-usuarios/novos.log
    echo "" >> /var/log/criar-usuarios/novos.log    

  fi
done < $1

O script acima gera três tipos de log:

  • /var/log/criar-usuarios/erro.log → contém os usuários que não retornaram nome de usuário no LDAP ou retonaram múltiplos nomes de usuário;
  • /var/log/criar-usuarios/existentes.log → contém os usuários da lista informada que já estão cadastrados;
  • /var/log/criar-usuarios/novos.log → contém os nomes de usuários criados na última vez o script foi executado.

A cada execução, todos os logs na pasta "/var/log/criar-usuários" são apagados. Há também um script para a criação manual de usuários de alunos, caso seja encontrado mais de um nome de usuário para o mesmo aluno ou caso não seja encontrado nenhum nome de usuário.
A sintaxe de utilização é:

root@quartus-matlab:/# ./criar-usuario-aluno "nome_de_usuario" "NOME COMPLETO" "matrícula" "curso"
root@quartus-matlab:/# ./criar-usuario-aluno "maria.fs" "MARIA FONSECA DE SOUZA" "246801357-9" "Engenharia de Telecomunicações"

O código do script é:

#!/bin/bash

nomedeusuario=$1
nomecompleto=$2
matricula=$3
curso=$4

  echo "Criando usuario $nomedeusuario para o aluno $nomecompleto"
  useradd -m -d /home/alunos/$nomedeusuario -s /bin/bash  -c "$nomecompleto,$curso,$matricula" $nomedeusuario

  echo "Usando a matricula $matricula como senha do usuario $nomedeusuario."
  echo "$nomedeusuario:$matricula" |chpasswd
  
  echo "Obrigando usuario a mudar senha no proximo login."
  chage -d 0 $nomedeusuario

  echo "Adicionando usuario $nomedeusuario ao grupo alunos"
  addgroup $nomedeusuario alunos

  echo "Mudando grupo dono da pasta /home/alunos/$nomedeusuario."
  chown -R $nomedeusuario:alunos /home/alunos/$nomedeusuario
  
  echo "Mudando a permissao da pasta /home/alunos/$nomedeusuario"
  chmod -R 700 /home/alunos/$nomedeusuario
  
  echo "Conta $nomedeusuario do usuario $nomecompleto criada"
  echo " "

E há um script para a criação de usuários para os professores, usando a seguinte sintaxe:

root@quartus-matlab:/# ./criar-usuario-professor "usuario" "Nome Completo" "senhatemporaria"

#!/bin/bash

nomedeusuario=$1
nomecompleto=$2
senha=$3

  echo "Criando usuário $nomedeusuario para o professor $nomecompleto."
  useradd -m -d /home/professores/$nomedeusuario -s /bin/bash  -c "$nomecompleto" $nomedeusuario

  echo "Usando $senha como senha temporária do usuario $nomedeusuario."
  echo "$nomedeusuario:$senha" |chpasswd
  
  echo "Obrigando usuário a mudar senha no próximo login."
  chage -d 0 $nomedeusuario

  echo "Adicionando usuário $nomedeusuario ao grupo professores."
  addgroup $nomedeusuario professores
  
  echo "Mudando a permissão da pasta /home/professores/$nomedeusuario."
  chmod -R 700 /home/professores/$nomedeusuario
  
  echo "Conta $nomedeusuario do usuário $nomecompleto criada."
  echo " "

Uso do Gdrive

O Gdrive é uma ferramenta de gerência, em modo texto, de arquivos e diretórios no Google Drive. Abaixo, serão listados comandos úteis para o uso da ferramenta.


  • Uso

$ gdrive list → Lista os arquivos e pastas do diretório raiz. Na primeira vez que for executado, informará um link para que você acesse pelo navegador. Acessando o link, você receberá um código, copie e cole esse código no terminal ao lado de "Enter verification code:". Após isso você poderá usar a aplicação para manipular os arquivos da sua conta do Google Drive.

$ gdrive upload arquivo → envia um arquivo para o diretório raiz do Google Drive.
$ gdrive upload --parent ID_DA_PASTA arquivo → enviar um arquivo para uma pasta específica.
$ gdrive upload -r /caminho/da/pasta/no/pc → envia uma pasta com todo seu contéudo para o diretório raiz do sistema.
$ gdrive upload --parent ID_DA_PASTA -r /caminho/da/pasta/no/pc → envia uma pasta com todo seu conteúdo para uma pasta específica.
O ID da pasta pode ser obtido pela URL do Google Drive: https://drive.google.com/drive/u/0/folders/ID_DA_PASTA ;

$ gdrive download ID_DO_ARQUIVO → baixa um arquivo.

Programando Localmente a FPGA via JTAG na Nuvem

Executar os comandos abaixo na maquina local

/opt/altera/13.0sp1/nios2eds/nios2_command_shell.sh 
jtagd
jtagconfig --enableremote senha
jtagconfig

Verificar se a porta 6XXXX está em uso:

ssh  usuario@191.36.8.33 netstat -lnt | grep 127.0.0.1:60[0-9][0-9][0-9]

Estabelecer um túnel ssh reverso fazendo um bind entre 6XXXX não utilizada e a porta da jtag local

ssh -XC -R 6XXXX:localhost:1309 usuario@191.36.8.33

Para o número da porta a sugestão é utilizar o ID do usuário.

No Quartus é necessário abrir o programador [Tools > Programmer] em seguida [Edit > Hardware Setup] na aba [JTAG Settings] [Add Server] preencher os campos:

Server name: 127.0.0.1:6XXXX
Server password: senha

JTAG settings QUARTUS13.png

Em seguida é necessário selecionar a JTAG na aba [Hardware Settings]

Hardware settings QUARTUS13.png

Programação e visualização remota do kit FPGA

Provisoriamente estou experimentando disponibilizar um kit Mercúrio IV conectado a minha maquina. Segue o procedimento para acessar o kit através do quartus e visualizar o resultado.

Programação

Estabelecer um túnel ssh reverso fazendo um bind entre 60002 e a porta da jtag local

ssh -XC -R 60002:localhost:1309 <seu_usuário_na_nuvem>@191.36.8.33

No Quartus é necessário abrir o programador [Tools > Programmer] em seguida [Edit > Hardware Setup] na aba [JTAG Settings] [Add Server] preencher os campos:

Server name: 127.0.0.1:60002
Server password: lab_DLP_remoto2017

JTAG settings QUARTUS13.png

Em seguida é necessário selecionar a JTAG na aba [Hardware Settings]

Hardware settings QUARTUS13.png

Visualização

Para visualizar o resultado da programação do kit, está disponível uma câmera de vídeo que monitora on-line um kit. Para acessá-la de dentro da rede do IFSC, basta digitar a url da câmera:

 http://172.18.116.32/axis-cgi/mjpg/video.cgi

Remotamente de fora do IFSC, use o vlc na nuvem.

 vlc http://172.18.116.32/axis-cgi/mjpg/video.cgi

Eventualmente você pode não acesso aos kits, pois estão conectados a maquina do prof Moecke.

Hoje a porta de conexão é 60001, e a senha é senha.  --Marcos Moecke 14h12min de 30 de outubro de 2017 (-02)

Estão disponíveis 2 kits, mas o video só mostra um deles.

Endereços IPs internos em uso no servidor

Esta seção desta página desinga-se a uso interno dos professores e administradores do servidor de aplicações.
A fim te ter-se uma melhor organização, recomendo a utilização a faixa de endereços 10.10.10.100 à 10.10.10.254 para a criação de contêineres, alocando, se possível, endereços em ordem crescente.
Para o redirecionamento de portas, consulte o item 1.2.5 (Redirecionamento de Portas).
Abaixo, estão listadas as pontes de rede presentes no Docker bem como os nomes dos contêineres associados às mesmas, sendo primeiramente referido o nome da ponte no sistema operacional de gerência e entre parênteses o nome que aparece no Docker (que é o mesmo que aparece no Portainer):

docker0 (bridge) → não é possível escolher o endereço IP nessa ponte

Endereço IP da interface: 172.17.0.1
Máscara de sub-rede:' 255.255.0.0 = 16
IP de início: 172.17.0.1
Último endereço IP: 172.17.0.254
Endereço de broadcast: 172.17.0.255
Gateway (automático): 172.17.0.1

DMZ191 (DMZ191) → não roteável devido ao virtualizador

Endereço IP da interface: 191.36.8.33
Máscara de sub-rede:' 255.255.255.224 = 27
IP de início: 191.36.8.33
Último endereço IP: 191.36.8.62
Endereço de broadcast: 191.36.8.63
Gateway (automático): 191.36.8.33

faixa10 (faixa10)

Endereço IP da interface: 10.10.10.10
Máscara de sub-rede: 255.255.255.0 = 24
IP de início: 10.10.10.1
Último endereço IP: 10.10.10.254
Endereço de broadcast: 10.10.10.255
Gateway (automático): 10.10.10.10

  • 10.10.10.88 → Estacao_pluviometrica
  • 10.10.10.100 → quartus-matlab
  • 10.10.10.101 → hackrf
  • 10.10.10.102 → quartus-matlab2
  • 10.10.10.103 → Portainer
  • 10.10.10.104 → quartus-matlab3
  • 10.10.10.105 →
  • 10.10.10.106 →
  • 10.10.10.107 →
  • 10.10.10.108 →
  • 10.10.10.109 →
  • 10.10.10.110 →
  • 10.10.10.111 →
  • 10.10.10.112 →
  • 10.10.10.113 →
  • 10.10.10.114 →
  • 10.10.10.115 →
  • 10.10.10.116 →
  • 10.10.10.117 →
  • 10.10.10.118 →
  • 10.10.10.119 →
  • 10.10.10.120 →
  • 10.10.10.121 →
  • 10.10.10.122 →
  • 10.10.10.123 →
  • 10.10.10.124 →
  • 10.10.10.125 →
  • 10.10.10.126 →
  • 10.10.10.127 →
  • 10.10.10.128 →
  • 10.10.10.129 →
  • 10.10.10.130 →
  • 10.10.10.131 →
  • 10.10.10.132 →
  • 10.10.10.133 →
  • 10.10.10.134 →
  • 10.10.10.135 →
  • 10.10.10.136 →
  • 10.10.10.137 →
  • 10.10.10.138 →
  • 10.10.10.139 →
  • 10.10.10.140 →
  • 10.10.10.141 →
  • 10.10.10.142 →
  • 10.10.10.143 →
  • 10.10.10.144 →
  • 10.10.10.145 →
  • 10.10.10.146 →
  • 10.10.10.147 →
  • 10.10.10.148 →
  • 10.10.10.149 →
  • 10.10.10.150 →
  • 10.10.10.151 →
  • 10.10.10.152 →
  • 10.10.10.153 →
  • 10.10.10.154 →
  • 10.10.10.155 →
  • 10.10.10.156 →
  • 10.10.10.157 →
  • 10.10.10.158 →
  • 10.10.10.159 →
  • 10.10.10.160 →
  • 10.10.10.161 →
  • 10.10.10.162 →
  • 10.10.10.163 →
  • 10.10.10.164 →
  • 10.10.10.165 →
  • 10.10.10.166 →
  • 10.10.10.167 →
  • 10.10.10.168 →
  • 10.10.10.169 →
  • 10.10.10.170 →
  • 10.10.10.171 →
  • 10.10.10.172 →
  • 10.10.10.173 →
  • 10.10.10.174 →
  • 10.10.10.175 →
  • 10.10.10.176 →
  • 10.10.10.177 →
  • 10.10.10.178 →
  • 10.10.10.179 →
  • 10.10.10.180 →
  • 10.10.10.181 →
  • 10.10.10.182 →
  • 10.10.10.183 →
  • 10.10.10.184 →
  • 10.10.10.185 →
  • 10.10.10.186 →
  • 10.10.10.187 →
  • 10.10.10.188 →
  • 10.10.10.189 →
  • 10.10.10.190 →
  • 10.10.10.191 →
  • 10.10.10.192 →
  • 10.10.10.193 →
  • 10.10.10.194 →
  • 10.10.10.195 →
  • 10.10.10.196 →
  • 10.10.10.197 →
  • 10.10.10.198 →
  • 10.10.10.199 →
  • 10.10.10.200 →
  • 10.10.10.201 →
  • 10.10.10.202 →
  • 10.10.10.203 →
  • 10.10.10.204 →
  • 10.10.10.205 →
  • 10.10.10.206 →
  • 10.10.10.207 →
  • 10.10.10.208 →
  • 10.10.10.209 →
  • 10.10.10.210 →
  • 10.10.10.211 →
  • 10.10.10.212 →
  • 10.10.10.213 →
  • 10.10.10.214 →
  • 10.10.10.215 →
  • 10.10.10.216 →
  • 10.10.10.217 →
  • 10.10.10.218 →
  • 10.10.10.219 →
  • 10.10.10.220 →
  • 10.10.10.221 →
  • 10.10.10.222 →
  • 10.10.10.223 →
  • 10.10.10.224 →
  • 10.10.10.225 →
  • 10.10.10.226 →
  • 10.10.10.227 →
  • 10.10.10.228 →
  • 10.10.10.229 →
  • 10.10.10.230 →
  • 10.10.10.231 →
  • 10.10.10.232 →
  • 10.10.10.233 →
  • 10.10.10.234 →
  • 10.10.10.235 →
  • 10.10.10.236 →
  • 10.10.10.237 →
  • 10.10.10.238 →
  • 10.10.10.239 →
  • 10.10.10.240 →
  • 10.10.10.241 →
  • 10.10.10.242 →
  • 10.10.10.243 →
  • 10.10.10.244 →
  • 10.10.10.245 →
  • 10.10.10.246 →
  • 10.10.10.247 →
  • 10.10.10.248 →
  • 10.10.10.249 →
  • 10.10.10.250 →
  • 10.10.10.251 →
  • 10.10.10.252 →
  • 10.10.10.253 →
  • 10.10.10.254 →