GNU/Linux >> Linux Esercitazione >  >> Linux

Come spostare Request Tracker in un container Linux

Anche se mi ci è voluto molto tempo per motivarmi, alla fine ho containerizzato diversi servizi Linux personali. Ho documentato il progetto in questa serie. In questo articolo, ti guideremo attraverso un ultimo esempio, Request Tracker.

Per iniziare, abbiamo esaminato alcuni principi generali per la migrazione delle applicazioni nei contenitori. Quindi abbiamo esaminato la containerizzazione di WordPress e, successivamente, abbiamo discusso dello spostamento di MediaWiki in un container. Quel progetto era un po' più coinvolto del primo, con l'aggiunta della pianificazione delle attività. In questo articolo finale, prenderemo in considerazione una migrazione molto più complessa. In particolare, esamineremo Request Tracker. Questo servizio potrebbe essere il più complicato perché sia ​​la compilazione che l'esecuzione sono piuttosto sofisticati.

Nota dell'editore:ai fini di questo articolo, presumiamo che creerai i tuoi container su Red Hat Enterprise Linux 8 usando podman build. Potresti essere in grado di utilizzare le istruzioni su altre distribuzioni o con altre toolchain, tuttavia potrebbero essere necessarie alcune modifiche.

Traccia richiesta di spostamento

Costruisci

A differenza di WordPress e MediaWiki, che vengono eseguiti su un'immagine a livello singolo sopra un'immagine di base, Request Tracker utilizza due livelli sopra un'immagine di base. Diamo un'occhiata a ogni livello e vediamo perché l'abbiamo fatto in questo modo.

Il primo livello è costruito in modo abbastanza simile a httpd-php Immagine. Questa immagine aggiunge i servizi necessari per un'applicazione web basata su Perl. Includiamo Apache, il modulo FastCGI, Perl, MariaDB, cron e alcune utilità di base per la risoluzione dei problemi:

FROM registry.access.redhat.com/ubi8/ubi-init
MAINTAINER fatherlinux <[email protected]>
RUN yum install -y httpd mod_fcgid perl mariadb-server mariadb crontabs cronie iputils net-tools; yum clean all
RUN systemctl enable mariadb
RUN systemctl enable httpd
RUN systemctl enable postfix
RUN systemctl disable systemd-update-utmp.service
ENTRYPOINT ["/sbin/init"]
CMD ["/sbin/init"]

Il secondo livello è dove le cose diventano piuttosto sofisticate. Request Tracker utilizza molti moduli Perl da CPAN. Molti di questi moduli sono compilati con gcc e richiede molto tempo per l'installazione. Ci è voluto anche molto lavoro per inchiodare tutte queste dipendenze per ottenere l'installazione corretta di Request Tracker. Storicamente, avremmo catturato questo in uno script da qualche parte, ma con i container possiamo averlo tutto in un Containerfile. È molto conveniente.

[ Potrebbero interessarti anche: 6 guide per rendere sicuri i container ]

La prossima cosa che dovresti notare su questo file è che è una build a più fasi. Podman e Buildah possono assolutamente eseguire build multifase e possono essere estremamente utili per applicazioni come Request Tracker. Avremmo potuto montare il binding nelle directory, come abbiamo fatto con WordPress e MediaWiki, ma abbiamo invece scelto una build multi-stadio. Questo ci darà portabilità e velocità se dobbiamo ricostruire l'applicazione da qualche altra parte.

Le build multifase possono essere considerate come l'acquisizione del server di sviluppo e del server di produzione in un unico file di build. Storicamente, i server di sviluppo erano in realtà i più difficili da automatizzare. Sin dai primi giorni di CFEngine a metà degli anni '90, gli sviluppatori si sono rifiutati di utilizzare il controllo della versione e hanno aggiunto tutto ciò che volevano ai server di sviluppo per farli funzionare. Spesso non sapevano nemmeno cosa aggiungere per completare una build. Questo era in realtà razionale quando si disponeva di server di lunga durata di cui era stato eseguito un backup adeguato, ma causava sempre problemi quando gli amministratori di sistema dovevano "aggiornare il server di sviluppo". È stato un incubo far funzionare le build su un server nuovo di zecca con un nuovo sistema operativo.

