K8s (Kubernetes) 学習 (4): コントローラー コントローラー: デプロイ、StatefulSet、Daemonset、ジョブ

  • コントローラーとその役割とは何ですか
  • 共通コントローラ コントローラ
  • コントローラーがポッドを管理する方法
  • 導入の基本操作と応用
  • コントローラーを介してポッドのアップグレードのロールバックと柔軟なスケーリングを実装する
  • StatefulSetの基本操作と応用
  • Daemonsetの基本操作と応用
  • ジョブの基本操作と応用
  • コントローラーでは問題を解決できません

1 コントローラーコントローラー

公式ウェブサイト: http://kubernetes.p2hp.com/docs/concepts/architecture/controller.html

1.1 コントローラーとは

Kubernetes 通常不会直接创建 Pod, 而是通过 Controller 来管理 Pod 的。ポッドのデプロイメント特性 (コピーの数、どのノードで実行されるかなど) はコントローラーで定義されます平たく言えば、ControllerはPodを管理するためのオブジェクトであると考えることができます。その中心的な役割は、次の一文に要約できます。通过监控集群的公共状态,并致力于将当前状态转变为期望的状态。

一般的な定義: コントローラーはポッドを管理して、ポッドの運用とメンテナンスの能力を高めることができます。

1.2 共通コントローラ コントローラ

  • Deployment最も一般的に使用されるコントローラーです。デプロイメントでは、Pod の複数のコピーを管理し、Pod が期待どおりに実行されていることを確認できます。

    • ReplicaSetはPodの複数コピー管理を実現します。ReplicaSet は、Deployment を使用するときに自動的に作成されます。つまり、Deployment は ReplicaSet を通じて Pod の複数のコピーを管理し、通常は ReplicaSet を直接使用する必要はありません。
  • Daemonset各ノードが最大 1 つのポッド コピーを実行するシナリオで使用されます。その名前が示すように、DaemonSet は通常、デーモンを実行するために使用されます。

  • Statefulesetこれにより、Pod の各コピーの名前がライフサイクルを通じて変更されないことが保証されますが、他のコントローラーはこの機能を提供しません。ポッドに障害が発生し、削除して再起動する必要がある場合、ポッドの名前が変更され、StatefuleSet によってレプリカが固定された順序で起動、更新、または削除されるようになります。

  • Job他のコントローラーのポッドは通常、長時間継続して実行されますが、実行後に削除されるアプリケーションに使用されます。

1.3 コントローラーはポッドをどのように管理するか

注意: Controller 通过 label 关联起来 Pods

画像-20230307105007568

2 展開

公式アドレス: http://kubernetes.p2hp.com/docs/concepts/workloads/controllers/deployment.html

Deployment は、Pod と ReplicaSet の宣言的な更新機能を提供します。

デプロイメントでターゲットの状態を記述するのはユーザーの責任であり、デプロイメント コントローラー (コントローラー) は実際の状態を制御された速度で変更して、望ましい状態にします。Deployment を定義して新しい ReplicaSet を作成したり、既存の Deployment を削除してそのリソースを新しい Deployment を通じて採用したりできます。

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.19
          ports:
            - containerPort: 80

2.2 展開を表示する

# 部署应用
$ kubectl apply -f app.yaml
# 查看 deployment
$ kubectl get deployment
# 查看 pod
$ kubectl get pod -o wide
# 查看 pod 详情
$ kubectl describe pod pod-name
# 查看 deployment 详细
$ kubectl describe deployment 名称
# 查看 log
$ kubectl logs pod-name
# 进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。
$ kubectl exec -it pod-name -- bash
# 输出到文件
$ kubectl get deployment nginx-deployment -o yaml >> test.yaml
  • NAMEネームスペース内のデプロイメントの名前をリストします。
  • READY利用可能なアプリケーションの「コピー」数を表示します。表示されるパターンは「Ready Count/Expected Count」です。
  • UP-TO-DATE望ましい状態を達成するために更新されたレプリカの数を示します。
  • AVAILABLEユーザーが利用できるアプリのコピー数を表示します。
  • AGEアプリケーションの実行時間を表示します。

