Kubernetes——Pod控制器

发布于:2024-06-02 ⋅ 阅读:(63) ⋅ 点赞:(0)

目录

一、Pod控制器

1.定义

2.Pod与控制器的关系

3.作用

4.Pod控制器的类型组成及特点

4.1Pod控制器的类型

4.1.1ReplicaSet

4.1.2Deployment

4.1.3DaemonSet

4.1.4StateSet

4.1.5Job

4.1.6CronJob

4.2Pod与控制器的关系

二、Kubernetes中的服务发现

1.服务发现的需求

2.Kubernetes DNS 服务

3.DNS 插件的演变

4.CoreDNS 的特点

5.安装CoreDNS(仅在二进制部署环境需要安装CoreDNS)

5.1方法一 下载并配置

5.2上传配置文件

三、Pod与控制器之间的关系

1.Deployment(更新资源)控制器

2.StatefulSet(管理有状态应用)控制器

2.1StatefulSet的三个关键组成部分以及其作用

2.2为什么要有Headless

2.3为什么要有VolumeClainTemplate

2.4清单定义StatefulSet

2.5创建、管理和删除StatefulSet

2.5.1创建StatefulSet

2.5.2查看StatefulSet

2.3滚动更新

2.4扩容和伸缩

3.DaemonSet(工作负载)控制器

3.1关键特性

3.2典型用例

3.3应用场景

3.4实例

4.Job(特殊的工作负载)控制器

4.1普通Job(Job)

4.2定时任务(CronJob)

4.3应用场景

4.4实例

5.CronJob(管理周期性任务的工作负载)控制器

5.1CronJob的关键特性

5.2应用场景

5.3实例

四、总结

1.有状态和无状态的区别

2.常见Service和无头服务的区别

3.Pod控制器

4.Deployment与Statefulset的区别

4.1 应用场景

4.2 Pod管理

4.3 存储与网络

4.4 升级与回滚

4.5 扩展性


一、Pod控制器

1.定义

在 Kubernetes 中,Pod 控制器是一种管理 Pod 的中间层。使用 Pod 控制器,只需告诉它想要多少个什么样的 Pod,它会创建出满足条件的 Pod 并确保每个 Pod 资源处于用户期望的目标状态。如果 Pod 在运行中出现故障,控制器会根据指定策略重新编排或重建 Pod。常见的 Pod 控制器包括 ReplicaSetDeploymentStatefulSet 等,每种都适用于不同的场景和需求。

Pod控制器,又称之为工作负载(workload),是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。

2.Pod与控制器的关系

Pod和控制器在Kubernetes中的关系是相互依赖的。Pod是Kubernetes中的基本工作单元,而控制器则是用来管理Pod生命周期和行为的高级抽象。下面是它们之间的关系:

  • 管理关系:控制器通过定义期望的状态(如Pod的数量、配置等)来管理Pod。控制器会监视Pod的实际状态,并在发现任何偏差时采取措施来恢复到期望状态。
  • 生命周期管理:当Pod因为某些原因(如节点故障、Pod崩溃等)无法正常运行时,控制器会根据其策略(如重启、替换等)来处理这些Pod,确保应用的高可用性。
  • 自动化操作:控制器可以自动执行滚动更新、回滚、扩缩容等操作,这些操作通常涉及到Pod的创建、删除和更新。
  • 标签和选择器:Pod通过标签(Labels)与控制器关联。控制器使用标签选择器(Label Selector)来识别它所管理的Pod。这样,控制器就可以对一组具有相同标签的Pod执行操作。
  • 服务发现:控制器(如Deployment或StatefulSet)可以与服务(Service)关联,服务负责为Pod提供稳定的网络标识和负载均衡。这样,其他Pod或外部客户端可以通过服务来访问这些Pod,而不需要知道具体的Pod信息。
  • 持久化存储:对于需要持久化数据的Pod,控制器(如StatefulSet)会管理与这些Pod关联的持久化存储卷(PersistentVolumes和PersistentVolumeClaims),确保Pod在重启或迁移后能够访问到其数据。
  • 任务执行:对于一次性任务(Job)或周期性任务(CronJob),控制器负责调度这些任务的执行,并在任务完成后进行清理。
  • 声明式配置:用户通过定义控制器的配置(如Deployment的YAML文件),控制器会根据这些声明式配置来管理Pod。这种方式使得用户可以专注于期望的结果,而不是具体的操作步骤。

总结来说,Pod是Kubernetes中执行应用的实体,而控制器则是负责确保这些Pod按照用户定义的期望状态运行的管理者。控制器通过自动化和声明式配置,简化了Pod的管理,提高了集群的运维效率。

3.作用

  • 确保期望状态:Pod控制器负责确保Pod的运行状态与用户定义的期望状态相匹配。如果Pod因为某些原因(如节点故障、Pod崩溃等)与期望状态不一致,控制器会采取措施来恢复Pod,使其回到期望状态。
  • 自动重启:当Pod失败或被删除时,Pod控制器会根据其配置自动重启Pod,以保证Pod的数量和状态符合用户的设定。
  • 滚动更新:对于Deployment和StatefulSet等控制器,它们支持滚动更新(Rolling Update)策略,这意味着在更新Pod时,旧的Pod会逐渐被新的Pod替换,而不会一次性全部替换,从而减少服务中断时间。
  • 回滚:如果更新后的Pod出现问题,Pod控制器允许用户回滚到之前的版本,以恢复服务。
  • 扩缩容:Pod控制器可以根据负载或其他策略自动调整Pod的副本数量,实现水平伸缩(Horizontal Scaling)。
  • 有序管理:对于有状态的Pod(如StatefulSet管理的Pod),控制器确保Pod的创建、更新和删除是有序进行的,以维护Pod的顺序和状态。
  • 服务发现:通过与服务(Service)的配合,Pod控制器帮助实现服务发现,使得Pod可以通过DNS名称被其他Pod或服务发现和访问。
  • 持久化存储管理:对于需要持久化存储的Pod,Pod控制器可以与PersistentVolumes和PersistentVolumeClaims配合,确保Pod的存储需求得到满足,并且在Pod重新调度后仍然能够访问到相同的持久化数据。
  • 任务调度:Job和CronJob控制器用于执行一次性任务或周期性任务,Pod控制器在这里负责调度和管理这些任务的执行。

