学习K8S的第一步,当然是了解它基本概念了(说实话很多)。本文总结自《kubernetes权威指南》,个人学习笔记。
Kubernetes简称K8S
K8S是一个基于容器技术的分布式架构解决方案,提供了完善的管理工具,涵盖了开发、部署、动态扩容、滚动升级、运维监控等多个方面。相比于Docker,K8S是容器的管理者,协调者,监控者(一个全局把控的角色),而Docker则在这个平台中充当运行时。
Docker生态也有类似于K8S概念的东西-Docker Swarm,但功能上并没有K8S强大,毕竟K8S是Google在多年实践的产物。目前主流的还是K8S+Docker运行时
Kubernetes基本概念和术语
在kubernetes中Node、Pod、RC、Service等都被看作是一种 资源对象 ,几乎所有的资源对象都由K8S提供的 kubectl 工具(或者通过API调用),执行增删该查的操作,并将其保存到 etcd 中持久存储。
通常使用 yaml 或 json 文件来声明一个 资源对象 (每个资源对象都有自己特定的属性和语法结构),需要重点注意的是 apiVersion 属性。K8S平台采用了“核心+外围扩展”的设计思路(在保持平台核心稳定的同时持续推进升级优势),大部分的 资源对象 都是属于 v1 这个 核心API(apiVersion: v1)。K8S升级过程中,这些资源对象会有一些新的属性,K8S的处理方式是,一开始,将它存储到一个很长的备注字段里面(作为一种扩展属性),等到成熟后,修改数据库结构(增改表列)形成正式版。
Master(第一个讲的肯定很重要)
集群控制节点(通常单独占据一台服务器,高可用建议部署3台)。K8S集群都需要一个Master来负责管理和控制,基本上K8S伤感所有控制命令都发给它,它负责具体的执行过程。如果Master炸了,那集群内容器应用管理也都会失效。另外,Master上通常还需要部署etcd服务,因为K8S所有的资源对象的数据都存储在etcd中
关键进程:
- Kubernetes API Server(kube-apiserver):提供HTTP Rest接口,能力就是对所有资源进行过增、删、改、查。
- Kubernetes Controller Manager(kube-controller-manager):Kubernetes里所有资源对象的自动化控制中心,理解成资源对象的“大主管”。
- Kubernetes Scheduler(kube-scheduler):负责资源调度(Pod调度)的进程,相当于公交公司“调度室”。
Node
除Master之外,其他的机器被称为Node(较早版本为Minion),是K8S集群中工作负载节点,每个Node节点会被Master分配一些工作负载(其实就是Docker容器)。当Node宕机时,它的工作负载会被Master指派给其他的Node。
关键进程:
- kubelet:负责Pod对应容器的创建,启停等任务,同时和Master密切协作,实现集群的管理。
- kube-proxy:实现Kubernetes Service的通信和负载均衡机制的重要组件。
- Docker Engine:Docker引擎,负责提供容器创建和管理工作。
==待补充==:Node相关命令和详细属性信息解释
Pod(最重要的基本概念)
每一个Pod都包含一个被称为“根容器”的Pause容器和一个或者多个密切相关的用户业务容器。它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元。 Pod 表示集群上正在运行的进程。
为什么Pod是这样的一个结构组成(为什么有Pause容器)?
- 在一组容器作为一个单元的情况下,很难简单的对“整体”进行判断。例如一个容器死亡了,此时算整体死亡吗?还是说超过N/M的死亡率才算是死亡。引入一个与业务无关的且不容易死亡的Pause容器作为Pod的根容器,以它的状态代表整个容器状态,很简单,巧妙的解决了这个问题。
- Pod里的多个业务容器共享Pause容器的Ip和挂在的Volume。简化了业务容器之间的通信问题,和他们之间的文件共享问题。
Pod其实有两种类型,普通的Pod和静态的Pod(Static Pod)。后者比较特殊,并没有存储到K8S的etcd存储里,而是存储在具体Node上的一个具体文件中,并且只能在此Node上启动运行。而普通的Pod,一旦创建;就会被放入到etcd中存储,后被K8S Master调度到具体的某个Node上并进行(Binding),之后该Node上的kubelet进程实例化成一组相关的Docker容器并运行。如果Pod所在的Node宕机,就会将这个Node上所有Pod重新调度到其他节点上。
Kubernetes为每个Pod都分配了唯一的IP地址,称之为Pod IP。一个Pod里多个容器共享Pod IP地址。Kubernetes要求底层网络支持集群内任意两个Pod之间的TCP/IP直接通信(这通常使用虚拟二层网络技术来实现)。牢记一点:在Kubernetes里,一个Pod里的容器与另外主机伤感的Pod容器能够直接通信。。Pod的IP加上这里的容器端口(containerPort),组成一个新的概念EndPoint,它代表Pod里的一个服务进程的对外通信地址,一个Pod存在多个Endpoint的情况。
对于绝大多数的容器来说,一个CPU的资源配额相当大,所以K8S通常以千分之一CPU配额为最小单位,用m来表示。一般一个容器的CPU配额为100~300m(占0.1~0.3个CPU)。和CPU配额类型,Memory配额也是个绝对值,它的单位是内存字节。一般需要配置两个参数
-Requests:该资源的最小申请资源量,系统必须满足要求。
-Limits:该资源最大使用量,突破后容器可能会被杀死。
Docker Volume在K8S里面对应Pod Volume,但做了一些扩展比如说可以使用分布式文件系统GlusterFS实现后端存储功能,Pod Volume被定义在Pod上,然后被各个容器挂在到自己的文件系统中。
还有一个Kubernetes Event的概念,Event是一个事件记录,记录了事件最早产生事件,最后重现时间,重试次数,发起者,类型以及导致此事件的原因信息。是排查故障的重要参考信息。Node的描述信息有Event的描述,Pod的也有。
kubectl describe pod xxx 来查看描述信息
==待补充==:Pod相关命令和属性定义解释
Label
标签,一个Label是一个key=value的键值对,其中key与value由用户自己指定,Lable可以附加到各种资源对象上(Node,Pod,Service,RC)。Lable和资源对象是多对多关系,通常在定义资源对象时确定,也可以在创建后进行动态的添加或者删除。通过Label我们可以很方便对资源进行过筛选,以便进行资源分配,调度,配置,部署管理。
常用Label:
- 版本标签:"release":"stable","release":"canary"
- 环境标签:"environment":"dev","environment":"qa","environment":"production"
- 架构标签:"tier":"frontend","tier":"backend","tier":"middleware"
- 分区标签:"partition":"customerA"
- 质量管控标签:"track":"daily","track":"weeklyss"
当给特定的资源打上标签后,可以通过Label Selector(标签选择器)查询和筛选拥有某些Lable的资源对象。当前有两种Lable Selector表达式。
1.基于等式(Equality-base)
- name=redis:匹配所有具有标签name=redis的资源对象
- env!=prod:匹配所有不具有标签env=prod的资源对象
2.基于集合(Set-based)
- name in (redis,mysql):具有括号内任何一个的
- name not in (redis,mysql):不包含括号内任何一个
可以通过多个Lable Selector表达式组合实现复杂的条件选择,多个表达式之间用“,”隔开,几个条件之间是AND的关系。如name=redis,env!=prod。
管理对象RC和Service可以通过Selector字段设置需要关联的Pod的Label。如下:
spec:
selector:
app:web
其他管理对象Deployment,ReplicaSet,DaemonSet和Job则可以在Selector中使用基于集合的筛选条件定义。如下:
selector:
matchLables:
app:web
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
- {key: enviroment, operator: NotIn, values: [dev]}
matchLabels用来定义一组Label,matchExpressions用来定义一组基于集合的筛选条件,可用的条件运算符包括,In,NotIn,Exists和DoesNotExists.如果同时使用了两者,则他们的关系为AND。
Label Selctor在Kubernetes中的重要使用场景如下:
- kube-controller进程通过资源对象RC上定义的Label Selector来筛选出副本的数量,使Pod的数量始终符合预期定义的全自动控制流程。
- kube-proxy进程通过Service的Lable Selector来选择对应的Pod,自动建立每个Service到对应的Pod的请求转发路由表,实现Service的智能负载均衡。
- 通过Node定义的Lable,并且Pod定义文件中使用Node Selector这种标签调度策略,kube-scheduler进程可以实现Pod定向调度的特性。
Replication Controller
简称RC,RC定义了一个期望的场景,即声明某种Pod的副本数量在任何时刻都符合耨个预期值,一个RC的定义包含如下几个部分。
- Pod期望的副本数量
- 用来筛选目标Pod的Label Selector
- 当Pod的副本数量小于预期数量时,用来创建新的Pod的Pod模版(template)。
在我们定义一个RC并将其提交到Kubernetes集群中后,Master上的Controller Manager组件就得到通知,定期检查系统中当前存活的Pod,并确保Pod实例的数量刚好等于RC的期望值(通过停掉或者创建)。并且运行期间我们可以通过修改RC的副本数量,来实现Pod的动态缩放(Scaling)。
kubectl scale rc redis-slave --replicas=3
在运行期间,删除RC并不会影响已经创建好的Pod。另外kubectl提供了stop和delete命令,一次性删除RC和RC控制的Pod。借助RC可以很容易的实现滚动升级,例如说有10个Pod,应用升级时,可以停掉一个久的应用,那么为了满足期望,就会重新启动一个新的,等启动好了之后,在搞掉一个旧的,重复这个步骤直到所有的容器都是新的版本。
Replication Controller由于和K8S代码中的模块Replication Controller同名,同时RC无法准确表达本意,所以在K8S1.2中,升级为一个新的概念Replia Sets 支持基于集合的Label Selector(Set-based selector),而RC仅支持等式的Label Selector(equality-based selector)。kubectl命令工具适用于RC的绝大部分命令同样适用于Replica Set。但是当前我们很少使用Replica Set 它主要被Deployment这个更高层的资源对象所使用,从而形成一整套Pod创建删除更新的编排机制。
总结RC(Replica Set)的特性和作用
- 在大多数情况下,我们通过定义一个RC实现Pod的创建及副本数量的自动控制。
- 在RC里包括了完整的Pod定义模版。
- RC通过Label Selector机制实现对Pod副本的自动控制。
- 通过改变RC里的Pod副本数量,可以实现Pod的扩容或缩容。
- 通过改变RC里Pod模版中的景象版本,可以实现Pod的滚动升级。
==待补充==:RC相关命令和属性定义解释
Deployment
Deployment是K8S在1.2版本中引入的新概念,用来跟好解决Pod的编排,Deployment在内部使用了Replica Set来实现目的,可以把它看作是对RC的一次升级,两者相似度超过90%。Deployment相对于RC的一个最大升级是我们可以随时知道当前Pod部署的进度(就是能够看到这个过程中的状态变化)。
Deployment的典型使用场景
- 创建一个Deployment对象来生成对应的Replica Set 并完成Pod副本的创建。
- 检查Deployment的状态,来看部署动作是否完成,(Pod副本数量是否达到预期的值)
- 更新Deployment以创建新的Pod(比如镜像升级)。
- 如果当前Deployment不稳定,则回滚到一个个早先的Deployment版本。
- 暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新的发布。
- 扩展Deployment以应对高负载。
- 查看Deployment的状态,以此作为发布是否成功的指标。
- 清理不再需要的旧版本ReplicatSets
Pod的管理对象,包括RC、ReplicatSet,Deployment、DaemonSet、StatefulSet、Job等。它们用于不同的应用场景中。
==待补充==:Deployment相关命令和属性定义解释
...未完待续