Temel görüntüler güncellenirse docker kapsayıcılarınızı otomatik olarak güncelleme


205

Diyelim ki temelli bir konteynır var ubuntu:latest. Şimdi bir güvenlik güncelleştirmesi var ve ubuntu:latestdocker deposunda güncellendi.

  1. Yerel imajımın ve kaplarının geride kaldığını nasıl bilebilirim?

  2. Docker repo güncellemelerini takip etmek için yerel görüntüleri ve kapsayıcıları otomatik olarak güncellemek için bazı en iyi uygulama var mıdır;


11
Docker'ın başlangıcından beri buna bir cevap arıyorum. Biraz daha karmaşık. Apache (örneğin) kurarsam ve bu güncellenirse, daha sonra yüklediğim için temel görüntü değişmez. Yine de apache için otomatik güncellemeler almak istiyorum. Aslında bu konuda IRC sordum ve bir cevap olarak "yukarı akış takip ve güncellemeler üzerinde yeniden" var ...
Mathias

8
Merak eden tek kişi olmadığım için mutluyum. Docker geliştiricileri için geliştirme ve tekrarlanabilirlik, yıllardır sahip olduğumuz mantıklı güncelleme mekanizmalarından daha önemli gibi görünüyor.
hbogert

Sorun şu ki, liman işçisi konteynırların teknolojisidir. Bir ekosistemin bunun etrafında gelişmesi için biraz zamana ihtiyacı olduğunu düşünüyorum. Docker'ın günlüğe kaydetme gibi ele almadığı başka sorunlar var.
Mathias

3
Cevaplayan herkese teşekkürler. Ödülü bölemediğim için özür dilerim. Sorunumun nihai bir çözümü olmasa da, hepinizden iyi girdiler vardı.
Mathias

1
@Mathias için, az önce eklediğim çözümde konteynırdan sonra kurulan paketler için güvenlik güncellemelerini kontrol eden bir komut dosyası var. Ayrıca temel görüntüyü kontrol etmek için ayrı bir komut dosyası vardır.
Fmstrat

Yanıtlar:


8

Bunu yapmanın yollarından biri, bunu CI / CD sistemleriniz üzerinden sürmektir. Ana görüntünüz oluşturulduktan sonra, git üst havuzunuzu bu üst öğeyi kullanarak görüntüler için tarayan bir şeye sahip olun. Eğer bulunursa, görüntünün yeni sürümlerine çarpmak için bir çekme isteği gönderirsiniz. Tüm testler başarılı olursa çekme isteği birleştirilecek ve güncellenen üst öğeye göre yeni bir alt resminiz olacaktır. Bu yaklaşımı benimseyen bir araca örnek burada bulunabilir: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 .

Ana resminizi kontrol etmezseniz, resmi ubunturesme bağlı olduğunuzda olduğu gibi, ana resim etiketindeki veya sağlama toplamındaki değişiklikleri (aynı şey değil, etiketler değiştirilebilir) algılayan bazı araçlar yazabilirsiniz ve çocuk imajını buna göre çağırır.


Vay canına, bu büyük bir çekiç, dedi: Ben bu soruyu sorduğum zamandan beri de inşa sunucusunun bu sorunu çözmek için bir yer olduğunu fark ettim. Bazı takımlar gördüğüme sevindim. Yaklaşımınızı genel kavramlarda açıklarsanız (tam aracınız / uygulamanızda değil) ve cevaba eklerseniz, muhtemelen kabul edeceğim.
hbogert

Thanks @hbogert Yukarıda düzenledi ve ayrıca kamu görüntüleri ile uğraşıyorsanız ne yapacağınız hakkında bir fikir içerir
Ma3oxuct

123

Çalışan bir kapsayıcıyla en son görüntünün başlatılıp başlatılmadığını kontrol eden bir komut dosyası kullanıyoruz. Docker görüntüsünü başlatmak için upstart init komut dosyalarını da kullanıyoruz.

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

