Para quem nunca utilizou o ingress em sua operação, a hora é agora! O artigo apresenta algumas features e conceitos básicos para que, ao final, você possa realizar sua primeira implementação.
Introdução
Neste artigo, vamos abordar de forma simplificada e objetiva conceitos sobre o uso do ingress no dia a dia de um operador de cluster kubernetes. Para quem nunca o utilizou em sua operação, a hora é agora. Serão apresentados aqui algumas features e conceitos básicos para que, ao final do artigo, você possa realizar sua primeira implementação.
O que é um Service ?
Antes de falarmos sobre ingress precisamos primeiramente conhecer alguns conceitos básicos, como o service.
Service é um balanceador de carga, que realiza uma requisição para a kube-apiserver , recebendo uma lista de endpoints das aplicações, direcionando o tráfego para os pods. Por padrão o service trabalha com estratégia de balanceamento “round robin”. Existem basicamente três tipos de services “ClusterIP”, “NodePort” e “LoadBalancer”, vamos entender um pouco sobre cada um.
ClusterIP: tipo padrão de service, que possibilita a comunicação apenas através da SDN criada para comunicação dos pods.
NodePort: um service que disponibiliza uma porta em cada nó do cluster que possui um pod em execução da aplicação, sua forma de acesso se dá através do “IP + porta” (xxx.xxx.xxx.xxx:porta), possuindo um range limite padrão de portas que podem ser utilizadas (30000–32767).
LoadBalancer: um tipo de service que realiza balanceamento de carga diretamente para dentro do cluster, porém para utilizar esse recurso você precisar ter realizado a integração com um serviço de “balanceamento de carga”, se você utiliza algum provedor cloud isso pode ser feito de forma simples, basta garantir que seus nodes possuem permissão para executar essa integração, já em ambiente on-premise é necessário ter um appliance que se integre com seu cluster. Um ponto importante sobre esse tipo de service é que é gerado um novo componente do tipo loadbalancer para cada aplicação, ou seja cuidado a utilizá-lo, para não gerar um custo considerável em ambientes cloud.
O que é Ingress ?
Indo direto ao ponto, Ingress é um objeto Kubernetes que nos permite externalizar services de um cluster, ou seja é uma forma de abstrair services internos do cluster para o público externo (cliente), com Ingress podemos trabalhar com protocolos HTTP/HTTPS, SSL/TLS, roteamento de tráfego, balanceamento de carga, controle de acesso, websocket e etc. Tudo isso utilizando apenas uma única integração com o serviço de loadbalancer.
Como o ingress funciona ?
O Ingress basicamente é composto por dois componentes, ingress controller e ingress resource.
Ingress controller é o interpretador do ingress resource, se você usa um serviço de kubernetes gerenciado como GKE, EKS e AKS, esses serviços já possuem seu ingress controller nativo podendo ser alterado para um de sua preferência. Existem vários tipos de ingress controller, duas sugestões descritas na documentação do Kubernetes são Nginx ingress e GCE, sendo ambos mantidos e suportados pela comunidade kubernetes. Existem também outras opções excelentes neste link, escolha um de sua preferência ou que melhor se adeque a sua necessidade.
Ingress resource é um componente que permite descrever como queremos externalizar nosso serviços, se vamos utilizar SSL/TLS, para onde vamos direcionar o roteamento de tráfego, se teremos controle de acesso, websocket e etc.
Qual a relação entre Service e Ingress ?
Quando é enviado um requisição pelo nosso cliente para o cluster, essa requisição é recebida e chega primeiramente no ingress controller, que verifica quais regras existem para aquela request no ingress resource que por sua vez direciona ao service correspondente e o direciona ao node que possui um pod da aplicação. Quando utilizamos o Ingress normalmente utilizamos o tipo de services ClusterIP, mantendo nossa aplicação um pouco mais seguras, pois toda parte de comunicação é realizada pelo ingress controller.
Abaixo uma imagem que abstrai muito bem o funcionamento de ambos componentes:
Que tipo de problema podemos resolver utilizando o ingress ?
Tão importante quanto aprender sobre novas tecnologias é saber qual problema conseguimos resolver com elas. Um problema muito comum que podemos resolver rapidamente com ingress é externalizar vários serviços via um único endpoint.
Para exemplificar melhor seu uso vamos criar um situação comum em um dia a dia de uma operação, vou demonstrar um exemplo utilizando paths.
“Suponha que você possui três aplicações no modelo microsserviços e realizou o deploy de ambas em um cluster kubernetes, mas agora precisa criar um service que permita expor essas aplicações através de um único endpoint por questões de custo, outro ponto é que cada aplicação possui um path para acesso (“/login”, “/cadastro” e “/monitor”).”
Nosso objetivo será criar um endpoint “exemplo.com/{“login”, “cadastro” e “monitor”}” com cada path das aplicações e disponibilizar o acesso para os nossos clientes. Dois pontos a se considerar são o custo e manutenibilidade.
Vimos que utilizar apenas o “service” isoladamente não é uma boa abordagem, e também que ter loadBalancers para cada entrada é inviável financeiramente, assim o Ingress se mostra a solução ideal concentrando os acessos em um único endpoint, como a centralização de configuração, e facilitando a manutenção ou atualização.
Vamos à pratica
Bom, até agora falamos bastante da parte teórica, então vamos para a prática.
Neste exemplo vamos utilizar o nginx ingress controller , por ser um controller simples e recomendado na documentação oficial, sua implementação será de duas formas uma via helm e outra manual.
Implementação via Helm
1 - Aqui vamos instalar o ingress controller, criei um namespace chamado “ingress” para melhor organização.
Kubernetes -Ingress
Agora verifique se o service ingress tem um “EXTERNAL-IP” atribuido a ele.
kubectl -n ingress get svc nginx-ingress-controller
2 - Agora vamos realizar a configuração do nosso ingress resource, devemos aplicar essas configurações dentro do namespace da aplicação e questão, neste caso minha aplicação está no namespace “myapp”.
cat << EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
namespace: myapp
annotations:
kubernetes.io/ingress.class: nginx # aquí estamos definir que tipo de ingress class vamos utilizado
spec:
rules:
- http: exemplo.com # aqui definimos o nosso domínio e/ou subdomínio, caso não tenha uma url você poderá remover dns e realizar a chamada pelo ip diretamente.
http:
paths:
- path: /login # path da aplicação
backend:
serviceName: login-svc # nome do service da aplicação
servicePort: 80
- path: /cadastro
backend:
serviceName: cadastro-svc
servicePort: 8080
- path: /monitor
backend:
serviceName: monitor-svc
servicePort: 80
EOF
3 - Agora pode ser verificado através das seguintes URLs.
curl http://exemplo.com
curl http://exemplo.com/login
curl http://exemplo.com/castro
curl http://exemplo.com/monitor
Implementação
Existem algumas configurações espeficicas que são vinculadas a seu cloud provider ou ao bare-metal, verifique o link para maiores dúvidas.
1- Para implentação manual é necessário algumas configurações como RBAC, criação de service, deployments e etc, seu namespace padrão é “ingress-nginx”
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml
2- Agora vamos realizar a configuração do nosso ngress resource, devemos aplicar essas configurações dentro do namespace da aplicação e questão, neste caso minha aplicação está no namespace “myapp”.
cat << EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
namespace: myapp
annotations:
kubernetes.io/ingress.class: nginx # aquí estamos definir que tipo de ingress class vamos utilizado
spec:
rules:
- http: exemplo.com # aqui definimos o nosso domínio e/ou subdomínio, caso não tenha uma url você poderá remover dns e realizar a chamada pelo ip diretamente.
http:
paths:
- path: /login # path da aplicação
backend:
serviceName: login-svc # nome do service da aplicação
servicePort: 80
- path: /cadastro
backend:
serviceName: cadastro-svc
servicePort: 8080
- path: /monitor
backend:
serviceName: monitor-svc
servicePort: 80
EOF
3 - Agora pode ser verificado através das seguintes URLs.
curl http://exemplo.com
curl http://exemplo.com/login
curl http://exemplo.com/castro
curl http://exemplo.com/monitor
Considerações finais
A utilização do ingress é um componente que elevará a maturidade de seu cluster, como vimos ele não é um “bicho de sete cabeças”, sua utilização é simples e intuitiva, se você chegou até aqui eu lhe agradeço, eu espero que você tenha conseguido ter tido êxito na implementação e aguarde as cenas dos próximos capítulos.
Autor: Kaio Cersar F. Santos