Cara memperbarui wadah buruh pelabuhan Anda secara otomatis, jika gambar dasar diperbarui

205

Katakanlah saya memiliki wadah sepele berdasarkan ubuntu:latest. Sekarang ada pembaruan keamanan dan ubuntu:latestdiperbarui di repo buruh pelabuhan.

  1. Bagaimana saya tahu gambar lokal saya dan wadahnya berjalan di belakang?

  2. Apakah ada beberapa praktik terbaik untuk secara otomatis memperbarui gambar dan wadah lokal untuk mengikuti pembaruan repo buruh pelabuhan, yang dalam praktiknya akan memberi Anda keramahtamahan yang sama dengan memiliki peningkatan tanpa pengawasan yang berjalan pada mesin ubuntu konvensional

hbogert
sumber
11
Saya mencari jawaban untuk ini sejak awal buruh pelabuhan. Ini bahkan sedikit lebih rumit. Jika saya menginstal apache (misalnya) dan yang diperbarui, gambar dasar tidak berubah, karena saya menginstalnya setelah itu. Saya masih ingin memiliki pembaruan otomatis untuk apache. Saya benar-benar bertanya di IRC tentang hal ini dan mendapat "ikuti hulu dan bangun kembali pada pembaruan" sebagai jawaban ...
Mathias
8
Senang saya bukan satu-satunya yang bertanya-tanya. Tampaknya pengembangan dan reproduktifitas lebih penting bagi para buruh pelabuhan daripada mekanisme pembaruan yang masuk akal yang telah kami miliki selama bertahun-tahun sekarang.
hbogert
Masalahnya, buruh pelabuhan hanya teknologi untuk wadah. Saya pikir perlu waktu untuk ekosistem untuk berkembang di sekitar itu. Ada masalah lain yang tidak ditangani oleh buruh pelabuhan seperti pencatatan.
Mathias
3
Terima kasih untuk semuanya yang telah menjawab. Maaf saya tidak bisa membagi hadiah. Meskipun tidak ada solusi akhir untuk masalah saya, ada masukan yang baik dari Anda semua.
Mathias
1
Untuk @Mathias, solusi yang baru saja saya tambahkan memiliki skrip yang akan memeriksa pembaruan keamanan untuk paket yang diinstal dalam wadah pasca-tarik. Ini juga memiliki skrip terpisah untuk memeriksa gambar dasar.
Fmstrat

Jawaban:

9

Salah satu cara untuk melakukannya adalah mengendarainya melalui sistem CI / CD Anda. Setelah gambar induk Anda dibuat, miliki sesuatu yang memindai repositori git Anda untuk gambar menggunakan orangtua itu. Jika ditemukan, Anda kemudian akan mengirimkan permintaan tarik untuk menabrak versi baru gambar. Permintaan tarik, jika semua tes lulus, akan digabung dan Anda akan memiliki gambar anak baru berdasarkan orang tua yang diperbarui. Contoh alat yang menggunakan pendekatan ini dapat ditemukan di sini: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 .

Jika Anda tidak mengontrol gambar induk Anda, seperti halnya jika Anda bergantung pada ubuntugambar resmi , Anda dapat menulis beberapa alat yang mendeteksi perubahan pada tag gambar induk atau checksum (bukan hal yang sama, tag dapat diubah) dan memohon gambar anak membangun sesuai.

Ma3oxuct
sumber
Wow ini adalah palu besar, yang mengatakan: sejak saat saya mengajukan pertanyaan ini saya juga menyadari bahwa build server adalah tempat untuk mengatasi masalah ini. Saya senang melihat beberapa perkakas. Jika Anda menjelaskan pendekatan Anda dalam konsep umum (dan bukan alat / implementasi persis Anda) dan memasukkannya dalam jawaban saya mungkin akan menerimanya.
hbogert
Terima kasih @hbogert Saya telah mengedit di atas dan juga menyertakan ide tentang apa yang harus dilakukan jika Anda berurusan dengan gambar publik
Ma3oxuct
123

