NGINX Ingress
O Ingress é um recurso do Kubernetes que permite acessar serviços dentro do cluster via HTTP e HTTPS. Ele fornece roteamento com base em URLs, domínios e outros parâmetros.
Neste artigo, vamos explorar o uso do Nginx Ingress com três Deployments Nginx simulando três serviços diferentes. Também configuraremos um certificado SSL para proteger a conexão.
Instalar o Nginx Ingress Copiar link
Primeiro, é necessário instalar o Nginx Ingress no cluster.
No painel de gerenciamento do cluster:
- Vá para a seção Kubernetes e clique em cluster.
- Vá para a aba Complementos.
- Clique nos três pontos ao lado de Nginx Ingress.
- Selecione Instalar.
Após a instalação, verifique se o Ingress está funcionando corretamente executando:
kubectl get pods -n ingress-nginxCertifique-se de que todos os pods estejam com o status Running.
Configurar Deployments e Services Copiar link
Vamos considerar um exemplo de uso do NGINX Ingress. Implantaremos três Deployments baseados em imagens Nginx, cada um simulando um serviço separado.
Para cada Deployment, criaremos um Service do tipo ClusterIP — o tipo padrão no Kubernetes — que fornece um IP interno dentro do cluster. Esse tipo de serviço não é acessível diretamente de fora do cluster; no entanto, pode ser exposto externamente usando um Ingress.
Para facilitar, criaremos um namespace separado para conter todos os manifests:
kubectl create namespace ingress-examplePara diferenciar os serviços, criaremos um ConfigMap contendo três páginas HTML distintas.
Crie o arquivo configmap.yaml com o seguinte conteúdo:
apiVersion: v1
kind: ConfigMap
metadata:
name: service-config
namespace: ingress-example
data:
service1.html: |
<html>
<head><title>Service 1</title></head>
<body><h1>Welcome to Service 1!</h1></body>
</html>
service2.html: |
<html>
<head><title>Service 2</title></head>
<body><h1>Welcome to Service 2!</h1></body>
</html>
service3.html: |
<html>
<head><title>Service 3</title></head>
<body><h1>Welcome to Service 3!</h1></body>
</html>Em seguida, vamos definir os Deployments.
service1-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: service1
namespace: ingress-example
spec:
replicas: 2
selector:
matchLabels:
app: service1
template:
metadata:
labels:
app: service1
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /usr/share/nginx/html
volumes:
- name: config-volume
configMap:
name: service-config
items:
- key: service1.html
path: index.html
---
apiVersion: v1
kind: Service
metadata:
name: service1
namespace: ingress-example
spec:
selector:
app: service1
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIPExplicação do manifesto:
- Deployment
replicas: 2especifica que dois pods Nginx estarão em execução.- As seções
selectoretemplate.metadata.labelsdefinem como o Service localizará os pods. volumeMountsevolumessão usados para montar o arquivoservice1.htmldoConfigMapno diretório padrão de conteúdo do Nginx.
- Service
ClusterIPsignifica que o serviço ficará acessível apenas dentro do cluster por meio de um IP interno. Para acesso externo, usaremos o Ingress.
Os manifests de service2 e service3 são semelhantes, diferindo apenas no nome do serviço e no arquivo HTML utilizado.
service2-deployment.yaml Copiar link
apiVersion: apps/v1
kind: Deployment
metadata:
name: service2
namespace: ingress-example
spec:
replicas: 2
selector:
matchLabels:
app: service2
template:
metadata:
labels:
app: service2
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /usr/share/nginx/html
volumes:
- name: config-volume
configMap:
name: service-config
items:
- key: service2.html
path: index.html
---
apiVersion: v1
kind: Service
metadata:
name: service2
namespace: ingress-example
spec:
selector:
app: service2
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIPservice3-deployment.yaml Copiar link
apiVersion: apps/v1
kind: Deployment
metadata:
name: service3
namespace: ingress-example
spec:
replicas: 2
selector:
matchLabels:
app: service3
template:
metadata:
labels:
app: service3
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /usr/share/nginx/html
volumes:
- name: config-volume
configMap:
name: service-config
items:
- key: service3.html
path: index.html
---
apiVersion: v1
kind: Service
metadata:
name: service3
namespace: ingress-example
spec:
selector:
app: service3
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIPAplique os manifests:
kubectl apply -f configmap.yaml
kubectl apply -f service1-deployment.yaml
kubectl apply -f service2-deployment.yaml
kubectl apply -f service3-deployment.yamlVerifique o status dos pods:
kubectl get pods -n ingress-exampleTodos devem estar com o status Running.
Criar o Ingress Copiar link
Com o Ingress, definiremos qual tráfego (com base em domínios e caminhos) será redirecionado para os serviços correspondentes.
Crie o manifesto ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: ingress-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: ingress1.example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
- host: ingress2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service3
port:
number: 80Explicação do manifesto:
rules.hostespecifica o domínio ao qual o Ingress será vinculado.pathsdefine as regras de roteamento:- Requisições para
ingress1.example.com/service1→service1 - Requisições para
ingress1.example.com/service2→service2 - Requisições para
ingress2.example.com/→service3
- Requisições para
Aplique o manifesto:
kubectl apply -f ingress.yamlCriar um LoadBalancer Copiar link
Para acessar o Nginx Ingress a partir de uma rede externa, criaremos um Service do tipo LoadBalancer, que fará o balanceamento de carga e fornecerá um IP externo.
Prepare o manifesto loadbalancer.yaml:
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
selector:
app.kubernetes.io/name: ingress-nginx
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
type: LoadBalancerAplique:
kubectl apply -f loadbalancer.yamlAguarde a criação do load balancer e verifique se ele recebeu um IP externo:
kubectl get services -n ingress-nginxO IP externo será exibido na coluna EXTERNAL-IP.
Adicione esse IP externo como registros A no DNS dos domínios ingress1.example.com e ingress2.example.com.
Após a propagação do DNS, você poderá acessar:
http://ingress1.example.com/service1— exibirá "Welcome to Service 1!"http://ingress1.example.com/service2— exibirá "Welcome to Service 2!"http://ingress2.example.com/— exibirá "Welcome to Service 3!"
Configurar um certificado SSL Copiar link
Para garantir uma conexão segura no Nginx Ingress, adicione um certificado SSL existente como Secret do Kubernetes e especifique esse secret no manifesto do Ingress.
Se quiser automatizar a emissão e renovação de certificados (por exemplo, com Let’s Encrypt), use o cert-manager.
Preparar os arquivos do certificado e da chave Copiar link
Salve localmente os arquivos:
tls.key(chave privada)tls.crt(certificado)
Certifique-se de que o certificado não esteja expirado e corresponda aos domínios que você deseja proteger.
Criar um Secret no Kubernetes Copiar link
Para adicionar o certificado ao cluster, codifique os arquivos em Base64:
base64 -w 0 ./tls.crt
base64 -w 0 ./tls.keyDepois, crie o arquivo tls-secret.yaml:
apiVersion: v1
kind: Secret
metadata:
name: ingress-example-tls
namespace: ingress-example
type: kubernetes.io/tls
data:
tls.crt: |-
<BASE64_ENCODED_CERTIFICATE>
tls.key: |-
<BASE64_ENCODED_KEY>Aplique:
kubectl apply -f tls-secret.yamlVerifique se os valores não estão vazios:
kubectl describe secret ingress-example-tls -n ingress-exampleAtualizar o manifesto do Ingress Copiar link
Atualize o ingress.yaml adicionando a seção tls e referenciando o secret criado:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: ingress-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- ingress1.example.com
- ingress2.example.com
secretName: ingress-example-tls
rules:
- host: ingress1.example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
- host: ingress2.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service3
port:
number: 80Agora, ao acessar ingress1.example.com ou ingress2.example.com via HTTPS, o navegador usará o certificado armazenado no secret ingress-example-tls. Isso garante que o tráfego para seus serviços esteja protegido.
Se você tiver vários certificados para domínios diferentes, crie um Secret para cada um (por exemplo, example.com e example.org) e adicione uma seção tls separada para cada domínio:
spec:
tls:
- hosts:
- example.com
secretName: example-com-tls
- hosts:
- example.org
secretName: example-org-tls