山岸  英樹

山岸 英樹

1636585560

Kubernetesでのデプロイ戦略

この記事では、Kubernetesコンテナオーケストレーションシステムを使用してコンテナをデプロイする際のデプロイメント戦略について学習します。この記事の最後で、Kubernetesクラスターでさまざまな方法を使用してデプロイを行う方法を学習しました。このトピックがおもしろいと思ったら、読み続けてください!このチュートリアルのコードは、Githubで入手できます。

Kubernetesの簡単な紹介

コンテナ化は時間の経過とともに人気を博し、アプリケーションの構築、出荷、保守のプロセスに革命をもたらしたため、これらのコンテナを効果的に管理する必要がありました。大規模システムでこれらのコンテナのライフサイクルを管理するために、多くのコンテナオーケストレーションツールが導入されました。

Kubernetesは、プロビジョニングとデプロイ、リソースの割り当て、負荷分散、サービスディスカバリ、高可用性の提供、その他のシステムの重要な側面を処理するオーケストレーションツールの1つです。このプラットフォームを使用すると、開発中にアプリケーションをより小さなシステム(マイクロサービスと呼ばれる)に分解できます。次に、展開中にこれらのシステムを一緒に構成(またはオーケストレーション)できます。

クラウドネイティブアプローチの採用により、マイクロサービスアーキテクチャに基づくアプリケーションの開発が増加しています。このようなアプリケーションの場合、組織が直面する最大の課題の1つは展開です。展開に関して適切な戦略を立てる必要があります。Kubernetesでは、アプリケーションをリリースするさまざまな方法があります。アプリケーションの展開または更新中にインフラストラクチャの信頼性を高めるには、適切な戦略を選択する必要があります。たとえば、実稼働環境では、エンドユーザーにダウンタイムが発生しないようにする必要が常にあります。Kubernetesオーケストレーションでは、適切な戦略により、さまざまなバージョンのコンテナイメージを適切に管理できます。要約すると、この記事では主にKubernetesでのさまざまなデプロイ戦略について説明します。

前提条件

この記事を続けるには、Kubernetesの使用経験が必要です。このプラットフォームを初めて使用する場合は、基本的なKubernetesコンセプトのステップバイステップの概要チュートリアルをご覧ください。そこでは、ここの指示に従うために必要なすべてを学ぶことができます。また、必要に応じて、Kubernetesのドキュメントを確認することをお勧めします。

さらに、ターミナルからクラスターを制御できるようにするコマンドラインインターフェイス(CLI)ツールであるkubectlが必要になります。このツールをお持ちでない場合は、Kube Control(kubectl)のインストールの手順を確認してください。LinuxとYAMLの基本的な理解も必要です。

Kubernetesでのデプロイとは何ですか?

デプロイは、プログラムの目的の状態を定義するKubernetesのリソースオブジェクトです。デプロイメントは宣言型です。つまり、状態を達成する方法を指示しません。代わりに、目的の状態を宣言し、Deployment-controllerが最も効率的な方法でその最終目標に自動的に到達できるようにします。デプロイにより、アプリに使用するイメージ、存在するポッドの数、更新方法など、アプリケーションのライフサイクルを記述できます。

Kubernetesデプロイメントを使用する利点

コンテナ化されたアプリケーションを手動で更新するプロセスは、時間と手間がかかる場合があります。Kubernetesのデプロイにより、このプロセスが自動化され、繰り返し可能になります。デプロイはKubernetesバックエンドによって完全に管理され、更新プロセス全体はクライアントとの対話なしでサーバー側で実行されます。

さらに、Kubernetesデプロイメントコントローラーは常にポッドとノードの状態を監視しています。障害が発生したポッドを置き換えるか、ノードをバイパスして、重要なアプリケーションの継続性を確保します。

展開戦略

ローリングアップデートの展開

ローリングデプロイメントは、Kubernetesのデフォルトのデプロイメント戦略です。これにより、以前のバージョンのアプリケーションのポッドが、クラスターのダウンタイムなしで新しいバージョンのポッドに1つずつ置き換えられます。ローリングデプロイメントは、以前のバージョンのアプリケーションのインスタンスを新しいバージョンのアプリケーションのインスタンスにゆっくりと置き換えます。

代替テキスト

RollingUpdate戦略を使用する場合、更新プロセスを微調整できるオプションがさらに2つあります。

maxSurge:更新中に必要な数のポッドを超えて作成できるポッドの数。これは、レプリカ数の絶対数またはパーセンテージにすることができます。デフォルトは25%です。

maxUnavailable:更新プロセス中に使用できなくなる可能性のあるポッドの数。これは、レプリカ数の絶対数またはパーセンテージにすることができます。デフォルトは25%です。

まず、rollingupdate.yamlデプロイメントテンプレートを作成します。以下のテンプレートでは、maxSurgeを2に設定し、maxUnavailableを1に設定しています。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rollingupdate-strategy
  version: nanoserver-1709
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  selector:
    matchLabels:
      app: web-app-rollingupdate-strategy
      version: nanoserver-1709
  replicas: 3
  template:
    metadata:
      labels:
        app: web-app-rollingupdate-strategy
        version: nanoserver-1709
    spec:
      containers:
        - name: web-app-rollingupdate-strategy
          image: hello-world:nanoserver-1709

次に、kubectlコマンドを使用してデプロイメントを作成できます。

$ kubectl apply -f rollingupdate.yaml

デプロイメントテンプレートを取得したら、サービスを作成してデプロイメントのインスタンスにアクセスする方法を提供できます。イメージhello-worldをバージョンnanoserver-1709でデプロイしていることに注意してください。したがって、この場合、「name = web-app-rollingupdate-strategy」と「version = nanoserver-1709」の2つのラベルがあります。これらを以下のサービスのラベルセレクターとして設定します。これを ' service.yaml 'ファイルに保存します。

