Làm cách nào để buộc Kubernetes kéo lại hình ảnh?


160

Tôi có bộ điều khiển sao chép sau trong Kubernetes trên 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

Bây giờ, nếu tôi nói

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

cập nhật cán được thực hiện, nhưng không kéo lại. Tại sao?


12
Tôi đã đưa ra một hình ảnh khác nhau, chỉ với cùng một thẻ. Nếu cần phải đưa ra một thẻ khác, tốt, tôi thấy không có điểm nào trong imagePullPolicytrường.
Torsten Bronger

4
Tôi muốn sử dụng một thẻ cụ thể, nhưng phiên bản mới nhất của nó.
Torsten Bronger

3
@TorstenBronger Tôi nghĩ rằng đây là một thay đổi đột phá trong lý thuyết Kubernetes / Docker. Ý tưởng rằng bạn có thể kéo hình ảnh: tag (không phải mới nhất) vào hai thời điểm khác nhau và nhận được hai hình ảnh khác nhau sẽ có vấn đề. Thẻ gần giống với số phiên bản. Sẽ tốt hơn nếu bạn luôn thay đổi thẻ khi hình ảnh thay đổi.
duct_tape_coder

2
Nó phụ thuộc. Có phần mềm với API rất ổn định nhưng cập nhật bảo mật. Sau đó, tôi muốn phiên bản mới nhất mà không cần phải nói quá rõ ràng.
Torsten Bronger

1
@TorstenBronger Về việc sử dụng latest, đừng làm điều đó. Mới nhất sẽ kéo hình ảnh, tốt, gần đây hơn với thẻ mới nhất. Những gì bạn muốn là một phạm vi SemVer. ~ 1.2.3 chẳng hạn. điều này sẽ kéo hình ảnh với các thẻ nằm trong phạm vi> = 1.2.3 và <1.3.0. Miễn là nhà cung cấp hình ảnh tuân theo SemVer bạn biết (và đây là phần quan trọng) không có thay đổi đột phá ngược nào được thêm vào (về mục đích) và không có tính năng mới nào được thêm vào (có thể có vấn đề bảo mật). Xin vui lòng, không bao giờ sử dụng latesttrong các hệ thống sản xuất.
David J Eddy

Câu trả lời:


140

Kubernetes sẽ kéo theo việc tạo Pod nếu một trong hai (xem tài liệu hình ảnh cập nhật ):

  • Sử dụng hình ảnh được gắn thẻ :latest
  • imagePullPolicy: Always được quy định

Điều này là tuyệt vời nếu bạn muốn luôn luôn kéo. Nhưng nếu bạn muốn làm theo yêu cầu : Ví dụ: nếu bạn muốn sử dụng some-public-image:latestnhưng chỉ muốn kéo một phiên bản mới hơn bằng tay khi bạn yêu cầu. Hiện tại bạn có thể:

  • Đặt imagePullPolicythành IfNotPresenthoặc Neverkéo trước : Kéo hình ảnh thủ công trên mỗi nút cụm sao cho mới nhất được lưu vào bộ đệm, sau đó thực hiện kubectl rolling-updatehoặc tương tự để khởi động lại Pods (hack dễ bị hỏng!)
  • Thay đổi tạm thờiimagePullPolicy , thực hiện a kubectl apply, khởi động lại nhóm (ví dụ kubectl rolling-update), hoàn nguyên imagePullPolicy, làm lại một kubectl apply(xấu xí!)
  • Kéo và đẩy some-public-image:latest vào kho lưu trữ riêng của bạn và thực hiện kubectl rolling-update(nặng!)

Không có giải pháp tốt cho kéo theo yêu cầu. Nếu điều đó thay đổi, xin vui lòng bình luận; Tôi sẽ cập nhật câu trả lời này.


Bạn nói rằng kubernetes sẽ kéo theo việc tạo Pod khi sử dụng :latest- còn patching thì sao? nó cũng luôn luôn kéo hình ảnh mới nhất / mới nhất? Có vẻ như không hoạt động đối với tôi :(
pkyeck

Nó phụ thuộc vào việc bản vá của bạn có buộc tạo lại Pod hay không. Nhiều khả năng là không, sau đó nó sẽ không kéo lại. Bạn có thể giết Pod bằng tay hoặc gắn thẻ với thứ gì đó độc đáo và vá với thẻ được cập nhật đó.
Wernight

Đây là một câu trả lời cho một câu hỏi khác nhau. Tôi yêu cầu buộc phải kéo lại.
Torsten Bronger

Điều này cho phép tôi buộc một lực kéo mới từ GCR. Tôi đã có một :latestthẻ chỉ vào một hình ảnh mới và kubectl rolling-updateđã làm việc để cập nhật các nhóm.
Randy L

Cảm ơn. Đã đi cho phương pháp kéo và đẩy. Tự động hóa càng nhiều càng tốt với các tập lệnh bash nhưng đồng ý, nó rất nặng :)
arcseldon

75

Người ta phải nhóm imagePullPolicybên trong dữ liệu container thay vì bên trong dữ liệu spec. Tuy nhiên, tôi đã nộp một vấn đề về điều này bởi vì tôi thấy nó kỳ lạ. Bên cạnh đó, không có thông báo lỗi.

Vì vậy, đoạn thông số kỹ thuật này hoạt động:

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

3
imagePullPolicy(hoặc gắn thẻ :latest) là tốt nếu bạn muốn luôn luôn kéo, nhưng không giải quyết được câu hỏi về việc kéo theo yêu cầu.
Wernight 11/03/2016

