Kubernetesのデプロイメント:完全ガイド

開発者コミュニティで人気の高いKubernetesは、Dockerコンテナをクラスター上で実行するための広く利用されているプラットフォームです。この強力なプラットフォームは、コンテナ内で実行されるアプリケーションのデプロイや更新を行うためのさまざまな方法を提供しており、さまざまなシナリオに対応する高い柔軟性を実現しています。Kubernetesでは、コンテナはポッド内で実行され、そのデプロイはKubernetesのDeploymentによって定義されます。このブログ記事では、KubernetesのDeployment、その種類、デプロイ戦略、およびベストプラクティスについて解説します。

NAKIVO Backup & Replication をお試しください

NAKIVO Backup & Replication をお試しください

無料トライアルを利用して、本ソリューションのデータ保護機能をすべてお試しください。15日間無料。機能や容量の制限は一切ありません。クレジットカードも不要です。

Kubernetes デプロイメントとは何ですか?

Kubernetes のデプロイメントとは、クラスター内でコンテナ化されたアプリケーションのデプロイメントとライフサイクルを管理するリソースオブジェクトです。必要な数の同一のポッドが常に稼働し、利用可能であることを保証するため、アプリケーションの更新を提供します。また、ポッドとレプリカセットの宣言的な更新も提供します。デプロイメントは、Kubernetes におけるスケーリングの自動化、ローリングアップデート、およびロールバックのための重要な機能です。

デプロイメントは、ポッドの望ましい状態を指定し、レプリカセットを作成・管理してその状態を維持します。レプリカセットは、ポッドを直接管理し、その状態や数も管理します。デプロイメントは、アプリケーションを持つコンテナを格納するポッドインスタンスをどう修正または作成するかを Kubernetes に指示します。ポッドのデプロイメント状態は、マニフェストで記述されます。

管理者は、レプリカポッドの数を効率的にスケーリングし、更新されたアプリケーションコードのロールアウトを高レベルで制御し、必要に応じて以前のバージョンのデプロイメントにロールバックすることができます。Kubernetes デプロイメントを管理するために、管理者は Linux や他のサポートされているオペレーティングシステム上でコマンドライン kubectl ツールを使用します。デプロイメントで作成された各ポッドは、このポッドに関連するレプリカセットを持ちます。レプリカセットは、それを作成したデプロイメントへのポインタを持ちます。

Kubernetes デプロイメントの基礎

Kubernetes デプロイメントは、クラスター内でコンテナ化されたアプリケーションをデプロイおよびスケーリングするために開発されました。デプロイメントは、アプリケーションの望ましい状態を宣言的に定義し、その状態を達成および維持するプロセスを自動化します。Kubernetes デプロイメントに関連する基本的な概念とコンポーネントは次のとおりです:

  • Desired state. デプロイメントは、ポッドのレプリカ数、使用するコンテナイメージ、各ポッドに割り当てられるリソースなど、アプリケーションの望ましい状態を定義します。
  • Declarative configuration. デプロイメントは通常、JSON または YAML ファイルで状態を指定する宣言的アプローチを使用します。命令的アプローチが管理者に直接何をするかを設定させるのに対して、Kubernetes の宣言的アプローチでは管理者が必要な結果を定義し、Kubernetes がそれを内部のメカニズムで達成します。Kubernetes デプロイメントコントローラはノードとポッドの正常性を監視しています。ポッドの障害などのリアルタイムの変更がある場合、このポッドは置き換えることができます。 このように、Kubernetes はクラスタの状態をリアルタイムで監視し、目標状態に合わせて調整を行います。
  • ReplicaSet。Deployment は ReplicaSet を管理します。ReplicaSet は、目標のレプリカ数を維持するために、必要に応じてポッドを作成・削除します。このアプローチにより、Kubernetes は、指定された数のポッドのレプリカが常に稼働している状態を保証できます。
  • Rolling updates。Deployment はローリングアップデートをサポートしており、ダウンタイムなしでアプリケーションを更新することができます。 Kubernetesは古いPodを新しいPodに徐々に置き換えるため、Deploymentの更新プロセス中も、コンテナ化されたアプリケーションが利用可能な状態を維持できるようになります。
  • Rollback。Kubernetesでの更新中に問題が発生した場合、Deploymentの以前のバージョンにロールバックして、アプリケーションを正常な状態に復元することができます。

