资讯详情

k8s-核心概念与API原语

第一章(快速入门)

1.1.贵圈发展史

  • 2004-2007 Google容器的大规模使用Cgroups技术
  • 2008.1 cgroups合并进入linux内核主干
  • 2013.1 docker项目发布,传统paas产品"降维打击"
  • 2014.6 kubernetes项目发布,Google Borg/Omega系统思想借助开源社区”重生“,”容器设计模式“的思想正式成立
  • 2015.7 CNCF(云原生基金会)成立,k8s成为第一个CNCF项目
  • 2015-2016 ,三国争霸容器编排,Docker Swarm(偏生态),Mesos(偏技术),Kubernetes在容器安排领域竞争。解决你知道的问题
  • 2017 Kubernetes确立项目标准,docker公司选举内置核心产品kubernetes服务,Swarm项目逐步停止维护
  • 2018 云原生技术理念逐渐萌芽,kubernetes以云为核心云制造商的既定标准,以云为核心的软件理念逐步旅行

1.2、landscape

landscape云原生全景图

1.3、云原生

:事实上,:

  Cloud native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach.   These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil.   The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of open source, vendor-neutral projects. We democratize state-of-the-art patterns to make these innovations accessible for everyone. 

:全新的软件开发、发布和运维模式,软件生在云上,生长在云上,

  • 云应用定义与开发过程:应用定义与镜像制作,CI/CD,消息和Streaming等
  • 云应用安排与管理:应用安排与调度、服务发现与治理、远程调用、API网关、Service Mesh
  • 监控和可观测性:监控、日志、Tracing、混沌工程
  • 云原生底层技术:容器运行时,云原生存储技术,云原生网络技术
  • 云原生工具集:流程自动化与配置管理、云原生安全技术、云密码管理
  • Serveless:Faas、Baas、Serveless计费 //Functions as a Service,Backend as a service

  • 不可变基础设施:

    • 目前实现:容器镜像 ///基础设施是不可改变的,是一个完全包含的东西,自描述可以随时迁移
  • 云应用编排理论:

    • 目前:容器设计模式:

  • 传统应用基础设施:(可变)
    • 例如:需要部署SSH到服务器,逐个调整配置,并在现有服务器上部署代码。基础设施是独一无二的宠物,要小心
  • 友好应用云基础设施:(不可变)
    • 部署完成后,基础设施不会修改或改变,如果要更新构建新的镜像即可。基础设施是可以替代的牲口,随时替换

  • 基础设施的一致性和可靠性:

    • 容器镜像 //镜像可以在任何地方打开
    • 自包含 //镜像包含运行所需要的所有依赖
    • 可飘逸 //可以在任何位置优雅
  • 简单可预测的部署和操作:

    • 自描述,自运维 //
    • 流程自动化 //
    • 水平扩展容易 //实例数调整
    • 控制系统和支持组件的快速复制 //

  • 自包含、可定制的应用镜像
  • 应用快速部署和隔离能力
  • 创建和销毁应用基础设施的自动化管理
  • 可复制的控制系统和支撑组件

二、第二章(K8s核心概念与API原语)

2.1、什么是Kubernetes

Kubernetes 源与希腊语,意思"舵手",或飞行员,k8s 通过将8个字母ubernete"替换8导出的缩写,container意为集装箱,k8s意思是成为一艘运输集装箱的船。k8s负责应用程序的部署、弹性和管理

2.2、核心功能

  • 平衡服务发现和负载
  • 自动发布和回滚
  • 容器自动装箱 //自动调度容器,将容器放在集群的机器上
  • 存储编排
  • 自动恢复 //检测节点状态,节点异常后自动调度pod
  • 配置与密文管理
  • 批量执行
  • 水平伸缩 ////修改副本值可以调整pod个数

