{"id":35941,"date":"2019-10-31T22:07:41","date_gmt":"2019-10-31T19:07:41","guid":{"rendered":"https:\/\/prohoster.info\/blog\/chto-zhe-takoe-gitops\/"},"modified":"2019-10-31T22:07:41","modified_gmt":"2019-10-31T19:07:41","slug":"chto-zhe-takoe-gitops","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/chto-zhe-takoe-gitops","title":{"rendered":"Che cos'\u00e8 GitOps?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i><b>Nota di traduzione.<\/b>: Dopo una recente pubblicazione <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/456754\/\">di materiale<\/a><\/noindex> sui metodi pull e push in GitOps, abbiamo notato un interesse per questo modello in generale; tuttavia, le pubblicazioni in lingua russa su questo argomento sono state molto scarse (sul sito di Habr non ce ne sono affatto). Pertanto, siamo lieti di offrire alla vostra attenzione la traduzione di un altro articolo \u2014 sebbene sia gi\u00e0 di quasi un anno fa! \u2014 della societ\u00e0 Weaveworks, il cui fondatore ha coniato il termine \u00abGitOps\u00bb. Nel testo viene spiegata la natura dell'approccio e le principali differenze rispetto a soluzioni gi\u00e0 esistenti.<\/i><\/p>\n<p>\nUn anno fa abbiamo pubblicato <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/gitops-operations-by-pull-request\">un'introduzione a GitOps<\/a><\/noindex>. All'epoca abbiamo raccontato come il team di Weaveworks ha avviato un SaaS interamente basato su Kubernetes e ha sviluppato un insieme di best practices prescrittive per il deployment, la gestione e il monitoraggio in un ambiente cloud native.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>L'articolo \u00e8 stato molto popolare. Altre persone hanno iniziato a parlare di GitOps e a pubblicare nuovi strumenti per <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/hasura\/gitkube\">git push<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/dzone.com\/articles\/weaveworks-gitops-developer-toolkit-part-one-skaff\">lo sviluppo<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/storing-secure-sealed-secrets-using-gitops\">di segreti<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.alexellis.io\/introducing-openfaas-cloud\/\">funzioni<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/jenkins.io\/blog\/2018\/03\/19\/introducing-jenkins-x\/\">all'integrazione continua<\/a><\/noindex> e cos\u00ec via. Sul nostro sito sono comparse <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/category\/gitops\/\">un gran numero di<\/a><\/noindex> pubblicazioni e casi d'uso di GitOps. Ma alcune persone avevano ancora delle domande. In cosa si distingue il modello rispetto al tradizionale <noindex><a rel=\"nofollow\" href=\"https:\/\/puppet.com\/blog\/a-deployment-pipeline-for-infrastructure-a-devops-case-study-at-nbn\">infrastructure as code<\/a><\/noindex> e alla consegna continua (<noindex><a rel=\"nofollow\" href=\"https:\/\/puppet.com\/blog\/a-deployment-pipeline-for-infrastructure-a-devops-case-study-at-nbn\">continuous delivery<\/a><\/noindex>)? \u00c8 necessario utilizzare Kubernetes?<\/p>\n<p>Presto ci siamo resi conto che era necessaria una nuova descrizione che offrisse:<\/p>\n<ol>\n<li> Un gran numero di esempi e storie;<\/li>\n<li> Una definizione concreta di GitOps;<\/li>\n<li> Un confronto con la tradizionale continuous delivery.<\/li>\n<\/ol>\n<p>\nIn questo articolo abbiamo cercato di coprire tutti questi temi. Troverete un'introduzione aggiornata a GitOps e un punto di vista da parte degli sviluppatori e del CI\/CD. Ci concentriamo principalmente su Kubernetes, anche se il modello pu\u00f2 essere generalizzato.<\/p>\n<h2>Vi presentiamo: GitOps<\/h2>\n<p>\nImmagina Alice. Gestisce l'azienda Family Insurance, che offre polizze per l'assicurazione sulla salute, automobili, propriet\u00e0 immobiliari e assicurazione turistica a persone troppo occupate per occuparsi dei dettagli dei contratti da sole. La sua attivit\u00e0 \u00e8 iniziata come un progetto secondario, quando Alice lavorava in banca come data scientist. Un giorno ha capito che poteva utilizzare avanzati algoritmi informatici per un'analisi dei dati e una formulazione di pacchetti assicurativi pi\u00f9 efficiente. Gli investitori hanno finanziato il progetto, e ora la sua azienda genera oltre 20 milioni di dollari all'anno e cresce rapidamente. Attualmente, 180 persone lavorano in diverse posizioni. Tra loro c'\u00e8 il team tecnologico che si occupa dello sviluppo, della manutenzione del sito web, del database e dell'analisi della clientela. La squadra di 60 persone \u00e8 guidata da Bob, il direttore tecnico dell'azienda.<\/p>\n<p>Il team di Bob distribuisce sistemi di produzione nel cloud. Le loro applicazioni principali funzionano su GKE, sfruttando i vantaggi di Kubernetes in Google Cloud. Inoltre, utilizzano vari strumenti per la gestione dei dati e l'analisi.<\/p>\n<p>Family Insurance non intendeva utilizzare i container, ma si \u00e8 lasciata contagiare dall'entusiasmo attorno a Docker. Presto gli specialisti dell'azienda hanno scoperto che GKE permette di distribuire cluster per testare nuove funzionalit\u00e0 in modo semplice e senza sforzo. Sono stati aggiunti Jenkins per CI e Quay per organizzare il registro dei container, e sono stati scritti script per Jenkins che pushavano nuovi container e configurazioni in GKE.<\/p>\n<p>\u00c8 passata un po' di tempo. Alice e Bob si sono scoraggiati dalle prestazioni dell'approccio scelto e dal suo impatto sul business. L'implementazione dei container non ha migliorato le prestazioni tanto quanto si sperava. A volte i deployment si rompevano e non era chiaro se il colpevole fosse rappresentato dalle modifiche al codice. \u00c8 stato anche difficile tenere traccia delle modifiche delle configurazioni. Spesso era necessario creare un nuovo cluster e spostare le applicazioni in esso, poich\u00e9 era il modo pi\u00f9 semplice per risolvere il caos in cui era diventato il sistema. Alice temeva che la situazione peggiorasse man mano che l'applicazione si sviluppava (tra l'altro, c'era un nuovo progetto in fase di avvio basato su machine learning). Bob aveva automatizzato gran parte del lavoro e non capiva perch\u00e9 il pipeline fosse ancora instabile, scalasse male e richiedesse periodicamente un intervento manuale.<\/p>\n<p><b>Poi hanno scoperto GitOps. Questa soluzione si \u00e8 rivelata proprio ci\u00f2 di cui avevano bisogno per proseguire con sicurezza.<\/b><\/p>\n<p>Alice e Bob avevano gi\u00e0 sentito parlare per anni di flussi di lavoro basati su Git, DevOps e infrastructure as code. L'unicit\u00e0 di GitOps \u00e8 che porta una serie di best practice\u2014categoriche e normative\u2014per implementare queste idee nel contesto di Kubernetes. Questo tema <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/search?q=gitops&amp;src=typd\">\u00e8 stato sollevato pi\u00f9 volte<\/a><\/noindex>, incluso in <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/gitops-high-velocity-cicd-for-kubernetes\">un blog di Weaveworks<\/a><\/noindex>.<\/p>\n<p>Family Insurance ha deciso di implementare GitOps. Ora l'azienda ha un modello di operazioni automatizzato compatibile con Kubernetes che combina <i>velocit\u00e0<\/i> per <i>stabilit\u00e0<\/i>, poich\u00e9 hanno:<\/p>\n<ul>\n<li> scoperto che la produttivit\u00e0 del team \u00e8 raddoppiata e nessuno di loro \u00e8 andato in crisi;<\/li>\n<li> smettere di gestire gli script. Invece, ora possono concentrarsi su nuove funzionalit\u00e0 e migliorare le pratiche ingegneristiche\u2014ad esempio, implementare il canary release e migliorare i test;<\/li>\n<li> ottimizzato il processo di deployment\u2014ora raramente si rompe;<\/li>\n<li> hanno ottenuto la possibilit\u00e0 di ripristinare i deployment dopo guasti parziali senza intervento manuale;<\/li>\n<li> acquisito b<i>un<\/i>maggiore fiducia nei sistemi di fornitura. Alice e Bob hanno scoperto che era possibile dividere il team in gruppi che si occupano di microservizi e lavorano in parallelo;<\/li>\n<li> possono apportare 30-50 modifiche al progetto ogni giorno grazie agli sforzi di ciascun gruppo e provare nuove tecniche;<\/li>\n<li> facilmente coinvolgono nuovi sviluppatori nel progetto, che possono applicare aggiornamenti in produzione tramite pull request gi\u00e0 dopo poche ore;<\/li>\n<li> superano facilmente l'audit nel contesto del SOC2 <i>(per l'adeguamento dei fornitori di servizi ai requisiti di gestione sicura dei dati; leggi di pi\u00f9, ad esempio, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.imperva.com\/learn\/data-security\/soc-2-compliance\/\">qui<\/a><\/noindex> \u2014 nota del traduttore.)<\/i>.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Cosa \u00e8 successo?<\/h3>\n<p>\nGitOps \u00e8 due cose:<\/p>\n<ol>\n<li> Un modello operativo per Kubernetes e cloud native. Fornisce un insieme di migliori pratiche per il deployment, la gestione e il monitoraggio di cluster e applicazioni containerizzati. Una definizione elegante in forma di <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/vitorsilva\/status\/999978906903080961\">una diapositiva<\/a><\/noindex> di <noindex><a rel=\"nofollow\" href=\"https:\/\/2018.agilept.org\/speaker_luis_faceira.html\">Luis Faceira<\/a><\/noindex>:\n<\/li>\n<li> Il percorso per creare un ambiente orientato agli sviluppatori per la gestione delle applicazioni. Applichiamo il flusso di lavoro Git sia all'operativit\u00e0 che allo sviluppo. Si noti che non si tratta semplicemente di un Git push, ma di organizzare l'intero insieme di strumenti CI\/CD e UI\/UX.<\/li>\n<\/ol>\n<p><\/p>\n<h3>Due parole su Git<\/h3>\n<p>\nSe non sei familiare con i sistemi di controllo versione e il flusso di lavoro basato su Git, ti consigliamo vivamente di approfondire la cosa. All'inizio, lavorare con rami e pull request pu\u00f2 sembrare magia nera, ma i vantaggi superano gli sforzi richiesti. Ecco <noindex><a rel=\"nofollow\" href=\"https:\/\/codeburst.io\/trunk-based-development-vs-git-flow-a0212a6cae64\">un buon articolo<\/a><\/noindex> per iniziare.<\/p>\n<h2>Come funziona Kubernetes<\/h2>\n<p>\nNella nostra storia, Alice e Bob si sono avvicinati a GitOps dopo aver lavorato per un po' con Kubernetes. Infatti, GitOps \u00e8 strettamente legato a Kubernetes: \u00e8 un modello operativo per infrastrutture e applicazioni basate su Kubernetes.<\/p>\n<h3>Cosa offre Kubernetes agli utenti?<\/h3>\n<p>\nEcco alcune delle principali funzionalit\u00e0:<\/p>\n<ol>\n<li> Nel modello Kubernetes, tutto pu\u00f2 essere descritto in forma dichiarativa.<\/li>\n<li> Il server API di Kubernetes accetta tale dichiarazione come input e poi cerca continuamente di riportare il cluster nello stato descritto nella dichiarazione.<\/li>\n<li> Le dichiarazioni sono sufficienti per descrivere e gestire una grande variet\u00e0 di carichi di lavoro \u2014 \"applicazioni\".<\/li>\n<li> Di conseguenza, le modifiche all'applicazione e al cluster si verificano a causa di:\n<ul>\n<li> cambiamenti nelle immagini dei container;<\/li>\n<li> cambiamenti nella specifica dichiarativa;<\/li>\n<li> errori nell'ambiente - come il crash dei container.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><\/p>\n<h3>Le splendide capacit\u00e0 di convergenza di Kubernetes<\/h3>\n<p>\nQuando un amministratore apporta modifiche alla configurazione, l'orchestratore Kubernetes le applicher\u00e0 al cluster finch\u00e9 il suo stato <i>non si avvicina alla nuova configurazione<\/i>. Questo modello funziona per qualsiasi risorsa Kubernetes ed \u00e8 ampliabile tramite Custom Resource Definitions (CRDs). Pertanto, i deployment Kubernetes hanno le seguenti meravigliose caratteristiche:<\/p>\n<ul>\n<li> <b>Automazione<\/b>: gli aggiornamenti di Kubernetes forniscono un meccanismo per automatizzare il processo di applicazione delle modifiche in modo corretto e tempestivo.<\/li>\n<li> <b>Convergenza<\/b>: Kubernetes continuer\u00e0 a tentare gli aggiornamenti fino al raggiungimento del successo.<\/li>\n<li> <b>Idempotenza<\/b>: le applicazioni ripetute della convergenza portano allo stesso risultato.<\/li>\n<li> <b>Determinismo<\/b>: con risorse sufficienti, lo stato del cluster aggiornato dipende solo dallo stato desiderato.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Come funziona GitOps<\/h2>\n<p>\nAbbiamo appreso abbastanza su Kubernetes per spiegare i principi di funzionamento di GitOps.<\/p>\n<p>Torniamo ai team di Family Insurance che si occupano di microservizi. Di cosa si occupano solitamente? Dai un'occhiata all'elenco qui sotto (se qualche punto ti sembra strano o sconosciuto, per favore, astieniti dal criticare e resta con noi). Questi sono solo esempi di flussi di lavoro basati su Jenkins. Ci sono anche molti altri processi quando si lavora con altri strumenti.<\/p>\n<p>La cosa principale \u00e8 che vediamo che ogni aggiornamento termina con modifiche ai file di configurazione e ai repository Git. Queste modifiche in Git portano il 'operatore GitOps' ad aggiornare il cluster:<\/p>\n<p>1. Flusso di lavoro: '<i>Build Jenkins - ramo master<\/i>\u00bb.<br \/>\nElenco dei compiti:<\/p>\n<ul>\n<li> Jenkins pushava immagini taggate in Quay;<\/li>\n<li> Jenkins pushava la configurazione e le Helm chart nel bucket del master storage;<\/li>\n<li> La funzione cloud copia la configurazione e i grafici dal bucket di archiviazione master al repository Git master;<\/li>\n<li> L'operatore GitOps aggiorna il cluster.<\/li>\n<\/ul>\n<p>\n2. <i>Build Jenkins - ramo release o hotfix<\/i>:<\/p>\n<ul>\n<li> Jenkins pushava immagini non taggate in Quay;<\/li>\n<li> Jenkins pushava la configurazione e le Helm chart nel bucket dello staging storage;<\/li>\n<li> La funzione cloud copia la configurazione e i grafici dal bucket di archiviazione staging al repository Git staging;<\/li>\n<li> L'operatore GitOps aggiorna il cluster.<\/li>\n<\/ul>\n<p>\n3. <i>Build Jenkins - ramo develop o feature<\/i>:<\/p>\n<ul>\n<li> Jenkins pushava immagini non taggate in Quay;<\/li>\n<li> Jenkins pushava la configurazione e le Helm chart nel bucket del develop storage;<\/li>\n<li> La funzione cloud copia la configurazione e i grafici dal bucket di archiviazione develop al repository Git develop;<\/li>\n<li>L'operatore GitOps aggiorna il cluster.<\/li>\n<\/ul>\n<p>\n4. <i>Aggiunta di un nuovo cliente<\/i>:<\/p>\n<ul>\n<li> Il manager o l'amministratore (LCM\/ops) chiama Gradle per il primo deployment e la configurazione dei bilanciatori di carico (NLB);<\/li>\n<li> LCM\/ops committano una nuova configurazione per preparare il deployment agli aggiornamenti;<\/li>\n<li> L'operatore GitOps aggiorna il cluster.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Breve descrizione di GitOps<\/h3>\n<p><\/p>\n<ol>\n<li> Descrivi lo stato desiderato dell'intero sistema, utilizzando specifiche dichiarative per ogni ambiente (nella nostra storia, il team di Bob definisce l'intera configurazione del sistema in Git).\n<ul>\n<li> Il repository Git \u00e8 l'unica fonte di verit\u00e0 riguardo allo stato desiderato dell'intero sistema.<\/li>\n<li> Tutte le modifiche allo stato desiderato avvengono tramite commit in Git.<\/li>\n<li> Tutti i parametri desiderati del cluster sono anche osservabili all'interno dello stesso cluster. Cos\u00ec possiamo determinare se coincidono (convergono, <i>converge<\/i>) o differiscono (divergono, <i>diverge<\/i>) lo stato desiderato e quello osservato.<\/li>\n<\/ul>\n<\/li>\n<li> Se lo stato desiderato e quello osservato differiscono, allora:\n<ul>\n<li> Esiste un meccanismo di convergenza che, prima o poi, sincronizza automaticamente lo stato atteso e quello osservato. All'interno del cluster, questo \u00e8 gestito da Kubernetes.<\/li>\n<li> Il processo si avvia immediatamente con la notifica \"change committed\".<\/li>\n<li> Dopo un certo intervallo di tempo configurabile, pu\u00f2 essere inviata una notifica \"diff\", se gli stati differiscono.<\/li>\n<\/ul>\n<\/li>\n<li> Cos\u00ec, tutti i commit in Git generano aggiornamenti verificabili e idempotenti nel cluster.\n<ul>\n<li>Un rollback \u00e8 una convergenza a uno stato desiderato precedente.<\/li>\n<\/ul>\n<\/li>\n<li> La convergenza \u00e8 definitiva. La sua avvenuta \u00e8 testimoniata da:\n<ul>\n<li> L'assenza di notifiche \"diff\" per un certo intervallo di tempo.<\/li>\n<li> La notifica \"converged\" (ad esempio, webhook, evento Git writeback).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><\/p>\n<h3>Che cos'\u00e8 la divergenza?<\/h3>\n<p>\nRipetiamo ancora una volta: <i>tutte le propriet\u00e0 desiderate del cluster devono essere osservabili all'interno dello stesso cluster<\/i>.<\/p>\n<p>Alcuni esempi di divergenza:<\/p>\n<ul>\n<li> Modifica nel file di configurazione a causa della fusione di branch in Git.<\/li>\n<li> Modifica nel file di configurazione a causa di un commit in Git effettuato da un client GUI.<\/li>\n<li> Multiple modifiche allo stato desiderato a causa di PR in Git seguite dalla costruzione di un'immagine del contenitore e modifiche della configurazione.<\/li>\n<li> Modifica dello stato del cluster a causa di errori, conflitti di risorse che portano a \"comportamenti indesiderati\", o semplicemente deviazioni casuali dallo stato originale.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Che cos'\u00e8 il meccanismo di convergenza?<\/h3>\n<p>\nAlcuni esempi:<\/p>\n<ul>\n<li> Per contenitori e cluster, il meccanismo di convergenza \u00e8 fornito da Kubernetes.<\/li>\n<li> Lo stesso meccanismo pu\u00f2 essere utilizzato per gestire applicazioni e strutture basate su Kubernetes (ad esempio, Istio e Kubeflow).<\/li>\n<li> Il meccanismo per gestire l'interazione operativa tra Kubernetes, i repository di immagini e Git fornisce <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/weaveworks\/flux\">l'operatore GitOps Weave Flux<\/a><\/noindex>, che \u00e8 parte di <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.weave.works\/\">Weave Cloud<\/a><\/noindex>.<\/li>\n<li> Per le macchine di base, il meccanismo di convergenza deve essere dichiarativo e autonomo. Dalla nostra esperienza possiamo dire che <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.gruntwork.io\/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c\">Terraform<\/a><\/noindex> \u00e8 pi\u00f9 vicino a questa definizione, ma richiede ancora un controllo umano. In questo senso, GitOps amplia le tradizioni dell'Infrastructure as Code.<\/li>\n<\/ul>\n<p>\nGitOps combina Git con un eccellente meccanismo di convergenza di Kubernetes, offrendo un modello per l'operativit\u00e0.<\/p>\n<p>GitOps ci consente di affermare che: <i>solo i sistemi che possono essere descritti e monitorati sono soggetti ad automazione e controllo<\/i>.<\/p>\n<h3>GitOps \u00e8 destinato all'intero stack cloud native (ad esempio, Terraform, ecc.)<\/h3>\n<p>\nGitOps non \u00e8 solo Kubernetes. Vogliamo che l'intero sistema sia gestito in modo dichiarativo e utilizzi la convergenza. Con 'sistema intero' ci riferiamo all'insieme degli ambienti che lavorano con Kubernetes, ad esempio, 'dev cluster 1', 'produzione', ecc. Ogni ambiente include macchine, cluster, applicazioni e interfacce per servizi esterni che forniscono dati, monitoraggio, ecc.<\/p>\n<p>Nota quanto sia importante Terraform per il problema del bootstrapping in questo caso. Kubernetes deve essere distribuito da qualche parte e utilizzare Terraform significa che possiamo applicare gli stessi flussi di lavoro GitOps per creare uno strato di gestione che sottende a Kubernetes e alle applicazioni. Questa \u00e8 una buona prassi.<\/p>\n<p>C'\u00e8 molta attenzione sull'applicazione dei concetti GitOps agli strati sopra Kubernetes. Attualmente ci sono soluzioni di tipo GitOps per Istio, Helm, Ksonnet, OpenFaaS e Kubeflow, e anche per Pulumi, che creano uno strato per lo sviluppo di applicazioni cloud native.<\/p>\n<h2>Kubernetes CI\/CD: confronto tra GitOps e altri approcci<\/h2>\n<p>\nCome detto, GitOps \u00e8 due cose:<\/p>\n<ol>\n<li> Un modello operativo per Kubernetes e cloud native, descritto sopra.<\/li>\n<li> Un percorso verso l'organizzazione di un ambiente orientato agli sviluppatori per gestire le applicazioni.<\/li>\n<\/ol>\n<p>\nPer molti, GitOps \u00e8 prima di tutto un flusso di lavoro basato sulle push di Git. Anche a noi piace. Ma non \u00e8 tutto: ora diamo un'occhiata ai pipeline CI\/CD.<\/p>\n<h3>GitOps garantisce il deployment continuo (CD) sotto Kubernetes<\/h3>\n<p>\nGitOps offre un meccanismo di deployment continuo che elimina la necessit\u00e0 di 'sistemi di gestione dei deployment' separati. Tutto il lavoro viene svolto da Kubernetes.<\/p>\n<ul>\n<li> L'aggiornamento di un'applicazione richiede un aggiornamento in Git. Questo \u00e8 un aggiornamento transazionale allo stato desiderato. Il \"deploy\" viene quindi effettuato all'interno del cluster da Kubernetes stesso, sulla base della descrizione aggiornata.<\/li>\n<li> A causa della specificit\u00e0 del funzionamento di Kubernetes, questi aggiornamenti sono convergenti. Ci\u00f2 fornisce un meccanismo per un deployment continuo, in cui tutti gli aggiornamenti sono atomici.<\/li>\n<li> Nota: <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.weave.works\/\">Weave Cloud<\/a><\/noindex> offre un operatore GitOps, che integra Git e Kubernetes e consentendo di eseguire CD mediante l'allineamento dello stato desiderato con quello attuale del cluster.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Senza kubectl e script<\/h3>\n<p>\nDovrebbe essere evitato l'uso di Kubectl per aggiornare il cluster, e in particolare degli script per raggruppare i comandi kubectl. Invece, con una pipeline GitOps, l'utente pu\u00f2 aggiornare il proprio cluster Kubernetes attraverso Git.<\/p>\n<p>I vantaggi includono:<\/p>\n<ol>\n<li> <b>Correttezza<\/b>. Un gruppo di aggiornamenti pu\u00f2 essere applicato, convergere e infine convalidare, avvicinandoci all'obiettivo del deployment atomico. Al contrario, l'uso di script non offre alcuna garanzia di convergenza (ne parler\u00f2 pi\u00f9 a lungo pi\u00f9 avanti).<\/li>\n<li> <b>Sicurezza<\/b>. <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/kelseyhightower\/status\/939003832805179392?lang=en\">Citare<\/a><\/noindex> Kelsey Hightower: \"Limitare l'accesso al cluster Kubernetes solo agli strumenti di automazione e agli amministratori responsabili della sua manutenzione o risoluzione dei problemi\". Vedi anche <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/gitops-compliance-and-secure-cicd\">la mia pubblicazione<\/a><\/noindex> sulla sicurezza e la conformit\u00e0 alle specifiche, cos\u00ec come <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/@vesirin\/how-i-gained-commit-access-to-homebrew-in-30-minutes-2ae314df03ab\">l'articolo sul hack di Homebrew<\/a><\/noindex> attraverso il furto di credenziali da uno script Jenkins scritto in modo superficiale.<\/li>\n<li> <b>Esperienza utente<\/b>. Kubectl espone la meccanica del modello a oggetti di Kubernetes, che \u00e8 piuttosto complessa. Idealmente, gli utenti dovrebbero interagire con il sistema a un livello pi\u00f9 alto di astrazione. Qui, richiamo di nuovo Kelsey e consiglio di dare un'occhiata a <noindex><a rel=\"nofollow\" href=\"http:\/\/superuser.openstack.org\/articles\/kubernetes-boring\/\">questo riassunto<\/a><\/noindex>.<\/li>\n<\/ol>\n<p><\/p>\n<h3>La differenza tra CI e CD<\/h3>\n<p>\nGitOps migliora i modelli CI\/CD esistenti.<\/p>\n<p>Un moderno server CI \u00e8 uno strumento per l'orchestrazione. In particolare, \u00e8 uno strumento per l'orchestrazione dei pipeline CI. Questi includono build, test, merge to trunk, ecc. I server CI automatizzano la gestione di pipeline complesse e multi-step. C'\u00e8 una tentazione comune di creare uno script per un insieme di aggiornamenti Kubernetes e di eseguirlo come elemento della pipeline per spingere le modifiche nel cluster. Infatti, molti esperti agiscono in questo modo. Tuttavia, non \u00e8 ottimale, ecco perch\u00e9.<\/p>\n<p>CI deve essere utilizzato per apportare aggiornamenti al trunk, mentre il cluster Kubernetes deve modificarsi in base a questi aggiornamenti per gestire il CD \"internamente\". Lo chiamiamo <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/gitops-compliance-and-secure-cicd\">modello pull per il CD<\/a><\/noindex>, a differenza del modello push del CI. Il CD \u00e8 parte della <i>orchestrazione runtime<\/i>.<\/p>\n<h3>Perch\u00e9 i server CI non dovrebbero gestire il CD tramite aggiornamenti diretti in Kubernetes<\/h3>\n<p>\n<i>Non utilizzare il server CI per orchestrare aggiornamenti diretti in Kubernetes come insieme di compiti CI. Questo \u00e8 un anti-modello di cui abbiamo <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/kubernetes-anti-patterns-let-s-do-gitops-not-ciops\">ha gi\u00e0 raccontato<\/a><\/noindex> parlato nel nostro blog.<\/i><\/p>\n<p>Torniamo ad Alice e Bob.<\/p>\n<p>Quali problemi hanno affrontato? Il server CI di Bob applica le modifiche al cluster, ma se si arresta durante il processo, Bob non sapr\u00e0 in quale stato si trova (o dovrebbe trovarsi) il cluster e come ripararlo. Lo stesso vale in caso di successo.<\/p>\n<p>Supponiamo che il team di Bob abbia creato una nuova immagine e poi patchato i propri deployment per distribuire l'immagine (tutto ci\u00f2 dal pipeline CI).<\/p>\n<p>Se l'immagine viene costruita correttamente, ma il pipeline si arresta, il team dovr\u00e0 scoprire:<\/p>\n<ul>\n<li> \u00c8 stata implementata l'aggiornamento?<\/li>\n<li> Stiamo eseguendo una nuova build? Porter\u00e0 a effetti collaterali indesiderati \u2014 c'\u00e8 la possibilit\u00e0 di ottenere due build della stessa immagine invariata? <\/li>\n<li> Dobbiamo aspettare un altro aggiornamento prima di eseguire la build?<\/li>\n<li> Cosa \u00e8 andato esattamente storto? Quali passaggi devono essere ripetuti (e quali di essi possono essere ripetuti in sicurezza)?<\/li>\n<\/ul>\n<p>\n<i>Organizzare un flusso di lavoro basato su Git non garantisce che il team di Bob non si imbatti in questi problemi. Potrebbero comunque commettere errori con il push del commit, con il tag o con qualche altro parametro; tuttavia, questo approccio \u00e8 comunque molto pi\u00f9 vicino a un esplicito tutto-o-niente.<\/i><\/p>\n<p>In sintesi, ecco perch\u00e9 i server CI non dovrebbero occuparsi del CD:<\/p>\n<ul>\n<li> Gli script di aggiornamento non sono sempre deterministici; \u00e8 facile commettere errori.<\/li>\n<li> I server CI non convergono verso un modello dichiarativo del cluster.<\/li>\n<li> \u00c8 difficile garantire l'idempotenza. Gli utenti devono comprendere la profonda semantica del sistema.<\/li>\n<li> \u00c8 pi\u00f9 complicato eseguire un ripristino dopo un guasto parziale.<\/li>\n<\/ul>\n<p>\n<i>Nota su Helm: se vuoi utilizzare Helm, ti consigliamo di combinarlo con un operatore GitOps, come <noindex><a rel=\"nofollow\" href=\"https:\/\/www.weave.works\/blog\/managing-helm-releases-the-gitops-way\">Flux-Helm<\/a><\/noindex>. Questo aiuter\u00e0 a garantire la convergenza. Da solo, Helm non \u00e8 n\u00e9 deterministico n\u00e9 atomico.<\/i><\/p>\n<h2>GitOps come miglior modo di realizzare il Continuous Delivery per Kubernetes<\/h2>\n<p>\nIl team di Alice e Bob implementa GitOps e scopre che lavorare con i prodotti software \u00e8 diventato molto pi\u00f9 semplice, mantenendo alte prestazioni e stabilit\u00e0. Concludiamo questo articolo con illustrazioni che mostrano come appare il loro nuovo approccio. Tieni presente che stiamo principalmente parlando di applicazioni e servizi, tuttavia GitOps pu\u00f2 essere utilizzato per gestire l'intera piattaforma.<\/p>\n<h3>Modello di operativit\u00e0 per Kubernetes<\/h3>\n<p>\nGuarda il diagramma seguente. Rappresenta Git e il repository delle immagini dei container come risorse comuni per due cicli di vita orchestrati:<\/p>\n<ul>\n<li> Pipelines di integrazione continua, che leggono e scrivono file in Git e possono aggiornare il repository delle immagini dei container.<\/li>\n<li> Pipelines Runtime GitOps, che combina il deployment con la gestione e l'osservabilit\u00e0. Legge e scrive file in Git e pu\u00f2 caricare immagini dei container.<\/li>\n<\/ul>\n<h3>Quali sono le principali conclusioni?<\/h3>\n<p><\/p>\n<ol>\n<li> <b>Separazione delle preoccupazioni<\/b>: Nota che entrambe le pipeline possono scambiare dati solo aggiornando Git o il repository delle immagini. In altre parole, c'\u00e8 un firewall tra l'ambiente CI e quello runtime. Lo chiamiamo 'firewall dell'immutabilit\u00e0' <i>(immutability firewall)<\/i>, poich\u00e9 tutti gli aggiornamenti dei repository creano nuove versioni. Per ulteriori informazioni su questo argomento, fai riferimento alle diapositive 72-87. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/weaveworks\/continuous-lifecycle-london-2018-event-keynote-97418556\">questa presentazione<\/a><\/noindex>.<\/li>\n<li> <b>Puoi utilizzare qualsiasi server CI e Git<\/b>: GitOps funziona con qualsiasi componente. Puoi continuare a utilizzare i tuoi server CI e Git preferiti, repository delle immagini e set di test. Quasi tutti gli altri strumenti per il Continuous Delivery sul mercato richiedono il proprio server CI\/Git o repository delle immagini. Questo pu\u00f2 diventare un fattore limitante nello sviluppo cloud native. Nel caso di GitOps, puoi utilizzare strumenti familiari.<\/li>\n<li> <b>Eventi come strumento di integrazione<\/b>: Una volta che i dati in Git vengono aggiornati, Weave Flux (o l'operatore Weave Cloud) notifica l'ambiente runtime. Ogni volta che Kubernetes accetta un insieme di modifiche, Git viene aggiornato. Questo fornisce un modello di integrazione semplice per organizzare i flussi di lavoro per GitOps, come mostrato di seguito.<\/li>\n<\/ol>\n<h2>Conclusione<\/h2>\n<p>\nGitOps fornisce forti garanzie di aggiornamento, necessarie per qualsiasi moderno strumento CI\/CD:<\/p>\n<ul>\n<li> automazione;<\/li>\n<li> convergenza;<\/li>\n<li> idempotenza;<\/li>\n<li> determinismo.<\/li>\n<\/ul>\n<p>\nQuesto \u00e8 importante poich\u00e9 offre un modello operativo per gli sviluppatori nel campo del cloud native.<\/p>\n<ul>\n<li> Gli strumenti tradizionali per la gestione e il monitoraggio dei sistemi sono legati ai team operativi che agiscono nell'ambito di un runbook <i>(un insieme di procedure e operazioni di routine \u2014 nota del traduttore)<\/i>, connesso a un deployment specifico.<\/li>\n<li> Nella gestione dei sistemi cloud native, gli strumenti di monitoraggio sono il miglior modo per valutare i risultati dei deployment, affinch\u00e9 il team di sviluppo possa reagire tempestivamente.<\/li>\n<\/ul>\n<p>\nImmagina un gran numero di cluster distribuiti su vari cloud e un gran numero di servizi con propri team e piani di deployment. GitOps offre un modello indipendente dalla scala per gestire tutta questa abbondanza.<\/p>\n<h2>P.S. dal traduttore<\/h2>\n<p>\nLeggi anche nel nostro blog:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/456754\/\">GitOps: confronto tra i metodi Pull e Push<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/434160\/\">Presentiamo la libreria kubedog per il monitoraggio delle risorse Kubernetes<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/449096\/\">Espandiamo e completiamo Kubernetes (panoramica e video della presentazione)<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p class=\"for_users_only_msg\">Solo gli utenti registrati possono partecipare al sondaggio. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Accedi<\/a><\/noindex>, per favore.<\/p>\n<h2 class=\"default-block__polling-title\">Sapevi di GitOps prima di questi due articoli su Habr?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    S\u00ec, lo sapevo<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Solo superficialmente<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    No<\/p>\n<\/li>\n<\/ul>\n<p>    Hanno votato 35 utenti. 10 utenti si sono astenuti.<br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/458878\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043c\u0435\u0442\u043e\u0434\u0430\u0445 pull \u0438 push \u0432 GitOps \u043c\u044b \u0443\u0432\u0438\u0434\u0435\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441 \u043a \u044d\u0442\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u0446\u0435\u043b\u043e\u043c, \u043e\u0434\u043d\u0430\u043a\u043e \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0445 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0439 \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0432\u0441\u0435\u043c \u043c\u0430\u043b\u043e (\u043d\u0430 \u0445\u0430\u0431\u0440\u0435 \u0438\u0445 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043d\u0435\u0442). \u041f\u043e\u0441\u0435\u043c\u0443 \u0440\u0430\u0434\u044b \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u043f\u0443\u0441\u0442\u044c \u0438 \u0443\u0436\u0435 \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0434\u0438\u0447\u043d\u043e\u0439 \u0434\u0430\u0432\u043d\u043e\u0441\u0442\u0438! \u2014 \u043e\u0442 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Weaveworks, \u0433\u043b\u0430\u0432\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35941","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u043c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/chto-zhe-takoe-gitops\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0427\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 GitOps? | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u043c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/chto-zhe-takoe-gitops\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:07:41+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:07:41+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Che cos'\u00e8 GitOps? | ProHoster","description":"Nota.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/chto-zhe-takoe-gitops","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0427\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 GitOps? | ProHoster","og:description":"\u041f\u0440\u0438\u043c.","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/chto-zhe-takoe-gitops","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:07:41+00:00","article:modified_time":"2019-10-31T19:07:41+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35941","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 01:21:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:53:31","updated":"2026-01-22 01:21:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/35941","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=35941"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/35941\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=35941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=35941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=35941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}