Come aggiornare automaticamente i contenitori della finestra mobile, se le immagini di base vengono aggiornate


206

Dire che ho un contenitore banale basato sul ubuntu:latest. Ora c'è un aggiornamento di sicurezza e ubuntu:latestviene aggiornato nel repository docker.

  1. Come faccio a sapere la mia immagine locale e i suoi contenitori sono in esecuzione dietro?

  2. Esistono alcune best practice per l'aggiornamento automatico di immagini e container locali per seguire gli aggiornamenti del repository docker, che in pratica ti darebbero le stesse qualità di avere aggiornamenti non presidiati in esecuzione su una macchina Ubuntu convenzionale


11
Sto cercando una risposta a questo dall'inizio della finestra mobile. È anche un po 'più complicato. Se installo apache (ad esempio) e questo viene aggiornato, l'immagine di base non cambia, poiché l'ho installata in seguito. Vorrei comunque avere aggiornamenti automatici per apache. In realtà ho chiesto all'IRC di questo e ho ottenuto "follow upstream e ricostruzione sugli aggiornamenti" come risposta ...
Mathias,

8
Sono contento di non essere l'unico a chiedermi. Sembra che lo sviluppo e la riproducibilità siano più importanti per gli sviluppatori docker rispetto ai meccanismi di aggiornamento sensibili che abbiamo ormai da anni.
hbogert,

Il problema è che la finestra mobile è solo la tecnologia per i contenitori. Penso che occorra del tempo perché un ecosistema si evolva attorno a questo. Ci sono altri problemi che la finestra mobile non affronta come la registrazione.
Mathias,

3
Grazie a tutti coloro che hanno risposto. Mi dispiace di non aver potuto dividere la taglia. Anche se non c'era una soluzione definitiva al mio problema, ci sono stati dei buoni suggerimenti da parte di tutti voi.
Mathias,

1
Per @Mathias, la soluzione che ho appena aggiunto ha uno script che verificherà la presenza di aggiornamenti di sicurezza per i pacchetti installati nel contenitore post-pull. Ha anche uno script separato per controllare l'immagine di base.
Fmstrat,

Risposte:


9

Uno dei modi per farlo è guidare questo attraverso i tuoi sistemi CI / CD. Una volta creata l'immagine principale, è necessario acquisire qualcosa che scansiona i repository git alla ricerca di immagini utilizzando quel padre. Se lo trovi, invierai quindi una richiesta pull per passare alle nuove versioni dell'immagine. La richiesta pull, se tutti i test superano, verrebbero uniti e si otterrebbe una nuova immagine figlio basata sul genitore aggiornato. Un esempio di uno strumento che utilizza questo approccio è disponibile qui: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 .

Se non controlli l'immagine principale, come nel caso dipenda ubuntudall'immagine ufficiale , puoi scrivere alcuni strumenti che rilevano le modifiche nel tag o nel checksum dell'immagine principale (non la stessa cosa, i tag sono mutabili) e invocare l'immagine dei bambini di conseguenza.


Wow, questo è un grande martello, che ha detto: dal momento in cui ho posto questa domanda, ho anche capito che il server di build è il posto giusto per affrontare questo problema. Sono contento di vedere alcuni strumenti. Se spieghi il tuo approccio in concetti generici (e non il tuo strumento / implementazione esatta) e lo includi nella risposta, probabilmente lo accetterò.
hbogert,

Grazie a @hbogert ho modificato quanto sopra e includo anche un'idea su cosa fare se hai a che fare con immagini pubbliche
Ma3oxuct

124

Utilizziamo uno script che verifica se un container in esecuzione viene avviato con l'immagine più recente. Utilizziamo anche script init upstart per l'avvio dell'immagine docker.

#!/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

E init sembra

docker run -t -i --name $NAME $im /bin/bash

1
Grazie mille per questo prezioso contributo. Questo sembra un buon modo per aggiornare l'immagine di base. La domanda rimanente è: come si aggiorna un'applicazione (come apache) che è stata installata dalla distribuzione nel file docker? Oppure usi solo immagini di base già pronte che richiedono solo il codice dell'applicazione (come un sito Web)?
Mathias,

