Riot Games

En este primer tutorial de la serie Docker, aprenderás:

  • Lo que estamos tratando de lograr en Riot

  • Configuración básica de Docker

  • Comandos Básicos de Extracción de Acoplador

  • Cómo ejecutar contenedores Docker como Demonios

  • Opciones de configuración básicas de Jenkins

Cuando empecé a aprender sobre Docker hace un año y a explorar su uso, tuve problemas para encontrar documentación y ejemplos excelentes , incluso hoy en día muchos describen casos de uso simples que, en última instancia, no están listos para la producción. La producción de aplicaciones con contenedores Docker requiere ajustarse a su naturaleza efímera y al enfoque de un solo proceso. Esto presenta desafíos para las aplicaciones con necesidades de persistencia de datos o arquitecturas multiproceso.

Como mencioné en mi último post, usamos Jenkins como una pieza fundamental de software de código abierto sobre la que construimos nuestra automatización. Jenkins también es una gran aplicación para demostrar una forma de pensar en «Acoplar» sus aplicaciones. Implementamos Jenkins con estos componentes arquitectónicos en mente:

  • Servidor maestro Jenkins (proceso Java)

  • Datos maestros de Jenkins (Complementos, Definiciones de trabajos, etc)

  • Proxy web NGINX (utilizamos certificados SSL, etc., con NGINX es una opción fácil aquí)

  • Construir agentes esclavos (máquinas que se conectan a SSH o a JNLP con Jenkins Master)

Este es un buen lugar para empezar. En esta serie de publicaciones de blog, cubriré formas de pensar en todo lo anterior como contenedores y terminaré con una visión avanzada de las formas de usar contenedores acoplables como esclavos de construcción. Para empezar, crearemos un servidor maestro Jenkins en un contenedor Docker. Luego pasaremos a lidiar con la persistencia de datos y agregar un proxy web con NGINX.

Toda esta serie de blogs cubrirá los siguientes conceptos de Docker:

  • Crear sus propios archivos acoplables

  • Minimizar las dependencias de imágenes en imágenes públicas

  • Creación y uso de volúmenes de datos, incluidas las copias de seguridad

  • Creación de «entornos de compilación» en contenedores mediante contenedores

  • Manejo de datos «secretos» con imágenes y Jenkins

Si no ha echado un vistazo a la imagen de Cloudbees Jenkins Docker, comience por ahí, ya que es realmente bastante buena. Este fue mi punto de referencia cuando pensé por primera vez en ejecutar Jenkins en un contenedor Docker y para muchas personas esto podría ser suficiente. Puedes encontrar su documentación aquí y su archivo de repositorio/Docker de Git aquí.

Este primer blog se divide en dos planes de lecciones. Cada uno tiene un tamaño que tarda unos 30 minutos en completarse. En primer lugar, la primera parte es preparar su entorno de desarrollo y aprender a trabajar con el contenedor de docker Jenkins predeterminado que ofrece Cloudbees. La segunda parte trata de sentar las bases para envolver esta imagen en su propio archivo acoplable y tomar un control más elegante de la imagen. Juntos, están diseñados para ayudarte a comenzar, especialmente si nunca has trabajado con Docker antes o eres relativamente nuevo en Docker, aunque suponen que ya sabes y entiendes cómo trabajar con Jenkins. Si tiene experiencia con Docker, parte del material de la Lección 1 será un resumen de cosas que probablemente ya sepa.

LECCIÓN 1: CONFIGURA Y EJECUTA TU PRIMERA IMAGEN

Vamos a prepararte para rodar. En Riot trabajamos con Docker (y Jenkins) en Windows, Mac OSX y Linux. Prefiero trabajar con Docker en OSX, aunque es perfectamente funcional en Windows desde Docker 1.6. En estos días hay excelentes instaladores para ambos sistemas operativos. Trabajaré desde una perspectiva OSX, pero existen las mismas herramientas para Windows.

REQUISITOS PREVIOS:

1. Necesitará Windows 10 Pro o Mac OSX Yosemite 10.10.3 (o posterior)

2. Si utiliza Windows, debe asegurarse de que tiene habilitada la virtualización de Windows (consulte la documentación que proporciona Docker)

