上图是整个Kubernetes集群中的资源对象,主要功能和对象分类如下:

  • 工作负载 (Workload)
  • 发现和负载均衡 (Discovery & LB),Service / Endpoint /Ingress
  • 配置和存储 (Config & Storage),ConfigMap / Secret /Volumn
  • 集群 (Cluster),Namespace / Node / Role / ClusterRole /RoleBinding / ClusterRoleBinding
  • 元数据 (Metadata),HPA / LimitRange
1.1 API对象
1.1.1 API对象基本组成

API对象是K8S的集群中管理操作单元,采用声明式设计风格,顶层(Top Level)元素由 kind、apiVersion、metadata、spec 和 status 等几个部分组成。

  1. kind:对象(objects)系统中的永久资源;列表(list)一个或多个资源类别的集合;简单类别(simple)包含作用在对象上的特殊行为和非持久实体
  2. apiVersion:API版本
  3. metadata元数据:标识API对象。API对象至少含有3个元数据:namespace,name,uid
  4. spec:期望状态。API对象通过spec去设置配置; 用户通过配置系统的理想状态来改变系统 , 所有的操作都是声明(Declarative)的而不是命令式(Imperative)的 ; 声明式操作在分布式系统中的好处是稳定,不怕丢操作或运行多次 。
  5. status:实际状态,对象部署后将当前的状态更新到status中。Pod的status信息主要包括conditions、phase、podIP、startTime等,其中phase描述对象所处的生命周期阶段、condition表示条件,由条件类型和状态值组成。

以下是简单的Deployment的yaml定义:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: nginx-example
 labels:
   apps: nginx
spec:
 replicas: 3
 selector:
  matchLabels:
app: nginx
 template:
  metadata:
labels:
  app: nginx
  spec:
     containers:
     - name: nginx
        image: nginx:1.7.9
      ports:
      - containerPort: 80
        resources:
          limits:
            memory: "200Mi"
          requests:
           memory: "100Mi"
status: {}

1.1.2 Label标签

Label是Kubernetes中另一个重要概念,一个Label是一个key=value的键值对,其中key与value由用户自己指定。Label是资源上的标识,用来对它们进行区分和选择,具有以下特点:

  • 一个label会以kv形式附加到各种对象上:Node、Pod、Service、RS。同一个资源对象的labels属性的key必须唯一
  • 一个资源对象可以定义任意多数量的Label,同一个Label也可以被添加到任意数量的资源对象上去;
  • label通常再资源对象确定时定义,也可以在资源创建后动态添加或删除;

实际过程中可以通过label实现资源的多维度分组,以便灵活,方便的进行资源分配,调度,配置,部署等管理工作;常用的多维度标签分类如下:

  • 版本标签(release): stable(稳定版),canary(金丝雀版本),beta(测试版)
  • 环境类(environment): dev(开发),qa(测试),production(生产),op(运维)
  • 应用类(applaction): ui(设计),as(应用软件),pc(电脑端),sc(网络方面)
  • 架构层(tier): frontend(前端),backend(后端),cache(缓存)
  • 分区标签(partition): customerA(客户),AreaB(区域)
  • 质量管控级别(track): daily(每天),weekly(每周)

Kubernetes通过label selector查询和筛选拥有某些Label的资源对象,这种方式类似于SQL的where查询条件,比如name=redis-slave匹配所有name=redis-slave的资源对象、env!=production匹配所有不具有标签env=production的资源对象。

1.2 NameSpace

NameSpace为Kubernetes集群提供虚拟的隔离作用,通过将集群内部的资源对象“分配”到不同的Namespace上,形成逻辑上分组的不同项目或用户组。

  • 为团队创建不同Namespace
  • 为开发、测试、生产环境创建不同的Namespace,以做到彼此之间相互隔离
  • 可以使用 ResourceQuota 与Resource LimitRange 限制资源分配与使用

Kubernetes集群初始有三个命名空间,分别是default、kube-system和kube-public,除此以外,管理员可以创建新的命名空间满足需要。一旦创建了Namespace,可以在创建资源对象的时候指定资源对象属于哪个NameSpace。

1.3 基础构成POD

官方对于Pod的解释是:

Pod是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。

