• 控制器又被称为工作负载,pod通过控制器实现应用的运维,比如伸缩、升级等
  • Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为

1、deployment:适合无状态的服务部署

2、StatefullSet:适合有状态的服务部署

3、DaemonSet:一次部署,所有的node节点都会部署,例如一些典型的应用场景:

  • 运行集群存储 daemon,例如在每个Node上运行 glusterd、ceph
  • 在每个Node上运行日志收集 daemon,例如 fluentd、 logstash
  • 在每个Node上运行监控 daemon,例如 Prometheus Node Exporter

4、Job:一次性的执行任务

5、Cronjob:周期性的执行任务

 

Deployment控制器

Deployment实现了Pod 的“水平扩展 / 收缩”(horizontal scaling out/in),适合部署无状态的应用服务,用来管理pod和replicaset,具有上线部署、副本设定、滚动更新、回滚等功能,还可提供声明式更新,例如只更新一个新的Image。

Deployment如何控制pod

这些控制器被统一放在 kubernetes/pkg/controller 目录下,因为它们都遵循 Kubernetes 项目中的一个通用编排模式,即:控制循环(control loop)。

比如,现在有一种待编排的对象 X,它有一个对应的控制器。

那么,我就可以用一段 Go 语言风格的伪代码,为你描述这个控制循环:

for {
  实际状态 := 获取集群中对象X的实际状态(Actual State)
  期望状态 := 获取集群中对象X的期望状态(Desired State)
  if 实际状态 == 期望状态{
    什么都不做
  } else {
    执行编排动作,将实际状态调整为期望状态
  }
}

在具体实现中,实际状态往往来自于 Kubernetes 集群本身。比如,kubelet 通过心跳汇报的容器状态和节点状态,或者监控系统中保存的应用监控数据,或者控制器主动收集的它自己感兴趣的信息,这些都是常见的实际状态的来源。

而期望状态,一般来自于用户提交的 YAML 文件。比如,Deployment 对象中 Replicas 字段的值。很明显,这些信息往往都保存在 Etcd 中。

接下来,以 Deployment 为例,我和你简单描述一下它对控制器模型的实现:

  • Deployment 控制器从 Etcd 中获取到所有携带了“app: nginx”标签的 Pod,然后统计它们的数量,这就是实际状态;
  • Deployment 对象的 Replicas 字段的值就是期望状态;Deployment 控制器将两个状态做比较,然后根据比较结果,确定是创建 Pod,还是删除已有的 Pod。
  • 可以看到,一个 Kubernetes 对象的主要编排逻辑,实际上是在第三步的“对比”阶段完成的。这个操作,通常被叫作调谐(Reconcile)。这个调谐的过程,则被称作“Reconcile Loop”(调谐循环)或者“Sync Loop”(同步循环)。

Deployment依赖ReplicaSet控制pod

当你更新了yaml模板中关于容器的相关配置(比如,修改了容器的镜像),那么 Deployment 就需要遵循一种叫作“滚动更新”(rolling update)的方式,来升级现有的容器。

而这个能力的实现,依赖的是 Kubernetes 项目中的一个非常重要的概念(API 对象):ReplicaSet。

在你通过yaml创建(API 对象)ReplicaSet的 Metadata 里,都有一个字段叫作 ownerReference,用于保存当前这个 API 对象的拥有者(Owner)的信息。

这个ownerReference的go 结构体定义如下:

 1 // OwnerReference contains enough information to let you identify an owning
 2 // object. Currently, an owning object must be in the same namespace, so there
 3 // is no namespace field.
 4 type OwnerReference struct {
 5     // API version of the referent.
 6     APIVersion string `json:"apiVersion" protobuf:"bytes,5,opt,name=apiVersion"`
 7     // Kind of the referent.
 8     // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
 9     Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
10     // Name of the referent.
11     // More info: http://kubernetes.io/docs/user-guide/identifiers#names
12     Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
13     // UID of the referent.
14     // More info: http://kubernetes.io/docs/user-guide/identifiers#uids
15     UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"`
16     // If true, this reference points to the managing controller.
17     // +optional
18     Controller *bool `json:"controller,omitempty" protobuf:"varint,6,opt,name=controller"`
19     // If true, AND if the owner has the "foregroundDeletion" finalizer, then
20     // the owner cannot be deleted from the key-value store until this
21     // reference is removed.
22     // Defaults to false.
23     // To set this field, a user needs "delete" permission of the owner,
24     // otherwise 422 (Unprocessable Entity) will be returned.
25     // +optional
26     BlockOwnerDeletion *bool `json:"blockOwnerDeletion,omitempty" protobuf:"varint,7,opt,name=blockOwnerDeletion"`
27 }

如果有如下yaml文件:

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

相关文章:

  • 2021-11-23
  • 2021-10-18
  • 2022-12-23
  • 2022-12-23
  • 2021-11-30
  • 2021-10-12
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-07-30
  • 2021-08-19
  • 2021-05-21
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案