2.3、架构

  • apiserver:处理api操作,K8s所有组件都会和apiserver连接,组件之间不连接,apiserver负责和etcd互动。集群中的所有操作都将通过apiserver
  • controller-manager: 负责集群中的资源对象(node,namespace,service,token等) 达到预期的工作状态 ///只有一个active,热热备
  • scheduler: 用于提交container 调度到合适的机器 ///只有一个active,热热备
  • etcd:元数据存储
  • kubelet: 负责这些组件的真正运行和监控apiserver的pod提交绑定事件container runtime中,在os创建容器所需的运行环境。
  • kub-proxy: 利用了iptables本地能力ipvs 规则创建

2.4、pod创建过程

0.每个组件的启动方向apiserver 发起watch请求订阅并告知apiserver您需要订阅哪些类型的变化数据。watch一种典型的发布-订阅模式是有条件的(例如kubelet只关心自己点上的Pod列表)。list是watch失败后,数据过于陈旧后的弥补手段。k8s的watch功能是建立在etcd的watch之上的,etcd key-value发生变化,通知apiserver,apiserver对外提供watch api。

1、用户通过cli或者ui进行pod创建,请求被apiserver接收

2、apiserver收到请求后,不会直接创建pod,而是生成一个包含创建信息的yaml,并将yaml信息存储到etcd

3、scheduler查看k8s api,判断pod.spec.Node == null?决定是否需要创建,并根据一定的算法找到最合适的pod,并将信息存储到etcd(通过apiserver存储)

4、kubelet watch apiserver查询自己是否有新增pod需要创建,如果有,Kubelet调用contianer runtime去创建容器运行环境

2.5、主要概念

  • pod : 是最小的调度以及资源单元、由一个或者多个容器组成、定义容器运行的方式(Command,环境变量等),提供给容器共享的运行环境(网络,进程空间等)

  • Volume:声明在pod中的容器可访问的文件目录,可以被挂载在Pod中一个或多个容器的指定路径下,支持多种后端多种存储的抽象(本地存储、分布式存储、云存储)

  • Deployment: 定义一组Pod的副本数目、版本等,通过Controller-manager维持Pod的数目;通过控制器指定的策略控制版本(滚动升级、重新生成、回滚等)

  • Service:提供访问一个或多个Pod实例的稳定访问地址,支持多种访问方式实现(ClusterIP,NodePort,LoadBalancer)

  • NameSpace:一个集群内部的逻辑隔离机制(鉴权、资源额度),每个资源都属于一个namespace,同一个Namespace中的资源命名唯一,不同Namespace中的资源可重命名

  • API:HTTP+JSON/YAML类型的api,kubectl/UI/curl命令 等发起请求

  • Label:一组key:value,可以被selector所查询,select color=red,资源集合的默认表达形式,例如Service 对应一组Pod

2.6、minikube

本地测试和实验使用

https://kubernetes/io/docs/tasks/tools/install-minikube

回到顶部

三、第三章(容器基本概念)

3.1、容器与镜像

:APP可以相互“看见“,相互通信,使用同样的文件系统,同样的系统资源。意味着具有privileged权限的进程可以攻击其他进程。使用同一个文件系统,导致APP可以对已有的文件系统进行增删改查,进程间资源依赖会出现冲突,以及系统资源抢占问题。

  • chroot: 视图级别进行隔离,把一个子目录编程根目录

  • namespace:资源试图隔离。进程在环境内使用独立的环境,但是资源还是使用操作系统的

  • cgroup: 限制APP的资源使用率

  • 容器是一个视图隔离、资源可限制、独立文件系统的进程集合。
    • 视图隔离:如能看见部分进程,独立主机名等;
    • 控制资源使用率:如2G内存大小;CPU使用个数等等。

  • 运行容器所需要的文件集合-容器镜像
  • DockerFile- 描述镜像构建步骤
  • 构建步骤所产出文件系统的变化 - changeset //镜像分层和复用 的理念和作用
    • 类似:disk snapshot
    • 提高分发效率,减少磁盘压力 #镜像分层带来的好处,各层级镜像复用,基础镜像被上层镜像所共用。#举例,如果本地已经有nginx的基础镜像,针对下载不同版本,只需要下载所需的镜像就可以
