Kubernetes cách thực hiện Triển khai để cập nhật hình ảnh


131

Tôi có triển khai với một nhóm duy nhất, với hình ảnh docker tùy chỉnh của tôi như:

containers:
  - name: mycontainer
    image: myimage:latest

Trong quá trình phát triển, tôi muốn đẩy phiên bản mới nhất mới nhất và cập nhật Triển khai. Không thể tìm thấy cách thực hiện điều đó mà không xác định rõ ràng thẻ / phiên bản và tăng nó cho mỗi bản dựng, và làm

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

Câu trả lời:


151

Bạn có thể định cấu hình nhóm của mình với thời gian gia hạn (ví dụ: 30 giây trở lên, tùy thuộc vào thời gian khởi động vùng chứa và kích thước hình ảnh) và đặt "imagePullPolicy: "Always". Và sử dụng kubectl delete pod pod_name. Một vùng chứa mới sẽ được tạo và hình ảnh mới nhất tự động tải xuống, sau đó vùng chứa cũ sẽ kết thúc.

Thí dụ:

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

Tôi hiện đang sử dụng Jenkins cho các bản dựng tự động và gắn thẻ hình ảnh và nó trông giống như sau:

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

Một mẹo khác là chạy phức tạp:

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

và sau đó:

kubectl set image deployment/my-deployment mycontainer=myimage

Nó thực sự sẽ kích hoạt cập nhật lần lượt nhưng hãy chắc chắn rằng bạn cũng đã imagePullPolicy: "Always"thiết lập.

Cập nhật:

một mẹo khác mà tôi đã tìm thấy, nơi bạn không phải thay đổi tên hình ảnh, là thay đổi giá trị của trường sẽ kích hoạt cập nhật liên tục, chẳng hạn như terminationGracePeriodSeconds. Bạn có thể thực hiện việc này bằng cách sử dụng kubectl edit deployment your_deploymenthoặc kubectl apply -f your_deployment.yamlhoặc sử dụng một bản vá như sau:

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

Chỉ cần đảm bảo rằng bạn luôn thay đổi giá trị số.


1
Trên thực tế, đó là thủ thuật của bạn không tồi, xem xét myimage: lastet và myimage về cơ bản giống nhau, cảm ơn!
tàu vào

1
Thủ thuật này có vẻ giống một lỗi hơn, không rõ tại sao chúng ta cần chỉ định nó hai lần.
bay cao tốc

2
Nếu bạn muốn triển khai kubernetes bắt đầu một nhóm mới bằng cách sử dụng cùng một hình ảnh (và thủ thuật này chỉ hoạt động với thẻ "mới nhất"), bạn phải chỉ định nó mà không có thẻ. Lần tới, hãy thêm thẻ "mới nhất" và nó sẽ kích hoạt cập nhật. Thứ tự có thể được đảo ngược, nó không quan trọng. Bạn không bao giờ sử dụng thẻ "mới nhất" trong quá trình sản xuất, nhưng vì mục đích phát triển, đôi khi bạn có thể hưởng lợi từ nó.
Camil

2
Nó chỉ hoạt động cho mới nhất. Theo mặc định, ít nhất là trong trung tâm docker, bằng cách không gắn thẻ hình ảnh, nó sẽ giả sử là thẻ "mới nhất". Nhưng cũng sẽ hoạt động nếu không có nó. Ví dụ này không phải là thứ bạn muốn trong môi trường sản xuất và không có nhiều trường hợp sử dụng mà bạn cũng có thể hưởng lợi từ nó trong quá trình phát triển. Có nhiều phương pháp tốt hơn để cập nhật hình ảnh tự động, sử dụng công cụ CI / CD.
Camil

11
Mỗi khi bạn thay đổi thẻ và kubectl set imagelệnh chạy , kubernetes sẽ thực hiện cập nhật liên tục. Ví dụ: giả sử bạn đã triển khai "repo / myimage: mới nhất". Trong khi đó, hình ảnh của bạn đã được thay đổi và được đẩy vào repo với thẻ "v0.2". Bạn có thể thực hiện cập nhật bằng cách chạy kubectl set image deployment/my-deployment mycontainer=myimage:v0.2Hình ảnh này cũng sẽ có thẻ "mới nhất".
Camil

