Kubernetes,又称为 k8s(首字母为 k、首字母与尾字母之间有 8 个字符、尾字母为 s,所以简称 k8s)或者简称为 "kube" ,是一种可自动实施 Linux 容器操作的开源平台。它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。
官网: https://kubernetes.io/zh/docs/tutorials/kubernetes-basics/
Kubernete简介
Kubernetes 是 Google 团队发起并维护的基于 Docker 的开源容器集群管理系统,它不仅支持常见的云平台,而且支持内部数据中心。
建于 Docker 之上的 Kubernetes 可以构建一个容器的调度服务,其目的是让用户透过 Kubernetes 集群来进行云端容器集群的管理,而无需用户进行复杂的设置工作。系统会自动选取合适的工作节点来执行具体的容器集群调度处理工作。其核心概念是Pod。一个 Pod 由一组工作于同一物理工作节点的容器构成。这些组容器拥有相同的网络命名空间、IP以及存储配额,也可以根据实际情况对每一个 Pod 进行端口映射。此外,Kubernetes 工作节点会由主系统进行管理,节点包含了能够运行 Docker 容器所用到的服务。
kubernetes前世
Kubernetes 是希腊语『舵手』的意思,它最开始由 Google 的几位软件工程师创立,深受公司内部 Borg 和 Omega 项目的影响,很多设计都是从 Borg 中借鉴的,同时也对 Borg 的缺陷进行了改进,Kubernetes目前是 CNCF 的项目并且是很多公司管理分布式系统的解决方案。
目标
Kubernetes 作为一个容器集群管理系统,用于管理云平台中多个主机上的容器应用,Kubernetes的目标是让部署容器化的应用变得简单且高效,并使应用程序运营商和开发人员完全将重点放在以容器为中心的原语上进行自助运营,所以Kubernetes 提供了应用部署,规划,更新,维护的一整套完整的机制。
Kubernetes 没有固定要求容器的格式,但是 Kubernetes使用它自己的 API 和命令行接口来进行容器编排。除了Docker 容器之外,Kubernetes 还支持其他多种容器,如 rkt、CoreOS 等。
Kubernetes 也提供稳定、兼容的基础(平台),用于构建定制化的workflows 和更高级的自动化任务。
Kubernetes 具备完善的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建负载均衡器、故障发现和自我修复能力、服务滚动升级和在线扩容、可扩展的资源自动调度机制、多粒度的资源配额管理能力。 这些特征便足以征服开发者,再加上 Kubernetes 有一个非常活跃的社区。它为用户提供了更多的选择以方便用户扩展编排容器来满足他们的需求。但是由于 Kubernetes 使用了自己的 API 接口,所以命令系统是另外一套系统,这也是 kubernetes 门槛比较高的原因所在。
另外Kubernetes 还提供完善的管理工具,涵盖开发、部署测试、运维监控等各个环节。
kubernetes架构
Kubernetes 遵循非常传统的客户端/服务端的架构模式,客户端可以通过 RESTful 接口或者直接使用 kubectl 与 Kubernetes 集群进行通信,这两者在实际上并没有太多的区别,后者也只是对 Kubernetes 提供的 RESTful API 进行封装并提供出来。每一个 Kubernetes集群都是由一组 Master 节点和一系列的 Worker 节点组成,其中 Master 节点主要负责存储集群的状态并为 Kubernetes 对象分配和调度资源。
Master
作为管理集群状态的 Master 节点,它主要负责接收客户端的请求,安排容器的执行并且运行控制循环,将集群的状态向目标状态进行迁移。Master 节点内部由下面三个组件构成:
API Server: 负责处理来自用户的请求,其主要作用就是对外提供 RESTful 的接口,包括用于查看集群状态的读请求以及改变集群状态的写请求,也是唯一一个与 etcd 集群通信的组件。
etcd: 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。
Scheduler: 主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。
controller-manager: 在主节点上运行控制器的组件,从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:节点控制器(负责在节点出现故障时进行通知和响应)、副本控制器(负责为系统中的每个副本控制器对象维护正确数量的 Pod)、端点控制器(填充端点 Endpoints 对象,即加入 Service 与 Pod))、服务帐户和令牌控制器(为新的命名空间创建默认帐户和 API 访问令牌)。
常用控制器
控制器 | 名称 | 作用 | 补充说明 |
---|---|---|---|
Node Controller | 节点控制器 | 负责在节点出现故障时发现和响应 | 定期检查 Node 的健康状态,标识出失效的 Node |
Replication Controller | 副本控制器 | 保证Replication Controller 定义的副本数量与实际运行 Pod 的数量一致 | 可以理解成确保集群中有且仅有N个Pod实例,N是RC中定义的Pod副本数量 |
Endpoints Controller | 端点控制器 | 填充端点对象(即连接Services和Pods),负责监听Service和对应的Pod副本的变化 | 端点是一个服务暴露出来的访问点,如果需要访问一个服务,则必须知道它的endpoint |
Service Account & Token Controllers | 服务账户和令牌控制器 | 为新的命名空间创建默认账户和API访问令 | |
ResourceQuota Controller | 资源配额控制器 | 确保指定的资源对象在任何时候都不会超量占用系统物理资源 | |
Namespace Controller | 命名空间控制器 | 管理namespace的声明周期 | 定期清理无效的 Namespace,以及 Namespace 下的 API 对象,比如:Pod、Service、Secrte 等 |
Service Controller | 服务控制器 | 属于K8S集群与外部的云平台之间的一个接口控制器 |
Worker
其他的 Worker 节点实现就相对比较简单了,它主要由 kubelet 和 kube-proxy 两部分组成。
kubelet: 是工作节点执行操作的 agent,负责具体的容器生命周期管理,根据从数据库中获取的信息来管理容器,并上报 pod 运行状态等。
kube-proxy: 是一个简单的网络访问代理,同时也是一个 Load Balancer。它负责将访问到某个服务的请求具体分配给工作节点上同一类标签的 Pod。kube-proxy 实质就是通过操作防火墙规则(iptables或者ipvs)来实现 Pod 的映射。
Container Runtime: 容器运行环境是负责运行容器的软件,Kubernetes 支持多个容器运行环境: Docker、 containerd、cri-o、 rktlet 以及任何实现 Kubernetes CRI(容器运行环境接口)。
Master 和 Node 的交互方式
Kubernetes 中所有的状态都是采用上报的方式实现的。APIServer 不会主动跟 Kubelet 建立请求链接,所有的容器状态汇报都是由 Kubelet 主动向 APIServer 发起的。
当集群资源不足的时候,可以按需增加Node 节点。一旦启动 Kubelet 进程以后,它会主动向 APIServer 注册自己,这是 Kubernetes 推荐的 Node 管理方式。当然你也可以在Kubelet 启动参数中去掉自动注册的功能,不过一般都是默认开启这个模式的。
一旦新增的 Node 被 APIServer 纳管进来后,Kubelet 进程就会定时向 APIServer 汇报“心跳”,即汇报自身的状态,包括自身健康状态、负载数据统计等。当一段时间内心跳包没有更新,那么此时 kube-controller-manager 就会将其标记为NodeLost(失联)。
Kubernetes 中各个组件都是以 APIServer 为中心,通过松耦合的方式进行。借助声明式 API,各部件通过 watch 的机制就可以根据各个对象的变化,很快地做出相应的处理操作。
Kubernetes资源对象
Pod
Pod是K8s能够创建和管理的最小单位,一个Pod里可以包含一个或者多个容器应用,Pod里的容器之间共享网络、存储等资源。
一个 Pod 里可以运行多个容器,又叫边车模式(SideCar)。
而在生产环境中一般都是单个容器或者具有强关联互补的多个容器组成一个 Pod。
同一个 Pod 之间的容器可以通过 localhost 互相访问,并且可以挂载 Pod 内所有的数据卷;
但是不同的 Pod 之间的容器不能用 localhost 访问,也不能挂载其他 Pod 的数据卷。
Pod控制器
Pod 控制器是 Pod 启动的一种模版,用来保证在K8S里启动的 Pod 应始终按照用户的预期运行(副本数、生命周期、健康状态检查等)。
Pod控制器 | 功能 |
---|---|
Deployment | 部署无状态应用,同时也负责管理replicaset(维持Pod副本数量符合预期数量)和Pod(容器化的应用进程) |
Statefulset | 部署有状态服务/应用 |
Daemonset | 在所有的node节点上部署同一类型的Pod |
Job | 一次性的部署短期任务的Pod(执行完任务后会自动退出的Pod) |
Cronjob | 周期性的部署短期任务的Pod(执行完任务后会自动退出的Pod) |
有状态和无状态服务的区别
从是否需要数据的实时存储和数据同步来区分。
有状态服务
1)有实时的数据需要存储;
2)集群服务中,把某一台服务器抽离出去,过一段时间再加入到集群中,如果服务集群无法正常工作(相互之间需要数据同步)。
无状态服务
1)没有实时的数据需要存储;
2)集群服务中,把某一台服务器抽离出去,过一段时间再加入到集群中,如果服务集群还是正常工作(相互之间不用数据同步)。
Service
为什么要用到Service(服务)?
因为 Deployment 的 Pod 可能有多个,并且这些 Pod 所在的 Node 并不固定,因此无法使用固定的 IP 和端口去访问。
Kubernetes 使用 Service 来解决此问题,一个 Service 对应一个应用,代表该应用提供的服务。
Service
在K8S集群内部,为通过标签选择器相关联的一组Pod提供一个统一的访问入口(clusterIP),只支持四层代理转发。
虚拟IP只在集群内部有效。
客户端通过cluster IP 来请求应用服务时,kube-proxy 会将请求转发给 Deployment 中的某个 Pod。
当 Pod 位置发生变化时,kube-proxy 能够及时感知到。
通过 kube-proxy 就解决了单个 Pod 服务的注册和发现问题,同时也实现了负载均衡。
Ingress
作为K8S集群外部接入层,可自定义ingress规则根据用户请求的域名或URL请求路径转发给指定的service,支持七层代理转发。
Kurbernetes创建Pod资源的工作流程
1)用户通过客户端发送创建Pod的请求给apiserver;
2)Apiserver接收到请求后,会先把请求信息写入到etcd中保存,再找controller-manager根据请求信息中的资源预设模板创建Pod资源;
3)Controller-manager会通过apiserver找到scheduler,来调度新创建的Pod资源;
4)Scheduler通过调度算法的预选策略及优选策略,筛选出最适合的Node节点进行调度;
5) 再通过apiserver找到对应的node节点上的Kubelet去创建和管理Pod;
6)Kubelet会跟容器引擎交互来管理Pod和容器的生命周期;
7)用户还可以通过apiserver在kube-proxy上写入iptables/ipvs网络规则,创建service资源,实现对Pod集群的网络代理。