总的来说,Pod控制器是Kubernetes中实现应用部署、运维和管理的关键组件,它通过自动化和声明式配置,简化了集群资源的管理,提高了应用的可靠性和可维护性。

4.Pod控制器的类型组成及特点

4.1Pod控制器的类型

4.1.1ReplicaSet

ReplicaSet(RS):确保指定数量的Pod副本始终运行。它通过标签选择器来识别和管理Pod,并且可以根据需要自动创建或删除Pod。ReplicaSet通常不直接使用,而是通过Deployment来间接管理。

  • 用户期望的Pod副本数量:这是ReplicaSet的核心目标,它定义了用户希望在集群中运行的Pod实例的数量。ReplicaSet会监控当前运行的Pod数量,并根据这个目标数量进行调整。如果Pod数量少于期望值,ReplicaSet会创建新的Pod;如果多于期望值,它会删除多余的Pod。
  • 标签选择器(Label Selector):标签选择器是一个过滤条件,它定义了哪些Pod应该由ReplicaSet管理。在Kubernetes中,每个Pod都可以被赋予一系列的标签(key-value对),而ReplicaSet通过标签选择器来识别这些Pod。只有匹配标签选择器的Pod才会被ReplicaSet视为其管理的对象。
  • Pod资源模板:当需要创建新的Pod时,ReplicaSet会使用这个模板来生成Pod的定义。这个模板包含了Pod的规格,如容器镜像、环境变量、存储卷等。ReplicaSet会根据这个模板创建新的Pod实例,以确保Pod的配置与用户期望的一致。

ReplicaSet通常不直接由用户创建和管理,而是通过Deployment来间接管理。Deployment是一个更高级别的抽象,它允许用户声明式地定义应用的期望状态,包括副本数量、更新策略等。Deployment会自动创建和管理ReplicaSet,以确保应用的稳定运行。这种方式简化了用户的管理操作,使得用户无需直接处理ReplicaSet的细节。

4.1.2Deployment

Deployment是Kubernetes中用于声明式更新的高级API对象。它管理ReplicaSet,允许用户声明期望的Pod副本数量和更新策略,如滚动更新。Deployment支持回滚到之前的版本,并且提供了声明式配置,使得应用的部署和管理更加简单和直观。

  • 声明式更新策略:允许用户定义如何更新Pod,例如滚动更新(Rolling Update)。
  • 回滚机制:支持用户回滚到之前的部署版本。
  • ReplicaSet管理:Deployment对象管理一个或多个ReplicaSet对象,确保Pod的副本数量符合期望状态。
  • 声明式配置:用户通过Deployment的声明来定义应用的期望状态,Kubernetes会自动调整实际状态以匹配期望状态。

部署无状态应用,管理Pod和ReplicaSet 

4.1.3DaemonSet

DaemonSet确保Pod副本在集群中的所有(或某些)节点上运行。这通常用于运行系统级服务,如日志收集或监控代理。DaemonSet确保这些服务在每个节点上都有一个实例,即使在节点重启后也能自动恢复。

  • Pod模板:定义DaemonSet中Pod的规格和配置。
  • 选择节点的策略:DaemonSet确保在集群中的每个节点上都运行一个Pod的副本,除非节点被明确排除。
  • 控制逻辑:DaemonSet控制器负责在新节点加入集群时创建Pod,并在节点不再需要DaemonSet时删除Pod。
4.1.4StateSet

StatefulSet用于管理有状态的分布式应用。与Deployment不同,StatefulSet提供了稳定的持久化存储、唯一的网络标识符(如DNS名)以及有序的部署和扩展。

  • Pod模板:定义StatefulSet中Pod的规格和配置。
  • 稳定的持久化存储:为每个Pod提供稳定的持久化存储,通常通过PersistentVolumes实现。
  • 有序部署和扩展:StatefulSet支持有序地部署和扩展Pod,这对于有状态的应用非常重要。
  • 唯一网络标识符:每个Pod都有一个稳定的DNS名称,这对于服务发现和负载均衡很有用。
4.1.5Job

Job负责运行一次性任务。当Pod成功终止时,Job完成。Job适用于批处理任务,如数据处理或备份。

  • Pod模板:定义Job执行任务所需的Pod规格和配置。
  • 完成条件:定义何时Job被认为是完成的,例如所有Pod成功终止。
  • 重试策略:可以设置失败时的重试次数和重试间隔。
4.1.6CronJob

CronJob用于管理周期性运行的任务。它基于时间表(Cron格式)来调度Job的执行。CronJob可以创建Job对象来执行周期性任务,非常适合定时任务。

  • 定时执行的Job:CronJob定义了一个定时任务,它会按照Cron格式的时间表周期性地创建Job。
  • Cron格式的调度:用户可以定义Cron表达式来指定Job的执行时间。
  • Job管理:CronJob控制器负责根据调度创建Job,并在Job完成后进行清理。

4.2Pod与控制器的关系

Pod通过label-selector与控制器关联,控制器负责应用的运维,如伸缩和升级。

二、Kubernetes中的服务发现

在 Kubernetes (K8S) 中,服务发现是一个关键特性,它允许集群内的服务和应用相互发现和通信。这对于构建动态、可扩展的微服务架构至关重要。

1.服务发现的需求

  • 动态性:Pod 可能会因为各种原因(如调度、节点故障等)在集群的不同节点之间移动。
  • 频繁更新和发布:现代应用开发强调快速迭代和持续部署,这要求服务能够在不停机的情况下进行更新和扩展。
  • 自动伸缩:在负载增加时,如促销活动期间,应用需要能够自动扩展以处理更多的请求。

2.Kubernetes DNS 服务

