Kubernetes cara membuat Deployment untuk mengupdate image


131

Saya memiliki penerapan dengan pod tunggal, dengan gambar buruh pelabuhan kustom saya seperti:

containers:
  - name: mycontainer
    image: myimage:latest

Selama pengembangan, saya ingin meluncurkan versi terbaru dan membuat Deployment diperbarui. Tidak dapat menemukan cara melakukan itu, tanpa secara eksplisit menentukan tag / versi dan menaikkannya untuk setiap build, and do

kubectl set image deployment/my-deployment mycontainer=myimage:1.9.1

Jawaban:


151

Anda dapat mengonfigurasi pod Anda dengan masa tenggang (misalnya 30 detik atau lebih, bergantung pada waktu mulai container dan ukuran gambar) dan disetel "imagePullPolicy: "Always". Dan gunakan kubectl delete pod pod_name. Penampung baru akan dibuat dan gambar terbaru diunduh secara otomatis, kemudian penampung lama dihentikan.

Contoh:

spec:
  terminationGracePeriodSeconds: 30
  containers:
  - name: my_container
    image: my_image:latest
    imagePullPolicy: "Always"

Saat ini saya menggunakan Jenkins untuk pembuatan otomatis dan penandaan gambar dan tampilannya seperti ini:

kubectl --user="kube-user" --server="https://kubemaster.example.com"  --token=$ACCESS_TOKEN set image deployment/my-deployment mycontainer=myimage:"$BUILD_NUMBER-$SHORT_GIT_COMMIT"

Trik lain adalah menjalankan awal:

kubectl set image deployment/my-deployment mycontainer=myimage:latest

lalu:

kubectl set image deployment/my-deployment mycontainer=myimage

Ini sebenarnya akan memicu pembaruan bergulir tetapi pastikan Anda juga telah imagePullPolicy: "Always"mengaturnya.

Memperbarui:

Trik lain yang saya temukan, di mana Anda tidak perlu mengubah nama gambar, adalah mengubah nilai bidang yang akan memicu pembaruan berkelanjutan, seperti terminationGracePeriodSeconds. Anda dapat melakukan ini menggunakan kubectl edit deployment your_deploymentatau kubectl apply -f your_deployment.yamlatau menggunakan tambalan seperti ini:

kubectl patch deployment your_deployment -p \
  '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'

Pastikan Anda selalu mengubah nilai angka.


1
Sebenarnya trik anda lumayan lah, mengingat myimage: lastet dan myimage pada dasarnya sama saja, thanks!
matahari

1
Trik ini tampaknya lebih seperti bug, tidak yakin mengapa kita perlu menentukannya dua kali.
speedplane

2
Jika Anda ingin sebuah kubernetes menjalankan sebuah pod baru menggunakan image yang sama (dan trik ini hanya bekerja dengan tag "terbaru") Anda harus menentukannya tanpa sebuah tag. Lain kali tambahkan tag "terbaru" dan ini akan memicu pembaruan. Urutan bisa dibalik, tidak masalah. Anda tidak pernah menggunakan tag "terbaru" dalam produksi, tetapi untuk tujuan pengembangan Anda terkadang bisa mendapatkan keuntungan darinya.
Camil

2
Ini hanya bekerja untuk yang terbaru. Secara default, setidaknya di hub buruh pelabuhan, dengan tidak memberi tag pada gambar itu akan menganggap tag "terbaru". Tetapi juga akan bekerja tanpa itu. Contoh ini bukanlah sesuatu yang Anda inginkan dalam lingkungan produksi, dan tidak banyak kasus penggunaan di mana Anda juga dapat memanfaatkannya dalam pengembangan. Ada metode yang lebih baik untuk memperbarui gambar secara otomatis, menggunakan alat CI / CD.
Camil

11
Setiap kali Anda mengubah tag dan menjalankan kubectl set imageperintah, kubernetes akan melakukan pembaruan berkelanjutan. Misalnya, Anda menerapkan "repo / myimage: latest". Sementara itu gambar Anda telah diubah dan didorong ke repo dengan tag "v0.2". Anda dapat melakukan update dengan menjalankan kubectl set image deployment/my-deployment mycontainer=myimage:v0.2Gambar ini juga akan memiliki tag "terbaru".
Camil

73

UPDATE 2019-06-24

Berdasarkan komentar @Jodiug jika Anda memiliki 1.15versi, Anda dapat menggunakan perintah:

kubectl rollout restart deployment/demo

Baca lebih lanjut tentang masalah ini:

https://github.com/kubernetes/kubernetes/issues/13488


