精通Kubernetes

978-7-115-53611-2
作者: [美]吉吉·塞凡(Gigi Sayfan)
译者: 任瑾睿胡久林
编辑: 陈聪聪

图书目录:

详情

本书通过理论与实践相结合,全方位地介绍Kubernetes这一容器编排的理想工具。本书共14章,涉及的主题包括理解Kubernetes架构,创建Kubernetes集群,监控、日志记录和故障排除,高可用性和可靠性,配置Kubernetes安全、限制和账户,使用关键Kubernetes资源,管理Kubernetes存储,使用Kubernetes运行有状态应用程序,滚动更新、可伸缩性和配额,高级Kubernetes网络,在云平台和集群联邦中运行Kubernetes,自定义Kubernetes API和插件,操作Kubernetes软件包管理器以及Kubernetes的未来。本书综合考虑不同环境和用例,使读者了解如何创建大型系统并将其部署在Kubernetes上。在各章节主题中,读者提供了丰富的实践案例分析,娓娓道来,引人入胜。 本书可以作为Kubernetes的实践参考手册,聚焦于设计和管理Kubernetes集群,为开发人员、运维工程师详细介绍了Kubernetes所提供的功能和服务。

图书摘要

版权信息

书名:精通Kubernetes

ISBN:978-7-115-53611-2

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    [美] 吉吉·塞凡(Gigi Sayfan)

译    任瑾睿 胡久林

责任编辑 陈聪聪

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


Copyright © Packt Publishing 2018. First published in the English language under the title Mastering Kubernetes.

本书由英国 Packt Publishing 公司授权人民邮电出版社有限公司出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。

版权所有,侵权必究。


本书通过理论与实践相结合,全方位地介绍Kubernetes这一容器编排的理想工具。本书共14章,涉及的主题包括理解Kubernetes架构,创建Kubernetes集群,监控、日志记录和故障排除,高可用性和可靠性,配置Kubernetes安全、限制和账户,使用关键Kubernetes资源,管理Kubernetes存储,使用Kubernetes运行有状态应用程序,滚动更新、可伸缩性和配额,高级Kubernetes网络,在云平台和集群联邦中运行Kubernetes,自定义Kubernetes API和插件,操作Kubernetes软件包管理器以及Kubernetes的未来。本书综合考虑不同环境和用例,使读者了解如何创建大型系统并将其部署在Kubernetes上。在各章节主题中,读者提供了丰富的实践案例分析,娓娓道来,引人入胜。

本书可以作为Kubernetes的实践参考手册,聚焦于设计和管理Kubernetes集群,为开发人员、运维工程师详细介绍了Kubernetes所提供的功能和服务。


吉吉·塞凡(Gigi Sayfan)是Helix的软件架构师,Helix是一家生物信息学和基因组学的创业公司。他已有20多年的软件开发经验,涉及即时通信、变形、芯片制造过程控制、游戏控制台嵌入式多媒体应用、脑启发机器学习、定制浏览器开发、3D分布式游戏平台的Web服务以及物联网传感器和虚拟现实等多个领域。

他使用多种编程语言在多种操作系统中编写代码,编程语言诸如Go、Python、C、C++、C#、Java、Delphi、JavaScript,甚至Cobol和PowerBuilder;操作系统包括Windows(3.11~7)、Linux、macOS、嵌入式Lynx;另外,还有Sony PlayStation游戏机等。他的技术专长包括数据库、底层网络、分布式系统、非正统的用户界面和一般软件开发生命周期。


雅库布·帕夫利克(Jakub Pavlik)是TCP Cloud的联合创始人、前CTO和首席架构师。TCP Cloud于2016年被Mirantis收购。Jakub和他的团队在基于OpenStack-Salt和OpenContrail项目的IaaS云平台从事了多年研发工作,这些云平台为全球服务提供商提供部署和运营服务。他的公司TCP Cloud凭借其架构成就和操作能力,被致力于OpenStack的Mirantis收购。

目前,他正与其他专业团队合作并担任产品工程总监,为NFV/SDN、IoT以及基于Kubernetes、容器化的OpenStack和OpenContrail的大型数据用例开发一个新的Mirantis云平台。他同时也是OpenContrail咨询委员会的成员。

他还热衷于Linux操作系统、冰球和电影,并且十分爱他的妻子哈努尔卡。


本书翻译历时5个多月,为了尽可能地做到技术词汇的统一、贴近中文,译者们可下了一番功夫。其间译者咨询了一些专业人士,在搜索引擎中查阅了大量的博客,关注了中文社区较长时间等。

“云提供商”和“云供应商”:两种中文说法都存在,并且好像都没有什么大的区别。本书采用了“云提供商”。

“注释”和“注解”:一部分人将Annotation翻译为“注释”,从Annotation的定义中可以发现,注解可使任意元数据与Kubernetes对象关联,而且其常以JSON对象等配置形式出现在命令行或者代码中。考虑到开发中注释为一种对代码的说明描述,而注解在Java等编程语言中是一种标记,故此处翻译为注解。

“Bare Metal”:本书翻译为裸金属,裸金属与物理机、裸机并不是一回事,它既不是虚拟机,也不是物理机,而是一个兼具虚拟机和物理机优势的产品。