apiVersion: v1
kind: Service
metadata: 
  name: web-app-rollingupdate-strategy
  labels: 
    name: web-app-rollingupdate-strategy
    version: nanoserver-1709
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: web-app-rollingupdate-strategy
    version: nanoserver-1709
  type: LoadBalancer

ここでサービスを作成すると、クラスターの外部からアクセスできるロードバランサーが作成されます。

$ kubectl apply -f service.yaml

kubectl get Deploymentsを実行して、Deploymentが作成されているかどうかを確認します。デプロイメントがまだ作成されている場合、出力は次のようになります。

$ kubectl get deployments

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
rollingupdate-strategy   0/3     0            0           1s

kubectlを実行すると、数秒後に再度デプロイメントを取得します。出力は次のようになります。

$ kubectl get deployments

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
rollingupdate-strategy   3/3     0            0           7s

デプロイメントによって作成されたReplicaSet(rs)を確認するには、kubectl getrsを実行します。出力は次のようになります。

$ kubectl get rs

NAME                                    DESIRED   CURRENT   READY   AGE
rollingupdate-strategy-87875f5897   3         3         3       18s

デプロイ用に実行されている3つのポッドを確認するには、kubectl getpodsを実行します。作成されたReplicaSetは、3つのポッドが実行されていることを確認します。出力は次のようになります。

$ kubectl get pods

NAME                                      READY     STATUS    RESTARTS   AGE       
rollingupdate-strategy-87875f5897-55i7o   1/1       Running   0          12s       
rollingupdate-strategy-87875f5897-abszs   1/1       Running   0          12s       
rollingupdate-strategy-87875f5897-qazrt   1/1       Running   0          12s

hello-world:nanoserver-1709イメージの代わりにhello-world:nanoserver-1809イメージを使用するようにrollingupdate.yamlデプロイメントテンプレートを更新しましょう。次に、kubectlコマンドを使用して、既存の実行中のデプロイメントのイメージを更新します。

$ kubectl set image deployment/rollingupdate-strategy web-app-rollingupdate-strategy=hello-world:nanoserver-1809 --record

出力は以下のようになります。

deployment.apps/rollingupdate-strategy image updated

現在、バージョンnanoserver-1809でイメージhello-worldをデプロイしています。したがって、この場合、「service.yaml」のラベルを更新する必要があります。ラベルは「version = nanoserver-1809」に更新されます。以下のkubectlコマンドを再度実行してサービスを更新し、新しいイメージで実行されている新しいポッドを選択できるようにします。

$ kubectl apply -f service.yaml

ロールアウトステータスを確認するには、以下のkubectlコマンドを実行します。

$ kubectl rollout status deployment/rollingupdate-strategy

Waiting for rollout to finish: 2 out of 3 new replicas have been updated...

もう一度実行して、ロールアウトが成功したことを確認します。

$ kubectl rollout status deployment/rollingupdate-strategy

deployment "rollingupdate-strategy" successfully rolled out

ロールアウトが成功したら、コマンドkubectl getdeploymentsを実行してデプロイメントを表示できます。出力は次のようになります。

$ kubectl get deployments

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
rollingupdate-strategy   3/3     0            0           7s

kubectl get rsを実行して、デプロイメントが更新されていることを確認します。新しいポッドは新しいReplicaSetで作成され、最大3つのレプリカにスケールアップされます。古いReplicaSetは0レプリカに縮小されます。

$ kubectl get rs

NAME                                    DESIRED   CURRENT   READY   AGE
rollingupdate-strategy-87875f5897   3         3         3       55s
rollingupdate-strategy-89999f7895   0         0         0       12s

kubectl get podsを実行すると、新しいReplicaSet内の新しいポッドのみが表示されます。

$ kubectl get pods

NAME                                      READY     STATUS    RESTARTS   AGE       
rollingupdate-strategy-89999f7895-55i7o   1/1       Running   0          12s       
rollingupdate-strategy-89999f7895-abszs   1/1       Running   0          12s       
rollingupdate-strategy-89999f7895-qazrt   1/1       Running   0          12s

ここでは、kubectlのrolloutコマンドが非常に役立ちます。これを使用して、デプロイメントがどのように行われているかを確認できます。このコマンドは、デフォルトで、デプロイメント内のすべてのポッドが正常に開始されるまで待機します。デプロイメントが成功すると、コマンドは終了し、成功を示す戻りコード0が返されます。展開が失敗した場合、コマンドはゼロ以外のコードで終了します。

$ kubectl rollout status deployment rollingupdate-strategy

Waiting for deployment "rollingupdate-strategy" rollout to finish: 0 of 3 updated replicas are available…
Waiting for deployment "rollingupdate-strategy" rollout to finish: 1 of 3 updated replicas are available…
Waiting for deployment "rollingupdate-strategy" rollout to finish: 2 of 3 updated replicas are available…

deployment "rollingupdate-strategy" successfully rolled out

Kubernetesでデプロイが失敗した場合、デプロイプロセスは停止しますが、失敗したデプロイのポッドは保持されます。デプロイメントが失敗すると、環境に古いデプロイメントと新しいデプロイメントの両方のポッドが含まれる場合があります。安定した動作状態に戻すには、rollout undoコマンドを使用して、動作中のポッドを元に戻し、失敗したデプロイメントをクリーンアップします。

$ kubectl rollout undo deployment rollingupdate-strategy

deployment.extensions/rollingupdate-strategy

次に、展開のステータスを再度確認します。

$ kubectl rollout status deployment rollingupdate-strategy

deployment "rollingupdate-strategy" successfully rolled out

Kubernetesがアプリケーションの準備ができたことを知るには、アプリケーションの助けが必要です。Kubernetesは、準備プローブを使用して、アプリケーションの動作を調べます。アプリケーションインスタンスが準備プローブに肯定応答で応答し始めると、インスタンスは使用可能であると見なされます。準備プローブは、アプリケーションの準備ができたときにKubernetesに通知しますが、アプリケーションの準備ができるかどうかは通知しません。アプリケーションが失敗し続ける場合、Kubernetesに対して肯定的な応答で応答しない可能性があります。

