目录
一、kubernetes简介
1、kubernetes的介绍与作用
2、为什么要用K8S?
二、kubernetes特性
1、自我修复
2、弹性伸缩
3、服务发现和负载均衡
4、自动发布(滚动发布/更新)和回滚
5、集中化配置管理和密钥管理
6、存储编排
7、任务批量处理运行
三、kubernetes集群架构与核心组件
1、master组件
1.1 kube-apiserver
1.2 kube-controller-manager(控制器管理中心)
1.3 kube-scheduler(调度器)
1.4 etcd(存储中心)
1.5 master节点工作流程
2、Node组件
2.1 Kubelet
2.2 kube-proxy
2.3 docker 或roket
总结:
3、kubernetes数据流向
四、Kubernetes核心概念
1、Pod(k8s基本单位)
2、Pod 控制器
3、Label(标签)
4、label选择器(label selector)
5、service(网关层)
6、Ingress
7、name(名称)
8、namespace(命令空间
官网:https://kubernetes.io
中文社区版:http://docs.kubernetes.org.cn/92.html
试想下传统的后端部署办法:把程序包(包括可执行二进制文件、配置文件等)放到服务器上,接着运行启动脚本把程序跑起来,同时启动守护脚本定期检查程序运行状态、必要的话重新拉起程序。
设想一下,如果服务的请求量上来,已部署的服务响应不过来怎么办?传统的做法往往是,如果请求量、内存、CPU超过阈值做了告警,运维人员马上再加几台服务器,部署好服务之后,接入负载均衡来分担已有服务的压力。
这样问题就出现了:从监控告警到部署服务,中间需要人力介入!那么,有没有办法自动完成服务的部署、更新、卸载和扩容、缩容呢?
而这就是 K8S 要做的事情:自动化运维管理容器化(Docker)程序。
K8S 的目标是让部署容器化应用简单高效。
K8S 解决了裸跑Docker 的若干痛点:
K8S是google开源的容器集群管理系统,在Docker等容器技术的基础上,为容器化的应用提供部署运行,资源调度,服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性,其主要功能如下:
使用Docker等容器技术对应用程序包装(package)、实例化(instantiate)、运行(run)
以集群的方式运行、管理跨机器的容器
解决Docker跨机器容器之间的通讯问题
K8S的自我修复机制使得容器集群总是运行在用户期望的状态。
K8S为多个pod提供一个统一访问入口(内部IP地址和一个DNS名称),并且负载均衡关联的所有容器,使用用户无需考虑容器IP问题。
服务发现: 服务可以通过自动发现的形式找到它所依赖的服务
负载均衡: 如果一个服务启动了多个容器,能够自动实现请求的负载均衡。
K8S是属于主从设备模型(master-slave架构),即有master节点负责集群的调度、管理和运维、salve节点时集群中的运算工作负载节点。
master:集群的控制平面,负责集群的决策(管理)
kubernetes API,集群的统一入口,各组件协调者,以Restful API提供接口服务,所有对象资源的增删改查和监听操作都交给 API server 处理后再提交给Etcd存储。
根据调度算法(预选/优选的策略)为新创建的pod选择一个node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上
k8s的存储服务,etcd是分布式键值对存储系统,存储了k8s的关键配置和用户配置,k8s中仅API server才具备读写权限,其它组件必须通过API server的接口才能读写数据。
API server 接收到请求创建一批Pod。API server 会让Controller-manager按照所预设的模板去创建Pod。Controller-manager会通过API server 去找Scherduler为新创建的Pod选择最适合的Node节点,比如运行这个Pod需要2C4G的资源,Schduler会通过预选策略在所有node节点中挑选最优的,node节点中还剩下多少资源是通过汇报给API Server 存储在etcd中,API server 会调用一个方法找到etcd里所有node节点的剩余资源,再对比新创建Pod所需要的资源,在所有node节点中查找哪些node节点符合要求,如果都符合,预算策略就交给优先策略处理,优先策略再通过CPU的负载、内存的剩余量等因素选择最适合的node节点,并把pod调度到这个node节点上运行。
Node节点的监视器,以及与master节点的通讯器 ,kubelet是master节点安插在node节点上的 “眼线” ,它会定时向APIserver 汇报自己node节点上运行的服务的状态,并处理来自master节点的请求。
从master节点获取自己节点上pod的期望状态(比如运行什么容器,运行的副本数量,网络或者存储如何配置等),直接跟容器引擎交互实现容器的生命周期管理,如果自己上pod的状态与期望状态不一致,则调用对应的容器平台接口(即docker的接口)达到这个状态,管理镜像和容器的清理工作,保证节点上镜像不会占满磁盘空间,退出的容器不会占用太多资源。
在每个node节点上实现pod网络代理,是kuberbetes service资源的载体,负责维护网络规划和四层负载均衡工作。 负责写入规则至iptables、ipvs实现服务映射访问的。
kube-proxy本身不是直接给pod提供网络,pod的网络是由kubelet提供的,kube-proxy实际上维护的是虚拟的pod集群网络。
kube-apiserver 通过监控kube-proxy 进行对kubernets service 的更新和端点的维护。
kube-proxy 是k8s集群内部的负载均衡器,它是一个分布式代理服务器,在k8s的每个节点上都会运行一个kube-proxy。
容器引擎,运行容器,负责本机的容器创建和管理工作。
#master
#worker node 节点
kubectl提交一条命令。
1、首先经过AUTH认证,然后将请求递交给API server进行处理(创建一个包含pod信息的yaml文件),然后将文件信息存储在etcd中。
2、controller-manager控制器会监听到API server,发现了创建Pod的请求后,会根据预设模板进行创建pod。(但是controller-manager无法完成调度,所以它会通过API server 向scheduler获取node节点的信息)//controller-manager的功能:控制、管理维护node节点。
3、此时API server 就会向etcd获取后端节点信息。
4、scheduler调度器也会监听API server,发现请求信息,然后进行预选调度和优选调度的调度计算,找出最闲且最符合条件的node节点。最后将结果信息给到API server。
//预选调度和优先调度
//1、预选调度: 一般根据资源对象的配置信息进行筛选,例如:nodeselector、hostselector、节点亲和性。
//2、优先调度: 根据资源对象需要的资源和node节点的资源的使用情况,为每个节点打分,然后选出最优的节点创建资源对象(pod)
5、此时controller-manage 也监听到 API server,选出了node节点,controller-manager会根据请求创建pod的配置信息。(也就是需要什么控制器),然后把控制资源给API server
------------下面开始与node节点交互------------------
6、此时API server会提交清单给对应的节点的kubelet(代理),kubelet相当于api server在node节点的监视器。
7、kubelet代理通过k8s与容器的接口(例如:containnerd)进行交互。假如是docker容器,那么此时kubelet就会通过dockershim以及runc接口与docker的守护进行docker-server进行交互,来创建对应的容器,再生成对应的pod。
8、kubelet同时会借助于 metric server收集本节点的所有状态信息,然后再提交给 API server。
9、最后 API server 会提交list清单给etcd存储。
------------------------------------------------------
10、最终用户可以通过kube-proxy实现访问不同节点的数据。(ipvs映射、iptables规则),kube-proxy为网络代理,四层负载均衡工作。
kubernetes包含多种类型的资源对象: pod、label、service、Replication、Contaroller等
Pod是Kubernetes创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程。
可以把Pod理解成豌豆荚,而同一个Pod内的每个容器是一颗豌豆。
一个Pod由一个或多个容器组成,Pod中容器共享网络,存储和计算资源,在同一台Docker主机上运行。
一个Pod里可以运行多个容器,又叫边车模式(sidecar),而在生产环境中一般都是单个容器或者具有强关联互补的多个容器组成一个Pod。
///边车模式
就是在一个pod里面可以运行多个容器。多个容器就是以边车模式存储在pod中。
//同一个Pod中,容器之间的端口不能冲突,不然会导致无限重启。
面试题:
# 相同节点不同Pod之间如何通信?
//不Pod之间不能通过localhost通信。它需要通过容器网络容器(比如docker0、bridge、host等)
# 不相同节点pod之间怎么通讯?
//借助于cni插件(container network interface:容器网络接口)通信。
//常用的接口有calico、flannel、cannel。
Pod 控制器是 Pod 启动的一种模版,用来保证在K8S里启动的 Pod 应始终按照用户的预期运行(副本数、生命周期、健康状态检查等)。
K8S 内提供了众多的 Pod 控制器,常用的有以下几种:
Statefulset: 有状态应用部署
Job : 一次性任务,根据用户的设置,Job管理的Pod把任务成功完成就自动退出了。
Cronjab: 周期性计划任务。
标签,是K8S特色的管理方式,便于分类管理资源对象。
Label可以附加到各种资源对象上,例如Node、Pod、Service、RC等,用于关联,查询和筛选。
一个Label是一个Key-value的键值对,其中key与value由用户自己指定。
一个资源对象可以定义任意数量的label,同一个label也可以被添加到任意数量的资源对象中,也可以在对象后动态添加或者删除,可以通过给指定的资源对象捆绑一个或多个不同的label,来实现多维度的资源分组管理功能。
与 Label 类似的,还有 Annotation(注释)。
区别在于有效的标签值必须为63个字符或更少,并且必须为空或以字母数字字符([a-z0-9A-Z])开头和结尾,中间可以包含横杠(-)、下划线(_)、点(.)和字母或数字。注释值则没有字符长度限制。
给某个资源对象定义一个label,就相当于给它打了一个标签。随后可以通过标签选择器(label selector)查询和筛选拥有某些label的资源对象。
标签选择器目前有两种: 基于等值关系(等于、不等于)和基于集合关系(属于、不属于、存在)
在K8S的集群里,虽然每个Pod会被分配一个单独的IP地址,但由于Pod是有生命周期的(它们可以被创建,而且销毁之后不会再启动),随时可能会因为业务的变更,导致这个 IP 地址也会随着 Pod 的销毁而消失。
service就是用来解决这个问题的核心概念。
//为啥ipvs推荐?
因为ipvs是效率高。它是直接通过ip转发。
iptables是经过策略进行转发,且在策略中,是一行一行执行,效率较低。
Service 是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了“微服务”。比如我们的一个服务A,部署了3个副本,也就是3个Pod;
对于用户来说,只需要关注一个Service 的入口就可以,而不需要操心究竞应该请求哪一个Pod。
优势非常明显 : 一方面外部用户不需要感知因为Pod上服务的意外崩溃、K8S重新拉起Pod 而造成的IP变更,外部用户也不需要感知因升级、变更服务带来的Pod替换而造成的IP变化。
总结:
service主要负责k8s集群内部的网络拓扑,那么集群外部怎么访问集群内部呢?
这个时候就需要ingress了,ingress是整个k8s集群的接入层,负责集群内外通讯。
Ingress是K8S集群里工作在OSI网络参考模型下,第七层的应用,对外暴露的接口,典型的访问方式是http/https
service只能进行第4层的流量调度,表现形式是ip+prot。ingress则可以调度不同的业务域,不同URL访问路径的业务流量。
比如:客户端请求http://www.ydq.com:prot ----->ingress ----->service----->pod
由于k8s内部,使用 “ 资源 ”来定义每一种逻辑概念(功能),所以每种“ 资源 ”,都应该有自己的“名称”。
“ 资源 ” : 有api版本(apiversion),类别(kind)、元素数据(metadata),定义清单(spec)、状态(status)等配置信息。
“名称 ” : 通常统一在“ 资源 ”的 “ 元数据 ”信息里,在同一个namespace空间中必须是唯一的。
随着项目增多,人员增加,集群规模的扩大,需要一种能够逻辑上隔离k8s内部“资源”的办法,这就是namespace。
namespace是为了把一个K8S集群划分为若干了资源不可共享的虚拟集群组而诞生的。
不同namespace内的“资源”名称可以相同,系相同的namespace内的同种“同种资源”,”名称“不能相同。
合理的使用k8s的namespace,可是的集群管理员能够更好的对交付到K8S里的服务进行分类管理和浏览。
K8S里默认存在namespace有:default、kube-system、kube-public等。
查询k8s里特定的“资源“ 要带上相应的namespace。
总结:k8s集群中需要namespace命令空间将资源进行隔离。当我们查找资源的时候,需要根据命令空间去查找。