上述只是3个举例,读者可以根据自己的习惯进行阅读,请读者理解。


参与本次翻译的一共有两位成员。其中胡久林负责第5~11章的翻译,任瑾睿负责序、第1~4章和第12~14章的翻译。译者尽量做到充分沟通,互相审阅,由胡久林负责统稿汇总。

有读者评价Mastering Kubernetes这本英文原书的时候,提到Mastering应该改为Knowing。我对本书的评价是结合实践,浅显易懂。通俗易懂对一本书来说,并不是一件坏事。译者认为,技术图书不一定要编著得高深莫测。经过十年计算机领域的求学和工作后,译者对技术最大的感慨就是授人以鱼不如授人以渔。译者认为如何加强逻辑训练,如何尽可能全面地考虑问题,如何一步一步地结合现有的技术和产品设计出自己的大型系统是极其重要的。译者认为本书的益处就是潜移默化地提升了读者这方面的能力。

十分感谢获得这次机会参与到翻译技术图书的工作中,衷心地祝愿读者,能像本书的原作者说的那样,在阅读完本书之后,与Kubernetes一起创造惊人的东西!

译者对技术一直抱有敬畏之心,当得知有机会翻译Mastering Kubernetes这本书时一直诚惶诚恐。技术是神圣的,图书更是带领读者走向神圣的钥匙。译者一直担心因自己专业知识的不足、文字功底不够扎实不能完美地诠释这本书。如果读者发现本书翻译错误或专业词汇失当,请随时发邮件至tohujiulin@126.com与译者联系,亦可访问译者的博客进行反馈。


本书聚焦于设计和管理Kubernetes集群,详细地介绍了Kubernetes为开发人员、DevOps工程师以及需要协作使用容器编排来构建和演进复杂分布式系统的开发人员所能提供的所有功能和服务。本书综合考虑不同的环境和用例,使读者了解如何创建大型系统并将其部署在Kubernetes上。本书将带领读者深入了解如何组织Kubernetes、它对特定资源的适宜场景,以及如何以有效的方式实现和配置集群。通过实际操作任务和练习,读者将深入了解Kubernetes体系结构,如何安装、操作和升级集群,以及如何使用最佳实践部署软件。

第1章,理解Kubernetes架构:简要介绍了本书的主要目标和分布式系统中的容器编排。它帮助读者理解构建Kubernetes的基本指导原则,并涉及了设计细节。

第2章,创建Kubernetes集群:这是一个实践性的章节。在本章中读者会使用不同的工具创建多个Kubernetes集群,涉及从快速测试集群到成熟的产业强度集群所要用到的各类工具。

第3章,监控、日志记录和故障排除:阐述从Kubernetes集群进行事件监控、日志记录事件和度量收集的方法,使读者识别和分析集群行为中的模式。

第4章,高可用性和可靠性:介绍高可用性架构的最佳实践。在考虑成本/性能权衡、实时升级和性能瓶颈的情况下,Kubernetes可以通过各种方式配置实现高可用性。

第5章,配置Kubernetes安全、限制和账户:带领读者了解如何通过SSL API、附加组件和Docker身份验证等保证Kubernetes生产环境的安全性。本章探讨了各种安全主题,深入研究了准入控制、外部授权系统的接口和命名空间。

第6章,使用关键Kubernetes资源:在本章中,读者将参与基于微服务的复杂系统的设计,包括Kubernetes资源的演练部署,其中每个资源将映射到应用程序结构或配置中的对应部分。

第7章,管理Kubernetes存储:介绍Kubernetes中的持久化存储卷。读者将能够通过Kubernetes中不同的存储类型,映射到特定的使用案例。

第8章,使用Kubernetes运行有状态的应用程序:讨论了用户在运行遗留的整体有状态应用程序和服务(如数据库、消息队列等)时将面临的问题。本章还介绍了集群有状态应用的环境共享变量和DNS记录。

第9章,滚动更新、可伸缩性和配额:介绍Kubernetes的高级特性,如Pod水平自动伸缩、集群规模和滚动更新。本章也涵盖了Kubernetes规模测试和压力测试工具。

第10章,高级Kubernetes网络:介绍第三方SDN插件的容器网络接口,本章也详细介绍了CNI插件、负载均衡和网络安全策略。

第11章,在云平台和集群联邦中运行Kubernetes:介绍如何在几个特定的平台(裸金属、AWS、GCE)上部署生产环境中的Kubernetes集群,也指明了现实世界中集群联邦的必要性。

第12章,自定义Kubernetes API和插件:介绍如何在API级别使用Kubernetes,以及开发第三方资源的用例和动机,还介绍了Kubernetes支持的插件类型以及如何开发自定义插件。

第13章,操作Kubernetes软件包管理器:介绍如何以打包形式处理Kubernetes应用程序。本章讨论了如何查找和安装现有的Helm包,以及如何自行编写Helm Chart。

第14章,Kubernetes的未来:着眼于未来,展望了Kubernetes的发展路线和发展趋势,以及它在容器编排场景中的地位,同时也与其竞争对手进行了比较。