Kubernetes 使用 DNS 作为服务发现的主要机制。当创建一个 Service 时,Kubernetes 会自动为它创建一个 DNS 记录,使得集群内的其他服务可以通过这个 DNS 名称来发现和访问它。

Service 的 DNS 名称通常遵循 服务名.命名空间.svc.cluster.local 的格式,例如 my-service.default.svc.cluster.local。

3.DNS 插件的演变

skyDNS:在 Kubernetes 1.3 版本之前,skyDNS 是集群内部 DNS 服务的实现。

kubeDNS:从 Kubernetes 1.3 到 1.11 版本,kubeDNS 成为了官方推荐的 DNS 插件。它提供了更好的性能和稳定性。

CoreDNS:从 Kubernetes 1.11 版本开始,CoreDNS 成为了默认的 DNS 插件。CoreDNS 是一个更现代、更灵活的 DNS 服务器,它支持更多的功能和插件。

4.CoreDNS 的特点

CoreDNS 是一个可扩展的 DNS 服务器,它允许通过插件来添加新的功能。

它提供了对 DNS 记录的更细粒度控制,例如可以为不同的 Service 类型(如 ClusterIP、NodePort、LoadBalancer)配置不同的 DNS 策略。

CoreDNS 还支持 DNSSEC,这是一个安全特性,可以为 DNS 查询提供加密和验证。

通过这些 DNS 插件,Kubernetes 集群能够实现服务的自动发现,这对于构建和管理大规模的分布式应用非常重要。开发者和运维人员可以依赖于这种内置的服务发现机制,而无需担心服务的网络位置变化。

5.安装CoreDNS(仅在二进制部署环境需要安装CoreDNS)

使用 sed 命令来修改 CoreDNS 配置文件的示例。这个过程通常用于将 CoreDNS 的基础模板文件 coredns.yaml.base 转换为一个特定的配置文件,以便在 Kubernetes 集群中部署 CoreDNS。

5.1方法一 下载并配置

#下载 CoreDNS 配置模板

https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base
#这个链接指向 Kubernetes 项目中的 CoreDNS 配置模板文件 coredns.yaml.base。这个文件是 CoreDNS 的默认配置模板,包含了 CoreDNS 的基本设置
#创建一个 sed 脚本文件
vim transforms2sed.sed
s/__DNS__SERVER__/10.0.0.2/g
s/__DNS__DOMAIN__/cluster.local/g
s/__DNS__MEMORY__LIMIT__/170Mi/g
s/__MACHINE_GENERATED_WARNING__/Warning: This is a file generated from the base underscore template file: coredns.yaml.base/g

#创建了一个名为 transforms2sed.sed 的文件,这个文件包含了一系列的 sed 替换命令。这些命令用于修改 coredns.yaml.base 文件中的特定占位符
#使用 sed 命令进行替换
sed -f transforms2sed.sed coredns.yaml.base > coredns.yaml


将 _DNS__SERVER__ 替换为 CoreDNS 的服务地址(例如 10.0.0.2)。
将 _DNS__DOMAIN__ 替换为集群的域名(例如 cluster.local)。
将 _DNS__MEMORY__LIMIT__ 替换为 CoreDNS Pod 的内存限制(例如 170Mi)。
将 __MACHINE_GENERATED_WARNING__ 替换为一个警告信息,表明这个文件是由基础模板文件生成的。
使用 sed 命令来读取 coredns.yaml.base 文件,并根据 transforms2sed.sed 文件中的指令进行替换。这里的替换包括:
生成最终的 CoreDNS 配置文件: 通过上述 sed 命令,将生成一个新的 coredns.yaml 文件,这个文件包含了根据集群环境定制的 CoreDNS 配置。

5.2上传配置文件

#上传 CoreDNS 配置文件并创建 Nginx 服务

#创建 Nginx 服务

kubectl create -f coredns.yaml
 
kubectl get pods -n kube-system
 
 
vim nginx-service.yaml
apiVersion: v1  
kind: Service  
metadata:
  name: nginx-service
  labels:
    app: nginx  
spec:
  type: NodePort  
  ports:
  - port: 80
    targetPort: 80  
  selector:
    app: nginx

#创建一个名为 nginx-service.yaml 的文件,定义了一个类型为 NodePort 的 Service,用于暴露 Nginx 应用
kubectl create -f nginx-service.yaml
#部署Nginx服务
kubectl get svc
#检查服务
#创建测试Pod
vim pod6.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - sleep 36000
  restartPolicy: Never

#创建一个名为 .yaml 的文件,定义了一个包含 busybox 容器的 Pod,该容器将用于测试服务发现
#部署测试 Pod

kubectl create -f pod6.yaml 
#测试服务发现
#解析kubernetes和nginx-service名称
kubectl exec -it dns-test sh
 
#查看statefulset的定义
kubectl explain statefulset
 
kubectl explain statefulset.spec
KIND:     StatefulSet
VERSION:  apps/v1
 
RESOURCE: spec <Object>
 
DESCRIPTION:
     Spec defines the desired identities of pods in this set.
 
     A StatefulSetSpec is the specification of a StatefulSet.
 
FIELDS:
   podManagementPolicy    <string>  #Pod管理策略
   replicas    <integer>    #副本数量
   revisionHistoryLimit    <integer>   #历史版本限制
   selector    <Object> -required-    #选择器,必选项
   serviceName    <string> -required-  #服务名称,必选项
   template    <Object> -required-    #模板,必选项
   updateStrategy    <Object>       #更新策略
   volumeClaimTemplates    <[]Object>   #存储卷申请模板,必选项



#在 dns-test Pod 中,可以使用 nslookup 或 dig 命令来测试对 Nginx 服务的 DNS 解析。例如,可以在 busybox 容器中执行 nslookup nginx-service 来查看 Nginx 服务的 IP 地址

三、Pod与控制器之间的关系