Ve init şöyle görünüyor

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

1
Bu değerli katkı için çok teşekkürler. Bu, temel görüntüyü güncellemek için iyi bir yol gibi görünüyor. Geriye kalan soru şudur: dockerfile içindeki dağıtım tarafından yüklenen bir uygulamayı (apache gibi) nasıl güncellersiniz? Yoksa yalnızca uygulama kodunuza (web sitesi gibi) ihtiyaç duyan hazır temel resimler mi kullanıyorsunuz?
Mathias

Görüntülerimizi yapılandırmak için paketleyici ve kukla kullanıyoruz. Görüntülerimiz yaratıldıktan sonra üretime geçmeye hazır
bsuttor

@Mathias, benim düzenlenmiş cevabımı görmek Çalışan tüm kapsayıcılarda linux (şu anda debian / ubuntu) paketleri güncellemek için kullandığım küçük bir araç docker çalıştırmak var.
iTech

3
Bir görüntü bir kapsayıcıyla (örneğin redis) aynı ada sahipse LATEST=`docker inspect --format "{{.Id}}" $IMAGE`kapsayıcı bilgilerini alır. --type imageBunu düzeltmek için ekleyin .
Patrick Fisher

1
Gönderiniz için teşekkürler. Docker'dan görüntü elde etmek için her şeyi bir döngü içine sarmak için değiştirdim: for IMAGE in $(docker ps --format {{.Image}} -q | sort -u)
Armand

25

'Docker yolu' docker hub otomatik yapıları kullanmak olacaktır . Depo Linkler bir yukarı akış konteyner yeniden edildiğinde özellik kapsayıcınızı yeniden inşa edecek ve Webhooks özelliğinin bir bildirim gönderir.

Web kancaları HTTP POST çağrılarıyla sınırlı görünüyor. Onları yakalamak için bir hizmet ayarlamanız veya postaları postalamak için POST'tan birini kullanmanız gerekebilir.

Buna bakmadım, ancak yeni Docker Evrensel Kontrol Düzleminde güncellenmiş kapsayıcıları tespit etme ve yeniden dağıtma özelliği olabilir.


AMQP hizmetine bir webhook yapmak zorunda kaldım: github.com/goliatone/rabbithook
goliatone

Maalesef, yukarı akış tetikleyicileri artık kullanılamıyor: github.com/docker/hub-feedback/issues/1717 .
Julien Chastang

23

Gözetleme Kulesi kullanabilirsinizBir kapsayıcıdan örnek alınan görüntünün güncellemelerini izlemek için ve güncellemeyi otomatik olarak çekebilir ve güncellenen görüntüyü kullanarak kapsayıcıyı yeniden başlatabilirsiniz. Ancak, bu, dayalı akış yukarı görüntüsünde bir değişiklik olduğunda kendi özel görüntülerinizi yeniden oluşturma sorununu çözmez. Bunu iki bölümlü bir sorun olarak görebilirsiniz: (1) bir akış yukarı görüntünün ne zaman güncellendiğini bilmek ve (2) gerçek görüntüyü yeniden oluşturmak. (1) oldukça kolay bir şekilde çözülebilir, ancak (2) yerel inşa ortamınıza / uygulamalarınıza çok bağlıdır, bu nedenle bunun için genelleştirilmiş bir çözüm oluşturmak muhtemelen çok daha zordur.

Docker Hub'ın otomatik derlemelerini kullanabiliyorsanız , tüm sorun, bağlantılı bir havuz (muhtemelen bir yukarı akış) güncellendiğinde otomatik olarak yeniden oluşturmayı tetiklemenizi sağlayan depo bağlantıları özelliği kullanılarak nispeten temiz bir şekilde çözülebilir . Bir web kancasını otomatik bir derleme gerçekleştiğinde size bildirecek şekilde de yapılandırabilirsiniz . Bir e-posta veya SMS bildirimi istiyorsanız, web kancasını IFTTT Maker'a bağlayabilirsiniz . IFTTT kullanıcı arayüzünü biraz kafa karıştırıcı buldum, ancak Docker web kancasını https://maker.ifttt.com/trigger/docker_xyz_image_built / ile / key / dizinine gönderecek şekilde yapılandırabilirsiniz your_key.

