Bagaimana cara memaksa Kubernetes untuk menarik kembali gambar?

161

Saya memiliki pengontrol replikasi berikut di Kubernetes di GKE:

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 2
  selector:
    app: myapp
    deployment: initial
  template:
    metadata:
      labels:
        app: myapp
        deployment: initial
    spec:
      containers:
      - name: myapp
        image: myregistry.com/myapp:5c3dda6b
        ports:
        - containerPort: 80
      imagePullPolicy: Always
      imagePullSecrets:
        - name: myregistry.com-registry-key

Sekarang, jika saya katakan

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b

pembaruan bergulir dilakukan, tetapi tidak ada tarik ulang. Mengapa?

Torsten Bronger
sumber
12
Saya memberi gambar yang berbeda, hanya dengan tag yang sama. Jika perlu untuk memberikan tag yang berbeda, well, saya tidak melihat titik di imagePullPolicylapangan.
Torsten Bronger
4
Saya ingin menggunakan tag tertentu, tetapi versi terbarunya.
Torsten Bronger
3
@ ThorstenBronger Saya pikir ini adalah perubahan besar dalam teori Kubernetes / Docker. Gagasan bahwa Anda dapat menarik gambar: tag (selain yang terbaru) pada dua waktu yang berbeda dan mendapatkan dua gambar yang berbeda akan bermasalah. Tag mirip dengan nomor versi. Akan lebih baik berlatih untuk selalu mengubah tag ketika gambar berubah.
duct_tape_coder
2
Tergantung. Ada perangkat lunak dengan API yang sangat stabil tetapi pembaruan keamanan. Lalu, saya ingin versi terbaru tanpa harus mengatakannya secara eksplisit.
Torsten Bronger
1
@ TorstenBronger Mengenai menggunakan latest, jangan lakukan itu. Terbaru akan menarik, well, gambar yang lebih baru dengan tag terbaru. Yang Anda inginkan adalah rentang SemVer. ~ 1.2.3 misalnya. ini akan menarik gambar dengan tag antara kisaran> = 1.2.3 dan <1.3.0. Selama vendor gambar mengikuti SemVer, Anda tahu (dan ini adalah bagian penting) tidak ada perubahan mundur yang ditambahkan (dengan sengaja) dan bahwa tidak ada fitur baru yang ditambahkan (kemungkinan masalah keamanan). Tolong, tolong jangan gunakan latestdalam sistem produksi.
David J Eddy

Jawaban:

141

Kubernetes akan memanfaatkan pembuatan Pod jika salah satu (lihat memperbarui-gambar doc ):

  • Menggunakan gambar yang ditandai :latest
  • imagePullPolicy: Always ditentukan

Ini bagus jika Anda ingin selalu menarik. Tetapi bagaimana jika Anda ingin melakukannya atas permintaan : Misalnya, jika Anda ingin menggunakan some-public-image:latesttetapi hanya ingin menarik versi yang lebih baru secara manual saat Anda memintanya. Anda saat ini dapat:

  • Setel imagePullPolicyke IfNotPresentatau Neverdan pra-tarik : Tarik gambar secara manual pada masing-masing simpul gugus sehingga yang terbaru di-cache, lalu lakukan kubectl rolling-updateatau serupa untuk me-restart Pods (hack yang mudah rusak!)
  • Ubah sementaraimagePullPolicy , lakukan a kubectl apply, mulai ulang pod (mis. kubectl rolling-update), Kembalikan imagePullPolicy, ulangi kubectl apply(jelek!)
  • Tarik dan dorong some-public-image:latest ke repositori pribadi Anda dan lakukan kubectl rolling-update(berat!)

Tidak ada solusi yang baik untuk tarikan sesuai permintaan. Jika itu berubah, beri komentar; Saya akan memperbarui jawaban ini.

Wernight
sumber
Anda mengatakan kubernet akan menarik pembuatan Pod saat menggunakan :latest- bagaimana patchdengan? apakah itu juga selalu menarik gambar terbaru / terbaru? Sepertinya tidak bekerja untuk saya :(
pkyeck
Itu tergantung apakah tambalan Anda memaksa pembuatan ulang Pod atau tidak. Kemungkinan besar tidak, maka itu tidak akan menarik lagi. Anda dapat membunuh Pod secara manual, atau memberi tag dengan sesuatu yang unik dan menambal dengan tag yang diperbarui itu.
Wernight
Ini adalah jawaban untuk pertanyaan yang berbeda. Saya meminta paksaan untuk menarik kembali.
Torsten Bronger
Ini memungkinkan saya untuk memaksa tarikan baru dari GCR. Saya memiliki :latesttag yang menunjuk ke gambar baru, dan kubectl rolling-updateberfungsi untuk memperbarui pod.
Randy L
Terima kasih. Pergi untuk pendekatan Tarik & Dorong. Otomatis sebanyak mungkin dengan skrip bash tetapi setuju, ini berat :)
arcseldon
77

Kita harus mengelompokkan imagePullPolicydi dalam data wadah alih-alih di dalam data spesifikasi. Namun, saya mengajukan masalah tentang ini karena saya merasa aneh. Selain itu, tidak ada pesan kesalahan.

