KubernetesのDeployment:完全ガイド
開発者コミュニティで広く支持されているKubernetesは、Dockerコンテナをクラスター上で実行するためのプラットフォームとして広く利用されています。この強力なプラットフォームは、コンテナ内で実行されるアプリケーションのデプロイや更新を行うためのさまざまな手法を提供し、あらゆるシナリオにおいて高い柔軟性を実現します。Kubernetesでは、コンテナはポッド内で実行され、そのデプロイはKubernetesのDeploymentによって定義されます。本記事では、KubernetesのDeployment、その種類、デプロイ戦略、およびベストプラクティスについて解説します。
Kubernetesのデプロイメントとは何ですか?
KubernetesにおけるDeploymentは、クラスタ内のコンテナ化されたアプリケーションのデプロイとライフサイクルを管理するリソースオブジェクトです。アプリケーションへの更新を提供し、必要な数の同一のPodが常に実行され、利用可能な状態であることを保証します。また、PodやReplicaSetに対する宣言型更新も提供します。Deploymentは、スケーリング、ローリングアップデート、ロールバックを自動化するKubernetesの重要な機能です。
Deploymentは、Podの望ましい状態を指定するKubernetesオブジェクトであり、この状態を維持するためにReplicaSetを作成・管理します。 ReplicaSetは、Podの状態や数を含め、Podを直接管理します。Deploymentは、アプリケーションを含むコンテナを保持するPodインスタンスをどのように変更または作成するかをKubernetesに指示します。Podデプロイメントの状態はマニフェストで記述されます。
管理者は、レプリカPodの数を効率的にスケーリングし、高度な制御下で更新されたアプリケーションコードのロールアウトを実行し、必要に応じて以前のバージョンのデプロイメントにロールバックすることができます。KubernetesのDeploymentを管理するために、管理者はコマンドラインを使用します kubectl Linux およびその他の対応 OS 上のツール。Deployment を使用して作成された各ポッドには、そのポッドに関連付けられた ReplicaSet が存在します。また、ReplicaSet には、その ReplicaSet を作成した Deployment へのポインタが含まれています。
Kubernetes デプロイメントの基礎
KubernetesのDeploymentは、クラスタ内でコンテナ化されたアプリケーションをデプロイおよびスケーリングするために設計されています。Deploymentを使用すると、アプリケーションの望ましい状態を宣言的に定義し、その状態への到達および維持のプロセスを自動化することができます。KubernetesのDeploymentに関連する基本的な概念とコンポーネントは以下の通りです:
Desired state. デプロイメントは、Podのレプリカ数、使用するコンテナイメージ、各Podに割り当てられるリソースなど、アプリケーションの望ましい状態を定義します。Declarative configuration. デプロイメントでは通常、宣言型のアプローチが採用されており、管理者はJSONまたはYAMLファイルで状態を指定します。命令型のアプローチでは管理者が実行内容を直接設定できますが、Kubernetesの宣言型アプローチでは、管理者が求める結果を定義すれば、Kubernetesが内部のメカニズムを用いてそれを実現します。 KubernetesのDeploymentコントローラーは、ノードとポッドの健全性を監視します。ポッドの障害などリアルタイムの変更が発生した場合、そのポッドは置き換えられます。このように、Kubernetesはクラスターの状態をリアルタイムで監視し、望ましい状態に合わせるための調整を行います。ReplicaSet. デプロイメントはレプリカセットを管理します。レプリカセットは、指定されたレプリカ数を維持するために、必要に応じてポッドを作成・削除します。このアプローチにより、Kubernetesは、指定されたポッドのレプリカが常に稼働している状態を保証することができます。Rolling updates. デプロイメントはローリングアップデートに対応しており、ダウンタイムなしでアプリケーションを更新できます。Kubernetesは古いポッドを新しいポッドに段階的に置き換えるため、デプロイメントの更新プロセス中も、コンテナ化されたアプリケーションが利用可能な状態を維持できるようになります。Rollback. Kubernetesでのアップデート中に問題が発生した場合、Deploymentを以前のバージョンにロールバックすることで、アプリケーションを正常な状態に復元することができます。
宣言型設定
Kubernetesにおける宣言型アプローチとは、システムの望ましい状態を指定すると、Kubernetesがその状態を実現・維持するために必要なアクションを実行することを意味します。 構成ファイル(通常はYAMLまたはJSONで記述)を使用して最終目標を記述すると、Kubernetesは実際の状態が望ましい状態と一致するように継続的に動作します。
宣言型アプローチは、望ましい状態の一貫性を維持し、自動化を促進し、コラボレーションとバージョン管理を向上させることができるため、Kubernetesでは一般的に推奨されています。命令型アプローチは、迅速なアドホックなタスクには有用ですが、複雑で長期的なアプリケーションのデプロイメントを管理するにはあまり適していません。
デプロイ、ポッド、およびレプリカセットの連携
Kubernetesにおいて、Deployment、Pod、およびReplicaSetは密接に関連したコンポーネントであり、これらが連携してアプリケーションのデプロイ、スケーリング、およびライフサイクルを管理します。適切な設定を行うためには、これらコンポーネント間の関係性を理解し、Kubernetes内でどのように連携して機能するかを把握することが重要です。
- A
PodPodは、Kubernetesクラスタにおいて最も単純かつ最小のオブジェクトであり、実行中のプロセスの単一インスタンスを表します。1つのPodには、同じストレージボリュームとネットワークネームスペースを共有する1つ以上のコンテナを含めることができます。Podは、Deploymentなどの上位オブジェクトによって指定された目標状態に合わせるため、必要に応じて作成および破棄されるよう設計されているため、一時的な存在です。 - A
ReplicaSetいつでも指定された数の同一のPodが実行されていることを保証します。ReplicaSetは、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を直接管理する際の複雑さを抽象化し、アプリケーションの更新やスケーリングを処理するための強力な手段を提供します。
導入構成の詳細
Kubernetesでのデプロイ設定にYAMLを使用することは、その可読性と簡潔さから一般的な慣行となっています。Kubernetesは設定ファイルとしてYAMLとJSONの両方の形式をサポートしていますが、人間にとって親しみやすい構文であるため、YAMLの方が広く使用されています。
YAML(YAML Ain’t Markup Language)は、人間が読みやすく、記述も容易なデータシリアライゼーションの標準規格です。 設定ファイルや、異なるデータ構造を持つ言語間のデータ交換に一般的に使用されています。Kubernetesでは、YAMLを使用して、Deployment、Service、Podなど、さまざまなオブジェクトの望ましい状態を定義します。
YAML Deploymentファイルの主要な構成要素:
apiVersionKubernetes オブジェクトの API バージョン(例:apps/v1)を指定するために使用されます。kindKubernetes オブジェクトのタイプ(例:Deployment)を指定します。metadataそのオブジェクトの名前やラベルなどのメタデータが含まれています。spec(仕様)は、Kubernetes オブジェクトの望ましい状態を定義するために使用され、以下を含みます:replicas維持するPodのレプリカ数を指定します。selectorDeploymentによって管理されるPodを識別する方法を指定します。templateポッドのテンプレートを定義し、これにはポッドのメタデータや仕様が含まれます。containersポッド内のコンテナを一覧表示します。これには以下が含まれます:name: コンテナ名image: 使用するDockerイメージports: 公開するポート
KubernetesのDeployment設定構文におけるYAMLとJSONの違いは以下の通りです:
- YAMLは、中括弧や角括弧を使わず、インデントとキー・バリューペアを採用しているため、人間にとって読みやすい形式となっています。
- JSONは中括弧({})や角括弧([])を用いたより厳格な構造を採用しているため、複雑な設定では可読性が低下します。
KubernetesのDeploymentでは、通常YAMLが推奨されます。
YAML デプロイメントの例
以下に、ポッドやコンテナの詳細な設定を含む、YAML形式のKubernetesデプロイメント例を示します。
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: ポッドとそのコンテナの設定
コンテナの設定
このセクションでは、コンテナを設定するためのDeploymentの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. 稼働確認プローブおよび準備確認プローブ
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. ConfigMap とシークレット
envFrom:
- configMapRef:
name: my-configmap
- secretRef:
name: my-secret
場所:
envFrom: ConfigMapまたはシークレットから環境変数をインポートします
Kubernetesのデプロイメント戦略
Kubernetesには複数のデプロイ戦略(タイプ)があり、現在の状況に最適なものを選択できます。ビジネスアプリケーションには、稼働時間や可用性に関してそれぞれ異なる要件があります。適切な戦略を選択することで、ダウンタイムやサービスの中断を回避できるだけでなく、リソースを効果的に活用することができます。以下に、最も一般的なKubernetesのデプロイタイプを示します。
ローリングアップデートとロールバック
ローリングアップデートによるデプロイでは、定義された順序に従って、あるアプリケーションバージョンから新しいバージョンへと移行します。新しいバージョンのアプリケーションを含む新しいReplicaSetが起動され、旧バージョンのレプリカは終了されます。その結果、旧バージョンのPodが新しいPodに置き換えられます。ローリングアップデートにより、旧バージョンから新バージョンへスムーズに移行できますが、この処理が完了するまでにはある程度の時間がかかります。
デプロイメントを再作成する
現在実行中のポッドは終了され、新しいバージョンで再作成されます。このデプロイ戦略は、ユーザーのアクティビティが問題にならない開発者向けのKubernetes環境で一般的に使用されます。古いデプロイがシャットダウンされ、再作成デプロイ戦略によって新しいデプロイインスタンスが起動され、ポッドとアプリケーションの状態が再作成される間、ダウンタイムが発生します。
Blue-Greenデプロイ
ブルー・グリーン・デプロイメントは、Kubernetes におけるアプリケーションの更新手法の一つですが、迅速な移行を特徴としています。Kubernetes のブルー・グリーン・デプロイメントでは、旧バージョン(ブルー)と新バージョン(グリーン)の 2 つの環境を並行して稼働させることを前提としています。これら 2 つの環境は、"サイド・バイ・サイド"または並行してデプロイされます。 新バージョンのテストが完了し、正常に動作することが確認された(設計通りに機能している)時点で、Service Selectorを更新してバージョンラベルを置き換えます。この操作は、クラスタ内でロードバランシングを行うKubernetes Serviceオブジェクトに対して行われます。その後、トラフィックは直ちに新バージョンに切り替わります。
Kubernetesのブルー・グリーンデプロイメント戦略により、管理者はバージョン間の移行時に異なるバージョンによる問題を引き起こすことなく、迅速なロールアウトを実行できます。 一定期間、2つの環境が並行して稼働するため、リソース使用率が高くなる点に留意してください。
Canaryデプロイ
Kubernetesのカナリアデプロイメントでは、コンテナ化されたアプリケーションの新バージョンに、ごく一部のユーザーのみをルーティングすることを前提としています。新バージョンは、それまで稼働していた旧バージョンよりも少ないポッドのサブセット上で実行されます。カナリアデプロイメントの主な目的は、本番環境において新しいアプリケーションバージョンの機能をテストすることです。 新しいバージョンに不具合が見られない場合、管理者は新しいバージョンのスケールアップを行い、適切な順序で以前のバージョンと置き換えていきます。
少数のユーザーを対象とした新しいバージョンのデプロイ後に問題が発生した場合、管理者はカナリアデプロイメントをロールバックして以前のバージョンに戻すことができます。この手法の利点は、システム全体の運用に悪影響を及ぼすリスクを負うことなく、少数のユーザーグループを対象に新機能をテストできる点にあります。
Kubernetes デプロイメントの再作成
"デプロイメントの再作成"を使用すると、すべてのポッドが終了し、新しいバージョンに置き換えられます。この戦略は、新旧のバージョンを同時に実行できない場合に利用できます。ダウンタイムは、古いアプリケーションをシャットダウンし、コンテナ内で新しいアプリケーションを起動するのに必要な時間によって決まります。完了すると、アプリケーションの状態は完全に更新されます。
スケーリングと管理
KubernetesのDeploymentのスケーリングと管理は、コンテナ化されたアプリケーションが変動するワークロードに対応し、高可用性を維持するために不可欠です。Kubernetesは、手動および自動のスケーリングのための堅牢なメカニズムに加え、Deploymentを効率的に管理するためのツールも提供しています。
手動での拡大縮小
手動スケーリングは、 kubectl コマンドラインツール。
- 規模の拡大:
kubectl scale deployment deployment-name --replicas=10このコマンドは、my-deployment のレプリカ数を 10 に増やします。
- 規模を縮小する:
kubectl scale deployment deployment-name --replicas=2このコマンドは、my-deployment のレプリカ数を 2 に減らします。
水平ポッドオートスケーラー(HPA)
水平ポッドオートスケーラー(HPA)は、観測されたCPU使用率やその他の指定されたメトリクスに基づいて、ポッドのレプリカ数を自動的に調整します。
- HPAを作成するコマンドは次のとおりです:
kubectl autoscale deployment deployment-name --cpu-percent=50 --min=2 --max=10このコマンドは、HPAを設定します。
deployment-nameCPU使用率を約50%に維持し、レプリカ数を2~10個の範囲で調整する。 - YAML形式でのHPA設定は、より高度な方法です。以下に、水平自動スケーリングのためのYAMLデプロイメント設定例を説明します。
apiVersion: autoscaling/v1kind: HorizontalPodAutoscalermetadata:name: deployment-hpa-namespec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: deployment-nameminReplicas: 2maxReplicas: 10targetCPUUtilizationPercentage: 50次のコマンドでYAML設定を適用します:
ubectl apply -f hpa.yaml
Vertical Pod Autoscaler (VPA)
Vertical Pod Autoscaler(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のDeploymentを適切に構成することで、コンテナ化されたアプリケーションを安定して確実に実行できる環境が確保されます。設定ミスや不適切なデプロイメント管理戦略は、システム停止やデータ損失などの問題を引き起こす可能性があります。Kubernetes Deploymentのベストプラクティスに従うことで、アプリケーションの耐障害性、スケーラビリティ、保守性を確保することができます。
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. ポッドセキュリティポリシーを実装して、ポッドに対するセキュリティ基準を適用します。Kubernetes デプロイメントではネットワークポリシーを使用して、ポッド間のトラフィックを制御します。Prepare for backups and disaster recovery. Kubernetesリソースと永続データの定期的なバックアップを実施してください。障害発生時にアプリケーションやサービスを迅速に復旧できるよう、災害復旧戦略を策定し、テストを行ってください。
結論
KubernetesのDeploymentは、Kubernetesクラスタ内でのアプリケーションのライフサイクル管理において極めて重要な役割を果たします。Deploymentは、レプリカの数、コンテナイメージ、設定など、アプリケーションの望ましい状態を定義するための宣言型のアプローチを提供します。 DeploymentはReplicaSetをオーケストレーションすることで、指定された数のPodが確実に実行されるようにし、更新やロールバックを制御されたシームレスな方法で自動的に処理します。これにより、アプリケーションのスケーラビリティ、耐障害性、管理の容易性が向上し、Kubernetes Deploymentは現代的なアプリケーションのデプロイと運用に不可欠なツールとなっています。