Usiamo packer e puppet per configurare le nostre immagini. Le nostre immagini sono pronte per la produzione dopo la loro creazione
bsuttor,

@Mathias, vedi la mia risposta modificata Ho un piccolo tool dock-run che sto usando per aggiornare i pacchetti linux (attualmente debian / ubuntu) in tutti i container in esecuzione.
iTech,

3
Se un'immagine ha lo stesso nome di un contenitore (ad es. redis), LATEST=`docker inspect --format "{{.Id}}" $IMAGE`Otterrà le informazioni sul contenitore. Aggiungi --type imageper risolvere questo problema.
Patrick Fisher,

1
Grazie per il tuo post. L'ho modificato per avvolgere il tutto in un loop per ottenere immagini dalla finestra mobile: for IMAGE in $(docker ps --format {{.Image}} -q | sort -u)
Armand

25

Un "modo docker" sarebbe quello di utilizzare build automatizzate dell'hub docker . La funzione Collegamenti repository ricostruirà il contenitore quando viene ricostruito un contenitore a monte e Webhooks funzione invierà una notifica.

Sembra che i webhook siano limitati alle chiamate POST HTTP. Dovresti creare un servizio per catturarli o magari utilizzare uno dei POST per inviare servizi di posta elettronica.

Non ci ho pensato, ma il nuovo Docker Universal Control Plane potrebbe avere una funzione per rilevare container aggiornati e ridistribuire.


Ho dovuto costruire un webhook per il servizio AMQP: github.com/goliatone/rabbithook
goliatone

Purtroppo, i trigger a monte non sono più disponibili: github.com/docker/hub-feedback/issues/1717 .
Julien Chastang,

23

Puoi usare Watchtower per controllare gli aggiornamenti dell'immagine da cui viene istanziato un contenitore ed estrarre automaticamente l'aggiornamento e riavviare il contenitore utilizzando l'immagine aggiornata. Tuttavia, ciò non risolve il problema di ricostruire le tue immagini personalizzate in caso di modifica dell'immagine a monte su cui si basa. È possibile visualizzare questo come un problema in due parti: (1) sapere quando un'immagine a monte è stata aggiornata e (2) fare la ricostruzione dell'immagine effettiva. (1) può essere risolto abbastanza facilmente, ma (2) dipende molto dall'ambiente / dalle pratiche di build locali, quindi è probabilmente molto più difficile creare una soluzione generalizzata per questo.

Se sei in grado di utilizzare le build automatizzate di Docker Hub , l'intero problema può essere risolto in modo relativamente pulito utilizzando la funzione dei collegamenti al repository , che consente di attivare automaticamente una ricostruzione quando viene aggiornato un repository collegato (probabilmente uno a monte). Puoi anche configurare un webhook per avvisarti quando si verifica una generazione automatica. Se si desidera ricevere una notifica via e-mail o SMS, è possibile connettere il webhook a IFTTT Maker . Ho trovato che l'interfaccia utente IFTTT fosse un po 'confusa, ma avresti configurato il webhook Docker per pubblicare su https://maker.ifttt.com/trigger/docker_xyz_image_built / with / key / your_key.

Se è necessario creare localmente, è possibile almeno risolvere il problema di ricevere notifiche quando viene aggiornata un'immagine a monte creando un repository fittizio in Docker Hub collegato ai repository di interesse. L'unico scopo del repository fittizio sarebbe quello di attivare un webhook quando viene ricostruito (il che implica che uno dei repository collegati è stato aggiornato). Se riesci a ricevere questo webhook, potresti persino usarlo per attivare una ricostruzione dalla tua parte.


1
La Torre di Guardia utilizza però la presa mobile. Dal punto di vista della sicurezza che sta concedendo l'accesso root al computer host.
Joe

1
Inoltre, Watchtower non sembra essere in grado di aggiornare le immagini da repository privati ​​diversi da Docker Hub. Un peccato per noi che usiamo Azure.
Thomas Eyde,

