Dawn's Blogs

分享技术 记录成长

0%

基本理解

在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。Kubernetes 使用这些实体去表示整个集群的状态。 比较特别地是,它们描述了如下信息

  • 哪些容器化应用正在运行(以及在哪些节点上运行)。
  • 可以被应用使用的资源。
  • 关于应用运行时表现的策略,比如重启策略、升级策略以及容错策略。

k8s一旦创建对象,将不断确保该对象存在。 通过创建对象,你就是在告知 Kubernetes 系统,你想要的集群工作负载状态看起来应是什么样子的, 这就是 Kubernetes 集群所谓的期望状态

操作 k8s 对象需要使用 Kubernetes API。

对象规约(Spec)与状态(Status)

每一个 Kubernetes 对象包含两个字段,它们负责管理对象的配置:

  • 对象规约 Spec:期望状态,在创建对象时必须设置的内容。
  • 对象状态 Status:当前状态,由 Kubernetes 系统和组件设置并更新的。

如一个对象需要启动 3 个副本,那么酒吧这个对象 Spec 设置为 3,当前副本数量就是 Status。Kubernetes 控制面会根据 Spec 和 Staus 来新增或者删除副本的数量。

描述 Kubernetes 对象

在创建 k8s 对象是,需要描述对象的基本信息,通过 yaml 文件来提供描述 Kubernetes 对象的信息。

一个 Kubernetes Deployment 对象的描述信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

必须字段

在 yaml 文件中,有以下必须的字段:

  • apiVersion:创建该对象所使用的 Kubernetes API 的版本。
  • kind:创建对象的类别。
  • metadata:帮助唯一标识对象的一些数据,包括一个 name、UID 和可选的 namespace。
  • spec:规约,期望的状态。

Kubernetes 简介

k8s 是一个大规模容器编排系统,具有以下特性:

  • 服务发现和负载均衡
    Kubernetes 可以使用名称或自己的 IP 地址公开容器(服务发现),如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
  • 存储编排
    Kubernetes 允许你自动挂载你选择的存储系统,并且管理这些分配的存储空间,例如本地存储、公共云提供商等。
  • 自动部署和回滚
    你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
  • 自动完成装箱计算
    Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。
  • 自我修复
    Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。
  • 密钥与配置管理
    Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

组件架构

Components of Kubernetes

控制平面(Control Plane)组件

控制平面组件会为集群做出全局决策,比如资源的调度、 以及检测和响应集群事件。

控制平面组件可以在集群中的任何节点上运行。 然而为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。

  • kube-apiserver:API 服务器,相当于控制平面的前端负责接受请求,可以水平扩容。
  • etcd:所有集群数据的后台数据库。
  • kube-scheduler:负责 Pod 的调度决策工作。
  • kube-controller-manager:负责运行控制器进程(控制器通过 API 服务器监控集群的公共状态,并致力于将当前的状态转换为期望的状态)。从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。控制器包括:
    • 节点控制器:负责在节点出现故障时进行通知和响应。
    • 任务控制器:监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成。
    • 端点分片控制器:填充端点分片(EndpointSlice)对象(以提供 Service 和 Pod 之间的链接)。
    • 服务账号控制器:为新的命名空间创建默认的服务账号(ServiceAccount)。
  • cloud-controller-manager:仅运行特定于云平台的控制器。

Node 组件

节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。

  • kubelet:在每一个节点上运行,用于管理运行在这个节点上的 Pod。
  • kube-proxy:是每一个节点上的网络代理,维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
  • 容器运行时(Container Runtime):负责运行容器的软件。

策略模式

策略模式中,可以随意的更换算法使用的策略。策略模式的角色和职责如下:

  • 环境类(Context):环境类是使用算法的角色,它在解决某个问题时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。
  • Strategy(抽象策略类):定义了策略抽象方法,在环境类的算法中调用了抽象策略类中的抽象方法,所以在具体执行时会调用具体策略类中定义的方法。
  • ConcreteStrategy(具体策略类):实现了抽象策略类,定义了具体的策略方法。

image-20230424223552253

阅读全文 »

模板方法模式

模板方法就是定义一个模板方法和组成模板方法的许多抽象子方法,通过重写抽象子方法来自定义模板方法的执行过程。模板方法模式中的角色和职责如下:

  • 抽象类(AbstractClass):在抽象类中定义了一系列基本操作,这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法,用于定义一个算法的框架。
  • 具体子类(ConcreteClass):抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

image-20230424220043836

阅读全文 »

适配器模式

适配器模式将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

适配器的核心在于将一个适配者 Adaptee,通过适配器 Adapter 转换为另一个接口 Target 来使用。实现原理就是 Adapter 通过实现 Target 接口,并在对应的方法中调用 Adaptee 的接口实现。

适配器模式的角色和职责如下:

  • 目标抽象类 Target:定义客户所需要的接口,也可以是具体类。
  • 适配器类 Adapter:适配器类是适配器模式的核心,在对象适配器中,它通过继承(活实现)Target 并关联一个 Adaptee 对象使二者产生联系。
  • 适配者类 Adaptee:被适配的角色,它定义了一个已经存在的接口,这个接口需要适配。

image-20230418212755861

阅读全文 »

代理模式

代理模式就是为对象提供一个代理,这个代理可以控制对这个对象的访问。这个代理又投了额外添加的功能,同样也符合开闭原则,因为原来对象并不会改变只会增加代理的功能。

代理中的角色和职责如下:

抽象主题角色:真实主题和代理主题的共同接口。

真实主题角色:代理角色所代理的真实对象,实现了抽象主题接口。

