No meu último artigo sobre Kubernetes, aprendemos como criar o nosso primeiro deployment, escalar utilizando replicas e expor ele externamente utilizando Services. Entretanto, o acesso externo foi feito através do IP do servidor, não sendo possível utilizar um domínio pra acesso.

Então, hoje vamos explorar o uso do Ingress Controller e configurar para que possamos acessar nossos serviços utilizando URLs e não apenas por IP.

O que é Ingress Controller ?

Ingress expõe rotas HTTP e HTTPS externas para os Services do cluster Kubernetes. Suas rotas são configuradas por regras definidas no Ingress resource.

Utilizando Ingress, podemos utilizar LoadBalancer, SSL e resolução de domínios, lembrando que o Ingress apenas trabalha com HTTP e HTTPS. Portanto, para outro casos, devemos utilizar os Services de tipo NodePort ou LoadBalancer.

Existem vários Ingress Controllers disponíveis no mercado. Segue abaixo a lista de alguns:

Lembrando que é possível utilizar mais de um ao mesmo tempo em um cluster.

Utilizando o NGINX Ingress Controller

Aqui, neste caso, utilizarei o NGINX Ingress Controller. Para instalar, vou seguir os passos da documentação.

Primeiro, vamos instalar o NGINX Ingress Controller no nosso cluster:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

Feito isso, precisamos criar o Service que irá expor o nosso Ingress Controller:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml

Agora, verifico se o serviço foi criado:

kubectl get services --namespace=ingress-nginx

Ele deve exibir algo parecido com os dados abaixo:

Com o nosso Ingress Controller instalado e exposto, chegou a hora de criar as aplicações e configurar o Ingress Resource.

Preparando os Pods e os Services

Mas antes de configurarmos o Ingress Resource, vamos criar nossas aplicações que serão expostas. A primeira será a mesma do post anterior, então vamos executar o arquivo YAML.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: primeiro-deployment
  labels:
    app: primeiro-deployment
spec:
  selector:
    matchLabels:
      app: primeiro-deploy
  template:
    metadata:
      labels:
        app: primeiro-deploy
    spec:
      containers:
      - name: primeiro-deploy-api
        image: fabricioveronez/cadastroprodutossimplesapi 
        ports:
        - containerPort: 80

---

kind: Service
apiVersion: v1
metadata:
  name: primeiro-service
spec:
  selector:
    app: primeiro-deploy
  ports:
  - protocol: TCP
    port: 80
  type: NodePort
kubectl apply -f primeirodeploy.yaml

A segunda, será um simples nginx e para executar, basta criarmos um deploy e expor com um service.

kubectl run deploy-nginx --image nginx
kubectl expose deployment deploy-nginx --type=NodePort --name=nginx-service --port 80

Feito isso, vamos verificar se os Services estão sendo executados.

kubectl get services

Ingress Resource

Agora, é hora de configurarmos o nosso Ingress Resource. No nosso exemplo, vou configurar para que o host name http://api.veronez.net seja direcionado para a webapi e que o host name http://nginx.veronez.net seja direcionado para o NGINX.
Podemos ver o arquivo YAML logo abaixo:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: virtual-host
spec:
  rules:
  - host: api.veronez.net
    http:
      paths:
      - backend:
          serviceName: primeiro-service
          servicePort: 80
  - host: nginx.veronez.net
    http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: 80

Antes de configurar uma regra, eu preciso configurar o host. Aqui, no caso, eu tenho o api.veronez.net e o nginx.veronez.net. Junto com o host, eu preciso configurar os paths. Neste caso, eu tenho o path padrão e o backend, que no caso é o nome do Service e a porta que vou direcionar.

Vamos executar o nosso Ingress Resource:

kubectl apply -f ingress-resource.yaml

E vamos verificar o resultado:

kubectl get ingress 

Agora, o Ingress Controller está configurado e podemos acessar as aplicações utilizando as urls configuradas.

Para acessar a api:

http://api.veronez.net:31645/api/produto

Para acessar o NGINX:

http://nginx.veronez.net:31645/

Lembrando que, assim como no artigo anterior, eu estou utilizando um servidor bare metal criado por mim. Logo, eu não possuo um load balance como os serviços de cloud. Por isso, preciso utilizar o IP dos meus Nodes ou do Master do meu cluster para acessar o Ingress. Além disso, preciso utilizar a porta configurada pelo NodePort Service que expõe o Ingress.

Na própria documentação do NGINX Ingress Controller, existem formas de resolver esse problema. Cabe então, analisar qual atende melhor a sua necessidade.

Para finalizar, vou inserir mais um Ingress Resource. Porém, utilizando um único host e 2 paths:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: path-host
spec:
  rules:
  - host: veronez.net
    http:
      paths: 
        - path: /api
          backend:
            serviceName: primeiro-service
            servicePort: 80
        - path: /
          backend: 
            serviceName: nginx-service
            servicePort: 80            

Vamos executar:

kubectl apply -f ingress-resource-paths.yaml

E vamos verificar o resultado:

kubectl get ingress 

Agora, é possível acessar a api pela URL http://veronez.net:31645/api/produto e o NGINX pela URL http://veronez.net:31645.

Conseguimos criar duas formas de acessar nossos Services através de regras de rotas utilizando o Ingress Controller.
Qualquer dúvida ou sugestões, é só entrar em contato.