1
È possibile utilizzare i registri privati ​​utilizzando REPO_USERe REPO_PASSle variabili di ambiente. Dai un'occhiata a readme.md dalla Torre di Guardia per maggiori informazioni: github.com/v2tec/watchtower#usage
Alejandro Nortes,

2
Un avvertimento, la torre di guardia viene abbandonata dal suo manutentore e l'immagine in DockerHub non è nemmeno aggiornata con quella in github.
XanderStrike

Sembra che il repository Watchtower sia stato migrato in containerrrr / watchtower . E ci sono alcuni problemi con le build automatizzate collegate su Dockerhub, come sottolineato da questa risposta su una domanda simile .
Chrki,

10

Ho avuto lo stesso problema e ho pensato che potesse essere semplicemente risolto chiamando un lavoro cron unattended-upgrade quotidianamente.

La mia intenzione è quella di avere questo come soluzione automatica e rapida per garantire che il contenitore di produzione sia sicuro e aggiornato perché può volerci un po 'di tempo per aggiornare le mie immagini e distribuire una nuova immagine docker con gli ultimi aggiornamenti di sicurezza.

È anche possibile automatizzare la generazione e la distribuzione dell'immagine hook di Github

Ho creato un'immagine docker di base che controlla e installa automaticamente gli aggiornamenti di sicurezza ogni giorno (può essere eseguita direttamente dadocker run itech/docker-unattended-upgrade ).

Mi sono anche imbattuto in un altro approccio diverso per verificare se il contenitore necessita di un aggiornamento.

La mia completa implementazione:

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

Script di supporto

installare

#!/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"]

inizio

#!/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

modificare

Ho sviluppato una piccola finestra mobile di strumenti che viene eseguita come contenitore docker e che può essere utilizzata per aggiornare i pacchetti all'interno di tutti o contenitori in esecuzione selezionati, ma può anche essere utilizzata per eseguire qualsiasi comando arbitrario.

Può essere facilmente testato con il seguente comando:

docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec

che per impostazione predefinita eseguirà il datecomando in tutti i contenitori in esecuzione e visualizzerà i risultati. Se si passa updateinvece execsi eseguirà apt-get updateseguito da apt-get upgrade -yin tutti i contenitori in esecuzione


il mio riferimento all'aggiornamento automatico era solo per mostrare l'analogia in un ambiente non docker. Il mio intento è quello di risolverlo nel modo docker (se esiste oc.) Avere un processo aggiuntivo in un contenitore batte lo scopo di docker imo. Corregge il problema del ritardo tra l'aggiornamento a monte della loro immagine e l'utente stesso, che lo sta effettivamente deponendo sul contenitore corrente. Anche se questo può richiedere fino a 1 giorno anche con gli aggiornamenti automatici, quindi .. Anche il riferimento github non è soddisfacente, perché il meccanismo di aggiornamento ora è fortemente dipendente dal sistema operativo host.
hbogert,

Il "modo docker" non impedisce di eseguire altri processi sullo stesso contenitore se sono strettamente correlati e non creano colli di bottiglia della scalabilità. E questo particolare caso d'uso è un buon esempio di quando è possibile avere un contenitore con un altro processo in esecuzione. (ad es. vedi l'immagine per gitlab mentre esegue più processi obbligatori sullo stesso contenitore).
iTech,

Non definirei un meccanismo di aggiornamento strettamente correlato alla funzione principale di un'immagine. Questa soluzione è come dare a ogni applicazione su una macchina convenzionale un proprio meccanismo di aggiornamento invece di imporre un onere a un gestore di pacchetti. Sebbene sia una soluzione, non risponde alla mia domanda che è, aggiornando automaticamente le immagini locali e quindi i contenitori dovrebbero essere rieseguiti. Con l'aggiornamento nei container stessi stiamo introducendo di nuovo molto stato di cui non abbiamo idea, che è contro il modo docker (di nuovo imho).
hbogert,