DockerFile最佳实践: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

  • 容器:和系统其他部分隔开的进程集合,包括网络,进程,文件系统等等
  • 镜像:容器所需要的所有文件集合- Build once,Run anywhere

3.2、容器生命周期

容器是一种具有隔离特性的进程集合,在使用doker run的时候可以使用image来提供独立的文件系统,以及指定相应的程序。所指定的这个程序称为init进程。容器的启停和init进程同步:

  • init进程生命周期 = 容器生命周期
  • 运行期间可运行exec执行运维操作

  • 独立于容器的生命周期
  • 数据卷 - docker volume vs bind

# bindg host dir into container
docker run -v /tmp:/tmp busybox:1.25 sh -c "date > /tmp/demo.log"

# check result
cat /tmp/demo.log

# let it handled by docker container engine
docker create volume demo

#demo is volume name 
docker run -v demo:/tmp busybox:1.25 sh -c "date > /tmp/demo.log"

#check result
docker run -v demo:/tmp busybox:1.25 sh -c "cat /tmp/demo.log"

3.3、容器项目的架构

moby和docker-ce以及docker-ee说明:

  • moby是继承了原先的docker的项目,是社区维护的的开源项目
  • docker-ce是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品
  • docker-ee是docker公司维护的闭源产品,是docker公司的商业产品

  • moby daemon:提供容器镜像,网络,volume等的管理
  • containerd:容器运行时管理引擎,独立于moby daemon
  • shim:类似于守护进程(单个容器的),shim负责管理容器的生命周期,容器可以有不同的运行时,现在有多种容器运行时的解决方案(runC,kata,gVisor等)。shim是用于针对不同的容器运行时所开发的。适用于多种容器运行时。并且可以被containerd动态接管

shim的另外一个好处:对moby或者containerd升级,因为有了shim,所以可以做到不影响业务

3.4、容器和vm的差异

  • VM
    • 隔离效果好,每个应用都是相互独立的,看不到其他guest os的应用
    • 占用更大的磁盘空间和更多的资源
  • container:
    • 启动时间较快
    • 磁盘空间占用较小
    • 隔离效果要比vm差很多,所以整体提供的隔离效果要差很多。kata container和gadvisor等强隔离的解决方案因此就火了起来

四、第四章(容器设计模式)

4.1、为什么我们需要pod

4.1.1、容器的本质

    • 一个视图被隔离、资源受限的进程
      • 容器中PID = 1 的进程就是应用本身
        • 容器里PID = 1的进程就是应用本身
          • 管理虚拟机 = 管理基础设施; 管理容器 = 直接管理应用本身
    • kubernetes就是云时代的操作系统
      • 以此类推,容器镜像其实就是:这个操作系统的软件安装包
    • 容器 = 进程(linux线程)
    • Pod = ?
      • 进程组(linux线程组)

linux实现 线程为 轻量级的进程

4.1.2、进程组概念提出

  • 举例: hello world程序由4个进程组成,这些进程之间共享某些文件
  • 问题:helloworld程序如何用容器跑起来呢?
    • 解法1: 在一个docker容器中,启动这4个进程
      • 疑问:容器 PID =1的进程就是APP本身的main进程,那么”谁“来负责管理剩余的3个进程?
      • 容器是”单进程“模型
      • 除非:
        • 应用进程本身具备”进程管理“能力(这意味着:helloworld程序需要具备systemd的能力)
        • 或者,容器的PID=1进程改为systemd
          • 这会导致:管理容器 = 管理systemd != 直接管理应用本身

