Docker + Cluster DRBD + SQL Server – Database as a Service utilizando volumes replicados

Este artigo abordará como configurar dois nós em um Cluster Ativo/Passivo através da ferramenta DRBD Manage.

Entretanto, teremos um volume DRBD em modo primário/primário em ambos os hosts.

Deste modo, todos os dados gravados no nó Ativo serão replicados para o nó Passivo, dados esses que irão compor um volume de dados que poderá ser utilizado por um ou mais containers que serão provisionados através da tecnologia Docker.

O container que iremos provisionar utilizará a imagem oficial da Microsoft para disponibilizar o serviço de Banco de Dados Microsoft SQL Server.

Para a criação do volume de dados replicado no Docker utilizaremos o plugin drbdmanage.

Realizaremos operações no container em execução no primeiro nó do cluster e em seguida, pararemos a execução do container no primeiro nó e inicializaremos ele no segundo nó, permitindo demonstrar que os dados não só irão persistir após a finalização do container como será replicado para o segundo nó do Cluster.

Um pouco de história

Docker

Docker é um projeto open source que permite automatizar o desenvolvimento, distribuição e execução de aplicações em Linux containers.

Um Linux container é um método para executar isoladamente um ou mais binários em um único host (hospedeiro), sem a necessidade de um hipervisor (que demandaria a instalação de um sistema operacional convidado).

projeto Docker pode ser instalado e configurado com facilidade não apenas em sistemas GNU/Linux, mas também em sistemas como Windows e Mac OS/X.

Diferentemente de uma tecnologia de virtualização como Linux KVM, VMWare vSphere, Xen e Hyper-V que demandam a instalação de um sistema operacional convidado, compartilham apenas o Kernel do host no qual estão sendo executados, onde binários e bibliotecas dentro de cada container são a priori restritos ao ambiente de execução de cada container.

Deste modo, cada aplicação/serviço em execução dentro de um container poderá ter seus binários e bibliotecas atualizados sem a preocupação de prejudicar outros containers.

Docker é baseado na tecnologia LXC (Linux Containers), mas temos outras tecnologias de containers como o Jails de sistemas BSD, assim como, temos tecnologias muito mais simples para criação de sandbox (que é base para a idéia empregada em Linux Containers), por exemplo, chroot, onde é possível isolar serviços como o Web Service Apache e o DNS Service Bind.

O Docker foi desenvolvido inicialmente como uma API de alto nível que complementaria o LXC , mas a partir da versão 0.9 introduziu sua própria biblioteca, desenvolvida utlizando a linguagem GO.

Através do Docker é possível executar aplicações diversas como, por exemplo, servidores de banco de dados, web application service, servidores de banco de dados (alvo deste artigo).

Supondo que temos um host com Debian, é possível executarmos containers que disponibilize um sistema/distribuição Ubuntu, Suse ou CentOS, pois toda a árvore de filesystem contendo binários, arquivos de configuração, bibliotecas (dinâmicas e estáticas) particulares para cada distribuição estarão isoladas em cada container, onde o único elemento utilizado em comum por cada container é o kernel.

DRBD

DRBD é um software compatível com o Sistema Operacional Linux desenvolvido pela empresa Linbit que permite estabelecer um sistema de armazenamento distribuído e replicado.

Ele foi implementado como módulo do Kernel Linux, bem como, oferece diversas ferramentas e scripts para gerenciamento dos volumes replicados.

DRBD é  tradicionalmente utilizado em Cluster de Computador com finalidade de complementar sistemas de Alta Disponibilidade. Entretanto, desde a versão 9 ele também vem sendo utilizado para criação de grande estruturas para armazenamento de dados baseados no conceito de SDS (Software Defined Storage), bem como, vem evoluindo com grande foco na integração com tecnologias de Cloud Computing.

É possível utilizar dois modos de operação: Ativo/Passivo (modo que iremos utilizar neste artigo) e o modo Ativo/Ativo, que permite que tanto o primeiro nó do Cluster como o segundo possar ler e gravar dados no volume replicado. Entretanto, o uso do modo Ativo/Ativo demanda tecnologias complementares para gerenciamento do acesso concorrente aos dados, neste caso, sistemas de arquivos para clusters, como por exemplo, GFS2 e OCFS, bem como, é possível utilizar uma variação da tecnologia LVM, o Cluster LVM (CLVM), que permite alocar volumes lógicos de dados (que representam partições de disco) de maneira simultânea em ambos os nós do Cluster.

