segunda-feira, 23 de novembro de 2015

Docker na prática - Mysql

Não vou perder tempo explicando o que é o docker ou pra que server o docker vamos para parte prática.

Docker - https://www.docker.com/

Instalação no Linux: http://docs.docker.com/linux/step_one/

Depois do docker instalado vamos a um exemplo prático.

Resolvi substituir alguns serviços da minha minha máquina e usar o docker e o primeiro serviço foi o MySql:

Instalando a imagem do MySql:

sudo docker pull mysql     - baixa o docker (imagem) com mysql


O parâmetro  "pull" irá baixar a imagem "mysql" dos repositório do docker, https://hub.docker.com/_/mysql/

sudo docker images       - Listas as imagens baixadas/criadas na máquina

O resultado fica assim:

ubuntu@ubuntu:~$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mysql                     latest              c29b1276a98a        12 days ago         359.8 MB
ubuntu@ubuntu:~$




Agora vamos cria o container para usar o mysql, em resumo o container nada mais é do que uma instancia real da imagem, o container usa a imagem instalada e aplica as configurações para que o serviço ou servidor funcione. Podemos ter vários container de uma unica imagem e cada container tem sua funcionalidade.

Como exemplo irei criar 2 servidores mysql, serão 2 container:

1 - Servidor mysql com ip próprio:

sudo docker run --name mymysql -e MYSQL_ROOT_PASSWORD=root1 -d mysql


Parâmetros:

run       - executa a imagem criando um container
--name  - da uma nome para o container
mymysql - nome do container fica a critério da pessoal
-e          - setando variaveis de ambiente no exemplo acima estamos setando a variavel MYSQL_ROOT_PASSWORD
 -d         - deixa o container rodando em background
 mysql   - neste exemplo é nome da imagem no repositório que baixar anteriormente

Para ver se o container esta rodando:

sudo docker ps  


O resultado fica assim:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
aed91beee6fe        mysql               "/entrypoint.sh mysql"   3 days ago          Up 5 seconds        3306/tcp                 mymysql




Agora temos um servidor de MySql rodando no docker vamos pegar o ip para podemos usar na nossa aplicação:

sudo docker inspect aed91beee6fe


Parâmetros:

inspect            -  returna informações do container e da imagem
aed91beee6fe - Id do container, cada container tem um id próprio

