阿里云《云原生》公开课笔记 第五章 应用编排与管理

课程文字:https://edu.aliyun.com/lesson_1651_18353?spm=5176.10731542.0.0.5a8220beAacF7d#_18353

Kubernetes的资源元

元数据的组成
  • 用来识别资源的具有标识型的标签:Labels
    • key value
    • selector(筛选/组合资源):多个相等条件,逻辑与的关系; 集合型,in notin
  • 用来描述资源的非标识型的注解:Annotations
    • 扩展资源的spec/status
    • 可以包含特殊字符
    • 可以结构化也可以非结构化
  • 用来描述多个资源之间相互关系的 OwnerReference
    • 集合类的资源:replicaset、statefulset
    • replicaset 控制器在操作中会创建 Pod,被创建 Pod 的 Ownereference 就指向了创建 Pod 的 replicaset【可以用来定位和级联删除】

控制器模式

  • 三个逻辑组件:控制器,被控制的系统,以及能够观测系统的传感器
  • 过程:外界通过修改资源 spec 来控制资源,控制器比较资源 spec 和 status,从而计算一个 diff,diff 最后会用来决定执行对系统进行什么样的控制操作,控制操作会使得系统产生新的输出,并被传感器以资源 status 形式上报,控制器的各个组件将都会是独立自主地运行,不断使系统向 spec 表示终态趋近。
    image
控制模式中的传感器
  • 构成:Reflector、Informer、Indexer 三个组件
    image
Reflector
  • Reflector 通过 List 和 Watch K8s server 来获取资源的数据。
    • List 用来在 Controller 重启以及 Watch 中断的情况下,进行系统资源的全量更新;
    • Watch 则在多次 List 之间进行增量的资源更新;
  • Reflector 在获取新的资源数据后,会在 Delta 队列中塞入一个包括资源对象信息本身以及资源对象事件类型的 Delta 记录,Delta 队列中可以保证同一个对象在队列中仅有一条记录,从而避免 Reflector 重新 List 和 Watch 的时候产生重复的记录。
Informer

Informer 组件不断地从 Delta 队列中弹出 delta 记录,然后把资源对象交给 indexer,让 indexer 把资源记录在一个缓存中,缓存在默认设置下是用资源的命名空间来做索引的,并且可以被 Controller Manager 或多个 Controller 所共享。之后,再把这个事件交给事件的回调函数

控制模式中的控制器
  • 控制循环中的控制器组件主要由事件处理函数以及 worker 组成,事件处理函数之间会相互关注资源的新增、更新、删除的事件,并根据控制器的逻辑去决定是否需要处理。
  • 对需要处理的事件,会把事件关联资源的命名空间以及名字塞入一个工作队列中,并且由后续的 worker 池中的一个 Worker 来处理,工作队列会对存储的对象进行去重,从而避免多个 Woker 处理同一个资源的情况。
  • Worker 在处理资源对象时,一般需要用资源的名字来重新获得最新的资源数据,用来创建或者更新资源对象,或者调用其他的外部服务,Worker 如果处理失败的时候,一般情况下会把资源的名字重新加入到工作队列中,从而方便之后进行重试。
控制模式的例子
  • replicaset:replicas从2修改成3
    image
  • Reflector 会 watch 到 ReplicaSet 和 Pod 两种资源的变化,为什么我们还会 watch pod 资源的变化稍后会讲到。发现 ReplicaSet 发生变化后,在 delta 队列中塞入了对象是 rsA,而且类型是更新的记录。
  • Informer 一方面把新的 ReplicaSet 更新到缓存中,并与 Namespace nsA 作为索引。另外一方面,调用 Update 的回调函数,ReplicaSet 控制器发现 ReplicaSet 发生变化后会把字符串的 nsA/rsA 字符串塞入到工作队列中,工作队列后的一个 Worker 从工作队列中取到了 nsA/rsA 这个字符串的 key,并且从缓存中取到了最新的 ReplicaSet 数据。
  • Worker 通过比较 ReplicaSet 中 spec 和 status 里的数值,发现需要对这个 ReplicaSet 进行扩容,因此 ReplicaSet 的 Worker 创建了一个 Pod,这个 pod 中的 Ownereference 取向了 ReplicaSet rsA。

