docker - tutorial - Cómo actualizar automáticamente sus contenedores acoplables, si las imágenes base se actualizan
tutorial docker file (16)
Aquí hay una forma más sencilla de actualizar el contenedor de Docker automáticamente
Pon el trabajo a través de
$ crontab -e
:
0 * * * * sh ~/.docker/cron.sh
Crear directorio
~/.docker
con archivo
cron.sh
:
#!/bin/sh
if grep -Fqe "Image is up to date" << EOF
`docker pull ubuntu:latest`
EOF
then
echo "no update, just do cleaning"
docker system prune --force
else
echo "newest exist, recompose!"
cd /path/to/your/compose/file
docker-compose down --volumes
docker-compose up -d
fi
Digamos que tengo un contenedor trivial basado en
ubuntu:latest
.
Ahora hay una actualización de seguridad y
ubuntu:latest
se actualiza en el repositorio de Docker.
-
¿Cómo sabría si mi imagen local y sus contenedores se están quedando atrás?
-
¿Existe alguna práctica recomendada para actualizar automáticamente las imágenes y contenedores locales para seguir las actualizaciones de repositorios de Docker, que en la práctica le darían las mismas ventajas de tener actualizaciones desatendidas ejecutándose en una máquina ubuntu convencional?
¿Has probado esto? https://github.com/v2tec/watchtower . es una herramienta simple que se ejecuta en el contenedor acoplable y mira otros contenedores, si su imagen base cambia, se extraerá y volverá a desplegar.
Una solución simple y excelente es shepherd
ACTUALIZACIÓN: Use Dependabot - https://dependabot.com/docker/
BLUF: encontrar el punto de inserción correcto para monitorear los cambios en un contenedor es el desafío. Sería genial si DockerHub resolviera esto. (Se han mencionado los enlaces del repositorio, pero tenga en cuenta al configurarlos en DockerHub: " Dispare una compilación en este repositorio siempre que la imagen base se actualice en Docker Hub. Solo funciona para imágenes no oficiales" ).
Mientras intentaba resolver esto por mí mismo, vi varias recomendaciones para webhooks, así que quise elaborar un par de soluciones que he usado.
-
Use microbadger.com para rastrear cambios en un contenedor y use su función de notificación de webhook para activar una acción. Configuré esto con zapier.com (pero puedes usar cualquier servicio de webhook personalizable) para crear un nuevo problema en mi repositorio de github que usa Alpine como imagen base.
- Pros: puede revisar los cambios informados por microbadger en github antes de tomar medidas.
- Contras: Microbadger no te permite rastrear una etiqueta específica. Parece que solo rastrea ''lo último''.
-
Rastree la fuente RSS para git commits a un contenedor ascendente. ex. https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64 . Utilicé zapier.com para monitorear este feed y activar una compilación automática de mi contenedor en Travis-CI cada vez que algo se confirma. Esto es un poco extremo, pero puede cambiar el gatillo para hacer otras cosas como abrir un problema en su repositorio de git para la intervención manual.
- Pros: más cerca de una tubería automatizada. La compilación de Travis-CI solo verifica si su contenedor tiene problemas con lo que se haya comprometido con el repositorio de imágenes base. Depende de usted si su servicio de CI toma alguna medida adicional.
- Contras: el seguimiento del feed de confirmación no es perfecto. Muchas cosas se comprometen con el repositorio que no afectan la construcción de la imagen base. No tiene en cuenta ningún problema con la frecuencia / número de confirmaciones y cualquier limitación de API.
Aquí hay muchas respuestas, pero ninguna de ellas satisfizo mis necesidades. Quería una respuesta real a la pregunta número 1 del autor de la pregunta. ¿Cómo sé cuándo se actualiza una imagen en hub.docker.com?
El siguiente script se puede ejecutar a diario. En la primera ejecución, obtiene una línea base de las etiquetas y las fechas de actualización del registro HUB y las guarda localmente. A partir de ese momento, cada vez que se ejecuta, verifica el registro en busca de nuevas etiquetas y fechas de actualización. Como esto cambia cada vez que existe una nueva imagen, nos dice si la imagen base ha cambiado. Aquí está el guión:
#!/bin/bash
DATAPATH=''/data/docker/updater/data''
if [ ! -d "${DATAPATH}" ]; then
mkdir "${DATAPATH}";
fi
IMAGES=$(docker ps --format "{{.Image}}")
for IMAGE in $IMAGES; do
ORIGIMAGE=${IMAGE}
if [[ "$IMAGE" != *//* ]]; then
IMAGE=library/${IMAGE}
fi
IMAGE=${IMAGE%%:*}
echo "Checking ${IMAGE}"
PARSED=${IMAGE/////.}
if [ ! -f "${DATAPATH}/${PARSED}" ]; then
# File doesn''t exist yet, make baseline
echo "Setting baseline for ${IMAGE}"
curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/" > "${DATAPATH}/${PARSED}"
else
# File does exist, do a compare
NEW=$(curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/")
OLD=$(cat "${DATAPATH}/${PARSED}")
if [[ "${VAR1}" == "${VAR2}" ]]; then
echo "Image ${IMAGE} is up to date";
else
echo ${NEW} > "${DATAPATH}/${PARSED}"
echo "Image ${IMAGE} needs to be updated";
H=`hostname`
ssh -i /data/keys/<KEYFILE> <USER>@<REMOTEHOST>.com "{ echo /"MAIL FROM: root@${H}/"; echo /"RCPT TO: <USER>@<EMAILHOST>.com/"; echo /"DATA/"; echo /"Subject: ${H} - ${IMAGE} needs update/"; echo /"/"; echo -e /"/n${IMAGE} needs update./n/ndocker pull ${ORIGIMAGE}/"; echo /"/"; echo /"./"; echo /"quit/"; sleep 1; } | telnet <SMTPHOST> 25"
fi
fi
done;
Deberá modificar la variable
DATAPATH
en la parte superior y modificar el comando de notificación por correo electrónico al final para satisfacer sus necesidades.
Para mí, lo tengo SSH en un servidor en otra red donde se encuentra mi SMTP.
Pero también podría usar fácilmente el comando de
mail
.
Ahora, también desea verificar si hay paquetes actualizados dentro de los contenedores. En realidad, esto es probablemente más efectivo que hacer una "extracción" una vez que sus contenedores están funcionando. Aquí está el guión para lograrlo:
#!/bin/bash
function needsUpdates() {
RESULT=$(docker exec ${1} bash -c '' /
if [[ -f /etc/apt/sources.list ]]; then /
grep security /etc/apt/sources.list > /tmp/security.list; /
apt-get update > /dev/null; /
apt-get upgrade -oDir::Etc::Sourcelist=/tmp/security.list -s; /
fi; /
'')
RESULT=$(echo $RESULT)
GOODRESULT="Reading package lists... Building dependency tree... Reading state information... Calculating upgrade... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."
if [[ "${RESULT}" != "" ]] && [[ "${RESULT}" != "${GOODRESULT}" ]]; then
return 0
else
return 1
fi
}
function sendEmail() {
echo "Container ${1} needs security updates";
H=`hostname`
ssh -i /data/keys/<KEYFILE> <USRER>@<REMOTEHOST>.com "{ echo /"MAIL FROM: root@${H}/"; echo /"RCPT TO: <USER>@<EMAILHOST>.com/"; echo /"DATA/"; echo /"Subject: ${H} - ${1} container needs security update/"; echo /"/"; echo -e /"/n${1} container needs update./n/n/"; echo -e /"docker exec ${1} bash -c ''grep security /etc/apt/sources.list > /tmp/security.list; apt-get update > /dev/null; apt-get upgrade -oDir::Etc::Sourcelist=/tmp/security.list -s''/n/n/"; echo /"Remove the -s to run the update/"; echo /"/"; echo /"./"; echo /"quit/"; sleep 1; } | telnet <SMTPHOST> 25"
}
CONTAINERS=$(docker ps --format "{{.Names}}")
for CONTAINER in $CONTAINERS; do
echo "Checking ${CONTAINER}"
if needsUpdates $CONTAINER; then
sendEmail $CONTAINER
fi
done
La gestión de dependencias para las imágenes de Docker es un problema real. Soy parte de un equipo que creó una herramienta, MicroBadger , para ayudar con esto al monitorear las imágenes del contenedor e inspeccionar los metadatos. Una de sus características es permitirle configurar un webhook de notificación que se llama cuando cambia una imagen que le interesa (por ejemplo, una imagen base).
Las respuestas anteriores también son correctas
Hay dos enfoques
- Usa webhooks
- Ejecute el script por cada minuto específico para obtener nuevas imágenes de la ventana acoplable
Solo estoy compartiendo el script, ¡puede ser útil para usted! Puedes usarlo con cronjob, lo intenté con éxito en OSX
#!/bin/bash
##You can use below commented line for setting cron tab for running cron job and to store its O/P in one .txt file
#* * * * * /usr/bin/sudo -u admin -i bash -c /Users/Swapnil/Documents/checkimg.sh > /Users/Swapnil/Documents/cron_output.log 2>&1
# Example for the Docker Hub V2 API
# Returns all images and tags associated with a Docker Hub organization account.
# Requires ''jq'': https://stedolan.github.io/jq/
# set username, password, and organization
# Filepath where your docker-compose file is present
FILEPATH="/Users/Swapnil/Documents/lamp-alpine"
# Your Docker hub user name
UNAME="ur username"
# Your Docker hub user password
UPASS="ur pwd"
# e.g organisation_name/image_name:image_tag
ORG="ur org name"
IMGNAME="ur img name"
IMGTAG="ur img tag"
# Container name
CONTNAME="ur container name"
# Expected built mins
BUILDMINS="5"
#Generally cronjob frequency
CHECKTIME="5"
NETWORKNAME="${IMGNAME}_private-network"
#After Image pulling, need to bring up all docker services?
DO_DOCKER_COMPOSE_UP=true
# -------
echo "Eecuting Script @ date and time in YmdHMS: $(date +%Y%m%d%H%M%S)"
set -e
PIDFILE=/Users/Swapnil/Documents/$IMGNAME/forever.pid
if [ -f $PIDFILE ]
then
PID=$(cat $PIDFILE)
ps -p $PID > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "Process already running"
exit 1
else
## Process not found assume not running
echo $$
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
else
echo $$ > $PIDFILE
if [ $? -ne 0 ]
then
echo "Could not create PID file"
exit 1
fi
fi
# Check Docker is running or not; If not runing then exit
if docker info|grep Containers ; then
echo "Docker is running"
else
echo "Docker is not running"
rm $PIDFILE
exit 1
fi
# Check Container is running or not; and set variable
CONT_INFO=$(docker ps -f "name=$CONTNAME" --format "{{.Names}}")
if [ "$CONT_INFO" = "$CONTNAME" ]; then
echo "Container is running"
IS_CONTAINER_RUNNING=true
else
echo "Container is not running"
IS_CONTAINER_RUNNING=false
fi
# get token
echo "Retrieving token ..."
TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d ''{"username": "''${UNAME}''", "password": "''${UPASS}''"}'' https://hub.docker.com/v2/users/login/ | jq -r .token)
# get list of repositories
echo "Retrieving repository list ..."
REPO_LIST=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/?page_size=100 | jq -r ''.results|.[]|.name'')
# output images & tags
echo "Images and tags for organization: ${ORG}"
echo
for i in ${REPO_LIST}
do
echo "${i}:"
# tags
IMAGE_TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${i}/tags/?page_size=100 | jq -r ''.results|.[]|.name'')
for j in ${IMAGE_TAGS}
do
echo " - ${j}"
done
#echo
done
# Check Perticular image is the latest or not
#imm=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${IMGNAME}/tags/?page_size=100)
echo "-----------------"
echo "Last built date details about Image ${IMGNAME} : ${IMGTAG} for organization: ${ORG}"
IMAGE_UPDATED_DATE=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${ORG}/${IMGNAME}/tags/?page_size=100 | jq -r ''.results|.[]|select(.name | contains("''${IMGTAG}''")).last_updated'')
echo "On Docker Hub IMAGE_UPDATED_DATE---$IMAGE_UPDATED_DATE"
echo "-----------------"
IMAGE_CREATED_DATE=$(docker image inspect ${ORG}/${IMGNAME}:${IMGTAG} | jq -r ''.[]|.Created'')
echo "Locally IMAGE_CREATED_DATE---$IMAGE_CREATED_DATE"
updatedDate=$(date -jf ''%Y-%m-%dT%H:%M'' "${IMAGE_UPDATED_DATE:0:16}" +%Y%m%d%H%M%S)
createdDate=$(date -jf ''%Y-%m-%dT%H:%M'' "${IMAGE_CREATED_DATE:0:16}" +%Y%m%d%H%M%S)
currentDate=$(date +%Y%m%d%H%M%S)
start_date=$(date -jf "%Y%m%d%H%M%S" "$currentDate" "+%s")
end_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
updiffMins=$(( ($start_date - $end_date) / (60) ))
if [[ "$updiffMins" -lt $(($CHECKTIME+1)) ]]; then
if [ ! -d "${FILEPATH}" ]; then
mkdir "${FILEPATH}";
fi
cd "${FILEPATH}"
pwd
echo "updatedDate---$updatedDate" > "ScriptOutput_${currentDate}.txt"
echo "createdDate---$createdDate" >> "ScriptOutput_${currentDate}.txt"
echo "currentDate---$currentDate" >> "ScriptOutput_${currentDate}.txt"
echo "Found after regular checking time -> Docker hub''s latest updated image is new; Diff ${updiffMins} mins" >> "ScriptOutput_${currentDate}.txt"
echo "Script is checking for latest updates after every ${CHECKTIME} mins" >> "ScriptOutput_${currentDate}.txt"
echo "Fetching all new"
echo "---------------------------"
if $IS_CONTAINER_RUNNING ; then
echo "Container is running"
else
docker-compose down
echo "Container stopped and removed; Network removed" >> "ScriptOutput_${currentDate}.txt"
fi
echo "Image_Created_Date=$currentDate" > ".env"
echo "ORG=$ORG" >> ".env"
echo "IMGNAME=$IMGNAME" >> ".env"
echo "IMGTAG=$IMGTAG" >> ".env"
echo "CONTNAME=$CONTNAME" >> ".env"
echo "NETWORKNAME=$NETWORKNAME" >> ".env"
docker-compose build --no-cache
echo "Docker Compose built" >> "ScriptOutput_${currentDate}.txt"
if $DO_DOCKER_COMPOSE_UP ; then
docker-compose up -d
echo "Docker services are up now, checked in" >> "ScriptOutput_${currentDate}.txt"
else
echo "Docker services are down, checked in" >> "ScriptOutput_${currentDate}.txt"
fi
elif [[ "$updatedDate" -gt "$createdDate" ]]; then
echo "Updated is latest"
start_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
end_date=$(date -jf "%Y%m%d%H%M%S" "$createdDate" "+%s")
diffMins=$(( ($start_date - $end_date) / (60) ))
if [[ "$BUILDMINS" -lt "$diffMins" ]]; then
if [ ! -d "${FILEPATH}" ]; then
mkdir "${FILEPATH}";
fi
cd "${FILEPATH}"
pwd
echo "updatedDate---$updatedDate" > "ScriptOutput_${currentDate}.txt"
echo "createdDate---$createdDate" >> "ScriptOutput_${currentDate}.txt"
echo "currentDate---$currentDate" >> "ScriptOutput_${currentDate}.txt"
echo "Found after comparing times -> Docker hub''s latest updated image is new; Diff ${diffMins} mins" >> "ScriptOutput_${currentDate}.txt"
echo "Actual image built time is less i.e. ${diffMins} mins than MAX expexted BUILD TIME i.e. ${BUILDMINS} mins" >> "ScriptOutput_${currentDate}.txt"
echo "Fetching all new" >> "ScriptOutput_${currentDate}.txt"
echo "-----------------------------"
if $IS_CONTAINER_RUNNING ; then
echo "Container is running"
else
docker-compose down
echo "Container stopped and removed; Network removed" >> "ScriptOutput_${currentDate}.txt"
fi
echo "Image_Created_Date=$currentDate" > ".env"
echo "ORG=$ORG" >> ".env"
echo "IMGNAME=$IMGNAME" >> ".env"
echo "IMGTAG=$IMGTAG" >> ".env"
echo "CONTNAME=$CONTNAME" >> ".env"
echo "NETWORKNAME=$NETWORKNAME" >> ".env"
docker-compose build --no-cache
echo "Docker Compose built" >> "ScriptOutput_${currentDate}.txt"
if $DO_DOCKER_COMPOSE_UP ; then
docker-compose up -d
echo "Docker services are up now" >> "ScriptOutput_${currentDate}.txt"
else
echo "Docker services are down" >> "ScriptOutput_${currentDate}.txt"
fi
elif [[ "$BUILDMINS" -gt "$diffMins" ]]; then
echo "Docker hub''s latest updated image is NOT new; Diff ${diffMins} mins"
echo "Docker images not fetched"
else
echo "Docker hub''s latest updated image is NOT new; Diff ${diffMins} mins"
echo "Docker images not fetched"
fi
elif [[ "$createdDate" -gt "$updatedDate" ]]; then
echo "Created is latest"
start_date=$(date -jf "%Y%m%d%H%M%S" "$createdDate" "+%s")
end_date=$(date -jf "%Y%m%d%H%M%S" "$updatedDate" "+%s")
echo "Docker hub has older docker image than local; Older than $(( ($start_date - $end_date) / (60) ))mins"
fi
echo
echo "------------end---------------"
rm $PIDFILE
Aquí está mi archivo docker-compose
version: "3.2"
services:
lamp-alpine:
build:
context: .
container_name: "${CONTNAME}"
image: "${ORG}/${IMGNAME}:${IMGTAG}"
ports:
- "127.0.0.1:80:80"
networks:
- private-network
networks:
private-network:
driver: bridge
No sabría que su contenedor está detrás sin ejecutar el docker pull . Entonces necesitarías rebuild o recompose tu imagen.
docker pull image:tag
docker-compose -f docker-compose.yml -f production.yml up -d --build
Los comandos se pueden colocar en un script junto con cualquier otra cosa necesaria para completar la actualización, aunque un contenedor adecuado no necesitaría nada adicional.
No voy a entrar en la cuestión de si quieres o no actualizaciones desatendidas en producción (creo que no). Solo dejo esto aquí como referencia en caso de que alguien lo encuentre útil. Actualice todas sus imágenes de Docker a la última versión con el siguiente comando en su terminal:
# docker images | awk ''(NR>1) && ($2!~/none/) {print $1":"$2}'' | xargs -L1 docker pull
Otro enfoque podría ser asumir que su imagen base se queda atrás bastante rápido (y es muy probable que suceda), y forzar periódicamente la creación de otra imagen de su aplicación (por ejemplo, cada semana) y luego volver a implementarla si ha cambiado.
Por lo que puedo decir, las imágenes de base populares como Debian o Java oficiales actualizan sus etiquetas para satisfacer las correcciones de seguridad, por lo que las etiquetas no son inmutables (si desea una garantía más sólida de eso, debe usar la referencia [imagen: @digest ], disponible en versiones más recientes de Docker).
Por lo tanto, si tuviera que construir su imagen con
docker build --pull
, entonces su aplicación debería obtener la última y mejor etiqueta de imagen base a la que hace referencia.
Dado que las etiquetas mutables pueden ser confusas, es mejor aumentar el número de versión de su aplicación cada vez que lo hace para que al menos las cosas estén más limpias.
Por lo tanto, no estoy seguro de que el script sugerido en una de las respuestas anteriores haga el trabajo, ya que no reconstruye la imagen de su aplicación: solo actualiza la etiqueta de imagen base y luego reinicia el contenedor, pero el nuevo contenedor aún hace referencia el viejo hash de imagen base.
No recomendaría ejecutar trabajos de tipo cron en contenedores (o cualquier otro proceso, a menos que sea realmente necesario), ya que esto va en contra del mantra de ejecutar solo un proceso por contenedor (hay varios argumentos sobre por qué esto es mejor, así que yo '' No voy a entrar aquí).
Puede usar Watchtower para ver las actualizaciones de la imagen de la que se crea una instancia de un contenedor y extraer automáticamente la actualización y reiniciar el contenedor utilizando la imagen actualizada. Sin embargo, eso no resuelve el problema de reconstruir sus propias imágenes personalizadas cuando hay un cambio en la imagen ascendente en la que se basa. Podría ver esto como un problema de dos partes: (1) saber cuándo se ha actualizado una imagen ascendente y (2) hacer la reconstrucción de la imagen real. (1) se puede resolver con bastante facilidad, pero (2) depende mucho de su entorno / prácticas de compilación locales, por lo que probablemente sea mucho más difícil crear una solución generalizada para eso.
Si puede utilizar las
compilaciones automatizadas de
Docker Hub, todo el problema se puede resolver de manera relativamente limpia utilizando la función de
enlaces
del
repositorio
, que le permite activar una reconstrucción automáticamente cuando se actualiza un repositorio vinculado (probablemente uno anterior).
También puede configurar un
Webhooks
para que le notifique cuando se produce una compilación automática.
Si desea una notificación por correo electrónico o SMS, puede conectar el webhook a
IFTTT Maker
.
Descubrí que la interfaz de usuario de IFTTT es un poco confusa, pero configuraría el webhook de Docker para publicar en
https://maker.ifttt.com/trigger/
docker_xyz_image_built
/ with / key /
your_key
.
Si necesita construir localmente, al menos puede resolver el problema de recibir notificaciones cuando se actualiza una imagen ascendente creando un repositorio ficticio en Docker Hub vinculado a su (s) repositorio (s) de interés. El único propósito del repositorio ficticio sería activar un webhook cuando se reconstruya (lo que implica que se actualizó uno de sus repositorios vinculados). Si puede recibir este webhook, incluso podría usarlo para activar una reconstrucción de su lado.
Tuve el mismo problema y pensé que puede resolverse simplemente con un trabajo cron que llama
unattended-upgrade
días.
Mi intención es tener esto como una solución automática y rápida para garantizar que el contenedor de producción sea seguro y actualizado porque me puede llevar algún tiempo actualizar mis imágenes e implementar una nueva imagen acoplable con las últimas actualizaciones de seguridad.
También es posible automatizar la creación e implementación de imágenes con ganchos Github
He creado una
imagen
básica de
docker
con la que comprueba e instala automáticamente actualizaciones de seguridad a diario (puede ejecutarse directamente con
docker run itech/docker-unattended-upgrade
).
También me encontré con otro approach diferente para verificar si el contenedor necesita una actualización.
Mi implementación completa:
Dockerfile
FROM ubuntu:14.04
RUN apt-get update /
&& apt-get install -y supervisor unattended-upgrades /
&& rm -rf /var/lib/apt/lists/*
COPY install /install
RUN chmod 755 install
RUN /install
COPY start /start
RUN chmod 755 /start
Guiones de ayuda
Instalar en pc
#!/bin/bash
set -e
cat > /etc/supervisor/conf.d/cron.conf <<EOF
[program:cron]
priority=20
directory=/tmp
command=/usr/sbin/cron -f
user=root
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
EOF
rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/start"]
comienzo
#!/bin/bash
set -e
echo "Adding crontab for unattended-upgrade ..."
echo "0 0 * * * root /usr/bin/unattended-upgrade" >> /etc/crontab
# can also use @daily syntax or use /etc/cron.daily
echo "Starting supervisord ..."
exec /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
Editar
Desarrollé una pequeña herramienta docker-run que se ejecuta como contenedor de docker y se puede usar para actualizar paquetes dentro de todos o contenedores de ejecución seleccionados, también se puede usar para ejecutar comandos arbitrarios.
Se puede probar fácilmente con el siguiente comando:
docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec
que de forma predeterminada ejecutará el comando de
date
en todos los contenedores en ejecución y mostrará los resultados.
Si pasa la
update
lugar de
exec
, ejecutará
apt-get update
seguido de
apt-get upgrade -y
en todos los contenedores en ejecución
Una ''forma de docker'' sería usar las compilaciones automatizadas de docker hub . La función Enlaces de repositorio reconstruirá su contenedor cuando se reconstruya un contenedor ascendente, y la función Webhooks le enviará una notificación.
Parece que los webhooks están limitados a llamadas HTTP POST. Tendría que configurar un servicio para atraparlos, o tal vez usar uno de los servicios POST para enviar por correo electrónico.
No lo he investigado, pero el nuevo Docker Universal Control Plane podría tener una función para detectar contenedores actualizados y volver a implementarlos.
Una de las formas de hacerlo es conducir esto a través de sus sistemas CI / CD. Una vez que se construye su imagen principal, tenga algo que escanee sus repositorios de git en busca de imágenes usando ese padre. Si se encuentra, enviaría una solicitud de extracción para pasar a nuevas versiones de la imagen. La solicitud de extracción, si se pasan todas las pruebas, se fusionaría y tendría una nueva imagen secundaria basada en el elemento primario actualizado. Puede encontrar un ejemplo de una herramienta que adopta este enfoque aquí: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 .
Si no controla su imagen principal, como sería el caso si depende de la imagen oficial de
ubuntu
, puede escribir algunas herramientas que detecten cambios en la etiqueta de la imagen principal e invocar las construcciones de imágenes secundarias en consecuencia.
Usamos un script que verifica si un contenedor en ejecución se inicia con la última imagen. También utilizamos secuencias de comandos de inicio para iniciar la imagen del acoplador.
#!/usr/bin/env bash
set -e
BASE_IMAGE="registry"
REGISTRY="registry.hub.docker.com"
IMAGE="$REGISTRY/$BASE_IMAGE"
CID=$(docker ps | grep $IMAGE | awk ''{print $1}'')
docker pull $IMAGE
for im in $CID
do
LATEST=`docker inspect --format "{{.Id}}" $IMAGE`
RUNNING=`docker inspect --format "{{.Image}}" $im`
NAME=`docker inspect --format ''{{.Name}}'' $im | sed "s/////g"`
echo "Latest:" $LATEST
echo "Running:" $RUNNING
if [ "$RUNNING" != "$LATEST" ];then
echo "upgrading $NAME"
stop docker-$NAME
docker rm -f $NAME
start docker-$NAME
else
echo "$NAME up to date"
fi
done
Y init parece
docker run -t -i --name $NAME $im /bin/bash
Premisa a mi respuesta:
- Los contenedores se ejecutan con etiquetas.
- La misma etiqueta puede apuntar a un UUID de imagen diferente, según nos parezca apropiado.
- Las actualizaciones realizadas en una imagen pueden confirmarse en una nueva capa de imagen
Acercarse a, aproximarse
- Cree todos los contenedores en primer lugar con un script de actualización de parche de seguridad
-
Cree un proceso automatizado para lo siguiente
- Ejecute una imagen existente en un nuevo contenedor con un script de parche de seguridad como comando
-
Confirmar cambios en la imagen como
- etiqueta existente -> seguido de reiniciar los contenedores uno por uno
- nueva etiqueta de versión -> reemplazar algunos contenedores con nueva etiqueta -> validar -> mover todos los contenedores a una nueva etiqueta
Además, la imagen base se puede actualizar / el contenedor con una imagen base completamente nueva se puede construir a intervalos regulares, según el mantenedor lo considere necesario
Ventajas
- Estamos preservando la versión anterior de la imagen mientras creamos la nueva imagen parcheada de seguridad, por lo tanto, podemos volver a la imagen anterior si es necesario
- Estamos preservando la memoria caché de la ventana acoplable, por lo tanto, menos transferencia de red (solo la capa cambiada se conecta al cable)
- El proceso de actualización se puede validar en etapas antes de pasar a producción
- Este puede ser un proceso controlado, por lo tanto, los parches de seguridad solo cuando son necesarios / se consideran importantes pueden ser empujados.