Mão na massa

Atualmente o Docker tem suporte a plugins, o que permite estender suas funcionalidades, e no caso deste artigo, iremos utilizar um plugin para volume de dados, o que permitirá especificamente armazenar o conteúdo de volumes Docker sob um backend storage DRBD.

A vantagem é que todas as operações que um ou mais containers realizar sob seus volumes de dados, não serão simplesmente gravadas em um filesystem local, mas gravados em um dispositivo virtual de blocos replicados gerenciado pelo módulo de kernel do DRBD, replicando os dados para um ou mais hosts (nós) do nosso Cluster.

A abordagem deste artigo será simplemente permitir que quando um container for ser executado em dos nós do Cluster, ele terá acesso aos dados mais recentes existentes no volume, pois este volume é proveniente de uma estrutura de replicação estabelecida pelo DRBD.

Em outros artigos estaremos explorando ambientes mais complexos com o DRBD atuando em um modo Ativo/Ativo.

Para criação de nosso container que proverá o serviço de banco de dados baseado no Microsoft SQL Server, estaremos utilizando uma imagem de container Docker disponibilizada pela Microsoft denominada microsoft/mssql-server-linux

Para este artigo utilizaremos o Docker Hub para realizar o pull da imagem acima mencionada.

A seguir temos os requisitos mínimos para poder utilizar a imagem de container Docker disponibilizada pela Microsoft:

  • Docker Engine 1.8 ou superior
  • Mínimo de 4 GB de espaço em disco
  • Mínimo de 4 GB de RAM (apesar que para a finalidade de testes, uma máquina virtual 2.5 GB atenderá o mínimo de 2 GB exigido pelo SQL Server sobre container).
  • Configurar uma senha forte para a conta de administrador do serviço do SQL Server, senha essa contendo pelo menos 8 caracteres utilizando letras maiúsculas e minúsculas, números e/ou símbolos não alfanuméricos.

Para este artigo utilizamos a distribuição CentOS Linux 7 (7.4.1708), e a instalação do Docker pode ser realizada de maneira simples através da etapas abaixo descritas.

Todas as etapas abaixo serão realizadas em ambos os nós do nosso Cluster, que para este artigo os nós serão referenciados como:

– containernode01  – Endereço IP: 192.168.0.161
– containernode02 – Endereço IP: 192.168.0.162

Para atividades de configuração especificas em um determinado nó do Cluster, estaremos informando previamente.

Portanto, em ambos os nós:

– Instale os pacotes que serão dependências no restante do processo de instalação do Docker Engine:

sudo yum install yum-utils

Neste caso, o pacote yum-utils permitirá utilizarmos a ferramenta yum-config-manager para adicionar o repositório Docker Comunity Edition.

– Adicione o repositório ao sistema:

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

– Instale o pacote do Docker Engine:

sudo yum install  -y docker-ce

– Execute os daemons do Docker e ative o serviço na inicialização do sistema:

sudo systemctl start docker
sudo systemctl enable docker

– Adicione o atual usuário logado no grupo de usuário Docker. Essa ação fará com que não seja necessária a utilização do comando sudo para utilização docker.

sudo gpasswd -a "${USER}" docker

– Reinicie o sistema para testar a inicialização do serviço do Docker:

sudo reboot

– Para testar o serviço Docker Engine, execute uma consulta simples através do docker cliente, por exemplo, se existe algum container em execução:

docker ps

Certamente a listagem estará vazia, o que indica que o docker client conseguiu estabelecer a conexão com o serviço Docker Engine.

– Instale o pacote para adicionar e configurar o repositório EPEL, pois a versão 9 do DRBD que será utilizada neste artigo, encontra-se neste repositório:

rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

– Instale os pacotes do DRBD:

yum install drbd90-utils kmod-drbd90

– Ative o carregamento do módulo do kernel durante o boot:

echo drbd > /etc/modules-load.d/drbd.conf

– Instale os pacotes a seguir pois serão necessários para podermos realizar o download e compilar a ferramenta drbdmanage. Em seguida, descompacte o arquivo e proceda com as etapas de build e instalação:

yum install wget pygobject2 -y
wget http://www.linbit.com/downloads/drbdmanage/drbdmanage-0.99.14.tar.gz
tar -xvzf drbdmanage-0.99.14.tar.gz -C /opt/
cd /opt/drbdmanage-0.99.14/
./setup.py build
./setup.py install

– Realize um teste com a ferramenta drbdmanage. O retorno deverá ser a palavra “pong”, indicando que a ferramenta está funcional:

drbdmanange ping

A grande vantagem da ferramenta drbdmanage é que ela facilita o gerenciamento de Clusters utilizando a tecnologia DRBD. Através dela podemos gerenciar dispositivos de bloco baseados em LVM ou ZFS, onde o mesmo estejam sob um dispositivos de replicação DRBD.

Para este artigo teremos em cada nó do Cluster dois discos, sendo um para uso exclusivo do sistema operacional e demais serviços e um dele para criação do volume de dados replicados pelo DRBD, e que será utilizado para o armazenamento de dados de forma persistente em nossos containers.

Por padrão o drbdmanage possui uma referência a um volume group chamado drbdpool, referência essa existente no arquivo /etc/drbdmanaged.cfg

Podemos manter esse nome padrão ou altera-lo no arquivo de configuração anteriormente citado. Para este artigo iremos utilizar o nome, containersData, portanto, execute o comando abaixo para realizar a alteração:

sed -r ‘s/^#(.*drbdctrl-vg.*)$/\1/’ -i /etc/drbdmanaged.cfg
sed ‘s/drbdpool/containersData\n/g’ -i /etc/drbdmanaged.cfg 

Para este artigo, vamos supor que a segunda unidade de disco seja /dev/sdb, portanto, criaremos um volume group chamado containersData nesta unidade de disco.

– Crie uma partição primária na segunda unidade de disco e em seguida crie um volume físico e depois o volume lógico chamado containersData

pvcreate /dev/sdb1
vgcreate containersData /dev/sdb1

No host containernode01 (192.168.0.161) e containernode02 (192.168.0.162) criaremos pares de chaves, para permitir que a partir de um host possamos acessar o outro via SSH, sem a necessidade de informarmos senha e vice-versa. Esta etapa é importante, pois iremos utilizar a ferramenta drbdmanage para provisionar nossa infraestrutura de Cluster, etapa essa que pode ser simplificada devido a autenticação entre hosts poderem ser realizadas por meio de chaves RSA.

– No host containernode01 (192.168.0.161) execute:

ssh-keygen -t rsa
scp .ssh/id_rsa.pub [email protected]:/root/.

– No host containernode02 (192.168.0.162) execute:

ssh-keygen -t rsa
scp .ssh/id_rsa.pub [email protected]:/root/.
cat id_rsa.pub >> .ssh/authorized_keys

– No host containernode01 (192.168.0.161) execute:

cat id_rsa.pub >> .ssh/authorized_keys

– No hosts containernode01 e containernode02 edite o arquivo /etc/hosts, deixando o final dele da seguinte forma para não dependermos de uma infraestrutura DNS para a resolução.

192.168.0.161 containernode01 containernode01.lab.local
192.168.0.162 containernode02 containernode02.lab.local

– No host containernode01 (192.168.0.161) execute:

ssh 192.168.0.162 hostname
ssh containernode02 hostname

Em ambos os comandos deverá ser exibido o hostname do host 192.168.0.162. Esta etapa é importante, para testarmos a comunicação entre ambos hosts via SSH sem uso autenticação baseada em senha, pois conforme exposto, isto permitirá que a ferramenta drbdmanage estabeleça a conexão via SSH entre os hosts e procedimentos, como por exemplo, criação de volumes lógicos sob o dispositivo de bloco replicado DRBD seja realizado durante a criação de volumes docker.

– No host containernode02 (192.168.0.162) execute:

ssh 192.168.0.161 hostname
ssh containernode01 hostname

Os testes de conexão via SSH sem senha em um primeiro momento, permitirá que os hosts que estão sofrendo conexão sejam inseridos na lista de hosts conhecidos em  (/root/.ssh/know_hosts).

Os volumes de dados que criaremos a partir do docker utilizará um plugin chamado drbdmanage, onde todas as chamadas realizadas a esse plugin serão direcionadas ao serviço docker-drbdmanage-plugin, e o mesmo utilizará a atual estrutura de cluster provisionada, permitindo transparência durante a criação de volumes no docker, criação essa que utilizará do mecanismo de replicação do DRBD.