为了同步实现每一章中的示例,读者需要在机器上安装Docker和Kubernetes的最新版本,理想情况下是Kubernetes 1.6。如果读者的操作系统是Windows 10专业版,最好启用系统管理程序模式,否则需要安装VirtualBox虚拟机并使用Linux客户操作系统。

本书面向那些已经具备Kubernetes的中级知识,并想要掌握其高级特性的系统管理员和开发人员。读者也应该具备基本的网络知识。本书作为进阶图书,为读者指明了掌握Kubernetes的学习路径。


本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。

本书提供如下资源:

要获得以上配套资源,请在异步社区本书页面中单击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果您所在的学校、培训机构或企业想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https:// www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。

异步社区

微信服务号


Kubernetes是拥有大量代码和功能的大型开源项目。读者可能阅读过Kubernetes的相关文章,或在其他项目中涉足这一领域,甚至在工作中使用过Kubernetes。但若想深入理解并有效使用Kubernetes,将其更好地应用于实践,则需要对其有更深入的了解。本章将构建Kubernetes的基本框架,首先,我们将理解容器编排(Container Orchestration)的含义;接着解释几个与Kubernetes相关的重要概念,这些概念将贯穿于全书;之后,深入介绍Kubernetes的体系架构,了解如何将Kubernetes的所有功能提供给用户;紧接着将介绍Kubernetes支持的各种运行时和容器引擎(Docker便是其中之一);最后,对Kubernetes在全连续集成(Full Continuous Integration)和部署管道(Deployment Pipeline)中的作用进行探讨。

本章将重点介绍以下几个方面:容器编排、Kubernetes适用条件、Kubernetes设计原理和体系结构以及Kubernetes支持的不同运行时环境。读者将熟悉开源仓库的整体结构,并为解决其余问题打好基础。

Kubernetes的主要功能是容器编排,是指确保所有容器都按照计划运行在物理机或虚拟机上。这些容器在部署环境和集群配置的约束下被打包执行大量工作负载。此外,Kubernetes必须密切关注所有运行中的容器,替换运行中止、无响应或其他非正常状态的容器。后续章节将会介绍Kubernetes的更多功能,本节将重点介绍容器及其编排。

硬件贯穿于容器编排的始终。运行工作负载需要一些真正的硬件配置,包括具有计算能力(CPU或核心)、内存和一些本地持久存储(机械硬盘或SSD)的实体物理机。此外,需要一些共享的持久存储,并使用网络连接所有物理机,以便于其互相查找和信息互通。此时,可在物理机上运行多个虚拟机或单纯保持裸金属状态。Kubernetes可部署在实体硬件或虚拟机集群上,同时也可以直接在实体硬件或虚拟机上管理容器。理论上,一个Kubernetes集群可以由物理机和虚拟机组合而成,但这并不常见。

容器是封装微服务的理想选择,因为它们不仅为微服务提供隔离,并且非常轻量,且在部署多个微服务时不会像使用虚拟机时那样产生大量开销。这使得容器非常适合于云部署,因为为每个微服务分配整个虚拟机的成本非常高。

现在主要的云提供商(如AWS、GCE和Azure)都提供容器托管服务,其中一些便是基于Kubernetes(如Google的GKE);另外诸如Microsoft Azure的容器服务,则是基于Apache Mesos等其他解决方案。此外,AWS将ECS(EC2上的容器服务)作为其自有的编排解决方案。Kubernetes的强大之处在于,它可以部署在上述这些云服务器上。Kubernetes有一个云提供商接口,允许任何云提供商执行并无缝集成Kubernetes。

过去系统规模很小,每个服务器都有一个名字。开发人员和用户确切地知道每台机器上运行的是什么软件。我工作过的许多公司都进行过数日讨论,来决定服务器的命名主题。例如,作曲家和希腊神话人物是受欢迎的选择。开发人员像对待自己挚爱的宠物一样对待服务器。如果一台服务器发生故障,这将是重大的危机,所有人都需投入全部精力完成这3件事情:更换一台新的服务器;确认发生故障的服务器上还运行着哪些数据;如何让这些数据在新服务器上运行。如果发生故障的服务器存储了一些重要的数据,那只能寄希望于备份数据和数据恢复。

显然,这种方法并不合适,当有几十个甚至上百个服务器时,必须像对待牲畜一样对待它们,此时需考虑的是集体而非个体。或许此时构建机器时仍需要像对待宠物一样处理,但对于网络服务器来讲,只能像对待牲畜一样去处理。

Kubernetes把这一方法推向极致,它承担了将容器分配给特定机器的全部任务。无须花费大量时间与各个机器(节点)交互。这对于无状态工作负载来说是最好的。对于有状态应用程序,情况稍有不同,但Kubernetes提供了一个名为StatefulSet的解决方案,我们接下来将对其进行讨论。

在本节中,讲述了容器编排的概念,讨论了主机(物理机或虚拟机)和容器之间的关系,以及在云端运行容器的优势,最后以牲畜和宠物作为类比探讨服务器的运行模式。1.2节将进入Kubernetes的世界,了解与之相关的概念和术语。