1
Có, tôi muốn luôn luôn kéo, như đã nêu trong câu hỏi.
Torsten Bronger

1
Sử dụng imagePullPolicy: Alwaysbên trong định nghĩa vùng chứa sẽ có các kuberneteshình ảnh được nạp được gắn thẻ :latestbất cứ khi nào một phiên bản mới hơn của chúng được đẩy vào sổ đăng ký?
pkaramol

1
@pkaramol số imagePullPolicy: Alwayschỉ đơn giản là bảo Kubernetes luôn lấy hình ảnh từ sổ đăng ký. Hình ảnh nào nó sẽ được cấu hình bởi imagethuộc tính. Nếu bạn định cấu hình nó image: your-image:latest, thì nó sẽ luôn kéo your-imagehình ảnh bằng latestthẻ.
Gajus

25

Cách hack của tôi trong quá trình phát triển là thay đổi bảng kê khai Triển khai của tôi để thêm thẻ mới nhất và luôn luôn kéo như vậy

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

Sau đó, tôi xóa pod bằng tay

kubectl delete pod my-app-3498980157-2zxhd

Vì là Triển khai, Kubernetes sẽ tự động tạo lại nhóm và kéo hình ảnh mới nhất.


Tôi thích tận dụng cơ sở "trạng thái mong muốn" của đối tượng "triển khai" ... cảm ơn vì lời đề nghị!
Marcello de Sales

2
Điều đáng chú ý là chiến lược chỉ khả thi nếu thất bại trong dịch vụ và thời gian chết là có thể chấp nhận được. Để phát triển có vẻ hợp lý, nhưng tôi sẽ không bao giờ thực hiện chiến lược này cho việc triển khai sản xuất.
Digitaldreamer

Chỉnh sửa triển khai, thay đổi imagePullPolicy thành luôn và xóa nhóm là đủ cho tôi, như Everett đề xuất. Đây là một môi trường phát triển mặc dù. kubernetes.io/docs/con accept /contersers / images
Jos Roberto Almaraz

17

Một cách giải quyết phổ biến là vá lỗi triển khai bằng một chú thích giả (hoặc nhãn):

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

Giả sử việc triển khai của bạn đáp ứng các yêu cầu này, điều này sẽ khiến K8 kéo bất kỳ hình ảnh mới nào và triển khai lại.


2
Vâng, tôi sử dụng một chú thích cho việc này.
Torsten Bronger

chú thích gì?
Jeryl Cook

1
Một giải pháp tinh vi khác sẽ là sự kết hợp của cả hai nghĩa là. thêm một chú thích và thiết lập ImagePullPolicyLuôn luôn . chú thích như deployment.kubernetes.io/revision: "v-someversion"kubernetes.io/change-cause: the reasoncó thể khá hữu ích và hướng tới việc triển khai bất biến.
chandan

15

Sẽ có một sự kết hợp mới để trực tiếp làm điều đó:

Tạo một kubectl rollout restartlệnh mới thực hiện khởi động lại khi triển khai.

Các pull yêu cầu Got sáp nhập. Nó sẽ là một phần của phiên bản 1.15( changelog )


Có một phần của Vấn đề: github.com/kubernetes/kubernetes/issues/13488
Tilo

Có, đây là cách tốt nhất để kích hoạt cập nhật trong phiên bản kubernetes mới của 1.15.
Cá heo

7

Rõ ràng bây giờ khi bạn chạy một bản cập nhật cuộn với --imageđối số giống như hình ảnh container hiện có, bạn cũng phải chỉ định một --image-pull-policy. Lệnh sau sẽ buộc kéo hình ảnh khi nó giống với hình ảnh chứa:

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

Bây giờ, lệnh kubectl rollout restart deploy YOUR-DEPLOYMENTkết hợp với một imagePullPolicy: Alwayschính sách sẽ cho phép bạn khởi động lại tất cả các nhóm với phiên bản mới nhất của hình ảnh của bạn.


3

Lệnh cập nhật cán, khi được đưa ra một đối số hình ảnh, giả định rằng hình ảnh khác với những gì hiện đang tồn tại trong bộ điều khiển sao chép.


Điều này có nghĩa là thẻ hình ảnh (tên còn gọi) phải khác nhau?
Torsten Bronger

Có, tên hình ảnh phải khác nếu bạn vượt qua --imagecờ.
Robert Bailey

1
Như câu trả lời của riêng tôi, nó cũng hoạt động nếu tên hình ảnh giống nhau. Nó chỉ đơn giản là imagePullPolicy đã ở sai vị trí. Để bảo vệ tôi, các tài liệu 1.0 của k8 là sai ở khía cạnh này.
Torsten Bronger

Phải yêu khi các tài liệu không đồng bộ với hành vi. : /
Robert Bailey

1
Url đó đã lỗi thời quá.
Dan Tenenbaum

2

Bạn có thể xác định imagePullPolicy: Alwaystrong tập tin triển khai của bạn.


0

Chính sách kéo hình ảnh sẽ luôn thực sự giúp kéo hình ảnh mỗi khi một nhóm mới được tạo (điều này có thể trong mọi trường hợp như nhân rộng các bản sao hoặc pod chết và pod mới được tạo)

Nhưng nếu bạn muốn cập nhật hình ảnh của nhóm đang chạy hiện tại, triển khai là cách tốt nhất. Nó giúp bạn cập nhật hoàn hảo mà không gặp vấn đề gì (chủ yếu là khi bạn có một khối lượng liên tục được gắn vào nhóm) :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.