目录
一、使用容器原因
二、容器与虚拟机区别
虚拟机
Docker
三、使用K8s原因
四、常用概念
Master
Node
Pod
为什么提出Pod的概念?
Labels
Namespace
Replication Controller(RC)
Deployment
Service
服务发现机制
kube-proxy
外部系统访问Service
Ingress
Volume
ConfigMap
五、Pod调度
调度说明
Affinity:亲和性调度
Taint(污点)和 Toleration(容忍)
一、使用容器原因
- 降低硬件成本,充分利用服务器资源,省钱(不是一星半点);
- 更快速的部署开发(性能更好、启动更快)
- 易维护(大大节省运维成本)
- 更易实现微服务、云原生
二、容器与虚拟机区别
虚拟机
以某种技术将物理资源虚拟成资源池。
通过Hypevisor层(虚拟机管理系统)抽象底层基础设施资源,提供相互隔离的虚拟机。
每一个隔离的虚拟机都建立在GuestOS(客户机操作系统)之上,因此每一个VM不仅需要运行操作系统的完整副本,还要同时运行操作系统运行所需要的所有硬件的虚拟副本,增加RAM、ROM和CPU成本;且由于中间增加的虚拟技术,导致计算、IO、网络性能损失,造成资源浪费。
其完全隔离,安全性更高,擅长于彻底的环境隔离、用户隔离
启动时间在分钟级
Docker
容器技术没有GuestOS(客户机操作系统),用Docker守护进程(一个后台进程)取代虚拟机技术的Hypevisor,直接运行于宿主机操作系统上,负责管理Docker容器;其将容器与宿主机操作系统分离,并将各个容器互相隔离;
所有的容器共享宿主机操作系统内核,减少重复的操作系统代码副本;因此启动更快,消耗资源更低,节省大量的ROM,增加硬件资源利用率;
进程级隔离,更擅长隔离不同的应用,但安全性有所降低
启动时间在毫秒级
三、使用K8s原因
K8s,全称kubernetes,因为首字母是k,结尾字母是s,中间8个字母,因此简称K8s。是Google一个开源容器编排引擎,是容器集群管理系统。
- 持续开发、集成和部署(自动化)
- 大规模弹性伸缩
- 应用容器化
特点
- 服务发现与负载均衡
- 存储系统挂载
- 应用健康检查
- 滚动更新
- 资源监控
- 故障迁移
四、常用概念
Master
集群控制节点,每个Kubernetes集群需要一个Master节点来对集群进行管理和控制,Kubernetes所有控制命令均发送给Master,负责具体执行过程。
Master节点通常会占据一个独立的服务器(物理机或虚机),因为太重要,宕机或不可用,整个控制命令都将失效。
Node
Kubernetes集群中,Master以外的节点均被称为Node节点,Node节点也会占据一个独立的服务器;是Kubernetes集群中的工作负载节点
当某个Node宕机时,其上的工作负载会被Master自动转移至其他Node节点
Pod
Pod是Kubernetes最重要也最基本的概念,是Kubernetes创建、管理、部署的最小单位。一个Pod内部可以封装一个或多个容器,每一个Pod都由Pause容器和用户业务容器组成;Pause容器为Pod的”根容器“,属于Kubrenetes平台的一部分。
Kubernetes直接管理的是Pod而不是容器;在Pod中,所有容器会被统一安排和调度;当Pod中某个容器停止,Kubernetes自动监测并重启该Pod(Pod中所有容器会被一起重启);若Pod所在的Node宕机,则该Node上所有Pod会被调度到其他节点上。
为什么提出Pod的概念?
假设一个业务需要使用一组容器来跑,当其中一个或多个出现问题,如何定义业务整体是否完好?因此当引入Pod概念,只要其中一个容器出问题,则整个Pod内所有容器将会被重启。
Kubernetes为每个Pod的Pause容器都分配了唯一的IP地址(Pod IP)和一个存储券,Pod中所有业务容器共享Pause的网络和存储,解决了业务容器之间的通信问题及文件共享问题。【Pod IP+containerPort组成Pod的Endpoint,表示Pod的对外通信地址】
Labels
标签,key / value键值对(key和value均由用户指定),Lavel可以附加到各种资源对象上,比如Node、Pod、Service等,一个资源对象可以拥有任意数量的Label,可以通过Label来实现多维度的资源分组管理。
Namespace
用于逻辑隔离不同用户,通过Namespace可以限制不同用户可占用的资源,比如CPU、RAM等,便于不同的分组在共享使用整个Kubernetes集群资源的同时还能被分别管理。
Replication Controller(RC)
- 控制某Pod副本在任意时刻都符合期望值,若某个副本挂了,则Kubernetes根据RC的定义自动创建并启动一个新的Pod副本(少了新建,多了杀死)【就像一个监控】
- 滚动升级,通过RC可实现平滑的过度方式,每次停止N个进行升级,旧的N个仍然继续跑,此消彼长,直至全部升级成功,不会全员宕机,产生不可用时间差。
Deployment
ReplicaSet是Replication Controller的升级版,Deployments管理ReplicaSets(不应该手动管理由Desplyoment创建的Replica Set,而是使用Deployment替代管理),引入其是为了更好的解决Pod编排问题,可随时知道当前Pod部署进度。
- RC的标签选择器只能选择一个标签;ReplicaSet可以控制多个不同标签的Pod副本,支持滚动升级
Service
由于Pod会被动态的销毁或创建(虽然Pod意外死亡会被重建,但已经不是原来的Pod,只是内容上看起来一样),所以其Pod IP是在不断变化的,因此Pod集群需要一个固定的入口进行通信,即Service。
Kubernetes中每个Service就是一个”微服务“,Service定义了一个服务的访问入口,其他服务可通过这个入口地址访问其背后的一组Pod副本组成的集群,Service与Pod集群通过Label Selector(部署服务时的标签)实现”无缝对接“,而RC保证Service的服务能力始终处于预期标准。
主要提供负载均衡与服务自动发现
每个Service都被分配了一个全局的虚拟IP(Cluster IP),在Service的整个生命周期,Cluster IP都不会发生变化,因此具备唯一的IP通信能力(需要配合端口,单独的IP不具备TCP/IP通信基础)。但该IP因为是虚拟的,无法在集群外部ping通,只能在内部使用。
服务发现机制
在Kubernetes集群内部,Service使用Name和Cluster IP作为映射唯一标识,其他Pod访问该Service,使用Name即可在集群中自动匹配到对应的Service。最初Kubernetes将该配置写维护在Linux环境变量中,后来修改到DNS系统中。
kube-proxy
kube-proxy部署在每个Node节点上,是实现Service通信与负载均衡机制的重要组件,负责为Pod创建代理服务,维护网络规则和四层负载均衡工作。
在Kubernetes集群中,负载均衡是由kube-proxy实现的,是集群内部的负载均衡,也是一个分布式代理服务器,在每个节点上都存在,具备伸缩性,需要访问服务的节点越多,提供负载均衡能力的kube-proxy就越多,高可用节点也随之增多。
默认情况下,Kubernetes集群采用RoundRobin轮询模式对客户端请求进行负载分发;也可通过设置启用SessionAffinity策略,将同一个客户端IP的请求转发到固定的Pod。
外部系统访问Service
Cluster IP只能在集群内部使用,采用NodePort可开放外部通信(nodePort指定外部端口),此种方式在Kubernetes集群中每个Node上都开放一个对应的TCP监听端口,使用任意一个NodeIP+nodePort均可访问服务,但由于是NodeIP访问,失去了service的负载均衡能力。
因此需要在多个Node与客户端之间增加LB功能。
Service配置端口定义
- port:当在Kubernetes集群内部访问时,通过Cluster IP+port进行TCP/IP通信
- nodePort:外部系统访问Service的对外端口
- targetPort:Pod中具体业务容器的端口,比如启动了一个java进程,端口是8080,若该参数不写,默认与port相同。
Ingress
Service的表现形式为IP:Port,工作在四层,而对于HTTP请求来说,不同的URL地址经常对应不同的后盾服务,因此使用Ingress可以实现一个完整的负载均衡器。
Volume
是Pod中能被多个容器访问的共享目录。在Pod上声明Volume,并与容器的目录挂载即可。
- emptyDir:初始内容为空,无需指定挂载目录,作为临时空间使用,随同Pod一起存在消亡
- hostPath:在Pod上挂载宿主机的文件或目录
- 其他:使用网络文件系统或云存储等
ConfigMap
配置信息集合,使镜像和配置信息解耦,实现镜像的可移植性和可复用性
五、Pod调度
调度说明
Deployment或RC
全自动调度。自动部署一个容器应用的多份副本,并持续监控副本数量,在集群内始终维持用户指定副本数。
但这N个副本最终运行在哪个节点,是Master经过一系列算法得出的最优解,用户无法干预,即部署结果无法预期(主要依据内存和CPU使用率)。
NodeSelector
定向调度。指定Pod部署节点(Node的标签与Pod的nodeSelector匹配)
若定义的Node标签数量超过Pod副本数,则在这些Node中自动计算出最优解;若定义的Node标签与nodeSelector没有匹配结果,则不会进行Pod部署
DeamonSet
每个Node仅运行一份Pod副本。调度策略与RC类似,也可指定节点调度,但保证每个节点只运行一个Pod
Job
批处理调度。启动多个进程去处理一批工作项,处理完成后,整个任务结束
CronJob
定时任务。
自定义调度器
schedulerName
Affinity:亲和性调度
- NodeAffinity:Node亲和性
- PodAffinity:Pod亲和性
亲和性调度,是pod的一种属性(偏好或者硬性要求),使pod被吸引到一类特定的节点。用于替换NodeSelector的下一代调度策略。由于NodeSelector通过Node的Label进行精确匹配,所以Affinity增加了In、NotIn、Exists、DoesNotExist、Gt、Lt等操作符来选择,使调度策略更加灵活。
- In:label的值在某个列表中
- NotIn:label的值不在某个列表中
- Gt:label的值大于某个值
- Lt:label的值小于某个值
- Exists:某个label存在
- DoesNotExist:某个label不存在
调度策略
- RequiredDuringSchedulingRequiredDuringExecution:硬策略。不满足的就不去,严格按照条件执行;且当Node不满足条件时,同时移除该Node之前运行的Pod
- RequiredDuringSchedulingIgnoredDuringExecution:硬策略。作用同1;但当Node不满足条件时,该Node之前运行的Pod不一定被移除
- PreferredDuringSchedulingIngnoredDuringExecution:软策略。满足条件的Node中,更优先的调度(尽量保证);且当Node不满足条件时,该Node之前运行的Pod不一定被移除
Taint(污点)和 Toleration(容忍)
Taint与Affinity相反,使Node能够排斥一类特定的Pod;但如果将Toleration应用于Pod上,则这些Pod可以(但不一定)被调度到具有匹配Taint的Node上。Taint和Toleration相互配合,可以用来避免pd被分配到不合适的节点上。
taint effect
- NoSchedule:绝不会将Pod调度到具有该污点的Node上
- PreferNoSchedule:尽量避免把Pod调度到具有该污点的Node上
- NoExecute:绝不会将Pod调度到具有该污点的Node上,并且把Node上已经存在的Pod移除