Kami menggunakan skrip yang memeriksa apakah wadah berjalan dimulai dengan gambar terbaru. Kami juga menggunakan skrip init pemula untuk memulai gambar buruh pelabuhan.

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

Dan init sepertinya

docker run -t -i --name $NAME $im /bin/bash
bsuttor
sumber
1
Terima kasih banyak atas kontribusi berharga ini. Ini sepertinya cara yang bagus untuk memperbarui gambar dasar. Pertanyaan yang tersisa adalah, bagaimana Anda memperbarui aplikasi (seperti apache) yang diinstal oleh distribusi di dockerfile? Atau apakah Anda hanya menggunakan gambar dasar yang sudah jadi yang hanya membutuhkan kode aplikasi Anda (seperti situs web)?
Mathias
Kami menggunakan pengepak dan boneka untuk mengonfigurasi gambar kami. Gambar kami siap untuk diproduksi setelah penciptaannya
bsuttor
@Mathias, lihat jawaban saya yang sudah diedit. Saya punya alat kecil untuk menjalankan docker yang saya gunakan untuk memperbarui paket linux (saat ini debian / ubuntu) di semua wadah yang berjalan.
ITech
3
Jika suatu gambar memiliki nama yang sama dengan wadah (mis. redis), LATEST=`docker inspect --format "{{.Id}}" $IMAGE`Akan mendapatkan info wadah. Tambahkan --type imageuntuk memperbaikinya.
Patrick Fisher
1
Terima kasih atas kiriman Anda. Saya memodifikasinya untuk membungkus semuanya dalam satu lingkaran untuk mendapatkan gambar dari buruh pelabuhan: for IMAGE in $(docker ps --format {{.Image}} -q | sort -u)
Armand
25

Suatu 'cara buruh pelabuhan' adalah dengan menggunakan bangunan pelabuhan otomatis . Fitur Tautan Repositori akan membangun kembali wadah Anda saat wadah hulu dibangun kembali, dan fitur Webhooks akan mengirimi Anda pemberitahuan.

Sepertinya webhooks terbatas pada panggilan HTTP POST. Anda perlu mengatur layanan untuk menangkap mereka, atau mungkin menggunakan salah satu POST untuk mengirim email layanan di luar sana.

Saya belum memeriksanya, tetapi Docker Universal Control Plane yang baru mungkin memiliki fitur untuk mendeteksi kontainer yang diperbarui dan digunakan kembali.

TAKSI
sumber
Saya harus membuat webhook untuk layanan AMQP: github.com/goliatone/rabbithook
goliatone
Sayangnya, pemicu hulu tidak lagi tersedia: github.com/docker/hub-feedback/issues/1717 .
Julien Chastang
23

Anda dapat menggunakan Menara Pengawal untuk menonton pembaruan untuk gambar wadah berasal dari dan secara otomatis menarik pembaruan dan restart wadah menggunakan gambar yang diperbarui. Namun, itu tidak menyelesaikan masalah membangun kembali gambar khusus Anda sendiri ketika ada perubahan pada gambar hulu yang menjadi dasarnya. Anda dapat melihat ini sebagai masalah dua bagian: (1) mengetahui kapan gambar hulu telah diperbarui, dan (2) melakukan gambar yang sebenarnya dibangun kembali. (1) dapat diselesaikan dengan cukup mudah, tetapi (2) sangat tergantung pada lingkungan / praktik pembangunan lokal Anda, jadi mungkin lebih sulit untuk membuat solusi umum untuk itu.