image

  • 然后 Reflector Watch 到的 Pod 新增事件,在 delta 队列中额外加入了 Add 类型的 deta 记录,一方面把新的 Pod 记录通过 Indexer 存储到了缓存中,另一方面调用了 ReplicaSet 控制器的 Add 回调函数,Add 回调函数通过检查 pod ownerReferences 找到了对应的 ReplicaSet,并把包括 ReplicaSet 命名空间和字符串塞入到了工作队列中。
  • ReplicaSet 的 Woker 在得到新的工作项之后,从缓存中取到了新的 ReplicaSet 记录,并得到了其所有创建的 Pod,因为 ReplicaSet 的状态不是最新的,也就是所有创建 Pod 的数量不是最新的。因此在此时 ReplicaSet 更新 status 使得 spec 和 status 达成一致。
控制器模式采用命令式api
  • 两种API类型
    • 命令式 API:家长和孩子交流方式,因为孩子欠缺目标意识,无法理解家长期望,家长往往通过一些命令,教孩子一些明确的动作,比如说:吃饭、睡觉类似的命令。容器编排体系中,命令式 API 就是通过向系统发出明确的操作来执行的。
      • 存在问题1:如果命令没有正确执行,调用方只能反复充实恢复错误;某解决思路:交互系统后台会做一个巡检系统,修正数据不一致的场景;但巡检系统一般是人工触发的。
      • 存在问题2:多并发访问,命令式系统会在操作前加锁,从而保证系统最后生效,但会降低操作效率。但是声明式系统天然记录了系统现在和最终的状态
    • 声明式 API:老板对自己员工的交流方式。老板一般不会给自己的员工下很明确的决定,实际上可能老板对于要操作的事情本身,还不如员工清楚。因此,老板通过给员工设置可量化的业务目标的方式,来发挥员工自身的主观能动性。比如说,老板会要求某个产品的市场占有率达到 80%,而不会指出要达到这个市场占有率,要做的具体操作细节。
      • 对资源状态的巡检属于正常操作
      • 支持多并发的访问,合并多次对资源的修改
  • k8s的控制器模式
    • 声明式api,根据资源对象修改
    • 异步控制系统,逼近于设置的最终状态
    • 有状态的应用,可以自定义资源和控制器方式【后续的operator场景】
