Comment fournir un accès externe à plusieurs services Kubernetes dans mon cluster Amazon EKS ?

Date de la dernière mise à jour : 29/01/2020

Je souhaite fournir un accès externe à plusieurs services Kubernetes dans mon cluster Amazon Elastic Kubernetes Service (Amazon EKS).

Brève description

Vous pouvez utiliser le contrôleur d’Ingress NGINX pour Kubernetes pour fournir un accès externe à plusieurs services Kubernetes dans votre cluster Amazon EKS.

Remarque : le contrôleur d’Ingress peut être plus efficace et plus économique qu'un équilibreur de charge. En outre, vous devrez peut-être réserver votre équilibreur de charge pour envoyer le trafic vers différents microservices.

Important : le contrôleur d’Ingress n'est pas identique à l’Ingress. L'Ingress est une ressource Kubernetes qui expose les routes HTTP et HTTPS depuis l'extérieur du cluster vers les services au sein du cluster. Le contrôleur d’Ingress assure l'Ingress (généralement avec un équilibreur de charge). Vous ne pouvez pas utiliser l’Ingress sans un contrôleur d'Ingress.

Résolution

La résolution suivante utilise le contrôleur d'Ingress nginxinc/kubernetes-ingress. L'autre contrôleur d'Ingress disponible pour un usage public est kubernetes/ingress-nginx. Pour plus d'informations, consultez la page Différences entre les contrôleurs d'Ingress nginxinc/kubernetes-ingress et kubernetes/ingress-nginx.

Déploiement du contrôleur d'Ingress NGINX pour Kubernetes

1.    Pour télécharger le contrôleur d'Ingress NGINX pour Kubernetes, exécutez la commande suivante :

git clone https://github.com/nginxinc/kubernetes-ingress.git

2.    Pour choisir le répertoire de déploiement du contrôleur d'Ingress, exécutez la commande suivante :

cd kubernetes-ingress/deployments/

Remarque : toutes les commandes des étapes suivantes sont exécutées à partir du répertoire deployments (déploiements).

3.    Pour créer un espace de noms dédié, un compte de service et des certificats TLS (avec une clé) pour le serveur par défaut, exécutez les commandes suivantes :

kubectl apply -f common/ns-and-sa.yaml
kubectl apply -f common/default-server-secret.yaml

Remarque : le serveur par défaut renvoie une page « Not Found » (Introuvable) avec un code de statut 404 pour toutes les demandes de domaines pour lesquelles aucune règle d’Ingress n'est définie. Vous pouvez utiliser le certificat autosigné et la clé qui sont générés à des fins de test. Une bonne pratique consiste à utiliser votre propre certificat et votre propre clé pour les environnements de production.

4.    Pour créer une ressource ConfigMap afin de personnaliser votre configuration NGINX, exécutez la commande suivante :

kubectl apply -f common/nginx-config.yaml

Remarque : pour obtenir des exemples de configurations, consultez ConfigMap et annotations.

5.    Pour configurer le contrôle d'accès basé sur les rôles (RBAC), créez un ClusterRole, puis liez le ClusterRole au compte de service à partir de l'étape 3.

kubectl apply -f rbac/rbac.yaml

Remarque : le ClusterRole donne au contrôleur d'Ingress l'autorisation d'interagir avec votre cluster Amazon EKS.

6.    Pour déployer le contrôleur d'Ingress, exécutez les commandes suivantes.

Remarque : vous pouvez déployer un contrôleur d'Ingress avec l'option Deployment ou DaemonSet. L'option Deployment vous permet de modifier dynamiquement le nombre de réplicas du contrôleur d'Ingress. L'option DaemonSet vous permet de déployer le contrôleur d'Ingress sur chaque nœud ou sous-ensemble de nœuds. L'étape 6 utilise l'option Deployment.

kubectl apply -f deployment/nginx-ingress.yaml
kubectl get pods --namespace=nginx-ingress

Vous obtenez une sortie similaire à ce qui suit :

NAME                            READY   STATUS    RESTARTS   AGE
nginx-ingress-fb4f4b44c-xmq6z   1/1     Running   0          3d7h

Votre contrôleur d'Ingress peut désormais accepter les demandes provenant d'objets d'Ingress.

Accédez au contrôleur d'Ingress et exécutez votre application.

Pour un déploiement ingress-controller, vous pouvez utiliser un objet de service avec le type NodePort ou LoadBalancer. Les étapes suivantes utilisent le type LoadBalancer.

1.    Pour appliquer votre configuration, exécutez les commandes suivantes :

kubectl apply -f service/loadbalancer-aws-elb.yaml
kubectl get svc --namespace=nginx-ingress

Vous obtenez une sortie similaire à ce qui suit :

NAME          TYPE         EXTERNAL-IP                                      PORT(S)
nginx-ingress LoadBalancer aaa71bxxxxx-11xxxxx10.us-east-1.elb.amazonaws.com 80:32462/TCP,443:32226/TCP

