GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo mover Request Tracker a un contenedor de Linux

Aunque me tomó mucho tiempo motivarme, finalmente organicé varios servicios personales de Linux en contenedores. He documentado el proyecto en esta serie. En este artículo, lo guiaremos a través de un ejemplo final, Request Tracker.

Para comenzar, analizamos algunos principios generales para migrar aplicaciones a contenedores. Luego, analizamos la creación de contenedores de WordPress y, a continuación, analizamos el traslado de MediaWiki a un contenedor. Ese proyecto fue un poco más complicado que el primero, con la adición de la programación de tareas. En este artículo final, vamos a considerar una migración mucho más compleja. Específicamente, veremos Request Tracker. Este servicio puede ser el más complicado porque tanto la compilación como la ejecución son bastante sofisticadas.

Nota del editor:para los fines de este artículo, asumimos que construirá sus contenedores en Red Hat Enterprise Linux 8 usando la compilación podman. Es posible que pueda usar las instrucciones en otras distribuciones o con otras cadenas de herramientas; sin embargo, es posible que se requieran algunas modificaciones.

Rastreador de solicitudes de mudanza

Construir

A diferencia de WordPress y MediaWiki, que se ejecutan en una imagen de una sola capa encima de una imagen base, Request Tracker usa dos capas encima de una imagen base. Miremos cada capa y veamos por qué lo hicimos de esta manera.

La primera capa está construida de manera bastante similar a httpd-php imagen. Esta imagen agrega los servicios necesarios para una aplicación web basada en Perl. Incluimos Apache, el módulo FastCGI, Perl, MariaDB, cron y algunas utilidades básicas para la resolución de problemas:

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 segunda capa es donde las cosas se vuelven bastante sofisticadas. Request Tracker usa muchos módulos Perl de CPAN. Muchos de estos módulos están compilados con gcc y toma mucho tiempo para instalar. También tomó mucho trabajo concretar todas estas dependencias para que Request Tracker se instalara correctamente. Históricamente, habríamos capturado esto en un script en alguna parte, pero con los contenedores, podemos tenerlo todo en un Containerfile. Es muy conveniente.

[ También puede disfrutar de: 6 guías sobre cómo hacer que los contenedores sean seguros ]

Lo siguiente que debe notar sobre este archivo es que es una compilación de varias etapas. Podman y Buildah pueden hacer compilaciones de múltiples etapas y pueden ser extremadamente útiles para aplicaciones como Request Tracker. Podríamos haberlo montado en directorios, como hicimos con WordPress y MediaWiki, pero en su lugar elegimos una compilación de varias etapas. Esto nos dará portabilidad y velocidad si necesitamos reconstruir la aplicación en otro lugar.

Se puede considerar que las compilaciones de varias etapas capturan el servidor de desarrollo y el servidor de producción en un único archivo de compilación. Históricamente, los servidores de desarrollo eran en realidad los más difíciles de automatizar. Desde los primeros días de CFEngine a mediados de la década de 1990, los desarrolladores se negaron a usar el control de versiones y agregaron todo lo que querían a los servidores de desarrollo para que funcionaran. A menudo, ni siquiera sabían qué agregaron para completar una construcción. En realidad, esto era racional cuando tenía servidores de larga duración que estaban bien respaldados, pero siempre causaba dolor cuando los administradores de sistemas tenían que "actualizar el servidor de desarrollo". Fue una pesadilla hacer que las compilaciones funcionaran en un servidor nuevo con un sistema operativo actualizado.

Con las compilaciones de varias etapas, capturamos todas las instrucciones de compilación e incluso las capas de caché que se construyen. Podemos reconstruir este servidor virtual de desarrollo en cualquier lugar que queramos.

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 segunda etapa de esta compilación de varias etapas construye el servidor de producción virtual. Al dividir esto en una segunda etapa, no tenemos que instalar herramientas de desarrollo como gcc o expat-devel en la imagen de producción final. Esto reduce el tamaño de nuestra imagen y reduce el tamaño de la cadena de suministro de software en los servicios expuestos a la red. Esto también reduce potencialmente las posibilidades de que alguien haga algo desagradable con nuestro contenedor, en caso de que lo pirateen.

