KubernetesポッドコントローラーのDaemonSetとStatefulSetの説明

DaemonSet と StatefulSet の使用

Pod今回は、このようなオブジェクトリソースの使い方を中心に説明しましたが、次に、特定の場面で使用するコントローラー、 Deploymentについて説明しますDaemonSetStatefulSet

DaemonSet の使用

コントローラーの名前から、その用途がわかります: デーモンはデーモン プロセスをデプロイするために使用され、デーモン プロセスのコピーをDaemonSetKubernetesノードでバックグラウンド プロセスとして実行するために使用されます。各ノードのデーモン プロセスをPodコピーすると、ノードがKubernetesクラスターに参加すると、Podそのノードで実行されるようにスケジュールされます。ノードがクラスターからのみ削除できる場合は、ノード上のこのノードも削除されますPod。 、すべて、およびこのオブジェクトを削除しますDaemonSet。関連するものがPods削除されます。

このビジネス シナリオを使用する必要があるのはどのような状況ですか? 実際、次のようなこのシナリオは比較的一般的です。

  • クラスターストレージデーモン。たとえば、永続ストレージを提供するためglusterdceph各ノードにデプロイされます。
  • 監視クラスターなどのノード監視デーモンはPrometheus、各ノードでプロセスを実行して、node-exporter監視ノードに関する情報を収集できます。
  • fluentdまたは などのログ収集デーモンがlogstash各ノードで実行され、コンテナのログを収集します。

ここで特に説明する必要があるのは、DaemonSetを実行する際のスケジューリングの問題ですPod。通常、Podどのノードで実行するかはKubernetesスケジューラの戦略によって決まりますが、実際にはDaemonSetコントローラが作成するノードはPodあらかじめ決まっています。(Podで指定)作成時間.spec.nodeName)、つまり:

  • DaemonSetノードのフィールドは関係ありませんunshedulable。これについては、後のスケジューリングの章で説明します。
  • DaemonSetPodスケジューラが起動していなくても作成できますが、これは非常に重要です。

以下では、各ノードに 1 つをデプロイする例を直接使用して説明しますNginx Pod: (nginx-ds.yaml)

kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: nginx-ds
  labels:
    k8s-app: nginx
spec:
  selector:
    matchLabels:
      k8s-app: nginx
  template:
    metadata:
      labels:
        k8s-app: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        name: nginx
        ports:
        - name: http
          containerPort: 80

次に、それを直接作成します。

$ kubectl create -f nginx-ds.yaml

Pod次に、それが各ノードに分散されているかどうかを観察できます。

$ kubectl get nodes
$ kubectl get pods -o wide

StatefulSet の使用

この種のコントローラーについて学ぶ前にStatefulSet、「ステートフル サービスとは何なのか」という概念を理解する必要があります。ステートレスサービスとは何ですか?

  • WordPressステートレス サービス (ステートレス サービス): このサービスの実行中のインスタンスは、永続化する必要があるデータをローカルに保存しません。また、同じリクエストに応答する複数のインスタンスの結果は、前に説明したインスタンスのように完全に一貫しています。複数のインスタンスを同時に起動できますが、どのインスタンスから得られる結果も同じですよね。永続化する必要があるデータのみがデータベースに保存されているため、このアプリケーションはステートレス サービスであるMySQLと言えますが、データをローカルに永続化する必要があるため、データベースはステートレス サービスではありません。WordPressMySQL

  • ステートフル サービス (ステートフル サービス): 上記の概念とは反対です。このサービスの実行中のインスタンスは、永続的なデータをローカルに保存する必要があります。たとえば、上記のデータベースは、現在ノード A で実行している場合、そのデータは次の場所に保存されますMySQL。ノード A では、この時点でサービスをノード B に移行すると、以前のデータはなくなります。これは、対応するデータ ディレクトリにデータを復元する必要があり、現時点ではデータが存在しないためです。

