- Instale o Minikube e o Kubernetes no Ubuntu.
- Crie um cluster Kubernetes no Minikube.
- Crie um deployment do MySQL no cluster Kubernetes.
- Crie um serviço para o deployment do MySQL, para que a aplicação possa se conectar a ele.
- Crie um deployment da aplicação Java no cluster Kubernetes.
- Exponha a aplicação através de um serviço do tipo NodePort, para que ela possa ser acessada a partir do host.
- Adicione um health check à aplicação, para garantir que ela esteja funcionando corretamente.
- Configure a aplicação para permitir a alteração da versão da imagem sem downtime.
- Execute um stress test na aplicação para validar sua capacidade de lidar com cargas de trabalho pesadas.
- Configure a aplicação para fazer o scaling horizontal com base na utilização de recursos.
- criar ambiente
- minikube local
- instalar argocd
- terraform para deploy de ec2 com minikube
- subir o MySQL
- criar Application
- subir aplicação Java
- código da aplicação
- pipeline para build da imagem
- dockerfile
- criar manifestos K8s
criei 2 repositórios:
https://github.com/brunoarruda/devops-challenge-terraform, para versionar a criação dos recursos na AWS https://github.com/brunoarruda/devops-challenge-base-deployment, para versionar o deployment dentro do cluster
Eu iniciei um terceiro repositório que conteria uma aplicação java que escutaria requisições HTTP e consumiria recursos, para simular algum tipo de atividade real, e aproximar um pouco mais o cenário ao que foi solicitado, entretanto não houve tempo hábil para prosseguir, então eu decidi um nginx para demonstrar a funcionalidade de escabilidade dentro do cluster usando HPA.
criei o módulo para EC2 me baseando no módulo da comunidade terraform-aws-modules/ec2-instance/aws"
No mesmo repositório, eu criei uma pasta infrastructure
para guardar as configurações dos recursos a serem criados na AWS. Dentro da pasta há uma hierarquia para organizar o código, da seguinte maneira:
├── infrastructure
│ └── lab # conta ou ambiente do recurso
│ └── ec2 # tipo de recurso
│ └── challenge # projeto
│ └── <arquivos terraform para deployment>
├── module
└── ec2 # tipo do módulo
└── <arquivos de definição do módulo>
Houve 2 recursos que precisei criar manualmente para poder executar meu código terraform:
- a chave ssh para conectar na EC2. Apesar de existir um recurso aws_key_pair, ele só faz gestão de uma chave existente, não gera uma nova.
- o s3 onde o tfstate ficou salvo
tf plan -var-file=./variables.tfvars
Pelo terraform, já é instalado o minikube, ArgoCD e Nginx Ingress. Caso fosse necessário obter alguma informação sobre a execução dos comandos no script user_data
, isso seria possível de recuperar consultando os logs em /var/log/syslog
, na EC2.
O minikube foi instalado com sucesso na EC2 usando a propriedade user_data
, entretanto não foi possível conectar no minikube a partir da minha máquina. Devido aos problemas, eu alternei algumas estratégias, primeiro tentei usar o podman como driver para o cluster kubernetes, após falhas eu tentei o Docker e após mais falhas, decidi não usar nenhum drive, fazendo a instalação baremetal.
Não é suficiente instalar o docker e o minikube para a instalação funcionar corretamente no Ubuntu 20.04. Foi necessário tomar as seguintes medidas para conseguir configurar o k8s modificações necessárias na máquina para fazer o minikube funcionar:
- desativação do AppArmor
- instalação do conntrack, crictl, cri-dockerd
para configurar o acesso ao Lens, eu copio o kubeconfig da instância ec2 para meu computador local com scp:
scp -i ~/.ssh/minikube-challenge.pem ubuntu@<ec2 public ip>:/home/ubuntu/.kube/config ~/.kube/minikube-ec2
Com o kubeconfig, configurei o acesso ao cluster via lens e kubectl
Para o HPA funcionar no minikube, é necessário ativar o addon do metrics-server, que é um requisito para o funcionamento do HPA
Após essa configuração, o HPA funcionou, escalando a aplicação quando ela tinha alta demanda.
Por se tratar de um ambiente de demonstração e devido à falta de tempo, foram feitas grandes simplificações:
- Não há cuidados na parte de segurança quanto à criação e gestão de secrets, que estão salvas em código. Isso pode ser resolvido por um serviço de gerenciamento de secrets (Hashicorp Vault ou AWS Secrets Manager) ou pela criptografia dos dados sensíveis usando SOPS
- O ArgoCD instala a aplicação lendo manifestos kubernetes diretamente. Em um ambiente que use ArgoCD para várias aplicações, seria mais interessante criar um template em Helm para permitir a reusabilidade e facilitar a manutenção de templates
- Eu realizei o setup do ArgoCD via userData no EC2, mas um jeito mais robusto de resolver isso é usando um módulo de Helm no terraform, entretanto o módulo supõe a existência do cluster como um EKS, e não como uma instância on-premise em uma EC2.