Southbridge a Chelyabinsk e Bitrix a Kubernetes

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!

Southbridge a Chelyabinsk e Bitrix a Kubernetes

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.

La mia relazione

Southbridge a Chelyabinsk e Bitrix a Kubernetes

Slides

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:

Ne consiglio l'ascolto.

Sviluppare la propria soluzione dall'utente serkyron su Habrè.
Trovato di più una tale decisione.

Eee... in realtà, questo è tutto.

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".

Ma ci sono già molte immagini Docker già pronte per eseguire Bitrix in Docker: https://hub.docker.com/search?q=bitrix&type=image

È 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).

Southbridge a Chelyabinsk e Bitrix a Kubernetes

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.

Abbiamo creato proprio un'immagine del genere.

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
  • Ogni contenitore ha una base di codice completa.
  • Divieto di modifica del codice nei contenitori.

cron sotto:

  • contenitore con apache, php, cron
  • base di codice completa inclusa
  • divieto di modificare il codice nei contenitori

aggiornamento sotto:

  • contenitore nginx + contenitore apache/php-fpm + msmtp
  • 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:

Southbridge a Chelyabinsk e Bitrix a Kubernetes

E assomiglia a questo:

Southbridge a Chelyabinsk e Bitrix a Kubernetes

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.

In breve, sembra così

$ helm upgrade --install project .helm --set image=registrygitlab.local/k8s/bitrix -f .helm/values.yaml --wait --timeout 300 --debug --tiller-namespace=production

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).

Southbridge a Chelyabinsk e Bitrix a Kubernetes

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.

Fonte: habr.com

Aggiungi un commento