Yerel olarak inşa etmeniz gerekiyorsa, Docker Hub'da ilgi alanlarınıza bağlı olarak sahte bir repo oluşturarak bir yukarı akış görüntüsü güncellendiğinde bildirim alma sorununu en azından çözebilirsiniz. Kukla repo'nun tek amacı, yeniden inşa edildiğinde (bağlantılı depolarından birinin güncellendiğini ima eden) bir web kancasını tetiklemek olacaktır. Bu web kancasını alabiliyorsanız, bunu sizin tarafınızda yeniden oluşturmayı tetiklemek için bile kullanabilirsiniz.


1
Gözetleme kulesi yine de docker soketini kullanır. Ana makineye root erişimi veren güvenlik açısından.
JoeG

1
Ayrıca, Gözcü Kulesi Docker Hub dışındaki özel havuzlardaki görüntüleri güncelleyemiyor gibi görünüyor. Azure kullanan bizim için bir serseri.
Thomas Eyde

1
Özel kayıtları REPO_USERve REPO_PASSortam değişkenlerini kullanarak kullanabilirsiniz . Daha fazla bilgi için Watchtower'dan readme.md'e bakın: github.com/v2tec/watchtower#usage
Alejandro Nortes

2
Uyarı kelimesi, gözetleme kulesi koruyucusu tarafından terk edildi ve DockerHub'daki görüntü github'daki görüntüyle bile güncel değil.
XanderStrike

Gözcü Kulesi repo, rum / gözetleme kulesine taşınmış gibi görünüyor . Ve benzer bir soru üzerine bu cevabın işaret ettiği gibi, Dockerhub'daki bağlantılı otomatik yapılarla ilgili bazı sorunlar var .
chrki

10

Aynı sorunu yaşadım ve unattended-upgradeher gün çağrılan bir cron işi tarafından çözülebileceğini düşündüm .

Amacım bunu üretim konteynerinin güvenli ve güncel olmasını sağlamak için otomatik ve hızlı bir çözüm olarak kullanmaktır, çünkü görüntülerimi güncellemem ve en son güvenlik güncellemeleriyle yeni bir docker görüntüsünü dağıtmam biraz zaman alabilir.

Github kancaları ile görüntü oluşturma ve yerleştirmeyi otomatikleştirmek de mümkündür

Güvenlik güncelleştirmelerini günlük olarak otomatik olarak kontrol eden ve yükleyen temel bir liman işçisi resmi oluşturdum (doğrudan çalıştırabilir docker run itech/docker-unattended-upgrade).

Ayrıca , kabın bir güncellemeye ihtiyacı olup olmadığını kontrol etmek için başka bir yaklaşımla karşılaştım.

Uygulamamın tamamı:

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

Yardımcı komut dosyaları

Yüklemek

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

Başlat

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

Düzenle

Docker kapsayıcısı olarak çalışan ve paketlerin tümünü veya seçilen çalışan kapsayıcıları güncellemek için kullanılabilecek küçük bir takım docker çalışması geliştirdim , ayrıca herhangi bir rastgele komut çalıştırmak için de kullanılabilir.

Aşağıdaki komutla kolayca test edilebilir:

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

varsayılan dateolarak tüm çalışan kapsayıcılarda komut yürütür ve sonuçları görüntüler. Eğer geçerseniz updateyerine execo yürütmek olacak apt-get updateizledi apt-get upgrade -yçalışan tüm kaplarda