宣言型構成

Kubernetes における宣言型アプローチとは、システムの望ましい状態を指定すると、Kubernetes がその状態を達成・維持するために必要なアクションを実行することを意味します。 構成ファイル(通常はYAMLまたはJSONで記述)を使用して最終目標を記述すると、Kubernetesは実際の状態が望ましい状態と一致するように継続的に動作します。

宣言型アプローチは、望ましい状態の一貫性を維持し、自動化を促進し、より良いコラボレーションとバージョン管理をサポートできるため、Kubernetesでは一般的に好まれます。命令型アプローチは、迅速なアドホックなタスクには有用ですが、複雑で長期的なアプリケーションのデプロイメントを管理するにはあまり適していません。

Deployment、Pod、ReplicaSetの連携

Kubernetesにおいて、Deployment、Pod、ReplicaSetは密接に関連するコンポーネントであり、これらが連携してアプリケーションのデプロイ、スケーリング、ライフサイクルを管理します。適切な設定を行うためには、これら間の関係性を理解し、Kubernetes内でどのように連携するかを把握することが重要です。

  • Pod は、Kubernetesクラスタにおいて最も単純かつ最小のオブジェクトであり、実行中のプロセスの単一インスタンスを表します。Podには、同じストレージボリュームとネットワークネームスペースを共有する1つ以上のコンテナを含めることができます。Podは、Deploymentsのような上位レベルのオブジェクトによって指定された望ましい状態に合わせるために、必要に応じて作成および破棄されるため、設計上、一時的な存在です。
  • ReplicaSet は、いつでも指定された数の同一のPodが実行されていることを保証します。 これは、望ましいレプリカ数を維持するために、Podの作成と削除を管理します。各ReplicaSetは、ラベルセレクタを使用して、その管理下にあるPodを識別・管理し、正しいPodが維持されるようにします。ReplicaSetを直接作成・管理することも可能ですが、通常は追加の機能を提供するDeploymentによって管理されます。
  • A Deployment は、ReplicaSetを管理し、アプリケーションへの宣言型更新を提供する、より高レベルのKubernetesオブジェクトです。 前述のように、Deployment を使用すると、管理者はアプリケーションの必要な状態やその他の設定を定義できます。

Deployment を作成または更新すると、定義された仕様に従って Pod を管理するための新しい ReplicaSet が自動的に作成されます。 Deployment を更新するたびに、新しいバージョンの Pod を処理するための新しい ReplicaSet が作成されますが、新しい Pod のロールアウトが正常に完了するまでは、古い ReplicaSet は残ります。これにより、アプリケーションの可用性を維持しながら、制御された方法で更新が実施されます。

Deployment は、ReplicaSet を通じて間接的に Pod のライフサイクルを管理します。Deployment で望ましい状態を定義することで、実行したい Pod の特性や数を指定します。 その後、Deploymentは適切なReplicaSetを管理することでこの状態を確保し、ReplicaSetがPodを管理します。

したがって、Podはコンテナを実行する実行単位であり、ReplicaSetは必要な数のPodが実行されていることを保証し、DeploymentはReplicaSetを制御することで、アプリケーションの宣言型管理と更新を提供します。この階層構造により、アプリケーションのスケーラビリティ、耐障害性、および管理の容易性が確保されます。 Deploymentは、ReplicaSetやPodを直接管理する際の複雑さを抽象化し、アプリケーションの更新やスケーリングを処理するための強力な手段を提供します。

Deployment構成の詳細