必要なレプリカの数は.spec.replicasフィールド 3 に従って設定されることに注意してください。

2.3 スケーリング展開

# 查询副本
$ kubectl get rs|replicaset
# 伸缩扩展副本
$ kubectl scale deployment nginx --replicas=5

2.4 ロールバック展開

例証します:

.spec.templateDeployment go-liveは、テンプレートのタグやコンテナー イメージが更新されるなど、Deployment Pod テンプレート (つまり ) が変更された場合にのみトリガーされます。他の更新 (デプロイメントの拡張または縮小など) は、ライブ稼働アクションをトリガーしません。

# 查看上线状态
$ kubectl rollout status [deployment nginx-deployment | deployment/nginx]
# 查看历史
$ kubectl rollout history deployment nginx-deployment
# 查看某次历史的详细信息
$ kubectl rollout history deployment/nginx-deployment --revision=2
# 回到上个版本
$ kubectl rollout undo deployment nginx-deployment
# 回到指定版本
$ kubectl rollout undo deployment nginx-deployment --to-revision=2
# 重新部署
$ kubectl rollout restart deployment nginx-deployment
# 暂停运行,暂停后,对 deployment 的修改不会立刻生效,恢复后才应用设置
$ kubectl rollout pause deployment ngixn-deployment
# 恢复
$ kubectl rollout resume deployment nginx-deployment

2.5 デプロイメントの削除

# 删除 Deployment
$ kubectl delete deployment nginx-deployment
$ kubect delete -f nginx-deployment.yml
# 删除默认命名空间下全部资源
$ kubectl delete all --all
# 删除指定命名空间的资源
$ kubectl delete all --all -n 命名空间的名称

3 ステートフルセット

3.1 ステートフルセットとは

公式アドレス: https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/statefulset/

StatefulSet は、有状态应用管理に使用されるワークロード API オブジェクトです。

ステートレス アプリケーション: アプリケーション自体にデータを格納しないアプリケーションは、ステートレス アプリケーションと呼ばれます。

ステートフル アプリケーション: アプリケーション自体が関連データを保存する必要があり、このアプリケーションはステートフル アプリケーションと呼ばれます。

ブログ: フロントエンド vue バックエンド Java mysql redis…

データ取得: 取得手順のステートフルな適用

StatefulSet は、Pod コレクションのデプロイメントと拡張を管理し、これらの Pod に永続的なストレージと永続的な識別子を提供するために使用されます。

Deployment と同様に、StatefulSet は同じコンテナ仕様に基づいて Pod のセットを管理します。ただし、Deployment とは異なり、StatefulSet は各 Pod のスティッキー ID を維持します。これらの Pod は同じプロトコルに基づいて作成されますが、交換可能ではありません。どのようにスケジュールされているかに関係なく、各 Pod は永続的な ID を持ちます。

ストレージ ボリュームを使用してワークロードに永続ストレージを提供する場合は、ソリューションの一部として StatefulSet を使用できます。StatefulSet 内の個々の Pod で障害が発生する可能性はありますが、永続的な Pod 識別子により、既存のボリュームと、障害が発生した Pod を置き換える新しい Pod との照合が容易になります。

3.2 ステートフルセットの機能

StatefulSet は、次の要件の 1 つ以上を満たす必要があるアプリケーションにとって価値があります。

  • 安定した一意のネットワーク識別子。
  • 安定した耐久性のある保管。
  • 秩序正しく適切なデプロイメントとスケーリング。
  • 秩序ある自動ローリング更新。

上記の説明では、「安定」とは、Pod のスケジューリングまたは再スケジューリングのプロセス全体が永続的であることを意味します。アプリケーションが安定した識別子や秩序あるデプロイ、削除、スケーリングを必要としない場合、アプリケーションは、ステートレス レプリカ コントローラーのセットによって提供されるワークロードを使用してデプロイされる必要があります。ステートレス アプリケーションのデプロイメントには、Deployment または ReplicaSet の方が適している場合があります。ニーズ。