:除非程序具有systemd的功能,否则他是没有管理多个进程的能力:

  • 如果在容器中启动了多个进程,只有一个能成为pid为1的进程。如果pid为1的进程挂了,那么其他的进程就成为了孤儿,没人能够回收容器内其他进程的资源。
  • 如果在程序中run systemd程序,那么就会存在第二个问题:没办法直接管理应用,因为应用的生命周期被systemd接管,应用状态的生命周期就不等于容器的生命周期。并且无法及时获知应用程序状态

4.1.3、pod是什么

Pod为K8s提出的类似于一个进程组的概念:

四个进程共同组成的一个应用hello workld,实际上会被定义为拥有四个容器的pod。pod是一个逻辑概念,真实启动的是4个容器。pod是k8s分配资源的一个单位。pod是k8s分配资源的一个单位

4.1.5、来自Google Borg的思考

Google的工程师么们发现,在Borg项目部署的应用,往往都粗壮乃着类似于”进程和进程组“的关系,更具体的说,就是这些应用之间有着密切的协作关系,使得他们必须部署在同一台机器上并且分享某些信息。

:1、怎么去描述超亲密关系;2、怎么对超亲密关系的容器或者业务进行调度

  • 亲密关系 - 调度解决
    • 两个应用需要运行在同一台宿主机上
  • 超亲密关系 - Pod解决
    • 会发生直接的文件交换
    • 使用localhost或者socket进行本地通信
    • 会发生非常频繁的RPC调用
  • 会共享某些Linux namespace(比如一个容器要加入另外一个容器的netowrk namespace)

4.2、pod的实现机制

如何让一个pod中的多个容器之间最高效的共享某些资源和数据?容器之间原本是被Linux Namespace和cgroups隔离开的

解决方法分为两个部分:共享网络和共享存储

4.2.1、共享网络

  • 容器A和B

    • 通过infra container的方式共享同一个 Network NameSpace #pause还提供PID,network,IPC,UTS等命名空间
      • 镜像: k8s.gcr.io/pause;汇编语言编写的、永久处于”暂停“,puase:3.1 大小为743KB非常小
    • 直接使用localhost进行通信
    • 看到的网络设备跟infra容器看到 的完全一样
    • 一个pod只有一个ip地址,也就是这个pod的network Namespace对应的IP地址
      • 所有网络资源,都是一个pod一份,并且被该pod中的所有容器共享
    • 整个Pod的生命周期和infra 容器一致,而与容器A和B无关
  • 通过infra container的方式共享network namespace

  • 一个pod中的所有容器看到的网络试图是一样的,整个pod的生命周期一定是等于infra pod的生命周期,并且infra pod一定是第一个启动的

4.2.2、pod如何去共享存储

apiVersion: "apps/v1"
kind: "Pod"
metadata:
  name: "name01"
spec:
  restartPolicy: "Always"
  volumes:
  - name: shared-data
	hostPath: 
      path: /data
  containers:	  
    - name: nginx-controller
	  image: nginx 
	  volumeMounts:
	  - name: shared-data 
	    mountPath: /usr/share/nginx/html 
    - name: debian-container
	  image: debian 
	  volumeMounts:
	  - name: shared-data 
	    mountPath: /pod-data 
      command: ["/bin/sh"]		
	  args: ["-c","echo Hello from the debian container ! > /pod-data/index.html"]

shared-data 对应在宿主机上的目录会被同时绑定挂载进了两个容器当中

4.3、详解容器设计模式

所有设计模式的本质都是:解耦和重用

  • 方法一: 把WAR包和Tomcat大包进一个镜像
    • 无论是WAR包和Tomcat更新都需要重新制作镜像
  • 方法二:镜像里只打包Tomcat。使用数据卷(hostPath)从宿主机上将WAR包挂载进tomcat容器
    • 需要维护一套分布式存储系统
  • 有没有其他更通用的方法?initContainer

apiVersion: "apps/v1"
kind: "Pod"
metadata:
  name: "javaweb-2"