1.Deployment(更新资源)控制器

  • 部署无状态应用
  • 管理Pod和ReplicaSet
  • 具有上线部署、副本设定、滚动升级、回滚等
  • 提供声明式更新,例如只更新一个新的image
  • 应用场景:Web服务、微服务
mkdir /opt/pod/control -p
cd /opt/pod/control/

kubectl create deployment nginx-deployment --image=nginx:1.15 --port=80 --replicas=1 --dry-run=client -oyaml > nginx-deployment.yaml

vim nginx-deployment.yaml


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

kubectl create -f nginx-deployment.yaml

kubectl get pod,deploy,rs

  • 应用场景

Deployment非常适合部署和管理无状态的应用,如web服务器、缓存服务器等。它的滚动更新和回滚功能使得应用的持续部署和维护变得简单。

  • 声明式更新

Deployment支持声明式更新,这意味着可以在Deployment的YAML文件中指定新的镜像版本,然后应用这个更新。Kubernetes会自动创建新的ReplicaSet和Pod,逐步替换旧的Pod,直到所有Pod都更新到新的版本。

  • 示例中的Deployment

在示例中,Deployment使用了Nginx的Docker镜像nginx:1.15。如果想要更新这个镜像到新版本,只需修改YAML文件中的image字段,然后重新应用配置即可。Kubernetes会自动处理更新过程。

#查看控制器配置
kubectl edit deployment/nginx-deployment

#使用kubectl edit命令可以直接在默认编辑器中修改Deployment的配置。在例子中,查看了名为nginx-deployment的Deployment的配置。这个配置文件包含了Deployment的各种设置,例如:

replicas:期望的Pod副本数量。

selector:用于选择Pod的标签选择器。

strategy:定义了更新策略,这里使用的是RollingUpdate,它指定了在升级过程中新Pod的最大数量(maxSurge)和旧Pod的最大不可用数量(maxUnavailable)。

template:定义了Pod模板,包括容器的镜像、端口和其他规格。

#查看历史版本
kubectl rollout history deployment/nginx-deployment
#查看Deployment的历史版本和变更原因。在您的例子中,Deployment的当前版本是1,没有提供变更原因。这意味着Deployment自创建以来没有经历过任何更新。

2.StatefulSet(管理有状态应用)控制器

StatefulSet 是 Kubernetes 中用于管理有状态应用的控制器。它为每个 Pod 提供了一个持久化的身份,这对于需要持久化存储或稳定网络标识的应用非常有用。

  • 稳定的持久化存储:StatefulSet 通过 Persistent Volume Claims (PVC) 为每个 Pod 提供稳定的存储。即使 Pod 被重新调度到其他节点,它仍然能够访问到相同的持久化数据。
  • 稳定的网络标识:StatefulSet 通过 Headless Service 为每个 Pod 提供稳定的网络标识。这意味着即使 Pod 被重新调度,其 PodName 和 HostName 也不会改变。
  • 有序部署和扩展:StatefulSet 确保 Pod 是有序创建的,即从 0 到 N-1 的顺序。在下一个 Pod 运行之前,所有之前的 Pod 必须都是 Running 和 Ready 状态。
  • 有序收缩和删除:StatefulSet 也确保 Pod 是有序删除的,即从 N-1 到 0 的顺序。
  • Pod 选择器和模板:StatefulSet 使用 Pod 选择器来识别它管理的 Pod,并且有一个 Pod 模板来定义 Pod 的规格。
  • 更新策略:StatefulSet 支持滚动更新,允许用户配置和禁用 Pod 的自动化滚动更新。
  • 最小准备时间:StatefulSet 允许设置 minReadySeconds,指定新创建的 Pod 在被认为是可用之前应该运行和就绪的最小秒数。
  • Pod 索引标签:StatefulSet 为每个 Pod 创建时,会添加一个 pod-index 标签,其值为 Pod 的序号索引。
  • 部署和扩展保证:StatefulSet 在部署和扩展时,确保所有前驱 Pod 都是 Running 和 Ready 状态,然后才会启动下一个 Pod。在删除 Pod 时,也确保所有后继 Pod 都已完全关闭。
  • Pod 管理策略:StatefulSet 允许通过 podManagementPolicy 字段放松其顺序保证,同时保留其唯一性和身份保证。
  • 持久卷声明模板:StatefulSet 使用 volumeClaimTemplates 来定义每个 Pod 应该请求的存储资源。

常见的应用场景:数据库

官方文档:StatefulSets | Kubernetes

https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
 
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi


#示例定义了一个 Headless Service 和一个 StatefulSet,用于部署一个名为 nginx 的应用。这个 StatefulSet 配置了 3 个副本,每个 Pod 都有一个名为 www 的 PVC,用于存储,并且使用了 nginx-slim 镜像。这个 StatefulSet 还设置了一个 Headless Service 来提供稳定的网络标识。

2.1StatefulSet的三个关键组成部分以及其作用

StatefulSet 的设计是为了满足有状态应用的需求,这些应用通常需要持久化存储和稳定的网络标识。

  • Headless Service
    • 目的:Headless Service 用于为 StatefulSet 中的每个 Pod 提供一个稳定的 DNS 名称。这样,即使 Pod 被重新调度到其他节点,它的 DNS 名称也不会改变,从而保证了网络标识的稳定性。
    • 实现:Headless Service 不分配 Cluster IP,而是直接将 DNS 请求解析到对应的 Pod IP。这样,每个 Pod 都有一个基于 StatefulSet 名称和 Pod 序号的 DNS 子域,例如 web-0.nginx.default.svc.cluster.local。
  • VolumeClaimTemplates
    • 目的:VolumeClaimTemplates 用于为每个 Pod 提供独立的持久化存储。这样,每个 Pod 都有自己的存储空间,即使在 Pod 重新调度后,也能保持数据的连续性和一致性。
    • 实现:在 StatefulSet 的定义中,可以包含一个或多个 VolumeClaimTemplates。当 StatefulSet 创建 Pod 时,会为每个 Pod 创建相应的 PersistentVolumeClaim (PVC)。这些 PVC 会请求与 StatefulSet 关联的 PersistentVolume (PV),从而为每个 Pod 提供专用的存储卷。
  • StatefulSet 控制器
    • 目的:StatefulSet 控制器负责管理 Pod 的生命周期,确保 Pod 的数量符合用户的期望,并且按照顺序进行部署、扩展和收缩。
    • 实现:StatefulSet 控制器会监控 Pod 的状态,确保每个 Pod 都按照定义的顺序运行。在进行滚动更新时,它会按照顺序逐个更新 Pod,确保在更新下一个 Pod 之前,所有先前的 Pod 都已经就绪。同样,在删除 Pod 时,也会按照相反的顺序进行,以确保服务的平滑过渡。
  • Headless Service(无头服务):用于为Pod资源标识符生成可解析的DNS记录
  • VolumeClaimTemplates(存储卷申请模板):基于静态或动态PV供给方式为Pod资源提供专有的固定存储
  • StatefulSet:用于管控Pod资源 