1
Potrebbe essere necessario qualcosa di livello superiore rispetto alla finestra mobile, ad esempio Kubernetesutile per la distribuzione di grandi infrastrutture, ma è ancora in fase di forte sviluppo da parte di Google. Al momento, puoi automatizzarlo con uno strumento di provisioning come Ansible in un modo abbastanza semplice.
iTech,

Il tuo "approccio diverso" citato potrebbe essere quello che stavo cercando. Il tuo contributo sembra un'alternativa praticabile per i "contenitori grassi". Sicuramente esaminerò ulteriormente entrambi, grazie per la risposta.
Mathias,

7

Non sapresti che il tuo contenitore è dietro senza eseguire la finestra mobile . Quindi dovrai ricostruire o ricomporre la tua immagine.

docker pull image:tag
docker-compose -f docker-compose.yml -f production.yml up -d --build

I comandi possono essere inseriti in uno script insieme a qualsiasi altra cosa necessaria per completare l'aggiornamento, sebbene un contenitore adeguato non necessiterebbe di ulteriori elementi.


1: ok, ma poi dovrei guardare tutte le mie immagini locali, ottenere le loro immagini di base, estrarle. Quindi ricostruire le immagini le cui immagini di base sono cambiate. Quindi arrestare i contenitori la cui immagine viene cambiata e ricreare i contenitori con 'docker run' e i parametri necessari. Questo sembra eccessivamente manuale. Ma se questo è lo status quo, accetterò la risposta.
hbogert,

Si prega di attendere prima di accettare. Forse c'è qualcosa là fuori. Uso la finestra mobile da 6 mesi, ma non sono stato al passo con gli ultimi sviluppi.
seanmcl

In qualche modo, internamente, Docker è in grado di confrontare le immagini al fine di eseguire la sua capacità di "memorizzazione nella cache". Forse puoi trovare un modo per sfruttarlo. In altre parole, controlla se le immagini sottostanti (fino alla base) sono cambiate e quindi attiva un processo per la ricostruzione. Sfortunatamente, la memorizzazione nella cache non ti aiuterà in quel caso: l'intera immagine verrà ricostruita perché l'immagine di base è cambiata.
Thom Parkin,

5

La gestione delle dipendenze per le immagini Docker è un vero problema. Faccio parte di un team che ha creato uno strumento, MicroBadger , per aiutarlo monitorando le immagini dei container e ispezionando i metadati. Una delle sue caratteristiche è quella di permetterti di impostare un webhook di notifica che viene chiamato quando un'immagine che ti interessa (ad esempio un'immagine di base) cambia.


5

Ci sono molte risposte qui, ma nessuna di queste si adattava alle mie esigenze. Volevo una risposta effettiva alla domanda n. 1 del richiedente. Come faccio a sapere quando un'immagine viene aggiornata su hub.docker.com?

Lo script seguente può essere eseguito quotidianamente. Alla prima esecuzione, ottiene una base dei tag e le date di aggiornamento dal registro HUB e li salva localmente. Da allora in poi, ogni volta che viene eseguito controlla il registro per nuovi tag e date di aggiornamento. Poiché questo cambia ogni volta che esiste una nuova immagine, ci dice se l'immagine di base è cambiata. Ecco la sceneggiatura:

#!/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;

Ti consigliamo di modificare la DATAPATHvariabile in alto e il comando di notifica e-mail alla fine per soddisfare le tue esigenze. Per me, l'ho SSH in un server su un'altra rete in cui si trova il mio SMTP. Ma potresti anche usare facilmente il mailcomando.

Ora, si desidera anche verificare la presenza di pacchetti aggiornati all'interno dei contenitori stessi. Questo in realtà è probabilmente più efficace di un "pull" quando i container funzionano. Ecco lo script per farlo:

#!/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

1
mkdir nel primo script dovrebbe probabilmente essere: mkdir -p Inoltre, il primo script confronta VAR1 con VAR2, supponendo che dovrebbe confrontare OLD con NEW. Se vero, ciò significa che questo script non farà realmente ciò che OP vuole, A MENO che non sia stato eseguito per la prima volta al momento dell'installazione. Cioè, non sta davvero determinando nulla su ciò che è installato, solo se i risultati differiscono dalle precedenti esecuzioni ...
JoeG