ローリングデプロイメントは通常、古いコンポーネントをスケールダウンする前に、準備チェックによって新しいポッドの準備が整うのを待ちます。重大な問題が発生した場合は、ローリングデプロイメントを中止できます。問題がある場合は、クラスター全体を停止せずに、ローリング更新またはデプロイメントを中止できます。

デプロイメントを再作成する

再作成デプロイメントでは、新しいアプリケーションバージョンをスケールアップする前に、既存のアプリケーションバージョンを完全にスケールダウンします。次の図では、バージョン1は現在のアプリケーションのバージョンを表し、バージョン2は新しいアプリケーションのバージョンを表します。現在のアプリケーションバージョンを更新するときは、最初にバージョン1の既存のレプリカをゼロにスケールダウンしてから、新しいバージョンでレプリカを同時にデプロイします。

代替テキスト

以下のテンプレートは、再作成戦略を使用したデプロイを示しています。まず、次のyamlをファイルrecreate.yamlに保存して、再作成デプロイメントを作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: recreate-strategy
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: web-app-recreate-strategy
      version: nanoserver-1809
  replicas: 3
  template:
    metadata:
      labels:
        app: web-app-recreate-strategy
    spec:
      containers:
        - name: web-app-recreate-strategy
          image: hello-world:nanoserver-1809

次に、kubectlコマンドを使用してデプロイメントを作成できます。

$ kubectl apply -f recreate.yaml

デプロイメントテンプレートを取得したら、サービスを作成してデプロイメントのインスタンスにアクセスする方法を提供できます。イメージhello-worldをバージョンnanoserver-1809でデプロイしていることに注意してください。したがって、この場合、「name = web-app-recreate-strategy」と「version = nanoserver-1809」の2つのラベルがあります。これらを以下のサービスのラベルセレクターとして設定します。これをservice.yamlファイルに保存します。

apiVersion: v1
kind: Service
metadata: 
  name: web-app-recreate-strategy
  labels: 
    name: web-app-recreate-strategy
    version: nanoserver-1809
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: web-app-recreate-strategy
    version: nanoserver-1809
  type: LoadBalancer

ここでサービスを作成すると、クラスターの外部からアクセスできるロードバランサーが作成されます。

$ kubectl apply -f service.yaml

recreateメソッドには、更新プロセス中にダウンタイムが発生します。メンテナンスウィンドウや停止を処理できるアプリケーションでは、ダウンタイムは問題になりません。ただし、高いサービスレベルアグリーメント(SLA)と可用性要件を備えたミッションクリティカルなアプリケーションがある場合は、別の展開戦略を選択することが適切なアプローチになります。再作成デプロイメントは、セットアップが簡単で、アプリケーションの状態が新しいバージョンで完全に更新されるため、開発者は通常、開発段階で使用します。さらに、複数のアプリケーションバージョンを並行して管理する必要がないため、データとアプリケーションの下位互換性の問題を回避できます。

青緑色の展開

青/緑の展開戦略(赤/黒とも呼ばれる)では、青は現在のアプリケーションバージョンを表し、緑は新しいアプリケーションバージョンを表します。この場合、一度に1つのバージョンのみがライブになります。緑の展開が作成およびテストされている間、トラフィックは青の展開にルーティングされます。テストが終了したら、トラフィックを新しいバージョンにルーティングします。

デプロイメントが成功した後、ロールバックの可能性のために青いデプロイメントを維持するか、それを廃止することができます。または、これらのインスタンスに新しいバージョンのアプリケーションをデプロイすることもできます。その場合、現在の(青の)環境が次のリリースのステージング領域として機能します。

この手法により、展開戦略の再作成で直面したダウンタイムをなくすことができます。さらに、青緑の展開によりリスクが軽減されます。緑の新しいバージョンで予期しないことが発生した場合は、青に切り替えることで、すぐに最後のバージョンにロールバックできます。即時のロールアウト/ロールバックがあります。バージョン管理の問題を回避することもできます。1回のデプロイメントでアプリケーション全体の状態が変更されます。

代替テキスト

Blue-Greenの展開は、2倍のリソースを必要とするため、費用がかかります。プラットフォーム全体の適切なテストは、本番環境にリリースする前に実行する必要があります。さらに、ステートフルアプリケーションの処理は困難です。

まず、次のyamlを「blue.yaml」ファイルに保存して、blueデプロイメントを作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue-deployment
spec:
  selector:
    matchLabels:
      app: blue-deployment
      version: nanoserver-1709
  replicas: 3
  template:
    metadata:
      labels:
        app: blue-deployment
        version: nanoserver-1709
    spec:
      containers:
        - name: blue-deployment
          image: hello-world:nanoserver-1709

次に、kubectlコマンドを使用してデプロイメントを作成できます。

$ kubectl apply -f blue.yaml

デプロイメントテンプレートを取得したら、サービスを作成してデプロイメントのインスタンスにアクセスする方法を提供できます。イメージhello-worldをバージョンnanoserver-1809でデプロイしていることに注意してください。したがって、この場合、「name = blue-deployment」と「version = nanoserver-1709」の2つのラベルがあります。これらを以下のサービスのラベルセレクターとして設定します。これをservice.yamlファイルに保存します。

apiVersion: v1
kind: Service
metadata: 
  name: blue-green-service
  labels: 
    name: blue-deployment
    version: nanoserver-1709
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: blue-deployment
    version: nanoserver-1709
  type: LoadBalancer

ここでサービスを作成すると、クラスターの外部からアクセスできるロードバランサーが作成されます。

$ kubectl apply -f service.yaml

これで、以下の設定が完了しました。

代替テキスト

