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 支持 OnDeleteRollingUpdate 两种更新策略。OnDelete 策略下,需要手动删除 Pod 才会触发更新;RollingUpdate 则会自动进行滚动更新。Deployment 默认使用 RollingUpdate 策略。
相关推荐
张青贤1 小时前
K8s中的containerPort与port、targetPort、nodePort的关系:
云原生·容器·kubernetes
云攀登者-望正茂3 小时前
AKS 支持 Kata Container容器沙盒 -预览阶段
容器·azure
撸码到无法自拔5 小时前
docker常见命令
java·spring cloud·docker·容器·eureka
小马爱打代码7 小时前
K8S - GitLab CI 自动化构建镜像入门
ci/cd·kubernetes·gitlab
zhojiew7 小时前
istio in action之服务网格和istio组件
云原生·istio
hi,编程哥10 小时前
Docker、ECS 与 K8s 网段冲突:解决跨服务通信中的路由问题
docker·容器·kubernetes
How_doyou_do10 小时前
项目全栈实战-基于智能体、工作流、API模块化Docker集成的创业分析平台
运维·docker·容器
代码的奴隶(艾伦·耶格尔)10 小时前
微服务!!
微服务·云原生·架构
Cloud Traveler13 小时前
Kubernetes vs. OpenShift:深入比较与架构解析
架构·kubernetes·openshift
是垚不是土14 小时前
探秘高可用负载均衡集群:企业网络架构的稳固基石
运维·服务器·网络·云原生·容器·架构·负载均衡