其实docker之前有自己的一套编排软件:docker swarm
它可以在多台主机中创建一个docker集群,但是也仅限于此了,docker在很早就放弃了这个项目。
docker machine 是配合swarm的一个预处理工具
还有一个mesos 是一个分布式资源管理框架,可以统一调度多台主机组成的集群,推特之前用的这个,然后转头就去投了k8s
marathon是mesos的容器编排框架,用来调度运行一些常驻服务
k8s全称:kubernetes,因为中间有8个字母,所以简称k8s。lol
是谷歌公司开发的一款容器编排工具,占据了80%以上的市场份额。
上面的东西都是为了微服务而诞生的
微服务:把一个应用拆解成一个个微小的服务,每个服务只干一件事。
用于自动部署,扩展和管理“容器化应用程序”的开源系统
就是可以自动化运维管理docker等多个容器化程序的集群,并且它的生态极其丰富,本质上是一个容器编排工具。
官网:http://kubernetes.io
Github:https://github.com/kubernetes/kubernetes
传统的后端部署办法是:
把程序包放进服务器
运行启动脚本,同时启动守护脚本。
对齐检查程序状态,有必要的话重新拉起程序
如果服务请求量增大了,服务器响应不过来,传统运维就是增加服务器,部署负载均衡。那有没有办法自动完成服务的部署呢?k8s就解决了这一点。
K8S的目标是让部署容器化应用简单高效。
K8s解决了裸跑 Docker 的若干痛点:
K8S提供了容器编排,资源调度,弹性伸缩,部署管理,服务发现等一系列功能。
弹性伸缩:
使用命令,UI或者基于CPU使用情况自动快速扩容和缩容应用程序实例,保证应用业务高可用,业务低峰期时回收资源,用最小成本运行服务。
自我修复:
在节点故障时重新启动失败的容器,替换和重新部署,保证预期的副本数量。杀死健康检查失败的容器,并且在未准备好前不会处理客户端请求。
服务发现和负载均衡:
k8s为多个容器提供一个统一访问的入口(内部IP地址和一个DNS名),并且负载均衡所有相关容器,使得用户无需考虑容器ip问题。
自动发布和回滚:
k8s采用滚动更新策略更新应用,一次更新一个Pod,不是同时删除所有Pod。如果更新时出现错误,可以回滚,确保升级不影响业务。
集中化配置管理和密钥管理:
管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性,并可以将一些常用的配置存储在k8s中,方便应用程序使用。
存储编排:
支持外挂存储,并对外挂存储资源进行编排
挂载外部存储系统,无论本地还是公有云,还是网络存储,都作为集群资源的一部分使用,极大提高了存储使用灵活性
任务批处理运行:
提供一次性任务,定时任务,满足批量处理数据和分析的场景。
k8s是属于主从设备模型(master-slave架构),在k8s中,主节点被称为Matser节点,从节点被称为Worker node节点,每个node节点会被master分配一些工作负载。
master节点可以在群集中的任何计算机上运行,但是建议Master节点占据一个独立的服务器,因为Master是整个集群的大脑,如果master所在节点宕机时,那么整个集群控制命令就会失效,除了master,其余节点都是worker node节点,当某个node宕机时,其上的工作负载会被master自动转移到其他节点上去。
(1)master组件
可以理解成apiserver是k8s的请求入口服务。api server负责接收k8s所有请求,然后根据用户的具体请求,去通知其他组件干活。可以说apiserver是k8s集群架构的大脑
由一系列控制器组成,通过apiserver监控整个集群的状态,确保处于预期的工作状态。
控制器主要包括:
Node Controller(节点控制器):负责在节点出现故障时发现和响应。
Replication Controller(副本控制器):负责保证集群中一个RC(资源对象)所关联的Pod副本数始终保持预设值。可以理解成确保集群中有固定的POD实例,数量由RC定义。
Endpoints Controller(端点控制器):填充端点对象(即连接services和pods),负责监听service和对应的pod副本的变化。也就是说,如果我要访问一个服务,我就需要知道这个服务的endpoint。
Service Account & Token Controllers(服务账户和令牌控制器):为新的命名 空间创建默认账户和API令牌
ResourceQuota Controller(资源配额控制器):确保指定的资源会在任何时候都不会超量占用系统物理资源。
Namespace Controller(命名空间控制器):管理namespace的生命周期
Service Controller(服务控制器):属于K8s集群和外部云平台之间的一个接口控制器
这个就是一个给所有k8s的node节点的调度器。用户要部署服务的时候,它会根据调度算法选择最合适的node节点来部署pod。
API Server接收到请求创建一批pod,API Server会让Controller-manager 按照所预设的模板去创建Pod。Controller-manager会通过API Server去找Scheduler为新创建的pod选择的最适合的node节点。node节点中还剩多少资源是通过汇报给API Server 存储在etcd里,用API Server会调用一个方法找到etcd里所有node节点的剩余资源,再对比pod所需要的资源,在所有node节点中查找哪些node节点符合要求。
如果都符合,预算策略就交给优选策略处理,优选策略再通过cpu的负载,内存的剩余量等因素选择最合适的node节点,并把Pod调度到这个node节点上运行。
(2)上面的Etcd是啥?
etcd是k8s的存储服务,etcd是分布式键值存储系统,存储了k8s的关键配置和用户配置,k8s中仅api server才具备读写权限,其他组件必须通过api server的接口才能读写数据。
(3)node的组件
从master节点获取自己节点上Pod的期望状态(比如运行什么容器、运行的副本数量、网络或者存储如何配置等)
直接和容器引擎交互,实现容器的生命周期管理。
管理镜像和容器的清理工作,保证节点上镜像不会占满磁盘空间,退出的容器不会占用太多资源。
它本身不是直接给pod提供网络的,pod的网络是由kubelet提供,而proxy实际是维护虚拟的pod集群网络。
kube-apiserver 通过监控Kube-proxy实现对kubernetes service的更新和端点的维护。
在k8s集群中微服务的负载均衡是由proxy实现的,是一个分布式代理服务器,在k8s的每个节点上都会进行一个kube-proxy组件。。
资源类型对象:Pod、Label、Service、Replication Controller等。
所有的资源对象都可以通过k8s提供的kubectl工具进行增删改查,并保存在etcd中。
k8s就是一个高度自动化的资源控制系统,通过跟踪对比eicd存储里保存的资源期望状态与当前环境的实际状态的差异,来实现自动控制和自动纠错。
一个 Pod 由一个或多个容器组成,Pod 中容器共享网络、存储和计算资源,在同一台 Docker 主机上运行。
一个 Pod 里可以运行多个容器,又叫做边车模式(SideCare)模式,而在生产环境中一般使用单个容器或者具有强关联互补的多个容器组成一个Pod。
同一个 Pod 之间和容器可以通过 localhost 互相访问,并且可以挂载 Pod 内所有的数据卷;但是不同 Pod 之间的容器不能用 localhost 访问,也不能挂载其他 Pod 的数据卷。
K8S 内提供了众多的 Pod 控制器,常用的有以下几种:
① Deployment:无状态应用部署。Deployment 的作用是管理和控制 Pod 和 ReplicaSet,管控它们运行在用户期望的状态中。
② Replicaset:确保预期的 Pod 副本数量。ReplicaSet 的作用就是管理和控制 Pod,管控它们好好干活。但是,ReplicaSet 受控于 Deployment。
可以理解为 Deployment 就是总包工头,主要负责监督底下的工人 Pod 干活,确保每时每刻都有用户要求数量的 Pod 在工作,如果一旦发现了某个工人 Pod 不行了,就赶紧新拉一个 Pod 过来替换它。而ReplicaSet就是包工头手底下的小包工头。
从 K8S 使用者角度来看,用户只需要关系Deployment 而不操心 ReplicaSet 的前身,官方推荐用 Deployment 取代 Replication Controller 来部署服务。
③ Daemonset:确保所有节点运行同一类Pod,保证每个节点上都有一个此类的 Pod 运行,通常用于实现系统级后台任务。
④ Statefulset:有状态应用部署。
⑤ Job:一次性任务。根据用户的设置,Job 管理的Pod 把任务成功完成就自动退出了。
⑥ Cronjob:周期性计划任务。
Label 可以附加到各种资源对象上,例如:Node、Pod、Service、RC 等,用于关联对象、查询和筛选。
一个 Label 是一个 key-value 的键值对,其中 key 与 value 由用户自己指定。
一个资源对象可以定义任意数量的Label,同一个 Label 也可以被添加倒任意数量的资源对象中,也可以在对象创建后动态添加或者删除。
可以通过给指定的资源对象捆绑一个或多个不同的 Label,来实现多维度的资源分组管理功能。
与 Label 类似的,还有 Annotation (注释)。
区别在于有效的标签值必须为63个字符或更少,并且必须为空或字母数字([a-z0-9A-Z])开头和结尾,中间可以包含横杠(-)、下划线()、点(.)和字母或者数字。注释值则没有字符长度限制。
-label选择器
给某个资源对象定义一个 Label,就相当于给它打了一个标签,随后可以通过标签选择器(Label selector)查询和筛选拥有某些 Label 的资源对象。
标签选择器目前有两种:基于等值关系(等于、不等于)和 基于集合关系(属于、不属于、存在)。
在 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 (推荐,性能最好)来实现网络的转发。
Service是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了“微服务”。比如我们的一个服务A,部署了3个副本,也就是3个 Pod;对 于用户来说,只需要关注一个 Service 的入口就可以,而不需要操心究竞应该请求哪一个Pod。
优势非常明显:一方面外部用户不需要感知因为Pod.上服务的意外崩溃、K8S重新拉起Pod而造成的IP变更,外部用户也不需要感知因升级、变更服务带来的Pod替换而造成的IP变化。
Ingress是K8S集群里工作在OSI网络参考模型下,第7层的应用,对外暴露的接口,典型的访问方式是http/https。Service只能进行第四层的流量调度,表现形式是ip+port。 Ingress 则可以调度不同业务域、不同URL访问路径的业务流量。
Name
由于K8S 内部,使用“资源”来定义每一种逻辑概念(功能),所以每种“资源”,都应该有自己的“名称”。
“资源”有api版本(apiversion) 、类别(kind) 、元数据(metadata) 、定义清单(spec) 、状态(status) 等配置信息。
“名称”通常定义在“资源”的“元数据”信息里。在同一个namespace 空间中必须是唯一的。
namespace
随着项目增多、人员增加、集群规模的扩大,需要一种能够逻辑.上隔离K8S内各种“资源”的方法,这就是Namespace。Namespace是为了把一个K8S集群划分为若千个资源不可共享的虚拟集群组而诞生的。不同Namespace 内的“资源”名称可以相同,相同Namespace 内的同种“资源",“名称”不能相同。
合理的使用K8S的Namespace,可以使得集群管理员能够更好的对交付到K8S里的服务进行分类管理和浏览。K8S里默认存在的Namespace 有: default、 kube-system、 kube-public 等。
查询K8S里特定“资源"要带上相应的Namespace。
namespace的六项隔离
namespace | 系统调用参数 | 隔离内容 |
---|---|---|
UTS | CLONE_NEWITS | 主机名与域名 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 |
PID | CLONE_NEWPID | 进程编号 |
Network | CLONE_NEWNET | 网络设备、网格线、端口等 |
Mount | CLONE_NEWNS | 挂载点 |
User | CLONE_NEWUSER | 用户和用户组 |