以下のために緑の展開我々はと並行して、新たな展開展開する青色の展開を。以下のテンプレートはファイルの内容です。green.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: green-deployment
spec:
  selector:
    matchLabels:
      app: green-deployment
      version: nanoserver-1809
  replicas: 3
  template:
    metadata:
      labels:
        app: green-deployment
        version: nanoserver-1809
    spec:
      containers:
        - name: green-deployment
          image: hello-world:nanoserver-1809

image hello-world:nanoserver-1809 tag-nameが2に変更されていることに注意してください。そのため、name = green-deploymentとversion = nanoserver-1809の2つのラベルを使用して個別にデプロイしました。

$ kubectl apply -f green.yaml

カットオーバーするには、緑の展開、我々は既存のサービスのためのセレクタを更新します。service.yamlを編集し、セレクターのバージョンを2に、名前をgreen-deployemntに変更します。これにより、グリーン展開のポッドと一致するようになります。

apiVersion: v1
kind: Service
metadata: 
  name: blue-green-service
  labels: 
    name: green-deployment
    version: nanoserver-1809
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: green-deployment
    version: nanoserver-1809
  type: LoadBalancer

kubectlコマンドを使用してサービスを再度作成します。

$ kubectl apply -f service.yaml

代替テキスト

したがって、結論として、新しいバージョンを段階的に展開できないローリング更新展開とは異なり、青緑色の展開はオールオアナッシングであることがわかります。既存のセッションは古いインスタンスでの作業を終了できますが、すべてのユーザーが同時に更新を受け取ります。したがって、変更を開始すると、すべてが機能するはずの賭け金よりも少し高くなります。また、すべてのポッドの2つのコピーを実行する必要があるため、より多くのサーバーリソースを割り当てる必要があります。

幸い、ロールバック手順も同様に簡単です。スイッチをもう一度切り替えるだけで、前のバージョンが元の場所に戻されます。これは、古いバージョンがまだ古いポッドで実行されているためです。それは単にトラフィックがもはやそれらにルーティングされていないということです。新しいバージョンが残っていると確信したら、それらのポッドを廃止する必要があります。

カナリアの展開

カナリア更新戦略は部分的な更新プロセスであり、完全な展開を約束することなく、実際のユーザーベースで新しいプログラムバージョンをテストできます。青/緑の展開に似ていますが、より制御されており、展開が段階的なアプローチである場合は、よりプログレッシブな配信を使用します。ダークローンチやA / Bテストなど、カナリアの傘下に入る戦略はたくさんあります。

カナリア展開では、アプリケーションの新しいバージョンがKubernetesクラスターに徐々に展開され、ライブトラフィックが非常に少なくなります(つまり、ライブユーザーのサブセットが新しいバージョンに接続し、残りは以前のバージョンを使用しています)このアプローチでは、2つのほぼ同一のサーバーがあります。1つは現在アクティブなすべてのユーザーに送信され、もう1つはユーザーのサブセットに展開されて比較される新機能を備えています。エラーが報告されず、信頼性が高まると、新しいバージョンをインフラストラクチャの残りの部分に徐々に展開できます。最終的に、すべてのライブトラフィックはカナリアに送られ、カナリアバージョンが新しい製品バージョンになります。

次の図は、カナリアの展開を行うための最も簡単で簡単な方法を示しています。新しいバージョンがサーバーのサブセットにデプロイされます。

代替テキスト

これが発生している間、アップグレードされたマシンの動作を監視します。エラーやパフォーマンスの問題をチェックし、ユーザーからのフィードバックを聞きます。カナリアに自信が持てるようになり、すべてが最新リリースを実行するまで、残りのマシンにカナリアをインストールし続けます。

代替テキスト

カナリアの配備を計画する際には、さまざまなことを考慮に入れる必要があります。

  1. ステージ:最初にカナリアに送信するユーザーの数と、ステージの数。
  2. 期間:カナリアを実行する予定の期間はどれくらいですか?カナリアのリリースは異なります。結果を評価する前に、十分な数のクライアントが更新されるのを待つ必要があるためです。これは、数日または数週間にわたって発生する可能性があります。
  3. メトリック:アプリケーションのパフォーマンスやエラーレポートなど、進捗状況を分析するために記録するメトリックは何ですか?カナリアの展開を成功させるには、適切に選択されたパラメーターが不可欠です。たとえば、デプロイメントを測定する非常に簡単な方法は、HTTPステータスコードを使用することです。デプロイが成功したときに200を返す単純なpingサービスを作成できます。展開に問題がある場合は、サーバー終了エラー(5xx)が返されます。
  4. 評価:カナリアが成功したかどうかを判断するためにどのような基準を使用しますか

カナリアは、通常、アプリケーションのバックエンドで新しい機能をテストする必要があるシナリオで使用されます。新しいバージョンに100%自信がない場合は、カナリア展開を使用する必要があります。失敗する可能性は低いと予測しています。この戦略は通常、新しい機能や実験的な機能の追加など、メジャーアップデートがある場合に使用されます。

K8sの導入戦略の概要

要約すると、アプリケーションをデプロイする方法はいくつかあります。開発/ステージング環境にリリースする場合、通常、再作成またはランプ展開が適切な選択です。本番環境では、通常、ランプ展開または青/緑展開が適していますが、新しいプラットフォームの適切なテストが必要です。プラットフォームの安定性と、新しいソフトウェアバージョンのリリースの影響に自信がない場合は、カナリアリリースが最適です。そうすることで、消費者にアプリケーションとそのプラットフォームへの統合をテストさせます。この記事では、Kubernetesデプロイメントの機能のほんの一部にすぎません。デプロイを他のすべてのKubernetes機能と組み合わせることで、ユーザーはあらゆるニーズに合わせて、より堅牢なコンテナ化されたアプリケーションを作成できます。 

リンク: https://auth0.com/blog/deployment-strategies-in-kubernetes/

#k8s #kubernetes 

What is GEEK

Buddha Community

Kubernetesでのデプロイ戦略
山岸  英樹