这三个组件共同工作,使得 StatefulSet 能够为有状态应用提供所需的稳定性和可靠性。Headless Service 解决了网络标识的稳定性问题,VolumeClaimTemplates 解决了持久化存储的需求,而 StatefulSet 控制器则确保了 Pod 的有序管理和更新。这种设计使得 StatefulSet 成为部署和管理有状态应用的理想选择,如数据库、消息队列等。

2.2为什么要有Headless

在deployment中,每一个pod是没有名称,是随机字符串,是无序的。而statefulset中是要求有序的,每一个pod的名称必须是固定的。当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一。
为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称。

2.3为什么要有VolumeClainTemplate

大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点。而在 deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的,这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷。

2.4清单定义StatefulSet

一个完整的 StatefulSet 控制器由一个 Headless Service、一个 StatefulSet 和一个 volumeClaimTemplate 组成。

vim pod-buxybox.yaml

apiVersion: v1
kind: Pod
metadata:
  name: dns-buxybox
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - sleep 36000
  restartPolicy: Never

kubectl apply -f pod-buxybox.yaml

kubectl get pod

kubectl exec -it dns-buxybox sh

2.5创建、管理和删除StatefulSet

如何在 Kubernetes 集群中创建、管理和删除StatefulSet,以及与之相关的服务、持久卷(PV)、持久卷声明(PVC)和Pod

2.5.1创建StatefulSet

StatefulSet 资源依赖于无头模式的service

vim service.yaml

apiVersion: v1
#指定API版本
kind: Service
#创建资源类型为Service
metadata:
  name: sts-svc
  #指定service名称
  labels:
    app: sts-svc
    #设置service标签
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  #将clusterIP地址的值设置为None,表示无IP地址,即无头模式
  selector:
    app: state
  type: ClusterIP


kubectl apply -f service.yaml

kubectl get svc
2.5.2查看StatefulSet
vim statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: state
spec:
  serviceName: headless-svc
  replicas: 3
  selector:
    matchLabels:
      app: state
  template:
    metadata:
      labels:
        app: state
    spec:
      containers:
      - name: myapp
        image: soscscs/myapp:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        #定义将存储卷卷挂载到指定目录
        - name: html
        #指定存储卷名称
          mountPath: /usr/share/nginx/html
          #挂载到此目录,此目录为nginx服务的站点目录
  volumeClaimTemplates:
  #PVC的请求模板
  - metadata:
      name: html
      #定义PVC的名称 要与PVC名称一致
      annotations:
        volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
        #用于指定存储类的注解。该存储类定义了用于动态卷供应的后端存储类型
    spec:
      accessModes: ["ReadWriteOnce"]
      #指定访问模式为RWO
      resources:
        requests:
          storage: 1Gi
          #指定存储卷的使用大小

kubectl apply -f stateful-demo.yaml 

kubectl get pod -w
#可以滚动查看是从0创建但2的

kubectl delete -f statefulset.yaml
#删除的话  可以看到是从2删除到1的  也就是关闭的逆向的

#此时PVC依旧存在的,再重新创建pod时,依旧会重新去绑定原来的pvc
kubectl apply -f statefulset.yaml

这些步骤展示了 StatefulSet 的生命周期管理,包括创建、查看、删除和重新创建。在实际应用中,这种管理方式允许您灵活地部署和管理有状态应用,同时保持数据的持久化和一致性。

由于pod的IP地址是k8s集群内部的IP地址,且并没有clusterIP去绑定podIP,只有域名管理,宿主机的DNS解析,无法解析k8s集群内部的域名与地址,所以使用宿主机无法访问pod。只能通过创建pod,在pod中进行访问 

可以看到,访问的pod是随机的,因为k8s内部的负载均衡方式,是通过资源的使用率进行分配的,它会将请求优先分配到资源使用率较少的pod上,可以使用压测工具去测试,而后再进行访问 

2.3滚动更新

在 Kubernetes 中对 StatefulSet 进行滚动更新,以及如何在 Pod 内部解析其他 Pod 的名称。StatefulSet 控制器将在 StatefulSet 中删除并重新创建每个 Pod。它将以与 Pod 终止相同的顺序进行(从最大的序数到最小的序数),每次更新一个 Pod。在更新其前身之前,它将等待正在更新的 Pod 状态变成正在运行并就绪。如下操作的滚动更新是按照2-0的顺序更新。

vim stateful-demo.yaml  		#修改image版本为v2
.....
image: ikubernetes/myapp:v2
....

kubectl apply -f stateful-demo.yaml

#观察滚动更新过程
kubectl get pods -w
#可以看到每个 Pod 依次进入终止状态,然后新的 Pod 被创建并启动。这个过程是从序号最大的 Pod 开始,逆序进行的。
#在创建的每一个Pod中,每一个pod自己的名称都是可以被解析的
kubectl exec -it myapp-0 /bin/sh
#使用 kubectl exec -it myapp-0 /bin/sh 命令进入 myapp-0 Pod 的 shell。然后,可以使用 hostname 命令查看当前 Pod 的完整名称,或者使用 nslookup 命令解析其他 Pod 的名称。