5

Un altro approccio potrebbe essere quello di supporre che l'immagine di base si allontani abbastanza rapidamente (e questo è molto probabile che accada) e forzare periodicamente un'altra generazione di immagini dell'applicazione (ad esempio ogni settimana) e quindi ridistribuirla se è cambiata.

Per quanto ne so, le immagini di base popolari come Debian o Java ufficiali aggiornano i loro tag per soddisfare le correzioni di sicurezza, quindi i tag non sono immutabili (se vuoi una garanzia più forte di ciò devi usare il riferimento [image: @digest ], disponibile nelle versioni Docker più recenti). Pertanto, se dovessi creare la tua immagine docker build --pull, l'applicazione dovrebbe ottenere l'ultimo e il più grande dei tag dell'immagine di base a cui fai riferimento.

Poiché i tag mutabili possono essere fonte di confusione, è meglio aumentare il numero di versione dell'applicazione ogni volta che lo fai in modo che almeno dalla tua parte le cose siano più pulite.

Quindi non sono sicuro che lo script suggerito in una delle risposte precedenti funzioni, poiché non ricostruisce l'immagine dell'applicazione: aggiorna solo il tag immagine di base e quindi riavvia il contenitore, ma il nuovo contenitore fa ancora riferimento l'hash dell'immagine di base precedente.

Non difenderei l'esecuzione di lavori cron-type nei container (o in qualsiasi altro processo, a meno che non sia realmente necessario) poiché ciò va contro il mantra dell'esecuzione di un solo processo per container (ci sono vari argomenti sul perché sia ​​meglio, quindi non ci entrerò qui).


4

Non entrerò nell'intera questione se si desidera o meno aggiornamenti automatici nella produzione (penso di no). Sto solo lasciando questo qui come riferimento nel caso qualcuno lo trovasse utile. Aggiorna tutte le immagini della finestra mobile all'ultima versione con il seguente comando nel tuo terminale:

# docker images | awk '(NR>1) && ($2!~/none/) {print $1":"$2}' | xargs -L1 docker pull


1
Il comando è utile per aggiornare tutte le immagini, ma non cambia nulla in esecuzione in produzione. I contenitori derivano ancora dalle vecchie immagini, che ora sono senza tag.
Nessuno

Vero. Ed ecco un altro per i libri ... Usa # docker system prune -a --volumes -fper ripulire i vecchi (penzoloni) immagini, volumi ecc
Meferdati

4

AGGIORNAMENTO: Usa Dependabot - https://dependabot.com/docker/

BLUF: trovare il giusto punto di inserimento per monitorare le modifiche a un container è la sfida. Sarebbe bello se DockerHub lo risolvesse. (I collegamenti al repository sono stati menzionati ma nota quando li configuri su DockerHub - " Attiva una build in questo repository ogni volta che l'immagine di base viene aggiornata su Docker Hub. Funziona solo per immagini non ufficiali." )

Mentre cercavo di risolverlo da solo, ho visto diversi consigli per i webhook, quindi volevo approfondire un paio di soluzioni che ho usato.

  1. Usa microbadger.com per tenere traccia delle modifiche in un contenitore e usa la sua funzione webhook di notifica per attivare un'azione. Ho impostato questo con zapier.com (ma è possibile utilizzare qualsiasi servizio webhook personalizzabile) per creare un nuovo problema nel mio repository github che utilizza Alpine come immagine di base.

    • Pro: puoi rivedere le modifiche segnalate da microbadger in github prima di agire.
    • Contro: Microbadger non ti consente di tracciare un tag specifico. Sembra che tenga traccia solo degli "ultimi".
  2. Traccia il feed RSS per git si impegna su un contenitore a monte. ex. https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64 . Ho usato zapier.com per monitorare questo feed e per innescare una compilazione automatica del mio contenitore in Travis-CI ogni volta che si commette qualcosa. Questo è un po 'estremo ma puoi cambiare il trigger per fare altre cose come aprire un problema nel tuo repository git per un intervento manuale.

    • Pro: più vicino a una pipeline automatizzata. La build di Travis-CI verifica solo se il contenitore presenta problemi con qualsiasi cosa sia stata impegnata nel repository di immagini di base. Dipende da te se il tuo servizio CI intraprende ulteriori azioni.
    • Contro: il monitoraggio del feed di commit non è perfetto. Molte cose si impegnano nel repository che non influiscono sulla build dell'immagine di base. Non tiene conto di eventuali problemi con frequenza / numero di commit e limitazione delle API.

