One place for hosting & domains

      Otimizar

      Como otimizar consultas do MySQL com o cache do ProxySQL no Ubuntu 16.04


      O autor selecionou a Free Software Foundation para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O ProxySQL é um servidor proxy com reconhecimento de SQL que pode ser posicionado entre seu aplicativo e seu banco de dados. Ele oferece muitos recursos, como o de balancear carga entre vários servidores de MySQL e servir como uma camada de cache para consultas. Este tutorial irá se concentrar no recurso de cache do ProxySQL e como ele pode otimizar as consultas para o seu banco de dados do MySQL.

      O cache do MySQL ocorre quando o resultado de uma consulta é armazenado para que, quando essa consulta for repetida, o resultado possa ser retornado sem a necessidade de classificar o banco de dados. Isso pode aumentar significativamente a velocidade das consultas comuns. Em muitos métodos de cache, porém, os desenvolvedores precisam modificar o código do seu aplicativo, o que poderia introduzir um bug na base de códigos. Para evitar essa prática propensa a erros, o ProxySQL permite que você configure o cache transparente.

      No cache transparente, apenas os administradores do banco de dados precisam alterar a configuração do ProxySQL para habilitar o cache para as consultas mais comuns. Tais alterações podem ser feitas através da interface de administrador do ProxySQL. Tudo o que o desenvolvedor precisa fazer é conectar-se ao proxy que reconhece o protocolo. O proxy decidirá se a consulta pode ser atendida a partir do cache sem chegar ao servidor de back-end.

      Neste tutorial, você usará o ProxySQL para configurar o cache transparente de um servidor MySQL no Ubuntu 16.04. Em seguida, você testará seu desempenho usando o mysqlslap – com e sem o cache, no intuito de demonstrar o efeito do cache e quanto tempo ele pode poupar na execução de várias consultas semelhantes.

      Pré-requisitos

      Antes de iniciar este guia, você precisará do seguinte:

      Passo 1 — Instalando e configurando o servidor MySQL

      Primeiro, você instalará o servidor MySQL e o configurará para ser usado pelo ProxySQL como um servidor de back-end para atender consultas de clientes.

      No Ubuntu 16.04, o mysql-server pode ser instalado usando este comando:

      • sudo apt-get install mysql-server

      Pressione Y para confirmar a instalação.

      Em seguida, você será solicitado a digitar sua senha de usuário root do MySQL. Digite uma senha forte e salve-a para usar mais tarde.

      Agora que você tem seu servidor MySQL pronto, irá configurá-lo para que o ProxySQL funcione corretamente. Você precisa adicionar um usuário monitor para o ProxySQL monitorar o servidor MySQL, uma vez que o ProxySQL escuta o servidor de back-end através do protocolo da SQL, em vez de usar uma conexão TCP ou pedidos pelo método GET do HTTP – para garantir que o back-end esteja funcionando. O monitor usará uma conexão SQL fictícia para determinar se o servidor está ativo ou não.

      Primeiro, faça login no shell do MySQL:

      O parâmetro -uroot, conecta você através do usuário root do MySQL e o -p solicita a senha do usuário root. Esse usuário root é diferente do usuário root do seu servidor e a senha é a que você digitou quando instalou o pacote mysql-server.

      Digite a senha do root e pressione ENTER.

      Agora, você criará dois usuários, um chamado monitor para o ProxySQL e outro que você usará para executar consultas de clientes e conceder-lhes os privilégios corretos. Este tutorial nomeará esse usuário como sammy.

      Crie o usuário monitor:

      • CREATE USER 'monitor'@'%' IDENTIFIED BY 'monitor_password';

      A consulta CREATE USER é usada para criar um novo usuário que pode se conectar a partir de IPs específicos. Usar % denota que o usuário pode se conectar a partir de qualquer endereço IP. IDENTIFIED BY define a senha para o novo usuário; digite qualquer senha que quiser, mas certifique-se de lembrá-la para uso posterior.

      Com o usuário monitor criado, crie o usuário sammy:

      • CREATE USER 'sammy'@'%' IDENTIFIED BY 'sammy_password';

      Em seguida, conceda privilégios aos seus novos usuários. Execute o seguinte comando para configurar o monitor:

      • GRANT SELECT ON sys.* TO 'monitor'@'%';

      A consulta GRANT é usada para dar privilégios aos usuários. Aqui, você concedeu privilégios somente de SELECT em todas as tabelas no banco de dados sys para o usuário monitor; ele precisa apenas desse privilégio para escutar o servidor de back-end.

      Agora, conceda ao usuário sammy todos os privilégios em relação a todos os bancos de dados:

      • GRANT ALL PRIVILEGES on *.* TO 'sammy'@'%';

      Isso permitirá que o sammy faça as consultas necessárias para testar seu banco de dados mais tarde.

      Aplique as alterações de privilégios, executando o seguinte:

      Por fim, saia do shell do mysql:

      Agora, você instalou o mysql-server e criou um usuário para ser usado pelo ProxySQL para monitorar seu servidor MySQL e outro para executar consultas de clientes. Em seguida, você instalará e configurará o ProxySQL.

      Passo 2 — Instalando e configurando o servidor ProxySQL

      Agora, você pode instalar o servidor ProxySQL, que será usado como uma camada de cache para as suas consultas. Uma camada de cache existe como uma parada entre os servidores do seu aplicativo e os servidores de back-end do banco de dados; ela é usada para se conectar ao banco de dados e salvar os resultados de algumas consultas em sua memória para acesso rápido mais tarde.

      A página de lançamentos do ProxySQL no Github oferece arquivos de instalação para distribuições comuns do Linux. Para este tutorial, você usará o wget para baixar o arquivo de instalação do ProxySQL versão 2.0.4 do, Debian:

      • wget https://github.com/sysown/proxysql/releases/download/v2.0.4/proxysql_2.0.4-ubuntu16_amd64.deb

      Em seguida, instale o pacote usando o dpkg:

      • sudo dpkg -i proxysql_2.0.4-ubuntu16_amd64.deb

      Assim que estiver instalado, inicie o ProxySQL com este comando:

      • sudo systemctl start proxysql

      Verifique se o ProxySQL iniciou corretamente com este comando:

      • sudo systemctl status proxysql

      Você receberá um resultado semelhante a este:

      Output

      root@ubuntu-s-1vcpu-2gb-sgp1-01:~# systemctl status proxysql ● proxysql.service - LSB: High Performance Advanced Proxy for MySQL Loaded: loaded (/etc/init.d/proxysql; bad; vendor preset: enabled) Active: active (exited) since Wed 2019-06-12 21:32:50 UTC; 6 months 7 days ago Docs: man:systemd-sysv-generator(8) Tasks: 0 Memory: 0B CPU: 0

      Agora, é hora de conectar o seu servidor ProxySQL ao servidor MySQL. Para tanto, utilize a interface administrativa SQL do ProxySQL, a qual, por padrão, escuta a porta 6032 no localhost e tem admin como seu nome de usuário e senha.

      Conecte-se à interface executando o seguinte:

      • mysql -uadmin -p -h 127.0.0.1 -P6032

      Digite admin quando for solicitado a inserir uma senha.

      -uadmin define o nome de usuário como admin e o sinalizador -h especifica o host como localhost. A porta é 6032, especificada com o sinalizador -P.

      Aqui, você teve que especificar claramente o host e a porta porque, por padrão, o cliente MySQL se conecta usando um arquivo de socket local e a porta 3306.

      Agora que você se conectou ao shell mysql como admin, configure o usuário monitor para que o ProxySQL possa usá-lo. Primeiro, use consultas SQL padrão para definir os valores de duas variáveis globais:

      • UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
      • UPDATE global_variables SET variable_value='monitor_password' WHERE variable_name='mysql-monitor_password';

      A variável mysql-monitor_username especifica o nome de usuário do MySQL que será usado para verificar se o servidor de back-end está ativo ou não. A variável mysql-monitor_password aponta para a senha que será usada ao se conectar ao servidor de back-end. Use a senha que criou para o nome de usuário monitor.

      Toda vez que fizer uma alteração na interface administrativa do ProxySQL, precisará usar o comando LOAD (carregar) correto para aplicar as alterações na instância do ProxySQL em execução. Você alterou variáveis globais do MySQL,assim, carregue-as no RUNTIME para aplicar as alterações:

      • LOAD MYSQL VARIABLES TO RUNTIME;

      Em seguida, SAVE (salve) as alterações no banco de dados em disco para manter as alterações entre as reinicializações. O ProxySQL usa seu próprio banco de dados do SQLite local para armazenar suas próprias tabelas e variáveis:

      • SAVE MYSQL VARIABLES TO DISK;

      Agora, você dirá ao ProxySQL sobre o servidor de back-end. A tabela mysql_servers detém as informações sobre cada servidor de back-end ao qual o ProxySQL pode conectar-se e onde pode executar consultas. Assim, adicione um novo registro usando uma instrução SQL padrão INSERT, com os seguintes valores para hostgroup_id, hostname e port:

      • INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (1, '127.0.0.1', 3306);

      Para aplicar as alterações, execute LOAD e SAVE novamente:

      • LOAD MYSQL SERVERS TO RUNTIME;
      • SAVE MYSQL SERVERS TO DISK;

      Por fim, você dirá ao ProxySQL qual usuário se conectará ao servidor de back-end; defina o sammy como o usuário e substitua sammy_password pela senha que criou anteriormente:

      • INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('sammy', 'sammy_password', 1);

      A tabela mysql_users contém informações sobre os usuários usados para se conectar aos servidores de back-end; você especificou o username (nome de usuário), password (senha) e default_hostgroup (grupo de host padrão).

      LOAD e SAVE as alterações:

      • LOAD MYSQL USERS TO RUNTIME;
      • SAVE MYSQL USERS TO DISK;

      Então, saia do shell do mysql:

      Para testar se você consegue se conectar ao seu servidor de back-end usando o ProxySQL, execute a seguinte consulta teste:

      • mysql -usammy -h127.0.0.1 -p -P6033 -e "SELECT @@HOSTNAME as hostname"

      Nesse comando, você usou o sinalizador -e para executar uma consulta e fechar a conexão. A consulta imprime o nome do host do servidor de back-end.

      Nota: por padrão, o ProxySQL usa a porta 6033 para escutar as conexões de entrada.

      O resultado ficará parecido com este, sendo o your_hostname substituído pelo seu nome de host:

      Output

      +----------------------------+ | hostname | +----------------------------+ | your_hostname | +----------------------------+

      Para aprender mais sobre a configuração do ProxySQL, consulte o Passo 3 sobre Como usar o ProxySQL como um balanceador de carga para o MySQL no Ubuntu 16.04.

      Até aqui, você configurou o ProxySQL para usar seu servidor MySQL como um back-end e se conectou ao back-end usando o ProxySQL. Agora,você está pronto para usar o mysqlslap para comparar o desempenho das consultas sem cache.

      Passo 3 — Testando o uso do mysqlslap sem o cache

      Neste passo, você fará download de um banco de dados de teste para que possa executar consultas nele com o mysqlslap, no intuito de testar a latência sem o armazenamento em cache, definindo um parâmetro de comparação para a velocidade das suas consultas. Você também irá explorar como o ProxySQL mantém os registros das consultas na tabela stats_mysql_query_digest.

      O mysqlslap é um cliente de emulação de carga que é usado como uma ferramenta de teste de carga para o MySQL. Ele pode testar um servidor MySQL com consultas geradas automaticamente ou com algumas consultas personalizadas, executadas em um banco de dados. Ele vem instalado no pacote do cliente MySQL, de modo que não é necessário instalá-lo; em vez disso, você irá baixar um banco de dados apenas para fins de teste, no qual você poderá usar o mysqlslap.

      Neste tutorial, você usará uma amostra de banco de dados de funcionários. Você vai usar essa amostra de banco de dados de funcionários porque ela apresenta um conjunto grande de dados que pode ilustrar as diferenças na otimização das consultas. O banco de dados tem seis tabelas, mas os dados que ele contém têm mais de 300.000 registros de funcionários. Isso ajudará você a emular uma carga de trabalho de produção em grande escala.

      Para baixar o banco de dados, clone primeiro o repositório do Github usando este comando:

      • git clone https://github.com/datacharmer/test_db.git

      Em seguida, acesse o diretório test_db e carregue o banco de dados no servidor MySQL usando estes comandos:

      • cd test_db
      • mysql -uroot -p < employees.sql

      Esse comando usa o redirecionamento da shell para ler as consultas em SQL no arquivo employees.sql e as executa no servidor MySQL para criar a estrutura do banco de dados.

      Você verá um resultado como este:

      Output

      INFO CREATING DATABASE STRUCTURE INFO storage engine: InnoDB INFO LOADING departments INFO LOADING employees INFO LOADING dept_emp INFO LOADING dept_manager INFO LOADING titles INFO LOADING salaries data_load_time_diff 00:00:32

      Assim que o banco de dados for carregado no seu servidor MySQL, teste se o mysqlslap está funcionando com a seguinte consulta:

      • mysqlslap -usammy -p -P6033 -h127.0.0.1 --auto-generate-sql --verbose

      O mysqlslap tem sinalizadores semelhantes aos do cliente mysql; aqui estão os usados neste comando:

      • -u – especifica o usuário usado para se conectar ao servidor.
      • -p – solicita a senha do usuário.
      • -P – conecta-se usando a porta especificada.
      • -h – conecta-se ao host especificado.
      • --auto-generate-sql – permite que o MySQL faça testes de carga, usando suas próprias consultas geradas.
      • --verbose – faz o resultado mostrar mais informações.

      Você irá obter um resultado similar ao seguinte:

      Output

      Benchmark Average number of seconds to run all queries: 0.015 seconds Minimum number of seconds to run all queries: 0.015 seconds Maximum number of seconds to run all queries: 0.015 seconds Number of clients running queries: 1 Average number of queries per client: 0

      Nesse resultado, você pode ver o número médio, mínimo e máximo de segundos gastos para executar todas as consultas. Isso lhe dará uma ideia sobre o tempo necessário para executar as consultas feitas por um certo número de clientes. Nesse resultado, apenas um cliente foi usado para executar consultas.

      Em seguida, descubra quais consultas o mysqlslap executou no último comando, examinando o stats_mysql_query_digest do ProxySQL. Isso nos dará informações como o resumo das consultas, que é uma forma normalizada da instrução em SQL que poderá ser referenciada mais tarde para habilitar o armazenamento em cache.

      Acesse a interface de administração do ProxySQL com este comando:

      • mysql -uadmin -p -h 127.0.0.1 -P6032

      Depois, execute esta consulta para encontrar informações na tabela stats_mysql_query_digest:

      • SELECT count_star,sum_time,hostgroup,digest,digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;

      Você verá um resultado similar ao seguinte:

      +------------+----------+-----------+--------------------+----------------------------------+
      | count_star | sum_time | hostgroup | digest             | digest_text                      |
      +------------+----------+-----------+--------------------+----------------------------------+
      | 1          | 598      | 1         | 0xF8F780C47A8D1D82 | SELECT @@HOSTNAME as hostname    |
      | 1          | 0        | 1         | 0x226CD90D52A2BA0B | select @@version_comment limit ? |
      +------------+----------+-----------+--------------------+----------------------------------+
      2 rows in set (0.01 sec)
      

      A consulta anterior seleciona os dados da tabela stats_mysql_query_digest, a qual contém informações sobre todas as consultas executadas no ProxySQL. Aqui, você tem cinco colunas selecionadas:

      • count_star: o número de vezes que essa consulta foi executada.
      • sum_time: tempo total em milissegundos que essa consulta levou para executar.
      • hostgroup: o grupo de hosts usado para executar a consulta.
      • digest: um resumo da consulta executada.
      • digest_text: a consulta em si. No exemplo deste tutorial, a segunda consulta é parametrizada usando sinais de ? no lugar de parâmetros de variável. select @@version_comment limit 1 e select @@version_comment limit 2 são, portanto, agrupados juntos como a mesma consulta e com o mesmo resumo.

      Agora que você sabe como verificar os dados de consulta na tabela stats_mysql_query_digest, saia do shell do mysql:

      O banco de dados que baixou contém algumas tabelas com dados de demonstração. Agora, você testará consultas na tabela dept_emp, selecionando quaisquer registros cujo from_date formaior que 2000-04-20 e registrando o tempo médio de execução.

      Use este comando para executar o teste:

      • mysqlslap -usammy -P6033 -p -h127.0.0.1 --concurrency=100 --iterations=20 --create-schema=employees --query="SELECT * from dept_emp WHERE from_date>'2000-04-20'" --verbose

      Aqui, você está usando alguns sinalizadores novos:

      • --concurrency=100: define o número de usuários a simular, neste caso 100.
      • --iterations=20: faz com que o teste seja executado 20 vezes e calcula os resultados de todos elas.
      • --create-schema=employees: aqui você selecionou o banco de dados employees (funcionários).
      • --query="SELECT * from dept_emp WHERE from_date>'2000-04-20'": aqui você especificou a consulta executada no teste.

      O teste levará alguns minutos. Após terminar, você receberá resultados semelhantes ao seguinte:

      Output

      Benchmark Average number of seconds to run all queries: 18.117 seconds Minimum number of seconds to run all queries: 8.726 seconds Maximum number of seconds to run all queries: 22.697 seconds Number of clients running queries: 100 Average number of queries per client: 1

      Seus números podem ser um pouco diferentes. Mantenha esses números em algum lugar para compará-los com os resultados obtidos após habilitar o armazenamento em cache.

      Após testar o ProxySQL sem armazenar em cache, é hora de executar o mesmo teste novamente; mas, desta vez, com o armazenamento em cache habilitado.

      Neste passo, o armazenamento em cache nos ajudará a diminuir a latência ao executar consultas semelhantes. Aqui, você identificará as consultas executadas, pegará seus resumos da tabela stats_mysql_query_digest do ProxySQL e os usará para habilitar o armazenamento em cache. Em seguida, você testará novamente para verificar a diferença.

      Para habilitar o armazenamento em cache, você precisa conhecer os resumos das consultas que serão armazenadas em cache. Faça login na interface de administração do ProxySQL, usando este comando:

      • mysql -uadmin -p -h127.0.0.1 -P6032

      Depois, execute esta consulta novamente para obter uma lista das consultas executadas e seus resumos:

      • SELECT count_star,sum_time,hostgroup,digest,digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;

      Você receberá um resultado semelhante a este:

      Output

      +------------+-------------+-----------+--------------------+------------------------------------------+ | count_star | sum_time | hostgroup | digest | digest_text | +------------+-------------+-----------+--------------------+------------------------------------------+ | 2000 | 33727110501 | 1 | 0xC5DDECD7E966A6C4 | SELECT * from dept_emp WHERE from_date>? | | 1 | 601 | 1 | 0xF8F780C47A8D1D82 | SELECT @@HOSTNAME as hostname | | 1 | 0 | 1 | 0x226CD90D52A2BA0B | select @@version_comment limit ? | +------------+-------------+-----------+--------------------+------------------------------------------+ 3 rows in set (0.00 sec)

      Examine a primeira linha. Trata-se de uma consulta que foi executada 2000 vezes. Essa é a consulta executada anteriormente como parâmetro de comparação. Pegue seu resumo e guarde-o para ser usado na adição de uma regra de consulta para o armazenamento em cache.

      As próximas consultas vão adicionar uma nova regra de consulta ao ProxySQL que fará a correspondência entre o resumo da consulta anterior e colocará um valor cache_ttl para ela. O cache_ttl é o número de milissegundos em que o resultado ficará armazenado em memória cache:

      • INSERT INTO mysql_query_rules(active, digest, cache_ttl, apply) VALUES(1,'0xC5DDECD7E966A6C4',2000,1);

      Nesse comando, você está adicionando um novo registro à tabela mysql_query_rules; essa tabela contém todas as regras aplicadas antes de executar uma consulta. Nesse exemplo, você está adicionando um valor à coluna cache_ttl, que fará com que a consulta – que foi combinada por determinado resumo – seja armazenada em cache pelo tempo (em milissegundos) especificado nessa coluna. Coloque 1 na coluna de aplicação para garantir que a regra seja aplicada às consultas.

      LOAD e SAVE essas alterações e, em seguida, saia do shell mysql:

      • LOAD MYSQL QUERY RULES TO RUNTIME;
      • SAVE MYSQL QUERY RULES TO DISK;
      • exit;

      Agora que o armazenamento em cache está habilitado, execute novamente o teste para verificar o resultado:

      • mysqlslap -usammy -P6033 -p -h127.0.0.1 --concurrency=100 --iterations=20 --create-schema=employees --query="SELECT * from dept_emp WHERE from_date>'2000-04-20'" --verbose

      Isso dará um resultado similar ao seguinte:

      Output

      Benchmark Average number of seconds to run all queries: 7.020 seconds Minimum number of seconds to run all queries: 0.274 seconds Maximum number of seconds to run all queries: 23.014 seconds Number of clients running queries: 100 Average number of queries per client: 1

      Aqui, você consegue ver a grande diferença em tempo médio de execução: o tempo baixou de 18.117 segundos para 7.020.

      Conclusão

      Neste artigo, você configurou o armazenamento em cache transparente com o ProxySQL para armazenar em cache os resultados das consultas no banco de dados. Também testou a velocidade de consulta com e sem o armazenamento em cache para ver a diferença que o armazenamento em cache pode fazer.

      Neste tutorial, você usou um nível de armazenamento em cache. Você também poderia tentar fazer o armazenamento em cache baseado na Web, o qual fica na frente de um servidor Web e armazena em cache as respostas a pedidos semelhantes, enviando a resposta de volta para o cliente, sem chegar aos servidores de back-end. É bem parecido com o armazenamento em cache do ProxySQL, porém em um outro nível. Para aprender mais sobre o armazenamento em cache baseado na Web, acesse o artigo Noções básicas de armazenamento em cache baseado na Web: terminologia, cabeçalhos de HTTP e primer de estratégias de armazenamento em cache.

      O servidor MySQL também tem seu próprio cache de consulta; você pode aprender mais sobre isso em nosso tutorial sobre Como otimizar o MySQL com o cache de consulta no Ubuntu 18.04.



      Source link

      Como Configurar um Banco de Dados Remoto para Otimizar o Desempenho do Site com o MySQL no Ubuntu 18.04


      Introdução

      À medida que sua aplicação ou site cresce, pode chegar um momento em que você superou a configuração atual do seu servidor. Se você estiver hospedando o seu servidor web e o back-end do banco de dados na mesma máquina, pode ser uma boa ideia separar essas duas funções para que cada uma possa operar em seu próprio hardware e compartilhar a carga de responder às solicitações dos visitantes.

      Neste guia, veremos como configurar um servidor de banco de dados MySQL remoto ao qual sua aplicação web pode se conectar. Usaremos o WordPress como exemplo para ter algo para trabalhar, mas a técnica é amplamente aplicável a qualquer aplicação suportada pelo MySQL.

      Pré-requisitos

      Antes de iniciar este tutorial, você precisará de:

      • Dois servidores Ubuntu 18.04. Cada um deles deve ter um usuário não-root com privilégios sudo e um firewall UFW habilitado, conforme descrito em nosso tutorial de Configuração Inicial de servidor com Ubuntu 18.04. Um desses servidores hospedará seu back-end MySQL e, ao longo deste guia, o chamaremos de servidor de banco de dados. O outro se conectará ao seu servidor de banco de dados remotamente e atuará como seu servidor web; da mesma forma, iremos nos referir a ele como servidor web ao longo deste guia.
      • Nginx e PHP instalado em seu servidor web. Nosso tutorial How To Install Linux, Nginx, MySQL, PHP (LEMP stack) in Ubuntu 18.04 o guiará no processo, mas observe que você deve pular o Passo 2 deste tutorial, que se concentra na instalação do MySQL, pois você instalará o MySQL no seu servidor de banco de dados.
      • MySQL instalado em seu servidor de banco de dados. Siga o tutorial Como Instalar o MySQL no Ubuntu 18.04 para configurar isso.
      • Opcionalmente (mas altamente recomendado), certificados TLS/SSL da Let’s Encrypt instalados em seu servidor web. Você precisará comprar um nome de domínio e ter registros DNS configurados para seu servidor, mas os certificados em si são gratuitos. Nosso guia Como Proteger o Nginx com o Let’s Encrypt no Ubuntu 18.04 lhe mostrará como obter esses certificados.

      Passo 1 — Configurando o MySQL para Escutar Conexões Remotas

      Ter os dados armazenados em um servidor separado é uma boa maneira de expandir elegantemente após atingir o limite máximo de desempenho de uma configuração de uma única máquina. Ela também fornece a estrutura básica necessária para balancear a carga e expandir sua infraestrutura ainda mais posteriormente. Após instalar o MySQL, seguindo o tutorial de pré-requisitos, você precisará alterar alguns valores de configuração para permitir conexões a partir de outros computadores.

      A maioria das mudanças na configuração do servidor MySQL pode ser feita no arquivo mysqld.cnf, que é armazenado no diretório /etc/mysql/mysql.conf.d/ por padrão. Abra este arquivo em seu servidor de banco de dados com privilégios de root em seu editor preferido. Aqui, iremos usar o nano:

      • sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

      Este arquivo é dividido em seções indicadas por labels entre colchetes ([ e ]). Encontre a seção com o label mysqld:

      /etc/mysql/mysql.conf.d/mysqld.cnf

      . . .
      [mysqld]
      . . .
      

      Nesta seção, procure um parâmetro chamado bind-address. Isso informa ao software do banco de dados em qual endereço de rede escutar as conexões.

      Por padrão, isso está definido como 127.0.0.1, significando que o MySQL está configurado para escutar apenas conexões locais. Você precisa alterar isso para fazer referência a um endereço IP externo onde seu servidor pode ser acessado.

      Se os dois servidores estiverem em um datacenter com recursos de rede privada, use o IP da rede privada do seu servidor de banco de dados. Caso contrário, você pode usar seu endereço IP público:

      /etc/mysql/mysql.conf.d/mysqld.cnf

      [mysqld]
      . . .
      bind-address = ip_do_servidor_de_banco_de_dados
      

      Como você se conectará ao seu banco de dados pela Internet, é recomendável que você exija conexões criptografadas para manter seus dados seguros. Se você não criptografar sua conexão MySQL, qualquer pessoa na rede poderá fazer sniff por informações confidenciais entre seus servidores web e de banco de dados. Para criptografar conexões MySQL, adicione a seguinte linha após a linha bind-address que você acabou de atualizar:

      /etc/mysql/mysql.conf.d/mysqld.cnf

      [mysqld]
      . . .
      require_secure_transport = on
      . . .
      

      Salve e feche o arquivo quando terminar. Se você estiver usando nano, faça isso pressionando CTRL+X, Y e, em seguida, ENTER.

      Para que as conexões SSL funcionem, você precisará criar algumas chaves e certificados. O MySQL vem com um comando que os configura automaticamente. Execute o seguinte comando, que cria os arquivos necessários. Ele também os torna legíveis pelo servidor MySQL, especificando o UID do usuário mysql:

      • sudo mysql_ssl_rsa_setup --uid=mysql

      Para forçar o MySQL a atualizar sua configuração e ler as novas informações de SSL, reinicie o banco de dados:

      • sudo systemctl restart mysql

      Para confirmar que o servidor agora está escutando na interface externa, execute o seguinte comando netstat:

      • sudo netstat -plunt | grep mysqld

      Output

      tcp 0 0 ip_do_servidor_de_banco_de_dados:3306 0.0.0.0:* LISTEN 27328/mysqld

      O netstat imprime estatísticas sobre o sistema de rede do seu servidor. Esta saída nos mostra que um processo chamado mysqld está anexado ao ip_do_servidor_de_banco_de_dados na porta 3306, a porta padrão do MySQL, confirmando que o servidor está escutando na interface apropriada.

      Em seguida, abra essa porta no firewall para permitir o tráfego através dela:

      Essas são todas as alterações de configuração que você precisa fazer no MySQL. A seguir, veremos como configurar um banco de dados e alguns perfis de usuário, um dos quais você usará para acessar o servidor remotamente.

      Passo 2 — Configurando um Banco de Dados para o WordPress e Credenciais Remotas

      Embora o próprio MySQL agora esteja escutando em um endereço IP externo, atualmente não há usuários ou bancos de dados habilitados para controle remoto configurados. Vamos criar um banco de dados para o WordPress e um par de usuários que possam acessá-lo.

      Comece conectando-se ao MySQL como o usuário root do MySQL:

      Nota: Se você tiver a autenticação por senha ativada, conforme descrito no Passo 3 do pré-requisito do tutorial do MySQL, você precisará usar o seguinte comando para acessar o shell do MySQL:

      Depois de executar este comando, você será solicitado a fornecer sua senha de root do MySQL e, após inseri-la, receberá um novo prompt mysql>.

      No prompt do MySQL, crie um banco de dados que o WordPress usará. Pode ser útil atribuir a esse banco de dados um nome reconhecível para que você possa identificá-lo facilmente mais tarde. Aqui, vamos chamá-lo de wordpress:

      • CREATE DATABASE wordpress;

      Agora que você criou seu banco de dados, você precisará criar um par de usuários. Criaremos um usuário somente local e um usuário remoto vinculado ao endereço IP do servidor web.

      Primeiro, crie seu usuário local, wpuser, e faça com que esta conta corresponda apenas às tentativas de conexão local usando localhost na declaração:

      • CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'senha';

      Em seguida, conceda a esta conta acesso total ao banco de dados wordpress:

      • GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';

      Agora, esse usuário pode executar qualquer operação no banco de dados do WordPress, mas essa conta não pode ser usada remotamente, pois corresponde apenas às conexões da máquina local. Com isso em mente, crie uma conta complementar que corresponda às conexões exclusivamente do seu servidor web. Para isso, você precisará do endereço IP do seu servidor web.

      Observe que você deve usar um endereço IP que utilize a mesma rede que você configurou no seu arquivo mysqld.cnf. Isso significa que, se você especificou um IP de rede privada no arquivo mysqld.cnf, precisará incluir o IP privado do seu servidor web nos dois comandos a seguir. Se você configurou o MySQL para usar a internet pública, você deve fazer isso corresponder ao endereço IP público do servidor web.

      • CREATE USER 'remotewpuser'@'ip_do_servidor_web' IDENTIFIED BY 'senha';

      Depois de criar sua conta remota, conceda a ela os mesmos privilégios que o usuário local:

      • GRANT ALL PRIVILEGES ON wordpress.* TO 'remotewpuser'@'ip_do_servidor_web';

      Por fim, atualize os privilégios para que o MySQL saiba começar a usá-los:

      Então saia do prompt do MySQL digitando:

      Agora que você configurou um novo banco de dados e um usuário habilitado remotamente, você pode testar se consegue se conectar ao banco de dados a partir do seu servidor web.

      Passo 3 — Testando Conexões Remotas e Locais

      Antes de continuar, é melhor verificar se você pode se conectar ao seu banco de dados tanto a partir da máquina local — seu servidor de banco de dados — quanto pelo seu servidor web.

      Primeiro, teste a conexão local a partir do seu servidor de banco de dados tentando fazer login com sua nova conta:

      Quando solicitado, digite a senha que você configurou para esta conta.

      Se você receber um prompt do MySQL, então a conexão local foi bem-sucedida. Você pode sair novamente digitando:

      Em seguida, faça login no seu servidor web para testar as conexões remotas:

      • ssh sammy@ip_do_servidor_web

      Você precisará instalar algumas ferramentas de cliente para MySQL em seu servidor web para acessar o banco de dados remoto. Primeiro, atualize o cache de pacotes local se você não tiver feito isso recentemente:

      Em seguida, instale os utilitários de cliente do MySQL:

      • sudo apt install mysql-client

      Depois disso, conecte-se ao seu servidor de banco de dados usando a seguinte sintaxe:

      • mysql -u remotewpuser -h ip_do_servidor_de_banco_de_dados -p

      Novamente, você deve certificar-se que está usando o endereço IP correto para o servidor de banco de dados. Se você configurou o MySQL para escutar na rede privada, digite o IP da rede privada do seu banco de dados. Caso contrário, digite o endereço IP público do seu servidor de banco de dados.

      Você será solicitado a inserir a senha da sua conta remotewpuser. Depois de inseri-la, e se tudo estiver funcionando conforme o esperado, você verá o prompt do MySQL. Verifique se a conexão está usando SSL com o seguinte comando:

      Se a conexão realmente estiver usando SSL, a linha SSL: indicará isso, como mostrado aqui:

      Output

      -------------- mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64) using EditLine wrapper Connection id: 52 Current database: Current user: remotewpuser@203.0.113.111 SSL: Cipher in use is DHE-RSA-AES256-SHA Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.7.18-0ubuntu0.16.04.1 (Ubuntu) Protocol version: 10 Connection: 203.0.113.111 via TCP/IP Server characterset: latin1 Db characterset: latin1 Client characterset: utf8 Conn. characterset: utf8 TCP port: 3306 Uptime: 3 hours 43 min 40 sec Threads: 1 Questions: 1858 Slow queries: 0 Opens: 276 Flush tables: 1 Open tables: 184 Queries per second avg: 0.138 --------------

      Depois de verificar que você pode se conectar remotamente, vá em frente e saia do prompt:

      Com isso, você verificou o acesso local e o acesso a partir do servidor web, mas não verificou se outras conexões serão recusadas. Para uma verificação adicional, tente fazer o mesmo em um terceiro servidor para o qual você não configurou uma conta de usuário específica para garantir que esse outro servidor não tenha o acesso concedido.

      Observe que antes de executar o seguinte comando para tentar a conexão, talvez seja necessário instalar os utilitários de cliente do MySQL, como você fez acima:

      • mysql -u wordpressuser -h ip_do_servidor_de_banco_de_dados -p

      Isso não deve ser concluído com êxito e deve gerar um erro semelhante a este:

      Output

      ERROR 1130 (HY000): Host '203.0.113.12' is not allowed to connect to this MySQL server

      Isso é esperado, já que você não criou um usuário do MySQL que tem permissão para se conectar a partir deste servidor, e também é desejado, uma vez que você quer ter certeza de que seu servidor de banco de dados negará o acesso de usuários não autorizados ao seu servidor do MySQL.

      Após testar com êxito sua conexão remota, você pode instalar o WordPress em seu servidor web.

      Passo 4 — Instalando o WordPress

      Para demonstrar os recursos do seu novo servidor MySQL com capacidade remota, passaremos pelo processo de instalação e configuração do WordPress — o popular sistema de gerenciamento de conteúdo — em seu servidor web. Isso exigirá que você baixe e extraia o software, configure suas informações de conexão e então execute a instalação baseada em web do WordPress.

      No seu servidor web, faça o download da versão mais recente do WordPress para o seu diretório home:

      • cd ~
      • curl -O https://wordpress.org/latest.tar.gz

      Extraia os arquivos, que criarão um diretório chamado wordpress no seu diretório home:

      O WordPress inclui um arquivo de configuração de exemplo que usaremos como ponto de partida. Faça uma cópia deste arquivo, removendo -sample do nome do arquivo para que ele seja carregado pelo WordPress:

      • cp ~/wordpress/wp-config-sample.php ~/wordpress/wp-config.php

      Quando você abre o arquivo, sua primeira abordagem será ajustar algumas chaves secretas para fornecer mais segurança à sua instalação. O WordPress fornece um gerador seguro para esses valores, para que você não precise criar bons valores por conta própria. Eles são usados apenas internamente, portanto, não prejudicará a usabilidade ter valores complexos e seguros aqui.

      Para obter valores seguros do gerador de chave secreta do WordPress, digite:

      • curl -s https://api.wordpress.org/secret-key/1.1/salt/

      Isso imprimirá algumas chaves na sua saída. Você as adicionará momentaneamente ao seu arquivo wp-config.php:

      Atenção! É importante que você solicite seus próprios valores únicos sempre. Não copie os valores mostrados aqui!

      Output

      define('AUTH_KEY', 'L4|2Yh(giOtMLHg3#] DO NOT COPY THESE VALUES %G00o|te^5YG@)'); define('SECURE_AUTH_KEY', 'DCs-k+MwB90/-E(=!/ DO NOT COPY THESE VALUES +WBzDq:7U[#Wn9'); define('LOGGED_IN_KEY', '*0kP!|VS.K=;#fPMlO DO NOT COPY THESE VALUES +&[%8xF*,18c @'); define('NONCE_KEY', 'fmFPF?UJi&(j-{8=$- DO NOT COPY THESE VALUES CCZ?Q+_~1ZU~;G'); define('AUTH_SALT', '@qA7f}2utTEFNdnbEa DO NOT COPY THESE VALUES t}Vw+8=K%20s=a'); define('SECURE_AUTH_SALT', '%BW6s+d:7K?-`C%zw4 DO NOT COPY THESE VALUES 70U}PO1ejW+7|8'); define('LOGGED_IN_SALT', '-l>F:-dbcWof%4kKmj DO NOT COPY THESE VALUES 8Ypslin3~d|wLD'); define('NONCE_SALT', '4J(<`4&&F (WiK9K#] DO NOT COPY THESE VALUES ^ZikS`es#Fo:V6');

      Copie a saída que você recebeu para a área de transferência e abra o arquivo de configuração no seu editor de texto:

      • nano ~/wordpress/wp-config.php

      Encontre a seção que contém os valores fictícios para essas configurações. Será algo parecido com isto:

      /wordpress/wp-config.php

      . . .
      define('AUTH_KEY',         'put your unique phrase here');
      define('SECURE_AUTH_KEY',  'put your unique phrase here');
      define('LOGGED_IN_KEY',    'put your unique phrase here');
      define('NONCE_KEY',        'put your unique phrase here');
      define('AUTH_SALT',        'put your unique phrase here');
      define('SECURE_AUTH_SALT', 'put your unique phrase here');
      define('LOGGED_IN_SALT',   'put your unique phrase here');
      define('NONCE_SALT',       'put your unique phrase here');
      . . .
      

      Exclua essas linhas e cole os valores que você copiou a partir da linha de comando.

      Em seguida, insira as informações de conexão para seu banco de dados remoto. Essas linhas de configuração estão na parte superior do arquivo, logo acima de onde você colou suas chaves. Lembre-se de usar o mesmo endereço IP que você usou no teste de banco de dados remoto anteriormente:

      /wordpress/wp-config.php

      . . .
      /** The name of the database for WordPress */
      define('DB_NAME', 'wordpress');
      
      /** MySQL database username */
      define('DB_USER', 'remotewpuser');
      
      /** MySQL database password */
      define('DB_PASSWORD', 'password');
      
      /** MySQL hostname */
      define('DB_HOST', 'db_server_ip');
      . . .
      

      E, finalmente, em qualquer lugar do arquivo, adicione a seguinte linha que diz ao WordPress para usar uma conexão SSL para o nosso banco de dados MySQL:

      /wordpress/wp-config.php

      define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);
      

      Salve e feche o arquivo.

      Em seguida, copie os arquivos e diretórios encontrados no diretório ~/wordpress para a raiz de documentos do Nginx. Observe que este comando inclui a flag -a para garantir que todas as permissões existentes sejam transferidas:

      • sudo cp -a ~/wordpress/* /var/www/html

      Depois disso, a única coisa a fazer é modificar a propriedade do arquivo. Altere a propriedade de todos os arquivos na raiz de documentos para www-data, o usuário padrão do servidor web do Ubuntu:

      • sudo chown -R www-data:www-data /var/www/html

      Com isso, o WordPress está instalado e você está pronto para executar sua rotina de configuração baseada em web.

      Passo 5 — Configurando o WordPress Através da Interface Web

      O WordPress possui um processo de configuração baseado na web. Conforme você avança, ele fará algumas perguntas e instalará todas as tabelas necessárias no seu banco de dados. Aqui, abordaremos as etapas iniciais da configuração do WordPress, que você pode usar como ponto de partida para criar seu próprio site personalizado que usa um back-end de banco de dados remoto.

      Navegue até o nome de domínio (ou endereço IP público) associado ao seu servidor web:

      http://example.com
      

      Você verá uma tela de seleção de idioma para o instalador do WordPress. Selecione o idioma apropriado e clique na tela principal de instalação:

      WordPress install screen

      Depois de enviar suas informações, você precisará fazer login na interface de administração do WordPress usando a conta que você acabou de criar. Você será direcionado para um painel onde poderá personalizar seu novo site WordPress.

      Conclusão

      Ao seguir este tutorial, você configurou um banco de dados MySQL para aceitar conexões protegidas por SSL a partir de uma instalação remota do WordPress. Os comandos e técnicas usados neste guia são aplicáveis a qualquer aplicação web escrita em qualquer linguagem de programação, mas os detalhes específicos da implementação serão diferentes. Consulte a documentação do banco de dados da aplicação ou linguagem para obter mais informações.



      Source link

      Como Otimizar Imagens Docker para Produção


      O autor escolheu a Code.org para receber uma doação como parte do programa Write for DOnations.

      Introdução

      Em um ambiente de produção, o Docker facilita a criação, o deployment e a execução de aplicações dentro de containers. Os containers permitem que os desenvolvedores reúnam aplicações e todas as suas principais necessidades e dependências em um único pacote que você pode transformar em uma imagem Docker e replicar. As imagens Docker são construídas a partir de Dockerfiles. O Dockerfile é um arquivo onde você define como será a imagem, qual sistema operacional básico ela terá e quais comandos serão executados dentro dela.

      Imagens Docker muito grandes podem aumentar o tempo necessário para criar e enviar imagens entre clusters e provedores de nuvem. Se, por exemplo, você tem uma imagem do tamanho de um gigabyte para enviar toda vez que um de seus desenvolvedores aciona uma compilação, a taxa de transferência que você cria em sua rede aumentará durante o processo de CI/CD, tornando sua aplicação lenta e, consequentemente, custando seus recursos. Por causa disso, as imagens Docker adequadas para produção devem ter apenas as necessidades básicas instaladas.

      Existem várias maneiras de diminuir o tamanho das imagens Docker para otimizá-las para a produção. Em primeiro lugar, essas imagens geralmente não precisam de ferramentas de compilação para executar suas aplicações e, portanto, não há necessidade de adicioná-las. Através do uso de um processo de construção multi-stage, você pode usar imagens intermediárias para compilar e construir o código, instalar dependências e empacotar tudo no menor tamanho possível, depois copiar a versão final da sua aplicação para uma imagem vazia sem ferramentas de compilação. Além disso, você pode usar uma imagem com uma base pequena, como o Alpine Linux. O Alpine é uma distribuição Linux adequada para produção, pois possui apenas as necessidades básicas que sua aplicação precisa para executar.

      Neste tutorial, você otimizará as imagens Docker em algumas etapas simples, tornando-as menores, mais rápidas e mais adequadas à produção. Você construirá imagens para um exemplo de API em Go em vários containers Docker diferentes, começando com o Ubuntu e imagens específicas de linguagens, e então passando para a distribuição Alpine. Você também usará compilações multi-stage para otimizar suas imagens para produção. O objetivo final deste tutorial é mostrar a diferença de tamanho entre usar imagens padrão do Ubuntu e as equivalentes otimizadas, e mostrar a vantagem das compilações em vários estágios (multi-stage). Depois de ler este tutorial, você poderá aplicar essas técnicas aos seus próprios projetos e pipelines de CI/CD.

      Nota: Este tutorial utiliza uma API escrita em Go como um exemplo. Esta simples API lhe dará uma compreensão clara de como você abordaria a otimização de microsserviços em Go com imagens Docker. Embora este tutorial use uma API Go, você pode aplicar esse processo a praticamente qualquer linguagem de programação.

      Pré-requisitos

      Antes de começar, você precisará de:

      Passo 1 — Baixando a API Go de Exemplo

      Antes de otimizar sua imagem Docker, você deve primeiro fazer o download da API de exemplo, a partir da qual você construirá suas imagens Docker. O uso de uma API Go simples mostrará todas as principais etapas de criação e execução de uma aplicação dentro de um container Docker. Este tutorial usa o Go porque é uma linguagem compilada como o C++ ou Java, mas ao contrário dele, tem uma pegada muito pequena.

      No seu servidor, comece clonando a API Go de exemplo:

      • git clone https://github.com/do-community/mux-go-api.git

      Depois de clonar o projeto, você terá um diretório chamado mux-go-api em seu servidor. Mova-se para este diretório com cd:

      Este será o diretório home do seu projeto. Você construirá suas imagens Docker a partir desse diretório. Dentro dele você encontrará o código fonte para uma API escrita em Go no arquivo api.go. Embora essa API seja mínima e tenha apenas alguns endpoints, ela será apropriada para simular uma API pronta para produção para os propósitos deste tutorial.

      Agora que você baixou a API Go de exemplo, você está pronto para criar uma imagem base do Ubuntu no Docker, com a qual você poderá comparar as imagens posteriores e otimizadas.

      Passo 2 — Construindo uma Imagem Base do Ubuntu

      Para a sua primeira imagem Docker, será útil ver como ela é quando você começa com uma imagem base do Ubuntu. Isso irá empacotar sua API de exemplo em um ambiente similar ao software que você já está rodando no seu servidor Ubuntu. Isso irá empacotar sua API de exemplo em um ambiente similar ao software que você já está rodando no seu servidor Ubuntu. Dentro da imagem, você instalará os vários pacotes e módulos necessários para executar sua aplicação. Você descobrirá, no entanto, que esse processo cria uma imagem bastante pesada do Ubuntu que afetará o tempo de compilação e a legibilidade do código do seu Dockerfile.

      Comece escrevendo um Dockerfile que instrui o Docker a criar uma imagem do Ubuntu, instalar o Go e executar a API de exemplo. Certifique-se de criar o Dockerfile no diretório do repositório clonado. Se você clonou no diretório home, ele deve ser $HOME/mux-go-api.

      Crie um novo arquivo chamado Dockerfile.ubuntu. Abra-o no nano ou no seu editor de texto favorito:

      • nano ~/mux-go-api/Dockerfile.ubuntu

      Neste Dockerfile, você irá definir uma imagem do Ubuntu e instalar o Golang. Em seguida, você vai continuar a instalar as dependências necessárias e construir o binário. Adicione o seguinte conteúdo ao Dockerfile.ubuntu:

      ~/mux-go-api/Dockerfile.ubuntu

      FROM ubuntu:18.04
      
      RUN apt-get update -y 
        && apt-get install -y git gcc make golang-1.10
      
      ENV GOROOT /usr/lib/go-1.10
      ENV PATH $GOROOT/bin:$PATH
      ENV GOPATH /root/go
      ENV APIPATH /root/go/src/api
      
      WORKDIR $APIPATH
      COPY . .
      
      RUN  
        go get -d -v 
        && go install -v 
        && go build
      
      EXPOSE 3000
      CMD ["./api"]
      

      Começando do topo, o comando FROM especifica qual sistema operacional básico a imagem terá. A seguir, o comando RUN instala a linguagem Go durante a criação da imagem. ENV define as variáveis de ambiente específicas que o compilador Go precisa para funcionar corretamente. WORKDIR especifica o diretório onde queremos copiar o código, e o comando COPY pega o código do diretório onde o Dockerfile.ubuntu está e o copia para a imagem. O comando RUN final instala as dependências do Go necessárias para o código-fonte compilar e executar a API.

      Nota: Usar os operadores && para unir os comandos RUN é importante para otimizar os Dockerfiles, porque todo comando RUN criará uma nova camada, e cada nova camada aumentará o tamanho da imagem final.

      Salve e saia do arquivo. Agora você pode executar o comando build para criar uma imagem Docker a partir do Dockerfile que você acabou de criar:

      • docker build -f Dockerfile.ubuntu -t ubuntu .

      O comando build constrói uma imagem a partir de um Dockerfile. A flag -f especifica que você deseja compilar a partir do arquivo Dockerfile.ubuntu, enquanto -t significa tag, o que significa que você está marcando a imagem com o nome ubuntu. O ponto final representa o contexto atual onde o Dockerfile.ubuntu está localizado.

      Isso vai demorar um pouco, então sinta-se livre para fazer uma pausa. Quando a compilação estiver concluída, você terá uma imagem Ubuntu pronta para executar sua API. Mas o tamanho final da imagem pode não ser ideal; qualquer coisa acima de algumas centenas de MB para essa API seria considerada uma imagem excessivamente grande.

      Execute o seguinte comando para listar todas as imagens Docker e encontrar o tamanho da sua imagem Ubuntu:

      Você verá a saída mostrando a imagem que você acabou de criar:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 61b2096f6871 33 seconds ago 636MB . . .

      Como é destacado na saída, esta imagem tem um tamanho de 636MB para uma API Golang básica, um número que pode variar um pouco de máquina para máquina. Em múltiplas compilações, esse grande tamanho afetará significativamente os tempos de deployment e a taxa de transferência da rede.

      Nesta seção, você construiu uma imagem Ubuntu com todas as ferramentas e dependências necessárias do Go para executar a API que você clonou no Passo 1. Na próxima seção, você usará uma imagem Docker pré-criada e específica da linguagem para simplificar seu Dockerfile e agilizar o processo de criação.

      Passo 3 — Construindo uma Imagem Base Específica para a Linguagem

      Imagens pré-criadas são imagens básicas comuns que os usuários modificaram para incluir ferramentas específicas para uma situação. Os usuários podem, então, enviar essas imagens para o repositório de imagens Docker Hub, permitindo que outros usuários usem a imagem compartilhada em vez de ter que escrever seus próprios Dockerfiles individuais. Este é um processo comum em situações de produção, e você pode encontrar várias imagens pré-criadas no Docker Hub para praticamente qualquer caso de uso. Neste passo, você construirá sua API de exemplo usando uma imagem específica do Go que já tenha o compilador e as dependências instaladas.

      Com imagens base pré-criadas que já contêm as ferramentas necessárias para criar e executar sua aplicação, você pode reduzir significativamente o tempo de criação. Como você está começando com uma base que tem todas as ferramentas necessárias pré-instaladas, você pode pular a adição delas ao seu Dockerfile, fazendo com que pareça muito mais limpo e, finalmente, diminuindo o tempo de construção.

      Vá em frente e crie outro Dockerfile e nomeie-o como Dockerfile.golang. Abra-o no seu editor de texto:

      • nano ~/mux-go-api/Dockerfile.golang

      Este arquivo será significativamente mais conciso do que o anterior, porque tem todas as dependências, ferramentas e compilador específicos do Go pré-instalados.

      Agora, adicione as seguintes linhas:

      ~/mux-go-api/Dockerfile.golang

      FROM golang:1.10
      
      WORKDIR /go/src/api
      COPY . .
      
      RUN 
          go get -d -v 
          && go install -v 
          && go build
      
      EXPOSE 3000
      CMD ["./api"]
      

      Começando do topo, você verá que a instrução FROM agora é golang:1.10. Isso significa que o Docker buscará uma imagem Go pré-criada do Docker Hub que tenha todas as ferramentas Go necessárias já instaladas.

      Agora, mais uma vez, compile a imagem do Docker com:

      • docker build -f Dockerfile.golang -t golang .

      Verifique o tamanho final da imagem com o seguinte comando:

      Isso produzirá uma saída semelhante à seguinte:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE golang latest eaee5f524da2 40 seconds ago 744MB . . .

      Embora o próprio Dockerfile seja mais eficiente e o tempo de compilação seja menor, o tamanho total da imagem aumentou. A imagem pré-criada do Golang está em torno de 744MB, uma quantidade significativa.

      Essa é a maneira preferida de criar imagens Docker. Ela lhe dá uma imagem base que a comunidade aprovou como o padrão a ser usado para a linguagem especificada, neste caso, Go. No entanto, para tornar uma imagem pronta para produção, você precisa cortar partes que a aplicação em execução não precisa.

      Tenha em mente que o uso dessas imagens pesadas é bom quando você não tem certeza sobre suas necessidades. Sinta-se à vontade para usá-las como containers descartáveis, bem como a base para a construção de outras imagens. Para fins de desenvolvimento ou teste, onde você não precisa pensar em enviar imagens pela rede, é perfeitamente aceitável usar imagens pesadas. Mas, se você quiser otimizar os deployments, precisará fazer o seu melhor para tornar suas imagens o menor possível.

      Agora que você testou uma imagem específica da linguagem, você pode passar para a próxima etapa, na qual usará a distribuição leve do Alpine Linux como uma imagem base para tornar a imagem Docker mais leve.

      Passo 4 — Construindo Imagens Base do Alpine

      Um dos passos mais fáceis para otimizar as imagens Docker é usar imagens base menores. Alpine é uma distribuição Linux leve projetada para segurança e eficiência de recursos. A imagem Docker do Alpine usa musl libc e BusyBox para ficar compacta, exigindo não mais que 8MB em um container para ser executada. O tamanho minúsculo é devido a pacotes binários sendo refinados e divididos, dando a você mais controle sobre o que você instala, o que mantém o ambiente menor e mais eficiente possível.

      O processo de criação de uma imagem Alpine é semelhante ao modo como você criou a imagem do Ubuntu no Passo 2. Primeiro, crie um novo arquivo chamado Dockerfile.alpine:

      • nano ~/mux-go-api/Dockerfile.alpine

      Agora adicione este trecho:

      ~/mux-go-api/Dockerfile.alpine

      FROM alpine:3.8
      
      RUN apk add --no-cache 
          ca-certificates 
          git 
          gcc 
          musl-dev 
          openssl 
          go
      
      ENV GOPATH /go
      ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
      ENV APIPATH $GOPATH/src/api
      RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" "$APIPATH" && chmod -R 777 "$GOPATH"
      
      WORKDIR $APIPATH
      COPY . .
      
      RUN 
          go get -d -v 
          && go install -v 
          && go build
      
      EXPOSE 3000
      CMD ["./api"]
      

      Aqui você está adicionando o comando apk add para utilizar o gerenciador de pacotes do Alpine para instalar o Go e todas as bibliotecas que ele requer. Tal como acontece com a imagem do Ubuntu, você precisa definir as variáveis de ambiente também.

      Vá em frente e compile a imagem:

      • docker build -f Dockerfile.alpine -t alpine .

      Mais uma vez, verifique o tamanho da imagem:

      Você receberá uma saída semelhante à seguinte:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE alpine latest ee35a601158d 30 seconds ago 426MB . . .

      O tamanho caiu para cerca de 426MB.

      O tamanho reduzido da imagem base Alpine reduziu o tamanho final da imagem, mas há mais algumas coisas que você pode fazer para torná-la ainda menor.

      A seguir, tente usar uma imagem Alpine pré-criada para o Go. Isso tornará o Dockerfile mais curto e também reduzirá o tamanho da imagem final. Como a imagem Alpine pré-criada para o Go é construída com o Go compilado dos fontes, sua tamanho é significativamente menor.

      Comece criando um novo arquivo chamado Dockerfile.golang-alpine:

      • nano ~/mux-go-api/Dockerfile.golang-alpine

      Adicione o seguinte conteúdo ao arquivo:

      ~/mux-go-api/Dockerfile.golang-alpine

      FROM golang:1.10-alpine3.8
      
      RUN apk add --no-cache --update git
      
      WORKDIR /go/src/api
      COPY . .
      
      RUN go get -d -v 
        && go install -v 
        && go build
      
      EXPOSE 3000
      CMD ["./api"]
      

      As únicas diferenças entre Dockerfile.golang-alpine e Dockerfile.alpine são o comando FROM e o primeiro comando RUN. Agora, o comando FROM especifica uma imagem golang com a tag 1.10-alpine3.8 e RUN só tem um comando para a instalação do Git. Você precisa do Git para o comando go get para trabalhar no segundo comando RUN na parte inferior do Dockerfile.golang-alpine.

      Construa a imagem com o seguinte comando:

      • docker build -f Dockerfile.golang-alpine -t golang-alpine .

      Obtenha sua lista de imagens:

      Você receberá a seguinte saída:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE golang-alpine latest 97103a8b912b 49 seconds ago 288MB

      Agora o tamanho da imagem está em torno de 288MB.

      Mesmo que você tenha conseguido reduzir bastante o tamanho, há uma última coisa que você pode fazer para preparar a imagem para a produção. É chamado de uma compilação de múltiplos estágios ou multi-stage. Usando compilações multi-stage, você pode usar uma imagem para construir a aplicação enquanto usa outra imagem mais leve para empacotar a aplicação compilada para produção, um processo que será executado no próximo passo.

      Passo 5 — Excluindo Ferramentas de Compilação em uma Compilação Multi-Stage

      Idealmente, as imagens que você executa em produção não devem ter nenhuma ferramenta de compilação instalada ou dependências redundantes para a execução da aplicação de produção. Você pode removê-las da imagem Docker final usando compilações multi-stage. Isso funciona através da construção do binário, ou em outros termos, a aplicação Go compilada, em um container intermediário, copiando-o em seguida para um container vazio que não tenha dependências desnecessárias.

      Comece criando outro arquivo chamado Dockerfile.multistage:

      • nano ~/mux-go-api/Dockerfile.multistage

      O que você vai adicionar aqui será familiar. Comece adicionando o mesmo código que está em Dockerfile.golang-alpine. Mas desta vez, adicione também uma segunda imagem onde você copiará o binário a partir da primeira imagem.

      ~/mux-go-api/Dockerfile.multistage

      FROM golang:1.10-alpine3.8 AS multistage
      
      RUN apk add --no-cache --update git
      
      WORKDIR /go/src/api
      COPY . .
      
      RUN go get -d -v 
        && go install -v 
        && go build
      
      ##
      
      FROM alpine:3.8
      COPY --from=multistage /go/bin/api /go/bin/
      EXPOSE 3000
      CMD ["/go/bin/api"]
      

      Salve e feche o arquivo. Aqui você tem dois comandos FROM. O primeiro é idêntico ao Dockerfile.golang-alpine, exceto por ter um AS multistage adicional no comando FROM. Isto lhe dará um nome de multistage, que você irá referenciar na parte inferior do arquivo Dockerfile.multistage. No segundo comando FROM, você pegará uma imagem base alpine e copiará para dentro dela usando o COPY, a aplicação Go compilada da imagem multiestage. Esse processo reduzirá ainda mais o tamanho da imagem final, tornando-a pronta para produção.

      Execute a compilação com o seguinte comando:

      • docker build -f Dockerfile.multistage -t prod .

      Verifique o tamanho da imagem agora, depois de usar uma compilação multi-stage.

      Você encontrará duas novas imagens em vez de apenas uma:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE prod latest 82fc005abc40 38 seconds ago 11.3MB <none> <none> d7855c8f8280 38 seconds ago 294MB . . .

      A imagem <none> é a imagem multistage construída com o comando FROM golang:1.10-alpine3.8 AS multistage. Ela é apenas um intermediário usado para construir e compilar a aplicação Go, enquanto a imagem prod neste contexto é a imagem final que contém apenas a aplicação Go compilada.

      A partir dos 744MB iniciais, você reduziu o tamanho da imagem para aproximadamente 11,3MB. Manter o controle de uma imagem minúscula como esta e enviá-la pela rede para os servidores de produção será muito mais fácil do que com uma imagem de mais de 700MB e economizará recursos significativos a longo prazo.

      Conclusão

      Neste tutorial, você otimizou as imagens Docker para produção usando diferentes imagens Docker de base e uma imagem intermediária para compilar e construir o código. Dessa forma, você empacotou sua API de exemplo no menor tamanho possível. Você pode usar essas técnicas para melhorar a velocidade de compilação e deployment de suas aplicações Docker e de qualquer pipeline de CI/CD que você possa ter.

      Se você estiver interessado em aprender mais sobre como criar aplicações com o Docker, confira o nosso tutorial Como Construir uma Aplicação Node.js com o Docker. Para obter informações mais conceituais sobre como otimizar containers, consulte Building Optimized Containers for Kubernetes.



      Source link