#解析 Pod 名称到 IP 地址
#从上面的解析,我们可以看到在容器当中可以通过对Pod的名称进行解析到ip。其解析的域名格式如下:
(pod_name).(service_name).(namespace_name).svc.cluster.local
#在 Pod 内部,可以通过 Pod 的名称解析到其对应的 IP 地址。解析的域名格式遵循 (pod_name).(service_name).(namespace_name).svc.cluster.local。例如,myapp-1.myapp-svc.default.svc.cluster.local。

请注意,nslookup 命令在某些情况下可能无法解析 Pod 的名称,这可能是因为 DNS 解析缓存或者网络问题。在实际环境中,可能需要检查 CoreDNS 的配置或者网络设置,以确保 DNS 解析正常工作。

滚动更新是 StatefulSet 的一个重要特性,它允许在不中断服务的情况下更新应用。通过这种方式,可以逐步部署新版本的应用,同时确保集群的稳定性和可用性。

2.4扩容和伸缩

如何在 Kubernetes 中对 StatefulSet 进行扩容和缩容操作

#扩容 StatefulSet

kubectl scale sts myapp --replicas=4
#扩容副本增加到4个

#使用 kubectl scale sts myapp --replicas=4 命令将名为 myapp 的 StatefulSet 的副本数扩展到 4 个。这将创建一个新的 Pod,使其总副本数达到 4。
#动态查看扩容过程

kubectl get pods -w

#使用 kubectl get pods -w 命令观察扩容过程。可以看到新的 Pod 被创建,并且状态从 Pending 变为 Running。
#查看 PersistentVolumes (PV)
kubectl get pv

#使用 kubectl get pv 命令查看当前集群中所有的 PV。在扩容过程中,新的 Pod 将尝试绑定到现有的 PV,或者如果有必要,可能会创建新的 PV。
#缩容 StatefulSet

kubectl patch sts myapp -p '{"spec":{"replicas":2}}'  #打补丁方式缩容

#使用 kubectl patch sts myapp -p '{"spec":{"replicas":2}}' 命令通过打补丁的方式将 StatefulSet 的副本数缩容到 2。这将导致 StatefulSet 控制器逐步终止并删除额外的 Pod。
#动态查看缩容过程

kubectl get pods -w


#再次使用 kubectl get pods -w 命令观察缩容过程。可以看到 Pod 的数量减少,直到只剩下 2 个 Pod。

在 StatefulSet 中进行扩容和缩容时,Kubernetes 会确保操作是有序的,以避免数据丢失或服务中断。对于有状态应用,通常需要确保在进行这些操作时,应用的状态能够正确地迁移和同步。

3.DaemonSet(工作负载)控制器

DaemonSet 是 Kubernetes 中的一种工作负载控制器,它确保在集群中的所有(或指定的)节点上运行一个 Pod 的副本。这使得 DaemonSet 成为运行集群级服务的理想选择,如日志收集、监控代理、存储守护进程等。

3.1关键特性

  • 节点覆盖:DaemonSet 确保在集群中的每个节点上都有一个 Pod 副本运行,或者根据需要在特定节点上运行。
  • 自动管理:当新节点加入集群时,DaemonSet 会自动在这些节点上创建 Pod。当节点被移除时,相应的 Pod 也会被清理。
  • 删除行为:删除 DaemonSet 会删除它创建的所有 Pod,这有助于维护集群的整洁。

3.2典型用例

  • 集群存储守护进程:在每个节点上运行如 GlusterFS 的 glusterd 或 Ceph 的守护进程,以提供分布式存储服务。
  • 日志收集:部署如 Fluentd、Logstash 等日志收集代理,以便在每个节点上收集日志并将其发送到中央日志存储。
  • 监控代理:在每个节点上运行监控代理,如 Prometheus 的 Node Exporter、Collectd、Datadog 代理、New Relic 代理或 Ganglia 的 gmond,以收集节点的监控数据。

3.3应用场景

  • Agent:DaemonSet 常用于部署代理或守护进程,这些代理或守护进程作为集群的“代理”,执行特定的任务,如数据收集、服务代理等。

官方案例(监控):https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/

Kubernetes 官方文档提供了使用 DaemonSet 进行集群监控的案例。例如,可以部署 Prometheus Node Exporter 作为 DaemonSet,这样每个节点都会运行一个 Node Exporter Pod,用于暴露节点的监控指标。然后,可以使用 Prometheus 服务器来抓取这些指标,进行进一步的分析和可视化。

DaemonSet 是 Kubernetes 生态系统中的重要组成部分,它为在集群范围内部署和管理分布式服务提供了一种简单而有效的方式。

3.4实例

如何创建一个 DaemonSet 并在 Kubernetes 集群中的每个节点上部署一个 Nginx Pod

vim ds.yaml 

apiVersion: apps/v1
#指定 Kubernetes API 的版本
kind: DaemonSet
#指定资源类型为 DaemonSet
metadata:
#包含 DaemonSet 的名称和标签
  name: nginx-daemonset
  labels:
    app: nginx
spec:
#包含 DaemonSet 的规格
  selector:
  #用于选择 Pod 的标签选择器
    matchLabels:
      app: nginx
  template:
  #定义 Pod 模板,包括 Pod 的元数据和规格
    metadata:
    #Pod 的标签
      labels:
        app: nginx
    spec:
    #Pod 的规格,包括容器定义
      containers:
      #定义容器的名称、镜像和端口
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80


kubectl apply -f ds.yaml
#这将创建一个名为 nginx-daemonSet 的 DaemonSet,并在每个节点上部署一个 Nginx Pod

#DaemonSet会在每个node节点都创建一个Pod
kubectl get pods



#在示例中,nginx-deployment 是之前创建的 Deployment 的名称,而不是 DaemonSet。DaemonSet 创建的 Pod 名称通常会包含 daemonset 关键字,例如 nginx-daemonset-...。如果希望查看由 DaemonSet 创建的 Pod,需要使用更具体的过滤器,例如 kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | grep nginx-daemonset。