Con le build multifase, acquisiamo tutte le istruzioni di build e persino i livelli di cache che vengono costruiti. Possiamo ricostruire questo server virtuale di sviluppo ovunque vogliamo.

FROM registry.access.redhat.com/ubi8/ubi-init
FROM localhost/httpd-perl AS localhost/rt4-build
MAINTAINER fatherlinux <[email protected]>
RUN yum install -y expat-devel gcc; yum clean all
RUN cpan -i CPAN
RUN cpan -i -f GnuPG::Interface
RUN cpan -i DBIx::SearchBuilder \
ExtUtils::Command::MM \
Text::WikiFormat \
Devel::StackTrace \
Apache::Session \
Module::Refresh \
HTML::TreeBuilder \
HTML::FormatText::WithLinks \
HTML::FormatText::WithLinks::AndTables \
Data::GUID \
CGI::Cookie \
DateTime::Format::Natural \
Text::Password::Pronounceable \
UNIVERSAL::require \
JSON \
DateTime \
Net::CIDR \
CSS::Minifier::XS \
CGI \
Devel::GlobalDestruction \
Text::Wrapper \
Net::IP \
HTML::RewriteAttributes \
Log::Dispatch \
Plack \
Regexp::Common::net::CIDR \
Scope::Upper \
CGI::Emulate::PSGI \
HTML::Mason::PSGIHandler \
HTML::Scrubber \
HTML::Entities \
HTML::Mason \
File::ShareDir \
Mail::Header \
XML::RSS \
List::MoreUtils \
Plack::Handler::Starlet \
IPC::Run3 \
Email::Address \
Role::Basic \
MIME::Entity \
Regexp::IPv6 \
Convert::Color \
Business::Hours \
Symbol::Global::Name \
MIME::Types \
Locale::Maketext::Fuzzy \
Tree::Simple \
Clone \
HTML::Quoted \
Data::Page::Pageset \
Text::Quoted \
DateTime::Locale \
HTTP::Message \
Crypt::Eksblowfish \
Data::ICal \
Locale::Maketext::Lexicon \
Time::ParseDate \
Mail::Mailer \
Email::Address::List \
Date::Extract \
CSS::Squish \
Class::Accessor::Fast \
LWP::Simple \
Module::Versions::Report \
Regexp::Common \
Date::Manip \
CGI::PSGI \
JavaScript::Minifier::XS \
FCGI \
PerlIO::eol \
GnuPG::Interface \
LWP::UserAgent >= 6.02 \
LWP::Protocol::https \
String::ShellQuote \
Crypt::X509
RUN cd /root/rt-4.4.4;make testdeps;make install

# Deploy
FROM localhost/httpd-perl AS localhost/rt:4.4.4
RUN yum install -y postfix mailx;yum clean all
COPY --from=localhost/rt4-build /opt/rt4 /opt/rt4
COPY --from=localhost/rt4-build /usr/lib64/perl5 /usr/lib64/perl5
COPY --from=localhost/rt4-build /usr/share/perl5 /usr/share/perl5
COPY --from=localhost/rt4-build /usr/local/share/perl5 /usr/local/share/perl5
COPY --from=localhost/rt4-build /usr/local/lib64/perl5/ /usr/local/lib64/perl5/
RUN chown -R root.bin /opt/rt4/lib;chown -R root.apache /opt/rt4/etc
ENTRYPOINT ["/sbin/init"]
CMD ["/sbin/init"]