Provisionando o Cluster

– No host containernode01, execute:

drbdmanage init 192.168.0.161

Confirme a operação informando “yes”.

– Verifique que dois volumes DRBD foram criados:

drbdadm status

– Verifique o status do Cluster que até o momento possui um nó:

drbdmanage list-nodes 

– No host containernode01, execute o comando abaixo para associar o segundo nó ao Cluster:

drbdmanage add-node containernode02.lab.local 192.168.0.162

Confirme a operação informando “yes”.

Esta etapa será executada baseando-se no uso do SSH, portanto, a criação dos pares de chaves que realizamos anteriormente (para permitir autenticação sem depender de senha) é fundamental para o funcionamento desta etapa.

– No host c0ntainernode01, verifique o status do Cluster que agora possuirá dois nós:

drbdmanage list-nodes

– No host containernode02, execute o comando abaixo para verificar o status da replicação:

drbdadm status

Observe que o Status indicado é Secundário para o containernode02 e Primário para o containernode01, bem como, os dois volumes criados estão em estado UpToDate entre os volumes 0 e 1 de ambos os nós do Cluster.

Instalando o serviço DRBD Manage Docker Volume Plugin

Em ambos os nós do Cluster:

– Realize o download o arquivo e proceda com a: descompactação, build e instalação dos arquivos e ativação do serviço:

wget http://www.linbit.com/downloads/connectors/drbdmanage-docker-volume-0.7.tar.gz
tar -xvzf drbdmanage-docker-volume-0.7.tar.gz -C /opt/
cd /opt/drbdmanage-docker-volume-0.7/
make
make install
wget https://raw.githubusercontent.com/LINBIT/drbdmanage-docker-volume/master/systemd/docker-drbdmanage-plugin.service
mv docker-drbdmanage-plugin.service /etc/systemd/system/multi-user.target.wants/.
systemctl daemon-reload
systemctl start docker-drbdmanage-plugin
systemctl status docker-drbdmanage-plugin

No último comando é necessário que o status do serviços esteja em running para podermos proceder com as próximas etapas.

Criando um volume de dados no Docker para persistência de dados.

Neste etapa utilizaremos o plugin/driver drbdmanage para criar nosso volume de dados, para permitir a persistência de dados após a finalização do container.

Todas as etapas a seguir serão realizadas no primeiro nó do Cluster (containernode01) execute:

docker volume create -d drbdmanage –name=volumeDatabase  –opt fs=ext4 –opt size=400
docker volume ls
lvs

Os dois últimos comandos poderão ser executados também no segundo do Cluster (containernode02), para elucidar que as operações de gravação no primeiro nó, são replicadas para o segundo nó, bem como, o volume criado no docker automaticamente teve um volume lógico LVM criado para armazenar as informações.

Lembrando que todas as operações de leitura e escrita no container são direcionadas ao driver drbdmanage, que faz com que as informações sejam armazenadas em um volume lógico LVM, volume este que está sob um device virtual (que representa um dispositivo de bloco replicado do DRBD, que por si só replicada as informações para o segundo nó do Cluster).

Criando um container para execução do Microsoft SQL Server.

Vamos realizar o pull da imagem de container do SQL Server e utiliza-la para criar e executar o container que proverá um serviço de banco de dados da Microsoft sob o host atual.

Lembrando que, a configuração a seguir utilizará a persistência de dados, pois ao finalizar o container, por padrão os dados serão perdidos, e em muitas situações a perda dos dados gerados durante a execução do container não é aceitável.

Entretanto, tudo dependerá da finalidade do container, afinal, podemos executar um container, gerar informações nele, mas tais informações poderem ser descartadas ou as mesmas já terem sido armazenadas em outro host ou container que utiliza persistência de dados.

– No host containernode01 (192.168.0.161) execute:

docker run –name SQLServer01 -e ‘ACCEPT_EULA=Y’ \
-e ‘SA_PASSWORD=#AdminSQLServer2017’  \
-p 1433:1433  -v volumeDatabase:/var/opt/mssql  \
-d microsoft/mssql-server-linux

Aguarde o pull da imagem para que o container seja criado e entre em execução