请注意,DaemonSet 通常用于在每个节点上运行特定的守护进程或服务,而一般不是用于部署像 Nginx 这样的 web 服务。如果你的目标是在集群中部署 web 服务,通常使用 Deployment 或 StatefulSet 会更合适。DaemonSet 更适合于那些需要在每个节点上运行的服务,如日志收集器、监控代理等。

4.Job(特殊的工作负载)控制器

在 Kubernetes 中,Job 是一种用于执行一次性任务的工作负载,它保证任务至少运行一次,直到成功完成。Job 有两种类型:普通 Job 和定时任务 CronJob。

4.1普通Job(Job)

  • 一次性任务:Job 用于执行那些只需要运行一次直到成功完成的任务。
  • 保证执行:如果 Job 中的 Pod 失败(例如,因为节点故障),Kubernetes 会自动重新启动一个新的 Pod,直到任务成功完成。
  • 任务完成:一旦 Job 中的所有 Pod 成功终止,Job 就被认为是完成的。

4.2定时任务(CronJob)

  • 周期性执行:CronJob 用于定期执行任务,它基于 Cron 表达式来定义任务的调度。
  • 重复执行:CronJob 会创建 Job 对象来执行任务,并且可以根据设定的时间表重复执行。
  • 历史记录:CronJob 保留了 Job 的历史记录,包括成功和失败的任务。

4.3应用场景

  • 数据库迁移:执行数据库迁移脚本,直到迁移成功。
  • 批处理脚本:运行批处理作业,如数据备份、日志清理等。
  • 安全扫描:使用 kube-bench 等工具对集群进行安全扫描。
  • 离线数据处理:处理不需要持续运行的大量数据,如数据分析、报告生成等。
  • 视频解码:执行视频转码等耗时的一次性任务。

官方文档:https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/    

Job 是 Kubernetes 中处理短期、一次性任务的重要资源,它为开发者和运维人员提供了一种简单的方式来自动化和保证任务的执行。CronJob 则为周期性任务提供了自动化的解决方案,使得集群能够根据预定的时间表执行任务。

4.4实例

如何在 Kubernetes 中创建和处理 Job 资源

vim job.yaml


apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
    #spec.template.spec 定义了 Pod 的规格,包括容器的名称、镜像和执行的命令
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
        #perl解释器,-Mbignum=bpi模块中的子进程,使用计算功能,计算结果输出圆周率2000位的结果
      restartPolicy: Never
      #表示 Pod 失败后不会重启。
  backoffLimit: 4
  #表示 Job 在失败后最多重试 4 次

#定义了一个名为 pi 的 Job,它将运行一个 Perl 容器来计算圆周率(π)

kubectl apply -f job.yaml 

kubectl get pods

kubectl get pod -w

kubectl get pod

kubectl logs <podname>

kubectl delete -f job.yaml

vim job-limit.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: busybox
spec:
  template:
    spec:
      containers:
        - name: busybox
          image: busybox
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]
      restartPolicy: Never
  backoffLimit: 2
  
kubectl apply -f job-limit.yaml

kubectl get job,pods

kubectl get pod -w

这里可以看到一次性计划任务是在于date时间正常的情况下进行执行,执行完成后就退出

kubectl describe jobs.batch

通过这些步骤,可以了解如何在 Kubernetes 中创建和管理一次性任务。Job 是执行这类任务的理想选择,尤其是当任务需要在集群中运行到完成为止时。CronJob 则用于定期执行这类任务。 

5.CronJob(管理周期性任务的工作负载)控制器

CronJob 是 Kubernetes 中用于管理周期性任务的工作负载,它类似于 Linux 系统中的 crontab。CronJob 可以创建一个或多个 Job 对象来执行定时任务,这些任务按照预定的时间表(Cron 表达式)重复执行。

5.1CronJob的关键特性

  • 定时执行:CronJob 使用 Cron 表达式来定义任务的执行时间表。
  • Job 创建:在预定的时间,CronJob 控制器会创建一个 Job 对象来执行任务。
  • 历史记录:CronJob 保留了 Job 的历史记录,包括成功和失败的任务,这对于审计和调试非常有用。
  • 并发控制:CronJob 允许配置并发策略,以控制同时运行的任务数量。

5.2应用场景

  • 通知系统:定期发送系统状态通知、日志报告或其他类型的定期通知。
  • 数据备份:执行数据库备份、文件备份等周期性数据保护任务。
  • 定期清理:清理日志文件、临时文件或其他不再需要的数据。
  • 监控和报告:定期执行监控任务并生成报告。

官方文档:https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/

CronJob 是 Kubernetes 中处理周期性任务的强大工具,它使得自动化任务的创建和管理变得简单。通过定义 Cron 表达式,您可以轻松地安排任务在特定的时间执行,从而实现自动化运维。

5.3实例

如何在 Kubernetes 中创建一个 CronJob,该 CronJob 每分钟执行一次打印 "Hello" 的任务。

#创建 CronJob 配置文件 (cronjob.yaml) 每分钟打印hello

vim cronjob.yaml

apiVersion: batch/v1beta1
#指定 Kubernetes API 的版本
kind: CronJob
#指定资源类型为 CronJob
metadata:
#包含 CronJob 的名称
  name: hello
spec:
#包含 CronJob 的规格
  schedule: "*/1 * * * *"
  #使用 Cron 表达式定义任务的执行时间表。在这个例子中,"*/1 * * * *" 表示每分钟执行一次。
  jobTemplate:
  #定义了 Job 模板,它包含了执行任务的 Pod 规格
    spec:
      template:
        spec:
          containers:
          #定义了容器的名称、镜像和其他参数
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            args:
            #执行的命令,这里使用 /bin/sh 打印当前日期和 "Hello" 消息
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
          #设置为 OnFailure,表示只在容器失败时重启