自测题目
  • 下列哪个键值对无法作为 k8s对象的 label ?(单选题)D

    • A. app.kubernetes.io/version=3.4.1
    • B. failure-domain.beta.kubernetes.io/region=cn-shanghai
    • C. app-name=trade
    • D. scaling-config=“min-replicas:50”
  • 下列哪个键值对不适合做为 annotations ?(单选题)B

    • A. statefulset 的历史配置 yaml
    • B. service 对应的应用名,用来方便筛选
    • C. 用来表示 ingress 路由的正则表达式值
    • D. 用来扩展 pod 状态,表示对应 pod 在第三方数据库的记录情况
  • 下列哪个场景不是 selector 的使用场景?(单选题)C

    • A. 设计一个查询的界面,根据 label 筛选资源
    • B. 配置应用的调度规则, 选择必需调度到包含某些 label 的节点
    • C. 存储数据库应用的配置信息
    • D. 判断可能归属于 replicaset 的 pod
  • controller 中 reflector 不会对 apiserver 进行 LIST 操作的场景?(单选题)D

    • A. controller 重启的时候
    • B. 和 apiserver watch 操作异常的情况
    • C. 配置定期的执行 LIST
    • D. controller 中需要筛选符合标签的 pod 时候
  • Controller 中的 object store 默认以什么作为索引?(单选题) C

    • A. 对象的 label
    • B. 对象的 annotation
    • C. 对象的 namespace
    • D. 对象的名字
      • https://blog.csdn.net/fy_long/article/details/89678829#%E5%AF%B9%E8%B1%A1%E7%BC%93%E5%AD%98-store
      • Store 是key-value类型的对象缓存;NewStore函数返回struct cache类型对象
      • Indexer是在Store的基础上,增加了索引,可以快速获取一批对象;NewIndexer返回实现该接口的struct cache类型对象。对象的索引是一个字符串列表,该列表是由IndexFunc函数生成;client-go package 提供了名为 NamespaceIndex 的 IndexFunc 类型函数 MetaNamespaceIndexFunc,它提取对象的 Namespace 作为索引。
  • Controller 中的 workerqueue 中可以存放什么内容?(单选题)A

    • A. Namespace 名+ pod 名
    • B. Namespace 名+pod 名+事件的类型
    • C. Pod 的列表
    • D. Pod 对象的指针
  • 下列关于 controller 中 workqueue 描述不正确的(单选题)B

    • A. 因为 workqueue 具备去重功能,可以往 workqueue 中反复加入资源
    • B. 为了加速 controller 的处理,可以往 workqueue 中加入资源的指针
    • C. 一个控制器的 workqueue 一般只存储一种类型资源的名字
    • D. 对于处理 node 的控制器,可以只在 workqueue 中加入节点的名字而不包括命名空间
  • 在 controller 的 event handler 中,不适合执行的操作是(单选题)D

    • A. 根据资源的 ownerreference 找到资源的创建者
    • B. 判断资源信息,对于不关心的对象, 直接返回
    • C. 在 workqueue 中加入资源
    • D. 执行控制器的实际处理工作 (workqueue实现的)
  • controller 中 worker 最不适合做什么操作(单选题)D

    • A. 创建其他资源对象
    • B. 重新往 workqueue 中塞入对象
    • C. 更新资源对象的 status
    • D. 调用其他耗时的 web 服务并等待返回(占用资源低效)
    • E. 什么都不做
  • 以下不是声明式的 API 设计(多选题)ABC

    • A. 创建一个容器的 API 是 POST /containers/create,请求参数是容器的各种规格, 返回系统生成的容器 id
    • B. 删除一个容器的 API 是 DELETE /containers/, 返回一个异步删除的工单号,可以根据工单号查询删除进度
    • C. 给应用扩容的 API 是 PUT /containers/create?increaseReplicas=1, 参数指定扩容的增量容器数量
    • D. 更新一个容器镜像的 API 是 PATCH /containers/?image=nginx, 返回的是容器新的目标状态

k8s命令

  • kubectl get pods --show-labels
  • kubectl label pods nginx1 env=test —overwrite (覆盖标签)
  • kubectl label pods nginx1 env=test(添加标签)
  • kubectl label pods nginx env- (删除标签)
  • kubectl get pods —show-labels -l env=test (selector通过-l来指定)
  • kubectl get pods —show-labels -l env=test,env=dev (与关系)
  • kubectl get pods —show-labels -l ’env in (dev,test)’ (集合)
  • kubectl annotate pods nginx1 my-annotate=‘my annotate,ok’ (增加注解)
  • kubectl get pods nging1 -o yaml | less (通过less分页显示)

附录

apiserver的list-watch源码学习
  • 相关链接:https://www.kubernetes.org.cn/174.html
  • watchCache是数据从etcd过来的第一站
  • 从watchCache中拿到从某个resourceVersion以来的所有数据——initEvents,然后用这个数据创建了一个watcher返回出去为某个客户端提供服务。
  • apiserver向etcd发起的watch是没有条件的,只能知道某个数据发生了变化或创建、删除,但不能过滤具体的值。
  • list是watch失败,数据太过陈旧后的弥补手段。list本身是一个简单的列表操作,和其它apiserver的增删改操作一样。
    image
master核心组件之间的关系

image

  • kubectl直接和master节点的apiserver通信
  • master节点的apiserver和etcd通信
  • master节点的controller-manager和sheduler,通过和apiserver通信获取信息(list-watch)
回调函数
  • 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值