一. Kubernetes 介绍
Kubernetes是一个全新的基于容器技术的分布式架构领先方案, 它是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S。K8S是Google内部一个叫Borg的容器集群管理系统衍生出来的,Borg已经在Google大规模生产运行十年之久。K8S主要用于自动化部署、扩展和管理容器应用,提供了资源调度、部署管理、服务发现、扩容缩容、监控等一整套功能。2015年7月,Kubernetes v1.0正式发布,截止到2017年9月29日最新稳定版本是v1.8。Kubernetes目标是让部署容器化应用简单高效。
Kubernetes最初源于谷歌内部的Borg,提供了面向应用的容器集群部署和管理系统。Kubernetes 的目标旨在消除编排物理/虚拟计算,网络和存储基础设施的负担,并使应用程序运营商和开发人员完全将重点放在以容器为中心的原语上进行自助运营。Kubernetes 也提供稳定、兼容的基础(平台),用于构建定制化的workflows 和更高级的自动化任务。
Kubernetes 具备完善的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建负载均衡器、故障发现和自我修复能力、服务滚动升级和在线扩容、可扩展的资源自动调度机制、多粒度的资源配额管理能力。Kubernetes 还提供完善的管理工具,涵盖开发、部署测试、运维监控等各个环节。
二. Kubernetes主要功能
Kubernetes是开源容器集群管理系统,是基于Docker构建一个容器的调度服务,提供资源调度、均衡容灾、服务注册、动态扩缩容等功能套件。Kubernetes提供应用部署、维护、 扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用,其主要功能如下:
数据卷: Pod中容器之间共享数据,可以使用数据卷。
应用程序健康检查: 容器内服务可能进程堵塞无法处理请求,可以设置监控检查策略保证应用健壮性。
复制应用程序实例: 控制器维护着Pod副本数量,保证一个Pod或一组同类的Pod数量始终可用。
弹性伸缩: 根据设定的指标(CPU利用率)自动缩放Pod副本数。
服务发现: 使用环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址。
负载均衡: 一组Pod副本分配一个私有的集群IP地址,负载均衡转发请求到后端容器。在集群内部其他Pod可通过这个ClusterIP访问应用。
滚动更新: 更新服务不中断,一次更新一个Pod,而不是同时删除整个服务。
服务编排: 通过文件描述部署服务,使得应用程序部署变得更高效。
资源监控: Node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDB时序数据库,再由Grafana展示。
提供认证和授权: 支持属性访问控制(ABAC)、角色访问控制(RBAC)认证授权策略。
除此之外, Kubernetes主要功能还体现在:
- 使用Docker对应用程序包装(package)、实例化(instantiate)、运行(run)。
- 将多台Docker主机抽象为一个资源,以集群的方式运行、管理跨机器的容器,包括任务调度、资源管理、弹性伸缩、滚动升级等功能。
- 使用编排系统(YAML File)快速构建容器集群,提供负载均衡,解决容器直接关联及通信问题
- 解决Docker跨机器容器之间的通讯问题。
- 自动管理和修复容器,简单说,比如创建一个集群,里面有十个容器,如果某个容器异常关闭,那么,会尝试重启或重新分配容器,始终保证会有十个容器在运行,反而杀死多余的。Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态. 当前Kubernetes支持GCE、vShpere、CoreOS、OpenShift。
三. Kubernetes架构和组件
Kubernetes架设图
kubernetes主要由以下几个核心组件组成:
etcd: 集群的主数据库,保存了整个集群的状态; etcd负责节点间的服务发现和配置共享。etcd分布式键值存储系统, 用于保持集群状态,比如Pod、Service等对象信息。
kube-apiserver: 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;这是kubernetes API,作为集群的统一入口,各组件协调者,以HTTPAPI提供接口服务,所有对象资源的增删改查和监听操作都交给APIServer处理后再提交给Etcd存储。
kube-controller-manager: 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;它用来执行整个系统中的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等, 一个资源对应一个控制器,而ControllerManager就是负责管理这些控制器的。
kube-scheduler: 资源调度,按照预定的调度策略将Pod调度到相应的机器上;它负责节点资源管理,接受来自kube-apiserver创建Pods任务,并分配到某个节点。它会根据调度算法为新创建的Pod选择一个Node节点。
kubectl: 客户端命令行工具,将接受的命令格式化后发送给kube-apiserver,作为整个系统的操作入口。
kubelet: 负责维护容器的生命周期,负责管理pods和它们上面的容器,images镜像、volumes、etc。同时也负责Volume(CVI)和网络(CNI)的管理;kubelet运行在每个计算节点上,作为agent,接受分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver; kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet将每个Pod转换成一组容器。
container runtime: 负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy: 负责为Service提供cluster内部的服务发现和负载均衡;它运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到service信息来做相应的策略。它在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作。
docker或rocket(rkt): 运行容器。
除了上面的几个核心组建, 还有一些常用插件(Add-ons):
kube-dns: 负责为整个集群提供DNS服务;
Ingress Controller: 为服务提供外网入口;
Heapster: 提供资源监控;
Dashboard: 提供GUI;
Federation: 提供跨可用区的集群;
Fluentd-elasticsearch: 提供集群日志采集、存储与查询;
其中:
master组件包括: kube-apiserver, kube-controller-manager, kube-scheduler;
Node组件包括: kubelet, kube-proxy, docker或rocket(rkt);
第三方服务:etcd
Kubernetes Master控制组件,调度管理整个系统(集群),包含如下组件:
Kubernetes API Server: 作为Kubernetes系统入口,其封装了核心对象的增删改查操作,以RESTful API接口方式提供给外部客户和内部组件调用,维护的REST对象持久化到Etcd中存储。
Kubernetes Scheduler: 为新建立的Pod进行节点(node)选择(即分配机器),负责集群的资源调度。组件抽离,可以方便替换成其他调度器。
Kubernetes Controller: 负责执行各种控制器,目前已经提供了很多控制器来保证Kubernetes的正常运行。
Replication Controller: 管理维护Replication Controller,关联Replication Controller和Pod,保证Replication Controller定义的副本数量与实际运行Pod数量一致。
Node Controller: 管理维护Node,定期检查Node的健康状态,标识出(失效|未失效)的Node节点。
Namespace Controller: 管理维护Namespace,定期清理无效的Namespace,包括Namesapce下的API对象,比如Pod、Service等。
Service Controller: 管理维护Service,提供负载以及服务代理。
EndPoints Controller: 管理维护Endpoints,关联Service和Pod,创建Endpoints为Service的后端,当Pod发生变化时,实时更新Endpoints。
Service Account Controller: 管理维护Service Account,为每个Namespace创建默认的Service Account,同时为Service Account创建Service Account Secret。
Persistent Volume Controller: 管理维护Persistent Volume和Persistent Volume Claim,为新的Persistent Volume Claim分配Persistent Volume进行绑定,为释放的Persistent Volume执行清理回收。
Daemon Set Controller: 管理维护Daemon Set,负责创建Daemon Pod,保证指定的Node上正常的运行Daemon Pod。
Deployment Controller: 管理维护Deployment,关联Deployment和Replication Controller,保证运行指定数量的Pod。当Deployment更新时,控制实现Replication Controller和 Pod的更新。
Job Controller: 管理维护Job,为Jod创建一次性任务Pod,保证完成Job指定完成的任务数目
Pod Autoscaler Controller: 实现Pod的自动伸缩,定时获取监控数据,进行策略匹配,当满足条件时执行Pod的伸缩动作。
Kubernetes Node运行节点,运行管理业务容器,包含如下组件:
Kubelet: 负责管控容器,Kubelet会从Kubernetes API Server接收Pod的创建请求,启动和停止容器,监控容器运行状态并汇报给Kubernetes API Server。
Kubernetes Proxy: 负责为Pod创建代理服务,Kubernetes Proxy会从Kubernetes API Server获取所有的Service信息,并根据Service的信息创建代理服务,实现Service到Pod的请求路由和转发,从而实现Kubernetes层级的虚拟转发网络。
Docker: Node上需要运行容器服务
Kubernetes的分层设计理念
Kubernetes设计理念和功能类似Linux的分层架构,如下图:
核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境;
应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等);
管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等);
接口层:kubectl命令行工具、客户端SDK以及集群联邦;
生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴:
- Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等;
- Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等;
Kubelet流程图:
根据上图可知Kubelet是Kubernetes集群中每个Minion和Master API Server的连接点,Kubelet运行在每个Minion上,是Master API Server和Minion之间的桥梁,
接收Master API Server分配给它的commands和work,与持久性键值存储etcd、file、server和http进行交互,读取配置信息。Kubelet的主要工作是管理Pod和容
器的生命周期,其包括Docker Client、Root Directory、Pod Workers、Etcd Client、Cadvisor Client以及Health Checker组件,具体工作如下:
- 通过Worker给Pod异步运行特定的Action;
- 设置容器的环境变量;
- 给容器绑定Volume;
- 给容器绑定Port;
- 根据指定的Pod运行一个单一容器;
- 杀死容器;
- 给指定的Pod创建network 容器;
- 删除Pod的所有容器;
- 同步Pod的状态;
- 从Cadvisor获取container info、 pod info、root info、machine info;
- 检测Pod的容器健康状态信息;
- 在容器中运行命令;
四. Kubernetes基本对象概念
Kubernetes中的大部分概念Node、Pod、Replication Controller、Service等都可以看作一种“资源对象”,几乎所有的资源对象都可以通过kubectl工具(API调用)执行增、删、改、查等操作并将其保存在etcd中持久化存储。从这个角度来看,kubernetes其实是一个高度自动化的资源控制系统,通过跟踪对比etcd库里保存的“资源期望状态”与当前环境中的“实际资源状态”的差异来实现自动控制和自动纠错的高级功能。
基本对象:
Pod: Pod是最小部署单元,一个Pod有一个或多个容器组成,Pod中容器共享存储和网络,在同一台Docker主机上运行; Pod 中的容器会作为一个整体被Master调度到一个Node上运行。
Service : Service一个应用服务抽象,定义了Pod逻辑集合和访问这个Pod集合的策略。Service代理Pod集合对外表现是为一个访问入口,分配一个集群IP地址,来自这个IP的请求将负载均衡转发后端Pod中的容器。Service通过LableSelector选择一组Pod提供服务。
Volume: 数据卷,共享Pod中容器使用的数据。
Namespace: 命名空间将对象逻辑上分配到不同Namespace,可以是不同的项目、用户等区分管理,并设定控制策略,从而实现多租户。命名空间也称为虚拟集群。
Lable: 标签用于区分对象(比如Pod、Service),键/值对存在;每个对象可以有多个标签,通过标签关联对象。
基于基本对象更高层次抽象:
ReplicaSet: 下一代ReplicationController。确保任何给定时间指定的Pod副本数量,并提供声明式更新等功能。RC与RS唯一区别就是lableselector支持不同,RS支持新的基于集合的标签,RC仅支持基于等式的标签。
Deployment: Deployment是一个更高层次的API对象,它管理ReplicaSets和Pod,并提供声明式更新等功能。官方建议使用Deployment管理ReplicaSets,而不是直接使用ReplicaSets,这就意味着可能永远不需要直接操作ReplicaSet对象。
StatefulSet: StatefulSet适合持久性的应用程序,有唯一的网络标识符(IP),持久存储,有序的部署、扩展、删除和滚动更新。
DaemonSet: DaemonSet确保所有(或一些)节点运行同一个Pod。当节点加入Kubernetes集群中,Pod会被调度到该节点上运行,当节点从集群中移除时,DaemonSet的Pod会被删除。删除DaemonSet会清理它所有创建的Pod。
Job: 一次性任务,运行完成后Pod销毁,不再重新启动新容器。还可以任务定时运行。Kubernetes中的Job 用于运行结束就删除的应用。
kubernetes概念说明
API对象是K8s集群中的管理操作单元。K8s集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作。例如副本集Replica Set对应的API对象是RS。
Kubernetes中所有的配置都是通过API对象的spec去设置的,也就是用户通过配置系统的理想状态来改变系统,这是k8s重要设计理念之一,即所有的操作都是声明式 (Declarative) 的而不是命令式(Imperative)的。声明式操作在分布式系统中好处是稳定,不怕丢操作或运行多次,例如设置副本数为3的操作运行多次也还是一个结果, 而给副本数加1的操作就不是声明式的, 运行多次结果就错了。
Cluster
Cluster 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用
Master
kubernetes集群的管理节点,负责管理集群,提供集群的资源数据访问入口。拥有Etcd存储服务(可选),运行Api Server进程,Controller Manager服务进程及Scheduler服务进程,关联工作节点Node。Kubernetes API server提供HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口。也是集群控制的入口进程;Kubernetes Controller Manager是Kubernetes所有资源对象的自动化控制中心;Kubernetes Schedule是负责资源调度(Pod调度)的进程.
Node
Node是Kubernetes集群架构中运行Pod的服务节点(亦叫agent或minion)。Node是Kubernetes集群操作的单元,用来承载被分配Pod的运行,是Pod运行的宿主机。关联Master管理节点,拥有名称和IP、系统资源信息。运行docker eninge服务,守护进程kunelet及负载均衡器kube-proxy. 每个Node节点都运行着以下一组关键进程:
- kubelet:负责对Pod对于的容器的创建、启停等任务
- kube-proxy:实现Kubernetes Service的通信与负载均衡机制的重要组件
- Docker Engine(Docker):Docker引擎,负责本机容器的创建和管理工作
Node节点可以在运行期间动态增加到Kubernetes集群中,默认情况下,kubelet会想master注册自己,这也是Kubernetes推荐的Node管理方式,kubelet进程会定时向Master汇报自身情报,如操作系统、Docker版本、CPU和内存,以及有哪些Pod在运行等等,这样Master可以获知每个Node节点的资源使用情况,冰实现高效均衡的资源调度策略。、
Pod
运行于Node节点上,若干相关容器的组合。Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行通。Pod是Kurbernetes进行创建、调度和管理的最小单位,它提供了比容器更高层次的抽象,使得部署和管理更加灵活。一个Pod可以包含一个容器或者多个相关容器。
Pod其实有两种类型:普通Pod和静态Pod,后者比较特殊,它并不存在Kubernetes的etcd存储中,而是存放在某个具体的Node上的一个具体文件中,并且只在此Node上启动。普通Pod一旦被创建,就会被放入etcd存储中,随后会被Kubernetes Master调度到摸个具体的Node上进行绑定,随后该Pod被对应的Node上的kubelet进程实例化成一组相关的Docker容器并启动起来。在默认情况下,当Pod里的某个容器停止时,Kubernetes会自动检测到这个问起并且重启这个Pod(重启Pod里的所有容器),如果Pod所在的Node宕机,则会将这个Node上的所有Pod重新调度到其他节点上。
Pod是在K8s集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务.比如你运行一个操作系统发行版的软件仓库,一个Nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务.
Kubernetes 引入 Pod 主要基于下面两个目的:
- 可管理性
有些容器天生就是需要紧密联系, 一起工作。Pod 提供了比容器更高层次的抽象,将它们封装到一个部署单元中。Kubernetes 以 Pod 为最小单位进行调度、扩展、共享资源、管理生命周期。
- 通信和资源共享
Pod 中的所有容器使用同一个网络 namespace,即相同的 IP 地址和 Port 空间。它们可以直接用 localhost 通信。同样的,这些容器可以共享存储,当 Kubernetes 挂载 volume 到 Pod,本质上是将 volume 挂载到 Pod 中的每一个容器。
File Puller 会定期从外部的 Content Manager 中拉取最新的文件,将其存放在共享的 volume 中。Web Server 从 volume 读取文件,响应 Consumer 的请求。这两个容器是紧密协作的,它们一起为 Consumer 提供最新的数据;同时它们也通过 volume 共享数据。所以放到一个 Pod 是合适的。
Controller
Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。为了满足不同的业务场景, Kubernetes 提供了多种 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等.
Replication Controller (副本集RC)
Replication Controller用来管理Pod的副本,保证集群中存在指定数量的Pod副本。集群中副本的数量大于指定数量,则会停止指定数量之外的多余容器数量,反之,则会启动少于指定数量个数的容器,保证数量不变。Replication Controller是实现弹性伸缩、动态扩容和滚动升级的核心。
通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本 (这是k8s早期技术概念)
Replica Set (副本集RS)
RS是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用. Replica Set 实现了 Pod 的多副本管理。使用 Deployment 时会自动创建 ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod 的多个副本,我们通常不需要直接使用 ReplicaSet。
Deployment (部署)
Deployment 是最常用的 Controller,Deployment 可以管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。Deployment是一个比RS应用模式更广的API对象,支持动态扩展。可以创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。滚动升级一个服务,实际是创建一个新的RS,然后逐渐将新RS中副本数增加到理想状态,将旧RS中的副本数减小到0的复合操作 (逐步升级新得副本,剔除旧的副本).
总结:RC、RS和Deployment只是保证了支撑服务的微服务Pod的数量.
DaemonSet
DaemonSet 用于每个 Node 最多只运行一个 Pod 副本的场景。正如其名称所揭示的,DaemonSet 通常用于运行 daemon。
StatefuleSet
StatefuleSet 能够保证 Pod 的每个副本在整个生命周期中名称是不变的。而其他 Controller 不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。
Service
Service定义了Pod逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了统一的服务访问入口以及服务代理和发现机制,关联多个相同Label的Pod,用户不需要了解后台Pod是如何运行。
外部系统访问Service的问题:
-> 首先需要弄明白Kubernetes的三种IP这个问题
- Node IP:Node节点的IP地址
- Pod IP: Pod的IP地址
- Cluster IP:Service的IP地址
-> 首先,Node IP是Kubernetes集群中节点的物理网卡IP地址,所有属于这个网络的服务器之间都能通过这个网络直接通信。这也表明Kubernetes集群之外的节点访问Kubernetes集群之内的某个节点或者TCP/IP服务的时候,必须通过Node IP进行通信
-> 其次,Pod IP是每个Pod的IP地址,他是Docker Engine根据docker0网桥的IP地址段进行分配的,通常是一个虚拟的二层网络。
最后Cluster IP是一个虚拟的IP,但更像是一个伪造的IP网络,原因有以下几点:
-> Cluster IP仅仅作用于Kubernetes Service这个对象,并由Kubernetes管理和分配P地址
-> Cluster IP无法被ping,他没有一个“实体网络对象”来响应
-> Cluster IP只能结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备通信的基础,并且他们属于Kubernetes集群这样一个封闭的空间。
-> Kubernetes集群之内,Node IP网、Pod IP网于Cluster IP网之间的通信,采用的是Kubernetes自己设计的一种编程方式的特殊路由规则。
RC、RS和Deployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。在K8s集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。在K8s集群中微服务的负载均衡是由Kube-proxy实现的。Kube-proxy是K8s集群内部的负载均衡器。它是一个分布式代理服务器,在K8s的每个节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的Kube-proxy就越多,高可用节点也随之增多。与之相比,我们平时在服务器端做个反向代理做负载均衡,还要进一步解决反向代理的负载均衡和高可用问题。
Kubernetes 运行容器(Pod)与访问容器(Pod)这两项任务分别由 Controller 和 Service 执行。
Namespace
名字空间为K8s集群提供虚拟的隔离作用,K8s集群初始有两个名字空间,分别是默认名字空间default和系统名字空间kube-system,除此以外,管理员可以可以创建新的名字空间满足需要。
Label
Kubernetes中任意API对象都是通过Label进行标识,Label的实质是一系列的Key/Value键值对,其中key于value由用户自己指定。Label可以附加在各种资源对象上,如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去。Label是Replication Controller和Service运行的基础,二者通过Label来进行关联Node上运行的Pod。
我们可以通过给指定的资源对象捆绑一个或者多个不同的Label来实现多维度的资源分组管理功能,以便于灵活、方便的进行资源分配、调度、配置等管理工作。
一些常用的Label如下:
版本标签:"release":"stable","release":"canary"......
环境标签:"environment":"dev","environment":"qa","environment":"production"
架构标签:"tier":"frontend","tier":"backend","tier":"middleware"
分区标签:"partition":"customerA","partition":"customerB"
质量管控标签:"track":"daily","track":"weekly"
Label相当于我们熟悉的标签,给某个资源对象定义一个Label就相当于给它大了一个标签,随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制。
Label Selector在Kubernetes中重要使用场景如下:
-> kube-Controller进程通过资源对象RC上定义Label Selector来筛选要监控的Pod副本的数量,从而实现副本数量始终符合预期设定的全自动控制流程;
-> kube-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立起每个Service岛对应Pod的请求转发路由表,从而实现Service的智能负载均衡;
-> 通过对某些Node定义特定的Label,并且在Pod定义文件中使用Nodeselector这种标签调度策略,kuber-scheduler进程可以实现Pod”定向调度“的特性;
======================================================================================
重要概念小结 (细节):
Master:集群控制管理节点,所有的命令都经由master处理。
Node:是kubernetes集群的工作负载节点。Master为其分配工作,当某个Node宕机时,Master会将其工作负载自动转移到其他节点。
Node节点可动态增加到kubernetes集群中,前提是这个节点已经正确安装、配置和启动了上述的关键进程,默认情况下,kubelet会向Master注册自己,这也kubernetes推荐的Node管理方式。一旦Node被纳入集群管理范围,kubelet会定时向Master汇报自身的情况,以及之前有哪些Pod在运行等,这样Master可以获知每个Node的资源使用情况,并实现高效均衡的资源调度策略。如果Node没有按时上报信息,则会被Master判断为失联,Node状态会被标记为Not Ready,随后Master会触发工作负载转移流程。
Pod:是kubernetes最重要也是最基本的概念。每个Pod都会包含一个 “根容器”,还会包含一个或者多个紧密相连的业务容器。
Kubernetes为每个Pod都分配了唯一IP地址, 称之为PodIP, 一个Pod里多个容器共享PodIP地址. 要求底层网络支持集群内任意两个Pod之间的直接通信,通常采用虚拟二层网络技术来实现 (Flannel).
Label:是一个key=value的键值对,其中key与value由用户指定, 可以附加到各种资源对象上, 一个资源对象可以定义任意数量的Label。可以通过LabelSelector(标签选择器)查询和筛选资源对象。
RC:Replication Controller声明某个Pod的副本数在任意时刻都符合某个预期值。定义包含如下:
- Pod期待的副本数(replicas);
- 用于筛选目标Pod的Label Selector;
- 当Pod副本数小于期望时,用于新的创建Pod的模板template;
需要注意
- 通过改变RC里的Pod副本数量,可以实现Pod的扩容或缩容功能;
- 通过改变RC里Pod模板中的镜像版本,可以实现Pod的滚动升级功能;
Service:“微服务”,kubernetes中的核心。通过分析、识别并建模系统中的所有服务为微服务,最终系统有多个提供不同业务能力而又彼此独立的微服务单元所组成,服务之间通过TCP/IP进行通信。每个Pod都会被分配一个单独的IP地址,而且每个Pod都提供了一个独立的Endpoint以被客户端访问。
客户端如何访问?
部署负载均衡器,为Pod开启对外服务端口,将Pod的Endpoint列表加入转发列表中,客户端通过负载均衡器的对外IP+Port来访问此服务。每个Service都有一个全局唯一的虚拟ClusterIP,这样每个服务就变成了具备唯一IP地址的“通信节点”,服务调用就变成了最基础的TCP网络通信问题。
Volume:是Pod中能够被多个容器访问的共享目录。定义在Pod之上,被一个Pod里的多个容器挂载到具体的文件目录之下;Volume与Pod生命周期相同。Volume可以让一个Pod里的多个容器共享文件、让容器的数据写到宿主机的磁盘上或者写文件到 网络存储中,具体如下图所示:
在kubernetes1.2的时候,RC就由Replication Controller升级成Replica Set,“下一代RC”。命令兼容适用,Replica Set主要被Deployment这个更高层的资源对象所使用,从而形成一套Pod创建、删除、更新的编排机制。当我们使用Deployment时,无需关心它是如何创建和维护ReplicaSet的,这一切是自动发生的。
Docker: 既然k8s是基于容器的,那么就不得不提到docker。2013年初,docker横空出世,孕育着新思想的“容器”,Docker选择容器作为核心和基础,以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员设计,用于构建、发布和运行分布式应用的平台。是一个跨平台、可移植并且简单易用的容器解决方案。通过操作系统内核技术(namespaces、cgroups等)为容器提供资源隔离与安全保障。
上图是一个image的简单使用。我们可以通过一个dockerfile来build自己的image。可以把image上传(push)到自己的私有镜像仓库,也可以从私有仓库pull到本地进行使用。可以单独使用命令行,直接run container,可以对container进行stop、start、restart操作。也可以对image进行save保存操作以及加载load操作,大家具体可以根据自己的使用,选择不同的操作即可。
Docker资源隔离技术
Docker选择容器作为核心和基础,以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理员设计,用于构建、发布和运行分布式应用的平台。Docker是一个跨平台、可移植并且简单易用的容器解决方案, 通过操作系统内核技术(namespaces、cgroups等)为容器提供资源隔离与安全保障。
Docker监控
cAdvisor(Container Advisor)是Google开发的用于分析运行中容器的资源占用和性能指标的开源工具。cAdvisor是一个运行时的守护进程,负责收集、聚合、处理和输出运行中容器的信息。对于每个容器,cAdvisor都有资源隔离参数、资源使用历史情况以及完整的历史资源使用和网络统计信息的柱状图。cAdvisor不但可以为用户提供监控服务,还可以结合其他应用为用户提供良好的服务移植和定制。包括结合InfluxDB对数据进行存储,以及结合Grafana提供web控制台,自定义查询指标,并进行展示:
etcd: etcd是一个键值存储仓库,用于配置共享和服务发现。etcd受Zookeeper与doozer启发而催生的项目。
etcd架构:
etcd存储
etcd的存储分为内部存储和持久化(硬盘)存储两部分。内存中的存储除了顺序化地记录所有用户对节点数据变更的记录外,还会对用户数据进行索引、建堆等方便查询的操作。而持久化则使用WAL进行记录存储。在k8s中,所有数据的存储以及操作记录都在etcd中进行存储,所以对于k8s集群来说,etcd是相当重要的,一旦故障,可能导致整个集群的瘫痪或者数据丢失。
在WAL体系中,所有的数据在提交之前都会进行日志记录。持久化存储的目录分为两个:snap和wal。snapshot相当于数据压缩,默认会将10000条wal操作记录merge成snapshot,节省存储,又保证数据不会丢失。其中:
- WAL:存储所有事务的变化记录
- Snapshot:用于存放某一时刻etcd所有目录的数据
etcd核心算法
etcd的核心算法是raft算法,强一致性算法。具体如下图所示:
需要注意:由于etcd是负责存储,所以不建议搭建单点集群,如zookeeper一样,由于存在选举策略,所以一般推荐奇数个集群,如3,5,7。只要集群半数以上的结点存活,那么集群就可以正常运行,否则集群可能无法正常使用。
五. Kubernetes 集群环境部署记录
Kubernetes (K8s)是docker容器用来编排和管理的工具.
通过kubectl向k8s Master发出指令, kubernetes Master主要是提供API Server、Scheduler、Controller组件,接收kubectl的命令,从Node节点获取Node的资源信息,并发出调度任务。Node节点提供kubelet、kube-proxy,每个node节点都安装docker,是实际的执行者。kubernetes不负责网络,所以一般是用flannel或者weave。etcd负责服务发现和node信息存储.
kubernetes基本部署步骤
- node节点安装docker
- node节点配置跨主机容器通信
- master节点部署etcd、kube-apiserver、kube-controller-manager和kube-scheduler组件
- node节点部署kubelet、kube-proxy组件
如果minion主机没有安装docker,启动kubelet时会报如下错误:
Could not load kubeconfig file /var/lib/kubelet/kubeconfig: stat /var/lib/kubelet/kubeconfig: no such file or directory. Trying auth path instead.
Could not load kubernetes auth path /var/lib/kubelet/kubernetes_auth: stat /var/lib/kubelet/kubernetes_auth: no such file or directory. Continuing with defaults.
No cloud provider specified.