3

Premessa alla mia risposta:

  1. I contenitori vengono eseguiti con tag.
  2. Lo stesso tag può essere puntato su UUID di immagine diversa come preferiamo / ci sentiamo appropriati.
  3. Gli aggiornamenti eseguiti su un'immagine possono essere assegnati a un nuovo livello immagine

Approccio

  1. Costruire tutti i contenitori in primo luogo con uno script di aggiornamento della patch di sicurezza
  2. Costruire un processo automatizzato per quanto segue
    • Esegui un'immagine esistente in un nuovo contenitore con lo script della patch di sicurezza come comando
    • Apporta modifiche all'immagine come
      • tag esistente -> seguito dal riavvio dei contenitori uno alla volta
      • tag nuova versione -> sostituisci alcuni contenitori con un nuovo tag -> convalida -> sposta tutti i contenitori nel nuovo tag

Inoltre, l'immagine di base può essere aggiornata / il contenitore con una nuova immagine di base completa può essere creato a intervalli regolari, poiché il manutentore ritiene necessario

vantaggi

  1. Conserviamo la vecchia versione dell'immagine durante la creazione della nuova immagine con patch di sicurezza, quindi, se necessario, possiamo ripristinare l'immagine in esecuzione precedente
  2. Stiamo preservando la cache della finestra mobile, quindi meno trasferimento di rete (solo il layer modificato arriva sul filo)
  3. Il processo di aggiornamento può essere convalidato nella stadiazione prima di passare a prod
  4. Questo può essere un processo controllato, quindi le patch di sicurezza solo quando è necessario / ritenuto importante possono essere spinte.

In un ambiente di produzione, sebbene siano aggiornamenti di sicurezza, dubito che vorresti avere aggiornamenti automatici! Se sono necessari aggiornamenti non presidiati, il processo può essere eseguito a intervalli regolari (a seconda dei casi) come processo cron.
Phani,

1
La mia premessa è che gli aggiornamenti di sicurezza dovrebbero provenire da immagini upstream / base.
hbogert,

@hbogert Preferirei dire che esiste una linea sottile di differenziazione tra teoria e pratica. Quando le cose entreranno in pratica, ci saranno molti aspetti esterni che devono essere presi in considerazione, come: costo (non solo valore del dollaro, ma anche tempo) associato all'attuazione.
Phani,

3

Le risposte sopra sono anche corrette

Ci sono due approcci

  1. Usa i webhook
  2. Esegui lo script per ogni minuto specifico per ottenere nuove immagini della finestra mobile

Sto solo condividendo la sceneggiatura potrebbe essere utile per te! Puoi usarlo con cronjob, ho provato con successo su 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

Ecco il mio file comporre docker

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

3

Ecco un modo più semplice per aggiornare automaticamente il contenitore docker

Inserisci il lavoro tramite $ crontab -e:

0 * * * * sh ~/.docker/cron.sh

Crea dir ~/.dockercon file 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

0

hai provato questo: https://github.com/v2tec/watchtower . è un semplice strumento in esecuzione in un contenitore docker che guarda altri contenitori, se la loro immagine di base viene modificata, verrà estratta e ridistribuita.


-1

Una soluzione semplice e ottima è il pastore


iiuc, questo non aiuta in senso generale, perché è accoppiato a Swarm e si riavvia solo a monte, mentre vogliamo reagire, ricostruire, ecc. sulle modifiche a monte e non semplicemente riavviare.
hbogert,

Sembra qualcosa che dovresti fare in una pipeline CI
user672009
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.