当前位置: 首页 > article >正文

K8S基础知识:DaemonSet、Deployment、StatefulSet的用法区别

在 K8s 中,DaemonSet、Deployment 和 StatefulSet 都是用于管理 Pod 的资源对象,但它们的设计目的和适用场景有所不同,以下是它们用法的详细区别:

一、deployment

Deployment 用于管理无状态应用的多个 Pod 副本,它提供了声明式的方式来创建、更新和删除 Pod。Deployment 通过控制 ReplicaSet 来确保指定数量的 Pod 副本始终处于运行状态。

适用场景:

  • Web 应用:适合部署 Web 服务器、API 服务等无状态应用。这些应用可以通过水平扩展来处理更多的流量, 可以方便地进行副本数量的调整和版本的更新。
  • 微服务架构:在微服务架构中,Deployment 可以用于管理各个微服务的 Pod,实现微服务的快速部署和更新。

作用:

  • 管理 Pod 副本:通过 Deployment 可以轻松地指定 Pod 的副本数量 replicas,确保应用程序具有足够的实例来处理负载。
  • 滚动更新:支持对应用程序进行滚动更新,即在不中断服务的情况下逐步替换旧版本的 Pod 为新版本
  • 回滚:如果在更新过程中发现问题,Deployment 允许快速回滚到上一个稳定版本。Kubernetes 会自动将 Pod 恢复到之前的状态,确保服务的稳定性。
  • 标签选择器通过标签选择器来关联 Pod,能够方便地对一组具有相同标签的 Pod 进行管理和操作。例如,通过标签选择器app: my-app可以选中所有属于该应用的 Pod,进行统一的升级、扩缩容等操作。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3        // 期望有 3 个副本
  selector:
    matchLabels:
      apps: my-app   // Deployment 会管理所有带有标签 apps: my-app标签的 Pod
  template:
    metadata:
      labels:
        apps: my-app // Pod 的标签的,跟上面 Deployment 标签关联
    spec:
      containers:
      - name: my-container
        image: my-image:latest
        ports:
        - containerPort: 80

常用操作:

以下是一个完整的示例,通过更新一个 Nginx 应用来展示相关操作:

# 查看当前Deployment
kubectl get deployments -n your-namespace

# 编辑Deployment
kubectl edit deployment nginx-deployment -n your-namespace

# 修改镜像版本
# 在编辑器中找到并修改 image 字段为新的版本
# image: nginx:1.21.0

# 保存并退出编辑器

# 监控滚动更新过程
kubectl rollout status deployment nginx-deployment -n your-namespace

# 查看Deployment历史版本
kubectl rollout history deployment nginx-deployment -n your-namespace

# 若需要回滚更新
kubectl rollout undo deployment nginx-deployment -n your-namespace

二、StatefulSet

StatefulSet 用于管理有状态应用的 Pod,它为每个 Pod 提供了稳定的网络标识和持久存储。StatefulSet 中的 Pod 有固定的名称和顺序,并且在删除和重新创建时会保留其状态。

适用场景:

  • 数据库:适合部署有状态的数据库,如 MySQL、MongoDB 等。这些数据库需要稳定的网络标识和持久存储来保证数据的一致性和可靠性。
  • 分布式系统:在分布式系统中,一些节点需要有固定的身份和顺序,如 ZooKeeper、Kafka 等,StatefulSet 可以满足这些需求。

特点:

  • Pod 命名的稳定性:StatefulSet 中的每个 Pod 都有一个稳定且唯一的名称,名称格式为<statefulset名称>-<序号>,例如 mysql-0mysql-1 等。这个稳定的命名在关联 PVC 时起到关键作用,即使 Pod 被删除和重新创建,名称也不会改变
  • PVC 命名规则:StatefulSet 使用 PVC 模板(volumeClaimTemplates)为每个 Pod 创建 PVC,PVC 的命名也与 Pod 相关联。通常 PVC 的名称格式为<PVC模板名称>-<Pod名称>,比如 mysql-pvc-mysql-0。由于 Pod 名称稳定,重新创建 Pod 时,Kubernetes 会根据这个规则找到对应的 PVC
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: zookeeper
#  namespace: kafka
spec:
  serviceName: zookeeper
  replicas: 3        # 副本数
  selector:
    matchLabels:
      app: zookeeper # StatefulSet 也会管理所有带有标签 app: zookeeper 标签的 Pod
  template:
    metadata:
      labels:
        app: zookeeper # pod标签
    spec:
      containers:
      - name: zookeeper
        image: bitnami/zookeeper:3.9.2
        ports:
          - containerPort: 2181
            name: client
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        env:
          - name: ALLOW_ANONYMOUS_LOGIN
            value: "yes"
        volumeMounts:
        - name: zookeeper-data
          mountPath: /bitnami/zookeeper # 定义了挂载到容器中的持久卷的名称及在容器内的挂载路径
      restartPolicy: Always # 可选 ,默认Always:无论如何停止,都会自动重启pod容器
      securityContext:
        runAsUser: 0
        fsGroup: 0
  volumeClaimTemplates:  # PVC模版
    - metadata:
        name: zookeeper-data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        resources:
          requests:
            storage: 1Gi

常用操作:

# 查看特定命名空间下的所有 StatefulSet:
kubectl get statefulsets -n your-namespace

# 使用 kubectl edit 命令编辑 StatefulSet 的 YAML 文件:
kubectl edit statefulset your-statefulset-name -n your-namespace

# 用以下命令监控更新进度:
kubectl rollout status statefulset your-statefulset-name -n your-namespace

# 若在更新过程中发现问题,可以使用以下命令回滚到上一个稳定版本:
kubectl rollout undo statefulset your-statefulset-name -n your-namespace