Jika Anda dapat menggunakan bangunan otomatis Docker Hub , seluruh masalah dapat diselesaikan secara relatif bersih menggunakan fitur tautan repositori , yang memungkinkan Anda memicu pembangunan kembali secara otomatis ketika repositori terkait (mungkin yang upstream) diperbarui. Anda juga dapat mengonfigurasi webhook untuk memberi tahu Anda ketika build otomatis terjadi. Jika Anda ingin pemberitahuan email atau SMS, Anda bisa menghubungkan webhook ke IFTTT Maker . Saya menemukan antarmuka pengguna IFTTT agak membingungkan, tetapi Anda akan mengkonfigurasi webhook Docker untuk dikirim ke https://maker.ifttt.com/trigger/docker_xyz_image_built / with / key / your_key.

Jika Anda perlu membuat secara lokal, Anda setidaknya bisa menyelesaikan masalah mendapatkan pemberitahuan ketika gambar hulu diperbarui dengan membuat repo tiruan di Docker Hub yang ditautkan dengan repo Anda yang menarik. Satu-satunya tujuan repo tiruan adalah untuk memicu webhook ketika akan dibangun kembali (yang menyiratkan salah satu repo terkait yang diperbarui). Jika Anda dapat menerima webhook ini, Anda bahkan dapat menggunakannya untuk memicu pembangunan kembali di sisi Anda.

jjlin
sumber
1
Menara Pengawal menggunakan soket buruh pelabuhan. Dari perspektif keamanan yang memberikan akses root ke mesin host.
JoeG
1
Selain itu, Menara Pengawal tampaknya tidak dapat memperbarui gambar dari repositori pribadi selain Docker Hub. Nyebelin bagi kita yang menggunakan Azure.
Thomas Eyde
1
Anda dapat menggunakan register pribadi menggunakan REPO_USERdan REPO_PASSvariabel lingkungan. Lihatlah readme.md dari Menara Pengawal untuk info lebih lanjut: github.com/v2tec/watchtower#usage
Alejandro Nortes
2
Kata peringatan, menara pengawal ditinggalkan oleh pengelolanya, dan gambar di DockerHub bahkan tidak mutakhir dengan yang ada di github.
XanderStrike
Repo Menara Pengawal tampaknya telah dimigrasi ke containrrr / watchtower . Dan ada beberapa masalah dengan pembuatan otomatis tertaut di Dockerhub, seperti yang ditunjukkan oleh jawaban ini pada pertanyaan serupa .
chrki
10

Saya memiliki masalah yang sama dan berpikir itu bisa diselesaikan dengan cron job calling unattended-upgradesetiap hari.

Tujuan saya adalah menjadikan ini sebagai solusi otomatis dan cepat untuk memastikan bahwa wadah produksi aman dan diperbarui karena kadang-kadang saya perlu memperbarui gambar saya dan menggunakan gambar buruh pelabuhan baru dengan pembaruan keamanan terbaru.

Dimungkinkan pula untuk mengotomatisasi pembuatan dan penyebaran gambar dengan kait Github

Saya telah membuat gambar buruh pelabuhan dasar dengan yang secara otomatis memeriksa dan menginstal pembaruan keamanan setiap hari (dapat dijalankan langsung oleh docker run itech/docker-unattended-upgrade).

Saya juga menemukan pendekatan lain yang berbeda untuk memeriksa apakah wadah perlu pembaruan.

Implementasi lengkap saya:

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

Skrip pembantu

Install

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

Mulailah

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

Edit

Saya mengembangkan alat docker-run kecil yang berfungsi sebagai wadah buruh pelabuhan dan dapat digunakan untuk memperbarui paket di dalam semua atau kontainer yang berjalan yang dipilih, itu juga dapat digunakan untuk menjalankan perintah sewenang-wenang.

Dapat dengan mudah diuji dengan perintah berikut:

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

yang secara default akan menjalankan dateperintah di semua wadah yang berjalan dan menampilkan hasilnya. Jika Anda lulus updatealih-alih execitu akan menjalankan apt-get updatediikuti oleh apt-get upgrade -ydi semua wadah berjalan