KubernetesでのDeployment構成にYAMLを使用することは、その可読性と簡潔さから一般的な慣行となっています。Kubernetesは構成ファイルとしてYAMLとJSONの両方の形式をサポートしていますが、YAMLは人間にとって親しみやすい構文であるため、より広く使用されています。

YAML(YAML Ain’t Markup Language)は、人間が読みやすく、記述も容易なデータシリアライゼーション標準です。設定ファイルや、データ構造の異なる言語間のデータ交換に一般的に使用されています。Kubernetesでは、YAMLを使用して、Deployment、Service、Podなど、さまざまなオブジェクトの望ましい状態を定義します。 YAML Deployment ファイルの主要な構成要素:

  • apiVersion は、Kubernetes オブジェクトの API バージョン(例:apps/v1)を指定するために使用されます。
  • kind は、Kubernetes オブジェクトのタイプ(例:Deployment)を指定します。
  • metadata には、オブジェクトの名前やラベルなどのメタデータが含まれます。
  • spec (specification) は、Kubernetes オブジェクトの望ましい状態を定義するために使用され、以下を含みます:
    • replicas は、維持すべきポッドのレプリカ数を指定します。
    • selector は、Deployment によって管理されるポッドを識別する方法を指定します。
    • template は、ポッドのメタデータや仕様を含むポッドテンプレートを定義します。
    • containers は、ポッド内のコンテナを列挙します。これには以下が含まれます:
      • name: コンテナ名
      • image: 使用する Docker イメージ
      • ports: 公開するポート

Kubernetes Deployment の設定構文における YAML と JSON の違いは以下の通りです:

  • YAML は、中括弧や角括弧を使用せず、インデントとキー・値ペアを用いるため、人間にとって読みやすい形式です。
  • JSONは中括弧({})や角括弧([])を用いたより厳格な構造を採用しているため、複雑な構成では可読性が低下します。

KubernetesのDeploymentでは、通常YAMLが推奨されます。

YAMLによるDeploymentの例

以下に、Podやコンテナの詳細な構成を含む、YAML形式のKubernetes Deploymentの例を示します。

apiVersion: apps/v1

kind: Deployment

metadata:

  name: deployment-name

spec:

  replicas: 3

  selector:

    matchLabels:

      app: app-name

  template:

    metadata:

      labels:

        app: app-name

    spec:

      containers:

      - name: container-name

        image: image-name:1.0

        ports:

        - containerPort: 80

        resources:

          requests:

            memory: "128Mi"

            cpu: "250m"

          limits:

            memory: "256Mi"

            cpu: "500m"

        env:

        - name: MY_ENV_VAR

          value: "some-value"

        volumeMounts:

        - mountPath: "/path/volume"

          name: volume-name

      volumes:

      - name: volume-name

        persistentVolumeClaim:

          claimName: pvc-name

より理解を深めるために、各セクションについて詳しく説明しましょう。これらのセクションを設定することで、Kubernetes において堅牢でスケーラブルなアプリケーションのデプロイメントを定義し、要件に応じてポッドやコンテナが適切にセットアップされるようにすることができます。

主要な設定セクション

1. メタデータ

metadata:

  name: deployment-name

説明:

name: デプロイメントの名前

2. Spec(デプロイメント仕様)

spec:

  replicas: 3

  selector:

    matchLabels:

      app: app-name

説明:

replicas: 維持するポッドのレプリカ数

selector: ラベルを使用して、デプロイメントによって管理されるポッドを識別する方法を定義します

3. ポッドテンプレート(ポッド仕様)

template:

  metadata:

    labels:

      app: app-name

  spec:

    containers:

    - name: container-name

      image: image-name:1.0

説明: metadata: ポッドを識別するラベルです

spec: ポッドとそのコンテナの設定です

コンテナの設定

この部分では、コンテナを設定するためのデプロイメントのYAMLセクションを見ることができます。

1. コンテナイメージ

image: image-name:1.0

次の場所では:

image: 使用するコンテナイメージです。バージョンを指定するタグ(例: 1.0)を含めることができます。

