¿Cómo proporciono acceso externo a varios servicios de Kubernetes en mi clúster de Amazon EKS?
Quiero proporcionar acceso externo a varios servicios de Kubernetes en mi clúster de Amazon Elastic Kubernetes Service (Amazon EKS).
Descripción corta
Utilice el controlador de entrada NGINX o el controlador AWS Load Balancer para Kubernetes para proporcionar acceso externo a varios servicios de Kubernetes en su clúster de Amazon EKS. El controlador de ingreso de NGINX es mantenido principalmente por NGINX. Para comprobar si hay problemas con el controlador de ingreso de NGINX, consulte la lista de problemas en el sitio web de GitHub. Amazon Web Services (AWS) es mantenido por el AWS Load Balancer Controller. Para comprobar si hay problemas con AWS Load Balancer Controller, consulte la lista de problemas en el sitio web de GitHub.
**Importante:**El controlador de ingreso e IngressClass (del sitio web de Kubernetes) no son lo mismo que el Ingress (del sitio web de Kubernetes). El Ingress es un recurso de Kubernetes que expone las rutas HTTP y HTTPS desde fuera del clúster a los servicios del clúster. El controlador de ingreso normalmente completa el Ingress con un balanceador de carga. No puede usar Ingress sin un controlador de ingreso. La IngressClass se usa para identificar qué controlador de ingreso usar para cumplir con la solicitud de objetos Ingress.
Requisito previo:Instale el AWS Load Balancer Controller. Se recomienda utilizar el AWS Load Balancer Controller para crear y administrar un balanceador de carga de red para los objetos de servicio de tipo LoadBalancer en Amazon EKS.
Resolución
La siguiente resolución usa el controlador de ingreso kubernetes/ingress-nginx del sitio web GitHub de Kubernetes. El otro controlador de ingreso que está disponible para uso público es el nginxinc/kubernetes-ingress del sitio web de GitHub de NGINX.
Implemente el controlador de ingreso NGINX para Kubernetes
Puede implementar el controlador de ingreso NGINX para Kubernetes mediante el protocolo de control de transmisión (TCP) o la seguridad de la capa de transporte (TLS).
**Nota:**La siguiente resolución se probó en la versión 1.22 de Amazon EKS, la versión 1.3.0 del controlador de ingreso de NGINX y la versión 2.4.3 del controlador de carga de AWS.
(Opción 1) Controlador de ingreso NGINX con TCP en el balanceador de carga de red
- Obtenga el archivo YAML para implementar los siguientes objetos de Kubernetes: espacio de nombres, cuentas de servicio**,mapa de configuración**,roles de clúster, enlaces de roles, roles, role bindings,** servicios**, implementaciones, clases de ingreso, yvalidatingwebhookconfigurations.
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml
- Edite el archivo. A continuación, en la sección de objetos de servicio ingress-nginx-controller, sustituya todas las anotaciones de service.beta.kubernetes.io por las siguientes:
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"
- Aplique el manifiesto:
kubectl apply -f deploy.yaml
Ejemplo de salida:
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
(Opción 2) Terminación TLS del controlador de ingreso NGINX** en el balanceador de carga de red**
De forma predeterminada, la solución anterior termina TLS en el controlador de ingreso NGINX. También puede configurar el servicio NGINX Ingress para que termine TLS en el balanceador de carga de red.
- Descargue la plantilla deploy.yaml:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
- Edite el archivo. A continuación, en la sección de objetos de servicio ingress-nginx-controller reemplace todas las anotaciones de service.beta.kubernetes.io por las siguientes:
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"
**Nota:**Asegúrese de incluir su ARN para service.beta.kubernetes.io/aws-load-balancer-ssl-cert.
- Edite el archivo y cambie el CIDR de Amazon Virtual Private Cloud (Amazon VPC) para el clúster de Kubernetes:
proxy-real-ip-cidr: XXX.XXX.XXX/XX
- Aplique el manifiesto:
kubectl apply -f deploy.yaml
**Nota:**El manifiesto anterior usa ExternalTrafficPolicy como local para conservar la dirección IP de origen (cliente). El uso de esta configuración con un nombre DHCP personalizado en Amazon VPC provoca un problema. Para evitar que se produzca el problema, aplique el siguiente parche al kube-proxy:
kubectl edit daemonset kube-proxy -n kube-system
- Edite el manifiesto para incluir el siguiente fragmento:
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
Verificar los recursos desplegados
Controlador AWS Load Balancer
Comando:
kubectl get all -n kube-system --selector app.kubernetes.io/instance=aws-load-balancer-controller
Ejemplo de salida:
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 ingreso NGINX
Comando:
kubectl get all -n ingress-nginx --selector app.kubernetes.io/instance=ingress-nginx
Ejemplo de salida:
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
Clase de ingreso
Comando:
kubectl get ingressclass
Ejemplo de salida:
NAME CONTROLLER PARAMETERS AGE alb ingress.k8s.aws/alb IngressClassParams.elbv2.k8s.aws/alb 19h nginx k8s.io/ingress-nginx none 15h
Probar la configuración de despliegue
**Nota:El siguiente paso consiste en ejecutar dos micro servicios. Los micro servicios se exponen internamente con ** Kubernetes como tipo predeterminado.
- Configure sus implementaciones o micro servicios. Por ejemplo, hostname-app y apache-app.
Ejemplo de un hostname-app-svc.yaml archivo 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
Ejemplo de un apache-app-svc.yamlarchivo 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
- Aplique sus configuraciones.
aplicación de nombre de host:
kubectl apply -f hostname-app-svc.yaml
aplicación apache:
kubectl apply -f apache-app-svc.yaml
- Compruebe que se hayan creado los recursos.
**Despliegues **
Comando:
kubectl get deployment hostname-app apache-app -n default
Ejemplo de salida:
NAME READY UP-TO-DATE AVAILABLE AGE hostname-app 2/2 2 2 29m apache-app 2/2 2 2 29m
Servicios
Comando:
kubectl get svc apache-svc hostname-svc -n default
Ejemplo de salida:
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
Pruebe el controlador de ingreso NGINX
- Acceda a la URL DNS del balanceador de carga que has recuperado de la línea de comandos:
curl -I ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com
Ejemplo de salida:
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
**Nota:**El servidor predeterminado devuelve una página 404 No encontrada para todas las solicitudes de dominio que no tienen reglas de ingreso definidas. Según las reglas definidas, el controlador de ingreso no desvía el tráfico al servicio de backend especificado a menos que la solicitud coincida con la configuración. Como el campo host está configurado para el objeto Ingress, debe proporcionar el encabezado Host de la solicitud con el mismo nombre de host. En un entorno de prueba, utilice un indicador curl para proporcionar el encabezado Host. En un entorno de producción, asigne el nombre DNS del balanceador de carga al nombre de host de cualquier proveedor de DNS, como Amazon Route 53.
- Implemente la entrada para que interactúe con sus servicios mediante un único balanceador de carga proporcionado por el controlador de ingreso NGINX.
Ejemplo 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
**Nota:**Para obtener más información, consulte Alojamiento virtual basado en nombres (del sitio web de Kubernetes).
- Compruebe que se haya creado el recurso.
Ingreso
Comando:
kubectl get ingress -n default
Ejemplo de salida:
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
- Añada el encabezado Host a la solicitud.
Primer dominio configurado:
curl -i -H "Host: hostname.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Ejemplo de salida:
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 dominio configurado:
curl -i -H "Host: apache.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Ejemplo de salida:
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
Tras añadir el encabezado Host, el controlador de entrada redirige el tráfico al servicio configurado en el backend, ya que coincide con la configuración definida en el Ingress.
Para mantener el mismo nombre de dominio pero desviar el tráfico en función de la ruta a la que se accede, debe añadir el enrutamiento basado en rutas con el Ingress.
Por ejemplo:
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
**Nota:**Si las solicitudes tienen mydomain.com como encabezado de Hostheader, el ejemplo anterior solo devuelve la respuesta 200. Se accede a las solicitudes a través de las rutas /hostname o /apache paths. Para todas las demás solicitudes, se devuelven respuestas 404.
- Verifique que se haya agregado el enrutamiento basado en rutas:
Comando:
kubectl get ingress -n default
Salida:
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
-o-
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/apache
Pruebe la entrada con el controlador AWS Load Balancer
- Inicie el balanceador de carga de aplicaciones mediante el siguiente ejemplo de manifiesto de ingreso:
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
- Compruebe que se inicie el balanceador de carga de aplicaciones.
Comando:
kubectl get ingress -n default
Salida:
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
Solicitud basada en el primer dominio configurado:
curl -i -H "Host: alb.hostname.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Ejemplo de salida:
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
Solicitud basada en el segundo dominio configurado:
curl -i -H "Host: alb.apache.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Ejemplo de salida:
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
Contenido relevante
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace 2 años
- OFICIAL DE AWSActualizada hace 2 años
- OFICIAL DE AWSActualizada hace 2 años