ITech
sumber
referensi saya untuk upgrade tanpa pengawasan hanya untuk menunjukkan analogi dalam lingkungan non-buruh pelabuhan. Maksud saya adalah untuk menyelesaikan ini dengan cara buruh pelabuhan (jika ada oc.) Memiliki proses ekstra dalam sebuah wadah mengalahkan tujuan buruh pelabuhan imo. Itu menambal masalah penundaan antara upstream memperbarui gambar mereka dan Anda, pengguna, benar-benar merusaknya di wadah Anda saat ini. Meskipun ini bisa memakan waktu hingga 1 hari dengan upgrade tanpa pengawasan juga, jadi .. Juga referensi github tidak memuaskan, karena mekanisme pembaruan sekarang sangat bergantung pada OS host.
hbogert
"Cara buruh pelabuhan" tidak mencegah Anda menjalankan proses lain pada wadah yang sama jika mereka terkait erat dan tidak akan membuat hambatan skalabilitas. Dan use case khusus ini adalah contoh yang baik ketika Anda dapat memiliki wadah dengan proses berjalan lainnya. (mis. lihat gambar untuk gitlab saat menjalankan beberapa proses wajib pada wadah yang sama).
ITech
Saya tidak akan menyebut mekanisme pembaruan yang terkait erat dengan fungsi utama gambar. Solusi ini seperti memberikan setiap aplikasi pada mesin konvensional mekanisme pembaruannya sendiri daripada menempatkan beban pada manajer paket. Meskipun ini merupakan solusi, itu tidak menjawab pertanyaan saya yang, secara otomatis memperbarui gambar lokal dan kemudian, kontainer harus dijalankan kembali. Dengan memperbarui dalam wadah sendiri kami memperkenalkan banyak negara lagi yang kami tidak tahu, yang bertentangan dengan cara buruh pelabuhan (sekali lagi imho).
hbogert
1
Anda mungkin membutuhkan sesuatu yang lebih tinggi daripada buruh pelabuhan seperti Kubernetesyang berguna untuk penyebaran infrastruktur besar, tetapi masih dalam pengembangan berat oleh Google. Saat ini, Anda dapat mengotomatisasi ini dengan alat penyediaan seperti Ansible dengan cara yang cukup sederhana.
ITech
"Pendekatan berbeda" yang Anda kutip mungkin adalah yang saya cari. Kontribusi Anda sendiri terlihat seperti alternatif yang layak untuk "wadah lemak". Saya pasti akan melihat keduanya sedikit lebih jauh, terima kasih atas jawaban Anda.
Mathias
7

Anda tidak akan tahu wadah Anda ada di belakang tanpa menjalankan docker pull . Maka Anda perlu membangun kembali atau menyusun ulang gambar Anda.

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

Perintah dapat dimasukkan ke dalam skrip bersama dengan apa pun yang diperlukan untuk menyelesaikan upgrade, meskipun wadah yang tepat tidak memerlukan tambahan apa pun.

seanmcl
sumber
1: ok, tapi kemudian aku harus melihat semua gambar lokal saya, dapatkan gambar dasarnya, tarik itu. Kemudian buat kembali gambar yang gambar dasarnya telah berubah. Kemudian hentikan kontainer yang gambarnya diubah dan buat ulang wadah dengan 'docker run' dan parameter yang diperlukan. Ini sepertinya terlalu manual. Tetapi jika ini adalah status quo, maka saya akan menerima jawabannya.
hbogert
Harap tunggu sebelum Anda menerima. Mungkin ada sesuatu di luar sana. Saya telah menggunakan buruh pelabuhan selama 6 bulan, tetapi belum mengikuti perkembangan terakhir.
seanmcl
Entah bagaimana, secara internal, Docker dapat membandingkan gambar untuk melakukan kemampuan 'caching'. Mungkin Anda dapat menemukan cara untuk memanfaatkan ITU. Dengan kata lain, periksa untuk melihat apakah gambar yang mendasarinya (semua jalan kembali ke pangkalan) telah berubah dan kemudian memicu proses untuk membangun kembali. Sayangnya, caching tidak akan membantu Anda dalam hal ini: seluruh gambar akan dibangun kembali karena gambar dasar telah berubah.
Thom Parkin
5