山岸 英樹

1636585560

Kubernetesでのデプロイ戦略

この記事では、Kubernetesコンテナオーケストレーションシステムを使用してコンテナをデプロイする際のデプロイメント戦略について学習します。この記事の最後で、Kubernetesクラスターでさまざまな方法を使用してデプロイを行う方法を学習しました。このトピックがおもしろいと思ったら、読み続けてください!このチュートリアルのコードは、Githubで入手できます。

Kubernetesの簡単な紹介

コンテナ化は時間の経過とともに人気を博し、アプリケーションの構築、出荷、保守のプロセスに革命をもたらしたため、これらのコンテナを効果的に管理する必要がありました。大規模システムでこれらのコンテナのライフサイクルを管理するために、多くのコンテナオーケストレーションツールが導入されました。

Kubernetesは、プロビジョニングとデプロイ、リソースの割り当て、負荷分散、サービスディスカバリ、高可用性の提供、その他のシステムの重要な側面を処理するオーケストレーションツールの1つです。このプラットフォームを使用すると、開発中にアプリケーションをより小さなシステム(マイクロサービスと呼ばれる)に分解できます。次に、展開中にこれらのシステムを一緒に構成(またはオーケストレーション)できます。

クラウドネイティブアプローチの採用により、マイクロサービスアーキテクチャに基づくアプリケーションの開発が増加しています。このようなアプリケーションの場合、組織が直面する最大の課題の1つは展開です。展開に関して適切な戦略を立てる必要があります。Kubernetesでは、アプリケーションをリリースするさまざまな方法があります。アプリケーションの展開または更新中にインフラストラクチャの信頼性を高めるには、適切な戦略を選択する必要があります。たとえば、実稼働環境では、エンドユーザーにダウンタイムが発生しないようにする必要が常にあります。Kubernetesオーケストレーションでは、適切な戦略により、さまざまなバージョンのコンテナイメージを適切に管理できます。要約すると、この記事では主にKubernetesでのさまざまなデプロイ戦略について説明します。

前提条件

この記事を続けるには、Kubernetesの使用経験が必要です。このプラットフォームを初めて使用する場合は、基本的なKubernetesコンセプトのステップバイステップの概要チュートリアルをご覧ください。そこでは、ここの指示に従うために必要なすべてを学ぶことができます。また、必要に応じて、Kubernetesのドキュメントを確認することをお勧めします。

さらに、ターミナルからクラスターを制御できるようにするコマンドラインインターフェイス(CLI)ツールであるkubectlが必要になります。このツールをお持ちでない場合は、Kube Control(kubectl)のインストールの手順を確認してください。LinuxとYAMLの基本的な理解も必要です。

Kubernetesでのデプロイとは何ですか?

デプロイは、プログラムの目的の状態を定義するKubernetesのリソースオブジェクトです。デプロイメントは宣言型です。つまり、状態を達成する方法を指示しません。代わりに、目的の状態を宣言し、Deployment-controllerが最も効率的な方法でその最終目標に自動的に到達できるようにします。デプロイにより、アプリに使用するイメージ、存在するポッドの数、更新方法など、アプリケーションのライフサイクルを記述できます。

Kubernetesデプロイメントを使用する利点

コンテナ化されたアプリケーションを手動で更新するプロセスは、時間と手間がかかる場合があります。Kubernetesのデプロイにより、このプロセスが自動化され、繰り返し可能になります。デプロイはKubernetesバックエンドによって完全に管理され、更新プロセス全体はクライアントとの対話なしでサーバー側で実行されます。

さらに、Kubernetesデプロイメントコントローラーは常にポッドとノードの状態を監視しています。障害が発生したポッドを置き換えるか、ノードをバイパスして、重要なアプリケーションの継続性を確保します。

展開戦略

ローリングアップデートの展開

ローリングデプロイメントは、Kubernetesのデフォルトのデプロイメント戦略です。これにより、以前のバージョンのアプリケーションのポッドが、クラスターのダウンタイムなしで新しいバージョンのポッドに1つずつ置き換えられます。ローリングデプロイメントは、以前のバージョンのアプリケーションのインスタンスを新しいバージョンのアプリケーションのインスタンスにゆっくりと置き換えます。

代替テキスト

RollingUpdate戦略を使用する場合、更新プロセスを微調整できるオプションがさらに2つあります。

maxSurge:更新中に必要な数のポッドを超えて作成できるポッドの数。これは、レプリカ数の絶対数またはパーセンテージにすることができます。デフォルトは25%です。

maxUnavailable:更新プロセス中に使用できなくなる可能性のあるポッドの数。これは、レプリカ数の絶対数またはパーセンテージにすることができます。デフォルトは25%です。

まず、rollingupdate.yamlデプロイメントテンプレートを作成します。以下のテンプレートでは、maxSurgeを2に設定し、maxUnavailableを1に設定しています。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rollingupdate-strategy
  version: nanoserver-1709
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  selector:
    matchLabels:
      app: web-app-rollingupdate-strategy
      version: nanoserver-1709
  replicas: 3
  template:
    metadata:
      labels:
        app: web-app-rollingupdate-strategy
        version: nanoserver-1709
    spec:
      containers:
        - name: web-app-rollingupdate-strategy
          image: hello-world:nanoserver-1709

次に、kubectlコマンドを使用してデプロイメントを作成できます。

$ kubectl apply -f rollingupdate.yaml

デプロイメントテンプレートを取得したら、サービスを作成してデプロイメントのインスタンスにアクセスする方法を提供できます。イメージhello-worldをバージョンnanoserver-1709でデプロイしていることに注意してください。したがって、この場合、「name = web-app-rollingupdate-strategy」と「version = nanoserver-1709」の2つのラベルがあります。これらを以下のサービスのラベルセレクターとして設定します。これを ' service.yaml 'ファイルに保存します。