ubuntu@ubuntu-Aspire-E1-571:~$ sudo docker inspect aed
[
{
    "Id": "aed91beee6fe517d6358a39a0ba0b02c2daec2a4f2c393405ccba451b446130b",
    "Created": "2015-11-20T02:26:58.154562367Z",
    "Path": "/entrypoint.sh",
    "Args": [
        "mysqld"
    ],
    "State": {
        "Status": "running",
        "Running": true,
        "Paused": false,
        "Restarting": false,
        "OOMKilled": false,
        "Dead": false,
        "Pid": 13163,
        "ExitCode": 0,
        "Error": "",
        "StartedAt": "2015-11-23T13:07:50.033191231Z",
        "FinishedAt": "2015-11-20T16:28:28.493679426Z"
    },
   

 ...........,
    "Mounts": [
        {
            "Name": "4dcf2234e155ef26d1f22e0279634b7594b6cfa18af4b04f7c6afe3f699e131a",
            "Source": "/var/lib/docker/volumes/4dcf2234e155ef26d1f22e0279634b7594b6cfa18af4b04f7c6afe3f699e131a/_data",
            "Destination": "/var/lib/mysql",
            "Driver": "local",
            "Mode": "",
            "RW": true
        }
    ],
    "Config": {
        "Hostname": "aed91beee6fe",
        "Domainname": "",
        "User": "",
        "AttachStdin": false,
        "AttachStdout": false,
        "AttachStderr": false,
        "ExposedPorts": {
            "3306/tcp": {}
        },
        "Tty": false,
        "OpenStdin": false,
        "StdinOnce": false,
        "Env": [
            "MYSQL_ROOT_PASSWORD=root6Beer",
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "MYSQL_MAJOR=5.7",
            "MYSQL_VERSION=5.7.9-1debian8"
        ],
        "Cmd": [
            "mysqld"
        ],
        "Image": "mysql",
        "Volumes": {
            "/var/lib/mysql": {}
        },
        "WorkingDir": "",
        "Entrypoint": [
            "/entrypoint.sh"
        ],
        "OnBuild": null,
        "Labels": {},
        "StopSignal": "SIGTERM"
    },
    "NetworkSettings": {
        "Bridge": "",
        "SandboxID": "5e68cbcf0e18acad52ca101565fcc9df5b137a89ca018ac351cf9a14975d9344",
        "HairpinMode": false,
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "Ports": {
            "3306/tcp": null
        },
        "SandboxKey": "/var/run/docker/netns/5e68cbcf0e18",
        "SecondaryIPAddresses": null,
        "SecondaryIPv6Addresses": null,
        "EndpointID": "71d73085e4009639f332caf43689e3ba6b3331c8148a1105922b4d797adb0eff",
        "Gateway": "172.17.0.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "172.17.0.3",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "MacAddress": "02:42:ac:11:00:03",
        "Networks": {
            "bridge": {
                "EndpointID": "71d73085e4009639f332caf43689e3ba6b3331c8148a1105922b4d797adb0eff",
                "Gateway": "172.17.0.1",
                "IPAddress": "172.17.0.3",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "02:42:ac:11:00:03"
            }
        }
    }
}
]
ubuntu@ubuntu:~$



Ficando assim os dados para conexão com o banco e pode ser usando em qualquer aplicação:

hostname: 172.17.0.3  Port: 3306 User: root  Password: root1


Agora vamos a outro exemplo, no exemplo acima criei uma servidor com um ip próprio, mas existe uma opção para usarmos como se fosse localhost vamos ao exemplo:

sudo docker run -p 3306:3306 --name mymysql2 -e MYSQL_ROOT_PASSWORD=root1 -d mysql

Como podemos ver o que difere é o parâmetro 3306:3306 aqui estamos expondo a porta 3306 do container que será acessada também pela porta 3306 do localhost.

Ficando assim para conexão com o banco:

hostname: localhost  Port: 3306 User: root  Password: root1


E temos dois servidores de banco rodando na nossa maquina, um em cada container criado:

 ubuntu@ubuntu:~$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
52d08d09e575        mysql               "/entrypoint.sh mysql"   3 days ago          Up 21 hours         0.0.0.0:3306->3306/tcp   mymysql2
aed91beee6fe        mysql               "/entrypoint.sh mysql"   3 days ago          Up 46 minutes       3306/tcp                 mymysql
ubuntu@ubuntu:~$






quinta-feira, 3 de setembro de 2015

Criando um lib em c para ser usada no Python

Shared Objects no Python

Como gosto muito de escrever em python resolvi fazer algo parecido com o post anterior só que desta vez o python acessando uma lib em c.
Eu utilizei o modulo ctypes. O módulo ctypes provê a compatibilidade dos tipos de dados em C permitindo chamar bibliotecas, como por exemplo DDLs e shared objects.


Git:   https://github.com/crleal/python_com_c  

1 - Programa exemplo em c:

HelloWorld.c
1:  #include   
2:     
3:    double HelloWorld_dobro (int x)
4:    {
5:         printf("Metodo dobro!\n");
6:         return x * 2;
7:    }
8:    
9:    int somar(int n, int m)
10:    {
11:         return n + m;
12:    }  


2 - Compilando o HelloWorld.c:

1:  gcc -Wall HelloWorld.c -shared -fPIC -o HelloWorld_lib.so


3 - Programa em Python:


HelloWorld.py
1:  #!/usr/bin/env python
2:  
3:  import os
4:  import ctypes
5:  
6:  # Carrega a lib para uma variavel 
7:  libLocal = ctypes.CDLL("./HelloWorld_lib.so")
8:  
9:  print("A soma dos numeros:")
10:  
11:  # chama os metodos dentro da lib
12:  print(libLocal.somar(5, 6))
13:  print(libLocal.HelloWorld_dobro (5))  


4 - Executando o python:

1:  Python HelloWorld.py

Resultado:
 A soma dos numeros: 11 
 Metodo dobro! 10 

sexta-feira, 7 de agosto de 2015

Criando um lib em c para ser usada no Java

Eu precisei fazer uma rotina que integrasse uma lib em c com java. Abaixo mostrarei um passo-a-passo sem entrar muito em detalhes como consegui realizar isso.


Git:   https://github.com/crleal/java_com_c  

1 - Programa exemplo em java:

HelloWorld.java
1:  class HelloWorld {  
2:     //Le a lib em C  
3:     static {  
4:       System.loadLibrary("HelloWorld");  
5:     }  
6:       
7:     // declara os metodos que serão chamados na lib em "c"   
8:     private native void print();  
9:     private native double dobro(double x);  
10:    
11:     public static void main(String[] args) {  
12:       // Executa um metodo "c"  
13:       new HelloWorld().print();  
14:       // Chama um metodo passando parametro e retornando um valor  
15:       double valor = new HelloWorld().dobro(3);  
16:       System.out.printf("O dobro de 3 é: "+String.valueOf(valor));  
17:     }  
18:  }  


2 - Compile o código para ver se não tem erro:

1:  javac HelloWorld.java  


3 - Gerar HelloWorld.h :

1:    javah -jni HelloWorld  

Irá criar o arquivo:

HelloWorld.h
1:  /* DO NOT EDIT THIS FILE - it is machine generated */  
2:  #include <jni.h>  
3:  /* Header for class HelloWorld */  
4:    
5:  #ifndef _Included_HelloWorld  
6:  #define _Included_HelloWorld  
7:  #ifdef __cplusplus  
8:  extern "C" {  
9:  #endif  
10:  /*  
11:   * Class:   HelloWorld  
12:   * Method:  print  
13:   * Signature: ()V  
14:   */  
15:  JNIEXPORT void JNICALL Java_HelloWorld_print  
16:   (JNIEnv *, jobject);  
17:    
18:  /*  
19:   * Class:   HelloWorld  
20:   * Method:  dobro  
21:   * Signature: (D)D  
22:   */  
23:  JNIEXPORT jdouble JNICALL Java_HelloWorld_dobro  
24:   (JNIEnv *, jobject, jdouble);  
25:    
26:  #ifdef __cplusplus  
27:  }  
28:  #endif  
29:  #endif  


4 - Programa exemplo em c:

 HelloWorld.c
1:  #include <jni.h>  
2:  #include <stdio.h>  
3:  #include "HelloWorld.h"  
4:     
5:  JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *env, jobject obj)  
6:  {  
7:     printf("Hello World!\n");  
8:     return;  
9:  }  
10:    
11:  JNIEXPORT double JNICALL Java_HelloWorld_dobro (JNIEnv *env, jobject obj, jdouble x)  
12:  {  
13:     printf("Metodo dobro!\n");  
14:     return x * 2;  
15:  }  


5 - Compilando o HelloWorld.c:

1:  gcc  -I/usr/lib/jvm/java-8-oracle/include -I/usr/lib/jvm/java-8-oracle/include/linux -c -Wall -Werror -fpic HelloWorld.c  

Irá criar o arquivo: HelloWorld.o


6 - Gerando a lib:

1:  gcc -shared -o libHelloWorld.so HelloWorld.o  

Irá criar o arquivo: libHelloWorld.so


7 - Executando o java:

1:  java -Djava.library.path=. HelloWorld  

Resultado:
 Hello World!  
 Metodo dobro!  
 O dobro de 3 é: 6.0