La seconda fase di questa build multifase costruisce il server di produzione virtuale. Suddividendo questo in una seconda fase, non dobbiamo installare strumenti di sviluppo come gcc o expat-devel nell'immagine di produzione finale. Ciò riduce le dimensioni della nostra immagine e riduce le dimensioni della catena di fornitura del software nei servizi esposti in rete. Questo potenzialmente riduce anche le possibilità che qualcuno faccia qualcosa di brutto con il nostro container, in caso di hackeraggio.

Installiamo le utilità di posta solo in questa seconda fase, che definisce il secondo livello della nostra immagine di produzione per Request Tracker. Avremmo potuto installare queste utilità nel httpd-perl livello, ma molte altre applicazioni Perl non avranno bisogno di utilità di posta.

Un'altra comodità delle build multifase è che non dobbiamo ricostruire tutti quei moduli Perl ogni volta che vogliamo aggiornare l'interprete Perl, Apache o MariaDB per le patch di sicurezza.

Corri

Ora, come WordPress e MediaWiki, diamo un'occhiata ad alcuni dei trucchi che utilizziamo in fase di esecuzione:

[Unit]
Description=Podman container – rt.fatherlinux.com
Documentation=man:podman-generate-systemd(1)

[Service]
Type=simple
ExecStart=/usr/bin/podman run -i --rm --read-only -p 8081:8081 --name rt.fatherlinux.com \
-v /srv/rt.fatherlinux.com/code/reminders:/root/reminders:ro \
-v /srv/rt.fatherlinux.com/config/rt.fatherlinux.com.conf:/etc/httpd/conf.d/rt.fatherlinux.com.conf:ro \
-v /srv/rt.fatherlinux.com/config/MyConfig.pm:/root/.cpan/CPAN/MyConfig.pm:ro \
-v /srv/rt.fatherlinux.com/config/RT_SiteConfig.pm:/opt/rt4/etc/RT_SiteConfig.pm:ro \
-v /srv/rt.fatherlinux.com/config/root-crontab:/var/spool/cron/root:ro \
-v /srv/rt.fatherlinux.com/config/aliases:/etc/aliases:ro \
-v /srv/rt.fatherlinux.com/config/main.cf:/etc/postfix/main.cf:ro \
-v /srv/rt.fatherlinux.com/data/mariadb:/var/lib/mysql:Z \
-v /srv/rt.fatherlinux.com/data/logs/httpd:/var/log/httpd:Z \
-v /srv/rt.fatherlinux.com/data/logs/rt4:/opt/rt4/var:Z \
-v /srv/rt.fatherlinux.com/data/backups:/root/.backups:Z \
--tmpfs /etc \
--tmpfs /var/log/ \
--tmpfs /var/tmp \
--tmpfs /var/spool \
--tmpfs /var/lib \
localhost/rt:latest
ExecStop=/usr/bin/podman stop -t 3 rt.fatherlinux.com
ExecStopAfter=/usr/bin/podman rm -f rt.fatherlinux.com
Restart=always

[Install]
WantedBy=multi-user.target

Come MediaWiki, tutti i file di configurazione sono vincolati in sola lettura, fornendoci un solido aggiornamento della sicurezza. Infine, le directory dei dati sono in lettura e scrittura, proprio come gli altri nostri contenitori. Una semplice osservazione:abbiamo ancora vincolato il montaggio del codice nell'immagine per Promemoria , che è un piccolo insieme di script autoprodotto che invia e-mail e genera biglietti per voci settimanali, mensili e annuali.

Ulteriori analisi

Affrontiamo alcuni ultimi argomenti che non sono specifici di nessuno dei nostri servizi Linux containerizzati.

Recuperabilità

La recuperabilità è qualcosa che dobbiamo considerare attentamente. Usando systemd , otteniamo una solida recuperabilità, alla pari dei normali servizi Linux. Avviso systemd riavvia i miei servizi senza battere ciglio:

podman kill -a
55299bdfebea23db81f0277d45ccd967e891ab939ae3530dde155f550c18bda9
87a34fb86f854ccb86d9be46b5fe94f6e0e15322f5301e5e66c396195480047a
C8092df3249e5b01dc11fa4372a8204c120d91ab5425eb1577eb5f786c64a34b

Guarda quello! Servizi riavviati:

podman ps
CONTAINER ID  IMAGE                       COMMAND     CREATED       STATUS                     PORTS                   NAMES
33a8f9286cee  localhost/httpd-php:latest  /sbin/init  1 second ago  Up Less than a second ago  0.0.0.0:80->80/tcp      wordpress.crunchtools.com
37dd6d4393af  localhost/rt:4.4.4          /sbin/init  1 second ago  Up Less than a second ago  0.0.0.0:8081->8081/tcp  rt.fatherlinux.com
e4cc410680b1  localhost/httpd-php:latest  /sbin/init  1 second ago  Up Less than a second ago  0.0.0.0:8080->80/tcp    learn.fatherlinux.com

Suggerimenti e trucchi

Questo è abbastanza utile per apportare modifiche ai file di configurazione. Possiamo semplicemente modificare il file di configurazione sull'host del contenitore o usare qualcosa come Ansible e uccidere tutti i contenitori con podman kill -a comando. Perché stiamo usando systemd , gestirà con garbo il riavvio dei servizi. Questo è molto conveniente.

Può essere complicato far funzionare il software all'interno di un contenitore, soprattutto quando si desidera che venga eseguito in sola lettura. Stai vincolando il processo in modi in cui non è stato necessariamente progettato. Pertanto, ecco alcuni suggerimenti e trucchi.

Innanzitutto, è utile installare alcune utilità standard nei tuoi container. In questa guida, abbiamo installato ip-utils e net-tools in modo da poter risolvere i nostri contenitori. Ad esempio, con Request Tracker, ho dovuto risolvere la seguente voce in /etc/aliases , che genera ticket dalle email:

professional:         "|/opt/rt4/bin/rt-mailgate --queue 'Professional' --action correspond --url http://localhost:8081/"

Gli strumenti curl , ping e netstat sono stati tutti estremamente utili perché stiamo usando anche DNS esterni e Cloudflare.

Il prossimo è podman diff , che ho utilizzato ampiamente per l'esecuzione di contenitori in sola lettura. Puoi eseguire il contenitore in modalità lettura-scrittura e controllare costantemente podman diff per vedere quali file sono stati modificati. Ecco un esempio:

podman diff learn.fatherlinux.com
C /var
C /var/spool
C /var/spool/cron
A /var/spool/cron/root
C /var/www
C /var/www/html
A /var/www/html/learn.fatherlinux.com
C /root
A /root/.backups

Spostamento a Kubernetes

Nota che Podman ci dirà quali file sono cambiati dall'avvio del contenitore. In questo caso, ogni file che ci interessa è su un tmpfs o su un bind mount. Questo ci consente di eseguire questo contenitore in sola lettura.

Dare un'occhiata a Kubernetes è un passo successivo naturale. Usando un comando come podman generate kube ci porterà in parte, ma dobbiamo ancora capire come gestire i volumi persistenti e i backup su quei volumi persistenti. Per ora, abbiamo deciso che Podman + systemd fornisce una bella base. Tutto il lavoro che abbiamo svolto per dividere il codice, la configurazione e i dati è necessario per portarci a Kubernetes.

Note sull'ambiente

Il mio ambiente è una singola macchina virtuale in esecuzione su Linode.com con 4 GB di RAM, due CPU e 80 GB di spazio di archiviazione. Sono stato in grado di caricare la mia immagine personalizzata di RHEL 8 per fungere da host del contenitore. Oltre a impostare il nome host e puntare il DNS tramite Cloudflare, non ho dovuto apportare altre modifiche all'host. Tutti i dati importanti sono in /srv , il che renderebbe estremamente facile la sostituzione in caso di guasto. Infine, il /srv è stato eseguito il backup completo della directory sull'host del contenitore.