apiVersion: v1
kind: Service
metadata: 
  name: web-app-rollingupdate-strategy
  labels: 
    name: web-app-rollingupdate-strategy
    version: nanoserver-1709
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: web-app-rollingupdate-strategy
    version: nanoserver-1709
  type: LoadBalancer

ここでサービスを作成すると、クラスターの外部からアクセスできるロードバランサーが作成されます。

$ kubectl apply -f service.yaml

kubectl get Deploymentsを実行して、Deploymentが作成されているかどうかを確認します。デプロイメントがまだ作成されている場合、出力は次のようになります。

$ kubectl get deployments

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
rollingupdate-strategy   0/3     0            0           1s

kubectlを実行すると、数秒後に再度デプロイメントを取得します。出力は次のようになります。

$ kubectl get deployments

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
rollingupdate-strategy   3/3     0            0           7s

デプロイメントによって作成されたReplicaSet(rs)を確認するには、kubectl getrsを実行します。出力は次のようになります。

$ kubectl get rs

NAME                                    DESIRED   CURRENT   READY   AGE
rollingupdate-strategy-87875f5897   3         3         3       18s

デプロイ用に実行されている3つのポッドを確認するには、kubectl getpodsを実行します。作成されたReplicaSetは、3つのポッドが実行されていることを確認します。出力は次のようになります。

$ kubectl get pods

NAME                                      READY     STATUS    RESTARTS   AGE       
rollingupdate-strategy-87875f5897-55i7o   1/1       Running   0          12s       
rollingupdate-strategy-87875f5897-abszs   1/1       Running   0          12s       
rollingupdate-strategy-87875f5897-qazrt   1/1       Running   0          12s

hello-world:nanoserver-1709イメージの代わりにhello-world:nanoserver-1809イメージを使用するようにrollingupdate.yamlデプロイメントテンプレートを更新しましょう。次に、kubectlコマンドを使用して、既存の実行中のデプロイメントのイメージを更新します。

$ kubectl set image deployment/rollingupdate-strategy web-app-rollingupdate-strategy=hello-world:nanoserver-1809 --record

出力は以下のようになります。

deployment.apps/rollingupdate-strategy image updated

現在、バージョンnanoserver-1809でイメージhello-worldをデプロイしています。したがって、この場合、「service.yaml」のラベルを更新する必要があります。ラベルは「version = nanoserver-1809」に更新されます。以下のkubectlコマンドを再度実行してサービスを更新し、新しいイメージで実行されている新しいポッドを選択できるようにします。

$ kubectl apply -f service.yaml

ロールアウトステータスを確認するには、以下のkubectlコマンドを実行します。

$ kubectl rollout status deployment/rollingupdate-strategy

Waiting for rollout to finish: 2 out of 3 new replicas have been updated...

もう一度実行して、ロールアウトが成功したことを確認します。

$ kubectl rollout status deployment/rollingupdate-strategy

deployment "rollingupdate-strategy" successfully rolled out

ロールアウトが成功したら、コマンドkubectl getdeploymentsを実行してデプロイメントを表示できます。出力は次のようになります。

$ kubectl get deployments

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
rollingupdate-strategy   3/3     0            0           7s

kubectl get rsを実行して、デプロイメントが更新されていることを確認します。新しいポッドは新しいReplicaSetで作成され、最大3つのレプリカにスケールアップされます。古いReplicaSetは0レプリカに縮小されます。

$ kubectl get rs

NAME                                    DESIRED   CURRENT   READY   AGE
rollingupdate-strategy-87875f5897   3         3         3       55s
rollingupdate-strategy-89999f7895   0         0         0       12s

kubectl get podsを実行すると、新しいReplicaSet内の新しいポッドのみが表示されます。

$ kubectl get pods

NAME                                      READY     STATUS    RESTARTS   AGE       
rollingupdate-strategy-89999f7895-55i7o   1/1       Running   0          12s       
rollingupdate-strategy-89999f7895-abszs   1/1       Running   0          12s       
rollingupdate-strategy-89999f7895-qazrt   1/1       Running   0          12s

ここでは、kubectlのrolloutコマンドが非常に役立ちます。これを使用して、デプロイメントがどのように行われているかを確認できます。このコマンドは、デフォルトで、デプロイメント内のすべてのポッドが正常に開始されるまで待機します。デプロイメントが成功すると、コマンドは終了し、成功を示す戻りコード0が返されます。展開が失敗した場合、コマンドはゼロ以外のコードで終了します。

$ kubectl rollout status deployment rollingupdate-strategy

Waiting for deployment "rollingupdate-strategy" rollout to finish: 0 of 3 updated replicas are available…
Waiting for deployment "rollingupdate-strategy" rollout to finish: 1 of 3 updated replicas are available…
Waiting for deployment "rollingupdate-strategy" rollout to finish: 2 of 3 updated replicas are available…

deployment "rollingupdate-strategy" successfully rolled out

Kubernetesでデプロイが失敗した場合、デプロイプロセスは停止しますが、失敗したデプロイのポッドは保持されます。デプロイメントが失敗すると、環境に古いデプロイメントと新しいデプロイメントの両方のポッドが含まれる場合があります。安定した動作状態に戻すには、rollout undoコマンドを使用して、動作中のポッドを元に戻し、失敗したデプロイメントをクリーンアップします。

$ kubectl rollout undo deployment rollingupdate-strategy

deployment.extensions/rollingupdate-strategy

次に、展開のステータスを再度確認します。

$ kubectl rollout status deployment rollingupdate-strategy

deployment "rollingupdate-strategy" successfully rolled out

Kubernetesがアプリケーションの準備ができたことを知るには、アプリケーションの助けが必要です。Kubernetesは、準備プローブを使用して、アプリケーションの動作を調べます。アプリケーションインスタンスが準備プローブに肯定応答で応答し始めると、インスタンスは使用可能であると見なされます。準備プローブは、アプリケーションの準備ができたときにKubernetesに通知しますが、アプリケーションの準備ができるかどうかは通知しません。アプリケーションが失敗し続ける場合、Kubernetesに対して肯定的な応答で応答しない可能性があります。