本节将简要介绍许多与Kubernetes相关的重要概念,并提供一些案例来说明这些概念的重要性和相互间的关系,以便熟悉这些术语和概念。接着,介绍如何将这些概念编排在一起以实现令人敬畏的效果。读者可将其中的许多概念视为构建块。一些概念被视作一个Kubernetes组件来执行,如节点和主节点。这些组件处于不同的抽象级,这将在1.5节中进行详细讨论。

图1.1是著名的Kubernetes架构。

图1.1 Kubernetes架构

集群是主机存储和网络资源的集合,Kubernetes使用集群来运行组成系统的各种工作负载。一个完整的系统可以由多个集群组成。之后会详细讨论集群联邦的高级用例。

节点是单个主机,它可以是物理机或虚拟机,职责是运行Pod。每个Kubernetes节点运行多个Kubernetes组件,如Kuberlet和Kube代理。节点由Kubernetes主控制器管理,这些节点类似于Kubernetes的工蜂,肩负重担,过去它们被称为下属(Minion)。如果读者曾阅读过以往的文献资料,请不要被混淆,下属即指节点。

主节点是Kubernetes的控制面板,由几个组件组成,包含API服务器、调度器和控制器管理器。主节点负责节点在全局、集群水平的调度和事件处理。通常,所有的主控制器组件都设置在一个单一主机上,在考虑到高可用性场景或大型集群时,会倾向于采用多个主节点。在第4章中将详细说明高可用性集群。

Pod是Kubernetes的工作单元,每个Pod包含一个或多个容器,Pod通常在同一台机器上运行并一起调度。Pod中的所有容器具有相同的IP地址和端口空间,它们可通过本地主机或标准进程进行通信。此外,Pod中的所有容器都可以访问承载于Pod的节点上的本地共享存储,共享存储会存在于每个容器上。Pod是Kubernetes的重要特征,通过作为运行于多个进程的主Docker应用程序的超级管理员,可以实现在单个Docker容器中运行多个应用程序,但出于以下几点,并不鼓励这种做法。

对于相互依赖且需要在同一主机上协作以实现其目标的容器组,Pod提供了很好的解决方案。切记,Pod被认为是临时、可替代的实体,需要的话可以被丢弃和替换,Pod可破坏任何Pod存储。每个Pod都有一个唯一的ID(UID),因此,区分它们仍是可实现的。

标签是用来组合对象集合(通常是Pod)的键值对。这对于其他几个概念非常重要,例如副本控制器、副本集以及需要在对象动态组上进行操作、标识组成员的服务。对象和标签之间存在N×N的关系,每个对象可以具有多个标签,并且每个标签可以应用于不同的对象。标签的设计有一定的限制,对象上的每个标签都必须且有唯一密钥,标签密钥必须遵守严格的语法。它的语法包含两个部分:前缀和名称。前缀是可选的,如果它存在,则通过前斜杠(/)与名称分离,并且必须是有效的DNS子域,前缀最多包含253个字符。名称是强制的,最多包含63个字符。名称必须以字母、数字、字符(a~z、A~Z、0~9)开头和结尾,并且只包含字母、数字、字符、点、破折号和下划线。值的规则与名称相同。需注意的是,标签只用于标识对象,而不会将任何元数据附加到对象中。这便是注解的目的(参见1.2.6节)。

注解可使任意元数据与Kubernetes对象关联。Kubernetes只存储注解并使其元数据可用。与标签不同的是,它对字符类型和大小没有严格要求。复杂的系统通常需要这样的元数据,而Kubernetes可识别这样的需求并提供开箱即用的元数据,这样用户则不必提取自己单独的元数据存储进行映射。

这里已涵盖了大部分Kubernetes的概念,也对其进行了简要概括。在1.2.7节中,将从其设计动机、内部结构与实现、源代码方面继续研究Kubernetes的体系结构。

标签选择器根据标签选择对象,基于相等的选择器指定键名和值。基于值的等式或不等式,它有两个运算符:=(或==)和!=,代码如下。

role = webserver

这将选择所有具有该标签键和值的对象。

标签选择器可以用多个逗号分隔,代码如下。

role = webserver, application != foo

基于集合的选择器扩展性能并允许基于多个值进行选择,代码如下。

role in (webserver, backend)

副本控制器和副本集管理由标签选择器标识的一组Pod,确保一定数量的Pod始终运行。它们之间的主要区别在于,副本控制器通过名称匹配来测试成员资格,副本集则通过基于集合的选择器。副本集更新,并被指定为下一代副本控制器。它还处于测试阶段,且在编写时不能被所有工具支持。但也许读者在读到这本书时,它已完全成熟。

Kubernetes会保证在副本控制器或副本集中保持相同数量的Pod运行。在因主机节点或Pod本身的问题而导致数量下滑时,Kubernetes将启动新的用例。需注意的是,如果人为启动Pod并超过指定数量,则副本控制器将结束多余Pod的进程。

副本控制器曾经是许多工作流的中心,例如滚动更新和运行一次性作业。随着Kubernetes的发展,它引入了对很多类似工作流的直接支持,例如Deployment、Job和DaemonSet等专用对象。这些将在下面的章节中提到。