katılımsız yükseltme ile ilgili referansım, bağlantısız bir ortamda benzetmeyi göstermekti. Amacım bunu docker yolunu çözmek (eğer oc varsa) Bir kapta ekstra bir işleme sahip olmak docker imo'nun amacını yener. Yukarı doğru görüntülerini yukarı akışla güncellemeniz arasındaki gecikme sorununu yayar, kullanıcı, aslında mevcut konteynırınıza depolar. Bu katılımsız yükseltmeleri ile de 1 gün kadar sürebilir, bu yüzden .. Ayrıca github referansı tatmin edici değildir, çünkü güncelleme mekanizması şimdi ana işletim sistemine büyük ölçüde bağımlıdır.
hbogert

"Docker yolu", sıkı bir şekilde ilişkili oldukları ve ölçeklenebilirlik darboğazı oluşturmayacakları takdirde, aynı kapsayıcıda diğer işlemleri çalıştırmanızı engellemez. Ve bu özel kullanım durumu, başka bir çalışan işlemle ne zaman bir konteynıra sahip olabileceğinize iyi bir örnektir. (örneğin , aynı kapta birden çok zorunlu işlem yürüttüğü için gitlab görüntüsüne bakın ).
iTech

Bir görüntünün ana işlevi ile sıkı bir şekilde ilişkili bir güncelleme mekanizması çağırmazdım. Bu çözüm, yükü bir paket yöneticisine yerleştirmek yerine geleneksel bir makinedeki her uygulamaya kendi güncelleme mekanizmasını vermek gibidir. Bir çözüm olmasına rağmen, yerel görüntüleri otomatik olarak güncelleyen ve daha sonra kapların yeniden çalıştırılması gereken soruma cevap vermiyor. Konteynırların kendileri güncellenmesiyle, hiçbir fikrimiz olmayan, yine de docker yoluna (tekrar imho) karşı olan birçok durumu tanıtıyoruz.
hbogert

1
KubernetesBüyük altyapı dağıtımı için yararlı olan docker'dan daha yüksek bir şeye ihtiyacınız olabilir , ancak yine de Google tarafından ağır bir geliştirme aşamasındadır. Şu anda bunu Ansible gibi bir sağlama aracıyla oldukça basit bir şekilde otomatikleştirebilirsiniz.
iTech

Alıntıladığınız "farklı yaklaşımınız" aradığım şey olabilir. Kendi katkınız "yağ kapları" için uygun bir alternatif gibi görünüyor. Kesinlikle her ikisini de biraz daha inceleyeceğim, cevabınız için teşekkürler.
Mathias

7

Docker çekme işlemi yapmadan konteynerinizin arkasında olduğunu bilmezsiniz . Ardından resminizi yeniden oluşturmanız veya yeniden oluşturmanız gerekir .

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

Komutlar, uygun bir kapsayıcı ek bir şeye ihtiyaç duymasa da, yükseltmeyi tamamlamak için gerekli olan her şeyle birlikte bir komut dosyasına yerleştirilebilir.


1: tamam, ama sonra tüm yerel görüntülerime bakmak, temel görüntülerini almak, bunları çekmek zorundayım. Ardından, temel görüntüleri değişen görüntüleri yeniden oluşturun. Ardından, görüntüsü değiştirilen kapsayıcıları durdurun ve kapları 'docker çalıştırması' ve gerekli parametrelerle yeniden oluşturun. Bu aşırı manuel görünüyor. Ama eğer bu statüko ise, cevabı kabul edeceğim.
hbogert

Lütfen kabul etmeden önce bekleyin. Belki orada bir şey vardır. 6 aydır docker kullanıyorum ancak en son gelişmelere ayak uyduramıyorum.
seanmcl