73

CẬP NHẬT 2019-06-24

Dựa trên nhận xét @Jodiug nếu bạn có 1.15phiên bản, bạn có thể sử dụng lệnh:

kubectl rollout restart deployment/demo

Đọc thêm về vấn đề:

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


Có một cuộc thảo luận thú vị về chủ đề này trong dự án kubernetes GitHub. Xem sự cố: https://github.com/kubernetes/kubernetes/issues/33664

Từ các giải pháp được mô tả ở đó, tôi sẽ đề xuất một trong hai.

Đầu tiên

1. chuẩn bị triển khai

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. triển khai

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

Thứ hai (một lớp lót):

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

Tất nhiên imagePullPolicy: Alwayslà bắt buộc trên cả hai trường hợp.


Tìm thấy một thủ thuật liên quan khác. Nếu bạn chỉ thực hiện "triển khai khởi động lại triển khai kubectl" mà không chỉ định bất kỳ triển khai cụ thể nào thì tên đó sẽ thực hiện "tất cả" chúng.
Lennart Rolland

21
kubectl rollout restart deployment myapp

Đây là cách hiện tại để kích hoạt bản cập nhật luân phiên và giữ nguyên các bộ bản sao cũ cho các hoạt động khác được cung cấp bởi các bản cập nhật kubectl rollouttương tự.


@Prathameshdhanawade thao tác vá không có undolệnh hoặc tương đương.
Martin Peter

7

Tôi sử dụng Gitlab-CI để xây dựng hình ảnh và sau đó triển khai trực tiếp lên GCK. Nếu sử dụng một thủ thuật nhỏ gọn gàng để đạt được bản cập nhật liên tục mà không thay đổi bất kỳ cài đặt thực nào của vùng chứa, tức là thay đổi nhãn thành commit-short-sha hiện tại.

Lệnh của tôi trông như thế này:

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

Nơi bạn có thể sử dụng bất kỳ tên nào và bất kỳ giá trị nào cho nhãn miễn là nó thay đổi theo từng bản dựng.

Chúc vui vẻ!


6

Có vẻ như k8s mong đợi chúng tôi cung cấp một thẻ hình ảnh khác nhau cho mỗi lần triển khai. Chiến lược mặc định của tôi sẽ làm cho hệ thống CI tạo và đẩy những hình ảnh Docker, gắn thẻ cho họ với số lượng xây dựng: xpmatteo/foobar:456.

Để phát triển cục bộ, có thể thuận tiện khi sử dụng script hoặc makefile, như sau:

# 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

Các sedlệnh thay thế một placeholder trong tài liệu triển khai với các thẻ hình ảnh được tạo ra thực tế.


kubernetes không yêu cầu bạn cập nhật việc triển khai bằng thẻ mới để lấy phiên bản mới nhất của bất kỳ hình ảnh nào, "mới nhất" là ví dụ phổ biến nhất.
Dave White

1

Tôi đang sử dụng Azure DevOps để triển khai các ứng dụng container, tôi có thể dễ dàng khắc phục sự cố này bằng cách sử dụng ID bản dựng

Mỗi khi nó xây dựng và tạo ID bản dựng mới, tôi sử dụng ID bản dựng này làm thẻ cho hình ảnh docker, đây là ví dụ

imagename: buildID

sau khi hình ảnh của bạn được tạo (CI) thành công, trong đường dẫn CD trong tệp yml triển khai, tôi đã đặt tên hình ảnh là

imagename: env: buildID

ở đây evn: buildid là biến azure devops có giá trị là build ID.

vì vậy bây giờ mỗi khi tôi có những thay đổi mới để xây dựng (CI) và triển khai (CD).

xin vui lòng bình luận nếu bạn cần xây dựng định nghĩa cho CI / CD.


Tệp kê khai là một phần của repo. Tôi không hiểu các phương pháp hay nhất cho việc này là gì. Nếu tôi tạo hình ảnh trong đường dẫn, tôi có nên đẩy để làm chủ tệp kê khai được cập nhật không? hay tôi nên tạo một tệp kê khai cập nhật cho các tạo tác (và do đó, tệp kê khai trong kho sẽ chỉ là một mẫu không có hình ảnh được gắn thẻ thực tế)?
pablete
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.