本片文字性阐述较多,但可以给读者在脑海中建立起k8s的认知架构,然后后续在k8s上的深入认识后,再次回头看,可以进一步加强对k8s的更高层次的认识和学习。

K8s概述

1、简介

K8s是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

K8s一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着(用户无需关心怎么去做,K8s会自动去监控,然后去重启,新建,总之,让apache一直提供服务)。

在K8s中,所有的容器均在Pod中运行,一个Pod可以承载一个或者多个相关的容器,一个Pod也可以包含0个或者多个磁盘卷组(volumes),这些卷组将会以目录的形式提供给一个容器,或者被所有Pod中的容器共享,对于用户创建的每个Pod,系统会自动选择那个健康并且有足够容量的机器,然后创建类似容器的容器,当容器创建失败的时候,容器会被node agent自动的重启,这个node agent叫kubelet。

所有k8s中的资源,比如Pod,都通过一个叫URI的东西来区分,这个URI有一个UID,URI的重要组成部分是:
对象的类型(比如pod)
对象的名字
对象的命名空间
对于特殊的对象类型,在同一个命名空间内,所有的名字都是不同的,在对象只提供名称,不提供命名空间的情况下,这种情况是假定是默认的命名空间。UID是时间和空间上的唯一。

2、简要概述

Cluster:集群指由k8s使用一系列的物理机、虚拟机和其他基础资源运行你的应用程序;
Node:一个node就是运行着k8s的物理机或者虚拟机,并且pod可以在其上面被调度;
Pod:一个pod对应一个由容器和卷组成的容器组;
Lable:一个lable是一个被附件到资源上的键/值对,比如附到一个pod上,为它传递一个用户自定义的并且可识别的属性,Lable还可以被应用来组织和选择子网中的资源;
Selector:一个通过匹配lables来定义资源之间关系的表达式,比如为一个负载均衡的service指定目标pod;
Replication Controller:为了保证一定数量被指定的pod的复制品在任何时间都能正常工作,不仅允许复制你的系统易于扩展,还会处理当pod在机器重启或者发生故障的时候再次创建一个;
Service:一个service定义了访问pod的方式,就像单个固定ip地址与其相对应的DNS名之间的关系;
Volume:一个volume是一个目录,可能会被容器作为一部分来访问;k8s volume是建立在docker vlume之上,并且支持添加和配置volume目录或者其他存储设备;
Secret:存储了敏感数,比如能允许容器接收请求的权限令牌;
Name:用户为k8s中资源定义的名字;
Namespace:namespace好比资源名字的前缀,它帮助不同的项目、团队或是客户共享cluster,比如防止相互独立的团队之间出现命名冲突;
Annotation:相对于lable来说可以容量更大的键值对,他对我们来说可能是不可读的数据,只是为了存储不可识别的辅助数据,尤其是一些被工具或者系统扩展用来操作的数据。

k8s设计架构

K8s集群包含有节点代理kubelet和Master组件(APIs, scheduler, etcd),一切都基于分布式的存储系统

1、K8s的核心组件

Etcd:保存了整个集群的状态;
Apiserver:提供了操作资源作为唯一入口,并提供认证、授权、访问控制、API注册和发现机制;
Controller manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
Scheduler:负责资源的调度,按照预定的调度策略把pod调度到相应的机器上;
Kubelet:负责维护集群的生命周期,同时也负责volumes(CVI)和网络(CNI)的管理;
Container runtime:负责镜像管理以及pod和容器真正的运行(CRI);
kube-proxy:负责为service提供cluster内部的服务发现和负载均衡。

2、K8s的非核心组件

kube-dns负责为整个集群提供DNS服务;
Ingress Controller为服务提供外网入口;
Heapster提供资源监控;
Dashboard提供GUI;
Federation提供跨可用区的集群;
Fluentd-elasticsearch提供集群日志采集、存储与查询。

3、k8s的分层架构

Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示

k8s istio配置路由_Pod

核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等);
管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等);
接口层:kubectl命令行工具、客户端SDK以及集群联邦;
生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴;
Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等;
Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等。

4、概念细化

Kubelet:负责管理pods和它们上面的容器、images镜像、volumes、etc;
Kube-proxy:每个节点都运行一个简单的网络代理和负载均衡;
k8s的dashboard:面板可以分为多个部分,目前均运行在一个master上;
Etcd:所有master的持续状态都存在于etcd的一个实例中,用于存储配置数据;
K8s API-server:主要处理rest操作,在etcd中验证更新这些对象并最终存储;
Scheduler:调度器把未调度的pod通过binding ip api绑定到节点上;
K8s控制管理服务器:所有其他的集群级别的功能目前都是有控制管理器所负责。

k8s的核心技术概念

1、Pod

是集群中运行部署应用或者服务的最小单元;
Pod的设计理念是支持多个容器在一个pod中共享网络地址和文件系统,可以通过进程间的通信和文件共享这种简单高效的方式组合完成服务;
Pod是k8s集群中所有业务类型的基础,不通业务需要不通pod是执行。目前k8s中的业务主要分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-deamon)和有状态应用型(stateful application),分别对相应的pod控制器为Deployment、job、DeamonSet、PetSet。

2、复制控制器(Replication controller,RC)

RC是k8s集群中最早保证pod高可用的API对象;
通过监控运行中的pod来保证集群中运行指定数目的副本;当少于指定数目,RC就会启动运行新的pod副本;当对于指定数目,RC就会杀死多余的pod副本;
即使在指定数目为1的情况下,通过RC运行pod也比直接运行pod明智,因为RC也可以发挥它的高可用的能力,保证永远只有1个pod在运行。

3、副本集(Relplica Set,RS)

新一代的RC,提供同样的高可用能力,区别主要在于后来者居上,能支撑更多种类的匹配模式;副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用。

