GNU/Linux >> Tutoriels Linux >  >> Linux

Comment déplacer Request Tracker dans un conteneur Linux

Même s'il m'a fallu beaucoup de temps pour me motiver, j'ai finalement conteneurisé plusieurs services Linux personnels. J'ai documenté le projet dans cette série. Dans cet article, nous allons vous présenter un dernier exemple, Request Tracker.

Pour commencer, nous avons examiné quelques principes généraux de migration d'applications vers des conteneurs. Ensuite, nous avons examiné la conteneurisation de WordPress, puis nous avons discuté du déplacement de MediaWiki dans un conteneur. Ce projet était un peu plus impliqué que le premier, avec l'ajout de la planification des tâches. Dans ce dernier article, nous allons envisager une migration beaucoup plus complexe. Plus précisément, nous examinerons Request Tracker. Ce service peut être le plus délicat car la construction et l'exécution sont assez sophistiquées.

Note de l'éditeur :dans le cadre de cet article, nous supposons que vous allez créer vos conteneurs sur Red Hat Enterprise Linux 8 à l'aide de podman build. Vous pourrez peut-être utiliser les instructions sur d'autres distributions ou avec d'autres chaînes d'outils, cependant, certaines modifications peuvent être nécessaires.

Suivi des demandes de déménagement

Construire

Contrairement à WordPress et MediaWiki, qui s'exécutent sur une image à une seule couche au-dessus d'une image de base, Request Tracker utilise deux couches au-dessus d'une image de base. Examinons chaque couche et voyons pourquoi nous l'avons fait de cette façon.

La première couche est construite assez similaire au httpd-php image. Cette image ajoute les services nécessaires pour une application Web basée sur Perl. Nous incluons Apache, le module FastCGI, Perl, MariaDB, cron et quelques utilitaires de base pour le dépannage :

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

La deuxième couche est celle où les choses deviennent assez sophistiquées. Request Tracker utilise beaucoup de modules Perl de CPAN. Beaucoup de ces modules sont compilés avec gcc et prend beaucoup de temps à installer. Il a également fallu beaucoup de travail pour définir toutes ces dépendances afin que Request Tracker s'installe avec succès. Historiquement, nous aurions capturé cela dans un script quelque part, mais avec les conteneurs, nous pouvons tout avoir dans un seul fichier conteneur. C'est très pratique.

[ Vous pourriez également apprécier : 6 guides sur la sécurisation des conteneurs ]

La prochaine chose que vous devriez remarquer à propos de ce fichier est qu'il s'agit d'une construction en plusieurs étapes. Podman et Buildah peuvent absolument faire des constructions en plusieurs étapes, et ils peuvent être extrêmement utiles pour des applications comme Request Tracker. Nous aurions pu monter des liens dans des répertoires, comme nous l'avons fait avec WordPress et MediaWiki, mais nous avons plutôt choisi une construction en plusieurs étapes. Cela nous donnera la portabilité et la rapidité si nous devons reconstruire l'application ailleurs.

Les builds en plusieurs étapes peuvent être considérées comme la capture du serveur de développement et du serveur de production dans un seul fichier de build. Historiquement, les serveurs de développement étaient en fait les plus difficiles à automatiser. Depuis les débuts de CFEngine au milieu des années 1990, les développeurs ont refusé d'utiliser le contrôle de version et ont ajouté tout ce qu'ils voulaient aux serveurs de développement pour les faire fonctionner. Souvent, ils ne savaient même pas ce qu'ils ajoutaient pour terminer une construction. C'était en fait rationnel lorsque vous disposiez de serveurs de longue durée bien sauvegardés, mais cela causait toujours des difficultés lorsque les administrateurs système devaient "mettre à niveau le serveur de développement". C'était un cauchemar de faire fonctionner des builds sur un tout nouveau serveur avec un nouveau système d'exploitation.

Avec les builds en plusieurs étapes, nous capturons toutes les instructions de build et même les couches de cache qui sont construites. Nous pouvons reconstruire ce serveur virtuel de développement où nous voulons.

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 deuxième étape de cette génération en plusieurs étapes construit le serveur de production virtuel. En divisant cela en une deuxième étape, nous n'avons pas besoin d'installer des outils de développement comme gcc ou expat-devel dans l'image de production finale. Cela réduit la taille de notre image et réduit la taille de la chaîne d'approvisionnement des logiciels dans les services exposés au réseau. Cela réduit également potentiellement les chances que quelqu'un fasse quelque chose de mal avec notre conteneur, s'il pirate.

