Como faço para fornecer acesso externo a vários serviços do Kubernetes no meu cluster Amazon EKS?
Quero fornecer acesso externo a vários serviços do Kubernetes no meu cluster do Amazon Elastic Kubernetes Service (Amazon EKS).
Breve descrição
Use o controlador de entrada NGINX ou o AWS Load Balancer Controller para Kubernetes para fornecer acesso externo a vários serviços Kubernetes em seu cluster Amazon EKS. O controlador de entrada NGINX é mantido principalmente pelo NGINX. Para verificar se há problemas com o controlador de entrada NGINX, consulte a lista de problemas no site do GitHub. O AWS Load Balancer Controller é mantido pela Amazon Web Services (AWS). Para verificar se há problemas com o AWS Load Balancer Controller, consulte a lista de problemas no site do GitHub.
Importante: o controlador de entrada e o IngressClass (do site do Kubernetes) não são iguais ao Ingress (do site do Kubernetes). O Ingress é um recurso do Kubernetes que expõe as rotas HTTP e HTTPS de fora do cluster aos serviços dentro do cluster. O controlador de entrada geralmente preenche a entrada com um balanceador de carga. Você não pode usar o Ingress sem um controlador de entrada. O IngressClass é usado para identificar qual controlador de entrada usar para atender à solicitação do objeto de entrada.
Pré-requisito: Instale o AWS Load Balancer Controller. A prática recomendada é usar o AWS Load Balancer Controller para criar e gerenciar um Network Load Balancer para objetos de serviço do tipo LoadBalancer no Amazon EKS.
Resolução
A resolução a seguir usa o controlador de entrada kubernetes/ingress-nginx no site do Kubernetes no GitHub. O outro controlador de entrada que está disponível para uso público é o nginxinc/kubernetes-ingress no site do NGINX no GitHub.
Implantar o controlador de entrada NGINX para Kubernetes
Você pode implantar o controlador de entrada NGINX para Kubernetes por meio do protocolo de controle de transmissão (TCP) ou da segurança da camada de transporte (TLS).
Observação: a resolução a seguir foi testada no Amazon EKS versão 1.22, no controlador de entrada NGINX versão 1.3.0 e no AWS Load Balancer Controller na versão 2.4.3.
(Opção 1) Controlador de entrada NGINX com TCP no Network Load Balancer
1. Obtenha o arquivo YAML para implantar os seguintes objetos do Kubernetes: namespace, serviceaccounts, configmap, clusterroles, clusterrolebindings, roles, rolebindings, services, deployments, ingressclasses e validatingwebhookconfigurations.
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml
2. Edite o arquivo. Em seguida, na seção de objeto de serviço ingress-nginx-controller, substitua todas as anotações service.beta.kubernetes.io pelas seguintes:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
3. Aplique o manifesto:
kubectl apply -f deploy.yaml
Exemplo de saída:
namespace/ingress-nginx created serviceaccount/ingress-nginx created configmap/ingress-nginx-controller created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx created service/ingress-nginx-controller-admission created service/ingress-nginx-controller created deployment.apps/ingress-nginx-controller created ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created serviceaccount/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
(Opção 2) Terminação TLS do controlador NGINX de entrada no Network Load Balancer
Por padrão, a solução anterior encerra o TLS no controlador de entrada NGINX. Você também pode configurar o serviço NGINX Ingress para encerrar o TLS no Network Load Balancer.
1. Faça o download do modelo deploy.yaml:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
2. Edite o arquivo. Em seguida, na seção de objeto de serviço ingress-nginx-controller, substitua todas as anotações service.beta.kubernetes.io pelas seguintes:
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:XXXXXXXX:certificate/XXXXXX-XXXXXXX-XXXXXXX-XXXXXXXX service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
Observação: certifique-se de incluir seu ARN para service.beta.kubernetes.io/aws-load-balancer-ssl-cert.
3. Edite o arquivo e altere o CIDR da Amazon Virtual Private Cloud (Amazon VPC) para o cluster Kubernetes:
proxy-real-ip-cidr: XXX.XXX.XXX/XX
4. Aplique o manifesto:
kubectl apply -f deploy.yaml
Observação: o manifesto anterior usa ExternalTrafficPolicy como local para preservar o endereço IP de origem (cliente). Usar essa configuração com um nome DHCP personalizado na Amazon VPC causa um problema. Para evitar que o problema ocorra, aplique o seguinte patch ao kube-proxy:
kubectl edit daemonset kube-proxy -n kube-system
5. Edite o manifesto para incluir o seguinte trecho:
spec: template: spec: containers: - name: kube-proxy command: - kube-proxy - --hostname-override=$(NODE_NAME) - --v=2 - --config=/var/lib/kube-proxy-config/config env: - name: NODE_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.nodeName
Verifique os recursos implantados
Controlador AWS Load Balancer
Comando:
kubectl get all -n kube-system --selector app.kubernetes.io/instance=aws-load-balancer-controller
Exemplo de saída:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/aws-load-balancer-controller-85cd8965dc-ctkjt 1/1 Running 0 48m 192.168.37.36 ip-192-168-59-225.us-east-2.compute.internal none none pod/aws-load-balancer-controller-85cd8965dc-wpwx9 1/1 Running 0 48m 192.168.53.110 ip-192-168-59-225.us-east-2.compute.internal none> none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/aws-load-balancer-webhook-service ClusterIP 10.100.154.44 none 443/TCP 19h app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/aws-load-balancer-controller 2/2 2 2 19h aws-load-balancer-controller 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-load-balancer-controller:v2.4.0 app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/aws-load-balancer-controller-85cd8965dc 2 2 2 19h aws-load-balancer-controller 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-load-balancer-controller:v2.4.0 app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller,pod-template-hash=85cd8965dc
Controlador de entrada NGINX
Comando:
kubectl get all -n ingress-nginx --selector app.kubernetes.io/instance=ingress-nginx
Exemplo de saída:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/ingress-nginx-controller-54d8b558d4-k4pdf 1/1 Running 0 56m 192.168.46.241 ip-192-168-59-225.us-east-2.compute.internal none none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/ingress-nginx-controller LoadBalancer 10.100.99.129 ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80:32578/TCP,443:30724/TCP 15h app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx service/ingress-nginx-controller-admission ClusterIP 10.100.190.61 none 443/TCP 15h app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/ingress-nginx-controller 1/1 1 1 15h controller k8s.gcr.io/ingress-nginx/controller:v1.1.1@sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/ingress-nginx-controller-54d8b558d4 1 1 1 15h controller k8s.gcr.io/ingress-nginx/controller:v1.1.1@sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx,pod-template-hash=54d8b558d4 NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR job.batch/ingress-nginx-admission-create 1/1 2s 15h create k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 controller-uid=242bdf56-de16-471d-a691-1ca1dbc10a41 job.batch/ingress-nginx-admission-patch 1/1 2s 15h patch k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 controller-uid=a9e710d2-5001-4d40-a435-ddc8993bfe42
IngressClass
Comando:
kubectl get ingressclass
Exemplo de saída:
NAME CONTROLLER PARAMETERS AGE alb ingress.k8s.aws/alb IngressClassParams.elbv2.k8s.aws/alb 19h nginx k8s.io/ingress-nginx none 15h
Teste a configuração de implantação
**Observação:**A etapa a seguir é executar dois microsserviços. Os microsserviços são expostos internamente com o Kubernetes como o tipo padrão.
1. Configure suas implantações ou microsserviços. Por exemplo, hostname-app e apache-app.
Exemplo de um arquivo hostname-app-svc.yaml para hostname-app:
apiVersion: apps/v1 kind: Deployment metadata: name: hostname-app namespace: default spec: replicas: 2 selector: matchLabels: app: hostname-app template: metadata: labels: app: hostname-app spec: containers: - name: hostname-app image: k8s.gcr.io/serve_hostname:1.1 --- apiVersion: v1 kind: Service metadata: name: hostname-svc namespace: default spec: ports: - port: 80 targetPort: 9376 protocol: TCP selector: app: hostname-app
Exemplo de um arquivo apache-app-svc.yaml para apache-app:
apiVersion: apps/v1 kind: Deployment metadata: name: apache-app namespace: default spec: replicas: 2 selector: matchLabels: app: apache-app template: metadata: labels: app: apache-app spec: containers: - name: apache-app image: httpd:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: apache-svc namespace: default labels: spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: apache-app
2. Aplique suas configurações.
hostname-app:
kubectl apply -f hostname-app-svc.yaml
apache-app:
kubectl apply -f apache-app-svc.yaml
3. Verifique se os recursos foram criados.
Implantações
Comando:
kubectl get deployment hostname-app apache-app -n default
Exemplo de saída:
NAME READY UP-TO-DATE AVAILABLE AGE hostname-app 2/2 2 2 29m apache-app 2/2 2 2 29m
Serviços
Comando:
kubectl get svc apache-svc hostname-svc -n default
Exemplo de saída:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE apache-svc ClusterIP 10.100.73.51 none 80/TCP 29m hostname-svc ClusterIP 10.100.100.44 none 80/TCP 29m
Teste o controlador de entrada NGINX
1. Acesse o URL DNS do balanceador de carga que você recuperou da linha de comando:
curl -I ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com
Exemplo de saída:
HTTP/1.1 404 Not Found Date: Thu, 03 Mar 2022 14:03:11 GMT Content-Type: text/html Content-Length: 146 Connection: keep-alive
Observação: o servidor padrão retorna uma página 404 Not Found para todas as solicitações de domínio que não têm regras de entrada definidas. Com base nas regras definidas, o controlador de entrada não desvia o tráfego para o serviço de back-end especificado, a menos que a solicitação corresponda à configuração. Como o campo host está configurado para o objeto Ingress, você deve fornecer o cabeçalho Host da solicitação com o mesmo nome de host. Em um ambiente de teste, use um sinalizador curl para fornecer o cabeçalho Host. Em um ambiente de produção, mapeie o nome DNS do balanceador de carga para o nome do host em qualquer provedor de DNS, como o Amazon Route 53.
2. Implemente a entrada para que ela interaja com seus serviços usando um único balanceador de carga fornecido pelo controlador de entrada NGINX.
Exemplo de micro-ingress.yaml:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: micro-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx spec: rules: - host: hostname.mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: / pathType: Prefix - host: apache.mydomain.com http: paths: - backend: service: name: apache-svc port: number: 80 path: / pathType: Prefix
Observação: para mais informações, consulte Hospedagem virtual baseada em nomes (no site do Kubernetes).
3. Verifique se o recurso foi criado.
Entrada
Comando:
kubectl get ingress -n default
Exemplo de saída:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 29m
4. Adicione o cabeçalho Host à solicitação.
Primeiro domínio configurado:
curl -i -H "Host: hostname.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Exemplo de saída:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 18:50:38 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 29 Connection: keep-alive
Segundo domínio configurado:
curl -i -H "Host: apache.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Exemplo de saída:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 18:51:00 GMT Content-Type: text/html Content-Length: 45 Connection: keep-alive Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes
Depois de adicionar o cabeçalho Host, o controlador de entrada redireciona o tráfego para o serviço configurado no back-end, pois ele corresponde à configuração definida na entrada.
Para manter o mesmo nome de domínio, mas desviar o tráfego com base no caminho acessado, você deve adicionar o roteamento baseado em caminho com o Ingress.
Por exemplo:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: path-ingress namespace: default annotations: kubernetes.io/ingress.class: nginxd nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: /hostname pathType: Prefix - host: mydomain.com http: paths: - backend: service: name: apache-svc port: number: 80 path: /apache pathType: Prefix
Observação: se as solicitações tiverem mydomain.com como cabeçalho Host, o exemplo anterior retornará somente a resposta 200. As solicitações são acessadas nos caminhos /hostname ou /apache. Para todas as outras solicitações, 404 respostas são retornadas.
5. Verifique se o roteamento baseado em caminho foi adicionado:
Comando:
kubectl get ingress -n default
Saída:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 164m path-ingress none mydomain.com,mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 120m
Comando:
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/hostname
-ou-
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/apache
Teste a entrada usando o controlador do AWS Load Balancer
1. Inicie o Application Load Balancer usando o seguinte exemplo de manifesto de entrada:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: micro-ingress-alb namespace: default annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: rules: - host: alb.hostname.mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: / pathType: Prefix - host: alb.apache.mydomain.com http: - backend: service: name: apache-svc port: number: 80 path: / pathType: Prefix
2. Verifique se o Application Load Balancer é iniciado.
Comando:
kubectl get ingress -n default
Saída:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 164m micro-ingress-alb none alb.hostname.mydomain.com,alb.apache.mydomain.com k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com 80 18m path-ingress none mydomain.com,mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 120m
Solicitação com base no primeiro domínio configurado:
curl -i -H "Host: alb.hostname.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Exemplo de saída:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 20:46:02 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 29 Connection: keep-alive
Solicitação com base no segundo domínio configurado:
curl -i -H "Host: alb.apache.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Exemplo de saída:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 20:46:14 GMT Content-Type: text/html Content-Length: 45 Connection: keep-alive Server: Apache/2.4.53 (Unix) Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes
Vídeos relacionados


Conteúdo relevante
- Resposta aceitafeita há 4 meseslg...
- feita há 9 diaslg...
- feita há 2 meseslg...
- feita há 22 diaslg...
- AWS OFICIALAtualizada há 5 meses
- AWS OFICIALAtualizada há 2 anos
- Como faço para configurar o AWS Load Balancer Controller em um cluster do Amazon EKS para o Fargate?AWS OFICIALAtualizada há 2 meses
- AWS OFICIALAtualizada há 2 anos