Una NOTA RÁPIDA SOBRE KITEMATIC

Con Docker 1.8 y el lanzamiento de Docker Toolbox, Docker ahora incluye «Kitematic», una ingeniosa herramienta de interfaz gráfica de usuario para ayudar a administrar y visualizar lo que sucede con las imágenes y contenedores de Docker. La mayor parte de este tutorial se centra en usar argumentos de línea de comandos y trabajar con Docker sin la interfaz gráfica de usuario Kitematic. Esto es para exponerte mejor a los mecanismos subyacentes. Del mismo modo, en blogs posteriores empiezo a cubrir el uso de Compose para iniciar y detener múltiples contenedores a la vez.

PASO 1: INSTALE DOCKER

1. Ir a: https://www.docker.com/docker-mac o https://www.docker.com/docker-windows

2. Descargue e instale la versión adecuada de Docker para su sistema operativo

3. Siga todas las instrucciones de configuración.

4. Compruebe que la instalación funciona abriendo el shell recomendado para su sistema operativo (Terminal para OSX, Powershell para Windows) ejecutando «Terminal de inicio rápido de Docker». En Windows, este será un acceso directo en el escritorio. En OSX, lo encontrará en la carpeta aplicaciones/Docker. Compruebe los siguientes comandos y asegúrese de que no se producen errores

docker ps
docker info

5. Antes de hacer cualquier otra cosa, deberíamos aumentar la configuración predeterminada de memoria y CPU que usa Docker. Más tarde vamos a ajustar Jenkins para usar más memoria y si no ajustamos estos ajustes primero, Jenkins puede fallar.

  • Vaya a su widget Acoplable en la barra de herramientas y seleccione «Preferencias»

  • Vaya a la pestaña Configuración avanzada

  • Aumentar el uso de CPU a al menos 4 núcleos

6. Aumente el uso de memoria a al menos 8 GB, preferiblemente más, algo así como 12 GB para estar seguro (si lo tiene disponible)

PASO 2: TIRE Y EJECUTE EL CONTENEDOR CLOUDBEES JENKINS

1. Permanezca en la ventana de su terminal Acoplable.

2. Saca a Jenkins del repositorio público ejecutando:

docker pull jenkins/jenkins
docker run -p 8080:8080 --name=jenkins-master jenkins/jenkins