服务向用户或其他服务暴露一些功能。它们通常包含一组Pod,由标签进行区分。服务可提供对外部资源的访问路径,或者直接控制虚拟IP的Pod。本地Kubernetes服务器通过便捷的端点暴露功能。需注意的是,服务在第3层(TCP/UDP)进行。Kubernetes 1.2添加了入口对象,该对象提供对HTTP对象的访问,后续会对这一部分展开详谈。服务可通过以下两种机制之一被发布或发现:DNS或环境变量。服务可以由Kubernetes均衡负载。但当服务使用外部资源或需要特殊处理时,开发人员可自行管理和均衡负载。

与IP地址、虚拟IP地址和端口空间相关的细节,都将在之后的章节中深入讨论。

Pod上的存储是临时的,会随Pod一起消失。如果只是在节点的容器间交换数据,这已经足够,但有时数据需要在Pod上存储更长的时间,或在Pod间传递数据,存储卷的概念便支持了这种需求。需注意的是,虽然Docker中也有存储卷的概念,但它仍比较有限(尽管功能越来越强大)。Kubernetes使用自有的存储卷,并且支持额外的容器类型(如rkt),因此在根本上它独立于Docker的存储卷。

存储卷类型有多种,Kubernetes目前直接支持所有类型。如果可添加间接层,则抽象存储卷插件也许会被开发。emptyDir存储卷类型会在每个容器上安装一个卷,该卷会默认在宿主机器的任意可用容器上备份。如果需要,可以请求存储介质。当Pod由于任何原因终止时,此存储会被删除。对于特定的云环境、各种联网的文件系统,甚至Git存储库,都有许多存储卷类型。一个比较有意思的存储卷类型是PersistentDiskClaim,它概括了部分细节,并在开发者的云提供商环境中使用默认的持久存储。

如果关注Pod上的数据,则可以使用持久化存储。但若需要Kubernetes管理诸如Kubernetes或MySQL Galera分布式数据存储库,便不能用常规的Pod和服务来模拟它,因为这些集群存储使数据分布在唯一的节点上。说回有状态服务集,前文讨论了宠物与牲畜的关系,以及牲畜是如何管理和执行的。有状态服务集介于二者之间。有状态服务集能够确保给定数量的具有唯一标识的宠物在任意给定时间运行(类似于复制控制器)。宠物具有以下特性。

有状态服务集可以帮助对等体发现、添加或移除宠物。

密钥对象是包含敏感信息的小型对象,如凭据和令牌。它们以明文的形式存储在etcd中,可通过Kubernetes API服务器访问,并在需要访问时作为文件装入Pod中(使用负载于常规容量上的专用密钥对象容量)。相同的密钥对象可被安装到多个Pod中。Kubernetes本身已为它的组件加密,开发者也可以创造自有密钥对象。另一种方法是使用密钥对象作为环境变量。需注意的是,为获得更好的安全性,在预制密钥对象的情况下,Pod中的密钥对象一般存储于tmpfs内存中。

Kubernetes中的每个对象都由UID和名称标识,该名称用于引用API调用中的对象。名称应不超过253个字符,并使用小写字母数字字符、下划线(_)和圆点(.)。如果删除对象,则可以创建与已删除对象具有相同名称的另一对象,但UID在集群生命周期中必须是唯一的。UID由Kubernetes生成,因此无须担心其重复。

命名空间是一个虚拟集群。由命名空间分隔的多个虚拟集群可组成一个单独的物理集群。每个虚拟集群与其他虚拟集群完全隔离,它们只能通过公共接口交换信息。需注意的是,节点对象和持久化存储卷不存在于命名空间中。Kubernetes可以调度来自不同命名空间的Pod在同一节点运行。同样,来自不同命名空间的Pod可以使用相同的持久存储。

在使用命名空间时,必须考虑网络策略和资源配额,以确保物理集群资源的正确访问和分配。

Kubernetes有非常宏大的目标,它致力于管理并简化跨环境和云提供商的分布式系统的编排、部署和管理。它提供了许多功能和服务,这些功能和服务应当适应于各种情境,并不断衍化和保持足够简单以供大部分用户使用。这是一个艰巨的任务。Kubernetes通过清晰的排布、高水平的设计和成熟的架构来实现这一点,该架构同时促进了系统的扩展性和灵活性。Kubernetes的许多部分仍是硬编码或环境敏感的,但它们会被逐渐分解为插件,并保持内核的通用性和概括性。在本节中,将对Kubernetes层层解剖,首先介绍各种分布式系统设计模式以及Kubernetes如何对其进行支持;然后介绍Kubernetes外层,即它的API集;接下来会介绍组成Kubernetes的实际组件;最后,对源代码树进行简要介绍,以对Kubernetes的结构进行进一步了解。

在本节的最后,读者将对Kubernetes的架构、执行以及其部分设计决策有深入的理解。

用托尔斯泰在《安娜·卡列尼娜》中的一句话来形容幸福的家庭(工作的分布式系统)都是相似的。这意味着,所有设计良好的分布式系统都必须遵循最佳实践和原则,以使其功能正常运行。Kubernetes不仅是一个管理系统,它同时还可应用这些最佳实践为开发者和管理员提供高水平的服务。下面将介绍几种设计模式。

1.边车模式