Se sei interessato a guardare i file di configurazione e la struttura delle directory di /srv , ho salvato il codice qui nel mio GitHub.

Pregiudizi

Come tutti, ho dei pregiudizi e penso che sia giusto rivelarli. Ho lavorato come amministratore di sistemi Linux per gran parte della mia carriera prima di approdare in Red Hat. Ho una predilezione per Linux, e in particolare per Red Hat Enterprise Linux. Tendo anche verso l'automazione e la psicologia di come rendere quell'automa accessibile ai contributori regolari.

Una delle mie prime frustrazioni come amministratore di sistema è stata lavorare in un team con 1000 server Web Linux (facendo eCard nel Web 1.0) in cui la documentazione su come contribuire all'automazione era completamente opaca e non aveva ragioni documentate sul perché le cose stavano come stavano . Avevamo una grande automazione, ma nessuno ha considerato la psicologia di come presentare nuove persone ad essa. Era affondare o nuotare.

Questo blog mira ad aiutare le persone a superare quella gobba, mentre allo stesso tempo, rendendola quasi auto-documentante. Penso che sia di fondamentale importanza considerare gli input umani e gli output dei robot dell'automazione. Vedi anche:Documentazione bootstrap e rooting:parte 1

[ Cheat sheet gratuito:glossario Kubernetes ] 

Conclusione

Sembra così facile spostare un servizio comune come WordPress nei container, ma in realtà non lo è. L'architettura flessibile e sicura delineata in questo articolo consente a un amministratore Linux senior o alle competenze di un architetto di passare da un normale server LAMP a contenitori conformi a OCI. Questa guida ha sfruttato un motore di container chiamato Podman mentre preparava i tuoi servizi per Kubernetes. Separare codice, configurazione e dati è un passaggio necessario per passare a Kubernetes. Tutto inizia con competenze Linux solide e di base.

Alcune decisioni evidenziate in questo articolo mettono in discussione di proposito vari malintesi all'interno della comunità dei container, ad esempio utilizzando systemd in un container o concentrarsi solo sull'immagine di base più piccola che è possibile trovare senza prestare attenzione all'intera catena di fornitura del software. Tuttavia, il prodotto finale è semplice da usare. Fornisce un flusso di lavoro abbastanza simile a un server LAMP tradizionale, che richiede un carico cognitivo minimo per gli amministratori di sistemi Linux tradizionali.

Alcune delle decisioni di progettazione prese in questo articolo sono un compromesso e sono imperfette. Tuttavia, li ho realizzati perché capisco sia le pressioni di una moderna cultura DevOps sia la psicologia delle operazioni e dei team di sviluppo. Volevo offrire la flessibilità necessaria per ottenere più valore dai contenitori. Questo set di servizi dovrebbe essere utile come modello per la migrazione di molti dei propri servizi nei container. Ciò semplificherà la loro gestione, aggiornamento e ripristino. Questo non solo aiuta gli amministratori Linux esistenti, ma anche le future coorti che erediteranno questi servizi, inclusa la versione futura di me che avrà dimenticato tutti i dettagli. Questi servizi containerizzati sono essenzialmente autodocumentanti in uno stile favorevole a una cultura DevOps di successo.

Questa serie è basata su "A Hacker's Guide to Moving Linux Services into Containers" su CrunchTools.com ed è stata ripubblicata con il permesso.


Linux
  1. Come ho abbandonato il mio vecchio sistema operativo e sono passato a Linux

  2. Come spostare MediaWiki in un container Linux

  3. Come spostare WordPress in un container Linux

  4. Come posso spostare i file con xargs su Linux?

  5. Come spostare una partizione in GNU/Linux?

Come SSH in una directory particolare su Linux

Come spostare una directory in Linux

Come scrivere dati in file in Linux

Come spostare un gran numero di file in Linux

Come unire più file PDF in un unico PDF in Linux

Come SSH in un Docker Container