ローリングデプロイメントは通常、古いコンポーネントをスケールダウンする前に、準備チェックによって新しいポッドの準備が整うのを待ちます。重大な問題が発生した場合は、ローリングデプロイメントを中止できます。問題がある場合は、クラスター全体を停止せずに、ローリング更新またはデプロイメントを中止できます。

デプロイメントを再作成する

再作成デプロイメントでは、新しいアプリケーションバージョンをスケールアップする前に、既存のアプリケーションバージョンを完全にスケールダウンします。次の図では、バージョン1は現在のアプリケーションのバージョンを表し、バージョン2は新しいアプリケーションのバージョンを表します。現在のアプリケーションバージョンを更新するときは、最初にバージョン1の既存のレプリカをゼロにスケールダウンしてから、新しいバージョンでレプリカを同時にデプロイします。

代替テキスト

以下のテンプレートは、再作成戦略を使用したデプロイを示しています。まず、次のyamlをファイルrecreate.yamlに保存して、再作成デプロイメントを作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: recreate-strategy
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: web-app-recreate-strategy
      version: nanoserver-1809
  replicas: 3
  template:
    metadata:
      labels:
        app: web-app-recreate-strategy
    spec:
      containers:
        - name: web-app-recreate-strategy
          image: hello-world:nanoserver-1809

次に、kubectlコマンドを使用してデプロイメントを作成できます。

$ kubectl apply -f recreate.yaml

デプロイメントテンプレートを取得したら、サービスを作成してデプロイメントのインスタンスにアクセスする方法を提供できます。イメージhello-worldをバージョンnanoserver-1809でデプロイしていることに注意してください。したがって、この場合、「name = web-app-recreate-strategy」と「version = nanoserver-1809」の2つのラベルがあります。これらを以下のサービスのラベルセレクターとして設定します。これをservice.yamlファイルに保存します。

apiVersion: v1
kind: Service
metadata: 
  name: web-app-recreate-strategy
  labels: 
    name: web-app-recreate-strategy
    version: nanoserver-1809
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: web-app-recreate-strategy
    version: nanoserver-1809
  type: LoadBalancer

ここでサービスを作成すると、クラスターの外部からアクセスできるロードバランサーが作成されます。

$ kubectl apply -f service.yaml

recreateメソッドには、更新プロセス中にダウンタイムが発生します。メンテナンスウィンドウや停止を処理できるアプリケーションでは、ダウンタイムは問題になりません。ただし、高いサービスレベルアグリーメント(SLA)と可用性要件を備えたミッションクリティカルなアプリケーションがある場合は、別の展開戦略を選択することが適切なアプローチになります。再作成デプロイメントは、セットアップが簡単で、アプリケーションの状態が新しいバージョンで完全に更新されるため、開発者は通常、開発段階で使用します。さらに、複数のアプリケーションバージョンを並行して管理する必要がないため、データとアプリケーションの下位互換性の問題を回避できます。

青緑色の展開

青/緑の展開戦略(赤/黒とも呼ばれる)では、青は現在のアプリケーションバージョンを表し、緑は新しいアプリケーションバージョンを表します。この場合、一度に1つのバージョンのみがライブになります。緑の展開が作成およびテストされている間、トラフィックは青の展開にルーティングされます。テストが終了したら、トラフィックを新しいバージョンにルーティングします。

デプロイメントが成功した後、ロールバックの可能性のために青いデプロイメントを維持するか、それを廃止することができます。または、これらのインスタンスに新しいバージョンのアプリケーションをデプロイすることもできます。その場合、現在の(青の)環境が次のリリースのステージング領域として機能します。

この手法により、展開戦略の再作成で直面したダウンタイムをなくすことができます。さらに、青緑の展開によりリスクが軽減されます。緑の新しいバージョンで予期しないことが発生した場合は、青に切り替えることで、すぐに最後のバージョンにロールバックできます。即時のロールアウト/ロールバックがあります。バージョン管理の問題を回避することもできます。1回のデプロイメントでアプリケーション全体の状態が変更されます。

代替テキスト

Blue-Greenの展開は、2倍のリソースを必要とするため、費用がかかります。プラットフォーム全体の適切なテストは、本番環境にリリースする前に実行する必要があります。さらに、ステートフルアプリケーションの処理は困難です。

まず、次のyamlを「blue.yaml」ファイルに保存して、blueデプロイメントを作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue-deployment
spec:
  selector:
    matchLabels:
      app: blue-deployment
      version: nanoserver-1709
  replicas: 3
  template:
    metadata:
      labels:
        app: blue-deployment
        version: nanoserver-1709
    spec:
      containers:
        - name: blue-deployment
          image: hello-world:nanoserver-1709

次に、kubectlコマンドを使用してデプロイメントを作成できます。

$ kubectl apply -f blue.yaml

デプロイメントテンプレートを取得したら、サービスを作成してデプロイメントのインスタンスにアクセスする方法を提供できます。イメージhello-worldをバージョンnanoserver-1809でデプロイしていることに注意してください。したがって、この場合、「name = blue-deployment」と「version = nanoserver-1709」の2つのラベルがあります。これらを以下のサービスのラベルセレクターとして設定します。これをservice.yamlファイルに保存します。

apiVersion: v1
kind: Service
metadata: 
  name: blue-green-service
  labels: 
    name: blue-deployment
    version: nanoserver-1709
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: blue-deployment
    version: nanoserver-1709
  type: LoadBalancer

ここでサービスを作成すると、クラスターの外部からアクセスできるロードバランサーが作成されます。

$ kubectl apply -f service.yaml

これで、以下の設定が完了しました。

代替テキスト

