KubernetesのデプロイとStatefulSets
1. 概要
Kubernetes(K8s)は、オープンソースのコンテナオーケストレーションシステムです。 これにより、コンテナー化されたアプリケーションの展開、スケーリング、および管理を自動化できます。
このチュートリアルでは、さまざまなKubernetesリソースを使用してアプリケーション(ポッド)をKubernetesにデプロイする2つの異なる方法について説明します。 以下は、Kubernetesがポッドをデプロイするために提供する2つの異なるリソースです。
まず、ステートフルアプリケーションとステートレスアプリケーションの違いを見てみましょう。
2. ステートフルおよびステートレスアプリケーション
ステートフルアプリケーションとステートレスアプリケーションの主な違いは、
ステートフルアプリケーションを実行するには、ステートを維持することが重要です。 ただし、ステートレスサービスの場合、データフローは通常一時的なものです。 また、状態はデータベースなどの別のバックエンドサービスにのみ保存されます。 関連するストレージは通常、一時的なものです。 たとえば、コンテナが再起動すると、保存されているものはすべて失われます。 組織がコンテナを採用するとき、採用が容易なため、ステートレスコンテナから始める傾向があります。
Kubernetesは、ステートレスサービスの管理でよく知られています。デプロイメントワークロードは、ステートレスアプリケーションでの作業に適しています。 展開に関する限り、ポッドは交換可能です。 StatefulSet は、管理するポッドごとに一意のIDを保持します。 それらのポッドを再スケジュールする必要があるときはいつでも同じIDを使用します。 この記事では、これについてさらに説明します。
3. 展開
3.1. 導入の理解:基本
Kubernetes Deployment は、ポッドのセットを管理するための手段を提供します。 これらは、 ReplicaSets と呼ばれる、1つ以上の実行中のコンテナーまたは重複するポッドのグループである可能性があります。 Deployment を使用すると、同じポッドのグループを共通の構成で簡単に実行できます。
まず、Kubernetes Deployment を定義してから、デプロイします。 その後、Kubernetesは、デプロイによって管理されるすべてのポッドが、設定された要件を満たしていることを確認するように機能します。
レプリカが1のKubernetesDeployment では、コントローラーは現在の状態が ReplicaSet、の目的の状態、つまり1に等しいかどうかを確認します。 現在の状態が0の場合、
Kubernetes Deployment は通常、ステートレスアプリケーションに使用されます。
3.2. 展開Kubernetesのコンポーネント
以下は、Kubernetes Deploymentの主要コンポーネントです。
- 展開テンプレート
- PersistentVolume
- サービス
まず、デプロイテンプレートを作成し、「deployment.yaml」として保存しましょう。 以下のテンプレートでは、永続ボリュームもアタッチしています。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 1
selector:
matchLabels:
app: web-app
replicas: 3
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: hello-world:nanoserver-1809
volumeMounts:
- name: counter
mountPath: /app/
volumes:
- name: counter
persistentVolumeClaim:
claimName: counter
以下のテンプレートには、PersistentVolumeClaimがあります。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: counter
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50Mi
storageClassName: default
3.3. KubernetesでDeploymentを実行する
Deployment を実行する前に、上記のDeploymentにアクセスするためのサービスが必要です。 タイプNodePortのサービスを作成し、それを’service.yaml’として保存しましょう。
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
ports:
- name: http
port: 80
nodePort: 30080
selector:
name: web-app
type: NodePort
まず、以下のkubectl applyコマンドを使用してサービステンプレートを実行します。
kubectl apply -f service.yaml
次に、デプロイメントテンプレートに対して同じコマンドを実行します。
kubectl apply -f deployment.yaml
さらに、デプロイメントの詳細な説明を取得するために、kubectl describeコマンドを実行してみましょう。
kubectl describe deployment web-app-deployment
出力は次のようになります。
Name: web-app-deployment
Namespace: default
CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700
Labels: app=web-app
Annotations: deployment.kubernetes.io/revision=1
Selector: app=web-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 2 max surge
Pod Template:
Labels: app=web-app
Containers:
web-app:
Image: spring-boot-docker-project:1
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: web-app-deployment-1771418926 (3/3 replicas created)
No events.
上記のセクションでは、Deploymentが内部でReplicaSetを作成することを確認します。 次に、そのReplicaSet内にポッドを内部的に作成します。 将来、現在のデプロイメントを更新すると、新しいReplicaSetが作成されます。 次に、ポッドを古いReplicaSetから新しいものに制御された速度で徐々に移動します。
更新中にエラーが発生した場合、新しいReplicaSetがReady状態になることはありません。 古いReplicaSetは再び終了せず、更新に失敗した場合に100% uptimeを保証します。 Kubernetes Deployment では、新しい機能が期待どおりに機能しない場合に備えて、以前のReplicaSetに手動でロールバックすることもできます。
4. StatefulSet s
4.1. StatefulSet を理解する:基本
StatefulSet は、その中の各ポッドに2つの安定した一意のIDを提供します。 まず、ネットワークIDを使用すると、再起動の回数に関係なく、ポッドに同じDNS名を割り当てることができます。 IPアドレスはまだ異なる可能性があるため、コンシューマーはDNS名に依存する必要があります(または変更を監視して内部キャッシュを更新します)。
次に、ストレージIDは同じままです。 ネットワークIDは、再スケジュールされたノードに関係なく、常に同じストレージインスタンスを受け取ります。
StatefulSet もコントローラーですが、Kubernetes Deployment とは異なり、 ReplicaSet を作成するのではなく、podを一意で作成します。命名規則。 各ポッドパターンに従ってDNS名を受け取ります。
ステートフルセットのすべてのレプリカには独自の状態があり、各ポッドは独自のPVC(永続ボリュームクレーム)を作成します。したがって、3つのレプリカを持つStatefulSetは3つを作成します。ポッドにはそれぞれ独自のボリュームがあるため、合計3つのPVCがあります。 StatefulSet はデータを処理するため、メモリからディスクにデータを保持するために必要な時間を確保して、ポッドインスタンスを停止する際は注意が必要です。 たとえば、Kubernetesノードに障害が発生した場合など、強制削除を実行する正当な理由がまだある可能性があります。
4.2. ヘッドレスサービス
ステートフルアプリケーションには、一意のID(ホスト名)を持つポッドが必要です。 1つのポッドは、明確に定義された名前を持つ他のポッドに到達できる必要があります。 StatefulSet が機能するには、ヘッドレスサービスが必要です。 ヘッドレスサービスは、サービスIPを使用するサービスです。 したがって、関連するポッドのIPを直接返します。 これにより、プロキシではなくポッドと直接対話できます。 .spec.clusterIP。にNoneを指定するのと同じくらい簡単です。
ヘッドレスサービスにはIPアドレスがありません。 内部的には、DNS名でポッドを公開するために必要なエンドポイントを作成します。 StatefulSet 定義には、ヘッドレスサービスへの参照が含まれていますが、個別に作成する必要があります。
4.3. KubernetesのStatefulSetsコンポーネント
StatefulSetの主なコンポーネントは次のとおりです。
- StatefulSet
- PersistentVolume
- ヘッドレスサービス
まず、StatefulSetテンプレートを作成します。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumes:
- name: www
persistentVolumeClaim:
claimName: myclaim
次に、StatefulSetテンプレートに記載されているPersistentVolumeを作成します。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
最後に、上記のStatefulSetのヘッドレスサービスを作成します。
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
4.4. KubernetesでStatefulSetを実行する
3つのコンポーネントすべてに対応するテンプレートが用意されています。 次に、 create kubectlコマンドを実行して、StatefulSetを作成しましょう。
kubectl create -f statefulset.yaml
web-0、web-1、web-2という名前の3つのポッドが作成されます。 get pods を使用して、正しい作成を確認できます。
kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 1m
web-1 1/1 Running 0 46s
web-2 1/1 Running 0 18s
実行中のサービスを確認することもできます。
kubectl get svc nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None < none > 80/TCP 2m
StatefulSetはReplicaSetを作成しないため、StatefulSetを以前のバージョンにロールバックすることはできません。 Statefulsetの削除またはスケールアップ/スケールダウンのみが可能です。StatefulSet を更新すると、RollingUpdateも実行されます。つまり、1つのレプリカポッドがダウンし、更新されたポッドが表示されます。上。 同様に、次のレプリカポッドも同じようにダウンします。
たとえば、上記のStatefulSetの画像を変更します。 web-2 が終了し、完全に終了すると、 web-2 が再作成され、同時にweb-1が終了します。 。 次のレプリカ、つまりweb-0でも同じことが起こります。 更新中にエラーが発生した場合は、 web-2 ダウンします、 web-1 & web-0 以前の安定バージョンで実行され、引き続き稼働します。 Deployment とは異なり、StatefulSetの以前のバージョンにロールバックすることはできません。
StatefulSetを削除またはスケールダウンしても、StatefulSetに関連付けられたボリュームは削除されません。これにより、データの安全性が確保されます。これは、関連するすべてのStatefulSetリソースの自動パージよりも一般的に価値があります。 StatefulSets を削除した後、ポッドの終了は保証されません。 StatefulSet内のポッドの順序付けられた正常な終了を実現するために、削除する前にStatefulSetを0にスケールダウンすることができます。
4.5. StatefulSetの使用法
StatefulSet を使用すると、ステートフルアプリケーションとクラスター化アプリケーションをデプロイできます。 ComputeEngine永続ディスクなどの永続ストレージにデータを保存します。 これらは、Kafka、MySQL、Redis、ZooKeeper、およびその他のアプリケーション(一意で永続的なIDと安定したホスト名が必要)のデプロイに適しています。
たとえば、Solrデータベースクラスターは複数のZookeeperインスタンスによって管理されます。 このようなアプリケーションが正しく機能するためには、各Solrインスタンスがそれを制御しているZookeeperインスタンスを認識している必要があります。 同様に、Zookeeperインスタンス自体が相互に接続を確立して、マスターノードを選択します。 このような設計のため、Solrクラスターはステートフルアプリケーションの例です。 ステートフルアプリケーションの他の例には、MySQLクラスター、Redis、Kafka、MongoDBなどがあります。 このようなシナリオでは、StatefulSetが使用されます。
5. 展開対。 StatefulSet s
導入との主な違いを見てみましょう。 StatefulSet :
展開 | StatefulSet |
デプロイメントは、ステートレスアプリケーションをデプロイするために使用されます | StatefulSet は、ステートフルアプリケーションをデプロイするために使用されます |
ポッドは交換可能です | ポッドは交換できません。 各ポッドには永続的な識別子があり、再スケジュール時に維持されます |
ポッド名は一意です | ポッド名は順番に並んでいます |
展開でポッドと対話するにはサービスが必要です | ヘッドレスサービスは、ポッドのネットワークIDを担当します |
指定されたPersistentVolumeClaimは、すべてのポッドレプリカで共有されます。 言い換えれば、共有ボリューム | 各レプリカポッドがそれに関連付けられた一意のPersistentVolumeClaimを取得するように、指定されたvolumeClaimTemplates。 つまり、共有ボリュームはありません |
Kubernetes Deployment は、アプリケーションに宣言型の更新を提供するKubernetesのリソースオブジェクトです。 デプロイメントにより、アプリケーションのライフサイクルを記述できます。 アプリに使用する画像、ポッドの数、更新方法など。
StatefulSet は、ステートフルアプリに適しています。 ステートフルアプリケーションには、一意のID(ホスト名など)を持つポッドが必要です。 ポッドは、明確に定義された名前を持つ他のポッドに到達できるようになります。 ポッドに接続するには、ヘッドレスサービスが必要です。 ヘッドレスサービスにはIPアドレスがありません。 内部的には、DNS名でポッドを公開するために必要なエンドポイントを作成します。
StatefulSet 定義には、ヘッドレスサービスへの参照が含まれていますが、個別に作成する必要があります。 StatefulSet は、ホストされているアプリケーションが再起動時にその状態とデータを保存できるように、永続的なストレージを必要とします。 StatefulSet とヘッドレスサービスが作成されると、ポッドはサービス名の前に付けられた名前で別のポッドにアクセスできます。
6. 結論
このチュートリアルでは、Kubernetesでデプロイを行う2つの方法、StatefulsetとDeploymentについて説明しました。 それらの主な特性とコンポーネントを確認し、最後にそれらを比較しました。