Come posso fornire l'accesso esterno a più servizi Kubernetes nel mio cluster Amazon EKS?
Desidero fornire l'accesso esterno a più servizi Kubernetes nel mio cluster Amazon Elastic Kubernetes Service (Amazon EKS).
Breve descrizione
Usa il controller in ingresso NGINX o AWS Load Balancer Controller per Kubernetes per fornire l'accesso esterno a più servizi Kubernetes nel cluster Amazon EKS. Il controller in ingresso NGINX è gestito principalmente da NGINX. Per verificare la presenza di problemi nel controller in ingresso NGINX, consulta l'elenco dei problemi sul sito web di GitHub. AWS Load Balancer Controller è gestito da Amazon Web Services (AWS). Per verificare la presenza di problemi in AWS Load Balancer Controller, consulta l'elenco dei problemi sul sito web di GitHub.
Importante: Il controller in ingresso e IngressClass (dal sito web di Kubernetes) differiscono da Ingress (dal sito web di Kubernetes). Ingress è una risorsa di Kubernetes che espone i percorsi HTTP e HTTPS dall'esterno del cluster ai servizi all'interno del cluster. In genere, il controller in ingresso soddisfa Ingress con un sistema di bilanciamento del carico. Non è possibile usare Ingress senza un controller in ingresso. IngressClass viene utilizzato per identificare il controller in ingresso da utilizzare per soddisfare la richiesta dell'oggetto Ingress.
Prerequisito: Installa AWS Load Balancer Controller. È consigliabile utilizzare AWS Load Balancer Controller per creare e gestire un Network Load Balancer per gli oggetti assistenza di tipo LoadBalancer in Amazon EKS.
Risoluzione
La risoluzione seguente utilizza il controller in ingresso kubernetes/ingress-nginx sul sito web di Kubernetes GitHub. L'altro controller in ingresso di uso pubblico è nginxinc/kubernetes-ingress sul sito web di GitHub di NGINX.
Implementa il controller in ingresso NGINX per Kubernetes
Puoi implementare il controller in ingresso NGINX per Kubernetes tramite Transmission Control Protocol (TCP) o Transport Layer Security (TLS).
Nota: La seguente risoluzione è stata testata su Amazon EKS versione 1.22, controller in ingresso NGINX versione 1.3.0 e AWS Load Balancer Controller versione 2.4.3.
(Opzione 1) Controller in ingresso NGINX con TCP su Network Load Balancer
1. Recupera il file YAML per implementare i seguenti oggetti: 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. Modifica il file. Quindi, nella sezione degli oggetti assistenza ingress-nginx-controller sostituisci tutte le annotazioni service.beta.kubernetes.io con le seguenti:
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. Applica il manifesto:
kubectl apply -f deploy.yaml
Esempio di output:
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
(Opzione 2) Terminazione TLS del controller in ingresso NGINX su Network Load Balancer
Per impostazione predefinita, la soluzione precedente termina TLS nel controller in ingresso NGINX. È inoltre possibile configurare il servizio NGINX Ingress in modo che termini TLS su Network Load Balancer.
1. Scarica il modello deploy.yaml:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
2. Modifica il file. Quindi, nella sezione degli oggetti assistenza ingress-nginx-controller, sostituisci tutte le annotazioni service.beta.kubernetes.io con le seguenti:
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: Assicurati di includere l’ARN per service.beta.kubernetes.io/aws-load-balancer-ssl-cert.
3. Modifica il file e cambia il CIDR di Amazon Virtual Private Cloud (Amazon VPC) per il cluster Kubernetes:
proxy-real-ip-cidr: XXX.XXX.XXX/XX
4. Applica il manifesto:
kubectl apply -f deploy.yaml
Nota: Il manifesto precedente utilizza ExternalTrafficPolicy come locale per preservare l'indirizzo IP di origine (client). L'utilizzo di questa configurazione con un nome DHCP personalizzato in Amazon VPC genera un problema. Per evitare il problema, applica la seguente patch al kube-proxy:
kubectl edit daemonset kube-proxy -n kube-system
5. Modifica il manifesto in modo che includa il seguente frammento:
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
Verifica le risorse distribuite
AWS Load Balancer Controller
Comando:
kubectl get all -n kube-system --selector app.kubernetes.io/instance=aws-load-balancer-controller
Esempio di output:
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
Controller in ingresso NGINX
Comando:
kubectl get all -n ingress-nginx --selector app.kubernetes.io/instance=ingress-nginx
Esempio di output:
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
Esempio di output:
NAME CONTROLLER PARAMETERS AGE alb ingress.k8s.aws/alb IngressClassParams.elbv2.k8s.aws/alb 19h nginx k8s.io/ingress-nginx none 15h
Testa la configurazione della distribuzione
Nota: Il passaggio successivo prevede l'esecuzione di due microservizi. I microservizi sono esposti internamente con Kubernetes come tipo predefinito.
1. Configura le distribuzioni o i microservizi. Ad esempio, hostname-app e apache-app.
Esempio di file hostname-app-svc.yaml per 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
Esempio di file apache-app-svc.yaml per 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. Applica le configurazioni.
hostname-app:
kubectl apply -f hostname-app-svc.yaml
apache-app:
kubectl apply -f apache-app-svc.yaml
3. Verifica che le risorse siano state create.
Distribuzioni
Comando:
kubectl get deployment hostname-app apache-app -n default
Esempio di output:
NAME READY UP-TO-DATE AVAILABLE AGE hostname-app 2/2 2 2 29m apache-app 2/2 2 2 29m
Servizi
Comando:
kubectl get svc apache-svc hostname-svc -n default
Esempio di output:
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
Testa il controller in ingresso NGINX
1. Accedi all'URL DNS del sistema di bilanciamento del carico recuperato dalla riga di comando:
curl -I ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com
Esempio di output:
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:**Il server predefinito restituisce una pagina 404 Non trovato per tutte le richieste di dominio che non hanno regole di ingresso definite. In base alle regole definite, il controller in ingresso non devia il traffico verso il servizio backend specificato a meno che la richiesta non corrisponda alla configurazione. Poiché il campo host è configurato per l'oggetto Ingress, è necessario fornire l'intestazione Host della richiesta con lo stesso nome host. In un ambiente di test, usa un flag curl per fornire l'intestazione Host. In un ambiente di produzione, esegui il mapping del nome DNS del sistema di bilanciamento del carico al nome host di un provider DNS, ad esempio Amazon Route 53.
2. Implementa l'ingresso in modo che si interfacci con i servizi utilizzando un sistema di bilanciamento del carico unico fornito dal controller in ingresso NGINX.
Esempio 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: Per ulteriori informazioni, consulta Hosting virtuale basato su nome (dal sito web di Kubernetes).
3. Verifica che la risorsa sia stata creata.
Ingress
Comando:
kubectl get ingress -n default
Esempio di output:
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. Aggiungi l’intestazione Host alla richiesta.
Primo dominio configurato:
curl -i -H "Host: hostname.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Esempio di output:
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
Secondo dominio configurato:
curl -i -H "Host: apache.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
Esempio di output:
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
Dopo aver aggiunto l'intestazione Host, il controller in ingresso reindirizza il traffico al servizio configurato di backend in quanto corrisponde alla configurazione definita in Ingress.
Per mantenere lo stesso nome di dominio ma deviare il traffico in base al percorso a cui si accede, è necessario aggiungere un routing basato su percorso con Ingress.
Ad esempio:
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: Se le richieste hanno mydomain.com come intestazione Host, l'esempio precedente restituisce soltanto la risposta 200. È possibile accedere alle richieste tramite i percorsi /hostname e /apache. Per tutte le altre richieste, viene restituita la risposta 404.
5. Verifica che sia stato aggiunto il routing basato su percorso:
Comando:
kubectl get ingress -n default
Uscita:
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
-oppure-
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/apache
Verifica l'ingresso utilizzando AWS Load Balancer Controller
1. Avvia Application Load Balancer utilizzando il seguente esempio di manifesto Ingress:
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. Verifica che Application Load Balancer venga avviato.
Comando:
kubectl get ingress -n default
Uscita:
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
Richiesta basata sul primo dominio configurato:
curl -i -H "Host: alb.hostname.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Esempio di output:
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
Richiesta basata sul secondo dominio configurato:
curl -i -H "Host: alb.apache.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
Esempio di output:
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
Video correlati
Contenuto pertinente
- AWS UFFICIALEAggiornata un anno fa
- AWS UFFICIALEAggiornata un mese fa