3.3 制限事項

  • 特定のポッドのストレージは、要求された に基づいて Persistent Volume Provisioner によってstorage classプロビジョニングされるか、管理者によって事前にプロビジョニングされる必要があります。
  • StatefulSet を削除またはスケーリングしても、関連付けられているストレージ ボリュームは削除されません。これはデータを安全に保つために行われ、通常、StatefulSet のすべての関連リソースを自動的にクリアするよりも価値があります。
  • 現在、StatefulSet では、ポッドのネットワーク ID を担当するヘッドレス サービスが必要です。このサービスを作成するのはあなた自身の責任です。
  • StatefulSet が削除された場合、StatefulSet は Pod を終了する保証を提供しません。StatefulSet 内の Pod を秩序正しく適切に終了するには、削除前に StatefulSet を 0 にスケールダウンします。
  • デフォルトのポッド管理ポリシー ( )OrderedReadyでローリング アップデートを使用すると、修正するには手動介入が必要となる破損した状態になる可能性があります。

3.4 ステートフルセットの使用

1 NFS サービスを構築する
#安装nfs-utils
$ yum install -y rpcbind nfs-utils
#创建nfs目录
mkdir -p /root/nfs/data
#编辑/etc/exports输入如下内容 
# insecure:通过 1024 以上端口发送 rw: 读写 sync:请求时写入共享 no_root_squash:root用户有完全根目录访问权限
echo  "/root/nfs/data *(insecure,rw,sync,no_root_squash)" >> /etc/exports
#启动相关服务并配置开机自启动
systemctl start rpcbind
systemctl start nfs-server
systemctl enable rpcbind
systemctl enable nfs-server
#重新挂载 使 /etc/exports生效
exportfs -r
#查看共享情况
exportfs
2 クライアントテスト
# 1.安装客户端 所有节点安装
$ yum install -y nfs-utils
# 2.创建本地目录
$ mkdir -p /root/nfs
# 3.挂载远程nfs目录到本地
$ mount -t nfs 10.15.0.9:/root/nfs /root/nfs
# 4.写入一个测试文件
$ echo "hello nfs server" > /root/nfs/test.txt
# 5.去远程 nfs 目录查看
$ cat /root/nfs/test.txt

# 挂取消载
$ umount -f -l nfs目录
3 ステートフルセットを使用する
  • クラス.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"
  • nfsクライアントプロバイダー
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: kube-system
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: chronolaw/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 10.15.0.10
            - name: NFS_PATH
              value: /root/nfs/data
      volumes:
        - name: nfs-client-root
          nfs:
            server: 10.15.0.10
            path: /root/nfs/data
  • rbac.yml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: kube-system
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: kube-system
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
  • mysql.yml
apiVersion: v1
kind: Namespace
metadata:
  name: ems
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: mysql-nfs-sc
  namespace: ems
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  onDelete: "remain"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  labels:
    app: mysql
  namespace: ems
spec:
  serviceName: mysql #headless 无头服务  保证网络标识符唯一  必须存在
  replicas: 1
  template:
    metadata:
      name: mysql
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql/mysql-server:8.0
          imagePullPolicy: IfNotPresent
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: root
          volumeMounts:
            - mountPath: /var/lib/mysql #自己容器写入数据目录
              name: data    #保存到指定一个变量中 变量名字就是 data
          ports:
            - containerPort: 3306
      restartPolicy: Always
  volumeClaimTemplates:  #声明动态创建数据卷模板
    - metadata:
        name: data      # 数据卷变量名称
        namespace: ems  # 在哪个命名空间创建数据卷
      spec:
        accessModes:    # 访问数据卷模式是什么  
          - ReadWriteMany
        storageClassName: mysql-nfs-sc # 使用哪个 storage class 模板存储数据
        resources:
          requests:
            storage: 2G
  selector:
    matchLabels:
      app: mysql