spec:
  initContainers: 
  - image: resouer/sample:v2
    name: war
	command: ["cp","/sample.war","/app"]
	volumeMounts:
	- mountPath: /app 
	  name: app-volume
  containers:	  
    - name: tomcat
	  image: tomcat7:latest
	  command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]
	  volumeMounts:
	  - name: app-volume
	    mountPath: /root/apache-tomcat-7.0.42-v2/webapps
      ports:
      - containerPort: 8080
        hostPort: 8001	  
  volumes:
  - name: app-volume
    emptyDir: {}
  • init Container会比spec.Containers定义的用户容器先启动,并且严格按照定义的用户容器先启动;如果定义了多个initContainer,initContainer会严格按照定义顺序依次执行
  • /app是一个Volume
  • Tomcat容器,同样声明了挂载该Volume到自己的webapp目录下
  • 故当Tomcat容器启动时,它的webapps目录下就一定会存在sample.war
  • 在需要升级的时候,可以只更新sample镜像或者只更新tomcat镜像

 : 通过在pod内定义专门容器,来执行业务容器所需要的辅助工作

Sidecar的使用场景:

  • 应用与日志收集,Fluentd等作为日志收集
  • 代理容器:代理容器对业务容器屏蔽被大力的服务集群,简化业务代码的实现逻辑。{1、容器之间通过localhost通信,代理容器的代码被全公司重用}
  • 适配器容器:将业务容器暴漏出来的接口转换为另一种格式(yaml转为json,/metric转为/healthz等)

:一个container 需要访问外部系统或者服务,但是外部的服务或系统为集群状态,业务pod只需要访问一个ip地址,一种方法,改业务代码记录外部服务地址,还有一种方式就是解耦通过sidecar代理容器。单独写一个proxy专门用来对接外部的服务集群,但是对外只要暴漏一个ip地址就可以了。通过proxy代为连接集群。这里面该pod和proxy之间通信使用localhost无性能损耗。

回到顶部

五、第五章(应用编排与管理)

5.1、资源元信息

kubernetes资源对象

  • Spec: 期望的状态
  • Status:观测到的状态
  • Kind: 资源类型,Deployment,StatefulSet等
  • Metadata:
    • Labels:
    • Annotations:
    • OwnerReference: 描述多个资源之间的关系

5.1.1、Label

  • 标识性的Key: Value元数据
  • 作用:
    • 用于筛选资源
    • 唯一的组合资源的方法
  • 可以使用selector来查询
    • 类似于:SQL ' select * from ..wher ...'
资源 标签1 标签2
R1 Tie:front Env:dev
R2 Tie:back Env:prod
R3 Tie:front Env:test
R4 Tie:back Env:gray

  • 相等型Selector: Tie=front 筛选结果为R1和R3
  • 相等型的selector多个selector: Tie=front,Env=dev筛选结果为R1
  • 集合型selector:Env in (test,gray) 筛选结果为R3和R4
  • 其他集合selector:
    • Tie notin (front,back)
    • Tie notin release
    • Tie = !release

5.1.2、annotations

  • 作用:
    • 存储资源的非标识性信息
    • 扩展资源的spec/status
  • 特点:
    • 一般比label大
    • 格式为 key:value格式
    • 可以包含特殊字符
    • value可以结构化也可以非结构化
    • 可以用来存储证书id等

5.1.3、ownerReferences

  • ”所有者“即集合类资源
    • Pod的集合:Replicaset,statefulset
  • 集合类资源的控制器创建了归属资源
    • Replicaset控制器创建Pod
  • 作用:
    • 方便反向查找创建资源的对象
    • 方便进行级联删除

5.1.4、实践