Solo instalamos las utilidades de correo en esta segunda etapa, que define la segunda capa de nuestra imagen de producción para Request Tracker. Podríamos haber instalado estas utilidades en el httpd-perl capa, pero muchas otras aplicaciones de Perl no necesitarán utilidades de correo.

Otra ventaja de las compilaciones de varias etapas es que no tenemos que reconstruir todos esos módulos de Perl cada vez que queremos actualizar el intérprete de Perl, Apache o MariaDB para parches de seguridad.

Corre

Ahora, al igual que WordPress y MediaWiki, echemos un vistazo a algunos de los trucos que usamos en tiempo de ejecución:

[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

Al igual que MediaWiki, todos los archivos de configuración están montados en enlace en modo de solo lectura, lo que nos brinda una sólida actualización de seguridad. Finalmente, los directorios de datos son de lectura y escritura, al igual que nuestros otros contenedores. Una simple observación:aún enlazamos código de montaje en la imagen para Recordatorios , que es un pequeño conjunto de secuencias de comandos de cosecha propia que envían correos electrónicos y generan tickets para entradas semanales, mensuales y anuales.

Más análisis

Abordemos algunos temas finales que no son específicos de ninguno de nuestros servicios de Linux en contenedores.

Recuperabilidad

La recuperabilidad es algo que tenemos que considerar cuidadosamente. Usando systemd , obtenemos una capacidad de recuperación sólida, a la par de los servicios regulares de Linux. Aviso systemd reinicia mis servicios sin pestañear:

podman kill -a
55299bdfebea23db81f0277d45ccd967e891ab939ae3530dde155f550c18bda9
87a34fb86f854ccb86d9be46b5fe94f6e0e15322f5301e5e66c396195480047a
C8092df3249e5b01dc11fa4372a8204c120d91ab5425eb1577eb5f786c64a34b

¡Mira eso! Servicios reiniciados:

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

Consejos y trucos

Esto es bastante útil para hacer cambios en el archivo de configuración. Simplemente podemos editar el archivo de configuración en el host del contenedor o usar algo como Ansible y eliminar todos los contenedores con podman kill -a dominio. Porque estamos usando systemd , manejará con gracia el reinicio de los servicios. Esto es muy conveniente.

Puede ser complicado lograr que el software se ejecute dentro de un contenedor, especialmente cuando desea que se ejecute en modo de solo lectura. Está restringiendo el proceso de maneras en las que no fue necesariamente diseñado. Como tal, aquí hay algunos consejos y trucos.

Primero, es útil instalar algunas utilidades estándar en sus contenedores. En esta guía, instalamos ip-utils y net-tools para que podamos solucionar los problemas de nuestros contenedores. Por ejemplo, con Request Tracker, tuve que solucionar el problema de la siguiente entrada en /etc/aliases , que genera tickets a partir de correos electrónicos:

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

Las herramientas curl , ping y netstat fueron extremadamente útiles porque también usamos DNS externo y Cloudflare.

El siguiente es podman diff , que utilicé mucho para ejecutar contenedores como de solo lectura. Puede ejecutar el contenedor en modo de lectura y escritura y verificar constantemente podman diff para ver qué archivos han cambiado. He aquí un ejemplo:

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

Pasar a Kubernetes

Tenga en cuenta que Podman nos dirá qué archivos han cambiado desde que se inició el contenedor. En este caso, todos los archivos que nos interesan están en un montaje tmpfs o bind. Esto nos permite ejecutar este contenedor como de solo lectura.

Echar un vistazo a Kubernetes es el siguiente paso natural. Usando un comando como podman generate kube nos llevará parte del camino hasta allí, pero aún tenemos que descubrir cómo administrar los volúmenes persistentes y las copias de seguridad en esos volúmenes persistentes. Por ahora, hemos decidido que Podman + systemd proporciona una buena base. Todo el trabajo que hemos realizado con la división del código, la configuración y los datos es un requisito para llegar a Kubernetes.

Notas sobre el medio ambiente

Mi entorno es una única máquina virtual que se ejecuta en Linode.com con 4 GB de RAM, dos CPU y 80 GB de almacenamiento. Pude cargar mi propia imagen personalizada de RHEL 8 para que sirviera como host del contenedor. Aparte de configurar el nombre de host y apuntar DNS a través de Cloudflare, realmente no tuve que hacer ningún otro cambio en el host. Todos los datos importantes están en /srv , lo que lo haría extremadamente fácil de reemplazar si fallara. Finalmente, el /srv El directorio en el host del contenedor está completamente respaldado.

Si está interesado en ver los archivos de configuración y la estructura de directorios de /srv , he guardado el código aquí en mi GitHub.

Sesgos

Como todos, tengo prejuicios y creo que es justo revelarlos. Trabajé como administrador de sistemas Linux durante gran parte de mi carrera antes de llegar a Red Hat. Tengo una preferencia por Linux y, en particular, por Red Hat Enterprise Linux. También me inclino por la automatización y la psicología de cómo hacer que ese autómata sea accesible para los colaboradores regulares.

Una de mis primeras frustraciones como administrador de sistemas fue trabajar en un equipo con 1000 servidores web Linux (haciendo eCards en web 1.0) donde la documentación sobre cómo contribuir a la automatización era completamente opaca y no tenía un razonamiento documentado de por qué las cosas eran como eran. . Tuvimos una gran automatización, pero nadie consideró la psicología de cómo presentarle a nuevas personas. Era nadar o hundirse.

Este blog tiene como objetivo ayudar a las personas a superar ese obstáculo y, al mismo tiempo, hacerlo casi autodocumentado. Creo que es de vital importancia considerar las entradas humanas y las salidas robóticas de la automatización. Ver también:Documentación de Bootstrapping y Rooting:Parte 1

[ Hoja de referencia gratuita:glosario de Kubernetes ] 

Conclusión

Parece tan fácil mover un servicio común como WordPress a contenedores, pero en realidad no lo es. La arquitectura flexible y segura descrita en este artículo reúne las habilidades de un administrador o arquitecto senior de Linux para pasar de un servidor LAMP normal a contenedores compatibles con OCI. Esta guía aprovechó un motor de contenedor llamado Podman mientras preparaba sus servicios para Kubernetes. Separar su código, configuración y datos es un paso necesario para pasar a Kubernetes. Todo comienza con habilidades sólidas y fundamentales de Linux.

Algunas decisiones destacadas en este artículo desafían deliberadamente varios conceptos erróneos dentro de la comunidad de contenedores, como usar systemd en un contenedor o solo enfocarse en la imagen base más pequeña que pueda encontrar sin prestar atención a toda la cadena de suministro de software. Sin embargo, el producto final es fácil de usar. Proporciona un flujo de trabajo bastante similar a un servidor LAMP tradicional, que requiere una carga cognitiva mínima para los administradores de sistemas Linux tradicionales.

Algunas de las decisiones de diseño tomadas en este artículo son un compromiso e imperfectas. Aún así, los hice porque entiendo tanto las presiones de una cultura DevOps moderna como la psicología de las operaciones y los equipos de desarrollo. Quería brindar la flexibilidad para obtener más valor de los contenedores. Este conjunto de servicios debería ser útil como modelo para migrar muchos de sus propios servicios a contenedores. Esto simplificará su gestión, actualización y recuperación. Esto no solo ayuda a los administradores de Linux existentes, sino también a las generaciones futuras que heredarán estos servicios, incluida la versión futura de mí que habrá olvidado todos los detalles. Estos servicios en contenedores son esencialmente autodocumentados en un estilo que conduce a una cultura DevOps exitosa.

Esta serie se basa en "A Hacker's Guide to Move Linux Services into Containers" en CrunchTools.com y se vuelve a publicar con autorización.


Linux
  1. Cómo mover MediaWiki a un contenedor de Linux

  2. Cómo mover WordPress a un contenedor de Linux

  3. ¿Cómo iniciar sesión en el contenedor Lxc?

  4. ¿Cómo puedo mover archivos con xargs en Linux?

  5. ¿Cómo mover una partición en GNU/Linux?

Cómo SSH en un directorio particular en Linux

Cómo mover un directorio en Linux

Cómo escribir datos en un archivo en Linux

Cómo mover una gran cantidad de archivos en Linux

Cómo combinar varios archivos PDF en un solo PDF en Linux

Cómo usar SSH en un contenedor Docker