これで、誰もがステートフルとステートレスについてある程度理解できるようになりました。たとえば、一般的な WEB アプリケーションはユーザーsessionのログイン ステータスを維持します。sessionそれをノードに永続化すると、アプリケーションはステートフル サービスになります。はい、私は今ログインしていて、あなたはログインしているからです。データをノード A に永続化しました。次回ログインすると、リクエストはノード B にルーティングされる可能性がありますが、sessionノード B には現在のデータがまったくないため、ログインしていないと見なされ session一般的に、水平拡張のために、この種の WEB アプリケーションをステートレスなサービスに変更しますが、それをどのように変更するか? sessionクライアントのリクエストによっては、データを社内などの公共の場所に保存するだけでredis十分ですか。ユーザーのステータスを保持するためにAPIデータを使用するのではなく、代わりに使用することも可能です。sessiontoken

ステートレス サービスは、以前のサービスまたはステートフル サービスを使用することで適切に制御できます。ステートフル サービスについては、考慮する必要がある詳細がさらに多くあります。コンテナ化されたアプリケーションで最も困難なタスクの 1 つは、ステートフル分散コンポーネントのデプロイメントを設計することですDeploymentRCステートレス コンポーネントには、事前定義された起動シーケンス、クラスタリング要件、ポイントツーポイント TCP 接続、一意のネットワーク識別子、正常な起動および終了要件などが含まれていない可能性があるため、簡単にコンテナ化できます。データベース、ビッグ データ分析システム、分散キー/バリュー ストア、メッセージ ブローカーなどのシステムは、複雑な分散アーキテクチャを持ち、上記の機能を使用する場合があります。この目的を達成するために、このような複雑な要件をサポートするリソースKubernetesが導入されていますStatefulSet

StatefulSetに似ていますが、起動シーケンスを処理し、それぞれの状態を保持するための一意の識別子を設定することReplicaSetができます。また、次の機能があります。PodPod

  • 安定した一意のネットワーク識別子
  • 安定した永続的なストレージ
  • 秩序ある適切なデプロイメントとスケーリング
  • 秩序ある適切な削除と終了
  • 秩序ある自動ローリング更新

ステートフルセットを作成する

StatefulSet次に、オブジェクトの使用方法を示します。開始する前に、2 つの 1G ストレージ ボリューム (PV) を準備します。次のコースでは、PV と PVC の使用方法についても詳しく説明します。これについては掘り下げませんここ: (pv001.yaml)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    release: stable
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  hostPath:
    path: /tmp/data

もう 1 つは、名前を pv002 に変更して、以下を作成するだけです。

$ kubectl create -f pv001.yaml && kubectl create -f pv002.yaml
persistentvolume "pv001" created
persistentvolume "pv002" created
$ kubectl get pv
kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
pv001     1Gi        RWO            Recycle          Available                                      12s
pv002     1Gi        RWO            Recycle          Available                                      11s

2 つの PV オブジェクトが正常に作成され、ステータスが「Available」になっていることがわかります。

次に、それを使用してStatefulSetNginx ポッドを作成します。このタイプのリソースの場合、通常、ヘッドレス サービスとして設定されるHeadless Serviceサービスのタイプを作成してサービスを公開します: (statefulset-demo.yaml)clusterIPNone

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
    role: stateful

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
      role: stateful
  template:
    metadata:
      labels:
        app: nginx
        role: stateful
    spec:
      containers:
      - name: nginx
        image: cnych/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

volumeMounts新しい属性が上記の YAML ファイルvolumeClaimTemplatesに関連付けられていることに注意してください。これにより、管理用の pvc オブジェクトと pv が自動的に宣言されます。

次に、ここで 2 つのターミナル ウィンドウを開きます。最初のターミナルで、kubectl get を使用して、StatefulSet の Pod の作成を表示します。

$ kubectl get pods -w -l role=stateful

別のターミナルで、kubectl create を使用して、statefulset-demo.yaml で定義されたヘッドレス サービスと StatefulSet を作成します。

$ kubectl create -f statefulset-demo.yaml
service "nginx" created
statefulset.apps "web" created

ポッドの順序インデックスを確認する

N 個のレプリカを持つ StatefulSet の場合、ポッドはデプロイ時に {0…N-1} の順序で作成されます。最初のターミナルでは、次の情報が表示されます。

$ kubectl get pods -w -l role=stateful
NAME      READY     STATUS    RESTARTS   AGE
web-0     0/1       Pending   0          0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         19s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         18s

web-0 ポッドが実行状態および準備完了状態になるまで、web-1 ポッドは開始されないことに注意してください。

