Início
Versões
Imagens
Inicializando o banco
Rodando comando MySQL em containers
Variáveis de Ambiente
Ponto de montagem de Volumes
Alterando senhas
Criando um banco a partir de um template
Usando replicação MySQL
Criando o Deployment Config para o MySQL master
Criando um Headless Service
Escalando MySQL slaves
Troubleshooting
Linux Native AIO Failure
Início
O OpenShift fornece uma imagem Docker para rodar MySQL. Esta imagem provê serviços de banco baseado no usuário e senha fornecidos pela configuração.
Versões
A versão atual que o OpenShift suporta do MySQL é a 5.5 e 5.6
Imagens
Estas imagens estão disponíveis na distribuição CentOS 7:
Imagens baseadas em CentOS 7
Esta imagem está disponível no DockerHub. Para fazer download:
$ docker pull openshift/mysql-55-centos7
$ docker pull centos/mysql-56-centos7
Para usar essa imagem, você pode acessa-las diretamente através desseregistro de imagens, ou enviar para seu registro OpenShift Docker. Adicionalmente, você pode criar uma image stream que aponte para a imagem, no seu registro Docker ou numa localização externa. Os recursos do seu OpenShift podem agora fazer referencia ao ImageStream. Você pode encontrarexemplo de definições de image streams para todas as imagens do OpenShift.
Inicializando o banco
A primeira vez que você usa o volume compartilhar, a base é criada utilizando o usuário administrador (se você especificar a variável MYSQL_ROOT_PASSWORD). Depois disso o daemon do MySQL inicia. Se você esta montando o volume em outro container, então a base, usuário da base e o usuário administrador não são criados e então o MySQL inicia.
O comando a seguir cria um novo pod com o banco e o MySQL executando no container:
$ oc new-app -e MYSQL_USER=<username>,MYSQL_PASSWORD=<password>,MYSQL_DATABASE=<database_name> centos/mysql-55-centos7
Rodando comando MySQL em containers
O OpenShift utiliza Software Collections(SCLs) para instalar e iniciar o MySQL. Se você quer executar algum comando MySQL dentro de um container em execução(para debug), você deve executar usando o bash.
Para fazer isso, primeiro identifique o nome do pod que esta rodando o MySQL. Por exemplo, você pode ver a lista de pods no seu projeto ao executar:
$ oc get pods
Então conecte no pod com o seguinte comando:
$ oc rsh <pod>
Quando você logar no container, a SCL é automaticamente ativada.
Você pode agora rodar o comando mysql a partir do bash para iniciar uma sessão interativa do MySQL e executar operações do MySQL. Exemplo, para autenticar com o usuário da base:
bash-4.2$ mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -h $HOSTNAME $MYSQL_DATABASE
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.37 MySQL Community Server (GPL)
...
mysql>
Quando finalizado, entre com quit ou exit para fazer logout da sessão do MySQL.
Variáveis de Ambiente
O usuário do MySQL, senha e nome da base devem ser configurados com as seguintes variáveis de ambiente:
Tabela 1. Variáveis de ambiente do MySQL
Nome da Variável | Descrição |
MYSQL_USER | Especifique o nome do usuário da base a ser criado para uso da sua aplicação. |
MYSQL_PASSWORD | Senha para o MYSQL_USER. |
MYSQL_DATABASE | Nome da base que o MYSQL_USER tem acesso total. |
MYSQL_ROOT_PASSWORD | Senha opcional para o usuário root. Se não for setada, então logins remotos utilizando a conta root não será possível. Conexões locais a partir do container é sempre permitida sem senha. |
![]() |
Você deve especificar usuário, senha e nome da base. Se você não especificar os três, o pod vai falhar para iniciar e o OpenShift vai ficar num loop tentando reiniciar. |
As configurações do MySQL podem ser configuradas com as seguintes variáveis de ambiente:
Tabela 2. Configurações adicionais do MySQL
Nome da Variável | Descrição | Default |
MYSQL_LOWER_CASE_TABLE_NAMES | Define como os nomes das tabelas são armazenados. | 0 |
MYSQL_MAX_CONNECTIONS | O número máximo de conexões simultaneas. | 151 |
MYSQL_MAX_ALLOWED_PACKET | O tamanho máximo de um pacote ou string. | 200M |
MYSQL_FT_MIN_WORD_LEN | O número mínimo de caracteres a ser incluído em um index FULLTEXT. | 4 |
MYSQL_FT_MAX_WORD_LEN | O número máximo de caracteres a ser incluído em um index FULLTEXT. | 20 |
MYSQL_AIO | Controla o valor de innodb_use_native_aio se o AIO nativo estiver quebrado. | 1 |
MYSQL_TABLE_OPEN_CACHE | O número de tabelas abertas para os threads. | 400 |
MYSQL_KEY_BUFFER_SIZE | O tamanho do buffer usado pelos index blocks. | 32M(ou 10% da memória disponível) |
MYSQL_SORT_BUFFER_SIZE | O tamanho do buffer usado para sorting. | 256K |
MYSQL_READ_BUFFER_SIZE | O tamnho do buffer usado para um scan sequencial. | 8M(ou 5% da memória disponível) |
MYSQL_INNODB_BUFFER_POOL_SIZE | O tamanho do buffer pool onde o InnoDB faz cache da tabela e indexa os dados. | 32M(ou 50% da memória disponível) |
MYSQL_INNODB_LOG_FILE_SIZE | O tamanho de cada arquivo de log em um grupo de logs. | 8M(ou 15% da memória disponível) |
MYSQL_INNODB_LOG_BUFFER_SIZER | O tamanho do buffer que o InnoDB usa para escrever arquivos de log no disco. | 8M(ou 15% da memória disponível) |
Alguns dos parâmetros de memória listados tem dois valores default. O valor fixado é usado quando um container não tem limites de memória atribuído. O outro valor é calculado dinamicamente durante a inicialização do container, baseado na memória disponível.
Ponto de montagem de Volumes
A imagem do MySQL pode ser executada com volumes montados, para habilitar persistent storage para o banco:
- /var/lib/mysql/data - Este é o diretório onde o MySQL armazena os arquivos do banco.
Alterando senhas
As senhas são parte da configuração da imagem, entretanto o único meio de alterar senhas para o usuário do banco(MYSQL_USER) e usuário root, é ao alterar as variáveis de ambiente MYSQL_PASSWORD e MYSQL_ROOT_PASSWORD respectivamente.
Você pode ver as senhas atuais no pod ou no deployment config do console web ou ao listar as variáveis de ambiente na CLI:
$ oc env pod <pod_name> --list
Sempre que MYSQL_ROOT_PASSWORD for definida, vai habilitar acesso remoto para o usuário root com a devida senha e sempre que não definida o acesso remoto para o usuário root é desabilitado. Isso não afeta o usuário MYSQL_USER, que sempre tem acesso remoto. Isso também não afeta o acesso local pelo usuário root, que sempre pode logar sem senha no localhost.
Alterar a senha do banco através do comandos SQL ou qualquer outro meio que não seja através das variáveis de ambiente vai causar um erro de configuração entre os valores armazenados nas variáveis e as senhas atuais. Sempre que um container de banco for iniciado, ele reseta as senhas e define os valores setados nas variáveis de ambiente.
Para alterar estas senhas, atualize uma ou ambas das variáveis de ambiente designadas no deployment config, usando o comando oc env. Se múltiplos deployment configs utilizam estas variáveis, por exemplo no caso de uma aplicação criada a partir de um template, você deve atualizar as variáveis em cada deployment config para que as senhas sejam sincronizadas em todo lugas. Isso pode ser feito em um único comando:
$ oc env dc <dc_name> [<dc_name_2> ...] MYSQL_PASSWORD=<new_password> MYSQL_ROOT_PASSWORD=<new_root_password>
![]() |
Dependendo da sua aplicação, talvez tenha outras variáveis de ambiente para senhas em outras partes da aplicação que também devem ser atualizadas. Exemplo, pode ter uma variável mais genérica DATABASE_USER em um pod front-end que deve sempre fazer um match com a senha do usuário do banco. Tenha certeza que as senhas foram sincronizadas em todas as variáveis de ambiente de suas aplicações, se não seus pods podem falhar numa trigger de redeploy. |
Atualizar as variáveis de ambiente, acionam o redeployment do banco no servidor se você tiver uma trigger de alteração de configuração. Em outro caso, você deve iniciar manualmente um novo deployment para aplicar as alterações de senhas.
Para verificar se as novas senhas estão funcionando, primeiro abra uma sessão ao pod que esta rodando o MySQL:
$ oc rsh <pod>
A partir do bash, verifique a nova senha do usuário:
bash-4.2$ mysql -u $MYSQL_USER -p<new_password> -h $HOSTNAME $MYSQL_DATABASE -te "SELECT * FROM (SELECT database()) db CROSS JOIN (SELECT user()) u"
Se a senha foi alterada corretamente, você deve ver uma tabela igual a essa:
+------------+---------------------+
| database() | user() |
+------------+---------------------+
| sampledb | user0PG@172.17.42.1 |
+------------+---------------------+
Para verificar a senha do root:
bash-4.2$ mysql -u root -p<new_root_password> -h $MYSQL_DATABASE -te "SELECT * FROM (SELECT database()) db CROSS JOIN (SELECT user()) u"
Se a senha foi alterada corretamente, você deve ver uma tabela igual a essa:
+------------+---------------------+
| database() | user() |
+------------+---------------------+
| sampledb | root@172.17.42.1 |
+------------+---------------------+
Criando um banco a partir de um template
O OpenShift fornece um template que torna mais fácil a tarefa de criar um novo serviço de banco. O template fornece parâmetros para definir todas as variáveis de ambiente(usuário, senha, nome da base, etc) com valores default incluindo a criação de senhas aleatórias. Também define o deployment config e o service.
Os templates do MySQL devem ter sido registrados no projeto default do openshift pelo administrador do cluster durante o setup inicial. Veja carregando default image streams e templates para mais detalhes.
O template disponível:
- mysql-persistent utiliza um volume persistente para armazenar os dados do banco, o que significa que os dados vão sobreviver a um restart do pod. Usando volumes persistente requer que um pool seja definido no deployment do OpenShift.
Você pode encontrar instruções para instanciar templates nessa página.
Assim que você instanciou um serviço, você pode copiar o usuário, senha, nome da base e variáveis de ambiente dentro de um deployment config para outro componente que tenta acessar a base. Esse componente pode ser acessado pelo banco via service que foi definido.
Usando replicação MySQL
![]() |
O suporte de replicação fornecido pela imagem do MySQL é experimental e não deve ser usado em produção. |
Exemplo, para fazer upload do template de exemplo no projeto atual:
$ oc create -f https://raw.githubusercontent.com/openshift/mysql/master/5.5/examples/replica/mysql-replica.json
A seguinte seção detalha os objetos definidos no template de exemplo e descreve como eles trabalham em conjunto para iniciar um cluster de servidores MySQL implementando master-slave replication e failover. Essa é a strategy recomendada para replicação do MySQL.
Criando o Deployment Config para o MySQL master
Para configurar a replicação do MySQL, o deployment config é definido no template de exemplo que define um controlador de replicação. Para uma replicação MySQL master-slave, dois deployment config são necessários. Um deployment config define o MySQL master servers e o segundo define o MySQL slave servers.
Para dizer a um servidor MySQL para ser um master, o campo command no deployment config deve ser definido para run-mysqld-master. Esse script funciona como um entrypoint para a imagem do MySQL e configura o servidor MySQL para rodar como um master na replicação:
Nome da Variável | Descrição | Default |
MYSQL_MASTER_USER | O nome do usuário de replicação. | master |
MYSQL_MASTER_PASSWORD | A senha para o usuário de replicação | generated |
Exemplo 1. Definição do Objeto MySQL Master no deployment config no template de exemplo
{
"kind":"DeploymentConfig",
"apiVersion":"v1",
"metadata":{
"name":"mysql-master"
},
"spec":{
"strategy":{
"type":"Recreate"
},
"triggers":[
{
"type":"ConfigChange"
}
],
"replicas":1,
"selector":{
"name":"mysql-master"
},
"template":{
"metadata":{
"labels":{
"name":"mysql-master"
}
},
"spec":{
"volumes":[
{
"name":"mysql-master-data",
"persistentVolumeClaim":{
"claimName":"mysql-master"
}
}
],
"containers":[
{
"name":"server",
"image":"openshift/mysql-55-centos7",
"command":[
"run-mysqld-master"
],
"ports":[
{
"containerPort":3306,
"protocol":"TCP"
}
],
"env":[
{
"name":"MYSQL_MASTER_USER",
"value":"${MYSQL_MASTER_USER}"
},
{
"name":"MYSQL_MASTER_PASSWORD",
"value":"${MYSQL_MASTER_PASSWORD}"
},
{
"name":"MYSQL_USER",
"value":"${MYSQL_USER}"
},
{
"name":"MYSQL_PASSWORD",
"value":"${MYSQL_PASSWORD}"
},
{
"name":"MYSQL_DATABASE",
"value":"${MYSQL_DATABASE}"
},
{
"name":"MYSQL_ROOT_PASSWORD",
"value":"${MYSQL_ROOT_PASSWORD}"
}
],
"volumeMounts":[
{
"name":"mysql-master-data",
"mountPath":"/var/lib/mysql/data"
}
],
"resources":{
},
"terminationMessagePath":"/dev/termination-log",
"imagePullPolicy":"IfNotPresent",
"securityContext":{
"capabilities":{
},
"privileged":false
}
}
],
"restartPolicy":"Always",
"dnsPolicy":"ClusterFirst"
}
}
}
}
Desde que reivindicamos um volume persistente no deployment config para ter todos os dados salvos no servidor MySQL master, você deve solicitar ao administrador do cluster para criar um volume persistente para que você possa utilizar.
Depois que o deployment config é criado e o pod com o servidor MySQL master é iniciado, isso vai criar a base definida por MYSQL_DATABASE e configurar o servidor para replicar essa base para os servidores slaves.
O exemplo fornecido define somente uma replica do MySQL master server. Isso diz ao OpenShift para iniciar apenas uma instância do servidor. Múltiplas instancias(multi-master) não é suportada e portanto você não pode escalar esse controlador de replicação.
Para replicar a base criada pelo MySQL master, o deployment config deve ser definido no template. Esse deployment config cria um controlador de replicação que inicia a imagem MySQL com o campo command setado para run-mysqld-slave. Essa alternativa o entrypoint pula a inicialização da base e configura o MySQL server para conectar ao service mysql-master, que é também definido no template de exemplo.
Exemplo 2. Definição do Objeto MySQL Slave no deployment config no template de exemplo
{
"kind":"DeploymentConfig",
"apiVersion":"v1",
"metadata":{
"name":"mysql-slave"
},
"spec":{
"strategy":{
"type":"Recreate"
},
"triggers":[
{
"type":"ConfigChange"
}
],
"replicas":1,
"selector":{
"name":"mysql-slave"
},
"template":{
"metadata":{
"labels":{
"name":"mysql-slave"
}
},
"spec":{
"containers":[
{
"name":"server",
"image":"openshift/mysql-55-centos7",
"command":[
"run-mysqld-slave"
],
"ports":[
{
"containerPort":3306,
"protocol":"TCP"
}
],
"env":[
{
"name":"MYSQL_MASTER_USER",
"value":"${MYSQL_MASTER_USER}"
},
{
"name":"MYSQL_MASTER_PASSWORD",
"value":"${MYSQL_MASTER_PASSWORD}"
},
{
"name":"MYSQL_DATABASE",
"value":"${MYSQL_DATABASE}"
}
],
"resources":{
},
"terminationMessagePath":"/dev/termination-log",
"imagePullPolicy":"IfNotPresent",
"securityContext":{
"capabilities":{
},
"privileged":false
}
}
],
"restartPolicy":"Always",
"dnsPolicy":"ClusterFirst"
}
}
}
}
Este exemplo do deployment config, inicia o controlador de replicação com o número inicial de replicas setado em 1. Você pode escalar o controlador de replicação em ambas as direções, até a capacidade de recursos da sua conta.
Se o master ou qualquer um dos slaves cair, o OpenShift vai subir eles novamente. O master vai reutilizar o volume persistente, enquanto qualquer slave que foi reiniciado vai replicar os dados a partir do master.
Criando um Headless Service
Os pods criados pelo controlador de replicação do MySQL slave devem alcançar o master server para que possam registrar para a replicação. O template de exemplo define um headless service mysql-master para este propósito. O serviço não é usado apenas para a replicação, mas os clientes podem também enviar queries para o host mysql-master:3306.
Para ter um headless service, o parâmetro portalIP na definição do service é setado para None. Então você pode usar uma query DNS para conseguir uma lsita dos IP's dos pods que representam o endpoint para esse serviço.
Exemplo 3. Definição do objeto Headless Service no template de exemplo
{
"kind":"Service",
"apiVersion":"v1",
"metadata":{
"name":"mysql-master",
"labels":{
"name":"mysql-master"
}
},
"spec":{
"ports":[
{
"protocol":"TCP",
"port":3306,
"targetPort":3306,
"nodePort":0
}
],
"selector":{
"name":"mysql-master"
},
"portalIP":"None",
"type":"ClusterIP",
"sessionAffinity":"None"
},
"status":{
"loadBalancer":{
}
}
}
Escalando MySQL slaves
Para incrementar o número de membros no cluster:
$ oc scale rc mysql-slave-1 --replicas=<number>
Isso diz ao controlador de replicação para criar um pod do MySQL slave. Quando um slave é criado, primeiro tenta se comunicar com o serviço mysql-master e se registrar no set de replicação. Assim que isso for feito, o MySQL master server envia a base ao slave.
Quando estiver fazendo o scaling down, o MySQL slave é desligado, isso por que o slave não tem um storage persistente definido e todos os dados são perdidos. O MySQL server então percebe que o slave não esta mais acessível e remove automaticamente da aplicação.
Troubleshooting
Essa seção descreve alguns problemas que você pode ter e apresenta algumas possíveis soluções.
Linux Native AIO Failure
Sintoma
O container de MySQL falha para iniciar e os logs mostram algo como:
151113 5:06:56 InnoDB: Using Linux native AIO
151113 5:06:56 InnoDB: Warning: io_setup() failed with EAGAIN. Will make 5 attempts before giving up.
InnoDB: Warning: io_setup() attempt 1 failed.
InnoDB: Warning: io_setup() attempt 2 failed.
Waiting for MySQL to start ...
InnoDB: Warning: io_setup() attempt 3 failed.
InnoDB: Warning: io_setup() attempt 4 failed.
Waiting for MySQL to start ...
InnoDB: Warning: io_setup() attempt 5 failed.
151113 5:06:59 InnoDB: Error: io_setup() failed with EAGAIN after 5 attempts.
InnoDB: You can disable Linux Native AIO by setting innodb_use_native_aio = 0 in my.cnf
151113 5:06:59 InnoDB: Fatal error: cannot initialize AIO sub-system
151113 5:06:59 [ERROR] Plugin 'InnoDB' init function returned error.
151113 5:06:59 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
151113 5:06:59 [ERROR] Unknown/unsupported storage engine: InnoDB
151113 5:06:59 [ERROR] Aborting
Explicação
O MySQL storage engine foi incapaz de usar a facilitie kernel's AIO(Asynchronous I/O) devido aos limites de recursos.
Resolução
- Desabilite o uso do AIO, ao definir o valor da variável de ambiente MYSQL_AIO para 0. Nos deployments subsequentes garante que a configuração da variável de ambiente innodb_use_native_aio tenha o valor 0.
- Incremente o valor do aio-max-nr do kernel. O exemplo a seguir examina o valor atual de aio-max-nr e dobra o valor.
$ sysctl fs.aio-max-nr
fs.aio-max-nr = 1048576
# sysctl -w fs.aio-max-nr=2097152
Isso é uma solução temporária que é apagada até o próximo reboot do node.
Comentários
0 comentário
Por favor, entre para comentar.