容器集群管理系统--Kubernetes(K8S)

406 阅读11分钟

Kubernetes

什么是Kubernetes?

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化工作负载和服务,有助于声明式配置和自动化。它拥有庞大且快速发展的生态系统。Kubernetes 服务、支持和工具随处可见

Kubernetes作用

用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。 可以理解成 K8S 是负责自动化运维管理多个容器化程序(比如 Docker)的集群,是一个生态极其丰富的容器编排框架工具。

为什么需要K8S?

试想下传统的后端部署办法:把程序包(包括可执行二进制文件、配置文件等)放到服务器上,接着运行启动脚本把程序跑起来,同时启动守护脚本定期检查程序运行状态、必要的话重新拉起程序。

设想一下,如果服务的请求量上来,已部署的服务响应不过来怎么办?传统的做法往往是,如果请求量、内存、CPU超过阈值做了告警,运维人员马上再加几台服务器,部署好服务之后,接入负载均衡来分担已有服务的压力。这样问题就出现了:从监控告警到部署服务,中间需要人力介入!那么,有没有办法自动完成服务的部署、更新、卸载和扩容、缩容呢?而这就是K8S要做的事情:自动化运维管理容器化(Docker)程序。

K8S是Google开源的容器集群管理系统,在Docker等容器技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。

Kubernetes 主要功能

  • 跨主机编排容器。 
  • 更充分地利用硬件资源来最大化地满足企业应用的需求。 
  • 控制与自动化应用的部署与升级。 
  • 为有状态的应用程序挂载和添加存储器。 
  • 线上扩展或缩减容器化应用程序与它们的资源。 
  • 声明式的容器管理,保证所部署的应用按照我们部署的方式运作。 
  • 通过自动布局、自动重启、自动复制、自动伸缩实现应用的状态检查与自我修复。 
  • 为多个容器提供服务发现和负载均衡,使得用户无需考虑容器IP问题。 

K8S 的特性

  1. 弹性伸缩:使用命令、UI或者基于CPU使用情况自动快速扩容和缩容应用程序实例,保证应用业务高峰并发时的高可用性;业务低峰时回收资源,以最小成本运行服务。 
  2. 自我修复:在节点故障时重新启动失败的容器,替换和重新部署,保证预期的副本数量;杀死健康检查失败的容器,并且在未准备好之前不会处理客户端请求,确保线上服务不中断。 
  3. 服务发现和负载均衡:K8S为多个容器提供一个统一访问入口(内部IP地址和一个DNS名称),并且负载均衡关联的所有容器,使得用户无需考虑容器IP问题。 
  4. 自动发布(默认滚动发布模式)和回滚:K8S采用滚动策略更新应用,一个更新一个Pod,而不是同时删除所有的Pod,如果更新过程中出现问题,将回滚更改,确保升级不收影响业务。 
  5. 集中化配置管理和密钥管理:管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性,并可以将一些常用的配置存储在K8S中,方便应用程序使用。 
  6. 存储编排:支持外挂存储并对外挂存储资源进行编排,挂载外部存储系统,无论是来自本地存储,公有云(如:AWS),还是网络村存储(如:NFS、Glusterfs、Ceph)都作为集群资源的一部分使用,极大提高存储使用灵活性。 
  7. 任务批量处理运行:提供一次性任务,定时任务,满足批量数据处理和分析的场景。

Kubernetes 集群架构

K8S 是属于主从设备模型(Master-Slave架构),即有Master节点复制集群的调度、管理和运维,Slave节点是集群的运算工作负载节点。在K8S中,主节点一般被称为 Master 节点,而从节点则被称为 Worker Node 节点,每个 Node 都会被 Master 分配一些工作负载。 

Master组件可以在群集中的任何计算机上运行,但是 建议Master节点占据一个独立的服务器,因为Master是整个集群的大脑,如果Master所在的节点宕机或者不可用,那么所有的控制命令都将会失效。除了Master,在K8S集群中的其他机器被称为Worker Node 节点,当某个 Node宕机时,其上的工作负载会被Master自动转移到其他节点上去 

核心组件

k8s 有 masterworker node 两类节点

master节点上有 apiserver controller-manager scheduler 以及 使用 etcd 做k8s集群存储

node节点上有 kubelet kube-proxy 容器引擎(比如docker)

