ฉันจะบังคับให้ Kubernetes ดึงภาพใหม่ได้อย่างไร


161

ฉันมีตัวควบคุมการจำลองแบบต่อไปนี้ใน Kubernetes บน 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

ตอนนี้ถ้าฉันพูด

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

มีการดำเนินการอัพเดท แต่ไม่มีการดึงซ้ำ ทำไม?


12
ฉันให้ภาพที่แตกต่างเพียงแค่มีแท็กเดียวกัน หากจำเป็นต้องให้แท็กที่ต่างออกไปฉันก็ไม่เห็นจุดใด ๆ ในimagePullPolicyฟิลด์
Torsten Bronger

4
ฉันต้องการใช้แท็กเฉพาะ แต่เป็นรุ่นใหม่ล่าสุด
Torsten Bronger

3
@ TorstenBronger ฉันคิดว่านี่เป็นความเปลี่ยนแปลงครั้งใหญ่ในทฤษฎี Kubernetes / Docker แนวคิดที่ว่าคุณสามารถดึงภาพ: แท็ก (นอกเหนือจากล่าสุด) ในสองช่วงเวลาที่แตกต่างกันและการได้รับสองภาพที่แตกต่างกันนั้นอาจเป็นปัญหาได้ แท็กคล้ายกับหมายเลขเวอร์ชัน มันจะเป็นการดีกว่าถ้าจะเปลี่ยนแท็กเมื่อภาพเปลี่ยนแปลง
duct_tape_coder

2
มันขึ้นอยู่กับ. มีซอฟต์แวร์ที่มี API ที่เสถียรมาก แต่มีการอัพเดทความปลอดภัย จากนั้นฉันต้องการเวอร์ชันล่าสุดโดยไม่ต้องพูดอย่างชัดเจน
Torsten Bronger

1
@TorstenBronger เกี่ยวกับการใช้latestไม่ต้องทำ ล่าสุดจะดึงรูปภาพที่มีแท็กล่าสุด สิ่งที่คุณต้องการคือช่วง SemVer ตัวอย่างเช่น ~ 1.2.3 สิ่งนี้จะดึงภาพด้วยแท็กระหว่างช่วง> = 1.2.3 และ <1.3.0 ตราบใดที่ผู้ขายภาพตามSemVerคุณก็รู้ (และนี่คือส่วนที่สำคัญ) ไม่มีการเปลี่ยนแปลงการแบ่งย้อนหลัง (ตามวัตถุประสงค์) และไม่มีการเพิ่มคุณสมบัติใหม่ (อาจเป็นไปได้เกี่ยวกับความปลอดภัย) กรุณาอย่าใช้latestในระบบการผลิต
David J Eddy

คำตอบ:


141

Kubernetes จะดึงการสร้าง Pod หากมี (ดูที่เอกสารการปรับปรุงภาพ ):

  • กำลังใช้ภาพที่ติดแท็ก :latest
  • imagePullPolicy: Always ระบุไว้

มันดีมากถ้าคุณต้องการดึงเสมอ แต่ถ้าคุณต้องการทำตามความต้องการ : ตัวอย่างเช่นถ้าคุณต้องการใช้some-public-image:latestแต่ต้องการดึงเวอร์ชันที่ใหม่กว่าด้วยตนเองเมื่อคุณขอ คุณสามารถ:

  • ชุดimagePullPolicyไปIfNotPresentหรือNeverและดึงก่อน : ดึงภาพด้วยตนเองในแต่ละโหนดคลัสเตอร์ดังนั้นล่าสุดแคชแล้วทำkubectl rolling-updateหรือคล้ายกับการเริ่มต้นใหม่ฝัก (น่าเกลียดสับหักได้อย่างง่ายดาย!)
  • เปลี่ยนชั่วคราวimagePullPolicyทำ a kubectl apply, รีสตาร์ทพ็อด (เช่นkubectl rolling-update) เปลี่ยนกลับimagePullPolicyทำซ้ำ a kubectl apply(น่าเกลียด!)
  • ดึงและดัน some-public-image:latestไปยังที่เก็บส่วนตัวของคุณและทำkubectl rolling-update(หนัก!)

ไม่มีทางออกที่ดีสำหรับการดึงตามความต้องการ หากมีการเปลี่ยนแปลงโปรดแสดงความคิดเห็น; ฉันจะอัปเดตคำตอบนี้