[root@master1 yaml]# kubectl run nginx1 --image=reg.mt.com:5000/nginx:latest -l env=dev,tie=front --dry-run=true -o yaml > pod1.yaml
[root@master1 yaml]# kubectl run nginx2 --image=reg.mt.com:5000/nginx:latest -l env=dev,tie=front --dry-run=true -o yaml > pod2.yaml
[root@master1 yaml]# cat pod1.yaml #pod2的只有pod的名称和label不一样
apiVersion: apps/v1	
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    env: dev
    tie: front
  name: nginx1
spec:
  replicas: 1
  selector:
    matchLabels:
      env: dev
      tie: front
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        env: dev
        tie: front
    spec:
      containers:
      - image: reg.mt.com:5000/nginx:latest
        name: nginx1
        resources: {}
status: {}
[root@master1 yaml]# kubectl apply -f pod1.yaml  -f pod2.yaml
deployment.apps/nginx1 created
deployment.apps/nginx2 created

#1、获取pod的label
[root@master1 yaml]# kubectl get pods --show-labels
NAME                      READY   STATUS    RESTARTS   AGE     LABELS
nginx1-fb5497587-gdj9k    1/1     Running   0          3m15s   env=dev,pod-template-hash=fb5497587,tie=front
nginx2-6d5c4f84fb-qzr9q   1/1     Running   0          3m15s   env=dev,pod-template-hash=6d5c4f84fb,tie=front

#2、为pod打标签/删除标签 
[root@master1 ~]# kubectl label pods nginx1-fb5497587-gdj9k  env=test  --overwrite
pod/nginx1-fb5497587-gdj9k labeled
[root@master1 ~]# kubectl get pods --show-labels #因为deployment,所以直接打pod会自动创建一个新的pod
NAME                      READY   STATUS    RESTARTS   AGE    LABELS
nginx1-fb5497587-54x29    1/1     Running   0          14s    env=dev,pod-template-hash=fb5497587,tie=front
nginx1-fb5497587-gdj9k    1/1     Running   0          3h9m   env=test,pod-template-hash=fb5497587,tie=front
nginx2-6d5c4f84fb-qzr9q   1/1     Running   0          3h9m   env=dev,pod-template-hash=6d5c4f84fb,tie=front
[root@master1 ~]# kubectl label pods nginx1-fb5497587-gdj9k  env-   #删除标签

#3、label查找
[root@master1 ~]# kubectl get pods --show-labels -l 'env in (dev,prod)'
NAME                      READY   STATUS    RESTARTS   AGE     LABELS
nginx1-fb5497587-54x29    1/1     Running   0          36m     env=dev,pod-template-hash=fb5497587,tie=front
nginx2-6d5c4f84fb-qzr9q   1/1     Running   0          3h45m   env=dev,pod-template-hash=6d5c4f84fb,tie=front
[root@master1 ~]# kubectl get pods --show-labels -l 'env notin (dev,prod)'
NAME                     READY   STATUS    RESTARTS   AGE     LABELS
nginx1-fb5497587-gdj9k   1/1     Running   0          3h45m   pod-template-hash=fb5497587,tie=front

#4、anotate
[root@master1 ~]# kubectl annotate pods nginx1-fb5497587-dxl7k desc='author by MT'
pod/nginx1-fb5497587-dxl7k annotated
[root@master1 ~]# kubectl get pods nginx1-fb5497587-dxl7k -o yaml |grep annotations -A3
  annotations:
    desc: author by MT
  creationTimestamp: "2021-01-20T13:24:51Z"
  generateName: nginx1-fb5497587-
  
#5、ownerReference
[root@master1 ~]# kubectl get pods  nginx1-fb5497587-dxl7k   -o yaml |grep ownerReferences  -A5
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet	#被ReplicaSet控制的pod
    name: nginx1-fb5497587  #这个ReplicaSet的名称是 nginx1-fb5497587
[root@master1 ~]# kubectl get ReplicaSet nginx1-fb5497587  -o yaml |grep ownerReferences -A5
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: Deployment  
    name: nginx1  