4、部署(Deployment)

表示用户对k8s集群的一次更新操作;
可以是创建一个新的服务,更新一个新的服务,滚动升级一个服务;
滚动升级一个服务,实际上是创建一个新的RS,然后追渐将新的RS中的副本数增加到理想状态,将旧RS中的副本数减小到0的复合操作;这样一个复合操作用RS不好描述,所以用deployment来描述。

5、服务(service)

在k8s集群中,客户端需要访问的服务就是service对象;
RC、RS和deployment只是保证了支撑服务的微服务的pod的数量,但没有解决如果访问服务的问题;
一个pod在一个节点上停止,会在另外一个节点上创建,因为不能以确定的ip和端口号提供服务;
要稳定的提供服务需要服务发现和负载均衡的能力,服务发现完成的工作是针对客户端访问的服务,找到对应的后端服务实例。而客户端访问的服务就是service对象,每个service会对应一个集群内部有效的虚拟ip,集群内部通过虚拟ip访问一个服务;k8s中的负责均衡事由kube-proxy实现的,kube-proxy是k8s集群内部的负载均衡器,一个分部式代理服务器,每个节点上都有,这一设计体现了它的伸缩优势,需要访问的节点越多,提供负载均衡能力的kube-proxy就越多,高可用节点也随之增加。与之相比,我们平时咋服务器端做个反向代理做负载均衡,还需要进一步解决反向代理的负载均衡和高可用问题。

6、任务(Job)

k8s用来控制批处理型任务的API对象;
批处理型业务和长期伺服型业务的主要区别试试批处理业务有头有尾,而长期伺服性业务是在用户不停止的情况下运行。
Jon管理的pod根据用户的设置把任务完成后就自动退出了。成功完成后根据不同的spe.completios策略而不同;单Pod型任务有一个Pod成功就标志完成;定数成功型任务保证有N个任务全部成功;工作队列型任务根据应用确认的全局成功而标志成功。

7、后台支撑服务集(DaemonSet)

长期伺服型和批处理型服务的核心在业务应用,可能有些节点运行多个同类业务的Pod,有些节点上又没有这类Pod运行;而后台支撑型服务的核心关注点在K8s集群中的节点(物理机或虚拟机),要保证每个节点上都有一个此类Pod运行。节点可能是所有集群节点也可能是通过nodeSelector选定的一些特定节点。典型的后台支撑型服务包括,存储,日志和监控等在每个节点上支持K8s集群运行的服务。

8、有状态服务集(PetSet)

K8s在1.3版本里发布了Alpha版的PetSet功能。在云原生应用的体系里,有下面两组近义词;第一组是无状态(stateless)、牲畜(cattle)、无名(nameless)、可丢弃(disposable);第二组是有状态(stateful)、宠物(pet)、有名(having name)、不可丢弃(non-disposable)。
RC和RS主要是控制提供无状态服务的,其所控制的Pod的名字是随机设置的,一个Pod出故障了就被丢弃掉,在另一个地方重启一个新的Pod,名字变了、名字和启动在哪儿都不重要,重要的只是Pod总数;PetSet是用来控制有状态服务,PetSet中的每个Pod的名字都是事先确定的,不能更改。PetSet中Pod的名字的作用,并不是《千与千寻》的人性原因,而是关联与该Pod对应的状态。
对于RC和RS中的Pod,一般不挂载存储或者挂载共享存储,保存的是所有Pod共享的状态,Pod像牲畜一样没有分别(这似乎也确实意味着失去了人性特征);对于PetSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来Pod的存储继续以它的状态提供服务。
适合于PetSet的业务包括数据库服务MySQL和PostgreSQL,集群化管理服务Zookeeper、etcd等有状态服务。
PetSet的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。传统的虚拟机正是一种有状态的宠物,运维人员需要不断地维护它,容器刚开始流行时,我们用容器来模拟虚拟机使用,所有状态都保存在容器里,而这已被证明是非常不安全、不可靠的。使用PetSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,PetSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性。PetSet还只在Alpha阶段,后面的设计如何演变,我们还要继续观察。

k8s网络

k8s有一个独特的网络模型,k8s给每一个pod分配ip地址,当你新建一个集群,为了保证pod获得ip,你需要给k8s分配一个ip地址池。最简单的办法就是每个节点与节点之间的通信可以以一下两种方法实现:
(1)配置网络完成pod的ip地址路由-----难度较大
(2)建立一个拓扑网络-----较容易
如Flannel,weave,Open vSwitch(OVS)
(3)一些可选择的配置方式
如GCE,AWS
(4)给每一个node的pod地址分配一个CIDR子网或者一个
你总共需要max-pods-per-node * max-number-of-pod个ip地址。一个“/24”如果缺少ip地址,一个“/26”(62个节点)或者“/27”(30个节点)也能满足
例如:使用“10.10.0.0/16”,“10.10.0.0/24”,“10.10.255.0/24”
需要路由设置或者连接到拓扑网络

K8s会为每个service分配一个ip地址,但是service的地址并不一定是可路由的。当数据离开节点时,kube-proxy需要将service ip地址翻译成pod ip地址。因此你需要给service也分配一个地址段。这个网段叫做“SERVICE_CLUSTER_IP_RANGE”。如:你可以设置“SERVICE_CLUSTER_IP_RANGE=10.0.0.0/16”,这样的话就会允许65534个不同的service同时运行。当然你可以调整这个ip地址段,但不可在service和pod运行的时候移除这个网段。
同样,你需要为主节点选一个静态ip地址,命名这个ip地址为“MASTER_IP”。配置防火墙,从而允许apiserver端口的80和443。使用sysctl设置“net.ipv4.ip_forward = 1”从而开启IPv4 forwarding。