kubectl create -f cronjob.yaml 

kubectl get cronjob

kubectl get pods

kubectl logs hello-1717225740-8nlx7
#我们查看了 hello-1717225740-8nlx7 Pod 的日志,可以看到打印的日期和 "Hello" 消息。

#解决日志查看权限问题

kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous


#如果在查看日志时遇到权限问题,可以通过创建一个 clusterrolebinding 来授予 system:anonymous 用户 cluster-admin 权限。这通常不推荐,因为它会降低集群的安全性。在生产环境中,应该使用更细粒度的权限控制。

通过这些步骤,可以在 Kubernetes 中设置周期性任务,例如定期备份、日志清理或发送通知。CronJob 提供了一种简单的方式来自动化这些重复性任务。

四、总结

1.有状态和无状态的区别

  • 无状态应用(Stateless Applications)
    • Pod同质性:Deployment认为所有的Pod都一样,不用考虑顺序要求,不用考虑在哪个Node节点运行,可以随意扩容和缩容
    • 无顺序要求:Pod的创建、更新和删除没有特定的顺序要求
    • 节点无关性:Pod可以在任何节点上运行,不需要特定的节点
    • 伸缩性:可以根据负载自动或手动扩容和缩容
  • 有状态(Stateful Applications)
    • 实例差异性:实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,Zookeeper;实例之间不对等的关系,以及依靠外部存储的应用
    • 不对等关系:实例之间可能存在主从、领导者选举等不对等的关系
    • 外部存储依赖:应用可能依赖于外部存储,如数据库或文件系统
    • 顺序性:在部署、更新和删除时,需要考虑实例和顺序还有唯一性

2.常见Service和无头服务的区别

  • Service
    • 访问策略:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现。
    • ClusterIP:分配一个ClusterIP,集群内的其他组件可以通过这个IP访问Service
    • 负载均衡:如果配置了负载均衡,Service可以分发流量到后端的多个Pod
  • Headless service
    • 无头服务:无ClusterIP,不需要cluster-IP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。
    • DNS解析:通过DNS查询,可以直接获取后端Pod的IP地址列表
    • 服务发现:适合于需要直接与后端Pod通信的场景,如数据库集群的发现

在 Kubernetes 中,Deployment 和 StatefulSet 是管理无状态和有状态应用的两种主要资源。而 Service(包括 ClusterIP Service 和 Headless Service)则提供了不同的服务发现和负载均衡机制,以适应不同的应用场景。 

3.Pod控制器

  • Deployment:部署无状态应用的管理RS和Pod,创建Pod,主要是维护Pod副本数量与期望状态相同,创建和删除Pod时并行执行,升级时想创建一部分,再删除一部分
  • StatefulSet:部署有状态的应用,每个Pod的唯一(名称)且不变的,每个Pod拥有自己专属的持久化的存储(PVC和PV)在K8S集群内部可以通过(Pod_name).(Service_name).{namespace}.svc.cluster.local 解析出Pod的IP(基于headless service 和CoreDNS)
    • 创建和删除Pod时有顺序的(串行执行的),升级时串行执行的,会删除旧的Pod,再创建和新Pod删除和升级时逆序执行的(先从标识符最大的n-1开始,一直到最小的0)
  • Daemonset:理论上在K8S集群的所有Node节点上创建相同的Pod(无论Node节点什么时候加入到K8S集群),但是会受到Node节点上污点影响
  • Job:部署一次性任务,正常完成后容器立即退出并且不重启容器(RestartPolicy不设置Always),也不会重建异常完成后重试任务,重建次数根据backofflimit 配置指定(默认为6次)
  • CronJob:周期性部署任务的Pod,正常完成后容器会立即退出并不会重启容器(RestartPolicy,不设置Always)也不会重建Pod,Schedule配置周期性的事件表 * * * * *分时日月周

4.Deployment与Statefulset的区别

4.1 应用场景

Deployment:主要用于部署无状态服务,即服务实例之间可以相互替换且不需要保留特定的网络标识或存储数据。它适用于那些不需要关心Pod具体身份且可任意替换的弹性服务。

StatefulSet:适用于部署有状态的服务,比如数据库集群、消息队列等。这些服务需要稳定的持久化存储和唯一、有序的网络标识。StatefulSet为Pod分配的网络标识符和存储都是稳定的,使得应用能够维持跨重启或再调度的持久状态。

4.2 Pod管理

Deployment:通过ReplicaSet确保指定数量的Pod副本始终运行,提供水平扩展和滚动更新能力。Pod由Deployment创建时,虽然可以自定义名称,但通常由系统生成,并在重建或扩展时可能会发生变化。

StatefulSet:Pods在创建、更新和删除时按照顺序进行,以满足那些依赖于严格顺序启动或停止的应用场景需求。每个Pod都有一个固定的、唯一的网络标识符,并且其持久卷声明(PVC)会绑定到持久化的存储,即使Pod被删除后重新创建,存储的数据也会保留。

4.3 存储与网络

Deployment:通常不直接管理Pod的存储和网络,而是依赖于其他Kubernetes资源(如PersistentVolume和Service)来实现这些功能。

StatefulSet:为Pod提供稳定的存储和网络标识,确保有状态应用能够正常运行。StatefulSet通常与Headless Service和volumeClaimTemplate一起使用,以提供可解析的DNS资源记录和专有且固定的存储。

4.4 升级与回滚

Deployment:支持多种升级策略,如滚动更新和回滚,确保服务在整个升级过程中具有高可用性。通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态,并逐步替换旧的Pod。

StatefulSet:也支持有序而自动的滚动更新,但由于涉及到有状态应用,更新过程可能更加复杂和严格。同时,StatefulSet也支持回滚到之前的版本。

4.5 扩展性

Deployment:可以根据系统负载进行水平扩展和缩容,通过调整ReplicaSet的副本数来实现。

StatefulSet:虽然也支持扩展和缩容操作,但由于涉及到有状态应用和数据一致性等问题,扩展性可能相对较弱。