Nah ada pembahasan menarik tentang hal ini di proyek kubernetes GitHub. Lihat masalahnya: https://github.com/kubernetes/kubernetes/issues/33664

Dari solusi yang dijelaskan di sana, saya akan menyarankan satu dari dua solusi.

Pertama

1. Siapkan penerapan

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo
        image: registry.example.com/apps/demo:master
        imagePullPolicy: Always
        env:
        - name: FOR_GODS_SAKE_PLEASE_REDEPLOY
          value: 'THIS_STRING_IS_REPLACED_DURING_BUILD'

2. Terapkan

sed -ie "s/THIS_STRING_IS_REPLACED_DURING_BUILD/$(date)/g" deployment.yml
kubectl apply -f deployment.yml

Kedua (satu liner):

kubectl patch deployment web -p \
  "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"

Tentu saja imagePullPolicy: Alwaysdiperlukan pada kedua kasus tersebut.


Menemukan trik terkait lainnya. Jika Anda hanya melakukan "kubectl rollout restart deployment" tanpa menentukan nama deployment tertentu, ity akan melakukan "semua" dari semuanya.
Lennart Rolland

21
kubectl rollout restart deployment myapp

Ini adalah cara terkini untuk memicu pembaruan berkelanjutan dan membiarkan set replika lama di tempat untuk operasi lain yang disediakan oleh kubectl rolloutrollback seperti.


@Prathameshdhanawade operasi tambalan tidak memiliki undoperintah atau yang setara.
Martin Peter

7

Saya menggunakan Gitlab-CI untuk membangun image dan kemudian menerapkannya langsung ke GCK. Jika menggunakan trik kecil yang rapi untuk mencapai pembaruan berkelanjutan tanpa mengubah pengaturan nyata apa pun dari wadah, yang mengubah label menjadi commit-short-sha saat ini.

Perintah saya terlihat seperti ini:

kubectl patch deployment my-deployment -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"build\":\"$CI_COMMIT_SHORT_SHA\"}}}}}}"

Di mana Anda dapat menggunakan nama dan nilai apa pun untuk label asalkan berubah dengan setiap build.

Selamat bersenang-senang!


6

Tampaknya k8s mengharapkan kami memberikan tag gambar yang berbeda untuk setiap penerapan. Strategi default saya akan membuat sistem CI menghasilkan dan mendorong gambar buruh pelabuhan, penandaan mereka dengan nomor membangun: xpmatteo/foobar:456.

Untuk pengembangan lokal, akan lebih mudah menggunakan skrip atau makefile, seperti ini:

# create a unique tag    
VERSION:=$(shell date +%Y%m%d%H%M%S)
TAG=xpmatteo/foobar:$(VERSION)

deploy:
    npm run-script build
    docker build -t $(TAG) . 
    docker push $(TAG)
    sed s%IMAGE_TAG_PLACEHOLDER%$(TAG)% foobar-deployment.yaml | kubectl apply -f - --record

The sedperintah menggantikan placeholder dalam dokumen penyebaran dengan tag gambar yang dihasilkan sebenarnya.


kubernetes tidak mengharuskan Anda untuk memperbarui penerapan dengan tag baru untuk mendapatkan versi terbaru dari setiap gambar, "terbaru" adalah contoh yang paling umum.
Dave White

1

Saya menggunakan Azure DevOps untuk menyebarkan aplikasi containerize, saya dengan mudah mengelola untuk mengatasi masalah ini dengan menggunakan build ID

Setiap kali membangun dan menghasilkan ID Build baru, saya menggunakan ID build ini sebagai tag untuk gambar buruh pelabuhan di sini adalah contohnya

imagename: buildID

setelah gambar Anda berhasil dibangun (CI), di pipeline CD dalam penyebaran file yml saya telah memberi nama gambar sebagai

imagename: env: buildID

di sini evn: buildid adalah variabel azure devops yang memiliki nilai ID build.

jadi sekarang setiap kali saya memiliki perubahan baru untuk membangun (CI) dan menyebarkan (CD).

tolong beri komentar jika Anda membutuhkan definisi build untuk CI / CD.


Manifes adalah bagian dari repo. Saya tidak mengerti apa praktik terbaik untuk ini. Jika saya membuat gambar di pipeline, haruskah saya mendorong untuk menguasai manifes yang diperbarui? atau haruskah saya membuat manifes yang diperbarui ke artefak (dan dengan demikian manifes di repo hanya akan menjadi template tanpa gambar yang diberi tag sebenarnya)?
pablete
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.