# 如果需要回滚到指定版本,可以添加 --to-revision 参数:
kubectl rollout undo statefulset your-statefulset-name --to-revision=2 -n your-namespace

三、DaemonSet

DaemonSet 的主要目的是确保在集群中的每个节点(或满足特定条件的节点)上都运行一个且仅运行一个 Pod 副本。每当有新节点加入集群时,DaemonSet 会自动在该节点上创建一个 Pod;当节点从集群中移除时,对应的 Pod 也会被自动删除。

适用场景:

  • 系统层面服务:适合部署一些需要在每个节点上运行的系统级服务,如日志收集器(Fluentd、Filebeat)、监控代理(Prometheus Node Exporter)等。这些服务需要收集每个节点的日志或监控数据,因此需要在每个节点上都有一个实例。
  • 存储服务:在某些情况下,需要在每个节点上运行存储相关的服务,如分布式存储系统的客户端,以确保每个节点都能访问存储资源。

特点:

  • 每个节点运行一个实例:DaemonSet 的核心特点是确保在集群中的每个符合条件的节点上都运行一个且仅运行一个指定的 Pod 副本。当有新节点加入集群时,DaemonSet 会自动在该节点上创建对应的 Pod;而当节点从集群中移除时,该节点上的 Pod 也会被自动删除。。
  • 节点选择:可以通过节点选择器(Node Selector)或节点亲和性(Node Affinity)来指定 DaemonSet 中的 Pod 应该运行在哪些特定的节点上。比如,你可以根据节点的标签(如节点的角色、硬件特性等)来筛选节点,让 Pod 只在具有特定标签的节点上运行。
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: logger-agent
  labels: 
    apps: logger-agent
spec:
  selector:
    matchLabels:
      apps: logger-agent-pod
  template:
    metadata:
      labels:
        apps: logger-agent-pod
    spec:
      tolerations: # pod 配置添加容忍 Master节点的污点 (也就是说,即使master节点有污点,也会被调度)( tolerations是一个列表字段,用于指定 Pod 可以容忍的节点污点)
      - key: "node-role.kubernetes.io/master" # 这里定义了要容忍的污点的 key 值
        operator: "Exists" # 定义了污点的操作符,Exists 表示节点必须存在这个污点才能被容忍,而 NoSchedule 表示节点不能被调度到。
#        value: "NoSchedule" # 定义了要容忍的污点的 value 值,可以为空。
        effect: "NoSchedule" # 定义了容忍的效果,即 Pod 可以调度到那些设置了 NoSchedule 效果的污点的节点上
      volumes:  # 映射Pod对外的挂载
      - name: logger-agent-log # Pod要挂载的名称指代,即指向volumeMounts的name
        hostPath: # 采用主机目录的挂载方式
          path: /data/log/ac-logger-agent
          type: DirectoryOrCreate #没有的话,会自动创建目录
      - name: log-path
        hostPath:
          path: /data/log/
          type: DirectoryOrCreate
      containers:
      - name: logger-agent
        image: logger-agent:v1.02
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          protocol: TCP
          containerPort: 5046
        volumeMounts: # Pod的数据卷挂载
        - name: logger-agent-log
          mountPath: /log
        - name: log-path
          mountPath: /data/log/
        env:
          - name: LOG_DIR 
            value: /data/log/
          - name: LOG_LEVEL # 日志打印级别
            value: INFO
        envFrom:
          - configMapRef:
              name: access-env

四、StatefulSet 与 Deployment 的滚动更新差异

  • 更新顺序:StatefulSet 默认采用顺序更新,即从编号最大的 Pod 开始逐个更新,这是为了保证有状态应用的稳定性。而 Deployment 的滚动更新可以根据配置并行更新多个 Pod。
  • 网络标识和存储:StatefulSet 中的每个 Pod 有稳定的网络标识和持久存储,更新过程中这些标识和存储会得到保留。而 Deployment 管理的无状态 Pod 在更新时通常不会关注这些特性。
  • 更新策略:StatefulSet 支持 OnDelete 和 RollingUpdate 两种更新策略。OnDelete 策略下,需要手动删除 Pod 才会触发更新;RollingUpdate 则会自动进行滚动更新。Deployment 默认使用 RollingUpdate 策略。

http://www.kler.cn/a/611091.html

相关文章:

  • 【MySQL】索引 事务
  • 《基于python游戏设计与实现》开题报告
  • 创新前沿 | 接管主机即刻增量CDP备份,高效保障接管期间业务安全!
  • 基于腾讯云大模型知识引擎×DeepSeek的高等职业学校单独招生二级学院考前咨询系统
  • CentOS7 离线部署MySQL8.0+
  • 建造者模式的优点及其在优秀框架中的实现案例
  • GitLab 中文版17.10正式发布,27项重点功能解读【一】
  • 贪心算法经典应用:最优答疑调度策略详解与Python实现
  • Headless Chrome 优化:减少内存占用与提速技巧
  • Spring AI Alibaba ImageModel使用
  • 需求导向的K8S网络原理分析:Kube-proxy、Flannel、Calico的地位和作用
  • 浏览器存储 IndexedDB
  • CentOS 8 安装 Redis 全流程指南:从基础部署到远程安全配置
  • 无线安灯按钮盒汽车零部件工厂的故障告警与人员调度专家
  • 创建一个服务器启动自动执行的脚本,设置默认路由
  • 【MinIO】可靠的分布式MinIO集群部署
  • 基于深度学习的相位调制算法步骤
  • Android UI 组件系列(三):ImageView 使用技巧与图像加载
  • Unity游戏开发如何优化移动端的延迟渲染管线?
  • python笔记之判断月份有多少天