以下のために緑の展開我々はと並行して、新たな展開展開する青色の展開を。以下のテンプレートはファイルの内容です。green.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: green-deployment
spec:
  selector:
    matchLabels:
      app: green-deployment
      version: nanoserver-1809
  replicas: 3
  template:
    metadata:
      labels:
        app: green-deployment
        version: nanoserver-1809
    spec:
      containers:
        - name: green-deployment
          image: hello-world:nanoserver-1809

image hello-world:nanoserver-1809 tag-nameが2に変更されていることに注意してください。そのため、name = green-deploymentとversion = nanoserver-1809の2つのラベルを使用して個別にデプロイしました。

$ kubectl apply -f green.yaml

カットオーバーするには、緑の展開、我々は既存のサービスのためのセレクタを更新します。service.yamlを編集し、セレクターのバージョンを2に、名前をgreen-deployemntに変更します。これにより、グリーン展開のポッドと一致するようになります。

apiVersion: v1
kind: Service
metadata: 
  name: blue-green-service
  labels: 
    name: green-deployment
    version: nanoserver-1809
spec:
  ports:
    - name: http
      port: 80
      targetPort: 80
  selector: 
    name: green-deployment
    version: nanoserver-1809
  type: LoadBalancer

kubectlコマンドを使用してサービスを再度作成します。

$ kubectl apply -f service.yaml

代替テキスト

したがって、結論として、新しいバージョンを段階的に展開できないローリング更新展開とは異なり、青緑色の展開はオールオアナッシングであることがわかります。既存のセッションは古いインスタンスでの作業を終了できますが、すべてのユーザーが同時に更新を受け取ります。したがって、変更を開始すると、すべてが機能するはずの賭け金よりも少し高くなります。また、すべてのポッドの2つのコピーを実行する必要があるため、より多くのサーバーリソースを割り当てる必要があります。

幸い、ロールバック手順も同様に簡単です。スイッチをもう一度切り替えるだけで、前のバージョンが元の場所に戻されます。これは、古いバージョンがまだ古いポッドで実行されているためです。それは単にトラフィックがもはやそれらにルーティングされていないということです。新しいバージョンが残っていると確信したら、それらのポッドを廃止する必要があります。

カナリアの展開

カナリア更新戦略は部分的な更新プロセスであり、完全な展開を約束することなく、実際のユーザーベースで新しいプログラムバージョンをテストできます。青/緑の展開に似ていますが、より制御されており、展開が段階的なアプローチである場合は、よりプログレッシブな配信を使用します。ダークローンチやA / Bテストなど、カナリアの傘下に入る戦略はたくさんあります。

カナリア展開では、アプリケーションの新しいバージョンがKubernetesクラスターに徐々に展開され、ライブトラフィックが非常に少なくなります(つまり、ライブユーザーのサブセットが新しいバージョンに接続し、残りは以前のバージョンを使用しています)このアプローチでは、2つのほぼ同一のサーバーがあります。1つは現在アクティブなすべてのユーザーに送信され、もう1つはユーザーのサブセットに展開されて比較される新機能を備えています。エラーが報告されず、信頼性が高まると、新しいバージョンをインフラストラクチャの残りの部分に徐々に展開できます。最終的に、すべてのライブトラフィックはカナリアに送られ、カナリアバージョンが新しい製品バージョンになります。

次の図は、カナリアの展開を行うための最も簡単で簡単な方法を示しています。新しいバージョンがサーバーのサブセットにデプロイされます。

代替テキスト

これが発生している間、アップグレードされたマシンの動作を監視します。エラーやパフォーマンスの問題をチェックし、ユーザーからのフィードバックを聞きます。カナリアに自信が持てるようになり、すべてが最新リリースを実行するまで、残りのマシンにカナリアをインストールし続けます。

代替テキスト

カナリアの配備を計画する際には、さまざまなことを考慮に入れる必要があります。

  1. ステージ:最初にカナリアに送信するユーザーの数と、ステージの数。
  2. 期間:カナリアを実行する予定の期間はどれくらいですか?カナリアのリリースは異なります。結果を評価する前に、十分な数のクライアントが更新されるのを待つ必要があるためです。これは、数日または数週間にわたって発生する可能性があります。
  3. メトリック:アプリケーションのパフォーマンスやエラーレポートなど、進捗状況を分析するために記録するメトリックは何ですか?カナリアの展開を成功させるには、適切に選択されたパラメーターが不可欠です。たとえば、デプロイメントを測定する非常に簡単な方法は、HTTPステータスコードを使用することです。デプロイが成功したときに200を返す単純なpingサービスを作成できます。展開に問題がある場合は、サーバー終了エラー(5xx)が返されます。
  4. 評価:カナリアが成功したかどうかを判断するためにどのような基準を使用しますか

カナリアは、通常、アプリケーションのバックエンドで新しい機能をテストする必要があるシナリオで使用されます。新しいバージョンに100%自信がない場合は、カナリア展開を使用する必要があります。失敗する可能性は低いと予測しています。この戦略は通常、新しい機能や実験的な機能の追加など、メジャーアップデートがある場合に使用されます。

K8sの導入戦略の概要

要約すると、アプリケーションをデプロイする方法はいくつかあります。開発/ステージング環境にリリースする場合、通常、再作成またはランプ展開が適切な選択です。本番環境では、通常、ランプ展開または青/緑展開が適していますが、新しいプラットフォームの適切なテストが必要です。プラットフォームの安定性と、新しいソフトウェアバージョンのリリースの影響に自信がない場合は、カナリアリリースが最適です。そうすることで、消費者にアプリケーションとそのプラットフォームへの統合をテストさせます。この記事では、Kubernetesデプロイメントの機能のほんの一部にすぎません。デプロイを他のすべてのKubernetes機能と組み合わせることで、ユーザーはあらゆるニーズに合わせて、より堅牢なコンテナ化されたアプリケーションを作成できます。 

リンク: https://auth0.com/blog/deployment-strategies-in-kubernetes/

#k8s #kubernetes