简单来说Pod就是由若干容器组成的最小管理单元,在Pod内可以共享网络、存储和计算资源。Kubernetes为每个Pod都分配了唯一的IP地址,称之为Pod IP,一个Pod内的多个容器共享Pod IP地址。在同一节点上,Pod相互可见,但是Pod不能跨节点,一定在一个节点之上,如下图所示:

在这里插入图片描述

Pod有两种类型普通的Pod和静态Pod,静态Pod比较特殊,它并没有存放在K8S的etcd存储中,而是存放在某个具体的Node的一个具体文件中,并且只在此Node上启动运行。普通的Pod一旦被创建,就会放入etcd存储,随后被K8S Master调度到某个具体的Node上并进行绑定,随后该Pod被Kubelet进程实例化为一组Docker容器并启动。

1.3.1 创建POD

K8S中的所有对象都可以通过yaml来定义,以下是Pod的yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-ctr
    image: polinux/stress
    resources:
      limits:
        memory: "200Mi"
      requests:
        memory: "100Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
    volumeMounts:
    - name: redis-storage
      mountPath: /data/redis
  volumes:
  - name: redis-storage

  • apiVersion记录K8S的API Server版本,现在为v1
  • kind记录该yaml的对象类型,这里是Pod
  • metadata记录了Pod自身的元数据,比如Pod的名称、Pod属于哪个namespace
  • spec记录了Pod内部所有的资源的详细信息:
    • containers记录了Pod内的容器信息,包括:name容器名、image容器的镜像地址,resources容器需要的CPU、内存、GPU等资源,comman容器的入口命令,args容器的入口参数,volumeMounts容器要挂载的Pod数据卷等
    • volumes记录了Pod内的数据卷信息
1.3.2 POD创建过程

在这里插入图片描述

  1. 用户通过kubectl命名发起请求。
  2. apiserver通过对应的kubeconfig进行认证,认证通过后将yaml中的po信息存到etcd
  3. Controller-Manager通过apiserver的watch接口发现了pod信息的更新
  4. 执行该资源所依赖的拓扑结构整合,整合后将对应的信息交给apiserver
  5. apiserver写到etcd,此时pod已经可以被调度了
  6. Scheduler同样通过apiserver的watch接口更新到pod可以被调度,通过算法给pod分配节点
  7. 并将pod和对应节点绑定的信息交给apiserver
  8. apiserver写到etcd,然后将pod交给kubelet
  9. kubelet收到pod后,调用CNI接口给pod创建pod网络
  10. 调用CRI接口去启动容器,调用CSI进行存储卷的挂载
  11. 网络,容器,存储创建完成后pod创建完成,等业务进程启动后,pod运行成功
1.4 工作负载

Kubernetes集群中的Workload工作负载根据不同业务分为以下:

业务类型API对象
无状态ReplicaSet、Deployment
有状态StatefulSet
后台持续服务DaemonSet
批处理型Job
1.4.1基础构成ReplicaSet

ReplicaSet声明需要多少个复本,由调度控制器通知节点启动副本,目的是维护一组在任何时候都处于运行状态的Pod副本的稳定集合。因此,它通常用来保证给定数量的、完全相同的Pod的可用性。RS的特性与作用总结如下:

  • 通过定义RS实现Pod创建及副本数量的自动控制
  • RS中包括完整的Pod定义模板
  • 通过Label Selector机制实现对Pod副本的自动控制
  • 通过改变RS里Pod副本数量,可以实现Pod的扩容与缩容
  • 通过改变RS中Pod模板的镜像版本,可以实现Pod的滚动升级

如下图所示, ReplicaSets定义了5个副本分布在三个Node上,因此需要运行5个POD,而DaemonSet每个节点上只运行一个副本。
在这里插入图片描述

需要注意的是一般很少单独使用ReplicaSet,主要被Deployment这个更高层的资源对象引用,从而形成一整套Pod的创建、删除和更新的编排机制。

1.4.2 基础构成Deployment

Deployment的作用是管理和控制Pod和ReplicaSet,通过声明某种Pod的副本数量在任意时刻都符合某个预期值,并由ReplicaSet 控制。Deployment和ReplicaSet之间的关系如下:

在这里插入图片描述

