Kubernet ทำอย่างไรให้ Deployment อัปเดตอิมเมจ


132

ฉันมีการปรับใช้กับพ็อดเดี่ยวด้วยอิมเมจนักเทียบท่าที่กำหนดเองของฉันเช่น:

containers:
  - name: mycontainer
    image: myimage:latest

ในระหว่างการพัฒนาฉันต้องการพุชเวอร์ชันล่าสุดใหม่และอัปเดตการปรับใช้ ไม่พบวิธีการทำเช่นนั้นโดยไม่ได้กำหนดแท็ก / เวอร์ชันอย่างชัดเจนและเพิ่มขึ้นสำหรับแต่ละบิลด์และทำ

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

คำตอบ:


151

คุณสามารถกำหนดค่าฝักของคุณด้วยระยะเวลาผ่อนผัน (ตัวอย่างเช่น 30 วินาทีหรือมากกว่าขึ้นอยู่กับเวลาเริ่มต้นของภาชนะบรรจุและขนาดของภาพ) "imagePullPolicy: "Always"และการตั้งค่า และการใช้งานkubectl delete pod pod_name. คอนเทนเนอร์ใหม่จะถูกสร้างขึ้นและดาวน์โหลดรูปภาพล่าสุดโดยอัตโนมัติจากนั้นคอนเทนเนอร์เก่าจะสิ้นสุดลง

ตัวอย่าง:

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

ฉันกำลังใช้ Jenkins สำหรับการสร้างและการแท็กรูปภาพโดยอัตโนมัติและมีลักษณะดังนี้:

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

เคล็ดลับอีกประการหนึ่งคือการรันขั้นต้น:

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

แล้ว:

kubectl set image deployment/my-deployment mycontainer=myimage

มันจะเรียกใช้การอัปเดตแบบต่อเนื่อง แต่ต้องแน่ใจว่าคุณได้imagePullPolicy: "Always"ตั้งค่าไว้ด้วย

ปรับปรุง:

เคล็ดลับอีกอย่างที่ฉันพบโดยที่คุณไม่ต้องเปลี่ยนชื่อรูปภาพคือการเปลี่ยนค่าของฟิลด์ที่จะทำให้เกิดการอัปเดตแบบterminationGracePeriodSecondsต่อเนื่องเช่น คุณสามารถทำได้โดยใช้kubectl edit deployment your_deploymentหรือkubectl apply -f your_deployment.yamlหรือใช้โปรแกรมแก้ไขดังนี้:

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

ตรวจสอบให้แน่ใจว่าคุณเปลี่ยนค่าตัวเลขอยู่เสมอ


1
จริงๆแล้วเคล็ดลับของคุณก็ไม่เลวเมื่อพิจารณาจาก myimage: lastet และ myimage โดยพื้นฐานแล้วขอบคุณ!
เหนืออาทิตย์

1
เคล็ดลับนี้ดูเหมือนบั๊กมากกว่าไม่แน่ใจว่าทำไมเราต้องระบุสองครั้ง
เครื่องบินเร็ว

2
หากคุณต้องการให้ kubernetes ใช้งานได้เพื่อเริ่มพ็อดใหม่โดยใช้อิมเมจเดียวกัน (และเคล็ดลับนี้ใช้ได้กับแท็ก "ล่าสุด" เท่านั้น) คุณต้องระบุโดยไม่มีแท็ก ครั้งต่อไปให้เพิ่มแท็ก "ล่าสุด" และจะเรียกการอัปเดต คำสั่งสามารถย้อนกลับได้ไม่สำคัญ คุณไม่เคยใช้แท็ก "ล่าสุด" ในการใช้งานจริง แต่ในบางครั้งคุณอาจได้รับประโยชน์จากแท็กนี้เพื่อวัตถุประสงค์ในการพัฒนา
Camil

2
ใช้ได้เฉพาะกับรุ่นล่าสุดเท่านั้น โดยค่าเริ่มต้นอย่างน้อยที่สุดใน Docker hub การไม่ติดแท็กรูปภาพจะถือว่าเป็นแท็ก "ล่าสุด" แต่ยังจะทำงานได้โดยไม่ต้องใช้มัน ตัวอย่างนี้ไม่ใช่สิ่งที่คุณต้องการในสภาพแวดล้อมการใช้งานจริงและมีกรณีการใช้งานไม่มากนักที่คุณจะได้รับประโยชน์จากการพัฒนาเช่นกัน มีวิธีการที่ดีกว่าในการอัปเดตรูปภาพโดยอัตโนมัติโดยใช้เครื่องมือ CI / CD
Camil

11
ทุกครั้งที่คุณเปลี่ยนแท็กและรันkubectl set imageคำสั่ง kubernetes จะทำการอัปเดตแบบต่อเนื่อง ตัวอย่างเช่นสมมติว่าคุณใช้งาน "repo / myimage: latest" ในขณะเดียวกันรูปภาพของคุณถูกเปลี่ยนและถูกผลักไปที่ repo ด้วยแท็ก "v0.2" คุณสามารถทำการอัปเดตโดยเรียกใช้kubectl set image deployment/my-deployment mycontainer=myimage:v0.2รูปภาพนี้จะมีแท็ก "ล่าสุด" ด้วย
Camil

74

อัพเดท 2019-06-24