Jadi, cuplikan spesifikasi ini berfungsi:

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key
Torsten Bronger
sumber
3
imagePullPolicy(atau pemberian tag :latest) baik jika Anda ingin selalu menarik, tetapi tidak menyelesaikan pertanyaan tentang menarik berdasarkan permintaan.
Wernight
1
Ya, saya ingin selalu menarik, sebagaimana dinyatakan dalam pertanyaan.
Torsten Bronger
1
Menggunakan imagePullPolicy: Alwaysdefinisi dalam wadah akan kubernetesmengambil gambar dengan tag :latestsetiap kali versi yang lebih baru dari mereka didorong ke registri?
pkaramol
1
@ pkaramol No. imagePullPolicy: Alwayshanya memberi tahu Kubernetes untuk selalu menarik gambar dari registri. Gambar apa yang akan dikonfigurasikan berdasarkan imageatribut. Jika Anda mengonfigurasinya image: your-image:latest, maka itu akan selalu menarik your-imagegambar dengan latesttag.
Gajus
26

Retas saya selama pengembangan adalah untuk mengubah manifes Penempatan saya untuk menambahkan tag terbaru dan selalu menarik seperti itu

image: etoews/my-image:latest
imagePullPolicy: Always

Kemudian saya menghapus pod secara manual

kubectl delete pod my-app-3498980157-2zxhd

Karena ini Penyebaran, Kubernetes akan secara otomatis membuat ulang pod dan menarik gambar terbaru.

Everett Toews
sumber
Saya suka memanfaatkan tempat "keadaan yang diinginkan" dari objek "penyebaran" ... terima kasih atas sarannya!
Marcello de Sales
2
Perlu dicatat bahwa strategi hanya dapat dilakukan jika kegagalan dalam layanan dan waktu henti dapat ditoleransi. Untuk pengembangan tampaknya masuk akal, tetapi saya tidak akan pernah melakukan strategi ini untuk penyebaran produksi.
digitaldreamer
Edit penyebaran, ubah imagePullPolicy untuk selalu dan menghapus pod sudah cukup bagi saya, seperti yang disarankan Everett. Ini adalah lingkungan pengembangan. kubernetes.io/docs/concepts/containers/images
Jos Roberto Almaraz
17

Solusi populer adalah untuk menambal penyebaran dengan anotasi dummy (atau label):

kubectl patch deployment <name> -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

Dengan asumsi penyebaran Anda memenuhi persyaratan ini, ini akan menyebabkan K8 menarik gambar baru dan memindahkan.

Tamlyn
sumber
2
Ya, saya menggunakan anotasi untuk ini.
Torsten Bronger
penjelasan apa?
Jeryl Cook
1
Solusi canggih lainnya adalah kombinasi keduanya. menambahkan anotasi dan pengaturan ImagePullPolicysebagai Selalu . penjelasan seperti deployment.kubernetes.io/revision: "v-someversion"dan kubernetes.io/change-cause: the reasonbisa sangat membantu dan menuju penyebaran yang tidak dapat diubah.
chandan
16

Akan ada perintah baru untuk langsung melakukan itu:

Buat kubectl rollout restartperintah baru yang melakukan restart bergulir dari penerapan.

The tarik permintaan Got digabung. Ini akan menjadi bagian dari versi 1.15( changelog )

S.Spieker
sumber
Ya bagian dari Masalah: github.com/kubernetes/kubernetes/issues/13488
Tilo
Ya, ini adalah cara terbaik untuk memicu pembaruan di kubernet baru versi 1.15.
Dolphin
7

Rupanya sekarang ketika Anda menjalankan pembaruan bergulir dengan --imageargumen yang sama dengan gambar kontainer yang ada, Anda juga harus menentukan --image-pull-policy. Perintah berikut harus memaksa tarikan gambar ketika itu sama dengan gambar wadah:

kubectl rolling-update myapp --image=us.gcr.io/project-107012/myapp:5c3dda6b --image-pull-policy Always

sjking
sumber
6
# Linux

kubectl patch deployment <name> -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

# windows

kubectl patch deployment <name> -p (-join("{\""spec\"":{\""template\"":{\""metadata\"":{\""annotations\"":{\""date\"":\""" , $(Get-Date -Format o).replace(':','-').replace('+','_') , "\""}}}}}"))
Bar Nuri
sumber
3

Sekarang, perintah yang kubectl rollout restart deploy YOUR-DEPLOYMENTdikombinasikan dengan imagePullPolicy: Alwayskebijakan akan memungkinkan Anda untuk me-restart semua pod Anda dengan versi terbaru dari gambar Anda.

Orabîg
sumber
3

Perintah pembaruan bergulir, ketika diberikan argumen gambar, mengasumsikan bahwa gambar berbeda dari apa yang saat ini ada di pengontrol replikasi.

Robert Bailey
sumber
Apakah ini berarti tag gambar (alias nama) harus berbeda?
Torsten Bronger
Ya, nama gambar harus berbeda jika Anda melewati --imagebendera.
Robert Bailey
1
Seperti jawaban saya sendiri mengatakan, itu berfungsi juga jika nama gambarnya sama. Itu hanya karena imagePullPolicy berada di tempat yang salah. Untuk pertahanan saya, dokumen k8s 1.0 salah dalam aspek ini.
Torsten Bronger
Harus cinta ketika dokumen tidak sinkron dengan perilaku. : /
Robert Bailey
1
Url itu sudah usang juga.
Dan Tenenbaum
2

Anda dapat menentukan imagePullPolicy: Alwaysdalam file penempatan Anda.

Sachin Arote
sumber
0

Kebijakan tarik Gambar akan selalu benar-benar membantu menarik gambar setiap kali pod baru dibuat (ini bisa berupa penskalaan replika, atau pod dies dan pod baru dibuat)

Tetapi jika Anda ingin memperbarui gambar pod yang sedang berjalan, penerapan adalah cara terbaik. Ini membuat Anda tanpa cacat pembaruan tanpa masalah (terutama ketika Anda memiliki volume persisten terpasang ke pod) :)

Harish Desetti
sumber