5.2、控制器模式

5.2.1、控制循环

控制器模式,最核心的就是控制循环

外界通过修改资源的spec控制资源,控制器比较被控制资源的spec和status,计算一个diff。diff用来决定对系统执行什么样的操作。控制操作会使得系统产生新的输出。并被传感器以资源status的形式上报。控制器的各个组件都是独立自主的运行。

控制循环中逻辑的传感器主要有 Reflector,Informer,Indexer 三个组件构成。

  • Reflector: 通过list和watch apiserver来获取资源的数据
    • list用来在controller重启以及连接中断的情况下进行系统资源的全量分析
    • watch在多次list之间进行增量的资源更新
    • Reflector在获取新的资源数据后,会在一个delta队列中插入一个(包括资源本身信息以及资源事件(event)类型)的记录;delta队列保证同一个对象在queue中只有一条记录
  • Informer: 不断从delta队列中pop出记录, 一方便把资源事件交给event回调函数,一方面把资源对象交给Indexer
  • Indexer:把资源记录到缓存中。缓存默认情况下是以资源的namespace进行索引,并且被多个controller-manager共享

  • 主要由event handling 函数,以及worker组成
    • 事件处理函数:监听informer中的新增、更新、删除的事件。并根据控制器的逻辑决定是否需要处理。对于需要被处理的event,会把事件关联资源的namespace以及name信息放入到一个工作queue中。并且由worker池中的一个worker处理
    • 工作队列:对资源对象进行去重,从而避免多个worker处理同一个资源。worker在处理资源时,一般需要worker的名字,来重新获取最新的资源数据,用来创建或者更新资源对象,或者调用其他的外部服务。如果worker处理失败,一般会把资源重新加入到工作队列中,方便后续重试

5.2.2、控制器循环例子

举例:ReplicaSet(name=rsA,namespace=nsA)资源的replicas(pod个数)使用kubectl edit由2改为3的场景

先更新replicaset.spec,后更新pod,最后更新replicaset.status

  • 1、Reflector会watch Replicaset和Pod两种资源的变化,发现变化后在delta队列中新增记录

  • 2、Informer从delta queue中pop记录,把新的replicaset更新到缓存中(交给indexer)并以namespace和rsa作为索引,另一方面调用update的回调函数

  • 3、Replicaset控制器发现replicaset发生变化后,会把nsA/rsA字符串放入到工作队列中

  • 4、工作队列中的一个worker获取 nsA/rsA 这个字符串的key,并且从缓存中获取最新的replicaset数据

  • 5、worker通过比较replicaset中的status和spec中的replicas数据,发现需要对replicaset进行扩容。因此通知apiserver replicaset创建了一个pod,这个pod的ownereference取自 rsA,

  • 6、Reflector watch到了新增事件,在delta中添加记录

  • 7、informer从delta中获取新的记录,一方面通过indexer放入缓存中,另一方面调用repliset的控制器的add回调函数,add函数通过ownereference为rsA找到对应的replicaset,并把包括replicaset和namespace字符串放到 工作队列中

  • 8、replicaset的worker从工作队列中获取数据,从缓存中获取最新的replicaset记录。并得到所有创建的pod

  • 9、因为replicaset状态不是最新的,也就是所有创建的pod的数量已经不是最新的。因此更新rsA的status和spec一致。replicaset中的sepc和status达到了一致

5.3、控制器模式总结

API有两种声明方式:

  • 声明式API:市场占用率达到90%,副本个数为3个 //家长和孩子交流
  • 命令式API:吃饭,删除一个pod //领导和员工交流

kubernetes控制器模式:

  • 由声明式的API驱动 - k8s 资源对象
  • 由控制器异步地控制系统向终态驱近
  • 使系统的自动化和无人值守成为可能
  • 便于扩展- 自定义资源和控制器(特别的,operator)

标签: 8fu传感器传感器612gdj211bg传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台