คุณบอกว่า kubernetes จะดึงการสร้าง Pod เมื่อใช้:latest- แล้วpatchไอเอ็นจีล่ะ? มันดึงภาพใหม่ล่าสุด / ล่าสุดหรือไม่? ดูเหมือนจะไม่ทำงานกับฉัน :(
pkyeck

ขึ้นอยู่กับว่าแพทช์ของคุณบังคับให้สร้าง Pod ขึ้นมาใหม่หรือไม่ ส่วนใหญ่แล้วจะไม่ดึงอีกครั้ง คุณอาจฆ่า Pod ด้วยตนเองหรือแท็กด้วยสิ่งที่ไม่ซ้ำกันและแก้ไขด้วยแท็กที่อัปเดต
Wernight

นี่คือคำตอบสำหรับคำถามอื่น ฉันขอบังคับให้ดึงอีกครั้ง
Torsten Bronger

สิ่งนี้ทำให้ฉันสามารถบังคับให้ดึงใหม่จาก GCR ฉันมี:latestแท็กซึ่งชี้ไปที่ภาพใหม่และkubectl rolling-updateทำงานเพื่ออัปเดตพ็อด
แรนดี้ L

ขอบคุณ ไปสำหรับวิธีการดึงและดัน อัตโนมัติมากของมันเป็นไปได้ด้วยสคริปต์ทุบตี แต่ไม่เห็นด้วยก็หนัก :)
arcseldon

77

หนึ่งมีการจัดกลุ่มimagePullPolicyภายในข้อมูลภาชนะแทนที่จะเป็นข้อมูลจำเพาะภายใน อย่างไรก็ตามฉันได้ยื่นปัญหาเกี่ยวกับเรื่องนี้เพราะฉันพบว่ามันแปลก นอกจากนี้ไม่มีข้อผิดพลาด

ดังนั้นข้อมูลจำเพาะนี้จึงใช้งานได้:

spec:
  containers:
  - name: myapp
    image: myregistry.com/myapp:5c3dda6b
    ports:
    - containerPort: 80
    imagePullPolicy: Always
  imagePullSecrets:
    - name: myregistry.com-registry-key

3
imagePullPolicy(หรือติดแท็ก:latest) เป็นสิ่งที่ดีถ้าคุณต้องการดึงเสมอ แต่ไม่ได้แก้ปัญหาการดึงความต้องการ
Wernight

1
ใช่ฉันต้องการดึงเสมอตามที่ระบุไว้ในคำถาม
Torsten Bronger

1
การใช้imagePullPolicy: Alwaysภายในคำจำกัดความของคอนเทนเนอร์จะkubernetesดึงภาพที่ติดแท็ก:latestเมื่อใดก็ตามที่มีการส่งเวอร์ชันที่ใหม่กว่าไปยังรีจิสตรี
pkaramol

1
@pkaramol ไม่ได้imagePullPolicy: Alwaysบอกให้ Kubernetes ดึงภาพจากรีจิสตรีเสมอ รูปภาพใดจะถูกกำหนดค่าโดยimageแอตทริบิวต์ หากคุณกำหนดค่าให้image: your-image:latestมันจะดึงyour-imageภาพด้วยlatestแท็กเสมอ
Gajus

26

การแฮ็คของฉันในระหว่างการพัฒนาคือการเปลี่ยนรายการการปรับใช้เพื่อเพิ่มแท็กล่าสุดและดึงอย่างนั้น

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

จากนั้นฉันก็ลบพ็อดด้วยตนเอง

kubectl delete pod my-app-3498980157-2zxhd

เนื่องจากเป็นการปรับใช้ Kubernetes จะสร้างพ็อดใหม่โดยอัตโนมัติและดึงรูปภาพล่าสุด


ฉันชอบการใช้ประโยชน์จาก "สถานะที่ต้องการ" ของวัตถุ "การปรับใช้" ... ขอบคุณสำหรับคำแนะนำ!
Marcello de Sales

2
เป็นที่น่าสังเกตว่ากลยุทธ์นั้นจะสามารถทำงานได้ก็ต่อเมื่อความล้มเหลวในการให้บริการและการหยุดทำงานนั้นเป็นสิ่งที่ยอมรับได้ สำหรับการพัฒนาดูเหมือนสมเหตุสมผล แต่ฉันจะไม่ใช้กลยุทธ์นี้ในการปรับใช้การผลิต
digitaldreamer