Nous installons uniquement les utilitaires de messagerie dans cette deuxième étape, qui définit la deuxième couche de notre image de production pour Request Tracker. Nous aurions pu installer ces utilitaires dans le httpd-perl couche, mais de nombreuses autres applications Perl n'auront pas besoin d'utilitaires de messagerie.

Une autre commodité des constructions en plusieurs étapes est que nous n'avons pas à reconstruire tous ces modules Perl chaque fois que nous voulons mettre à jour l'interpréteur Perl, Apache ou MariaDB pour les correctifs de sécurité.

Exécuter

Maintenant, comme WordPress et MediaWiki, examinons quelques-unes des astuces que nous utilisons lors de l'exécution :

[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

Comme MediaWiki, tous les fichiers de configuration sont montés en liaison en lecture seule, ce qui nous donne une mise à niveau de sécurité solide. Enfin, les répertoires de données sont en lecture-écriture, tout comme nos autres conteneurs. Une observation simple :nous avons quand même lié le montage de certains codes dans l'image pour les rappels , qui est un petit ensemble de scripts maison qui envoient des e-mails et génèrent des tickets pour les entrées hebdomadaires, mensuelles et annuelles.

Analyse complémentaire

Abordons quelques derniers sujets qui ne sont spécifiques à aucun de nos services Linux conteneurisés.

Récupération

La récupérabilité est quelque chose que nous devons considérer attentivement. En utilisant systemd , nous obtenons une capacité de restauration solide, à égalité avec les services Linux classiques. Remarquez systemd redémarre mes services sans sourciller :

podman kill -a
55299bdfebea23db81f0277d45ccd967e891ab939ae3530dde155f550c18bda9
87a34fb86f854ccb86d9be46b5fe94f6e0e15322f5301e5e66c396195480047a
C8092df3249e5b01dc11fa4372a8204c120d91ab5425eb1577eb5f786c64a34b

Regarde ça! Services redémarrés :

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

Conseils et astuces

Ceci est très utile pour apporter des modifications au fichier de configuration. Nous pouvons simplement modifier le fichier de configuration sur l'hôte du conteneur ou utiliser quelque chose comme Ansible et tuer tous les conteneurs avec le podman kill -a commande. Parce que nous utilisons systemd , il gérera gracieusement le redémarrage des services. C'est très pratique.

Il peut être difficile d'exécuter un logiciel dans un conteneur, en particulier lorsque vous souhaitez qu'il s'exécute en lecture seule. Vous limitez le processus d'une manière qui n'a pas nécessairement été conçue. À ce titre, voici quelques trucs et astuces.

Tout d'abord, il est utile d'installer certains utilitaires standards dans vos conteneurs. Dans ce guide, nous avons installé ip-utils et net-tools afin que nous puissions dépanner nos conteneurs. Par exemple, avec Request Tracker, j'ai dû dépanner l'entrée suivante dans /etc/aliases , qui génère des tickets à partir d'e-mails :

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

Les outils curl , ping , et netstat étaient tous extrêmement utiles car nous utilisons également un DNS externe et Cloudflare.

La prochaine étape est podman diff , que j'ai beaucoup utilisé pour exécuter des conteneurs en lecture seule. Vous pouvez exécuter le conteneur en mode lecture-écriture et vérifier en permanence podman diff pour voir quels fichiers ont été modifiés. Voici un exemple :

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

Passer à Kubernetes

Notez que Podman nous dira quels fichiers ont changé depuis le démarrage du conteneur. Dans ce cas, chaque fichier qui nous intéresse se trouve soit sur un tmpfs, soit sur un montage lié. Cela nous permet d'exécuter ce conteneur en lecture seule.

Examiner attentivement Kubernetes est une prochaine étape naturelle. Utiliser une commande comme podman generate kube nous amènera une partie du chemin, mais nous devons encore comprendre comment gérer les volumes persistants et les sauvegardes sur ces volumes persistants. Pour l'instant, nous avons décidé que Podman + systemd offre une belle base. Tout le travail que nous avons effectué pour diviser le code, la configuration et les données est nécessaire pour nous amener à Kubernetes.

Remarques sur l'environnement

Mon environnement est une seule machine virtuelle fonctionnant sur Linode.com avec 4 Go de RAM, deux processeurs et 80 Go de stockage. J'ai pu télécharger ma propre image personnalisée de RHEL 8 pour servir d'hôte de conteneur. En dehors de la définition du nom d'hôte et du pointage DNS via Cloudflare, je n'ai vraiment pas eu à apporter d'autres modifications à l'hôte. Toutes les données importantes sont dans /srv , ce qui le rendrait extrêmement facile à remplacer en cas de défaillance. Enfin, le /srv répertoire sur l'hôte du conteneur est entièrement sauvegardé.

Si vous souhaitez consulter les fichiers de configuration et la structure des répertoires de /srv , j'ai enregistré le code ici dans mon GitHub.

Biais

Comme tout le monde, j'ai des préjugés et je pense qu'il est juste de les divulguer. J'ai été administrateur système Linux pendant la majeure partie de ma carrière avant de rejoindre Red Hat. J'ai un penchant pour Linux, et pour Red Hat Enterprise Linux en particulier. Je tends également vers l'automatisation et la psychologie de la façon de rendre cet automate accessible aux contributeurs réguliers.

L'une de mes premières frustrations en tant qu'administrateur système était de travailler dans une équipe avec 1000 serveurs Web Linux (faisant des eCards dans le Web 1.0) où la documentation sur la façon de contribuer à l'automatisation était complètement opaque et n'avait aucun raisonnement documenté pour expliquer pourquoi les choses étaient comme elles étaient . Nous avions une grande automatisation, mais personne n'a considéré la psychologie de la façon d'y introduire de nouvelles personnes. C'était couler ou nager.

Ce blog vise à aider les gens à surmonter cette difficulté, tout en le rendant presque auto-documenté. Je pense qu'il est extrêmement important de prendre en compte les entrées humaines et les sorties robotiques de l'automatisation. Voir aussi :Documentation d'amorçage et d'enracinement :partie 1

[ Aide-mémoire gratuit :glossaire Kubernetes ] 

Conclusion

Il semble si facile de déplacer un service commun comme WordPress dans des conteneurs, mais ce n'est vraiment pas le cas. L'architecture flexible et sécurisée décrite dans cet article rassemble les compétences d'un administrateur ou d'un architecte Linux senior pour passer d'un serveur LAMP standard à des conteneurs compatibles OCI. Ce guide a exploité un moteur de conteneur appelé Podman tout en préparant vos services pour Kubernetes. Séparer votre code, votre configuration et vos données est une étape nécessaire pour passer à Kubernetes. Tout commence par des compétences Linux solides et fondamentales.

Certaines décisions mises en évidence dans cet article remettent délibérément en question diverses idées fausses au sein de la communauté des conteneurs, comme utiliser systemd dans un conteneur ou se concentrer uniquement sur la plus petite image de base que vous pouvez trouver sans prêter attention à l'ensemble de la chaîne d'approvisionnement logicielle. Cependant, le produit final est simple à utiliser. Il fournit un flux de travail assez similaire à un serveur LAMP traditionnel, nécessitant une charge cognitive minimale pour les administrateurs de systèmes Linux traditionnels.

Certaines des décisions de conception prises dans cet article sont un compromis et imparfaites. Pourtant, je les ai créés parce que je comprends à la fois les pressions d'une culture DevOps moderne et la psychologie des opérations et des équipes de développement. Je voulais offrir la flexibilité nécessaire pour tirer le meilleur parti des conteneurs. Cet ensemble de services devrait être utile comme modèle pour migrer nombre de vos propres services dans des conteneurs. Cela simplifiera leur gestion, leur mise à niveau et leur récupération. Cela aide non seulement les administrateurs Linux existants, mais aussi les futures cohortes qui hériteront de ces services, y compris la future version de moi qui aura oublié tous les détails. Ces services conteneurisés sont essentiellement auto-documentés dans un style propice à une culture DevOps réussie.

Cette série est basée sur "A Hacker's Guide to Moving Linux Services into Containers" sur CrunchTools.com et est republiée avec autorisation.


Linux
  1. Comment j'ai abandonné mon ancien système d'exploitation et sauté dans Linux

  2. Comment déplacer MediaWiki dans un conteneur Linux

  3. Comment se connecter au conteneur Lxc ?

  4. Comment puis-je déplacer des fichiers avec xargs sous Linux ?

  5. Comment déplacer une partition sous GNU/Linux ?

Comment SSH dans un répertoire particulier sous Linux

Comment déplacer un répertoire sous Linux

Comment écrire des données dans un fichier sous Linux

Comment déplacer un grand nombre de fichiers sous Linux

Comment fusionner plusieurs fichiers PDF en un seul PDF sous Linux

Comment se connecter en SSH à un conteneur Docker