边车模式除主应用容器之外,还在Pod中共同定位另一个容器。应用容器并不知道边车容器,只是单纯执行自己的任务。中央日志代理(Central Logging Agent)就是一个很好的例子。主容器只将日志记录到stdout,但边车容器会将所有日志发送到一个中央日志服务,这些日志将在此处聚合整个系统的日志。使用边车容器相较于将中央日志添加到主应用容器有巨大的优势,应用不再受到中央日志的负担,如果要升级或更改中央日志记录策略或切换到新的提供商,只需更新并部署边车容器,应用容器并没有任何改变,因此不会由于意外情况而遭到破坏。

2.外交官模式

外交官模式是指将远程服务当作本地服务,并使其强制执行部分策略。外交官模式的一个很好的例子是,如果有一个Redis集群,该集群中一个主机用于编写,其余副本用于读取,则本地外交官容器可作为代理,并将Redis暴露给本地主机上的主应用容器。主应用容器简单地连接到localhost:6379(Redis缺省端口)上的Redis,但是它其实只是连接到在相同Pod中运行的外交官容器,该容器过滤请求,将编写请求发送到真正的Redis主机,并将读取请求随机发送到其中一个读取副本上,与挎斗模式类似,主应用在这期间并不了解运行过程。当测试真正的本地Redis集群时,这会有很大的帮助。此外,如果Redis集群配置发生改变,则只需要修改外交官容器,主应用同样不了解这一运行过程。

3.适配器模式

适配器模式是关于主应用容器的标准化输出。逐步推出的服务可能会面临如下问题:服务可能会生成不符合先前版本的格式报表,而其他使用该输出的服务和应用还未升级。适配器容器可以与新的应用容器共同部署在同一Pod上,并将其输出与旧版本相匹配,直到所有的用户都被升级。适配器容器与主应用程序容器共享文件系统,以此监控本地文件系统,每当新应用写入某个文件时,适配器容器将立即进行适配。

4.多节点模式

单节点模式都是直接由Kubernetes通过Pod直接进行支持的。而多节点模式并不被直接支持,例如负责人选举、工作队列和分散收集等,但使用标准接口组合Pod可实现Kubernetes支持。

若想了解一个系统的功能及其提供的服务,需要关注它的API。API为使用该系统的用户提供了一个全局图。Kubernetes从多角度为开发者提供多组REST API。有些API需通过工具使用,有些则可以被开发者直接使用。API的一个重要方面在于它们也在不断地发展,Kubernetes开发者通过尝试扩展(向现有对象添加新对象和新字段),避免重命名或删除现有对象和字段来保持其可管理性。此外,所有API端点都是版本化的,通常也包含Alpha或Beta记法。代码如下。

/api/v1
/api/v2alpha1

通过基于客户端库的kubectl CLI,或者直接调用REST API,可以访问API。下面的章节会对认证和授权机制进行详细介绍。由此,读者可对API有初步的认识。

这是Kubernetes的主要API,它非常庞大。前文所讲的所有概念以及许多辅助概念,都有相应的API对象和运算。若有正确的权限,则可列出、获取、创建和更新对象。下面是一个常见操作的详细文档,可以得到所有的Pod列表。

GET /api/v1/pods

它支持各种可选参数。

自动伸缩API非常聚焦,允许控制同级别的Pod自动缩放器。该自动缩放器基于CPU利用率,甚至特定于应用的度量来管理一组Pod。它可以用/apis/autoscaling/v1端点来列出、查询、创建、更新和销毁自动缩放器对象。

批处理API

批处理API用来管理作业。作业是执行和终止某些活动的Pod。与副本控制器管理的常规Pod不同,它们在作业完成时就应该终止。批处理API使用Pod模板指定作业,然后在大部分情况下,允许通过/apis/batch/v1端点列出、查询、创建和删除作业。

Kubernetes集群具有几个用于控制集群的主组件,以及在每个集群节点上运行的节点组件。这一部分将介绍这些组件,并解释它们是如何协同工作的。

主组件通常在一个节点上运行,但在高可用性集群或大型集群上,它们可以分布在多个节点上。

1.API服务器

Kube API服务器(Kube-API Server)提供Kubernetes REST API。由于其具有无状态性,因此它可以很轻松地水平缩放。它的所有数据都存储在etcd集群中。API服务器是Kubernetes控制平面的体现。

2.etcd

etcd是一种非常可靠的分布式数据存储。Kubernetes使用它来存储整个集群状态。在小型的瞬态集群中,单个etcd可以与所有其他主组件在同一节点上运行。但考虑到冗余和高可用性,更大型的集群通常包含3个,甚至5个etcd集群。

3.控制器管理器

控制器管理器是各种管理器的集合,这些管理器被打包成一个二进制文件。它包含副本控制器、Pod控制器、服务控制器和端点控制器等。所有这些控制器通过API监控集群状态,它们的任务是将集群控制在目标状态。

4.调度器

Kube调度器负责将Pod调度到节点中。这是一个非常复杂的任务,因为它需要考虑多个相互作用的因素,例如以下几点。

5.DNS

从Kubernetes 1.3开始,DNS服务便成为标准Kubernetes集群的一部分。它被调度成一个普通的Pod。除Headless服务外的每个服务都会接收DNS名称,Pod也可以接收DNS名称,这对于自动化探索非常有用。