Her nasılsa, dahili olarak Docker, 'önbellekleme' yeteneğini gerçekleştirmek için görüntüleri karşılaştırabilir. Belki THAT'tan yararlanmanın bir yolunu bulabilirsiniz. Başka bir deyişle, temeldeki görüntülerin (tabana kadar tümüyle) değişip değişmediğini kontrol edin ve ardından yeniden oluşturmak için bir işlemi tetikleyin. Ne yazık ki, önbellekleme bu durumda size yardımcı olmaz: temel görüntü değiştiği için tüm görüntü yeniden oluşturulacaktır.
Thom Parkin

5

Docker görüntüleri için bağımlılık yönetimi gerçek bir sorundur. Konteyner görüntülerini izleyerek ve meta verileri inceleyerek bu konuda yardımcı olacak bir araç olan MicroBadger'ı oluşturan bir ekibin parçasıyım . Özelliklerinden biri, ilgilendiğiniz bir görüntü (örneğin bir temel görüntü) değiştiğinde çağrılan bir bildirim web kancası ayarlamanıza izin vermektir.


5

Burada birçok cevap var, ama hiçbiri benim ihtiyaçlarıma uygun değil. Sorucunun 1. sorusuna gerçek bir cevap istedim. Bir görüntünün hub.docker.com'da güncellendiğini nasıl anlarım?

Aşağıdaki komut dosyası günlük olarak çalıştırılabilir. İlk çalıştırmada, HUB kayıt defterinden etiketlerin ve güncelleme tarihlerinin temelini alır ve bunları yerel olarak kaydeder. O andan itibaren, her çalıştırıldığında kayıt defterinde yeni etiketler ve güncelleme tarihleri ​​olup olmadığını kontrol eder. Her yeni görüntü olduğunda bu değiştiğinden, temel görüntünün değişip değişmediğini bize söyler. İşte senaryo:

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

DATAPATHDeğişkeni en üstte değiştirmek ve sonunda e-posta bildirim komutunu ihtiyaçlarınıza göre değiştirmek istersiniz . Benim için, SMTP'nin bulunduğu başka bir ağdaki bir sunucuya SSH var. Ancak mailkomutu da kolayca kullanabilirsiniz .

Şimdi, kapların içindeki güncelleştirilmiş paketleri de kontrol etmek istersiniz. Bu aslında konteynırlarınız çalıştıktan sonra bir "çekme" işleminden daha etkilidir. İşte bunu çıkarmak için komut dosyası:

#!/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
İlk komut dosyasında mkdir muhtemelen şöyle olmalıdır: mkdir -p Ayrıca, ilk komut dosyası VAR1'i VAR2 ile karşılaştırır, ESKİ'yi YENİ ile karşılaştırması gerektiğini varsayar. Eğer doğruysa, bu, bu komut dosyasının OP'nin istediği şeyi gerçekten yapmayacağı anlamına gelir, ilk kurulum sırasında ÇALIŞMAZ. Yani, sonuçlar önceki çalışmalardan farklıysa, yüklü olan şey hakkında gerçekten bir şey belirlemez ...
JoeG

5

Başka bir yaklaşım, temel görüntünüzün oldukça hızlı bir şekilde geride kaldığını varsaymak (ve bunun olması muhtemeldir) ve uygulamanızın başka bir görüntü derlemesini periyodik olarak (örneğin her hafta) zorlamak ve değiştiğinde yeniden dağıtmak olabilir.

Anlayabildiğim kadarıyla, resmi Debian veya Java gibi popüler temel resimler, güvenlik düzeltmelerine hitap etmek için etiketlerini güncellediğinden, etiketler değiştirilemez (bunun daha güçlü bir garantisini istiyorsanız referansı kullanmanız gerekir [image: @digest ], daha yeni Docker sürümlerinde kullanılabilir). Bu nedenle, resminizi birlikte oluşturacaksanız docker build --pull, uygulamanız referans verdiğiniz temel resim etiketinin en son ve en büyüğünü almalıdır.