3. Tenga en cuenta que el mensaje «Configuración inicial de Jenkins» en su ventana de shell generará una contraseña para usted. Anótalo, ya que lo necesitarás más tarde. Si lo pierde, puede ejecutar ‘ docker exec jenkins-master cat / var/jenkins_home/secrets / initialAdminPassword` con su contenedor ejecutándose para recuperarlo.

4. Abra su navegador favorito y apunte a http://localhost:8080

Tenga en cuenta que verá que uso la bandera Docker name name y el nombre del contenedor jenkins-master – esta es una convención que usaré en todo este blog. Nombrar sus contenedores es una práctica recomendada práctica con tres beneficios:

1. Hace que sean fáciles de recordar e interactuar con

2. Docker no permite que dos contenedores tengan el mismo nombre, lo que evita errores como iniciar accidentalmente dos contenedores idénticos

3. Muchas herramientas Docker comunes (como Docker Compose) usan nombres de contenedores específicos, por lo que acostumbrarse a nombrar sus contenedores es una buena práctica recomendada.

PASO 3: HACER ESTO UN POCO MÁS PRÁCTICO

El paso anterior inicia Jenkins con su configuración de inicio más básica. Incluso puede ver que Jenkins necesita una configuración básica y le está pidiendo una contraseña de administrador (que puede obtener de los registros que se muestran en su pantalla durante el inicio). Si eres como Riot, es poco probable que ejecutes Jenkins en la configuración predeterminada. Veamos cómo agregar algunas opciones útiles. No nos molestaremos en configurar Jenkins todavía; es suficiente con saber que se puede iniciar y ejecutar.

PASO 3A: DEMONIZACIÓN

Probablemente no quiera ver los registros de Jenkins escupidos a la salida estándar la mayor parte del tiempo. Por lo tanto, use la bandera del demonio acoplable para iniciar el contenedor (-d).

1. Ctrl-c en la ventana del terminal ejecutando el contenedor para detenerlo

2. Ejecute los siguientes comandos

docker rm jenkins-master
docker run -p 8080:8080 --name=jenkins-master -d jenkins/jenkins

Ahora debería mostrar una cadena de hash y devolverla a su terminal. Si es nuevo en Docker, esa cadena de hash es en realidad el ID único de su contenedor (útil si comienza a automatizar estos comandos).

PASO 3B: CONFIGURACIÓN DE MEMORIA

Tendemos a ejecutar Jenkins con algunos ajustes robustos en Riot. ¿Recuerdas cuando aumentaste la CPU / Memoria que usa Docker antes? Esta es la razón principal. Para un inicio básico, ejecute los siguientes comandos

docker stop jenkins-master
docker rm jenkins-master
docker run -p 8080:8080 --name=jenkins-master -d --env JAVA_OPTS="-Xmx8192m" jenkins/jenkins

Eso debería darle a Jenkins un buen grupo de memoria de 8 GB y espacio para manejar la recolección de basura.

PASO 3C: AUMENTAR EL GRUPO DE CONEXIONES

En Riot, recibimos mucho tráfico a nuestro servidor Jenkins, por lo que hemos aprendido a darle a Jenkins un poco más de espacio para respirar. Ejecute lo siguiente

docker stop jenkins-master
docker rm jenkins-master

Eso le dará a Jenkins un buen grupo de manipuladores y una gorra. Coincidentemente, ahora ha aprendido a usar tanto los OPT de JAVA como los OPT de JENKINS como variables de entorno de una manera significativa. Tenga en cuenta que esto funciona debido a la forma en que Cloudbees estructuró convenientemente su archivo Docker Jenkins.

PASO 4: JUNTANDO TODO

Coloqué todo lo que aprendimos aquí en un simple makefile para que pueda usar los comandos make para controlar la ejecución de su contenedor de docker Jenkins. Puedes encontrarlo aquí:

  • https://github.com/maxfields2000/docker Jenkins_tutorial / árbol / maestro / tutorial_01

Puede utilizar los siguientes comandos:

  • make build-Extrae la imagen de Jenkins

  • make run-Ejecuta el contenedor

  • hacer stop-Detiene el contenedor

  • limpiar: Detiene y elimina el contenedor existente

No tienes que usar el makefile, simplemente lo encuentro más fácil que escribir todo el comando run. En su lugar, podría colocarlos fácilmente en un guion de su elección.

Esperamos que vea lo fácil que es ponerse en marcha con Docker y Jenkins. He intentado darle algunas opciones básicas para tomar el contenedor predeterminado de Cloudbees Jenkins y hacerlo un poco más usable. Cloudbees tiene muchos tutoriales útiles para ejecutar su contenedor, como cómo preinstalar complementos y almacenar datos de Jenkins.

Eso me lleva a publicaciones futuras sobre el tema. Este contenedor / imagen es útil, pero tiene algunos inconvenientes: no hay registro consistente, no hay persistencia, no hay proxy de servidor web frente a él y no hay una forma limpia de garantizar que use la versión de Jenkins que desea. Esto plantea preguntas como: ¿qué pasa si quieres seguir con una versión anterior? ¿O qué pasa si quieres usar el último período de lanzamiento disponible?

En la próxima lección cubriré cómo hacer este contenedor un poco más robusto. Especialmente:

  • Crear su propio archivo acoplable para envolver la base de Cloudbees

  • Mover algunas de las variables de entorno a esta nueva imagen

  • Creación de una carpeta de registro, configuración de permisos y otros directorios Jenkins útiles, y recuperación de los registros de Jenkins mientras se está ejecutando

LECCIÓN 2 – Un ENVOLTORIO DE IMAGEN BASE JENKINS

En la lección anterior hablé sobre la configuración de un entorno de desarrollo para ejecutar Docker y experimenté con la imagen de Docker Jenkins proporcionada por Cloudbees. Descubrimos que era simple y fácil de usar, con algunas excelentes características listas para usar. Para avanzar en las áreas de mejora que identificamos, los conceptos de Docker cubiertos en esta lección son:

  • Creación de su propio archivo acoplable

  • Configuración de variables de entorno en un archivo acoplable

  • Creación de carpetas y permisos en un archivo acoplable

  • Uso de docker exec para ejecutar comandos contra un contenedor en ejecución

CREACIÓN DE SU ARCHIVO DE DOCKER BASE

Queremos hacer algunos cambios en la forma en que Jenkins se inicia de forma predeterminada. En el último blog manejamos esto creando un makefile que pasaba argumentos como variables de entorno. Dado que queremos hacer esto cada vez, podemos moverlos a nuestro propio Dockerfile. Además, nuestro propio Dockerfile nos permitirá bloquear la versión de Jenkins que estemos usando en caso de que Cloudbees actualice la suya y no estemos listos para actualizar.

hacemos esto en cuatro pasos:

1. Crear un directorio de trabajo

2. En su editor de texto favorito, cree un nuevo archivo llamado «Dockerfile»

3. Agregue lo siguiente al archivo y guárdelo:

FROM jenkins/jenkins:2.112LABEL maintainer=""

4. Luego, en la línea de comandos, ingrese:

docker build -t myjenkins .

Lo que hicimos aquí fue sacar una versión particular de la imagen de Jenkins del repositorio público de Docker. Encontrará todas las versiones disponibles aquí:

  • Siempre puede configurar la cláusula FROM para que sea la versión de la imagen disponible. Sin embargo, no puedes simplemente establecer la versión a la versión de Jenkins que quieras. Esta es la versión de imagen «etiqueta» o «etiqueta», y Cloudbees es lo suficientemente agradable como para que coincida con la versión de Jenkins dentro de la imagen. Cloudbees ofrece » jenkins / jenkins «como una forma conveniente de obtener la última versión, o» jenkins/jenkins:lts «para obtener la versión más reciente de» Soporte a largo Plazo». En este ejemplo utilizo una versión específica. Estas etiquetas que etiquetan tipos de versiones son geniales, pero usarlas significa que la versión de Jenkins puede cambiar debajo de ti, lo que puede causar complicaciones si no estabas listo para actualizar. Recomiendo «bloqueo de versión» como una práctica recomendada general cuando se trata de dependencias en Docker u otras herramientas de administración de dependencias. Quieres que las cosas cambien cuando quieres, no antes. Es por eso que uso una versión específica aquí.

    PROBANDO EL NUEVO DOCKERFILE

    Podemos cambiar a la imagen muy fácilmente modificando nuestro comando docker run a lo siguiente:

    docker run -p 8080:8080 --name=jenkins-master -d --env JAVA_OPTS="-Xmx8192m" --env JENKINS_OPTS=" --handlerCountMax=300" myjenkins

    Ahora podemos limpiar esas variables de entorno colocándolas en nuestro propio Dockerfile.

    AGREGAR VARIABLES DE ENTORNO A NUESTRO ARCHIVO ACOPLABLE

    Es fácil agregar configuraciones predeterminadas para cosas como variables de entorno a archivos acoplables. Esto también proporciona una buena documentación personal. Y, debido a que siempre puede sobrescribirlos al ejecutar el contenedor Docker, realmente no hay inconvenientes.

    1. En su archivo acoplable, agregue las siguientes líneas después de la línea «MANTENEDOR» :

    ENV JAVA_OPTS="-Xmx8192m"ENV JENKINS_OPTS=" --handlerCountMax=300"

    2. Guarda y reconstruye tu imagen:

    • docker build-t myjenkins .

    docker build -t myjenkins .

    ¡Muy simple! Puede probar que aún funciona ingresando los tres comandos siguientes:

    docker stop jenkins-master
    docker rm jenkins-master
    docker run -p 8080:8080 --name=jenkins-master -d myjenkins

    ¡Tu imagen debería comenzar de inmediato! Pero, ¿cómo sabes que funcionaron las variables de entorno? Simple: de la misma manera que verías qué argumentos comenzaron tu aplicación Jenkins normalmente usando ps. Y esto funciona incluso si estás desarrollando en Windows.

    EJECUTAR UN COMANDO BÁSICO CONTRA SU CONTENEDOR

    Para confirmar que las opciones de Java y Jenkins están configuradas correctamente, podemos ejecutar ps en nuestro contenedor y ver el proceso Java de Jenkins en ejecución utilizando docker exec

    docker exec jenkins-master ps -ef | grep java

    Debería ver algo similar a esto

    jenkins 1 0 99 21:28 ? 00:00:35 java -Xmx8192m -jar /usr/share/jenkins/jenkins.war --handlerCountMax=300

    A partir de esto, puede ver fácilmente que nuestra configuración se ha atascado. docker exec es una forma sencilla de ejecutar comandos de shell dentro de su contenedor y también una forma increíblemente sencilla de inspeccionarlos. Esto incluso funciona en Windows porque, recuerde, el comando después de «exec» se ejecuta dentro de su contenedor y, por lo tanto, se basa en cualquier imagen base que use su contenedor.

    CONFIGURAR UNA CARPETA DE REGISTRO

    En el blog anterior notamos que perdimos visibilidad en los registros de Jenkins cuando ejecutamos nuestro contenedor con la bandera daemonize (- d). Queremos usar la función incorporada de Jenkins para establecer una carpeta de registro. Vamos a necesitar hacer esto en nuestro Dockerfile y luego pasar la opción de registro a Jenkins.

    Editemos de nuevo nuestro Dockerfile. Entre el» MANTENEDOR » y la primera línea ENV vamos a agregar lo siguiente

    RUN mkdir /var/log/jenkins

    Colocamos el comando en esta ubicación en el archivo para seguir las mejores prácticas. Es más probable que cambiemos las variables de entorno que estos directorios de configuración, y cada línea de comandos en un archivo acoplable se convierte esencialmente en su propia capa de imagen. Maximiza la reutilización de capas colocando elementos que cambian con frecuencia cerca de la parte inferior.

    Ahora vuelve a crear tu imagen:

    docker build -t myjenkins

    obtendrá un error que parece

    ---> Running in 0b5ac2bce13bmkdir: cannot create directory '/var/log/jenkins': Permission denied

    No se preocupe. Esto se debe a que el contenedor predeterminado de Cloudbees establece al usuario en ejecución como el usuario «Jenkins». Si observa su archivo acoplable (que se encuentra aquí: https://github.com/ Jenkinsci/docker/blob/master/Dockerfile) debería ver, cerca de la parte inferior

    USER ${user}

    Esta sintaxis puede ser un poco confusa. Utiliza los «argumentos» de compilación de Docker para permitirle definir al usuario. Si busca más arriba en el archivo Acoplable, encontrará el valor predeterminado. Busque en la parte superior del archivo acoplable

    ARG user=jenkins

    Esto crea el argumento» user » (ARG) y lo establece en el usuario Jenkins. Esto le permite cambiar el nombre de usuario que Jenkins usa cuando llama a docker build build build-arg somevariable=somevalue. Tenga en cuenta que esto solo funciona si está creando el archivo acoplable desde cero. No puede cambiar estos valores con una extracción de docker o una ejecución de docker. Puedes leer más sobre los argumentos de construcción aquí. Debido a que estamos usando una versión precompilada en nuestra cláusula FROM, terminamos con el usuario predeterminado: «jenkins».

    En Linux normal, solo usarías SUDO o algún otro medio para crear la carpeta (/var / log es propiedad de root). Afortunadamente para nosotros, Docker nos permite cambiar de usuario.

    Agregue lo siguiente a su archivo acoplable:

    1. Antes de ejecutar la línea mkdir, añadir

    USER root

    2. Después de ejecutar la línea mkdir, agregue

    RUN chown -R jenkins:jenkins /var/log/jenkins

    3. Después de su línea de chown de CARRERA, agregue:

    USER jenkins

    Tenga en cuenta que también tuvimos que agregar un comando chown porque queremos que el usuario de Jenkins pueda escribir en la carpeta. A continuación, establecemos root y, a continuación, restablecemos Jenkins para que se conserve el comportamiento del archivo acoplable.

    Ahora construir su imagen de nuevo:

    docker build -t myjenkins .

    Y… tus errores deberían desaparecer.

    Con el conjunto de directorios de registro (tenga en cuenta que puede colocar esta carpeta donde quiera, usamos /var/log para mayor coherencia), ahora podemos decirle a Jenkins que escriba en esa carpeta al iniciar modificando las variables de entorno JENKINS_OPTS.

    En su Dockerfile editar el JENKINS_OPTS línea para parecerse a esto:

    • ENV JENKINS_OPTS=»–handlerCountMax=300 –logfile=/var/log/jenkins/jenkins.registro»

    ENV JENKINS_OPTS="--handlerCountMax=300 --logfile=/var/log/jenkins/jenkins.log"

    Ahora construya su imagen una vez más

    docker build -t myjenkins .

    ¡Probemos nuestra nueva imagen y si podemos seguir el archivo de registro! Pruebe los siguientes comandos

    docker stop jenkins-master
    docker rm jenkins-master
    docker run -p 8080:8080 --name=jenkins-master -d myjenkins

    Con el contenedor en ejecución, podemos rastrear el archivo de registro si todo funcionó

    docker exec jenkins-master tail -f /var/log/jenkins/jenkins.log

    RECUPERAR REGISTROS SI JENKINS SE BLOQUEA

    ¡Tiempo para una ronda de bonificación! Mientras estemos discutiendo los registros, Docker presenta un problema interesante si Jenkins se bloquea. El contenedor dejará de ejecutarse y docker exec ya no funcionará. Entonces, ¿qué hacer?

    Discutiremos formas más avanzadas de conservar el archivo de registro más adelante. Por ahora, debido a que el contenedor está detenido, podemos copiar archivos de él utilizando el comando docker cp. Simulemos un bloqueo deteniendo el contenedor y recuperando los registros:

    1. ctrl-c para salir del archivo de registro tail

    2. Ejecute los siguientes comandos

    docker stop jenkins-master
    docker cp jenkins-master:/var/log/jenkins/jenkins.log jenkins.log
    cat jenkins.log

    PENSAMIENTOS FINALES

    Puedes encontrar todo el trabajo en mi tutorial Git repo (y el makefile de conveniencia actualizado) aquí:

    • https://github.com/maxfields2000/docker Jenkins_tutorial / árbol / maestro / tutorial_02

    Al crear nuestro propio Dockerfile que envuelve el archivo Cloudbees, pudimos hacernos la vida un poco más fácil. Configuramos un lugar conveniente para almacenar los registros y aprendimos a verlos con el comando docker exec. Movimos nuestra configuración predeterminada al Dockerfile y ahora podemos guardarla en el control de código fuente como una buena documentación propia.

    Todavía tenemos un desafío de persistencia de datos. Hemos aprendido a extraer archivos de registro de un contenedor detenido (muy útil cuando Jenkins se bloquea). Pero en general, si nuestro contenedor se detiene, todavía perderemos todos los empleos que creamos. Por lo tanto, sin persistencia, esta imagen de Jenkins solo es útil para el desarrollo y las pruebas locales.

    Eso nos lleva al siguiente artículo. Con nuestras bases en su lugar, nuestro propio contenedor de archivos acoplables, bloqueado en una versión práctica de Jenkins, podemos resolver el problema de persistencia. El próximo artículo explorará estos conceptos:

    • Preservar los datos de trabajos y complementos de Jenkins

    • Persistencia de Datos de Docker con Volúmenes

    • Creación de un contenedor de volumen de datos

    • Compartir datos en volúmenes con otros contenedores

    Para obtener más información, consulte el resto de esta serie:

    Parte I: Pensar dentro del contenedor
    Parte II: Colocar a Jenkins en un contenedor Acoplable (este artículo)
    Parte III: Acoplable & Jenkins: Datos que persisten
    Parte IV: Jenkins, Acoplable, Proxies y Composición
    Parte V: Tomar el Control de Su Imagen de Docker
    Parte VI: Construcción con Jenkins Dentro de un Contenedor de Docker Efímero
    Parte VII: Tutorial: Construcción con Jenkins Dentro de un Contenedor de Docker Efímero
    Parte VIII: Charla de DockerCon y la Historia Hasta ahora

Deja una respuesta

Tu dirección de correo electrónico no será publicada.