Deployment的典型使用场景如下:

  1. 创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建
  2. 检查Deployment的状态来看部署动作是否完成(Pod副本数量是否达到预期的值)
  3. 更新Deployment以创建新的Pod
  4. 如果当前Deployment不稳定,则回滚到一个早先的Deployment版本
  5. 暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新的发布
  6. 扩展Deployment以应对高负载
  7. 查看Deployment的状态,以此作为发布是否成功的指标
  8. 清理不再需要的旧版本ReplicaSets

Deployment的定义如下所示,声明最终的部署结果,执行具体过程由kubernetes完成

apiVersion: apps/v1beta1
kind: Deployment
metadata:
 name: kubia
spec:
 replicas: 3
 template:
  metadata:
   name: kubia
    labels:
     app: kubia
  spec:
   containers:
   - image: luksa/kubia:v1
   name: nodejs

运行下面命令创建Deployment

# kubectl create -f tomcat-deployment.yaml

运行下面命令查看Deployment信息:

# kubectl get deployments
NAME          DESIRED        CURRENT       UP-TO-DATE    AGE
tomcat-deploy    1               1              1            4h

  • DESIRED:Pod副本数量的期望值,即在Deployment里定义的Replica。
  • CURRENT:当前Replica的值,实际上是Deployment创建的Replica Set里的Replica值,这个值不断增加,直到达到DESIRED为止,表明整个部署过程完成。
  • UP-TO-DATE:最新版本的Pod的副本数量,用于指示在滚动升级的过程中,有多少个Pod副本已经成功升级。
  • AVAILABLE:当前集群中可用的Pod副本数量,即集群中当前存活的Pod数量
1.4.3 组成部分StatefulSet

在Kubernetes管理的对象中,ReplicaSet、Deployment、DaemonSet和Job都是面向无状态的服务,但现实中很多服务是有状态的,比如数据库集群、Zookeeper集群等。这些有状态的集群有一些共性的特征:

  1. 每个节点都有固定的身份ID,通过这个ID,集群中的成员可以相互发现并通信;
  2. 集群的规模是比较固定的,集群规模不能随意变动;
  3. 集群中的每个节点都是有状态的,通常会持久化数据到永久存储中;
  4. 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。

为了解决这些有状态的服务,Kubernetes引入了StatefulSet资源,StatefulSet带有状态Pod,重启后依然具有原来的状态信息。具有以下特性:

  • StatefulSet里每个Pod都要稳定的、唯一的网络标识,可以用来发现集群内的其它成员。StatefulSet 中的每个 Pod 的名字都是事先确定的,不能更改。
  • StatefulSet控制的Pod的启停顺序是有依赖的,操作第n个Pod,前n-1个Pod已经运行且准备好
  • StatefulSet 中的 Pod,每个 Pod 挂载自己独立的存储,通过PV或PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷。如果一个 Pod 出现故障,从其他节点启动一个同样名字的 Pod,要挂载上原来 Pod 的存储继续以它的状态提供服务。

适合于StatefulSet的业务包括数据库服务MySQL和PostgreSQL、集群化管理服务ZooKeeper、etcd等有状态服务。StatefulSet的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。使用 StatefulSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,StatefulSet做的只是将确定的 Pod 与确定的存储关联起来保证状态的连续性。

1.4.4 后台支撑服务集DaemonSet

对于一些批处理型的业务,可能有些节点上运行多个同类业务的Pod,有些节点上又没有这类Pod运行。DaemonSet用于管理在集群中每个Node上仅运行一份Pod的副本实例。

在这里插入图片描述

典型的DaemonSet服务包括存储,日志和监控等在每个节点上支持Kubernetes集群运行的服务,比如每个Node上运行一个日志采集程序或者性能监控程序。

1.4.5 组成部分job

Job是Kubernetes用来控制批处理型任务的API对象,在处理完成后整个批处理任务就结束了。Job管理的Pod根据用户的设置把任务成功完成就自动退出了,成功完成的标志根据不同的spec.completions策略而不同:

  • 单Pod型任务有一个Pod成功就标志完成
  • 定数成功型任务保证有N个任务全部成功,需设定参数.spec.completions
  • 工作队列型任务根据应用确认的全局成功而标志成功

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

[外链图片转存中…(img-XuLTX9R9-1714813658893)]
[外链图片转存中…(img-Sxb0pwXL-1714813658894)]
[外链图片转存中…(img-r0E4OE3Y-1714813658894)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