代理主题角色:包含对真实主题角色的引用,代理也实现了抽象主题接口,代理在执行真实主题之前或者之后又进行了一些操作。

image-20230418202707559

案例

比如购物作为一个主题任务,这是一个抽象的主题。那么真实的主题包括韩国购物、美国购物等。那么海外代购就算是这些主题的代理,代理在去购物之前还需要辨别真假,接着购物,最后进行海关安检等。

image-20230418204443811

阅读全文 »

抽象工厂模式

工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。因此,可以考虑将一些相关的产品组成一个产品族,由同一个工厂来统一生产,这就是抽象工厂模式的基本思想。

产品族和产品等级结构

产品族:具有同一个地区、同一个厂商、同一个开发包、同一个组织模块等,但是具备不同特点或功能的产品集合,称之为是一个产品族。

产品等级结构:具有相同特点或功能,但是来自不同的地区、不同的厂商、不同的开发包、不同的组织模块等的产品集合,称之为是一个产品等级结构。

当程序中的对象可以被划分为产品族和产品等级结构之后,那么抽象工厂方法模式才可以被适用。抽象工厂模式就是一个针对产品族进行生产的。

image-20230418171322007

角色和职责

抽象工厂角色:声明了一组用于创建一族产品的方法,每一个方法对应一种产品。

具体工厂角色:实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。

抽象产品角色:工厂所创建对象的父类,描述产品的接口。抽象产品的角色定义了产品等级结构。

具体产品角色:抽象产品的具体实现。

阅读全文 »

简单工厂模式

简单工厂模式就是用一个工厂类负责生产所有的产品。其结构和职责如下:

  • 工厂角色:简单工厂模式的核心,负责生产所有的产品。工厂类可以被外界直接调用,创建所需的产品对象。
  • 抽象产品角色:工厂所创建对象的父类,描述产品的接口。
  • 具体产品角色:工厂所创建的对象。

image-20230418165944956

优缺点

优点:

  • 实现了对象创建和使用的分离。

缺点:

  • 工厂类职责过重,所有的产品均通过工厂类生产。
  • 违反开闭原则,添加新产品需要修改工厂逻辑,工厂越来越复杂。

工厂方法模式

在工厂方法种,将工厂抽象为一个抽象工厂,具体的工厂是抽象工厂的一个实现类。其角色和职责如下:

  • 抽象工厂角色:工厂方法模式的核心,任何工厂类都必须实现这个接口。
  • 工厂角色:是抽象工厂的一个实现,负责实例化产品对象。
  • 抽象产品角色:工厂所创建对象的父类,描述产品的接口。
  • 具体产品角色:工厂角色所创建的对象。

image-20230418170410589

优缺点

优点:

  • 实现了对象创建和使用的分离。
  • 对于新产品的创建,符合开闭原则。

缺点:

  • 每一种工厂负责一个产品的实现,增加了类的个数,抽象性和理解难度增加。

设计模式概述

GoF 提出的设计模式总共有 23 种,包括三种类型:

  • 创建型模式:如何创建对象。
  • 结构型模式:如何实现对象的组合。
  • 行为型模式:对象如何交互、怎样分配职责。

23 种设计模式 + 简单工厂模式,就是全部的 24 种设计模式。

设计模式总结

24 种设计模式总结如下:

  • 创建型模式(6种):
    • 单例模式:保证一个类只有一个实例,提供一个访问这个实例的全局访问点
    • 简单工厂模式:通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
    • 工厂方法模式:定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
    • 抽象工厂模式:提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。
    • 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
    • 建造者模式:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
  • 结构型模式(7种):
    • 适配器模式:将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
    • 装饰器模式:动态的给一个对象添加一些额外的职责。就增加功能来说,此模式比生成子类更为灵活。
    • 外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
    • 代理模式:为其他对象提供一种代理以控制对这个对象的访问
    • 桥接模式:将抽象部分与实际部分分离,使它们都可以独立的变化。
    • 组合模式:将对象组合成树形结构以表示“部分–整体”的层次结构。使得用户对单个对象和组合对象的使用具有一致性。
    • 亨元模式:以共享的方式高效的支持大量的细粒度的对象。
  • 行为型模式(11种):
    • 命令模式:一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
    • 观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    • 策略模式:准备一组算法,并将每一个算法封装起来,使得它们可以互换。
    • 模板方法模式:子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
    • 解释器模式:如何为简单的语言定义一个语法,如何在该语言中表示一个句子,以及如何解释这些句子。
    • 迭代器模式:提供了一种方法顺序来访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
    • 中介者模式:定义一个中介对象来封装系列对象之间的交互。终结者使各个对象不需要显示的相互调用 ,从而使其耦合性松散,而且可以独立的改变他们之间的交互。
    • 备忘录模式:是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
    • 状态模式:对象的行为,依赖于它所处的状态。
    • 访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
阅读全文 »

死码消除

什么是死码消除

死码消除(dead code elimination,DCE)是一种编译器优化技术,用处是在编译阶段去掉对程序运行结果没有任何影响的代码

死码消除有很多好处:减小程序体积,程序运行过程中避免执行无用的指令,缩短运行时间。

应用

全局常量 vs 全局变量

在某些情景下使用全局常量替换全局变量,性能可能会有很大的提升。

在使用常量时,在某些情况下编译器可以直接得到计算结果,进而可以死码消除

死码消除删除了不必要的分支和语句,不仅二编译后的二进制文件体积减小,而且因为可能少了一些判断分支的条件所以效率也会提升

阅读全文 »