Kubernetes 脱胎于 Google 的 Borg 系统,是一个功能强大的容器编排系统。Kubernetes 及其整个生态系统(工具、模块、插件等)均使用 Go 语言编写,从而构成一套面向 API、可高速运行的程序集合,这些程序文档精良、易于参与贡献或在其上构建应用程序。数据库
每一个开发、运维或感兴趣的读者都应熟悉它的一些核心概念,以便理解这个系统及其不一样的功能,以及为何几乎全部人都在使用它。segmentfault
在继续以前,我想提一下 Kubernetes 的几个顶级朋友(或竞争对手):ECS、Nomad 和 Mesos。ECS 是 AWS 本身的编排解决方案,最近它又推出了托管在 AWS 上的 Kubernetes 系统——EKS。二者都支持 FARGATE,让用户无须关心所运行的物理资源。安全
Kubernetes 毫无疑问是最大赢家,做为一个开源系统,三大主流云服务商都以托管的方式提供了这项功能。可是,它比其余几个产品都要来得复杂和混乱。Kubernetes 能够处理几乎任何类型的容器负载,也有不少技巧,但这并不意味着每一个人都应该使用它。其余解决方案或许也能知足某些公司的要求,例如,彻底部署在 AWS 上的互联网产品公司,使用 ECS 会比 Kubernetes 具备更佳的生产环境体验,是的,也好于 EKS。服务器
话虽如此,Kubernetes 的魔力在于:它能够部署在任何地方、它拥有一个活跃的社区,有数百个核心开发人员及数千个生态系统开源贡献者。它运行快速、具备创新性、模块化且面向 API,是一个对构建插件或服务很是友好的系统。网络
好了,闲话少说,开始咱们的旅程。app
Pod 是 Kubernetes 中最小的可互动单元。一个 Pod 能够由多个容器组成,这些容器共同部署在单个节点上造成一个单元。一个 Pod 具备一个 IP,该 IP 在其容器之间共享。
在微服务世界中,一个 Pod 能够是执行后台工做或服务请求的微服务的单个实例。运维
Node 是机器。它们是 Kubernetes 用于部署 Pod 的“裸机”(或虚拟机)。Node 为 Kubernetes 提供可用的集群资源用于以保持数据、运行做业、维护工做负载、建立网络路由等。模块化
Label 是 Kubernetes 及其最终用户用于过滤系统中类似资源的方式,也是资源与资源相互“访问”或关联的粘合剂。好比说,为 Deployment 打开端口的 Service。不管是监控、日志、调试或是测试,任何 Kubernetes 资源都应打上标签以供后续查验。例如,给系统中全部 Worker Pod 打上标签:app=worker,以后便可在 kubectl 或 Kubernetes API 中使用 --selector 字段对其进行选择。
Annotation 与 Label 很是类似,但一般用于以自由的字符串形式保存不一样对象的元数据,例如“更改缘由: 安全补丁升级”。微服务
做为编排系统,Kubernetes 控制着不一样工做负载的众多资源,负责管理 Pod、做业及全部须要通讯的物理资源的网络。为此,Kubernetes 使用了 ETCD。工具
ETCD 是 Kubernetes 的“内部”数据库,Master 经过它来获取全部资源的位置。Kubernetes 还为服务提供了实际的“服务发现”——全部 Pod 使用了一个自定义的 DNS 服务器,经过解析其余服务的名称以获取其 IP 地址和端口。它在 Kubernetes 集群中“开箱即用”,无须进行设置。
虽然 Pod 是一个物理性的运行任务,但一般使用单个实例是不够的。为了冗余并处理负载,出于某种缘由(好比“伸缩”)须要对 Pod 进行复制。为了实现负责扩展和复制的层,Kubernetes 使用了 ReplicaSet。这个层以副本的数量表示系统的指望状态,并在任意给定时刻保持该系统的当前状态。
这也是配置自动伸缩的所在,在系统高负载时建立额外的副本,并在再也不须要这些资源来支撑所运行的工做负载时进行缩容。
有时候,应用程序每一个节点须要的实例不超过一个。好比 FileBeat 这类日志收集器就是个很好的例子。为了从各个节点收集日志,其代理须要运行在全部节点上,但每一个节点只须要一个实例。Kubernetes 的 DaemonSet 便可用于建立这样的工做负载。
尽管多数微服务涉及的都是不可变的无状态应用程序,但也有例外。有状态的工做负载有赖于磁盘卷的可靠支持。虽然应用程序容器自己能够是不可变的,可使用更新的版本或更健康的实例来替代,可是全部副本仍是须要数据的持久化。StatefulSet 便是用于这类须要在整个生命周期内使用同一节点的应用程序的部署。
它还保留了它的“名称”:容器内的 hostname 以及整个集群中服务发现的名称。3 个 ZooKeeper 构成的 StatefulSet 能够被命名 zk-一、zk-2 及 zk-3,也能够扩展到更多的成员 zk-四、zk-5 等等…… StatefulSets 还负责管理 PersistentVolumeClaim(Pod 上链接的磁盘)。
Kubernetes 核心团队考虑了大部分使用编排系统的应用程序。虽然多数应用程序要求持续运行以同时处理服务器请求(好比 Web 服务器),但有时仍是须要生成一批做业并在其完成后进行清理。好比,一个迷你的无服务器环境。
为了在 Kubernetes 中实现这一点,可使用 Job 资源。正如其名,Job 的工做是生成容器来完成特定的工做,并在成功完成时销毁。举个例子,一组 Worker 从待处理和存储的数据队列中读取做业。一旦队列空了,就再也不须要这些 Worker 了,直到下个批次准备好。
若是你还不熟悉十二要素应用清单,请先行了解。现代应用程序的一个关键概念是无环境,并可经过注入的环境变量进行配置。应用程序应与其位置彻底无关。为了在 Kubernetes 中实现这个重要的概念,就有了 ConfigMap。实际上这是一个环境变量键值列表,它们会被传递给正在运行的工做负载以肯定不一样的运行时行为。在一样的范畴下,Secret 与正常的配置条目相似,只是会进行加密以防相似密钥、密码、证书等敏感信息的泄漏。
我我的认为 Hashicorp 的 Vault 是使用机密配置的最佳方案。请务必阅读一下我去年写的有关文章,文章讲述了将 Vault 做为生产环境一部分的缘由,以及个人一位同事写的另外一篇更技术性的文章。
一切看起来都很美好,Pod 能够正常运行,若是上层有 ReplicaSet,还能够根据负载进行伸缩。不过,你们蜂拥而来,为的是能用新版本快速替换应用程序。咱们想小规模地进行构建、测试和发布,以缩短反馈周期。使用 Deployments 便可持续地部署新软件,这是一组描述特定运行工做负载新需求的元数据。举个例子,发布新版本、错误修复,甚至是回滚(这是 Kubernetes 的另外一个内部选项)。
在 Kubernetes 中部署软件可以使用 2 个主要策略:
a. MaxAvailable——设置在部署新版本时可用的工做负载比例(或具体数量),100% 表示“我有 2 个容器,在部署时要保持 2 个存活以服务请求”;
b. MaxSurge——设置在当前存活容器的基础上部署的工做负载比例(或数量),100% 表示“我有 X 个容器,部署另外 X 个容器,而后开始滚动移除旧容器”。
Kubernetes 在存储之上添加了一层抽象。工做负载能够为不一样任务请求特定存储,甚至能够管理超过 Pod 生命周期的持久化。为简短起见,请阅读做者以前发布的关于 Kubernetes 存储的文章,特别重点看看为何它不能彻底解决相似数据库部署这样的数据持久性要求。
Kubernetes(如今仍然)是根据一些指导原则进行设计和开发的,构建在系统里的每一个功能、概念和想法都考虑了社区因素。此外,最终用户会被引导以某种方式使用该系统,但这不是强迫的;最佳实践也是公开的,但做为一个开源免费的系统,你彻底能够根据自身须要进行操做。
面向 API——系统每一个部分构建时经过优良的文档和可操做的 API 来实现可交互性。核心开发人员会确保最终用户能够进行更改、查询和更新,以避免将其阻挡在外或有不想要的过滤器。
欢迎包装工具——做为前一点的衍生产品,Kubernetes 对在其 API 之上构建的工具和包装器表示欢迎。做为一个原始平台,Kubernetes 是以一个很是可定制的方式进行构建的,以便他人使用,并进一步开发用于不一样用例的工具。有些工具已经变得很是有名并被普遍使用,好比 Spinnaker、Istio 等等。
声明性状态——鼓励用户在系统中使用声明性描述而非命令式描述。这意味着,系统的状态和组件最好被描述为在某种版本控制(如 Git)中管理的代码,以此避免手工修改形成的困扰。所以,Kubernetes 减小了灾难恢复的难度、更易于在团队之间分享并传递责任。
原文连接:https://medium.com/prodopsio/...
扫描下方二维码添加小助手,与 8000 位云原生爱好者讨论技术趋势,实战进阶!
进群暗号:公司-岗位-城市
搜索「阿里巴巴云原生公众号」获取更多K8s容器技术内容