A Chelyabinsk si stanno svolgendo incontri tra amministratori di sistema Sysadminka e all'ultimo ho fornito un rapporto sulla nostra soluzione per l'esecuzione di applicazioni su 1C-Bitrix in Kubernetes.
Bitrix, Kubernetes, Ceph: un ottimo mix?
Ti dirò come abbiamo messo insieme una soluzione funzionante da tutto questo.
Andiamo!
L'incontro ha avuto luogo il 18 aprile a Chelyabinsk. Puoi leggere i nostri incontri su Timepad e guarda Youtube.
Se vuoi venire da noi con un rapporto o come ascoltatore, benvenuto, scrivi a [email protected] e su Telegram t.me/vadimisakanov.
Soluzione "Bitrix in Kubernetes, versione Southbridge 1.0"
Parlerò della nostra soluzione nel formato “for dummies in Kubernetes”, come è stato fatto durante l'incontro. Ma presumo che tu conosca le parole Bitrix, Docker, Kubernetes, Ceph almeno a livello di articoli su Wikipedia.
Cosa c'è di già pronto su Bitrix in Kubernetes?
Ci sono pochissime informazioni su tutta Internet sul funzionamento delle applicazioni Bitrix in Kubernetes.
Ho trovato solo questi materiali:
Rapporto di Alexander Serbul, 1C-Bitrix e Anton Tuzlukov di Qsoft:
Ti avverto, non abbiamo controllato la qualità delle soluzioni nei link sopra :)
A proposito, durante la preparazione della nostra soluzione, ho parlato con Alexander Serbul, quindi il suo rapporto non era ancora apparso, quindi nelle mie diapositive c'è la voce "Bitrix non usa Kubernetes".
È sufficiente per creare una soluzione completa per Bitrix in Kubernetes?
NO. Ci sono un gran numero di problemi che devono essere risolti.
Quali sono i problemi con Bitrix in Kubernetes?
Innanzitutto le immagini già pronte di Dockerhub non sono adatte a Kubernetes
Se vogliamo costruire un'architettura di microservizi (e in Kubernetes di solito lo facciamo), dobbiamo separare la nostra applicazione Kubernetes in contenitori e fare in modo che ciascun contenitore esegua una piccola funzione (e la faccia bene). Perché solo uno? In breve, più è semplice, più è affidabile.
Per essere più specifici, guarda questo articolo e video, per favore: https://habr.com/ru/company/southbridge/blog/426637/
Le immagini Docker in Dockerhub sono fondamentalmente basate sul principio all-in-one, quindi dovevamo comunque creare la nostra bicicletta e persino creare immagini da zero.
Secondo: il codice del sito viene modificato dal pannello di amministrazione
Abbiamo creato una nuova sezione sul sito: il codice è stato aggiornato (è stata aggiunta una directory con il nome della nuova sezione).
Se hai modificato le proprietà di un componente dal pannello di amministrazione, il codice è cambiato.
Kubernetes "per impostazione predefinita" non può funzionare con questo; i contenitori devono essere senza stato.
Motivo: ciascun contenitore (pod) nel cluster elabora solo una parte del traffico. Se modifichi il codice in un solo contenitore (pod), il codice sarà diverso nei diversi pod, il sito funzionerà in modo diverso e versioni diverse del sito verranno mostrate a utenti diversi. Non puoi vivere così.
Terzo: devi risolvere il problema con la distribuzione
Se disponiamo di un monolite e di un server “classico”, tutto è abbastanza semplice: distribuiamo una nuova base di codice, migriamo il database, trasferiamo il traffico alla nuova versione del codice. La commutazione avviene istantaneamente.
Se abbiamo un sito in Kubernetes, suddiviso in microservizi, ci sono molti contenitori con codice - oh. È necessario raccogliere contenitori con una nuova versione del codice, distribuirli al posto di quelli vecchi, migrare correttamente il database e idealmente farlo inosservato dai visitatori. Fortunatamente, Kubernetes ci aiuta in questo, supportando tutta una serie di diversi tipi di implementazioni.
Quarto: è necessario risolvere il problema della memorizzazione dei dati statici
Se il tuo sito è “solo” 10 gigabyte e lo distribuisci interamente in contenitori, ti ritroverai con contenitori da 10 gigabyte che impiegano un’eternità per la distribuzione.
È necessario immagazzinare le parti “più pesanti” del sito al di fuori dei contenitori e sorge la domanda su come farlo correttamente
Cosa manca alla nostra soluzione?
L'intero codice Bitrix non è suddiviso in microfunzioni/microservizi (quindi la registrazione è separata, il modulo del negozio online è separato, ecc.). Archiviamo l'intera base di codice in ciascun contenitore.
Inoltre non memorizziamo il database in Kubernetes (ho comunque implementato soluzioni con database in Kubernetes per ambienti di sviluppo, ma non per produzione).
Sarà comunque evidente agli amministratori del sito che il sito viene eseguito su Kubernetes. La funzione “controllo sistema” non funziona correttamente; per modificare il codice del sito dal pannello di amministrazione è necessario prima cliccare sul pulsante “Voglio modificare il codice”.
I problemi sono stati identificati, è stata determinata la necessità di implementare i microservizi, l'obiettivo è chiaro: ottenere un sistema funzionante per eseguire applicazioni su Bitrix in Kubernetes, preservando sia le capacità di Bitrix che i vantaggi di Kubernetes. Iniziamo l'implementazione.
Architettura
Esistono molti pod "funzionanti" con un server Web (lavoratori).
Uno sotto con le attività cron (ne è richiesto solo uno).
Un aggiornamento per modificare il codice del sito dal pannello di amministrazione (anche solo uno è richiesto).
Risolviamo domande:
Dove archiviare le sessioni?
Dove archiviare la cache?
Dove archiviare i dati statici, non posizionare gigabyte di dati statici in un mucchio di contenitori?
Come funzionerà il database?
Immagine Docker
Iniziamo costruendo un'immagine Docker.
L'opzione ideale è che abbiamo un'immagine universale, sulla base della quale otteniamo pod di lavoro, pod con Crontask e pod di aggiornamento.
Include nginx, apache/php-fpm (può essere selezionato durante la creazione), msmtp per l'invio di posta e cron.
Durante l'assemblaggio dell'immagine, l'intero codice base del sito viene copiato nella directory /app (ad eccezione di quelle parti che sposteremo in un archivio condiviso separato).
Microservizi, servizi
pod lavoratore:
Contenitore con nginx + contenitore apache/php-fpm + msmtp
Non ha funzionato spostare msmtp in un microservizio separato, Bitrix inizia a indignarsi perché non può inviare direttamente la posta
Non vi è alcun divieto di modificare il codice nei contenitori
memorizzazione della sessione
Archiviazione cache Bitrix
Altra cosa importante: memorizziamo le password per connetterci a tutto, dal database alla posta, nei segreti di Kubernetes. Otteniamo un bonus: le password sono visibili solo a coloro a cui diamo accesso ai segreti e non a tutti coloro che hanno accesso al codice base del progetto.
Archiviazione per statica
Puoi utilizzare qualsiasi cosa: ceph, nfs (ma non consigliamo nfs per la produzione), archiviazione di rete da provider cloud, ecc.
Lo storage dovrà essere collegato in contenitori alla directory /upload/ del sito e ad altre directory con contenuto statico.
База данных
Per semplicità, consigliamo di spostare il database all'esterno di Kubernetes. La base in Kubernetes è un compito complesso separato; renderà lo schema un ordine di grandezza più complesso.
Archiviazione della sessione
Usiamo memcached :)
Gestisce bene l'archiviazione delle sessioni, è in cluster ed è supportato "nativamente" come session.save_path in php. Un tale sistema è stato testato molte volte nell'architettura monolitica classica, quando abbiamo costruito cluster con un gran numero di server web. Per la distribuzione utilizziamo helm.
$ helm install stable/memcached --name session
php.ini: qui l'immagine contiene le impostazioni per la memorizzazione delle sessioni in memcached
Abbiamo utilizzato le variabili d'ambiente per passare i dati sugli host con memcached https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
Ciò ti consente di utilizzare lo stesso codice negli ambienti di sviluppo, stage, test e produzione (i nomi host memcached in essi contenuti saranno diversi, quindi dobbiamo passare un nome host univoco per le sessioni a ciascun ambiente).
Archiviazione cache Bitrix
Abbiamo bisogno di uno spazio di archiviazione con tolleranza agli errori su cui tutti i pod possano scrivere e leggere.
Usiamo anche memcached.
Questa soluzione è consigliata dalla stessa Bitrix.
$ helm install stable/memcached --name cache
bitrix/.settings_extra.php - qui in Bitrix viene specificato dove è archiviata la cache
Utilizziamo anche le variabili d'ambiente.
Krontaski
Esistono diversi approcci all'esecuzione di Crontask in Kubernetes.
distribuzione separata con un pod per l'esecuzione di Crontask
cronjob per l'esecuzione di crontask (se si tratta di un'app Web, con wget https://$host$cronjobnameo kubectl exec all'interno di uno dei pod di lavoro, ecc.)
ecc.
Si può discutere su quale sia quella più corretta, ma in questo caso abbiamo scelto l'opzione “distribuzione separata con pod per Crontask”
Come è fatto:
aggiungere attività cron tramite ConfigMap o tramite il file config/addcron
in un caso lanciamo un contenitore identico al pod lavoratore + consentiamo l'esecuzione delle attività corona al suo interno
viene utilizzata la stessa base di codice, grazie all'unificazione, l'assemblaggio del contenitore è semplice
Che bene otteniamo:
abbiamo Crontask funzionanti in un ambiente identico a quello degli sviluppatori (docker)
I Crontask non hanno bisogno di essere “riscritti” per Kubernetes, funzionano nella stessa forma e nella stessa base di codice di prima
le attività cron possono essere aggiunte da tutti i membri del team con diritti di commit nel ramo di produzione, non solo dagli amministratori
Modulo Southbridge K8SDeploy e modifica del codice dal pannello di amministrazione
Stavamo parlando di aggiornamento sotto?
Come dirigere il traffico lì?
Evviva, abbiamo scritto un modulo per questo in PHP :) Questo è un piccolo modulo classico per Bitrix. Non è ancora disponibile al pubblico, ma abbiamo intenzione di aprirlo.
Il modulo è installato come un normale modulo in Bitrix:
E assomiglia a questo:
Ti consente di impostare un cookie che identifica l'amministratore del sito e consente a Kubernetes di inviare traffico al pod di aggiornamento.
Una volta completate le modifiche, è necessario fare clic su git push, le modifiche al codice verranno inviate a git, quindi il sistema creerà un'immagine con una nuova versione del codice e la “distribuirà” nel cluster, sostituendo i vecchi pod .
Sì, è un po' una stampella, ma allo stesso tempo manteniamo l'architettura dei microservizi e non togliamo agli utenti Bitrix la loro opportunità preferita di correggere il codice dal pannello di amministrazione. Alla fine, questa è un'opzione; puoi risolvere il problema della modifica del codice in un modo diverso.
Grafico del timone
Per creare applicazioni su Kubernetes, in genere utilizziamo il gestore pacchetti Helm.
Per la nostra soluzione Bitrix in Kubernetes, Sergey Bondarev, il nostro principale amministratore di sistema, ha scritto uno speciale grafico Helm.
Crea pod di lavoro, aggiornamento e cron, configura ingressi, servizi e trasferisce variabili dai segreti Kubernetes ai pod.
Archiviamo il codice in Gitlab ed eseguiamo anche la build Helm da Gitlab.
Helm ti consente anche di eseguire un rollback "senza soluzione di continuità" se improvvisamente qualcosa va storto durante la distribuzione. È bello quando non sei nel panico "aggiusta il codice tramite ftp perché il prodotto è caduto", ma Kubernetes lo fa automaticamente e senza tempi di inattività.
Distribuire
Sì, siamo fan di Gitlab e Gitlab CI, lo usiamo :)
Quando si impegna in Gitlab nel repository del progetto, Gitlab avvia una pipeline che distribuisce una nuova versione dell'ambiente.
Passi:
build (creazione di una nuova immagine Docker)
prova (prova)
ripulire (rimuovere l'ambiente di test)
push (lo inviamo al registro Docker)
deploy (distribuiamo l'applicazione su Kubernetes tramite Helm).
Evviva, è pronto, implementiamolo!
Bene, o fai domande se ce ne sono.
Allora cosa abbiamo fatto?
Dal punto di vista tecnico:
Bitrix dockerizzato;
“tagliare” Bitrix in contenitori, ognuno dei quali svolge un minimo di funzioni;
raggiunto lo stato stateless dei container;
risolto il problema con l'aggiornamento di Bitrix in Kubernetes;
tutte le funzioni di Bitrix hanno continuato a funzionare (quasi tutte);
Abbiamo lavorato sulla distribuzione su Kubernetes e sul rollback tra le versioni.
Dal punto di vista aziendale:
tolleranza agli errori;
Strumenti Kubernetes (facile integrazione con Gitlab CI, distribuzione senza soluzione di continuità, ecc.);
password segrete (visibili solo a chi ha accesso diretto alle password);
È conveniente creare ambienti aggiuntivi (di sviluppo, test, ecc.) all’interno di un’unica infrastruttura.