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