Değiştirilebilir etiketler kafa karıştırıcı olabileceğinden, bunu her yaptığınızda uygulamanızın sürüm numarasını arttırmak en iyisidir, böylece en azından yanınızda işler daha temiz olur.

Dolayısıyla, önceki yanıtlardan birinde önerilen komut dosyasının işi yaptığından emin değilim, çünkü uygulamanızın görüntüsünü yeniden oluşturmaz - sadece temel resim etiketini günceller ve ardından kapsayıcıyı yeniden başlatır, ancak yeni kap yine de başvurur eski temel resim karması.

Kaplarda cron türü işler (veya gerçekten gerekli olmadıkça başka herhangi bir işlem) çalıştırmayı savunmam, çünkü bu kap başına sadece bir işlem çalıştırma mantrasına karşı çıkıyor (bunun neden daha iyi olduğu hakkında çeşitli argümanlar var, bu yüzden ' buraya girmeyeceğim).


4

Üretimde katılımsız güncelleme isteyip istemediğinize dair tüm soruya girmiyorum (sanmıyorum). Herkesin yararlı bulması durumunda bunu burada referans olarak bırakıyorum. Terminalinizdeki aşağıdaki komutla tüm docker görüntülerinizi en son sürüme güncelleyin:

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


1
Komut, tüm görüntüleri güncellemek için yararlıdır, ancak üretimde çalışan hiçbir şeyi değiştirmez. Kaplar hala etiketsiz olan eski görüntülerden kaynaklanıyor.
Hiçbiri

Doğru. Ve işte kitaplar için bir tane daha ... # docker system prune -a --volumes -fEski (sarkan) görüntüleri, hacimleri vb. Temizlemek için kullanın
Meferdati

4

GÜNCELLEME: Dependabot kullanın - https://dependabot.com/docker/

BLUF: bir kaptaki değişiklikleri izlemek için doğru yerleştirme noktasını bulmak güçtür. DockerHub'ın bunu çözmesi harika olurdu. (Havuz Bağlantılarından bahsedildi, ancak DockerHub üzerinde ayarlarken not edin - " Docker Hub'da temel görüntü her güncellendiğinde bu havuzda bir yapıyı tetikleyin. Yalnızca resmi olmayan resimler için çalışır. ))

Bunu kendim çözmeye çalışırken webhooks için birkaç öneri gördüm, bu yüzden kullandığım birkaç çözüm üzerinde durmak istedim.

  1. Bir kapsayıcıdaki değişiklikleri izlemek için microbadger.com'u kullanın ve bir eylemi tetiklemek için bildirim webhook özelliğini kullanın. Bunu zapier.com ile ayarladım (ancak herhangi bir özelleştirilebilir webhook hizmetini kullanabilirsiniz) Alpine'yi temel görüntü olarak kullanan github havuzumda yeni bir sorun oluşturmak için.

    • Artıları: Microbadger tarafından harekete geçmeden önce github'da bildirilen değişiklikleri gözden geçirebilirsiniz.
    • Eksileri: Microbadger belirli bir etiketi izlemenize izin vermez. Görünüşe göre sadece 'en son' izler.
  2. Yukarı akış konteynerine git taahhütleri için RSS beslemesini izleyin. ex. https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64 . Bu beslemeyi izlemek ve bir şey yapıldığında Travis-CI'de kabımın otomatik olarak oluşturulmasını tetiklemek için zapier.com'u kullandım. Bu biraz aşırı ama manuel müdahale için git deponuzda bir sorun açmak gibi başka şeyler yapmak için tetikleyiciyi değiştirebilirsiniz.

    • Artıları: Otomatik bir boru hattına daha yakın. Travis-CI derlemesi sadece konteynerinizin temel görüntü havuzuna bağlı olanlarla ilgili sorunları olup olmadığını kontrol eder. CI hizmetinizin başka bir işlem yapması size kalmış.
    • Eksileri: Taahhüt özet akışını izlemek mükemmel değil. Temel görüntünün yapısını etkilemeyen bir çok şey depoya bağlıdır. Sıklık / taahhüt sayısı ve herhangi bir API kısıtlaması ile ilgili sorunları hesaba katmaz.

