一、k8s简介
Kubernetes 是容器集群管理系统工具,是一个开源平台,可实现容器集群的自动化部署、自动扩缩容、维护等功能。Kubernetesk8s是Kubernetes的缩写,Google 于 2014 年开源了 Kubernetes 项目,Kubernetes的名字来自希腊语,意思是“舵手” 或 “领航员”,K8s是将8个字母“ubernete”替换为“8”的缩写。
二、k8s来源与理论
2.1 应用部署方式的演变
在应用程序部署的方式上,主要经历了三个时代:
传统部署方式
互联网早期,直接将应用部署在物理机上(真实的服务器);
优点:
- 是部署简单快捷,资源独享,不需要其他的技术参与;
缺点:
- 不能为应用程序定义资源的使用边界,很难合理的分配服务器计算资源,程序之间容易产生干扰和影响;
-
部署多个物理机,维护许多物理服务器的成本很⾼;
虚拟化部署方式
允许在一台物理机上运行多个虚拟机,每个虚拟机都是一个独立环境,虚拟化能使应⽤程序在不同 VM 之间被彼此隔离,且能提供⼀定程度的安全性;
- 优点:程序环境不会相互产生影响,提供了一定程序上的安全性;
- 缺点:增加了操作系统,浪费了部分资源;
容器化部署方式
容器类似于 VM,但具有更宽松的隔离特性,使容器之间可以共享操作系统(OS),最典型的代表就是docker技术,随着docker的产生和大规模的实践,以docker为代表的容器化部署方式逐渐流行起来,其优势是很明显的:
- 简单的一行命令就可以快速搭建和部署各种中间件,如mysql,redis等;
- ⽐起 VM 被认为更轻量级,每个容器都有⾃⼰的⽂件系统、CPU、内存、进程空间等;
- 运行应用程序所需要的资源都被容器包装,并和底层基础架构解耦;
- 容器化的应用程序可以跨云服务商、跨 Linux 操作系统发行版进行部署;
用一张图表示如下
2.2 k8s 演变过程
传统的服务 => 虚拟机部署 => 容器部署 => k8s
k8s的由来,归根结底是容器的由来,因此需要先搞清楚容器的来龙去脉,k8s是在容器的基础上,方便容器管理、维护,包括声明式配置和自动化。
说到底,k8s的发展历程可以说说与docker的发展有着千丝万缕的联系,为了后面弄清k8s的相关理论,有必要对docker的发展做一个简单的介绍;
2.3 docker 演变历史
容器化时代,一台物理机上可以运行多个容器实例,而一个容器跑多个应用程序,如下图,为一个使用容器部署应用的典型架构;
容器类似于虚拟机,但它们具有松隔离性,可以在应用程序之间共享操作系统(OS)。因此,容器被认为是轻量级的;
与 VM 类似,容器有自己的文件系统、CPU 、内存、进程等。由于它们与底层基础架构分离,因此它们可以实现跨云和操作系统的分布移植。比如可以在ubuntu,centos,redhat,甚至不同的云平台都可以方便快捷的部署应用;
容器之所以在短短的几年快速流行起来,其自身的优势是多方面的,总结如下:
- 敏捷的应用创建与部署:与使用VM镜像像比,容器镜像创建的简便性和效率更高;
- 持续开发、集成和部署:提供可靠,且频繁的容器镜像构建和部署,以及可以快速高效的回滚(由于映像不变性);
- Dev 和 Ops 的关注点分离:在构建/发布时而不是部署时创建应用程序容器的镜像,从而将应用程序与基础架构解耦;
- 可观测性:不仅可以显示操作系统级别的信息和指标,还可以显示应用程序运行状况和其他信号;
- 开发、测试和生产之间的环境一致性:在笔记本电脑上运行与在云中运行环境相同;
- 以应用为中心的管理:将抽象级别从在虚拟硬件上运行操作系统提高到使用逻辑资源在操作系统上运行应用程序;
- 松散耦合、分布式、弹性、自由的微服务:应用程序被分解成更小的、独立的部分,并且可以动态部署和管理——而不是在一台大型单一用途机器上运行的单一堆栈;
- 资源隔离:可预测的应用程序性能;
- 资源利用:高效率、高密度;
总结来说,Docker 由镜像、镜像仓库、容器三个部分组成:
- 镜像: 跨平台、可移植的程序+环境包;
- 镜像仓库: 镜像的存储位置,有云端仓库和本地仓库之分,官方镜像仓库地址;
- 容器: 进行了资源隔离的镜像运行时环境;
2.4 从Docker到Kubernetes
随着容器的火爆,越来越多的业务系统利用容器来搭建部署,像 Docker 之类的容器引擎,部署少量还可以,但随着业务的增多,服务越来越多,动辄就要使用成百上千的容器,要管理这么多容器,Docker 们就力不从心了。随着容器技术越来越多的使用,出现了很多问题
- 百上千的容器管理问题,比如:10个物理机发布100个容器,怎么快速发布和管理?
- 突发海量请求过来,如何根据情况进行快速扩容 ?
- 某个容器故障了,如何快速启动新容器去替代 ?
- 分布式环境下容器如何通信?
- 如何协调和调度这些容器?
- 如何在升级应用程序时不会中断服务?
- 如何监视应用程序的运行状况?
- 如何批量重新启动容器里的程序?
有需求就有改变,于是市场上就出现了一批容器编排工具,典型的是 Swarm、Mesos 和 K8S。
- Docker Swarm:Docker自己的容器编排工具 ;
- Mesos:Apache的资源管控的工具,结合Marathon使用 ;
- Kubernetes:Google开源的的容器编排工具, 基于内部Borg系统的开源版本 ;
最后,K8S“击败”Swarm 和 Mesos,几乎成了当前容器编排的事实标准
再说 k8s
- Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”;
- k8s 这个缩写是因为 k 和 s 之间有八个字符的关系;
- Google 在 2014 年开源了 Kubernetes 项目。 Kubernetes 建立在Google 大规模运行生产工作负载十几年经验的基础上, 结合了社区中最优秀的想法和实践;
- Kubernetes是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,简称 K8S ;
- K8S的本质是一组服务器集群,可以在对应服务器集群的每个节点上运行程序,来对节点中的容器进行管理;
- 类似Master-Work方式,每个服务器上安装特定的k8s组件,就可以形成集群,然后部署对应的应用即可;
官方文档:Kubernetes 文档 | Kubernetes
k8s常见的功能
服务发现和负载均衡
- Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器;
- 如果进入容器的流量很大, Kubernetes 能够自动实现请求的负载均衡分配网络流量,从而使部署稳定 ;
存储编排
- Kubernetes 允许自动挂载选择的存储系统,例如本地存储、云提供商存储等 ;
自动部署和回滚
- 可以用k8s自动化部署创建新容器, 删除现有容器并将它们的所有资源用于新容器 ;
- 当版本发布错误,可以立刻回退到之前的版本
自我修复
- 如果某个容器宕机了,K8S 可以快速重新启动新的的容器,替换旧的容器 ;
密钥与配置管理
- K8S允许存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥 ;
k8s 主要特性
- 高可用,不宕机,自动灾难恢复;
- 灰度更新,不影响业务正常运转;
- 一键回滚到历史版本;
- 方便的伸缩管理(包括应用伸缩,机器增减),提供负载均衡;
- 有一个完善的生态体系,谷歌背书,社区活跃;
- 轻量级;
- 开源;
- 弹性伸缩;
三、k8s核心组件总结
下图为k8s的整体架构图,k8s的高效运行离不开各个组件的密切协作,接下来针对其中的各个核心组件做详细的说明;
从大的模块来看,可以分为master,node,etcd 和其他组件;
3.1 Master 相关组件
- api server: 所有服务访问的统一入口,图中未体现api server与kubelet、kube proxy交互,实际上有交互;
- replication controller: 副本控制器,维护pod副本的期望数,超过或不足将进行自动的关闭或重建;
- scheduler: 调度器,负责接收任务,选择合适的节点分配任务;
controller-manager
在主节点上运行 控制器 的组件。从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。这些控制器包括:
- 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应;
- 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成;
- 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod);
- 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌;
apiserver
API 服务器是 Kubernetes 控制面的组件, 该组件公开了 Kubernetes API, API 服务器是 Kubernetes 控制面的前端,通过kube-apiserver连接各个组件;
- Kubernetes API 服务器的主要实现是 kube-apiserver;
- kube-apiserver 设计上考虑了水平伸缩,也就是说,它可通过部署多个实例进行伸缩;
- 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量;
scheduler
- 控制平面组件,负责监视新创建的、未指定运行节点(node)的 Pods,选择节点让 Pod 在上面运行;
- 调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限;
etcd
etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库;
对k8s来说,只要etcd的数据库存在,各组件就能恢复,因此 Kubernetes 集群的 etcd 数据库通常需要有个备份方式,具体来说:
- 可信赖分布式键值对存储服务(KV服务),键值对数据库,存储k8s集群的所有重要信息(持久化);
- v2版本,写入内存;
- v3版本,支持本地磁盘;
- k8s的v1.11废弃了etcd的v2版本;
3.2 Node相关组件
node
一个node可直观上认为是k8s集群管理的一个物理节点,在一个node上面可能运行了多个docker容器;
-
除了 master , k8s 集群中的其他机器被称为 Node 节点, Node节点才是 kubernetes 集群中的⼯作负载节点;
-
每个 Node 节点都会被 master 分配⼀些⼯作负载(docker容器), node 节点上的 docker 负责容器的运⾏;
从上图可知,node上面除了docker容器,还有kubelet 和kube proxy,具体来说:
- kubelet: 直接跟容器引擎交互,实现容器的生命周期管理。比如:管理docker;
- kube proxy: 负责写入规则至IPTables或IPVS实现服务映射访问。通过操作防火墙达到Pod之间的通信以及Pod的负载均衡;
Pod
Pod 是⼀组容器 , 在 K8S 中,最⼩的单位是 Pod, ⼀个 Pod 可以包含多个容器,但通常情况下我们在每个Pod 中仅使⽤⼀个容器;
pod根据是否自主创建,可以分为自主创建和控制器创建,具体来说:
- ⾃主创建:直接创建出来的Pod,这种pod删除后就没有了,也不会⾃动重建;
- 控制器创建:通过控制器创建的pod,这类Pod删除了之后还会⾃动重建;
kubelet
一个在集群中每个节点(node)上运行的代理。 它保证容器(containers)都运行在 Pod 中。
- kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康;
- kubelet 不会管理不是由 Kubernetes 创建的容器;
kube-proxy
kube-proxy 是集群中每个节点上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分,例如做流量负载均衡。
- kube-proxy 维护节点上的网络规则;
- 这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信;
- 如果操作系统提供了数据包过滤层并可用的话,kube-proxy 会通过它来实现网络规则。否则, kube-proxy 仅转发流量本身;
两种kube-proxy:
- iptables:不允许访问service本身;
- ipvs:可以访问service本身;
Service
-
在 k8s ⾥,每个 Pod 都会被分配⼀个单独的 IP 地址, 但这个IP地址会随着 Pod 的销毁⽽消失;
- Service (服务)就是⽤来解决这个问题的,对外服务的统⼀⼊⼝,⽤于为⼀组提供服务的Pod 抽象⼀个稳定的⽹络访问地址;
- ⼀个Service可以看作⼀组提供相同服务的Pod的对外访问接⼝,作⽤于哪些Pod是通过标签选择器来定义的;
Label
K8S 提供了⼀种机制来为 Pod 进⾏分类,那就是 Label (标 签),同⼀类pod 会拥有相同的标签
-
Label 的具体形式是 key-value 的标记对,可以在创建资源的时候设置,也可以在后期添加和修改;
-
给某个资源对象定义⼀个Label,就相当于给它打了⼀个标签,可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,K8S通过这种⽅式实现了类似SQL的对象查询机制;
需要对不同版本的应用进行集中式的管理时,可以为不同的pod打上不同的标签,对应的资源打上标签后,可以使⽤标签选择器过滤指定的标签
NameSpace
Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为命名空间
具体来说,k8s中的NameSpace具有如下特点:
- 同⼀个名字空间中的资源名称必须唯⼀,⽽不同名字空间之间则没有这个要求;
- NameSpace是不能嵌套的,每⼀个 Kubernetes 的资源都只能在⼀个NameSpace内;
- NameSpace是在多个⽤户之间划分集群资源的⼀种⽅法(通过资源配额);
- 不必使⽤多个名字空间来分隔轻微不同的资源,例如同⼀软件的不同版本: 应该使⽤标签 来区分同⼀名字空间中的不同资源;
Kubernetes启动后,会创建四个初始NameSpace名称空间
- default 没有指明使⽤其它名字空间的对象所使⽤的默认名字空间;
- kube-system Kubernetes 系统创建对象所使⽤的名字空间;
-
kube-public ;
-
kube-node-lease;
3.3 其他重要组件
- CoreDNS: 可以为集群中的svc创建一个域名ip的对应关系解析;
- DashBoard: 给K8s提供一个B/S访问体系;
- Ingress Controller: 官方实现四层代理,Ingress可以实现七层代理(负载均衡);
- Federation: 提供一个可以跨集群中心多k8s统一管理功能;
- Prometheus: 提供K8S集群的监控能力;
- ELK: 提供k8s集群日志统一接入平台;