集群中的节点需要几个组件与集群主组件交互,接收要执行的工作负载,并根据它们的状态更新集群。

1.代理

Kube代理在每个节点上进行低水平的网络维护,它用于呈现本地Kubernetes服务,可以执行TCP及UDP转发,通过环境变量或DNS寻找集群IP。

2.Kubelet

Kubelet是节点上Kubernetes的代表。它负责监控与主组件的通信并管理运行中的Pod,包括以下几个方面的内容。

在本节中,我们通过Kubernetes的API以及用于控制管理集群的组件,深入研究了它的内在构成,从宏观的视角探讨了它的体系结构及其所支持的设计模式。1.6节将介绍Kubernetes支持的运行时。

Kubernetes最初只支持Docker作为容器运行时引擎,目前情况有所变化,Rkt成为另一被支持的运行时引擎,也通过HypernetHyper.sh容器工作进行了一些有趣的尝试。一个较为重要的设计策略是,Kubernetes本身应与特定的运行时完全脱离。Kubernetes与运行时的交互是通过运行时引擎必须执行的一个相对通用的接口实现的。大多数信息交换会通过Pod、容器概念以及可在容器上执行的操作来实现,每个运行时引擎负责保证Kubernetes运行时接口是兼容的。

在本节中,将深入介绍运行时接口,并细化到单个运行时引擎。阅读完本节,读者将能选择适合实际用例的运行时引擎,并知晓在同一系统中切换或组合多个运行时的具体实用场景。

容器的运行时接口在GitHub的Kubernetes项目中有详细介绍。Kubernetes是开源的,可以查看相关网址。

下面的代码展示了该文件中没有详细注释的部分片段。即便是对Go语言一无所知的入门级程序员,也能够从Kubernetes的角度掌握运行时引擎的功能范围。

type Runtime interface {
  Type() string
  Version() (Version, error)
  APIVersion() (Version, error)
  Status() error
  GetPods(all bool) ([]*Pod, error)
}


 

在此对Go语言进行简要介绍,以帮助读者更好地解析代码——首先是方法名,接下来是括号中的方法参数。每个参数都是一对,由名称和名称类型组成。最后,指定返回值。Go语言允许多个返回类型。除返回实际结果之外,返回错误对象也很常见,如果一切正常,错误对象将为nil。


事实上,这是一个意味着Kubernetes不执行任何操作的接口。第一组方法提供了运行时的基本信息:类型、版本、API版本和状态。通过下面的代码可以得到全部Pod。

SyncPod(pod *api.Pod, apiPodStatus api.PodStatus, podStatus
*PodStatus, pullSecrets []api.Secret, backOff
*flowcontrol.Backoff) PodSyncResult

KillPod(pod *api.Pod, runningPod Pod, gracePeriodOverride *int64)
error 

GetPodStatus(uid types.UID, name, namespace string) (*PodStatus,
error)

GetNetNS(containerID ContainerID) (string, error)

GetPodContainerID(*Pod) (ContainerID, error)

GetContainerLogs(pod *api.Pod, containerID ContainerID, logOptions
*api.PodLogOptions, stdout, stderr io.Writer) (err error)

DeleteContainer(containerID ContainerID) error

下一组方法主要处理Pod,因为这是Kubernetes概念模型中的主要概念框架。然后是GetPodContainerID(),它将数据从容器传输到Pod。还有如下一些与容器相关的更多方法。

ContainerCommandRunnerContainerAttacherImageService是运行时接口继承的接口。这意味着,任何需要执行运行时接口的人都需要执行这些接口方法。接口的定义存放在同一文件中,接口名称已经提供了很多接口功能的信息。显然,Kubernets需要在容器中执行命令,将容器附加到Pod并抽取容器映像。建议读者搜索这个文件并熟悉代码。

现在,读者已经在代码级别对作为运行时引擎的Kubernetes有了初步的认知,接下来将对各个运行时的引擎进行介绍。

当然,Docker是举足轻重的容器。Kubernetes在设计之初仅针对Docker容器,在Kubernetes 1.3中才首次加入多运行时功能。在此之前,Kubernetes只能管理Docker容器。

假定读者在阅读此书时对Docker非常熟悉并了解其功能,我们知道Docker饱受赞誉并历经发展,但也受到一些批判,对它的批判主要针对以下几个方面进行。

针对上述问题,Docker做出了一些改善,尤其针对Docker Swarm产品。Docker Swarm是一个对标Kubernetes的Docker本地编排解决方案,它使用起来比Kubernetes更简单,但没有Kubernetes强大和成熟。


 

从Docker 1.12开始,Docker Daemon进程中就自带群模式,但由于膨胀和范围蠕变使部分用户受挫。这反过来又使更多的人转而将CoreOS Rkt作为替代方案。


从2016年4月发布的Docker 1.11开始,Docker已经改变了运行容器的方式。运行时现在用containerdRunc在容器中运行开放容器倡议(OCI)镜像,如图1.2所示。

图1.2 容器中运行开放容器倡议(OCI)镜像