3

Cevabımın öncüsü:

  1. Kapsayıcılar etiketlerle çalıştırılır.
  2. Aynı etiket, uygun gördüğümüz gibi farklı görüntü UUID'sine işaret edilebilir.
  3. Bir görüntüye yapılan güncellemeler yeni bir görüntü katmanına uygulanabilir

Yaklaşmak

  1. Güvenlik kapsayıcısı güncelleştirme komut dosyasıyla tüm kapsayıcıları en başta oluşturun
  2. Aşağıdakiler için otomatik bir süreç oluşturun
    • Varolan bir görüntüyü komut olarak güvenlik düzeltme eki komut dosyasıyla yeni kapsayıcıya çalıştırma
    • Resimde değişiklik yap
      • mevcut etiket -> ardından kapsayıcıları teker teker yeniden başlatma
      • yeni sürüm etiketi -> birkaç kapsayıcıyı yeni etiketle değiştir -> onayla -> tüm kapsayıcıları yeni etikete taşı

Ek olarak, temel görüntü yükseltilebilir / tam bir yeni temel görüntü içeren kap, bakımcının gerekli hissettiği gibi düzenli aralıklarla oluşturulabilir

Avantajları

  1. Yeni güvenlik yamalı görüntüyü oluştururken görüntünün eski sürümünü koruyoruz, bu nedenle gerekirse önceki çalışan görüntüye geri dönebiliriz
  2. Docker önbelleğini koruyoruz, dolayısıyla daha az ağ aktarımı yapıyoruz (yalnızca değiştirilen katman kabloya geçiyor)
  3. Prodüksiyona geçmeden önce yükseltme işlemi aşamalı olarak doğrulanabilir
  4. Bu kontrollü bir süreç olabilir, bu nedenle güvenlik yamaları ancak gerektiğinde / önemli görüldüğünde itilebilir.

Bir üretim ortamında, güvenlik güncelleştirmeleri olmasına rağmen, katılımsız güncellemeler almak istediğinizden şüpheliyim! Katılımsız güncellemelerin olması gerekiyorsa, işlem bir cron işi olarak düzenli aralıklarla (uygun şekilde) çalıştırılabilir.
Phani

1
Benim önceliğim, güvenlik güncellemelerinin yukarı akış / temel görüntülerden gelmesi gerektiğidir.
hbogert

@hbogert Teori ve pratik arasında ince bir ayrım çizgisi olduğunu söylemeliyim. İşler yürürlüğe girdiğinde, dikkate alınması gereken birçok dış husus olacaktır, örneğin: uygulama ile ilişkili maliyet (sadece dolar değeri değil, aynı zamanda zaman).
15:00

3

Yukarıdaki Cevaplar da doğrudur

İki Yaklaşım var

  1. Web kancalarını kullan
  2. Liman işçilerinin resimlerini yeni çekmek için belirli bir dakikada komut dosyası çalıştırın

Ben sadece script paylaşıyorum sizin için yararlı olabilir! Sen cronjob ile kullanabilirsiniz, OSX üzerinde başarıyla denedim

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

İşte docker-compose dosyam

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

Docker kapsayıcısını otomatik olarak güncellemenin en basit yolu

İşi şu yolla koyun $ crontab -e:

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

~/.dockerDosya ile dizin oluştur 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


-1

Basit ve harika bir çözüm çoban


iiuc, bu genel anlamda yardımcı olmaz, çünkü bu Swarm ile birleşir ve sadece yukarı akışa yeniden başlar , oysa yukarı akış değişikliklerine tepki vermek, yeniden inşa etmek vb.
hbogert

Bu bir CI boru hattında yapmanız gereken bir şey gibi geliyor
user672009
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.