O comando acima pode ser entendido da seguinte maneira:

run – esta opção realiza três ações: pull da imagem, criação do container e em seguida execução do container criado.

-e – permite a criação de variáveis de ambiente sob o ambiente de execução do container. No caso acima, foram criadas duas variáveis de ambiente: ACCEPT_EULA recebendo o valor Y e SA_PASSWORD recebendo o valor #AdminSQLServer2017 (que será a senha da conta System Administrator do SQL Server). Deste modo, durante a execução do binário existente na imagem que sofreu o pull, este binário irá verificar a existências destas variáveis e utilizar os valores setados nelas.
A variável ACCEPT_EULA permite que definir se os termos da licença de uso serão aceitos.

-p – permite realizar o mapeamento de portas. No caso acima, qualquer conexão a porta 1433 (  valor numérico a esquerda dos :  ) será redirecionada para a porta 1433 (  valor numérico a direita dos :  ) em listening no container.

-d – executará o container em modo background.

-v – anexará um volume externo a um volume dentro do container, no caso, teremos o mapeamento do volume criado e gerenciado pelo serviço DRBD (volumeDatabase) existente no host físico para o diretório /var/opt/mssql existente no container.

Portanto, a ação de criação, exclusão e alteração ocorrida em /var/opt/mssql dentro do container também ocorrerá em no volume volumeDatabase, que por sua vez realizará o armazenamento no host físico onde o container é executado e os blocos de dados serão replicado para o segundo nó do Cluster.

–name – Define o nome que o container terá ao ser criado.

Em seguida verifique se o container está em execução:

docker ps

Caso o container não seja listado, então execute novamente o comando docker run sem a opção -d

Para podermos visualizar no console qualquer mensagem de erro durante a inicialização dos binários do container.
Um erro muito comum é a falta de memória no host, lembrando que a recomendação mínima são 4 GB.

Outra opção muito importante para verificar a inicialização de serviços/binários dentro de um container é a opção logs, portanto, você pode verificar da seguinte maneira:

docker logs SQLServer01

Verificada a existência de algum erro (por exemplo, quantidade de memória insuficiente), abra outro terminal e pare o container com o comando:

docker stop SQLServer01

Para executar novamente o container, basta executar:

docker start SQLServer01

Verifique novamente se o container está em execução:

docker ps

Inspecione as propriedades do volume que criamos anteriormente. Esta etapa permite verificar por exemplo, onde nosso volume está montado atualmente, bem como, verificar que o mesmo trata-se de um volume de dados replicado via DRBD:

docker volume inspect volumeDatabase

No ambiente em que estamos utilizando, as seguintes informações foram expostas:

“Driver”: “drbdmanage”,
“Labels”: {},
“Mountpoint”: “/run/docker/drbdmanage/mnt/volumeDatabase”,
“Name”: “volumeDatabase”,
“Options”: {
“fs”: “ext4”,
“size”: “400”
},
“Scope”: “local”

Execute o comando mount para confirmar que o volume está sob um device de replicação em bloco DRBD:

mount | grep volumeDatabase

A indicação do device /dev/drbdXXX indica que o volume está sob DRBD, onde XXX indica o valor atribuído no momento para o nome do dispositivo DRBD.

Podemos verificar que durante o carregamento do serviço o Microsoft SQL Server dentro do container, diversos arquivos, incluindo os datafiles foram criados, simplemente listando os arquivos do ponto de montagem verificado anteriormente.

Para listar os datafiles do serviço do SQL Server, execute:

ls /var/run/docker/drbdmanage/mnt/volumeDatabase/

Com o container em execução iremos estabelecer uma sessão de usuário com o serviço em execução sob o Container.

Dentro das das vantagens clássicas de container temos isolamento, portabilidade e flexibilidade, e graças a isso podemos não apenas executar binários e  bibliotecas existentes em uma imagem na forma de um container que atuará como serviço, mas também podemos simplesmente realizar a chamada a outros binários existentes no container já em execução, por exemplo, um binário que represente uma ferramenta de linha de comando que faz parte da solução empacotada dentro da imagem.

Iremos iniciar o binário bastante conhecido por DBAs que trabalham com SQL Server, o sqlcmd para estabelecermos uma sessão de usuário com o serviço do SQL Server.

docker exec -it SQLServer01 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P#AdminSQLServer2017