Remarque : Amazon EKS alloue un Classic Load Balancer en mode TCP avec le protocole PROXY activé pour transmettre les informations du client (l'adresse IP et le port). Vous devez transmettre ces informations de proxy au contrôleur d'Ingress.

2.    Pour configurer NGINX afin d'utiliser le protocole PROXY pour pouvoir transmettre les informations de proxy au contrôleur d'Ingress, ajoutez les clés suivantes au fichier nginx-config.yaml depuis l'étape 1. Consultez l'exemple suivant :

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
  namespace: nginx-ingress
data:
  proxy-protocol: "True"
  real-ip-header: "proxy_protocol"
  set-real-ip-from: "0.0.0.0/0"

Remarque : les informations de proxy sont transmises au contrôleur d'Ingress via la ressource ConfigMap que vous avez créée précédemment.

3.    Pour mettre à jour la ressource ConfigMap, exécutez la commande suivante :

kubectl apply -f common/nginx-config.yaml

4.    Configurez vos déploiements ou vos microservices (par exemple, hostname-app et apache-app). Reportez-vous aux exemples suivants.

Remarque : cette étape suppose que vous exécutez deux microservices (à des fins de démonstration). Les microservices sont exposés en interne avec Kubernetes comme type par défaut.

Exemple d'un fichier hostname-app-svc.yaml pour hostname-app :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hostname-app
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
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
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
  labels:
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: apache-app

Pour appliquer vos configurations, exécutez les commandes suivantes :

kubectl apply -f hostname-app-svc.yaml
kubectl apply -f apache-app-svc.yaml

5.    Implémentez l’Ingress afin qu'il interagisse avec vos services à l'aide de l’unique équilibreur de charge fourni par le contrôleur d’Ingress. Consultez l'exemple micro-ingress.yaml suivant :

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: micro-ingress
  namespace: default
spec:
  rules:
    - host: hostname.mydomain.com
      http:
        paths:
          - backend:
              serviceName: hostname-svc
              servicePort: 80
    - host: apache.mydomain.com
      http:
        paths:
          - backend:
              serviceName: apache-svc
              servicePort: 80

Remarque : pour plus d'informations, consultez la page Hébergement virtuel basé sur le nom.

6.    Pour appliquer votre configuration, exécutez la commande suivante :

kubectl apply -f micro-ingress.yaml

Remarque : cette ressource Ingress définit les règles qui redirigent tout élément relatif à hostname.mydomain.com vers hostname-svc, et tout élément relatif à apache.mydomain.com vers apache-svc. Toute demande qui ne correspond pas à la règle renvoie un message d'erreur 404 « Introuvable » ( Non trouvé).

Si vous décrivez l'Ingress, vous recevrez un message similaire à ce qui suit :

 Name:             micro-ingress
 Namespace:        default
 Address:          
 Default backend:  default-http-backend:80 (<none>)
 Rules:
  Host                   Path  Backends
  ----                   ----  --------
  hostname.mydomain.com  
                            hostname-svc:80 (192.168.2.45:9376,192.168.3.236:9376)
  apache.mydomain.com    
                            apache-svc:80 (192.168.2.47:80,192.168.3.45:80)

Test du contrôleur d'Ingress NGINX

1.    Pour accéder à l'URL DNS de l'équilibreur de charge à partir de la ligne de commande, exécutez la commande suivante :

curl -I
http://aaa71bxxxxx-11xxxxx10.us-east-1.elb.amazonaws.com/

Remarque : le point de terminaison de l'équilibreur de charge provient de la section Accès au contrôleur d'Ingress et exécution de l’application précédente.

Vous obtenez une sortie similaire à ce qui suit :

HTTP/1.1 404 Not Found
Server: nginx/1.17.5
Date: Mon, 25 Nov 2019 20:50:58 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive

Remarque : le serveur par défaut renvoie une page « Not Found » (Introuvable) avec un code de statut 404 pour toutes les demandes de domaines pour lesquelles aucune règle d'Ingress n'est définie. 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 host (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.

2.    Ajoutez l'en-tête Host à la demande.

Il s'agit d'une demande basée sur le premier domaine configuré :

curl -I -H "Host: hostname.mydomain.com"
http://aaa25a5010daa11eaa41e121e71bd6ca-113564610.us-east-1.elb.amazonaws.com/

Vous obtenez une sortie similaire à ce qui suit :

HTTP/1.1 200 OK
Server: nginx/1.17.5
Content-Type: text/html
Content-Length: 612
Connection: keep-alive

Il s'agit d'une demande basée sur le deuxième domaine configuré :

curl -I -H "Host: apache.mydomain.com"
http://aaa25a5010daa11eaa41e121e71bd6ca-113564610.us-east-1.elb.amazonaws.com/

Vous obtenez une sortie similaire à ce qui suit :

HTTP/1.1 200 OK
Server: nginx/1.17.5
Content-Type: text/html
Content-Length: 45
Connection: keep-alive

Une fois que vous avez ajouté l'en-tête Host le contrôleur d'Ingress peut rediriger le trafic vers le service backend configuré, car il correspond à la configuration définie dans l’Ingress.

Si vous souhaitez 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 d'accès avec l’Ingress. Consultez l'exemple suivant :

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: path-ingress
annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: hostname.mydomain.com
  http:
	paths:
	- path: /login
	  backend:
		serviceName: service1
		servicePort: 4200
	- path: /cart
	  backend:
		serviceName: service2
		servicePort: 8080

L'exemple précédent renvoie uniquement la réponse 200 lorsque les demandes ont pour en-tête d'hôte hostname.mydomain.com. Les demandes sont accessibles sur les chemins d’accès /login ou /cart . Pour toutes les autres demandes, les réponses 404 sont renvoyées. 


Cet article vous a-t-il été utile ?

Cette page peut-elle être améliorée ?


Vous avez besoin d’aide ?