2. ポートです。

ports:

- containerPort: 80

次の場所では:

containerPort: トラフィックを受けるためにコンテナがリッスンするポートです。

3. リソースの要求と制限です

resources:

  requests:

    memory: "128Mi"

    cpu: "250m"

  limits:

    memory: "256Mi"

    cpu: "500m"

次の場所では:

requests: 最小限のリソース要件です

limits: コンテナが使用できる最大リソースです

4. 環境変数です

env:

- name: MY_ENV_VAR

  value: "some-value"

次の場所では:

env: コンテナの環境変数を定義します

5. ボリュームマウントです

volumeMounts:

- mountPath: "/path/volume"

  name: volume-name

次の場所では:

volumeMounts: コンテナ内にマウントするボリュームを指定します

mountPath: ボリュームがマウントされるコンテナ内のパスです

ボリュームの設定

ボリューム セクションはボリュームを設定する役割を持っています。

volumes:

- name: volume-name

  persistentVolumeClaim:

    claimName: pvc-name

次の場所では:

volumes: マウント可能なボリュームを定義します

name: ボリュームの名前です

persistentVolumeClaim: ボリュームに使用するPersistentVolumeClaim (PVC)を指定します

詳細な設定

1. LivenessおよびReadinessプローブです

livenessProbe:

  httpGet:

    path: /healthz

    port: 8080

  initialDelaySeconds: 3

  periodSeconds: 3

readinessProbe:

  httpGet:

    path: /ready

    port: 8080

  initialDelaySeconds: 5

  periodSeconds: 10

次の場所では:

livenessProbe: コンテナが生存しているか確認します

readinessProbe: 現在のコンテナがトラフィックを受け入れる準備ができているかを確認します

2. コマンドと引数です

command: ["my-command"]

args: ["arg1", "arg2"]

次の場所では:

command: コンテナのデフォルトのエントリーポイントを上書きします

args: コマンドへの引数を指定します

3. ConfigMapsとSecretsです

envFrom:

- configMapRef:

  name: my-configmap

- secretRef:

  name: my-secret

次の場所では:

envFrom: 環境変数をConfigMapまたはSecretからインポートします

Kubernetesデプロイメント戦略

さまざまなKubernetesデプロイメント戦略(タイプ)があり、現在のシナリオに最も効果的なものを選択できます。ビジネスアプリケーションは稼働時間と可用性に対する異なる要件を持っています。適切な戦略を選択することで、ダウンタイムやサービスの中断を回避し、リソースを効果的に活用できます。以下は、最も一般的なKubernetesデプロイメントタイプです。

ローリングアップデートとロールバック

ローリングアップデートデプロイメントは、あるアプリケーションバージョンから別のバージョンへの移行を前提としています。 新しいバージョンのアプリケーションとともに、新しいReplicaSetが起動されます。旧バージョンのレプリカは終了されます。その結果、旧バージョンのポッドが新しいポッドに置き換えられます。ローリングアップデートにより、旧バージョンから新バージョンへスムーズに移行できますが、この操作が完了するまでにはある程度の時間がかかります。

デプロイメントの再作成

現在実行中のポッドは終了され、その後、新しいバージョンで再作成されます。このデプロイメント戦略は、ユーザーのアクティビティが問題にならない開発者向けの Kubernetes 環境で一般的に使用されます。古いデプロイメントがシャットダウンされ、再作成戦略によって新しいデプロイメントインスタンスが起動され、ポッドとアプリケーションの状態が再作成される間、ダウンタイムが発生します。

ブルー・グリーン・デプロイメント

