Kubernetesでイメージを更新するためのデプロイを行う方法


130

次のようなカスタムDockerイメージを使用して、単一のポッドで展開しています。

containers:
  - name: mycontainer
    image: myimage:latest

開発中、新しい最新バージョンをプッシュして、Deploymentを更新したいと考えています。タグ/バージョンを明示的に定義せずにその方法を見つけることができず、ビルドごとにインクリメントして、

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"されますが、設定も行っていることを確認してください。

更新:

画像名を変更する必要がないもう1つのトリックは、ローリング更新をトリガーするフィールドの値を変更することです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回指定する必要があるのか​​はわかりません。
スピードプレーン2017年

2
Kubernetesデプロイメントで同じイメージを使用して新しいポッドを開始する場合(このトリックは「最新」のタグでのみ機能します)、タグなしで指定する必要があります。次に「最新」のタグを追加すると、更新がトリガーされます。順序を逆にしてもかまいません。本番環境では「最新」のタグを使用することはありませんが、開発目的では、このタグを利用することができます。
Camil、2017年

2
それは最新のものでのみ機能します。デフォルトでは、少なくともdocker hubでは、画像にタグを付けないことにより、「最新」のタグを想定します。しかし、それなしでも動作します。この例は、本番環境では必要ないものであり、開発でもそれを活用できるユースケースは多くありません。CI / CDツールを使用してイメージを自動的に更新するより良い方法があります。
Camil 2017

11
タグを変更してkubectl set imageコマンドを実行するたびに、kubernetesはローリング更新を実行します。たとえば、「repo / myimage:latest」をデプロイしたとします。一方、イメージが変更され、「v0.2」タグを使用してリポジトリにプッシュされました。kubectl set image deployment/my-deployment mycontainer=myimage:v0.2このイメージを実行すると、更新を実行できます。このイメージには「最新」のタグが付けられます。
Camil 2017

73

更新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

そこで説明されている解決策から、私は2つのうちの1つを提案します。

最初

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.デプロイ

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

2番目(1つのライナー):

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

もちろん、imagePullPolicy: Always両方の場合に必要です。


関連する別のトリックを見つけました。特定のデプロイメント名を指定せずに単に「kubectl rollout restart deployment」を実行すると、それらの「すべて」が実行されます。
Lennart Rolland

20
kubectl rollout restart deployment myapp

これは、ローリング更新をトリガーし、古いレプリカセットをkubectl rollout同じようなロールバックによって提供される他の操作のために残しておく現在の方法です。


@Prathameshdhanawadeパッチ操作にはundoコマンドまたは同等の機能がありません。
マーティンピーター

7

Gitlab-CIを使用してイメージをビルドし、GCKに直接デプロイします。きちんとした小さなトリックを使用して、コンテナーの実際の設定を変更せずにローリング更新を実現します。つまり、ラベルを現在のcommit-short-shaに変更します。

私のコマンドは次のようになります:

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

ビルドごとに変更する限り、ラベルには任意の名前と値を使用できます。

楽しんで!


6

k8sはすべてのデプロイメントに異なるイメージタグを提供することを期待しているようです。私のデフォルトの戦略は、CIシステムにDockerイメージを生成してプッシュさせ、ビルド番号をタグ付けすることですxpmatteo/foobar:456

ローカル開発では、次のようにスクリプトまたはメイクファイルを使用すると便利です。

# 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では、イメージの最新バージョンをプルするためにデプロイメントを新しいタグで更新する必要はありません。「最新」が最も一般的な例です。
デイブホワイト

1

コンテナー化アプリケーションのデプロイにAzure DevOpsを使用していますが、ビルドIDを使用することでこの問題を簡単に克服できます

ビルドして新しいビルドIDを生成するたびに、このビルドIDをドッカーイメージのタグとして使用します。ここに例を示します。

imagename:buildID

イメージが正常にビルド(CI)されたら、展開ymlファイルのCDパイプラインで、次のようにイメージ名を指定します

imagename:env:buildID

ここでevn:buildidは、ビルドIDの値を持つazure devops変数です。

だから今私はbuild(CI)とdeploy(CD)に新しい変更を加えるたびに。

CI / CDのビルド定義が必要な場合はコメントしてください。


マニフェストはレポの一部です。これのベストプラクティスは何なのかわかりません。パイプラインでイメージをビルドする場合、更新されたマニフェストをマスターするためにプッシュする必要がありますか?または、アーティファクトに対して更新されたマニフェストを作成する必要がありますか(したがって、リポジトリ内のマニフェストは、実際のタグ付きイメージのない単なるテンプレートになります)?
pablete
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.