Manajemen ketergantungan untuk gambar Docker adalah masalah nyata. Saya bagian dari tim yang membuat alat, MicroBadger , untuk membantu dengan memantau gambar kontainer dan memeriksa metadata. Salah satu fiturnya adalah untuk memungkinkan Anda menyiapkan webhook pemberitahuan yang dipanggil saat gambar yang Anda minati (misalnya gambar dasar) berubah.

Liz Rice
sumber
5

Ada banyak jawaban di sini, tetapi tidak ada yang sesuai dengan kebutuhan saya. Saya ingin jawaban aktual untuk pertanyaan si penanya # 1. Bagaimana saya tahu ketika gambar diperbarui di hub.docker.com?

Script di bawah ini dapat dijalankan setiap hari. Saat pertama kali dijalankan, tag akan mendapat garis dasar dan memperbarui tanggal dari registri HUB dan menyimpannya secara lokal. Sejak saat itu, setiap kali dijalankan, ia akan memeriksa tanda-tanda baru dan memperbarui tanggal pada registri. Karena ini berubah setiap kali gambar baru ada, itu memberitahu kita jika gambar dasar telah berubah. Ini skripnya:

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

Anda akan ingin mengubah DATAPATHvariabel di bagian atas, dan mengubah perintah pemberitahuan email di akhir sesuai dengan kebutuhan Anda. Bagi saya, saya memilikinya SSH ke server di jaringan lain di mana SMTP saya berada. Tapi Anda bisa dengan mudah menggunakanmail perintah juga.

Sekarang, Anda juga ingin memeriksa paket yang diperbarui di dalam wadah itu sendiri. Ini sebenarnya mungkin lebih efektif daripada melakukan "tarikan" begitu wadah Anda bekerja. Berikut skrip untuk melakukan itu:

#!/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
Fstst
sumber
1
mkdir dalam skrip pertama mungkin harus: mkdir -p Selain itu, skrip pertama membandingkan VAR1 dengan VAR2, anggap yang harus membandingkan LAMA dengan BARU. Jika benar, ini berarti bahwa skrip ini tidak akan benar-benar melakukan apa yang diinginkan OP, KECUALI itu dijalankan pertama kali pada saat instalasi. Artinya, itu tidak benar-benar menentukan apa pun tentang apa yang diinstal, hanya jika hasilnya berbeda dari berjalan sebelumnya ...
JoeG
5

Pendekatan lain mungkin dengan mengasumsikan bahwa gambar dasar Anda ketinggalan cukup cepat (dan itu sangat mungkin terjadi), dan memaksakan pembuatan gambar lain dari aplikasi Anda secara berkala (mis. Setiap minggu) dan kemudian gunakan kembali jika telah berubah.

Sejauh yang saya tahu, gambar dasar populer seperti Debian atau Java resmi memperbarui tag mereka untuk memenuhi perbaikan keamanan, sehingga tag tidak dapat diubah (jika Anda menginginkan jaminan yang lebih kuat dari itu, Anda perlu menggunakan referensi [image: @digest ], tersedia dalam versi Docker terbaru). Karena itu, jika Anda ingin membangun citra Anda docker build --pull , maka aplikasi Anda harus mendapatkan tag gambar dasar terbaru dan terbesar yang Anda rujuk.

Karena tag yang dapat diubah dapat membingungkan, yang terbaik adalah menambah nomor versi aplikasi Anda setiap kali Anda melakukan ini sehingga setidaknya pada sisi Anda segala sesuatu lebih bersih.