ブルー・グリーン・デプロイメントは、Kubernetes におけるアプリケーションの更新手法の一つですが、迅速な移行を特徴とします。Kubernetes のブルー・グリーン・デプロイメントでは、旧バージョン(ブルー)と新バージョン(グリーン)の 2 つの環境が稼働していることを前提としています。これら両方は”並行して”、つまり並行してデプロイされます。 新しいバージョンのテストが完了し、正常に動作することが確認されたら(設計通りに動作している)、Service Selectorを更新してバージョンラベルを置き換えます。この操作は、クラスター内でロードバランシングを行っているKubernetesのServiceオブジェクトに対して行われます。その後、トラフィックは直ちに新しいバージョンに切り替わります。

Kubernetesのブルー・グリーン・デプロイメント戦略により、管理者は、バージョン間の移行時に異なるバージョンに起因する問題を引き起こすことなく、迅速なロールアウトを行うことができます。 ただし、一定期間、2つの環境が並行して稼働するため、リソース使用率が高くなる点に留意してください。

カナリアデプロイメント

Kubernetesのカナリアデプロイメントでは、コンテナ化されたアプリケーションの新しいバージョンへ、ごく一部のユーザーのみをルーティングすることを前提としています。新しいバージョンは、それまで稼働していた旧バージョンよりも少ないポッドのサブセット上で実行されます。 カナリアデプロイメントの主な目的は、本番環境において新しいアプリケーションバージョンの機能をテストすることです。新しいバージョンに不具合が見られない場合、管理者は新しいバージョンのスケールアップを行い、適切な順序で以前のバージョンを置き換えていきます。

少数のユーザーを対象とした新しいバージョンのデプロイ後に問題が発生した場合、管理者はカナリアデプロイメントをロールバックして以前のバージョンに戻すことができます。 このメリットは、システム全体の運用に悪影響を及ぼすリスクなしに、少人数のユーザーグループを対象に新機能をテストできる点にあります。

Kubernetes のデプロイメント再作成

デプロイメントの再作成を使用すると、すべてのポッドが終了され、新しいバージョンに置き換えられます。この戦略は、新旧のバージョンを同時に実行できない場合に利用できます。 ダウンタイムは、古いアプリケーションをシャットダウンし、コンテナ内で新しいアプリケーションを起動するのに必要な時間によって決まります。完了すると、アプリケーションの状態は完全に更新されます。

スケーリングと管理

Kubernetes デプロイメントのスケーリングと管理は、コンテナ化されたアプリケーションが変動するワークロードに対応し、高可用性を維持するために不可欠です。Kubernetes は、手動および自動のスケーリングの両方に対応した堅牢なメカニズムに加え、デプロイメントを効率的に管理するためのツールを提供しています。

手動スケーリング

手動スケーリングでは、 kubectl コマンドラインツールを使用して、アプリケーションのレプリカ(インスタンス)数を手動で調整します。

  • スケールアップ:

    kubectl scale deployment deployment-name --replicas=10

    このコマンドは、my-deployment のレプリカ数を 10 に増やします。

  • スケールダウン:

    kubectl scale deployment deployment-name --replicas=2

    このコマンドは、my-deployment のレプリカ数を 2 に減らします。

水平ポッドオートスケーラー (HPA)

水平ポッドオートスケーラー (HPA) は、観測された CPU 使用率やその他の指定されたメトリクスに基づいて、ポッドのレプリカ数を自動的に調整します。

  1. HPA を作成するためのコマンドは次のとおりです。

    kubectl autoscale deployment deployment-name --cpu-percent=50 --min=2 --max=10

    このコマンドは、 deployment-name に対して、CPU 使用率を約 50% に維持し、レプリカ数を 2 から 10 の間でスケーリングするように HPA を設定します。

  2. YAML 形式での HPA 設定は、より高度な方法です。 以下に、水平自動スケーリングのためのYAMLデプロイ構成例を示します。

    apiVersion: autoscaling/v1

    kind: HorizontalPodAutoscaler

    metadata:

      name: deployment-hpa-name

    spec:

      scaleTargetRef:

        apiVersion: apps/v1

        kind: Deployment

        name: deployment-name

      minReplicas: 2

      maxReplicas: 10

      targetCPUUtilizationPercentage: 50

    YAML構成を適用するには、次のコマンドを実行します:

    ubectl apply -f hpa.yaml