อ้างอิงจากความคิดเห็น @Jodiug หากคุณมี1.15เวอร์ชันคุณสามารถใช้คำสั่ง:

kubectl rollout restart deployment/demo

อ่านเพิ่มเติมเกี่ยวกับปัญหา:

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


มีการอภิปรายที่น่าสนใจเกี่ยวกับเรื่องนี้ในโครงการ kubernetes GitHub ดูปัญหา: https://github.com/kubernetes/kubernetes/issues/33664

จากวิธีแก้ปัญหาที่อธิบายไว้ฉันขอแนะนำหนึ่งในสองข้อ

เป็นครั้งแรก

1. เตรียมการปรับใช้

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.Deploy

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

วินาที (หนึ่งซับ):

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

แน่นอนว่าimagePullPolicy: Alwaysจำเป็นสำหรับทั้งสองกรณี


พบเคล็ดลับอื่นที่เกี่ยวข้อง หากคุณเพียงแค่ทำการ "kubectl rollout restart deployment" โดยไม่ระบุชื่อการปรับใช้ใด ๆ มันจะทำ "ทั้งหมด"
Lennart Rolland

22
kubectl rollout restart deployment myapp

นี่เป็นวิธีการในปัจจุบันในการเรียกใช้การอัปเดตแบบต่อเนื่องและปล่อยชุดการจำลองแบบเก่าไว้สำหรับการดำเนินการอื่น ๆ ที่จัดทำโดยkubectl rolloutเช่นการย้อนกลับ


@Prathameshdhanawade การดำเนินการแก้ไขไม่มีundoคำสั่งหรือเทียบเท่า
Martin Peter

7

ฉันใช้ Gitlab-CI เพื่อสร้างอิมเมจจากนั้นปรับใช้กับ GCK โดยตรง หากใช้เคล็ดลับเล็ก ๆ น้อย ๆ ที่เป็นระเบียบเพื่อให้ได้การอัปเดตแบบต่อเนื่องโดยไม่เปลี่ยนการตั้งค่าจริงใด ๆ ของคอนเทนเนอร์ซึ่งกำลังเปลี่ยนป้ายกำกับเป็นคอมมิต - ชอร์ตปัจจุบัน

คำสั่งของฉันมีลักษณะดังนี้:

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

โดยคุณสามารถใช้ชื่อและค่าใดก็ได้สำหรับป้ายกำกับตราบใดที่มีการเปลี่ยนแปลงในแต่ละบิลด์

มีความสุข!


6

ดูเหมือนว่า k8s คาดหวังให้เราจัดเตรียมแท็กรูปภาพที่แตกต่างกันสำหรับการปรับใช้ทุกครั้ง กลยุทธ์เริ่มต้นของฉันคือการทำให้ระบบ CI สร้างและพุชอิมเมจนักเทียบท่าโดยติดแท็กด้วยหมายเลขบิลด์:xpmatteo/foobar:456สร้างและผลักดันภาพนักเทียบท่าที่ติดแท็กพวกเขาด้วยการสร้างจำนวน:

สำหรับการพัฒนาท้องถิ่นสามารถใช้สคริปต์หรือ makefile ได้อย่างสะดวกเช่นนี้:

# 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

sedคำสั่งแทนที่ตัวยึดตำแหน่งในเอกสารการใช้งานที่มีแท็กสร้างภาพที่เกิดขึ้นจริง


kubernetes ไม่ต้องการให้คุณอัปเดตการปรับใช้ด้วยแท็กใหม่เพื่อดึงภาพเวอร์ชันล่าสุด "ล่าสุด" เป็นตัวอย่างที่พบบ่อยที่สุด
Dave White

1

ฉันใช้ Azure DevOps เพื่อปรับใช้แอปพลิเคชันคอนเทนเนอร์ฉันสามารถจัดการเพื่อแก้ไขปัญหานี้ได้อย่างง่ายดายโดยใช้รหัสการสร้าง

ทุกครั้งที่สร้างและสร้างรหัสบิวด์ใหม่ฉันใช้รหัสการสร้างนี้เป็นแท็กสำหรับอิมเมจนักเทียบท่านี่คือตัวอย่าง

imagename: buildID

เมื่ออิมเมจของคุณสร้าง (CI) สำเร็จในท่อซีดีในไฟล์ yml การปรับใช้ฉันตั้งชื่ออิมเมจเป็น

imagename: env: buildID

ที่นี่ evn: buildid คือตัวแปร azure devops ซึ่งมีค่าของ build ID

ดังนั้นทุกครั้งที่ฉันมีการเปลี่ยนแปลงใหม่ในการสร้าง (CI) และปรับใช้ (CD)

โปรดแสดงความคิดเห็นหากคุณต้องการสร้างคำจำกัดความสำหรับ CI / CD


ไฟล์ Manifest เป็นส่วนหนึ่งของ repo ฉันไม่เข้าใจว่าแนวทางปฏิบัติที่ดีที่สุดสำหรับสิ่งนี้คืออะไร หากฉันสร้างอิมเมจในไปป์ไลน์ฉันควรกดเพื่อควบคุมไฟล์ Manifest ที่อัปเดตหรือไม่ หรือฉันควรสร้างรายการที่อัปเดตให้กับสิ่งประดิษฐ์ (ดังนั้นรายการใน repo จะเป็นเพียงเทมเพลตที่ไม่มีภาพที่ติดแท็กจริง)
pablete
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.