master节点

  • apiserver:所有服务请求的统一访问入口 

  • controller-manager:负责为pod副本集、命名空间、端点等资源对象以及部署提供控制器,比如副本集控制器维持副本期望数目 

    控制器主要包括 •Node Controller(节点控制器):负责在节点出现故障时发现和响应。 •Replication Controller(副本控制器):负责保证集群中一个 RC(资源对象 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 的生命周期。 •Service Controller(服务控制器):属于 K8S 集群与外部的云平台之间的一个接口控制器。

  • scheduler:负责Pod资源调度,通过调度算法(预选策略、优选策略)为部署的pod选择最适合的node节点 

  • etcd:K8S集群数据库,是键值对存储结构的分布式数据库,存储K8S集群所有重要信息,只有apiserver有读写权限

noder节点

  • kubelet:创建和管理Pod中的容器,跟容器引擎交互实现容器的生命周期管理;收集节点的资源信息和pod的运行状态汇报给master的
  • apiserver kube-proxy:作为service资源的载体,实现 Pod 网络代理,维护网络规则和四层负载均衡工作 
  • 容器引擎:运行容器

Kubernetes 核心概念

Kubernetes 包含多种类型的资源对象:Pod、Label、Service、Replication Controller 等。

所有的资源对象都可以通过Kubernetes 提供的Kubectl 工具进行增删改查等操作,并将其保存在 etcd 中持久化存储。

Kubernetes其实是一个高度自动化的资源控制系统,通过跟踪对比etcd存储里保存的资源期望状态与当前环境中的实际资源状态的差异,来实现自动控制和自动纠错等高级功能。

Pod

Pod是 Kubernetes 创建或部署的最小/最简单的基本单位,一个 Pod 代表集群上正在运行的一个进程。可以把 Pod 理解成豌豆荚,而同一个 Pod 内的每一个容器就是一颗颗豌豆。

一个 Pod 由一个或多个容器组成,Pod 中容器共享网络、存储和计算资源,在同一台 Docker 主机上运行。

一个 Pod 里可以运行多个容器,又叫做边车模式(SideCare)模式,而在生产环境中一般使用单个容器或者具有强关联互补的多个容器组成一个Pod。

同一个 Pod 之间和容器可以通过 localhost 互相访问,并且可以挂载 Pod 内所有的数据卷;但是不同 Pod 之间的容器不能用 localhost 访问,也不能挂载其他 Pod 的数据卷。

Pod 控制器

Pod 控制器是 Pod 启动的一种模板,用来保证在 K8S 里启动的Pod 应始终按照用户的预期运行(副本数、生命周期、健康状态检查等)。

  • deployment:部署无状态应用。同时也管理replicaset (维持pod副本期望数)和pod (k8s创建的最小单元,一个容器化的应用进程) 
  • statefulset:部署有状态应用
  • daemonset: 在所有的node节点上部署同一种pod
  • job: 部署一次性任务的pod,pod执行完任务就会自动退出,只部署一次
  • cronjob: 周期性的部署一次性任务的pod

Label

Label 标签,是K8S 特色的管理方式,便于分类管理资源对象。

Label 可以附加到各种资源对象上,例如 Node、Pod、Service、RC 等,用于关联对象、查询和筛选。 

一个 Label 是一个 key-value 的键值对,其中 key 与 value 由用户自己指定。 

一个资源对象可以定义任意数量的Label,同一个Label 也可以被添加到任意数量的资源对象中,也可以在对象创建后动态添加或者删除。 

可以通过给指定的资源对象捆绑一个或多个不同的 Label,来实现多维度的资源分组管理功能。

Label 选择器(Label selector)

给某个资源对象定义一个 Label,就相当于给它打了一个标签;随后可以通过标签选择器(Label selector)查询和筛选拥有某些 Label 的资源对象。 

标签选择器目前有两种:基于等值关系(等于、不等于)和基于集合关系(属于、不属于、存在)。

Service

Service 是 K8S 服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了“微服务”。比如我们的一个服务 A,部署了 3 个副本,也就是 3 个 Pod; 对于用户来说,只需要关注一个 Service 的入口就可以,而不需要操心究竟应该请求哪一个 Pod。 优势非常明显:一方面外部用户不需要感知因为 Pod 上服务的意外崩溃、K8S 重新拉起 Pod 而造成的 IP 变更, 外部用户也不需要感知因升级、变更服务带来的 Pod 替换而造成的 IP 变化。

Ingress

Service 主要负责 K8S 集群内部的网络拓扑,那么集群外部怎么访问集群内部呢?这个时候就需要 Ingress 了。

Ingress 是整个 K8S 集群的接入层,负责集群内外通讯。 Ingress 是 K8S 集群里工作在 OSI 网络参考模型下,第7层的应用,对外暴露的接囗,典型的访问方式是 http/https。 

Service 只能进行第四层的流量调度,表现形式是 ip+port。Ingress 则可以调度不同业务域、不同URL访问路径的业务流量。 

比如:客户端请求 www.kgc.com:port ---> Ingress ---> Service ---> Pod

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创建Pod的工作流程

  • 用户通过客户端发送创建pob的请求到master节点上的apiserver
  • apiserver会先把相关的请求信息写入到etcd中,再找controller-manager根据预设的资源模板创建pod清单
  • 然后controller-manager会通过apiserver去找scheduler为新创建的pod选择最适合的Node节点
  • scheduler会通过调度算法的预选策略和优选策略筛选出最适合的Node节点
  • 然后再通过apiserver找到对应的Node节点上的kubelet去创建和管理pod
  • kubelet会直接跟容器引警交互来管理容器的生命周期
  • 用户通过创建承载在kube-proxy上的service资源,写入相关的网络规则,实现对pod的服务发现和负载均衡