条分缕析带你充分理解Kubernetes的各个细节与部分:它是什么,它如何解决容器编排问题,它包含哪些你必须掌握的关键对象,以及如何快速上手部署使用Kubernetes。前端
容器的好处不胜枚举:一致的运行时环境、节省磁盘空间、低开销、良好的隔离性,等等。了解完这些优点,您以及您的同事可能都开始跃跃欲试要把应用程序打包到容器中并准备运行它。而后忽然之间或许您会发现,容器运行起来以后有一些问题也接踵而来,您须要一种方法来管理全部正在运行的容器及其生命周期:它们如何相互链接,它们应该运行在什么硬件之上,它们如何获取数据存储,容器因各类缘由中止运行的话您该如何处理错误······nginx
这就是Kubernetes大显身手的地方了。后端
在本文中,咱们将了解Kubernetes是什么,它如何解决容器编排问题,它背后是由哪些理论支撑,如何将该理论直接与实际操做绑定,最终帮助您充分理解Kubernetes的各个细节与部分。设计模式
Kubernetes: 历史浏览器
Kubernetes,也被称为k8s(k... 8个字母...和s)或kube,是希腊语中的单词,意为州长、舵手或船长。拿真正的航海的情景来理解,大型船舶装载着大量现实生活的容器,而船长或舵手则是负责船舶的人。所以,在信息技术的语境下,Kubernetes就是Docker容器的船长、编排者。安全
Kubernetes最初是谷歌公司在内部使用的,基于谷歌运行容器15年的经验,Kubernetes于2014年开始做为Google的开源项目提供给社区。四年过去,Kubernetes飞速发展,下载及使用量惊人,被大量的中小型企业用户用于开发或生产环境,并已成为业界公认的容器编排管理的标准框架。网络
Kubernetes的发展势头架构
Kubernetes的增加态势惊人,在GitHub上拥有超过40,000颗星,在2018年拥有超过60,000个commit,而且比GitHub上的任何其余项目都有更多的pull request和issue。其增加背后的部分缘由是其不凡的可扩展性和强大的设计模式,这些咱们将在后文中进一步解读。您能够在此连接了解一些大型软件公司的Kubernetes应用案例:负载均衡
https://kubernetes.io/case-studies/框架
Kubernetes提供的服务
让咱们来看看是什么功能及特性让Kubernetes吸引到业界的如此关注。
Kubernetes的核心是以容器为中心的管理环境。它表明用户的工做负载来编排计算、网络和存储基础架构。这提供了平台即服务(PaaS)的简单性和基础架构即服务(IaaS)的灵活性,并实现了跨基础架构提供商的可移植性。Kubernetes不只仅是一个编排系统。实际上,它让用户再也不须要“编排”。“编排”的技术定义是“执行定义的工做流程”:首先执行A,而后运行B,而后运行C。而有了Kubernetes以后,Kubernetes由一组独立的、可组合的控制流程组成,这些流程可将当前状态持续推向所需状态。而你是如何从A进行到C的,在此可有可无。并且,用户也再也不须要集中控制,整个系统也变得更易于使用、功能更强大、可扩展性更佳。
Kubernetes的基本概念
要使用Kubernetes,您可使用Kubernetes API对象来描述集群的所需状态:您想要运行的应用程序或服务,它们使用的容器镜像、副本数量,您但愿提供的网络和磁盘资源等等。您能够经过使用Kubernetes API——kubectl(一般经过命令行界面)建立对象来设置所需的状态。您还能够直接使用Kubernetes API与集群交互,并设置或修改所需的状态。
设置完所需状态后,Kubernetes控制面板会让集群的当前状态与所需状态相匹配。为此,Kubernetes会自动执行各类任务,例如启动或从新启动容器、扩展给定应用程序的副本数量等等。
基本的Kubernetes对象包括: - 节点 - Pod - 服务 - 卷 - 命名空间
此外,Kubernetes包含许多称为controller的高级抽象。controller基于基本对象构建,并提供其余功能和便利的特性。它们包括:
ReplicaSet
Deployment
StatefulSet
DaemonSet
Job
下文中咱们会逐个介绍这些概念,而后再尝试一些动手练习。
节 点
节点( Node)是Kubernetes中的worker machine,之前称为minion。节点能够是虚拟机(VM)或物理机(具体取决于集群)。每一个节点都包含运行pod所需的服务,并由主组件管理。你能够这样理解节点:节点对于pod就像是Hypervisor对于虚拟机。
Pod
Pod是Kubernetes的基本构建块,它是您建立或部署的Kubernetes对象模型中最小和最简单的单元。一个Pod表明着一个部署单元:Kubernetes中的单个应用程序实例,可能包含单个容器或少许紧密组合并共享资源的容器。
Docker是Kubernetes Pod中最经常使用的容器运行时,但Pods也支持其余容器运行时。
Kubernetes集群中的Pod主要以两种方式使用:第一种是运行单个容器的Pod 。“one-container-per-Pod”模式是最多见的Kubernetes用例; 在这种状况下,您能够将Pod视为单个容器的打包,由Kubernetes而非容器来管理 Pods。第二种是运行多个须要协同工做的容器的Pod。一个Pod可能包含了一个应用程序,这个应用程序是由多个紧密耦合而且须要共享资源的容器组成的。这些共存的容器可能造成一个单一的内聚服务单元——一个容器负责从共享卷将文件公开,而另外一个单独的“sidecar”容器负责刷新或更新这些文件。该Pod 将这些容器和存储资源一块儿封装为一个可管理的实体。
Pod为其组成容器提供两种共享资源:网络和存储。
网络:每一个Pod都分配了一个惟一的IP地址。一个Pod中的全部容器都共享网络命名空间,包括IP地址和网络端口。Pod内的容器可使用localhost相互通讯。当Pod内的容器与Pod外的实体通讯时,它们必须协调如何使用共享网络资源(例如端口)。
存储:Pod能够指定一组共享存储卷。Pod中的全部容器均可以访问共享卷,容许这些容器共享数据。若是须要从新启动其中一个容器,卷还可让Pod中的持久数据一直保存着。
服 务
Kubernetes Pods不是不变的,它们被建立又被杀死后并不会重生。即便每一个Pod都有本身的IP地址,你也不能彻底期望它会随着时间推移却永不改变。这会产生一个问题,若是一组Pods(好比说后端)为Kubernetes集群中的另外一组Pods(好比说前端)提供了功能,那些前端pod如何可以与后端pod保持可靠的通讯?
这就是服务发挥做用的地方。
Kubernetes服务定义了一个逻辑集Pods和访问它们的策略(有时称为微服务),一般由Label Selector肯定。
例如,若是你有一个带有3个Pod的后端应用程序,那些pod是可替代的,前端并不关心它们使用哪一个后端。虽然Pods组成后端集的实际状况可能会发生变化,但前端客户端不该该知道这一点,也不须要跟踪后端列表自己。该Service抽象可实现这种分离。
对那些处于一样的Kubernetes集群中的应用,Kubernetes提供了一个简单的Endpoints API,每当服务中的一套Pods改变时,API就会相应地更新。对于集群外的应用程序,Kubernetes提供基于虚拟IP的桥接器,Services可将其重定向到后端Pods。
卷
容器中的磁盘文件是否是永久的,这会给运行在容器中的应用程序带来一些问题。首先,当容器崩溃时,它将由Kubernetes从新启动,但文件会丢失,由于容器老是以干净状态启动的。其次,当在一个pod中运行多个容器时,一般须要在这些容器之间共享文件。Kubernetes Volume就是来解决这两个问题的。
从本质上讲,卷只是一个目录,可能包含一些数据,在Pod中,它能够访问容器。该目录是如何造成的、支持它的介质是什么以及它的内容,是由所使用的特定卷类型决定的。
Kubernetes卷具备明确的生命周期,与建立它的Pod的生命周期相同。总而言之,一个卷超过了在Pod中运行的任何容器,而且在容器重启时保留了数据。一般,当一个Pod再也不存在时,卷也将不复存在。Kubernetes支持多种类型的卷,而且Pod能够同时使用任意数量的卷。
命名空间
Kubernetes支持由同一物理集群支持的多个虚拟集群。这些虚拟集群称为命名空间。
命名空间提供了名称范围。在一个命名空间内,每一个资源名称都须要是惟一的,不过跨命名空间时就没有这种要求了。
没有必要只是为了分离略有不一样的资源而使用多个命名空间,好比说同一软件的不一样版本:能够用标签来区分同一命名空间内的不一样资源。
ReplicaSet
ReplicaSet确保一次运行指定数量的pod副本。换句话说,ReplicaSet确保pod或同类pod组始终可用。可是,Deployment是一个更高级别的概念,它能够管理ReplicaSets,并为Pods提供声明性更新以及许多其余有用的功能。所以,除非您须要自定义更新编排或根本不须要更新,不然我建议您使用Deployments而不是直接使用ReplicaSets。
这实际上意味着您可能永远不须要直接操纵ReplicaSet对象,而是可使用Deployment做为替代。
Deployment
Deployment controller为Pods和ReplicaSets提供声明性更新。
您在Deployment对象中描述了所需状态,Deployment controller就将以受控速率将现阶段实际状态更改成所需状态。您能够定义Deployments来建立新的ReplicaSets,或删除现有的Deployments并使用新的Deployments来使用全部资源。
StatefulSets
StatefulSet用于管理有状态应用程序,它管理一组Pods的部署和扩展,并提供有关这些Pod 的排序和惟一性的保证。
StatefulSet的运行模式和controller相同。您能够在StatefulSet对象中定义所需的状态,StatefulSet controller就会进行各类必要的更新以从当前状态到达更新为所需状态。和Deployment相似,StatefulSet管理那些基于相同容器规范的Pods。与Deployment不一样的是,StatefulSet为每一个Pods保留一个粘性身份。这些Pods是根据相同的规范建立的,但不可互换:每一个都有一个永久的标识符,不论如何从新调度,这个标识都保持不变。
DaemonSet
DaemonSet确保全部(或某些)节点运行Pod的副本。随着节点添加到群集中,Pod会随之添加。当将节点从集群中删除后,Pods就成为了垃圾。此时,删除一个DaemonSet就将清理它所建立的Pods。
DaemonSet的一些典型用途有:
在每一个节点上运行集群存储daemon,例如glusterd、ceph。
在每一个节点上运行日志收集daemon,例如fluentd或logstash。
在每一个节点上运行节点监控daemon,例如Prometheus Node Exporter或collectd。
Job
job建立一个或多个pod,并确保在须要的时候成功终止指定数量的pod。Pods成功完成后,job会追踪顺利完成的状况。当达到指定数量时,job自己的任务就完成了。删除Job将清除它所建立的Pods。
一个简单的例子是建立一个Job对象,以即可靠地运行一个对象Pod。若是第一个Pod失败或被删除(例如因为节点硬件故障或节点重启),那么该Job对象将启动一个新Pod。
实际操做中的挑战
如今您已经了解了Kubernetes中的关键对象及概念了,很明显,想要玩转Kubernetes须要了解大量的信息。当你尝试使用Kubernetes时,可能会遇到以下挑战:
如何在不一样的基础架构中一致地部署?
如何跨多个集群(和名称空间)实现和管理访问控制?
如何与中央身份验证系统集成?
如何分区集群以更有效地使用资源?
如何管理多租户、多个专用和共享集群?
如何建立高可用集群?
如何跨集群/命名空间实施安全策略?
如何良好地进行监控,以确保有足够的可见性来检测和解决问题?
如何跟上Kubernetes快速发展的步伐?
这就是Rancher能够帮助您的地方。Rancher是一个100%开源的容器管理平台,用于在生产中运行Kubernetes。经过Rancher,你能够:
拥有易于使用的kubernetes配置和部署界面;
跨多个集群和云的基础架构管理;
自动部署最新的kubernetes版本;
工做负载、RBAC、政策和项目管理;
24x7企业级支持。
Rancher能够成为一个单一控制点,而您能够在多种、多个基础架构上运行多个Kubernetes集群:
上手Rancher和Kubernetes
如今让咱们看看如何在Rancher的帮助下轻松使用前文描述的Kubernetes对象。首先,您须要一个Rancher实例。按照本指南,在几分钟以内便可启动一个Rancher实例并使用它建立一个Kubernetes集群:
https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/deployment/quickstart-manual-setup/
启动集群后,您应该在Rancher中看到Kubernetes集群的资源:
要从第一个Kubernetes对象——节点开始,请单击顶部菜单上的Nodes。你应该能够组成了你的Kubernetes集群的Nodes的总体状况:
在那里,您还能够看到已从Kubernetes集群部署到每一个节点的pod的数量。这些pod由Kubernetes和Rancher内部系统使用。一般状况下你不须要处理那些。
下面让咱们继续Pod的例子。要作到这一点,转到Kubernetes集群的Default项目,而后进入Workloads选项卡。下面让咱们部署一个工做负载。点击Deploy并将Name和Docker image设置为nginx,剩下的一切都使用默认值,而后点击Launch。
建立后,Workloads选项卡会显示nginx工做负载。
若是单击nginx工做负载,您将会看到Rancher实际建立了一个Deployment,就像Kubernetes推荐的那样用来管理ReplicaSet,您还将看到该ReplicaSet建立的Pod:
如今你有一个Deployment,它将确保咱们所需的状态在集群中正确显示。如今,点击Scale附近+号,将此Workload扩容到3。一旦你这样作,你应该能当即看到另外2个Pods被建立出来,另外还多了2个ReplicaSet来缩放事件。使用Pod右侧菜单,尝试删除其中一个pod,并注意ReplicaSet是如何从新建立它以匹配所需状态的。
如今,您的应用程序已启动并运行,而且已经扩展到3个实例。下一个问题是,您如何访问它?在这里,咱们将尝试使用下一个Kubernetes对象——服务。为了暴露咱们的nginx工做负载,咱们须要先编辑它,从Workload右侧菜单中选择Edit。您将看到Deploy Workload页面,且已填好了您的nginx工做负载的详细信息:
请注意,如今您有3个pod在Scalable Deployment旁边,可是当您启动时,默认值为1。这是由于你的扩展工做刚完成不久。
如今单击Add Port,并按以下所示填充值:
将Publish the container port值设置为80;
Protocol仍为TCP;
将As a值设置为Layer-4 Load Balancer;
将On listening port值设置为80。
而后自信地点击Upgrade吧!这将在您的云提供商中建立一个外部负载均衡器,并将流量引至您的Kubernetes集群内的nginx Pods中。要对此进行测试,请再次访问nginx工做负载概述页面,如今您应该看到Endpoints旁的80/tcp连接:
若是点击80/tcp,它会导向您刚刚建立的负载均衡器的外部IP,而且向您展现一个默认的nginx页面,确认一切都按预期正常工做。
至此,你已经搞定了上半篇文章中介绍的大多数Kubernetes对象。你能够在Rancher中好好玩玩卷和命名空间,相信您必定能很快掌握如何经过Rancher更简单快捷地使用它们。至于StatefulSet、DaemonSet和Job,它们和Deployments很是相似,你一样能够在Workloads选项卡中经过选择Workload type来建立它们。
结 语
让咱们回顾一下你在上面的动手练习中所作的一切。你已经建立了咱们描述的大多数Kubernetes对象:
一、最开始,你在Rancher中建立了kubernetes集群;
二、而后你浏览了集群的Nodes;
三、你创造了一个Workload;
四、你已经看到了一个Workload实际上建立了3个独立的Kubernetes对象:一个Deployment管理着 ReplicaSet,同时按需保持着所需数量的Pods正常运行;
五、在那以后你扩展了你的Deployment数量,并观察它是如何改变了ReplicaSet并相应地扩展Pods的数量的;
六、最后你建立了一个Load Balancer类型的Service类型,用于平衡Pods之间的客户端请求。
全部这些均可以经过Rancher轻松完成,您只需进行一些点击的操做,无需在本地安装任何软件来复制身份验证配置或在终端中运行命令行。您只需一个浏览器,玩转Kubernetes唾手可得。