Implantar um pod no kubernetes para quem não é familiarizado pode ser um grande desafio. Os profissionais de desenvolvimento, que por vezes ficam distantes de cenários como esse, perdem tempo dando voltas e cometendo erros bobos. Esse artigo é um guia para a criação de um deployment de wordpress com mysql do zero até o uso em produção no google cloud platform. O nome do artigo é Kubernetes e o deployment quase perfeito por que optamos pode priorizar alguns pontos específicos que serão explicados ao longo do artigo.
Sumário
Instalando wordpress no kubernetes
Fazer um deploy no kubernetes é muito mais do que simplesmente criar um deployment e um service. Tentei com esse artigo explorar uma implantação completa, considerando a exposição externa num Loadbalancer, a instalação do Ingress, a configuração do TLS (SSL), configuração dos services, hpa, etc. É fundamental para o correto entendimento do artigo o uso do repositório https://github.com/Anselming/kube-wordpress-mysql onde você encontra todos os arquivos yaml.
A instalação de uma aplicação cloud-native exige uma grande quantidade de características particulares. Costumo dizer que assim como: em algum momento no passado foi necessário entender o conceito de sistema de arquivos, processos, endereçamento de memória, etc.; agora temos que entender healthchecks, ingress, escalabilidade em stateless services, service discoveries, etc.
Fica claro que vamos lidar com muitos assuntos diferentes, alguns mais e outros menos complexos. Por conta disso escolhi não abordar alguns temas por serem mais profundos e terem um direcionamento para a parte de OPS. Isso faz com que seja uma conversa sobre o Kubernetes e o deployment quase perfeito. De todo modo esse artigo é útil tanto para as áreas de DEV quanto de OPS.
A pasta ./general/
Todo começa pelo namespace app-wordpress. Nada de muito especial é feito para esse namespace, mas tudo gira ao redor desse nome. Já o ClusterIssuer é algo mais interessante: através dele o cluster tem a possibilidade de ter certificado digitais associados aos seus sites. Para que isso seja possível é obrigatório a instalação do Cert-manager (para instalar consulte 10 ferramentas mais utilizadas no kubernetes). O Cluster Issuer em questão aponta para o Ingress-Nginx que efetivamente se HTTP expõe para fora.
Após os pontos anteriores do namespace e do ClusterIssuer, há a configuração final do Ingress. Essa estrutura tem uns gatilhos para forçar que as chamadas HTTP se tornem HTTPS e garante que as chamadas para os sites ali configurados renovem seus certificados automaticamente. Isso é realmente muito bom!
A pasta ./mysql/
Vamos começar pelo workload: há um statefulset para o mysql. Esse workload suporta réplicas ordenadas (mysql-0, mysql-1, mysql-2, …), algo especialmente útil para situações como a de clusters de banco de dados no estilo arquitetural master-slave. Todos os nós slave conseguem ver o nó master por ter um URL sempre igual (o indice zero do statefulset: mysql-0 no caso). O nó master, em específico, tem um headless service, que dá a ele um CNAME válido para utilização no cluster.
Labels recomendados
Esse statefulset é bastante rico em detalhes: outra parte relevante é a aplicação de labels pré-definidos. Os labels name, instance, version, component, part-of e managed-by são definidos pela própria kubernetes através desse link https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/. Além disso há alguns labels que são amplamente utilizados pela comunidade: tais como enviroment, confidenciality e compliance.
Horizontal pod autoscaler
Há nesse mesmo statefulset a restrição de recursos. Isso é algo fundamental para saber, por um lado, qual é o mínimo que o cluster vai consumir de recursos com a aplicação no ar e qual é o máximo que ela vai gastar. Um Horizontal pod autoscaler (HPA) foi configurado no mysql para lidar com tal possibilidade de crescimento.
Gerenciamento de configuração: configmap e secret
Outro ponto relevante é o gerenciamento das configurações: há um configmap indicando o nome do banco de dados que ele criará para o wordpress; e há também um secret indicando o nome do usuário (do banco do wordpress), o password e o password do root do mysql.
Probes: Startup Probe, Liveness Probe e Readiness Probe
Há também uma estrutura de probes para observar a disponibilidade do pod e garantir que ele:
- 1 – O pod somente está apto a receber tráfego se realmente estiver ponto para isso, através do Startup Probe.
- 2 – Caso o pod não consiga se conectar TCP na porta 3306 (padrão), ele impeça o tráfego, através do Readiness Probe
- 3 – Caso ocorra o cenário 2 por um tempo maior o pod é reiniciado automaticamente, através do Liveness Probe
Volumes
O último ponto a destacar do statefulset é o uso de volumes. Esse é ,talvez, o ponto mais importante desse pod por ser um banco de dados. Note que há um storageclass que indica a relação entre o kubernetes e o Google Cloud (no caso em específico é o google mas poderia apontar para outros tipos de volume). E note também que há um PersistentVolumeClaim (PVC) que oferece 10Gi de storage a cada solicitação bem sucedida. Caso o HPA crie novas intâncias do pod o PVC criará novos volumes automaticamente.
Uso em alta escala
Embora essa estrutura esteja feita para lidar com escala observe que o storage do google é ReadWriteOnly. Ele é mais rápido entretanto não vai funcionar caso um pode seja criado em outros nodes do cluster de k8s. Para o cenário em questão eu não configurei afinidade do pod, mas seria obrigatório nesse caso. Para casos como esse é necessário cogitar o uso de outro storage que suporte READWRITEMANY ou mesmo não utilizar banco de dados no kubernetes. São decisões arquiteturais que dependem de cada negócio.
A pasta ./wordpress/
A pasta wordpress é bastante semelhante a mysql com a principal diferença de que o wp depende da existência prévia do banco de dados. Mas há outras pequenas diferenças que vale comentar:
- O service possui um ‘externalName’, útil para que seja possível ser exposto através do Ingress
- O secret tem o nome nome do usuário e senha do mysql
- O workload do wordpress é um deployment e não um statefulset
- O deployment verifica se a rota HTTP ‘/’ é acessível, ao contrário do mysql que verifica se é possível fazer conexão TCP
Uso em alta escala
Embora todo o ambiente tenha sido estruturado para funcionar em alta escala notei um comportamento indesejado. Quando o cluster possui apenas um pod de wordpress tudo funcionada corretamente. Mas quando tenho mais do que um, a aplicação não mantem a autenticação. Isso ocorre por que o wordpress por padrão guarda o estado da aplicação do próprio servidor web, portanto não é stateless. Para que ele seja stateless algumas ações precisam ser feitas, como, por exemplo, colocar autenticação JWT e guardar estados em um Redis ou semelhante. Mas isso não é necessário para o artigo: Kubernetes e o deployment quase perfeito.
Como implantar wordpress+mysql em meu cluster Kubernetes
Depois de tudo o que vimos a dúvida que fica é, como aplicar tudo isso no meu cluster? Utilize o código-fonte disponível no link https://github.com/Anselming/kube-wordpress-mysql:
# Criação do namespace
kubectl apply -f ./general/namespace-wordpress.yaml
# Aplicação de todos os demais arquivos yaml ao cluster
kubectl apply -Rf .
Conclusão de Kubernetes e o deployment quase perfeito
Implantar o WordPress com MySQL em um cluster Kubernetes pode parecer intimidante à primeira vista, mas com o guia adequado e a compreensão dos conceitos chave, é possível criar um ambiente robusto e escalável. Ao longo deste artigo, exploramos desde a configuração básica do namespace até a exposição externa do WordPress através de um Ingress, passando pela configuração do TLS (SSL) e a implementação de um Horizontal Pod Autoscaler (HPA). É importante destacar a importância do uso de práticas recomendadas, como o gerenciamento de configurações com ConfigMaps e Secrets, a utilização de probes para garantir a disponibilidade da aplicação e a configuração de volumes persistentes para garantir a integridade dos dados. Esperamos que este guia tenha sido útil e que você possa aplicar esses conhecimentos em seus próprios projetos no Kubernetes.
Ele atua/atuou como Dev Full Stack C# .NET / Angular / Kubernetes e afins. Ele possui certificações Microsoft MCTS (6x), MCPD em Web, ITIL v3 e CKAD (Kubernetes) . Thiago é apaixonado por tecnologia, entusiasta de TI desde a infância bem como amante de aprendizado contínuo.