垂直ポッドオートスケーラー(VPA)

垂直ポッドオートスケーラー(VPA)は、実際の使用状況に合わせてポッドのリソース要求値と制限値を自動的に調整します。YAML形式のVPA構成は以下の通りです:

apiVersion: autoscaling.k8s.io/v1

kind: VerticalPodAutoscaler

metadata:

  name: deployment-vpa-name

spec:

  targetRef:

    apiVersion: "apps/v1"

    kind: Deployment

    name: deployment-name

  updatePolicy:

    updateMode: "Auto"

YAML構成を適用するには、次のコマンドを使用します: kubectl apply -f vpa.yaml

Kubernetes導入のためのベストプラクティス

Kubernetes導入の正しい構成により、コンテナ化されたアプリケーションを実行するための成功し信頼できる環境を保証します。不適切な構成や管理戦略はダウンタイムやデータ損失といった問題を引き起こします。Kubernetes導入のベストプラクティスを活用することで、アプリケーションを堅牢でスケーラブルかつ保守可能に保つことができます。

  • Use declarative configuration. Kubernetesの設定をYAML/JSON形式のバージョン管理されたファイルに保存してください。これにより、変更の管理や必要に応じたロールバックが容易になります。これらの設定を適用するためには、kubectl apply -fを使用し、クラスターの状態と構成ファイルが一致していることを保証する冪等操作を可能にします。
  • Use namespace isolation. 開発、ステージング、本番環境やチームなど、異なる環境を論理的に分離するために名前空間を使用します。これにより、リソースと権限をより効果的に管理できます。
  • Resource requests and limits. リソース競合を防ぐために、ポッドのリソース要求と制限を定義してください。
  • Liveness and readiness probes. コンテナのヘルスチャックを行うためにリブネスプローブを設定し、コンテナへのトラフィック制御にレディネスプローブを使用します。
  • Use labels and selectors リソースを整理し選択するためにラベルを使用します。アプリケーション、環境、バージョンなどでリソースをグループ化するのに役立ちます。
  • Use ConfigMaps and secrets. 機密性のない設定データをConfigMapsに保存します。パスワードやAPIキーを含む機密データはSecretsに保存します。
  • Monitor and log your environment. GrafanaやPrometheusのようなツールを使用してコンテナ化されたアプリケーションのパフォーマンスとヘルスを監視します。ELKスタック(Elasticsearch、Logstash、Kibana)やFluentdのような集中ログソリューションを利用してログを収集し分析します。
  • Follow security best practices. ポッドにセキュリティ基準を強制するためにPod Security Policiesを実装します。Kubernetes導入のネットワークポリシーを使用してポッド間のトラフィックを制御します。
  • Prepare for backups and disaster recovery. Kubernetesリソースと永続データの定期的なバックアップを実施します。障害発生時にすぐにアプリケーションやサービスを復旧できるようにディザスタリカバリ戦略の計画とテストを行います。

結論

Kubernetes導入はKubernetesクラスター内でのアプリケーションのライフサイクルを管理する上で重要な役割を果たします。 これらは、レプリカの数、コンテナイメージ、設定など、アプリケーションの望ましい状態を定義するための宣言型のアプローチを提供します。DeploymentはReplicaSetをオーケストレーションすることで、指定された数のPodが確実に実行されるようにし、更新やロールバックを制御されたシームレスな方法で自動的に処理します。その結果、アプリケーションのスケーラビリティ、耐障害性、管理の容易性が向上し、KubernetesのDeploymentは、現代のアプリケーションのデプロイおよび運用において不可欠なツールとなっています。

NAKIVO Backup & Replication をお試しください

NAKIVO Backup & Replication をお試しください

無料トライアルを利用して、本ソリューションのデータ保護機能をすべてお試しください。15日間無料。機能や容量の制限は一切ありません。クレジットカードも不要です。

関連記事