A opção exec realiza a chamada a binários existentes dentro de um container em execução, ou seja, sem precisar criar um novo container apenas para executar um binário já existente na imagem que foi utilizada de base para a criação do container anterior.

Já as opções -it permitem que durante a execução do binário sqlcmd seja possível estabelecer a interação entre entre o shell e o binário em execução no momento.

Após a execução do binário sqlcmd será exibido o prompt

1>

Execute a instrução SQL select a seguir acompanhada da instrução GO:

SELECT Name from sys.Databases;

GO

Serão exibidos os databases padrão do SQL Server, no caso:

  • master
  • tempdb
  • model
  • msdb

Realizaremos a seguir algumas operações simples em SQL:

  • Criação de um database;
  • Abertura do database;
  • Criação de uma tabela;
  • Inserção de registros nesta tabela;
  • Consulta de registros;
create database empresa;
go
use empresa;
go
create table cliente (codigo integer, nome varchar(80), primary key(codigo));
go
insert into cliente values (1,”Linus Torvalds”);
go
insert into cliente values (2,”Dennis Ritchie”);
go
select * from cliente;
go
exit

Com a sessão finalizada com a instrução exit, iremos parar o container e inicia-lo novamente para comprovar que a persistência de dados está sendo realizada corretamente.

docker stop SQLServer01 

Verifique se o container não encontra-se mais em execução:

docker ps

Inicie o container novamente e verifique que o binário do serviço do SQL Server em execução sob o container irá obter acesso aos datafiles:

docker start SQLServer01

Execute o binário do cliente sqlcmd novamente:

docker exec -it SQLServer01 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P#AdminSQLServer2017

Liste os databases existentes:

SELECT Name from sys.Databases;
go
quit

Verificando a replicação de dados para o segundo nó do Cluster

Iremos parar o container no primeiro nó do Cluster (containernode01):

docker stop SQLServer01 

Verifique também que ao finalizar a execução do Container, o volume é desmontado, verificando o atributo MountPoint que antes referenciava /run/docker/drbdmanage/mnt/volumeDatabase e agora referencia somente /

docker volume inspect volumeDatabase

Acesse o segundo nó do Cluster (containerhost02), e crie o container utilizando o comando a seguir:

docker run –name SQLServer01 -e ‘ACCEPT_EULA=Y’ \
-e ‘SA_PASSWORD=#AdminSQLServer2017’  \
-p 1433:1433  -v volumeDatabase:/var/opt/mssql  \
-d microsoft/mssql-server-linux

Aguarde o pull da imagem para que o container seja criado e entre em execução.

Execute o binário do cliente sqlcmd novamente:

docker exec -it SQLServer01 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P#AdminSQLServer2017

Liste os databases existentes:

SELECT Name from sys.Databases;
go
quit

O último select comprova que todos os database do SQL Server, inclusive o que database que criamos (empresa) foi replicado para o segundo nó do Cluster.

Esta abordagem permite definir um host de containers que atuará em modo stand by, permitindo que na ocorrência de falhas do primeiro nó, o segundo nó inicie os containers e os mesmo acesse a réplica realizada dos volumes.

Conforme pode ser verificado, com a replicação de dados garantimos a alta disponibilidade de dados persistentes para containers, bem como, com o uso do plugin e da ferramenta drbdmanage, podemos rapidamente não só provisionar um Cluster, mas realizar a criação de volumes no Docker com grande facilidade.

Waldemar Dibiazi Junior

Mais artigos deste autor »

Analista de Infraestrutura de Redes da Prorede Telecom - Ribeirão Preto - SP, trabalhou em dezenas de projetos de virtualização, reestruturação, implantação, bem como, projetos envolvendo clusters fail over, Segregação de Redes, VPNs, Load Balance, File Servers sob Clusters, Monitoramento de Infraestrutura e Nuvens Privadas sob Amazon AWS e Openstack.

Engenheiro de Computação, Pós Graduação em Banco de Dados, MBA em Gestão de Infraestrutura como Serviço, certificado Red Hat RHCSA, RHCE e RHCSA-OSP, estando entre os 20 primeiros certificados da América da Latina na plataforma Openstack da Red Hat.


1 Comentários

Deixe seu comentário

Seu endereço de e-mail não será publicado. Campos com * são obrigatórios!