Comment fournir un accès externe à plusieurs services Kubernetes dans mon cluster Amazon EKS ?
Je veux fournir un accès externe à plusieurs services Kubernetes dans mon cluster Amazon Elastic Kubernetes Service (Amazon EKS).
Brève description
Utilisez le contrôleur d'Ingress NGINX ou AWS Load Balancer Controller pour Kubernetes afin de fournir un accès externe à plusieurs services Kubernetes dans votre cluster Amazon EKS. Le contrôleur d'Ingress NGINX est géré principalement par NGINX. En cas de problèmes liés au contrôleur d'Ingress NGINX, veuillez consulter la liste des problèmes sur le site web de GitHub. AWS Load Balancer Controller est géré par Amazon Web Services (AWS). En cas de problèmes liés à AWS Load Balancer Controller, veuillez consulter la liste des problèmes sur le site web de GitHub.
Important : le contrôleur d'Ingress et IngressClass (du site de Kubernetes) sont différents de l'Ingress (du site web de Kubernetes). L'Ingress est une ressource Kubernetes qui expose les routes HTTP et HTTPS de l'extérieur du cluster à des services au sein du cluster. Le contrôleur d'Ingress est généralement responsable de l'exécution de l'Ingress avec un équilibreur de charge. Vous ne pouvez pas utiliser d'Ingress sans contrôleur d'Ingress. L'IngressClass permet d'identifier le contrôleur d'Ingress à utiliser pour répondre à la demande d'objet Ingress.
Condition préalable : installez AWS Load Balancer Controller. Il est recommandé d'utiliser AWS Load Balancer Controller pour créer et gérer un Network Load Balancer pour les objets de service de type LoadBalancer dans Amazon EKS.
Solution
La solution suivante utilise le contrôleur d'Ingress kubernetes/ingress-nginx de la section Kubernetes du site web de GitHub. nginxinc/kubernetes-ingress de la section NGINX du site web de GitHub constitue l'autre contrôleur d'Ingress disponible pour un usage public.
Déploiement du contrôleur d'Ingress NGINX pour Kubernetes
Vous pouvez déployer le contrôleur d'Ingress NGINX pour Kubernetes par le biais du protocole TCP (Transmission Control Protocol) ou TLS (Transport Layer Security).
Remarque : la solution suivante est testée sur Amazon EKS version 1.22, le contrôleur d'Ingress NGINX version 1.3.0 et AWS Load Balancer Controller version 2.4.3.
(Option 1) Contrôleur d'Ingress NGINX avec TCP sur Network Load Balancer
1. Récupérez le fichier YAML pour déployer les objets Kubernetes suivants : namespace, serviceaccounts, configmap, clusterroles, clusterrolebindings, roles, rolebindings, services, deployments, ingressclasses et validatingwebhookconfigurations.
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml
2. Modifiez le fichier. Ensuite, dans la section de l'objet de service ingress-nginx-controller, remplacez l'ensemble des annotations service.beta.kubernetes.io par ce qui suit :
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. Appliquez le manifeste :
kubectl apply -f deploy.yaml
Exemple de sortie :
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
(Option 2) Terminaison TLS de contrôleur d'Ingress NGINX sur Network Load Balancer
Par défaut, la solution précédente établit la terminaison du protocole TLS au niveau du contrôleur d'Ingress NGINX. Vous pouvez également configurer le service Ingress NGINX afin qu'il établisse la terminaison du protocole TLS au niveau du Network Load Balancer.
1. Téléchargez le modèle deploy.yaml :
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
2. Modifiez le fichier. Ensuite, dans la section de l'objet de service ingress-nginx-controller, remplacez l'ensemble des annotations service.beta.kubernetes.io par ce qui suit :
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"
Remarque : assurez-vous d'inclure votre ARN pour service.beta.kubernetes.io/aws-load-balancer-ssl-cert.
3. Modifiez le fichier, puis l'adresse CIDR Amazon Virtual Private Cloud (Amazon VPC) pour le cluster Kubernetes :
proxy-real-ip-cidr: XXX.XXX.XXX/XX
4. Appliquez le manifeste :
kubectl apply -f deploy.yaml
Remarque : le manifeste précédent utilise ExternalTrafficPolicy en local afin de préserver l'adresse IP (client) source. L'utilisation de cette configuration avec un nom DHCP personnalisé dans l'Amazon VPC cause un problème. Pour éviter que ce problème ne se produise, appliquez le correctif suivant au kube-proxy :
kubectl edit daemonset kube-proxy -n kube-system
5. Modifiez le manifeste pour inclure l'extrait suivant :
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
Vérification des ressources déployées
AWS Load Balancer Controller
Commande :
kubectl get all -n kube-system --selector app.kubernetes.io/instance=aws-load-balancer-controller
Exemple de sortie :
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
Contrôleur d'Ingress NGINX
Commande :
kubectl get all -n ingress-nginx --selector app.kubernetes.io/instance=ingress-nginx
Exemple de sortie :
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
Commande :
kubectl get ingressclass
Exemple de sortie :
NAME CONTROLLER PARAMETERS AGE alb ingress.k8s.aws/alb IngressClassParams.elbv2.k8s.aws/alb 19h nginx k8s.io/ingress-nginx none 15h
Test de la configuration du déploiement
Remarque : l'étape suivante consiste à exécuter deux microservices. Les microservices sont exposés en interne avec Kubernetes comme type par défaut.
1. Configurez vos déploiements ou microservices. Par exemple, hostname-app et apache-app.
Exemple d'un fichier hostname-app-svc.yaml pour 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
Exemple d'un fichier apache-app-svc.yaml pour 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. Appliquez vos configurations.
hostname-app :
kubectl apply -f hostname-app-svc.yaml
apache-app :
kubectl apply -f apache-app-svc.yaml
3. Vérifiez que les ressources sont créées.
Déploiements
Commande :
kubectl get deployment hostname-app apache-app -n default
Exemple de sortie :
NAME READY UP-TO-DATE AVAILABLE AGE hostname-app 2/2 2 2 29m apache-app 2/2 2 2 29m
Services
Commande :
kubectl get svc apache-svc hostname-svc -n default
Exemple de sortie :
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
Test du contrôleur d'Ingress NGINX
1. Accédez à l'URL DNS de l'équilibreur de charge que vous avez récupéré à partir de la ligne de commande :
curl -I ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com
Exemple de sortie :
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
Remarque : le serveur par défaut renvoie une erreur 404 Not Found pour l'ensemble des demandes de domaine qui ne disposent pas de règles d'Ingress définies. D'après les règles définies, le contrôleur d'Ingress ne détourne pas le trafic vers le service backend spécifié, sauf si la demande correspond à la configuration. Étant donné que le champ hôte est configuré pour l'objet d'Ingress, vous devez fournir l'en-tête Host (Hôte) de la demande avec le même nom d'hôte. Dans un environnement de test, indiquez l'en-tête Host (Hôte) à l'aide d'un paramètre de ligne de commande d'action Curl (curl flag). Dans un environnement de production, mappez le nom DNS de l'équilibreur de charge sur le nom d'hôte d'un fournisseur DNS, tel qu'Amazon Route 53.
2. Implémentez l'Ingress afin qu'il interagisse avec vos services à l'aide de l'équilibreur de charge unique fourni par le contrôleur d'Ingress NGINX.
Exemple 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
Remarque : pour plus d'informations, veuillez consulter la section Hébergement virtuel basé sur le nom sur le site web de Kubernetes.
3. Vérifiez que la ressource est créée.
Ingress
Commande :
kubectl get ingress -n default
Exemple de sortie :
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. Ajoutez l'en-tête Host (Hôte) à la demande.
Premier domaine configuré :
curl -i -H "Host: hostname.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Exemple de sortie :
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
Deuxième domaine configuré :
curl -i -H "Host: apache.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Exemple de sortie :
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
Après avoir ajouté l'en-tête Host (Hôte), le contrôleur d'Ingress redirige le trafic vers le service backend configuré car il correspond à la configuration définie dans le contrôleur d'Ingress.
Si vous voulez conserver le même nom de domaine mais détourner le trafic en fonction du chemin d'accès, vous devez ajouter un routage basé sur le chemin avec l'Ingress.
Par exemple :
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
Remarque : si les demandes affichent mydomain.com comme en-tête Host (Hôte), l'exemple précédent ne renvoie que la réponse 200. Les demandes sont accessibles via le chemin /hostname ou /apache. Pour toutes les autres demandes, des réponses 404 sont renvoyées.
5. Vérifiez que le routage basé sur le chemin est ajouté :
Commande :
kubectl get ingress -n default
Sortie :
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
Commande :
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
Test de l'Ingress à l'aide d'AWS Load Balancer Controller
1. Lancez l'Application Load Balancer en utilisant l'exemple de manifeste d'Ingress suivant :
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. Vérifiez que l'Application Load Balancer est lancé.
Commande :
kubectl get ingress -n default
Sortie :
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
Demande basée sur le premier domaine configuré :
curl -i -H "Host: alb.hostname.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Exemple de sortie :
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
Demande basée sur le deuxième domaine configuré :
curl -i -H "Host: alb.apache.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Exemple de sortie :
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
Vidéos associées
Contenus pertinents
- demandé il y a 2 anslg...
- demandé il y a 9 moislg...
- demandé il y a un anlg...
- demandé il y a 7 moislg...
- AWS OFFICIELA mis à jour il y a 2 ans
- AWS OFFICIELA mis à jour il y a un an
- AWS OFFICIELA mis à jour il y a 2 ans
- AWS OFFICIELA mis à jour il y a un an