StatefulSet の概念で述べたように、StatefulSet 内のポッドは安定した一意の ID を持ちます。このフラグは、StatefulSet コントローラーによって各 Pod に割り当てられた一意の順次インデックスに基づいています。ポッド名の形式は です<statefulset name>-<ordinal index>Web StatefulSet には 2 つのレプリカがあるため、web-0 と web-1 の 2 つのポッドを作成します。

上記のコマンドは、それぞれ NGINX Web サーバーを実行する 2 つのポッドを作成します。nginx サービスと Web StatefulSet を取得して、それらが正常に作成されたことを確認します。

$ kubectl get service nginx
NAME      CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx     None         <none>        80/TCP    12s
$ kubectl get statefulset web
NAME      DESIRED   CURRENT   AGE
web       2         1         20s

安定したネットワーク ID を使用する

各ポッドには、シーケンシャルインデックスに基づいた安定したホスト名があります。kubectl exec を使用して各 Pod でホスト名を実行します。

$ for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1

次に、kubectl run を使用して、nslookup コマンドを提供するコンテナーを実行します。Pod のホスト名に対して nslookup を実行すると、クラスター内の DNS アドレスを確認できます。

$ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh 
nslookup web-0.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.244.1.6

nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-1.nginx
Address 1: 10.244.2.6

ヘッドレス サービスの CNAME は SRV レコードを指します (各ポッドを実行中および準備完了状態でログに記録します)。SRV レコードは、ポッドの IP アドレスを含むレコード エントリを指します。

次に、StatefulSet の下の Pod を削除することを見てみましょう。

ターミナルで StatefulSet ポッドを表示します。

$ kubectl get pod -w -l role=stateful

別のターミナルで kubectl delete を使用して、StatefulSet 内のすべての Pod を削除します。

$ kubectl delete pod -l role=stateful
pod "web-0" deleted
pod "web-1" deleted

StatefulSet がそれらを再起動し、両方の Pod が実行中および準備完了になるまで待ちます。

$ kubectl get pod -w -l app=nginx
NAME      READY     STATUS              RESTARTS   AGE
web-0     0/1       ContainerCreating   0          0s
web-0     1/1       Running   0          2s
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         34s

次に、kubectl exec を使用し、kubectl run を再度実行して、ポッドのホスト名とクラスター内の DNS エントリを表示します。

$ for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1
$ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh 
nslookup web-0.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.244.1.7

nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-1.nginx
Address 1: 10.244.2.8

ポッドの序数、ホスト名、SRV エントリ、およびレコード名は変更されていないことがわかりますが、ポッドに関連付けられた IP アドレスは変更されている可能性があります。このため、他のアプリケーションからの接続には StatefulSet 内の Pod の IP アドレスを使用しないことが重要です。一般に、SRV レコード web-0.nginx、web-1.nginx を介して直接接続できます。これらは安定しているため、ポッドのステータスが実行中および準備完了に変わると、アプリケーションはそれらのアドレスを検出できます。

同様に、PV と PVC の最終的なバインディング ステータスを確認できます。

$ kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM               STORAGECLASS   REASON    AGE
pv001     1Gi        RWO            Recycle          Bound     default/www-web-0                            1h
pv002     1Gi        RWO            Recycle          Bound     default/www-web-1                            1h
$ kubectl get pvc
NAME        STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
www-web-0   Bound     pv001     1Gi        RWO                           22m
www-web-1   Bound     pv002     1Gi        RWO                           22m

ストレージボリュームの使用方法については後で説明するため、混乱を避けるためにここでは説明しません。

もちろん、StatefulSet には他の機能もあります。実際のプロジェクトでは、自分で完全に保持できない限り、StatefulSet を介して直接ステートフル サービスをデプロイするために戻ることはまだほとんどありません。一部の特定のサービスについては、より高度な Operator を使用してデプロイする場合があります。 etcd-operator、prometheus-operator など。これらのアプリケーションは、単に StatefulSet を使用して Pod をデプロイするのではなく、ステートフル サービスを適切に管理できます。これは、ステートフル アプリケーションにとって最も重要なことはデータ リカバリ、フェイルオーバーなどであるためです。


おすすめ

転載: blog.csdn.net/u010674953/article/details/129535745