Prefazione
Di seguito è riportato un esempio di integrazione di Kubernetes con il servizio Edgio Delivery CDN per i professionisti Kubernetes esperti. Presuppone un livello di conoscenza in Kubernetes e una conoscenza dei protocolli Internet standard come TCP, DNS e HTTP/HTTPS. L’obiettivo finale è dimostrare un modo per far apparire il servizio Edgio Delivery CDN come ingresso standard. L’utente Kubernetes può mantenere la configurazione di ingresso in sistemi familiari come Portainer o Terraform.
Kubernetes
Kubernetes.io definisce Kubernetes come “un sistema open source per automatizzare la distribuzione, la scalabilità e la gestione di applicazioni containerizzate”. Esistono diversi modi per aprire un cluster. “Il modo più rapido e semplice è quello di sfruttare uno dei numerosi provider di servizi cloud che consentono implementazioni con un solo clic.”
I cluster di Kubernetes contengono molte parti. Nella demo, ci concentreremo su un sottoinsieme del totale.
Parti Kubernetes
- Nodo: Macchina o macchina virtuale che ospita i carichi di lavoro e i servizi.
- Carico di lavoro: Applicazione semplice o complessa
- Pod: Contenitori in cui è in esecuzione il software applicativo. Uno o più pod costituiscono un carico di lavoro.
- Servizio: Un meccanismo che espone un carico di lavoro ad altri carichi di lavoro o ingressi
- Ingress: Un meccanismo per esporre i servizi al mondo esterno
Edgio
Edgio rende la vita connessa più veloce, sicura e semplice da gestire grazie a velocità, sicurezza e semplicità senza pari alla periferia della rete grazie alle nostre soluzioni di delivery, applicazioni e streaming perfettamente integrate. La nostra tecnologia su scala globale e i nostri servizi di esperti alimentano i marchi più importanti del mondo con la capacità di offrire istruzione, intrattenimento, eventi e applicazioni più veloci, dinamiche e senza intoppi a ogni utente. Dedicata a fornire un’assistenza clienti senza precedenti e ad ampliare il valore in ogni fase del percorso, Edgio è un partner di scelta, che guida il traffico Internet in tutto il mondo per supportare i programmi, i film, gli sport, i giochi e la musica più popolari e i siti Web a caricamento istantaneo.
Architettura
CDN consegna Edgio
Per questa demo, utilizziamo l’SDK Python Edgio presso GitHub – llnw/llnw-sdk-Python: Limelight Networks Python SDK. La configurazione di base verrà mantenuta semplice.
Per configurare la CDN, sono necessari i seguenti dati (diversi dall’autenticazione).
- Shortname: Identificatore univoco all’interno di Edgio Delivery CDN che contiene regole CDN.
- Nome host pubblicato: Il nome host che si affaccia su Internet dal CDN. Nel caso di questa demo, il nome host cstradtman.s.llnwi.net è stato precedentemente configurato.
- Percorso URL pubblicato: Il percorso mappato nella regola specifica in questione.
- Nome host di origine: Il nome host dell’origine. In questo caso, un record round-robin punta al cluster Kubernetes.
- Percorso URL di origine: Il percorso di destinazione associato al nome host. In questo caso, sarà vuoto poiché lo descriveremo più avanti in questo documento. In questa demo, i carichi di lavoro saranno differenziati per numero di porta e non per percorso.
DNS
La demo utilizza l’API DNS Vultr. La configurazione della CDN utilizzando gli indirizzi IP come origini non è una procedura consigliata. La demo utilizza un’API per creare o modificare un round robin Un record che punta ai nodi cluster.
Cluster
La demo si trova in Vultr su un cluster a tre nodi.
Spazi dei nomi
La demo esisterà sotto lo spazio dei nomi predefinito poiché è l’unica cosa in esecuzione su questo cluster
Nodi
- Cluster VKE: 3 nodi ciascuno con
- RAM 4G.
- Disco da 80 G.
- 2 vCPU
- Rete 1 G.
Carichi di lavoro
Il carico di lavoro è un semplice programma Python che restituisce informazioni di base sulla connessione HTTP. Implementiamo questa demo in linea, che non è un tipico metodo di distribuzione. Tuttavia, consente alla demo di essere completamente autonoma anziché avere dipendenze esterne per creare i contenitori e memorizzarli. Il codice sorgente è riportato nell’appendice 1. Il codice Python effettivo è corsivo e il codice YAML che descrive la distribuzione non lo è. Il carico di lavoro utilizza la porta TCP 8000.
Servizi
Sono disponibili diversi tipi di servizio. “Stiamo utilizzando il tipo di servizio “NodePort”.” Espone il servizio sugli indirizzi IP esterni del cluster su un numero di porta alto selezionato casualmente. Kubernetes si occupa della connessione a un nodo in cui viene eseguito il carico di lavoro.
Ingresso
Kubernetes Ingress è un oggetto software che descrive il comportamento di un insieme di risorse che rendono disponibile un servizio Kubernetes al di fuori del cluster.
Una centralina Ingress combina software e/o hardware che crea un’istanza dell’oggetto software Ingress.
Una CDN è un reverse proxy distribuito ricco di funzionalità, oltre alla funzione reverse proxy, le CDN di solito dispongono di algoritmi di cache flessibili, diversità geografica, funzioni di sicurezza (ACL (GEO, method, regex), Web Applications Firewall, watermarking e altre funzioni più avanzate non disponibili nei semplici reverse proxy.
Le API per il monitoraggio degli oggetti Kubernetes sono ben definite e una serie di proxy inversi HTTP e bilanciatori di carico sono stati estesi per funzionare come controller Ingress. Ad esempio, NGINX e HAProxy sono proxy della vecchia scuola che sono stati estesi per funzionare come controller di ingresso e quelli come Traefik e Itsio sono stati sviluppati in parallelo a Kubernetes . Una CDN è una naturale progressione successiva da semplici proxy inversi. Nel caso di questa demo, verrà creato un controller di ingresso personalizzato che controlla Edgio Delivery CDN. I dati generalmente richiesti per descrivere un ingresso sono
- Nome host pubblico: Il nome host su cui sarà disponibile il servizio Kubernetes
- Percorso pubblico: Il percorso associato al nome host pubblico su cui saranno disponibili i servizi Kubernetes
- Nome del servizio back-end: Nome del servizio definito da una stanza dei servizi Kubernetes
- Porta backend: Nome corrispondente alla descrizione della porta nella descrizione del servizio
Mappature risorse CDN Edgio Delivery:
Kubernetes |
CDN consegna Edgio |
Nome host pubblico |
Nome host pubblicato |
Percorso pubblico |
Percorso URL pubblicato |
Nome servizio back-end Unico all’interno del cluster Kubernetes Non noto/disponibile al mondo esterno |
Nome host di origine Nome di dominio completo Non uno a uno |
La logica alla base è:
- Attendere l’evento di ingresso dello spazio dei nomi dal cluster
- “Se il tipo di evento è “aggiunto”.”
- Ottenere l’indirizzo IP dei nodi nel cluster
- Creare un record DNS in vultr
- Creare regole CDN in Edgio CDN rivolte verso i record DNS creati e la porta allocata dal servizio NodePort.
- “Se il tipo di evento è “modificato”.”
- Individuare le regole CDN in Edgio CDN che corrispondono all’ingresso esistente
- Modificare le regole in Edgio CDN per riflettere i nuovi dati nell’evento
- “Se il tipo di evento è “eliminato”.”
- Individuare le regole CDN in Edgio CDN che corrispondono all’ingresso rimosso
- Rimuovere i record DNS in Vultr associati a questo ingresso
- Rimuovere le regole CDN in Edgio che corrispondono all’ingresso rimosso
Configurazione
Oggetti
Gli oggetti Kubernetes sono descritti nei file YAML. In Kubernetes, ogni configurazione è un oggetto. È possibile inserire tutte le configurazioni di distribuzione in un unico file. È pratica comune separarli in base a quale parte della distribuzione descrivono.
Implementazione
Nell’Appendice 1, è presente un grande file YAML che è una combinazione di codice Python e YAML. Tutto dopo “spec.template.spec.containers.command” è il codice Python che viene trasformato in un container durante la distribuzione. Dal punto di vista dell’oggetto Kubernetes le linee che sono importanti per noi per la demo sono:
- Tipo: Distribuzione: Descrive l’oggetto come distribuzione
- Metadata.name: Il nome viene utilizzato dall’oggetto servizio per creare il collegamento tra i due.
- Spec.selector.matchlabels.app: indica a quali POD verrà applicata la distribuzione.
- Spec.template.spec.containers.image: Punta all’immagine ufficiale docker hub Python 3
- Spec.template.spec.containers.ports.name: Un’etichetta per la porta a cui fare riferimento nel servizio altri oggetti in questo caso
- Spec.template.spec.Containers.ports.containerport: Elenca la porta TCP esposta dal contenitore in esecuzione
Servizio
- Tipo: Distribuzione: Descrive l’oggetto come distribuzione
- Metadata.name: Il nome viene utilizzato dall’oggetto in ingresso per creare il collegamento tra i due.
- Spec.selector.app: indica il nome della distribuzione: Pywai-inline-service come indicato nell’oggetto di distribuzione.
- Spec.selector.type: Nodeport definisce questo servizio come tipo Nodeport come descritto sopra
- Spec.ports.name: L’etichetta della porta a cui fanno riferimento altri oggetti (ingresso in questo caso)
- Spec.ports.protocol: definisce il protocollo IP in uso – TCP
- Spec.ports.port: Definisce la porta esposta da questo servizio
- Spec.ports.targetPort: Punta alla porta esposta dall’implementazione, in questo caso pywai-inline-Deployment
Ingresso
Nell’Appendice 3, viene visualizzato il file YAML che descrive l’oggetto Kubernetes per il controller di ingresso Edgio. Gli oggetti da trattare sono:
- Tipo: Ingress – questo dice a Kubernetes che si tratta di un oggetto Ingress
- Medatdata.name – tutto a Kubernetes deve avere un nome
- Metadata.labels.cdn – questo tag viene utilizzato per segnalare al controller di ingresso che questo oggetto è per il controller di ingresso edgio
- Spec.rules.host – nome host pubblico per esporre il servizio.
- Spec.rules.http.paths.path – percorso associato al servizio.
- Spec.rules.http.paths.backend.service.name – etichetta del servizio da esporre
- Spec.rules.http.paths.backend.service.port.name – etichetta del porto del servizio da esporre
Mappe di configurazione
Segreti
Kubernetes ha un concetto integrato di segreti per la memorizzazione di dati sensibili. Questa demo utilizza questa funzione per i nomi utente e le chiavi condivise sia per Edgio SDK che per l’API DNS Vultr
Esempi di codice
Il codice per questa dimostrazione è incluso nei POS. git
- SDK Python di Edgio Delivery
- Implementazione demo di Kubernetes
- https://github.com/llnw/edgio-delivery-k8s-demo
- Si tratta di una serie di oggetti Kubernetes descritti come yaml che mostrano come implementare l’integrazione di Edgio Delivery
- Demo del controller di ingresso Edgio Delivery
- https://github.com/llnw/edgio-delivery-k8s-ingress-demo
- Questo è il codice effettivo che implementa il controller di ingresso Edgio Delivery
- Nel lungo periodo dovrebbe essere eseguito come servizio all’interno di Kubernetes, tuttavia per mantenere la demo semplice viene eseguito semplicemente come un processo separato
Aggiunte e miglioramenti futuri al progetto attuale
In un post futuro, mostreremo come sfruttare altre soluzioni Edgio per esempio le applicazioni. È possibile utilizzare il cluster Kubernetes per sfruttare e sincronizzare le configurazioni tra più offerte Edgio CDN per diversi flussi di lavoro.
Appendice 1 – pywai-inline-Deployment.yaml
ApiVersion: Apps/v1
Tipo: Distribuzione
metadati:
nome: pywai-inline-deployment
specifiche:
selettore:
Etichette abbinate:
app: implementazione di pywai-in-line
repliche: 1
modello:
metadati:
etichette:
app: implementazione di pywai-in-line
specifiche:
contenitori:
– nome: python
immagine: python:3
comando:
– /bin/sh
– “-c”
– |
cat > /test.py <<EOF
#!/usr/bin/env python3
“”
Server HTTP molto semplice in Python per le richieste di registrazione
Utilizzo:
./server.py [<porta>]
“”
Dal http.server importare BaseHTTPRequestHandler, HTTPServer
importa registrazione
importa pprint
Classe S(BaseHTTPRequestHandler):
def _set_response(self):
self.send_response(200)
self.send_header(‘Content-type’, «text/html»)
self.end_header()
def do_GET(self):
logging.info(“GET richiesta,\npercorso: %S\nintestazioni:\n%s\n”, str(self.path), str(pprint.pformat(self.headers))
self._set_response()
headerinfo=pprint.pformat(self.headers.items())
clientinfo=pprint.pformat(self.client_address)
lineinfo=pprint.pformat(self.requestline)
versioninfo=pprint.pformat(self.request_version)
self.wfile.write(“<pre> {} </pre>”.format(headerinfo).encode(“utf-8”))
self.wfile.write(“<pre> {} </pre>”.format(clientinfo).encode(“utf-8”))
self.wfile.write(“<pre> {} </pre>”.format(lineinfo).encode(“utf-8”))
self.wfile.write(“<pre> {} </pre>”.format(versioninfo).encode(“utf-8”))
Esecuzione def (server_class=HTTPServer, handler_class=S, porta=8080):
Logging.basicConfig(level=logging.INFO)
“indirizzo_server = (“, porta)”
httpd = server_class(server_address, handler_class)
logging.info(‘Starting httpd…\n»)
prova:
httpd.serve_forever()
Eccetto KeyboardInterrupt:
superato
httpd.server_close()
logging.info(‘Stopping httpd…\n»)
se __name__ == «__main__»:
da argv. importazione sist
se len(argv) == 2:
run(port=int(argv[1]))
altrimenti:
esegui()
EOF
exec python /test.py 8000
porte:
– nome: http
ContainerPort: 8000
Appendice 2 – pywai-inline-service.yaml
ApiVersion: v1
Tipo: Servizio
metadati:
nome: pywai-inline-service
specifiche:
selettore:
app: implementazione di pywai-in-line
Tipo: NodePort
porte:
– nome: http
protocollo: TCP
porto: 80
TargetPort: 8000
Appendice 3 – pywai-edgio-ingress.yaml
ApiVersion: Networking.k8s.io/v1
Tipo: Ingresso
metadati:
nome: external-pywai-in-line-ingress
annotazioni:
kubernetes.io/ingress.class: edgio
etichette:
cdn: edgio
specifiche:
regole:
– Host: <Immettere un nome abbreviato univoco> .s.llnwi.net
http:
percorsi:
– percorso: /fred
Tipo di percorso: Esatto
back-end:
servizio:
nome: external-pywai-inline-service
porta:
nome: pywai-port