Rkt是一个来自CoreOS的新型容器管理器(CoreOS Linux发行版、etcd、Flannel等)。Rkt运行时得益于其简单性、安全性和隔离性。它没有像Docker引擎那样的Daemon进程,而是依赖于诸如Systemd的OS Init系统来启动Rkt可执行文件。Rkt可以下载镜像[无论是App容器(appc)镜像,还是OCI镜像]、验证镜像,并在容器中运行镜像,它的体系结构要简单得多。

1.App容器

CoreOS于2014年12月开始了标准化工作,名为appc,包括标准镜像格式(如ACI)、运行时、签名和发现。几个月后,Docker也开始了自己的OCI标准化工作。由此可见,所有成果都将汇聚。这是一个伟大的事情,因为工具、镜像和运行时都能够自由地互相执行,然而,目前还未实现这一愿景。

2.Rkrnetes

Rktnetes在Kubernetes引入Rkt作为运行时引擎。Kubernetes仍抽象于运行时引擎进程中。Rktnetes并不是一个独立的产品。从外部来看,只需在每个节点上使用几个命令行交换机运行Kubelet。但由于Docker和Rkt之间存在根本性差异,因此实际中可能会遇到多种问题。

3.Rkt是否已为生产使用做好准备

Rkt和Kubernetes的集成不是完美的,这其中仍存在一些缺陷。在目前阶段(2016年底),若非有明确具体的原因而使用Rkt,仍然建议读者首选Docker。若有重要用例需使用Rkt,那最好基于CoreOS建立,这样便于找到与CoreOS集群的最佳集成,以及最佳文档和联机支持。

Hyper Container是另一种选择。Hyper Container有一个轻量级的VM(它自己的客户内核),它运行在裸金属上,并且依赖于系统管理程序进行隔离,而非Linux Cgroup。这种方式相比建立起来很费力的标准裸金属集群,提供了一个更为有趣的组合,并且公共云容器可以部署在重量级VM上。

Hypernetes

Hypernetes是一个多租户Kubernetes发行版,它使用Hyper Container以及一些OpenStack组件进行身份验证、持续存储和联网,如图1.3所示。由于容器不共享主机内核,因此在同一物理主机上运行不同租户的容器是安全的。

本节介绍了Kubernetes支持的各种运行时引擎以及标准化和融合化的趋势。1.7节将纵观全局,了解Kubernetes如何适应CI/CD流水线。

图1.3 Hypernetes

Kubernetes对于基于微服务的应用是一个很好的运行平台。通常,大多数开发人员可能并不知道系统部署在Kubernetes上,但是Kubernetes可以使之前看起来非常困难的任务成为可能。

本节将探讨CI/CD流水线以及Kubernetes可以为之带来什么。阅读完本节,读者将可以自行设计CI/CD流水线,该流水线利用Kubernetes特性(如易于伸缩和开发生产奇偶性)来提高日常开发和部署的效率和稳定性。

CI/CD流水线是由开发人员或操作人员修改系统代码、数据或配置,测试并将其部署到生产中的一系列步骤。有些流水线是完全自动化的,有些则是需人工核查的半自动化的。在大型公司中,测试和预演环境可能是自动化部署的,但发布到生产环境仍需人工干预。

值得一提的是,开发人员可以完全脱离生产基础设施。他们的接口只是一个Git工作流,一个很好的例子是Deis工作流(Kubernetes上的PaaS,类似于Heroku),如图1.4所示,描述了一个典型的传输过程。

图1.4 Deis工作流

当部署目标是Kubernetes集群时,应该重新思考一些传统的做法。首先,其包装是不同的,需要为容器打包镜像,通过使用智能标记来恢复代码的改变是非常简单和快捷的。如果一个不好的变化通过测试,但能立即恢复到之前版本,这会给用户很大的信心。但需要注意的是,模式更改和数据迁移不能自动回滚。Kubernetes的另一个独特性在于,开发者可以在本地运行整个集群。这在设计集群时会耗费一些精力,但由于组成系统的微服务在容器中运行,且这些容器通过API进行交互,因此仍是可行的。通常,如果系统是数据驱动的,则需要提供开发者可用的数据快照和合成数据来适应这种情况。

本章介绍了大量的基础和知识,读者可以了解Kubernetes的设计和架构。Kubernetes是运行在容器中、基于微服务的应用程序编排平台,Kubernetes集群有主节点和工作节点。容器在Pod内运行,每个Pod在单个物理机或虚拟机上运行。Kubernetes直接支持许多概念,例如服务、标签和持续存储。可以在Kubernetes上实现各种分布式系统设计模式。容器本身可以是Docker、Rkt或Hyper Container。

在第2章中,我们将探讨创建Kubernetes集群的各种方法,讨论如何在不同场景下使用不同的选项以及构建多节点集群。


相关图书

云原生测试实战
云原生测试实战
Kubernetes快速入门(第2版)
Kubernetes快速入门(第2版)
Kubernetes零基础实战
Kubernetes零基础实战
深入浅出Windows API程序设计:核心编程篇
深入浅出Windows API程序设计:核心编程篇
深入浅出Windows API程序设计:编程基础篇
深入浅出Windows API程序设计:编程基础篇
云原生技术中台:从分布式到云平台设计
云原生技术中台:从分布式到云平台设计

相关文章

相关课程