Kubernetes基础入门
Kubernetes基础入门
1. k8s 基础入门
1.1 部署模式发展
1.2 物理单机(~2000)
早期在物理服务器上运行应用程序也叫做传统的部署。
在商用服务计算领域几乎都是以单机为基础计算单元对计算资源 进行管理和协调控制的
部署新应用往往需要购买一台物理机器或者一组机器,并在机器上进行构建,部署和运行,而且一台机器往往只能运行单个应用,成本高,利用率低
1.2.1 主要代表
BM、Sun公司
早期在物理服务器上运行应用程序也叫做传统的部署。
传统部署时代: 在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界,这会导致资源分配的问题。
例如,如果在物理服务器上运行多个应用程序,则可能存在一个应用程序占用大部分资源的情况,因此导致其他应用程序获取不到资源。所以往往解决方案是在不同的物理服务器上运行每个应用程序。但是由于资源未得到充分利用,没有扩展,组织和维护这么多物理服务器的成本很高。
1.3 虚拟化:初期(2001~2009)
1.3.1 VMware
VMware:2001年,Xen:2003年,KVM:2007年
- VMware发布了针对服务器市场的虚拟化技术方案:提升计算资源的利用率和降低使用成本
- Vmware、Xen和KVM三足鼎立,促进了VM概念的普及,拉开了虚拟化云计算时代的大幕,基础计算单元变为VM,服务端应用的构建、部署和运行逐步迁移到虚拟机VM上了。
- 充分地物理单机将划分为多个虚拟机,提高计算机资源的利用率和降低成本
1.3.2 laaS
AWS 2006年,GCE(Google Compute Engine)2008年
- 基于虚拟机技术的Amazon Web
Services(AWS)开启了Infrastructure-as-a-Service(IaaS基础设施即服务)的市场 - 实现了自助的、按需租用以VM为基本计算单元的计算资源。
- 应用的部署运行依然以vm为单元并通过laaS厂商提供的控制台实现高效的计算资源管理。
这个时期也称为虚拟化部署时代:作为解决方案,引入了虚拟化。它允许在单个物理服务器的CPU上运行多个虚拟机(VM)。虚拟化允许应用程序在VM之间隔离,并提供一定程度的安全性,因为一个应用程序无法自由访问另一个应用程序的信息。
虚拟化可以更好地利用物理服务器中的资源,并且可以实现更好的可扩展性,因为可以轻松添加或更新应用程序,降低硬件成本等等。每个VM都是在虚拟化硬件之上运行所有组件(包括其自己的操作系统)的完整计算机。
1.4 虚拟化:成熟期(2010~至今)
1.4.1 OpenStack
OpenStack 2010 诞生,推动开源laaS平台的快速发展。推动商家将自有数据中心改造为虚拟化平台,部署数据敏感、业务敏感的核心应用
- 部署形式:公有云、私有云、混合云
- 服务模式:laaS、PaaS(Heroku 2009)、SaaS等
1.4.2 虚拟化四巨头
AWS、Azure、Aliyun、GCE(Google Compute Engine):2015-2017
基于虚拟化技术的公有云爆发式增长,形成公有云laaS四巨头
2017年底,全球企业的一半以上的计算资源放在了公有云上,半数企业在内部完成了私有云部署
1.5 容器化:(2013-至今)
1.5.1 Docker
2013 年诞生
- 以Docker为代表的内核容器技术不是新技术,而是将已有技术(LXC、cgroups、UnionFS)进行了更好的整合和包装,并形成了一种标准镜像格式。
- 与VM相比,容器具有开发交付流程操作对象同步、执行更为高效、资源占用更为集约等优势。
- 计算基本单元由虚拟机变为了容器,越来越多应用的构建、部署与运行选择在容器中进行。
Docker能够解决什么问题?如果我们在一台服务器上只跑很多个服务,比如说有一个服务内存泄漏把整个服务器内存占满了,其他服务也跟着倒霉,所以需要把每个服务隔离起来,让它们只使用自己那部分有限的CPU,内存和磁盘以及依赖的软件包。Docker相比虚拟机来说少了操作系统这一层,所以占用的资源少,启动速度快,能够提供一定程度的隔离。而且运维简单,可以克隆多个个环境相同的容器。
这个时期也称为容器部署时代:容器类似于VM,但它们具有宽松的隔离属性,可在应用程序之间共享操作系统(OS)。因此,容器被认为是轻量的的。与VM类似,容器具有自己的文件系统,CPU,内存,进程空间等。
1.6 云原生:初期(2015-至今)
1.6.1 云原生模式
随着容器技术的出现以及应用所面临的外部环境的变化,云原生逐渐成为一种应用云化开发、部署和运行的主流方式。基础前提:应用的容器化和微服务化。
- 容器,作为应用部署、运行和管理的基本单元;
- 核心:借助容器管理自动化平台进行动态编排和资源优化利用。
1.6.2 K8S
CNCF,Kubernetes:2015年
就在Docker容器技术被炒得热火朝天之时,大家发现,如果想要将Docker应用于具体的业务实现,是存在困难的——编排、管理和调度等各个方面,都不容易。于是,人们迫切需要一套管理系统,
对Docker及容器进行更高级更灵活的管理。Kuberentes可以说是乘着Docker和微服务的东风,一经推出便迅速蹿红,它的很多设计思想都契合了微服务和云原生应用的设计法则。Kuberentes从众多强大对手中脱颖而出。
CNCF组织的成立为应用上云安全地采用云原生模式提供了更稳、更快、更安全的解决方案,其核心是Kubernetes。从众多强大对手中脱颖而出,Kubernetes为云原生模式下应用的部署、运行和管理提供了可移植的、云厂商无关的事实标准。
1.6.3 趋势
- 应用部署运行模式:单机->虚拟机->容器->云原生
- 应用部署运行:更敏捷、更自动化、更有效率、更低成本
- 开发者:更聚焦于应用本身
1.7 发展变迁
应用部署运行模式的演变图:
2. k8s 概述
2.1 k8s 是什么
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)应用程序”的开源系统。
2.2 K8s的由来
源自谷歌的Borg,Borg是谷歌公司的内部容器管理系统。
Borg系统运行几十万个以上的任务,来自几千个不同的应用,跨多个集群,每个集群(cell)有上万个机器。它通过管理控制、高效的任务包装、超售、和进程级别性能隔离实现了高利用率。它支持高可用性应用程序与运行时功能,最大限度地减少故障恢复时间,减少相关故障概率的调度策略。该项目的目的是实现资源管理的自动化以及跨多个数据中心的资源利用率最大化。Kubernetes项目的目的就是将Borg最精华的部分提取出来,使现在的开发者能够更简单、直接地应用。它以Borg为灵感,但又没那么复杂和功能全面,更强调了模块性和可理解性。
2.2.1 K8s发展历程
Kubernetes 是 Google 开源的容器编排系统,2014 年对外宣布,2015 年发布 1.0 版本,同Google 与 Linux 基金会一起成立云原生计算基金会(CNCF-Cloud Native Computing Foundation),并把 Kubernetes 作为种子产品捐赠给了 CNCF。Google 一直在带领着 Kubernetes 的开发,我们也可以看到 CNCF 的 Kubernetes 项目代码贡献量,Google 所占比重是最高的。
2.2.2 发展时间线
Google 在容器领域拥有超过 15 年的经验。
- 2003 年,Google 内部几个工程师做了一个集群自动化管理的工具,叫做 Borg;
- 2012 年,Google Borg 升级成 Omega,实现容器的管理;
- 2013 年,随着业界 Docker 发布,整个行业开始往容器方向迁移;
- 2014 年,Borg/Omega 开源为 Kubernetes 项目;
- 到如今,Kubernetes 已经成为整个容器编排的主流技术。
2.3 为什么使用k8s
2.3.1 什么是容器
- 容器就是一个包,其中包含了应用及其所有依赖。
- 容器中的应用与主机系统是隔离的,不关注环境。
- 不像虚拟机,容器不需要启动操作系统的完整周期,这就是为啥容器启动和停止都非常快,并且可以更高效使用磁盘、内存、处理器的原因。
- 你不必记着你的应用是用什么语言和框架开发的,因为所需的一切都打包在了容器中,例如运行时环境、所需的库等等,可以安全的迁移,可以在任何环境中部署。
左边,应用是直接部署在服务器或者虚拟机里面的,右边,应用是打包在独立的容器中的,可以快速启动、智能扩展、在任何环境中平滑运行。
2.3.2 什么是 Kubernetes
Kubernetes 是一个开源项目,用于统一管理容器化的应用集群。
- Kubernetes 负责在大规模服务器环境中管理容器组(pod)的扩展、复制、健康,并解决 pod 的 启动、负载均衡等问题。
- Kubernetes 最初是 Google 发布的,现在已经被多家大公司支持,例如 Microsoft, RedHat, IBM,Docker。
2.3.3 K8s 的著名优势特色
2.3.3.1 一个平台搞定所有
使用 Kubernetes,部署任何应用都是小菜一碟,只要应用可以打包进容器,Kubernetes 就一定能启动它。
不管什么语言什么框架写的应用(Java, Python, Node.js),Kubernetes 都可以在任何环境中安全的启动它,物 理服务器、虚拟机、云环境。
2.3.3.2 云环境无缝迁移
如果你有换云环境的需求,例如从 GCP 到 AWS,使用 Kubernetes 的话,你就不用有任何担心。
Kubernetes 完全兼容各种云服务提供商,例如 Google Cloud、Amazon、Microsoft Azure,还可以工作在 CloudStack, OpenStack, OVirt, Photon, VSphere。
2.3.3.3 高效的利用资源
看下图,左边,是4个虚拟机,黄色和蓝色部分是运行的应用,白色部分是未使用的内存和处理器资源。
Kubernetes 如果发现有节点工作不饱和,便会重新分配 pod,帮助我们节省开销,高效的利用内存、处理器等资源。
如果一个节点宕机了,Kubernetes 会自动重新创建之前运行在此节点上的 pod,在其他节点上运行。
2.3.3.4 开箱即用的自动缩放能力
网络、负载均衡、复制等特性,对于 Kubernetes 都是开箱即用的。
- pod 是无状态运行的,任何时候有 pod 宕了,立马会有其他 pod 接替它的工作,用户完全感觉不 到。
- 如果用户量突然暴增,现有的 pod 规模不足了,那么会自动创建出一批新的 pod,以适应当前的 需求。
- 反之亦然,当负载降下来的时候,Kubernetes 也会自动缩减 pod 的数量。
2.3.3.5 使 CI/CD 更加简单
你不必精通于 Chef 和 Ansible 这类工具,只需要对 CI 服务写个简单的脚本然后运行它,就会使用你的代码创建一个新的 pod,并部署到 Kubernetes 集群里面。
应用打包在容器中使其可以安全的运行在任何地方,例如你的 PC、一个云服务器,使得测试极其简单。
2.3.3.6 可靠性
Kubernetes 如此流行的一个重要原因是:应用会一直顺利运行,不会被 pod 或 节点的故障所中断。
如果出现故障,Kubernetes 会创建必要数量的应用镜像,并分配到健康的 pod 或节点中,直到系统恢复,而且用户不会感到任何不适。
2.4 核心概念
2.4.1 节点
从上面的图可以看出来,k8s 集群的节点有两个角色,分别为 Master 节点和 Node 节点,整个K8s 集群Master 和 Node 节点关系如下图所示:
2.4.1.1 Master 节点
Master 节点也称为控制节点,每个 k8s 集群都有一个 Master 节点负责整个集群的管理控制,我们上面介绍的 k8s 三大能力都是经过 Master 节点发起的,Master 节点包含了以下几个组件:
- API Server:提供了 HTTP Rest 接口的服务进程,所有资源对象的增、删、改、查等操作的唯一入 口;
- Controller Manager:k8s 集群所有资源对象的自动化控制中心;
- Scheduler:k8s 集群所有资源对象自动化调度控制中心;
- ETCD:k8s 集群注册服务发现中心,可以保存 k8s 集群中所有资源对象的数据
2.4.1.2 Node
Node 节点的作用是承接 Master 分配的工作负载,它主要有以下几个关键组件:
- kubelet:负责 Pod 对应容器的创建、启停等操作,与 Master 节点紧密协作;
- kube-porxy:实现 k8s 集群通信与负载均衡的组件。
从图上可看出,在 Node 节点上面,还需要一个容器运行环境,如果使用 Docker 技术栈,则还需要在 Node 节点上面安装 Docker Engine,专门负责该节点容器管理工作。
2.4.2 Pod
Pod 是 k8s 最重要而且是最基本的一个资源对象,它的结构如下:
从以上 Pod 的结构图可以看出,它其实是容器的一个上层包装结构,这也就是为什么 K8s 可以支持多种容器类型的原因,基于这方面, k8s 的定位就是一个编排与调度工具,而容器只是它调度的一个资源对象而已。
Pod 可包含多个容器在里面,每个 Pod 至少会有一个 Pause 容器,其它用户定义的容器都共享该Pause 容器,Pause 容器的主要作用是用于定义 Pod 的 ip 和 volume。
Pod 在 k8s 集群中的位置如下图所示:
2.4.3 Label
Label 在 k8s 中是一个非常核心的概念,我们可以将 Label 指定到对应的资源对象中
例如 Node、Pod、Replica Set、Service 等,一个资源可以绑定任意个 Label,k8s 通过 Label 可实现多维度的资源分组管理,后续可通过 Label Selector 查询和筛选拥有某些 Label 的资源对象,例如创建一个 Pod,给定一个 Label,workerid=123,后续可通过 workerid=123 删除拥有该标签的 Pod 资源。
2.4.4 Replica Set
Replica Set 目的是为了定义一个期望的场景,比如定义某种 Pod 的副本数量在任意时刻都处于Peplica Set 期望的值
假设 Replica Set 定义 Pod 的副本数目为:replicas=2,当该 Replica Set 提交给 Master 后,Master 会定期巡检该 Pod 在集群中的数目,如果发现该 Pod 挂掉了一个,Master 就会尝试依据Replica Set 设置的 Pod 模版创建 Pod,以维持 Pod 的数量与 Replica Set 预期的 Pod 数量相同。
通过 Replica Set,k8s 集群实现了用户应用的高可用性,而且大大减少了运维工作量。因此生产环境一般用 Deployment 或者 Replica Set 去控制 Pod 的生命周期和期望值,而不是直接单独创建 Pod。
类似 Replica Set 的还有 Deployment,它的内部实现也是通过 Replica Set 实现的,可以说
Deployment 是 Replica Set 的升级版,它们之间的 yaml 配置文件格式大部分都相同。
2.4.5 Service
Service 是 k8s 能够实现微服务集群的一个非常重要的概念
顾名思义,k8s 的 Service 就是我们平时所提及的微服务架构中的“微服务”,本文上面提及的 Pod、Replica Set 等都是为 Service 服务的资源, 如下图表示 Service、Pod、Replica Set 的关系
从上图可看出,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,而 Service 则是通过 Label Selector 实现关联与对接的,Replica Set 保证服务集群资源始终处于期望值。
以上只是一个微服务,通常来说一个应用项目会由多个不同业务能力而又彼此独立的微服务组成,多个微服务间组成了一个强大而又高可用的应用服务集群。
2.4.6 Namespace
Namespace 顾名思义是命名空间的意思,在 k8s 中主要用于实现资源隔离的目的
用户可根据不同项目创建不同的 Namespace,通过 k8s 将资源分配到不同 Namespace 中,即可实现不同项目的资源隔离
3. k8s 组件介绍
3.1 整体架构
下图清晰表明了 Kubernetes 的架构设计以及组件之间的通信协议。
下面是更抽象的一个视图
3.1.1 Master 架构
3.1.2 Node 架构
3.2 k8s部署组件介绍
我们把一个有效的 Kubernetes 部署称为集群。您可以将 Kubernetes 集群可视化为两个部分:
控制平面与计算设备(或称为节点)。每个节点都是其自己的 Linux环境,并且可以是物理机或虚拟机。每个节点都运行由若干容器组成的容器集。
3.2.1 K8s 集群架构图
以下 K8s 架构图显示了 Kubernetes 集群的各部分之间的联系:
3.2.2.1 控制平面
K8s 集群的神经中枢
让我们从 Kubernetes 集群的神经中枢(即控制平面)开始说起。在这里,我们可以找到用于控制集群的 Kubernetes 组件以及一些有关集群状态和配置的数据。这些核心 Kubernetes 组件负责处理重要的工作,以确保容器以足够的数量和所需的资源运行。
控制平面会一直与您的计算机保持联系。集群已被配置为以特定的方式运行,而控制平面要做的就是确保万无一失。
3.2.2.2 kube-apiserver
K8s 集群API,如果需要与您的 Kubernetes 集群进行交互,就要通过 API
Kubernetes API 是 Kubernetes 控制平面的前端,用于处理内部和外部请求。API 服务器会确定请求是否有效,如果有效,则对其进行处理。您可以通过 REST 调用、kubectl 命令行界面或其他命令行工具(例如 kubeadm)来访问 API。
3.2.2.3 kube-scheduler
K8s 调度程序,您的集群是否状况良好?如果需要新的容器,要将它们放在哪里?这些是
Kubernetes 调度程序所要关注的问题。
调度程序会考虑容器集的资源需求(例如 CPU 或内存)以及集群的运行状况。随后,它会将容器集安排到适当的计算节点。
3.2.2.4 kube-controller-manager
K8s 控制器,控制器负责实际运行集群,而 Kubernetes 控制器管理器则是将多个控制器功能合而为一
控制器用于查询调度程序,并确保有正确数量的容器集在运行。如果有容器集停止运行,另一个控制器会发现并做出响应。控制器会将服务连接至容器集,以便让请求前往正确的端点。还有一些控制器用于创建帐户和 API 访问令牌。
3.2.2.5 etcd
键值存储数据库
配置数据以及有关集群状态的信息位于 etcd(一个键值存储数据库)中。etcd 采用分布式、容错设计,被视为集群的最终事实来源。
3.2.3 k8s运行组件
3.2.3.1 k8s节点
Kubernetes 集群中至少需要一个计算节点,但通常会有多个计算节点。
容器集经过调度和编排后,就会在节点上运行。如果需要扩展集群的容量,那就要添加更多的节点。
3.2.3.2 容器集
容器集是 Kubernetes 对象模型中最小、最简单的单元。
它代表了应用的单个实例。每个容器集都由一个容器(或一系列紧密耦合的容器)以及若干控制容器运行方式的选件组成。容器集可以连接至持久存储,以运行有状态应用。
3.2.3.3 容器运行时引擎
为了运行容器,每个计算节点都有一个容器运行时引擎。
比如 Docker,但 Kubernetes 也支持其他符合开源容器运动(OCI)标准的运行时,例如 rkt 和CRI-O。
3.2.3.4 kubelet
每个计算节点中都包含一个 kubelet,这是一个与控制平面通信的微型应用。
kublet 可确保容器在容器集内运行。当控制平面需要在节点中执行某个操作时,kubelet 就会执行该操作。
3.2.3.5 kube-proxy
每个计算节点中还包含 kube-proxy,这是一个用于优化 Kubernetes 网络服务的网络代理。kube-proxy 负责处理集群内部或外部的网络通信——靠操作系统的数据包过滤层,或者自行转发流量。
3.2.4 k8s 存储组件
3.2.4.1 持久存储
除了管理运行应用的容器外,Kubernetes 还可以管理附加在集群上的应用数据。
Kubernetes 允许用户请求存储资源,而无需了解底层存储基础架构的详细信息。持久卷是集群(而非容器集)所特有的,因此其寿命可以超过容器集。
3.2.4.2 容器镜像仓库
Kubernetes 所依赖的容器镜像存储于容器镜像仓库中。
这个镜像仓库可以由您自己配置的,也可以由第三方提供。
3.2.4.3 底层基础架构
您可以自己决定具体在哪里运行 Kubernetes。
答案可以是裸机服务器、虚拟机、公共云提供商、私有云和混合云环境。Kubernetes 的一大优势就是它可以在许多不同类型的基础架构上运行。