K8s 是什么?
Kubernetes 是 Google 在 2014 年开源的一个容器集群管理系统,使用 Go 开发,简称为 K8s,用于容器化应用程序的部署,扩展和管理
K8s 提供了容器编排(yml),资源调度,弹性伸缩,部署管理,服务发现等一系列功能,目标是让部署容器化应用简单高效
K8s 兼容多种容器类型,市场占用率最高,官网:https://kubernetes.io/
K8S是Kubernetes的全称,官方称其是:
Kubernetes is an open source system for managing containerized applications across multiple hosts. It provides basic mechanisms for deployment, maintenance, and scaling of applications.
用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。
翻译成大白话就是:“K8S是负责自动化运维管理多个Docker程序的集群”。那么问题来了:Docker运行可方便了,为什么要用K8S,它有什么优势?
插一句题外话:
为什么Kubernetes要叫Kubernetes呢?维基百科已经交代了(老美对星际是真的痴迷): Kubernetes(在希腊语意为“舵手”或“驾驶员”)由Joe Beda、Brendan Burns和Craig McLuckie创立,并由其他谷歌工程师,包括Brian Grant和Tim Hockin等进行加盟创作,并由谷歌在2014年首次对外宣布 。该系统的开发和设计都深受谷歌的Borg系统的影响,其许多顶级贡献者之前也是Borg系统的开发者。在谷歌内部,Kubernetes的原始代号曾经是[Seven] Kubernetes标识中舵轮有七个轮辐就是对该项目代号的致意。
为什么Kubernetes的缩写是K8S呢?我个人赞同[Why Kubernetes is Abbreviated k8s]中说的观点“嘛,写全称也太累了吧,不如整个缩写”。其实只保留首位字符,用具体数字来替代省略的字符个数的做法,还是比较常见的。
为什么是K8S?
试想下传统的后端部署办法:把程序包(包括可执行二进制文件、配置文件等)放到服务器上,接着运行启动脚本把程序跑起来,同时启动守护脚本定期检查程序运行状态、必要的话重新拉起程序。
有问题吗?显然有!最大的一个问题在于:如果服务的请求量上来,已部署的服务响应不过来怎么办?传统的做法往往是,如果请求量、内存、CPU超过阈值做了告警,运维马上再加几台服务器,部署好服务之后,接入负载均衡来分担已有服务的压力。
问题出现了:从监控告警到部署服务,中间需要人力介入!那么,有没有办法自动完成服务的部署、更新、卸载和扩容、缩容呢
- 数据卷
Pod中容器之间共享数据,可以使用数据卷。
- 应用程序健康检查
容器内服务可能进程堵塞无法处理请求,可以设置监控检查策略保证应用健壮性。
- 复制应用程序实例
控制器维护着Pod副本数量,保证一个Pod或一组同类的Pod数量始终可用。
- 弹性伸缩
根据设定的指标(CPU利用率)自动缩放Pod副本数。
- 服务发现
使用环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址。
- 负载均衡
一组Pod副本分配一个私有的集群IP地址,负载均衡转发请求到后端容器。在集群内部其他Pod可通过这个ClusterIP访问应用。
- 滚动更新
更新服务不中断,一次更新一个Pod,而不是同时删除整个服务。
- 服务编排
通过文件描述部署服务,使得应用程序部署变得更高效。
- 资源监控
Node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDB时序数据库,再由Grafana展示。
- 提供认证和授权
支持角色访问控制(RBAC)认证授权等策略。
2.K8s 特性
自我修复: 在节点故障时替换和重新部署,保证预期的副本数量;杀死健康检查失败的容器(探针),并且在未准备好之前不会处理客户端请求,确保线上服务不中断
弹性伸缩: 使用命令(字符界面)或 UI(图形化界面),基于 CPU 使用情况自动快速扩容和缩容应用程序实例,保证应用业务高峰并发时的高可用性;业务低峰时回收资源,以最小成本运行服务
自动部署和回滚: K8s 采用滚动更新策略更新应用,一次更新一个 Pod,而不是同时删除所有 Pod,如果更新过程中出现问题,将回滚更改,确保升级不受影响业务
服务发现和负载均衡: K8s 为多个容器提供一个统访问入口(内部 IP 地址和一个 DNS 名称),并且负载均衡关联的所有容器,使得用户无需考虑容器 IP 问题
机密和配置管理: 管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性;并可以将一些常用的配置存储在 K8s 中,方便应用程序使用(身份验证:命名空间,逻辑划分权限管理)
存储编排: 挂载外部存储系统,无论是来自本地存储,公有云(如 AWS),还是网络存储(如NFS、GlusterFS、Ceph)都作为集群资源的一部分使用, 极大提高存储使用灵活性
批处理: 提供一次性任务,周期性任务;满足批量数据处理和分析的场景
3.小拓展(业务升级)
灰度发布(金丝雀):
指在黑与白之间,能够平滑过渡的一种发布方式,灰度发布可以有效保证整体系统的稳定,降低产品升级所影响的用户范围
例如,让一部分用户继续使用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐渐扩大范围,把所有用户都迁移到B上面来
蓝绿发布:
例如,项目逻辑上分为A/B组,首先把A组从负载均衡中摘除,进行新版本部署,B组继续提供服务
当A组升级完毕,负载均衡重新接入A组,再将B组从负载列表中摘除进行新版本部署,A组重新提供服务
最终,B组完成升级,负载均衡重新接入B组,至此,A/B组皆升级完毕,对外提供服务,达到用户无感知、平滑过渡的效果
滚动发布:
指每次只升级一个或多个服务,升级完成后加入生产环境
不断执行这个过程,直到集群中的全部旧版本升级为新版
由容器引起的架构变化
这些功能在我们现在用到的没有什么本质的的区别。这其中最主要的change 是由 VM 换成了容器,容器的引入导致了部署,网络,quota,LB, 等等都发生了本质的变化。
1)先以container为起点,k8s既然是容器编排工具,那么一定会有container
(2)那k8s如何操作这些container呢?k8s不直接操作container,因为操作container的事情是docker来做的,k8s中要有自己的最小操作单位,称之为 Pod
说白了,Pod就是一个或多个Container的组合
看看官网怎么描述的 :https://kubernetes.io/docs/concepts/workloads/pods/pod/
A Pod (as in a pod of whales or pea pod) is a group of one or more containers (such as Docker containers),
with shared storage/network, and a specification for how to run the containers.
(3)那Pod的维护谁来做呢?那就是ReplicaSet,通过selector来进行管理
看看官网怎么描述的 :https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
A ReplicaSet is defined with fields, including a selector that specifies how to identify Pods it can acquire, a number of replicas indicating how many Pods it should be maintaining, and a pod template specifying the data of new Pods it should create to meet the number of replicas criteria.
(4)Pod和ReplicaSet的状态如何维护和监测呢?Deployment
官网是如何描述的 :https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
A Deployment controller provides declarative updates for Pods and ReplicaSets.
You describe a desired state in a Deployment, and the Deployment controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments.
(5)不妨把相同或者有关联的Pod分门别类一下,那怎么分门别类呢?Label
官网是如何描述的 :https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
Labels are key/value pairs that are attached to objects, such as pods.
(6)具有相同label的service要是能够有个名称就好了,Service
看官网上怎么说 :https://kubernetes.io/docs/concepts/services-networking/service/
An abstract way to expose an application running on a set of Pods as a network service.
With Kubernetes you don’t need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them.
(7)上述说了这么多,Pod运行在哪里呢?当然是机器咯,比如一台centos机器,我们把这个机器称作为Node
看看官网怎么说 :https://kubernetes.io/docs/concepts/architecture/nodes/
A node is a worker machine in Kubernetes, previously known as a minion. A node may be a VM or physical machine, depending on the cluster. Each node contains the services necessary to run pods and is managed by the master components.
(8)难道只有一个Node吗?显然不太合适,多台Node共同组成集群才行嘛
画个图表示一下咯,最好能把之前的Label,Service也一起画上去,整体感受一下
(9)此时,我们把目光转移到由3个Node节点组成的Master-Node集群
(10)这个集群要配合完成一些工作,总要有一些组件的支持吧?接下来我们来想想有哪些组件,然后画一个相对完整的架构图
Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项。
- Master Node:作为控制节点,对集群进行调度管理;Master Node由API Server、Scheduler、Cluster State Store和Controller-Manger Server所组成;
- Worker Node:作为真正的工作节点,运行业务应用的容器;Worker Node包含kubelet、kube proxy和Container Runtime;
- kubectl:用于通过命令行与API Server进行交互,而对Kubernetes进行操作,实现在集群中进行各种资源的增删改查等操作;
- Add-on:是对Kubernetes核心功能的扩展,例如增加网络和网络策略等能力。
组件
Kubernetes主要由以下几个核心组件组成:
- etcd保存了整个集群的状态;
- apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
- controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
- kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
- Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
- kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
除了核心组件,还有一些推荐的Add-ons:
- kube-dns负责为整个集群提供DNS服务
- Ingress Controller为服务提供外网入口
- Heapster提供资源监控
- Dashboard提供GUI
- Federation提供跨可用区的集群
- Fluentd-elasticsearch提供集群日志采集、存储与查询
K8S是属于主从设备模型(Master-Slave架构),即有Master节点负责核心的调度、管理和运维,Slave节点则在执行用户的程序。但是在K8S中,主节点一般被称为Master Node或者Head Node(本文采用Master Node称呼方式),而从节点则被称为Worker Node或者Node(本文采用Worker Node称呼方式)。
要注意一点:Master Node和Worker Node是分别安装了K8S的Master和Woker组件的实体服务器,每个Node都对应了一台实体服务器(虽然Master Node可以和其中一个Worker Node安装在同一台服务器,但是建议Master Node单独部署),所有Master Node和Worker Node组成了K8S集群,同一个集群可能存在多个Master Node和Worker Node。
Kubernetes是利用共享网络将多个物理机或者虚拟机组成一个集群,在各个服务器之间进行通信,该集群是配置Kubernetes的所有租金啊啊、功能和负载的物理平台。
一个Kubernetes集群由master和node组成。如下图:
- Master:是集群的网关和中枢枢纽,主要作用:暴露API接口,跟踪其他服务器的健康状态、以最优方式调度负载,以及编排其他组件之间的通信。单个的Master节点可以完成所有的功能,但是考虑单点故障的痛点,生产环境中通常要部署多个Master节点,组成Cluster。
-
Node:是Kubernetes的工作节点,负责接收来自Master的工作指令,并根据指令相应地创建和销毁Pod对象,以及调整网络规则进行合理路由和流量转发。生产环境中,Node节点可以有N个。
首先来看Master Node都有哪些组件:
API Server。K8S的请求入口服务。API Server负责接收K8S所有请求(来自UI界面或者CLI命令行工具),然后,API Server根据用户的具体请求,去通知其他组件干活。
Scheduler。K8S所有Worker Node的调度器。当用户要部署服务时,Scheduler会选择最合适的Worker Node(服务器)来部署。
Controller Manager。K8S所有Worker Node的监控器。Controller Manager有很多具体的Controller,在文章Components of Kubernetes Architecture中提到的有Node Controller、Service Controller、Volume Controller等。Controller负责监控和调整在Worker Node上部署的服务的状态,比如用户要求A服务部署2个副本,那么当其中一个服务挂了的时候,Controller会马上调整,让Scheduler再选择一个Worker Node重新部署服务。
etcd。K8S的存储服务。etcd存储了K8S的关键配置和用户配置,K8S中仅API Server才具备读写权限,其他组件必须通过API Server的接口才能读写数据(见Kubernetes Works Like an Operating System)。
接着来看Worker Node的组件,笔者更赞同HOW DO APPLICATIONS RUN ON KUBERNETES文章中提到的组件介绍:
Kubelet。Worker Node的监视器,以及与Master Node的通讯器。Kubelet是Master Node安插在Worker Node上的“眼线”,它会定期向Worker Node汇报自己Node上运行的服务的状态,并接受来自Master Node的指示采取调整措施。
Kube-Proxy。K8S的网络代理。私以为称呼为Network-Proxy可能更适合?Kube-Proxy负责Node在K8S的网络通讯、以及对外部网络流量的负载均衡。
-
Container Runtime。Worker Node的运行环境。即安装了容器化所需的软件环境确保容器化程序能够跑起来,比如Docker Engine。大白话就是帮忙装好了Docker运行环境。
Logging Layer。K8S的监控状态收集器。私以为称呼为Monitor可能更合适?Logging Layer负责采集Node上所有服务的CPU、内存、磁盘、网络等监控项信息。
Add-Ons。K8S管理运维Worker Node的插件组件。有些文章认为Worker Node只有三大组件,不包含Add-On,但笔者认为K8S系统提供了Add-On机制,让用户可以扩展更多定制化功能,是很不错的亮点。
总结来看,K8S的Master Node具备:请求入口管理(API Server),Worker Node调度(Scheduler),监控和自动调节(Controller Manager),以及存储功能(etcd);而K8S的Worker Node具备:状态和监控收集(Kubelet),网络和负载均衡(Kube-Proxy)、保障容器化运行环境(Container Runtime)、以及定制化功能(Add-Ons)。
分层架构
Kubernetes及容器生态系统
Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示
核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
接口层:kubectl命令行工具、客户端SDK以及集群联邦
生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等