แก้ไขการปรับใช้เปลี่ยน imagePullPolicy เป็นเสมอและการลบพ็อดก็เพียงพอแล้วสำหรับฉันตามที่ Everett แนะนำ นี่คือสภาพแวดล้อมการพัฒนาแม้ว่า kubernetes.io/docs/concepts/containers/images
Jos Roberto Almaraz

17

วิธีแก้ปัญหาที่เป็นที่นิยมคือการแก้ไขการใช้งานที่มีคำอธิบายประกอบหุ่น (หรือฉลาก):

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

สมมติว่าการปรับใช้ของคุณตรงตามข้อกำหนดเหล่านี้จะทำให้ K8s ดึงภาพใหม่และปรับใช้ใหม่


2
ใช่ฉันใช้คำอธิบายประกอบสำหรับสิ่งนี้
Torsten Bronger

คำอธิบายประกอบอะไร
Jeryl Cook

1
อีกวิธีที่ซับซ้อนจะเป็นการรวมกันของทั้งสองอย่าง เพิ่มคำอธิบายประกอบและการตั้งค่าImagePullPolicyเป็นเสมอ คำอธิบายประกอบเช่นdeployment.kubernetes.io/revision: "v-someversion"และkubernetes.io/change-cause: the reasonสามารถเป็นประโยชน์มากและมุ่งสู่การปรับใช้ไม่เปลี่ยนรูป
chandan

16

จะมีเพื่อนใหม่ที่ทำสิ่งนั้นโดยตรง:

สร้างใหม่ kubectl rollout restartคำสั่งที่เริ่มต้นการปรับใช้ใหม่

คำขอดึงได้รวม มันจะเป็นส่วนหนึ่งของเวอร์ชั่น1.15( changelog )


ใช่ส่วนหนึ่งของปัญหา: github.com/kubernetes/kubernetes/issues/13488
Tilo

ใช่นี่เป็นวิธีที่ดีที่สุดในการกระตุ้นการอัพเดทใน verub kubernetes ใหม่ที่ 1.15
โลมา

7

เห็นได้ชัดว่าตอนนี้เมื่อคุณเรียกใช้การอัปเดตกลิ้งกับการโต้แย้งเช่นเดียวกับภาพคอนเทนเนอร์ที่มีอยู่คุณยังต้องระบุ--image --image-pull-policyคำสั่งต่อไปนี้ควรบังคับให้ดึงอิมเมจเมื่อมันเหมือนกับอิมเมจคอนเทนเนอร์:

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


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('+','_') , "\""}}}}}"))

3

ตอนนี้คำสั่งที่kubectl rollout restart deploy YOUR-DEPLOYMENTรวมกับimagePullPolicy: Alwaysนโยบายจะอนุญาตให้คุณรีสตาร์ทพ็อดทั้งหมดด้วยอิมเมจเวอร์ชันล่าสุด


3

คำสั่ง roll update เมื่อได้รับการโต้แย้งภาพถือว่าภาพแตกต่างจากสิ่งที่มีอยู่ในตัวควบคุมการจำลองแบบ


สิ่งนี้หมายความว่าแท็กรูปภาพ (ชื่ออาคา) จะต้องแตกต่างกันหรือไม่?
Torsten Bronger

ใช่ชื่อภาพจะต้องแตกต่างกันถ้าคุณผ่าน--imageธง
Robert Bailey

1
ตามคำตอบของฉันเองมันก็ใช้งานได้ถ้าชื่อภาพเหมือนกัน มันเป็นเพียงแค่ภาพ imagePullPolicy ผิดที่ ในการป้องกันของฉันเอกสาร k8s 1.0 นั้นผิดพลาดในด้านนี้
Torsten Bronger

ต้องรักเมื่อเอกสารไม่สอดคล้องกับพฤติกรรม : /
Robert Bailey

1
URL นั้นล้าสมัยไปแล้วเช่นกัน
Dan Tenenbaum


0

นโยบายการดึงภาพมักจะช่วยดึงภาพทุกครั้งที่มีการสร้างพ็อดใหม่ (ในกรณีใด ๆ เช่นการปรับขนาดแบบจำลองหรือพ็อดตายและพ็อดใหม่จะถูกสร้างขึ้น)

แต่ถ้าคุณต้องการอัปเดตอิมเมจของพ็อดที่กำลังทำงานอยู่การปรับใช้เป็นวิธีที่ดีที่สุด มันทำให้คุณอัปเดตอย่างไร้ที่ติไม่มีปัญหาใด ๆ (ส่วนใหญ่เมื่อคุณมีระดับเสียงถาวรที่แนบมากับฝัก) :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.