Jadi saya tidak yakin skrip yang disarankan di salah satu jawaban sebelumnya berfungsi, karena skrip tidak membangun kembali gambar aplikasi Anda - hanya memperbarui tag gambar dasar dan kemudian memulai ulang wadah, tetapi wadah baru masih merujuk hash gambar dasar lama.

Saya tidak akan menganjurkan untuk menjalankan pekerjaan jenis cron dalam wadah (atau proses lain, kecuali benar-benar diperlukan) karena ini bertentangan dengan mantra menjalankan hanya satu proses per wadah (ada berbagai argumen tentang mengapa ini lebih baik, jadi saya ' Saya tidak akan membahasnya di sini).

Bogdan
sumber
4

Saya tidak akan membahas seluruh pertanyaan apakah Anda ingin pembaruan tanpa pengawasan dalam produksi (saya pikir tidak). Saya hanya meninggalkan ini di sini untuk referensi kalau-kalau ada yang merasa berguna. Perbarui semua gambar buruh pelabuhan Anda ke versi terbaru dengan perintah berikut di terminal Anda:

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

Meferdati
sumber
1
Perintah ini berguna untuk memperbarui semua gambar, tetapi tidak mengubah apa pun yang berjalan dalam produksi. Wadah masih berasal dari gambar lama, yang sekarang tidak diberi tag.
Tidak ada
Benar. Dan ini satu lagi untuk buku-buku itu ... Gunakan # docker system prune -a --volumes -funtuk membersihkan gambar-gambar lama (menggantung), volume dll.
Meferdati
4

UPDATE: Gunakan Dependabot - https://dependabot.com/docker/

BLUF: menemukan titik penyisipan yang tepat untuk memantau perubahan pada sebuah wadah adalah tantangannya. Akan lebih bagus jika DockerHub akan menyelesaikan ini. (Tautan Repositori telah disebutkan tetapi perhatikan ketika mengaturnya di DockerHub - "Trigger build dalam repositori ini setiap kali gambar dasar diperbarui pada Docker Hub. Hanya berfungsi untuk gambar yang tidak resmi." )

Ketika mencoba untuk menyelesaikan ini sendiri, saya melihat beberapa rekomendasi untuk webhook jadi saya ingin menguraikan beberapa solusi yang saya gunakan.

  1. Gunakan microbadger.com untuk melacak perubahan dalam sebuah wadah dan gunakan fitur webhook pemberitahuan untuk memicu tindakan. Saya mengatur ini dengan zapier.com (tetapi Anda dapat menggunakan layanan webhook yang dapat disesuaikan) untuk membuat masalah baru di repositori github saya yang menggunakan Alpine sebagai gambar dasar.

    • Pro: Anda dapat meninjau perubahan yang dilaporkan oleh microbadger di github sebelum mengambil tindakan.
    • Cons: Microbadger tidak membiarkan Anda melacak tag tertentu. Sepertinya itu hanya melacak 'terbaru'.
  2. Lacak umpan RSS untuk git yang berkomitmen ke wadah hulu. ex. https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64 . Saya menggunakan zapier.com untuk memantau umpan ini dan untuk memicu pembangunan otomatis wadah saya di Travis-CI kapan pun ada sesuatu yang dilakukan. Ini sedikit ekstrem tetapi Anda dapat mengubah pelatuk untuk melakukan hal-hal lain seperti membuka masalah di repositori git Anda untuk intervensi manual.

    • Pro: Lebih dekat ke saluran pipa otomatis. Build Travis-CI hanya memeriksa untuk melihat apakah wadah Anda memiliki masalah dengan apa pun yang dilakukan pada repositori gambar dasar. Terserah Anda jika layanan CI Anda mengambil tindakan lebih lanjut.
    • Cons: Melacak umpan komit tidak sempurna. Banyak hal yang dikomit ke repositori yang tidak memengaruhi pembuatan gambar dasar. Tidak memperhitungkan masalah dengan frekuensi / jumlah komitmen dan pembatasan API apa pun.
2 tumpukan
sumber
3

Premis untuk jawaban saya:

  1. Wadah dijalankan dengan tag.
  2. Tag yang sama dapat diarahkan ke gambar UUID yang berbeda sesuai keinginan kita.
  3. Pembaruan yang dilakukan pada gambar dapat dilakukan ke lapisan gambar baru

Pendekatan

  1. Bangun semua kontainer di tempat pertama dengan skrip pembaruan keamanan-patch
  2. Bangun proses otomatis untuk yang berikut ini
    • Jalankan gambar yang ada ke wadah baru dengan skrip patch keamanan sebagai perintah
    • Mengkomit perubahan pada gambar sebagai
      • tag yang ada -> diikuti dengan memulai kembali wadah satu per satu
      • tag versi baru -> ganti beberapa wadah dengan tag baru -> validasi -> pindahkan semua wadah ke tag baru

Selain itu, gambar dasar dapat ditingkatkan / wadah dengan gambar dasar baru yang lengkap dapat dibangun secara berkala, karena pengelola merasa perlu.

Keuntungan

  1. Kami menjaga versi lama gambar sambil membuat gambar keamanan yang ditambal baru, maka kami dapat mengembalikan ke gambar yang berjalan sebelumnya jika perlu
  2. Kami menjaga cache buruh pelabuhan, karenanya transfer jaringan lebih sedikit (hanya lapisan yang diubah yang terhubung)
  3. Proses peningkatan dapat divalidasi dalam pementasan sebelum pindah ke prod
  4. Ini bisa menjadi proses yang terkendali, maka patch keamanan hanya jika diperlukan / dianggap penting dapat didorong.
Phani
sumber
Pada lingkungan produksi, meskipun pembaruan keamanan, saya ragu Anda ingin memiliki pembaruan tanpa pengawasan! Jika memiliki pembaruan tanpa pengawasan diperlukan, proses dapat dijalankan secara berkala (sesuai kebutuhan) sebagai tugas cron.
Phani
1
Premis saya adalah bahwa pembaruan keamanan harus berasal dari gambar hulu / dasar.
hbogert
@ Hbogert Saya lebih suka mengatakan ada garis pembedaan yang bagus antara teori dan praktik. Ketika berbagai hal mulai dipraktikkan, akan ada banyak aspek eksternal yang perlu diperhitungkan, seperti: biaya (tidak hanya nilai dolar, tetapi juga waktu) yang terkait dengan implementasi.
Phani
3

Jawaban di atas juga benar

Ada dua Pendekatan

  1. Gunakan kait web
  2. Jalankan skrip untuk setiap menit tertentu untuk mendapatkan gambar buruh pelabuhan yang segar

Saya hanya membagikan skrip, semoga bermanfaat bagi Anda! Anda dapat menggunakannya dengan cronjob, saya mencoba dengan sukses di 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

Ini adalah file komposisi buruh pelabuhan saya

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
Akshay Shikre
sumber
3

Berikut adalah cara paling sederhana untuk memperbarui wadah buruh pelabuhan secara otomatis

Letakkan pekerjaan melalui $ crontab -e:

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

Buat dir ~/.dockerdengan 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
Chetabahana
sumber
0

Sudahkah Anda mencoba ini: https://github.com/v2tec/watchtower . itu adalah alat sederhana yang berjalan dalam wadah buruh pelabuhan menonton wadah lain, jika gambar dasarnya berubah, itu akan menarik dan memindahkan.

linehrr
sumber
-1

Solusi sederhana dan hebat adalah gembala

pengguna672009
sumber
iiuc, ini tidak membantu dalam arti umum, karena ini digabungkan ke Swarm dan hanya me- restart hulu, sedangkan kami ingin bereaksi, membangun kembali, dll pada perubahan hulu dan tidak hanya restart.
hbogert
Itu terdengar seperti sesuatu yang harus Anda lakukan dalam pipa CI
user672009