---

4 デーモンセット

4.1 DaemonSet とは

https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/daemonset/

DaemonSet は、すべて (または一部) のノードが Pod のコピーを実行することを保証します。ノードがクラスターに参加すると、それらのノードにポッドが追加されます。これらのポッドは、ノードがクラスターから削除されたときにもリサイクルされます。DaemonSet を削除すると、DaemonSet が作成したすべての Pod が削除されます。

DaemonSet の一般的な使用法をいくつか示します。

  • 各ノードでクラスターデーモンを実行する
  • 各ノードでログ収集デーモンを実行する
  • 各ノードで監視デーモンを実行する

簡単な使用法は、デーモンの種類ごとにすべてのノードで DaemonSet を開始することです。もう少し複雑な使用法は、同じ種類のデーモンに対して複数の DaemonSet をデプロイすることであり、それぞれが異なるフラグ、異なるメモリ、異なるハードウェア タイプの CPU 要件を持ちます。

4.2 DaemonSet の使用

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.19
        imagePullPolicy: IfNotPresent
        name: nginx
        resources: {
    
    }
      restartPolicy: Always

5 仕事

5.1 ジョブとは

https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/job/

ジョブは 1 つ以上の Pod を作成し、指定された数の Pod が正常に終了するまで Pod の実行を再試行し続けます。ポッドが正常に完了すると、ジョブは正常に完了したポッドの数を追跡します。数値が指定された成功しきい値に達すると、タスク (つまり、ジョブ) が終了します。ジョブを削除すると、作成されたすべてのポッドがクリアされます。ジョブを一時停止する操作では、ジョブが再び再開されるまで、ジョブのアクティブなポッドがすべて削除されます。

単純な使用例では、信頼性の高い方法でポッドを完了まで実行するジョブ オブジェクトを作成します。最初の Pod が失敗するか削除されると (ノードのハードウェア障害や再起動などにより) Job オブジェクトは新しい Pod を開始します。

ジョブを使用して複数の Pod を並行して実行することもできます。

5.2 ジョブの使用

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  # 当前任务出现失败 最大的重试次数
  backoffLimit: 4

5.3 自動的にクリーンアップされるジョブ

完了したジョブは通常、システム内に保持する必要はありません。これらをシステム内に常に保持すると、API サーバーに余分な負荷がかかります。ジョブがCronJobなどの上位レベルのコントローラーによって管理されている場合、ジョブは特定の容量ベースのクリーンアップ戦略に基づいて CronJob によってクリーンアップできます。

  • 完了したジョブの TTL メカニズム
    • Complete完了したジョブ (ステータスまたは)を自動的にクリーンアップするもう 1 つの方法Failedは、TTL コントローラが提供する TTL メカニズムを使用することです。Job.spec.ttlSecondsAfterFinishedフィールドを設定すると、コントローラーは完了したリソースをクリーンアップできます。TTL コントローラがジョブをクリーンアップすると、ジョブ オブジェクトがカスケードで削除されます。つまり、ポッドやジョブ自体を含むすべての依存オブジェクトが削除されます。ジョブが削除されるとき、システムはファイナライザーなどのライフサイクル保証を考慮することに注意してください。
apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-ttl
spec:
  ttlSecondsAfterFinished: 100
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

ジョブはpi-with-ttl終了後 100 秒後に自動的に削除できます。このフィールドが に設定されている場合0、ジョブは終了直後に自動的に削除可能になります。このフィールドが設定されていない場合、ジョブは完了後に TTL コントローラによって自動的にクリアされません。

6 コントローラーでは問題を解決できない

  • ポッドにネットワーク サービスを提供する方法
  • 複数のポッド間で負荷分散を実現する方法

おすすめ

転載: blog.csdn.net/qq_45808700/article/details/132714304