版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
云原生架构进阶实战目录TOC\h\h第1章云原生架构\h1.1云计算的演化\h1.2什么是云原生\h1.3云原生基础架构\h1.4云原生应用\h1.4.1微服务\h1.4.2健康状况报告\h1.4.3自动测量数据\h1.4.4弹性处理故障\h1.4.5声明式通信\h1.5十二要素应用\h1.6实现云原生模式\h1.7何时采用云原生\h1.8云设计模式\h1.9服务网格(ServiceMesh)\h1.10云原生的未来\h第2章Kubernetes核心对象\h2.1Kubernetes架构\h2.1.1工作节点\h2.1.2Master节点\h2.1.3Docker镜像库\h2.2命名空间\h2.3Pod\h2.3.1创建Pod\h2.3.2Pod内部多个容器\h2.3.3初始化容器\h2.3.4状态探针\h2.3.5测试工具\h2.4部署\h2.4.1ReplicaSet\h2.4.2部署\h2.4.3有状态部署\h2.4.4DaemonSet\h2.5服务\h2.5.1关于服务\h2.5.2Ingress\h2.6存储\h2.6.1存储类型\h2.6.2使用subPath\h2.7RBAC\h2.7.1角色和集群角色\h2.7.2角色绑定和集群角色绑定\h第3章敏捷基础架构\h3.1部署本地Repository\h3.1.1准备CentOS\h3.1.2部署nginx和sonatype/nexus3\h3.1.3配置Nexus\h3.1.4创建并使用NPMRegistry\h3.1.5创建并使用DockerRepository\h3.1.6创建Maven2LocalRepository\h3.1.7总结\h3.2部署Kubernetes\h3.2.1环境准备\h3.2.2安装DockerCE\h3.2.3安装kube工具\h3.2.4构建Master节点\h3.2.5在客户端设置环境\h3.2.6部署Flannel网络\h3.2.7加入工作节点\h3.2.8部署Dashboard\h3.3部署MetalLB\h3.3.1安装MetalLB\h3.3.2配置IP地址池\h3.3.3使用MetalLB\h3.3.4流量策略\h3.3.5IP共享\h3.4部署GlusterFS\h3.4.1卷类型\h3.4.2GlusterFS部署方法\h3.4.3GlusterFS要求\h3.4.4创建磁盘分区\h3.4.5安装软件\h3.4.6配置防火墙\h3.4.7配置信任池\h3.4.8创建GlusterFS卷\h3.4.9GlusterFS卷安全\h3.4.10GlusterFS快照\h3.4.11vSAN与GlusterFS的比较\h3.5使用GlusterFS卷\h3.5.1静态卷的使用\h3.5.2动态卷的使用\h3.6使用NFS卷\h3.6.1前提条件\h3.6.2授权\h3.6.3创建provisioner和StorageClass\h3.6.4测试\h3.7升级Kubernetes\h3.7.1升级Master节点\h3.7.2升级工作节点\h3.7.3查看升级结果\h第4章DevOps实战\h4.1DevOps简介\h4.1.1DevOps流程\h4.1.2云原生下的DevOps\h4.2软件部署策略\h4.2.1实践准备\h4.2.2重建部署(Recreate)\h4.2.3滚动部署(RollUpdate)\h4.2.4蓝绿部署(Blue/Green)\h4.2.5金丝雀部署(Canary)\h4.2.6A/B测试\h4.2.7影子部署\h4.2.8总结\h4.3部署GitLab\h4.3.1GitLab简介\h4.3.2在CentOS7.x中部署GitLab\h4.3.3使用Docker部署GitLab\h4.3.4在Kubernetes集群中运行GitLab\h4.3.5GitLabRunner\h4.4GitLab集成自动CI/CD\h4.4.1GitLab自动CI/CD\h4.4.2.gitlab-ci.yml\h4.4.3变量注册\h4.5容器部署模式\h4.5.1什么是sidecar模式\h4.5.2sidecar模式的优势\h4.5.3sidecar模式的适用场景\h4.5.4采用sidecar模式的事例\h第5章日志记录\h5.1模式\h5.1.1伴生模式\h5.1.2DaemonSet模式\h5.2日志采集\h5.2.1具有日志代理功能的伴生容器\h5.2.2DaemonSet模式下配置Fluentd\h5.3部署Elasticsearch\h5.3.1Elasticsearch简介\h5.3.2在DockerSwarm中部署Elasticsearch\h5.3.3在Kubernetes上创建Elasticsearch集群\h5.4部署Kibana\h5.4.1在Docker中部署Kibana\h5.4.2在Kubernetes上部署Kibana应用\h5.5部署fluentd作为syslogserver\h5.5.1创建fluentd服务\h5.5.2创建fluentd应用\h5.5.3测试\h第6章云原生下的监控\h6.1Prometheus简介\h6.1.1Prometheus组成及架构\h6.1.2使用Prometheus的场景\h6.1.3Prometheus相关概念\h6.2使用Exporter采集数据\h6.2.1常用Exporter\h6.2.2Exporter的运行方式\h6.2.3NodeExporter\h6.2.4容器监控cAdvisor\h6.2.5黑盒监控BlackboxExporter\h6.3在Kubernetes中部署Prometheus\h6.3.1创建RBAC文件\h6.3.2创建服务\h6.3.3创建配置文件\h6.3.4部署Prometheus\h6.4部署BlackboxExporter\h6.4.1BlackboxExporter配置文件\h6.4.2BlackboxExporter部署文件\h6.5NodeExporter\h6.5.1创建NodeExporter服务\h6.5.2创建NodeExporterDaemonSet\h6.6Grafana\h6.7在Kubernetes中部署Grafana\h6.7.1创建持久卷声明\h6.7.2部署Grafana\h6.7.3Grafana配置文件\h6.7.4创建Service\h6.8案例:监控Drupal站点\h6.8.1Drupal准备\h6.8.2准备镜像\h6.8.3准备stack文件\h6.8.4设置Grafana\h第7章服务网格应用\h7.1Istio架构\h7.1.1Istio的目标\h7.1.2服务网格资源\h7.2安装与卸载Istio\h7.2.1下载Istio安装包\h7.2.2使用helmtemplate安装\h7.2.3使用kubectl手动安装\h7.2.4卸载Istio\h7.3使用Istio\h7.4Istio常用场景\h7.4.1分布式调用追踪\h7.4.2遥测度量收集\h7.4.3灰度发布应用\h7.4.4熔断\h7.4.5故障注入\h7.5总结\h第8章案例\h8.1在Kubernetes中部署Drupal8站点\h8.1.1准备GlusterFS卷\h8.1.2创建PersistentVolumeClaim\h8.1.3创建数据库部署(Deployment)\h8.1.4创建Drupal部署\h8.1.5安装Drupal\h8.1.6总结\h8.2云原生架构下的Node.js自动CI/CD方法\h8.2.1Node.js示例\h8.2.2在Kubernetes集群中创建GitLab账户\h8.2.3部署DockerRegistry\h8.2.4配置GitLab\h8.2.5通过GitLab构建Docker\h8.2.6部署应用到Kubernetes集群中\h8.3ApereoCAS自动横向缩放部署策略\h8.3.1CAS简介\h8.3.2前提条件\h8.3.3准备环境\h8.3.4CAS模板修改\h8.3.5持续集成\h8.3.6持续部署\h8.4ApacheKafka部署与使用\h8.4.1Kafka介绍\h8.4.2为什么在Kubernetes上运行Kafka\h8.4.3在Kubernetes上部署Kafka的考虑\h8.4.4在Kubernetes上部署Kafka的方式\h8.4.5通过Helm部署Kafka\h8.4.6通过Operators部署Kafka\h8.5云原生应用架构在上海海事大学信息化建设中的实践\h8.5.1组织与赋权\h8.5.2敏捷性基础架构\h8.5.3持续交付\h8.5.4微服务\h8.5.5困难第1章云原生架构1.1云计算的演化在云原生概念之前,读者已经熟知虚拟化技术、云计算方法。虚拟化是将不存在的事物或现象虚拟成存在的事物或现象的方法,在计算机领域则是指软硬件资源的虚拟化。硬件资源的虚拟化包括计算资源虚拟化、存储资源虚拟化和网络资源虚拟化。利用虚拟化技术,可以将物理资源抽象为统一的逻辑表示,例如通过VMware的虚拟化技术,所有虚拟服务器都拥有统一的设备型号。利用虚拟化技术,也可以使得虚拟资源不受物理资源的限制,例如一台物理服务器可以虚拟成多台服务器,多台物理服务器也可以虚拟成一台服务器,从而整合硬件资源,提高资源利用率。虚拟化技术目前做得较好的公司有VMware、Citrix、Microsoft、RedHat和Oracle等公司。虚拟化技术的发展如图1-1所示。从1998年VMware引入x86虚拟化技术用于普通PC的虚拟,到2001年发布ESX实现服务器的虚拟,之后Citrix发布了Xen;Microsoft发布了VirtualPC和Hyper-V;RedHat借助Linux的优势发布了KVM;而Oracle则收购了VirtualBox。各大厂商都有了自己的虚拟化技术。图1-1虚拟化技术的发展尽管虚拟化技术可以有效地简化数据中心管理,降低数据中心的运营成本,但是并不能取消为了使用IT系统而进行的数据中心构建、硬件采购、软件安装和系统维护等环节,企业仍需要配备较多IT运维人员去从事物理资源的相关准备工作、软件系统的部署工作。此时人们更希望出现一种能够对计算、存储和网络等资源的按需自动分配、按使用量付费的服务,这就催生了云计算模式。云计算借助虚拟化技术的伸缩性和灵活性,进一步提高了资源利用率,简化了资源和服务的管理与维护,减少了数据中心的运营成本。根据云计算服务提供的内容,业界把云计算分成三层:基础架构即服务(IaaS)、平台即服务(PaaS)和软件即服务(SaaS)。根据云计算服务提供的来源和服务对象,云计算分为公有云和私有云。云计算的发展如图1-2所示。2006年Amazon(亚马逊)开始提供S3存储和EC2虚拟服务器的云服务;2009年Heroku提供了第一款PaaS云服务。2011年诞生了开源的IaaS实现——OpenStack,同年Pivotal开源了PaaS的实现——CloudFoundry。2014年诞生了第一款商用函数即服务(FaaS),更加推动了云服务的深度应用。图1-2云计算的发展在虚拟化计算和云计算服务蓬勃发展的阶段,人们也意识到了虚拟化技术的弊端。虚拟化技术虚拟出来的是一个完整操作系统,它的底层包括宿主机操作系统和虚拟化层,势必导致虚拟机的性能低于物理机的性能。此外,完整的操作系统所占用的存储空间较大,而且启动一个虚拟机,等同于启动一个完整操作系统。但是往往在虚拟服务器中可能仅仅是为了运行某一个软件而已。为此,LXC(LinuxContainer)技术和Docker技术开始出现。它摒弃了启动完整系统的弊端,在现有操作系统上对任务进行隔离,并实现资源按需分配。它允许多个容器共享一个操作系统内核,容器内存储的仅仅是与某个应用紧密相关的资源,其空间占用往往只有几十到几百MB。单独容器化如同虚拟PC一样会面临高可用性不足、管理低级等问题。为此,业界推出了容器编排技术,其发展如图1-3所示。2014年Google开源了Kubernetes(简称K8S),它是一种容器编排工具。容器编排工具将容器生命周期管理能力扩展到部署在大量机器集群上复杂的多容器工作负载,并且为开发人员和基础设施团队提供了一个抽象层来处理大规模的容器化部署。众多公司加入到了容器编排技术大战中,但是到了2017年,MESOS和Docker相继宣布支持Kubernetes,彻底奠定了Kubernetes在容器编排工具中的地位。2018年,Kubernetes从云原生计算基金会中毕业。图1-3容器技术和编排技术的发展随着虚拟化技术、云计算服务以及容器化技术的发展,越来越多的开发者和IT设施运维人员开始团队协作,改变过往独立运作的传统,开始对现有基础架构、运维人员的职责、开发团队的文化以及软件开发模式进行思考和研究,逐渐形成了云原生的概念。1.2什么是云原生云原生(CloudNative)概念是由Pivotal的MattStine在2013年首次提出的。这个概念得到了社区的不断完善,内容越来越丰富,目前已经包括了DevOps(Development和Operations的组合)、持续交付(ContinuousDelivery,CD)、微服务(MicroServices)、敏捷基础设施(AgileInfrastructure)和十二要素(TheTwelve-FactorApp)等几大主题。这个概念不但包括根据业务能力对企业(高校)进行文化、组织架构的重组与建设,也包括方法论和原则,以及具体的操作工具。采用基于云原生的技术和管理方法,可以更好地从云中诞生业务,也可以把业务迁移到不同的云中,从而享受云的高效与持续服务的能力。2015年云原生计算基金会(CNCF)成立,对云原生定义进行了修改,认为云原生需要包含应用容器化、面向微服务架构以及支持容器编排调度等方面的内容。2018年,随着云原生生态的壮大,主流云计算供应商都加入了该基金会,随之云原生定义又进一步得到完善。云原生技术增强了公司和机构在现代动态的环境中构建和运行可弹性扩展的应用,这些环境主要是公有云、私有云和混合云的环境。容器、服务网格、微服务、敏捷基础结构和声明性API都是这些方法的例证。这些技术能够构建可弹性扩展的、可管理的、可观察的松耦合系统。结合自动化手段,云原生技术可以使得开发者以最低的成本对系统进行频繁并可预测的重大变更。云三层模型与云原生架构的对比如图1-4所示,原先的IaaS层升级为敏捷基础设施,而PaaS和SaaS层则合并为微服务架构。敏捷基础设施和微服务都属于技术范畴的架构。在整个云原生架构中,也少不了自动化的持续交付和DevOps等管理措施。图1-4云原生架构在传统的应用系统开发过程中,软件开发商喜欢聚焦在业务系统,专注于系统如何开发、如何闭源成一个独立的整体系统。但是随着开源软件的盛行,全球合作背景下的分工细化,再加之GitHub的影响力越来越大,一个软件开发商很难在短时间内处理所有问题。软件开发商应该充分利用第三方开源或不开源的组件,自己仅仅实现必要的代码,再借助敏捷基础架构进行灵活多变的必要集成,从而节省大量人力、物力和时间,以便更加聚焦业务开发,同时又能利用整体协作快速部署业务。云原生的意义就在于此,按照云原生的理念进行顶层架构设计、实施、部署,即可实现快速迭代,投入生产使用。云原生主要包括两部分内容:云原生基础架构和云原生应用。1.3云原生基础架构云原生基础架构是隐藏在抽象背后的由软件管理并由API进行控制的基础架构,它的目标是运行应用系统。这也就兴起了一种新的管理模式——通过这些特性以可扩展、高效的方式进行基础设施管理。有用的抽象是具有重要意义的,它可以让开发者专注于自己的业务而无须了解底层、实现底层,更可以避免重复实现底层。由软件来管理基础架构是与云的一个关键区别。软件控制的基础架构使得基础架构能够扩展,也就实现了资源弹性处理、资源置备和资源可维护。这种软件管理基础架构的模式不仅影响了基础架构的管理和运行,也影响了在其上运行的应用系统,从系统架构到系统开发、部署、运维都有了重大变化。云原生基础架构不仅仅是在公有云上运行基础架构,也不是在容器中运行应用程序,所以公有云和容器化不是云原生基础架构的代名词。但是云原生基础架构可以借助容器化技术和公有云技术去实现。公有云仅仅是IaaS层的实现,一般的公有云还是要借助人力去申请、分配。而云原生基础架构则是用程序代码自动去申请。容器仅仅是应用程序的一种打包方式,这并不意味着这些应用程序具备自治功能。即使应用程序是通过持续集成和持续交付等DevOps流水线自动构建和部署的,也并不一定就是云原生基础架构。Kubernetes也不能简单地称为云原生基础架构。Kubernetes的容器编排技术为云原生基础架构提供了必要的平台支撑功能。是否是云原生基础架构的关键在于是否使用自动化处理的方式。例如在Kubernetes中手工分配物理卷,就不能称为云原生基础架构,因为物理卷不是自动分配的。而如果使用动态卷,依靠卷声明来分配容量,进而分配使用该卷的容器,则满足了云原生基础架构的要求。云原生应用对基础架构的基本要求有:●运行时间和隔离。●资源分配和调度。●环境隔离。●服务发现。●状态管理。●监测和日志记录。●度量聚合。●调试和追踪。云应用程序肯定会依赖一个或多个服务来提供业务价值。提供一种让服务在每个环境的基础上找到彼此的方法是基础架构的责任。有些应用的服务发现需要调用API来实现,而有些应用则通过DNS或者网络代理透明地发现。具体的实现方式不重要,重要的是使用服务发现服务。云原生应用程序和基础架构协作以发现其相关依赖服务。例如Prometheus抓取监控信息的动作主要在配置文件中描述,但是如果Prometheus监控的目标是动态的,则需要部署人员每次去修改Prometheus配置文件,这是非常麻烦的,而且人工操作易出错。为此,Prometheus实现了一种服务发现方式,主动感知系统监控目标的变化,自动添加、删除和更新服务。以下是一个Kubernetes上的服务允许Prometheus自动发现的代码,其中的prometheus.io/scrape:"true"就是为了让Prometheus感知到该服务。该服务暴露了HTTP协议访问,端口为8080,端点为/metrics。1.4云原生应用云原生应用程序的关键在于提供弹性、敏捷性、可操作性和可观察性。弹性的概念隐含了允许应用程序失败而不是试图阻止程序失败的意思。敏捷性允许应用快速部署和快速迭代,这就需要引入DevOps文化。可操作性是指从应用程序内部控制应用程序的生命周期,而不是依赖外部进程和监视器。可观察性是指应用程序需要提供信息以反映应用程序的状态。目前实现云原生应用程序所需特性的常用方法有:●微服务。●健康状况报告。●自动测量数据。●弹性。●声明模式而不是响应模式。1.4.1微服务传统应用程序是以单个实体为目标进行管理和部署的,这也是国内软件行业常用的开发方式,简称为单体应用程序。单体应用程序的好处是显而易见的,但是它无法解决面向大量互联网用户提供服务的并发量问题,且使得开发过程变得臃肿,开发进程变得缓慢,维护也越来越困难。解决这些问题最好的方法之一就是分解单体应用为众多小的服务模块。如图1-5所示,这些服务模块相互独立,使得开发人员可以独立维护这些小系统,而且开发和维护过程也变得敏捷。分解成微服务后,各服务的编写语言也可以自行确定,只需要遵守总体的API优先和通信要求即可。图1-5微服务架构微服务更像是UNIX哲学的实践和改造。UNIX哲学是“程序应该只关注一个目标,并尽可能把它做好。让程序能够互相协同工作。”例如UNIX命令行上的统计文件数量,通过下面的命令管道就可以把列表和统计两个命令串联起来使用。微服务也是如此,服务更专注于其用途,也就是只应做一件事,并把这件事做好。但是微服务不能等同于云原生架构,微服务只是云原生文化的一种实现。1.4.2健康状况报告为了能够由软件控制一切,应用程序必须提供可供管理软件监测的度量指标。而一个应用程序的度量指标只有创建应用程序的作者最清楚,因此在应用程序中内置度量指标是最好的设计方式。这要求各应用程序提供必要的端点,供管理软件访问以判断应用程序状态。例如Kubernetes、ETCD都通过HTTP提供了大量的度量指标。此外,应用程序应该提供更加丰富且必要的状态报告。在云原生架构下,一切皆是代码,一切皆可由软件控制。为了可以控制,各应用程序必须提供度量接口让管理软件获知应用程序运行状态以做出必要的反应,例如应用程序崩溃时,管理程序可做出停掉当前应用程序实例然后启动新实例的操作。应用程序的健康状况只是能够自动执行应用程序声明周期的一部分,管理程序还需要知道应用程序是否正在工作。1.4.3自动测量数据自动测量数据是做出决定所必需的信息,这些数据与健康状况报告的数据是有重叠的,但是它们的用途不一样。健康报告是告知管理程序所辖应用程序的生命周期状态,而自动测量数据是告知应用程序的业务度量指标。度量的指标一般称为服务级别指标(ServiceLevelIndicator,SLI)或关键绩效指标(KeyPerformanceIndicator,KPI)。这些指标是特定于应用程序的数据,让管理程序监测应用程序的性能在服务级别目标(ServiceLevelObjectives,SLO)内。自动测量数据可以解决以下问题:●应用程序每分钟收到的请求数。●是否有任何错误。●应用程序延迟多久。●业务处理需要多长时间。监测数据经常被抓取或推送到时间序列数据库(如Prometheus或InfluxDB),然后再由度量指标模型进行处理分析,以便后续提醒或者大屏展示。有一点需要注意的是,自动测量数据应该用于提醒场景而不是健康监测。在一个动态可自我修复的环境中,管理程序几乎不关心单个应用程序的生命周期,而更多关心应用程序的SLO,因为若是一个程序崩溃,管理程序可以动态重启应用程序实例以恢复正常运行状态。举一个例子,在Kubernetes中运行以下命令可以看到coredns重启过两次和3次,但是管理程序不关心这个行为,只关心它是否在正常运转,因为管理程序的SLO就是要正常运转。1.4.4弹性处理故障云原生应用程序应当正视故障而不是竭力避免故障。唯一不应该有故障的系统是那些维持生命的系统。任何系统都应该有一个合理的SLO,如果无视SLO而去避免故障发生,则花费的成本将非常巨大。为此,必须假设应用程序可能发生故障,并采取必要的措施应对故障,这是云原生应用的一种模式。无论发生什么样的故障,云原生应用都必须适应,并采取合理的调整措施应对。此外,云原生应用还需要设计一种方法应对过载,这也是互联网应用面临的常见问题,例如12306售票、淘宝双11活动时的并发访问过载。处理过载的一种常见方法是适度降级。在《SiteReliabilityEngineering》一书中对于应用程序的优雅降级做了详细描述。书中指出在负载过重的情况下,可以采取降低准确性、反馈少量数据等方式给用户适度响应,而不是拒绝服务。尽管减少应用程序负载可以通过负载均衡设备或者动态扩展等基础架构进行处理,但是应用程序仍有可能接收到超负载的请求。所以云原生应用要求具备服务优雅降级的能力。最现实的处理方式是服务降级,返回部分回应或使用本地缓存中的旧信息进行回应。这部分内容在ServiceMesh中得到了很好的解决。1.4.5声明式通信由于云原生应用程序在云环境中运行,因此它们与基础架构和支持应用程序的交互方式与传统应用程序不同。在云本机应用程序中,与任何内容进行通信的方式都是通过网络。很多时候,网络通信是通过RESTfulHTTP调用完成的,但也可以通过其他接口实现,例如远程过程调用(RPC)。传统应用程序可以通过消息队列、共享存储上的文件或触发shell命令的本地脚本来自动执行任务。事件发生后,通信方法根据本地服务器上的信息做出反应。例如,如果用户点击提交,则运行本地服务器上的提交脚本。在传统应用程序中,通信的介质可能是文件或者消息队列,但是这些方式都是尝试构建避免失败的方式,它们在云原生架构下存在一些问题。例如应用程序把结果写入到文件,写完后应用程序崩溃了。此时会出现了一种情况:应用程序崩溃之前,计算结果已经写入文件中。按照云原生理念,此时应用程序将重启,再次执行计算过程,计算结果再次写到文件中。因此,开发人员应该停止使用反应式通信,开始使用声明式通信,从而提高应用程序的健壮性,并且减少应用程序的依赖。1.5十二要素应用十二要素应用程序方法是Heroku的开发者起草的。十二要素中提到的特征并不特定于云提供者、平台或语言。这些要素代表了针对云环境中蓬勃发展的可移植弹性应用程序(特别是“软件即服务”应用程序)的一组准则或最佳实践。下面列出了这十二要素。(1)一份基准代码(Codebase),多份部署(Deploy)企业一般会采用代码版本控制系统来跟踪管理所有修订版本的代码库,这样就只需要一份代码,却可以同时存在多份部署,如图1-6所示。每份部署相当于运行了一个应用的实例。例如作者所在学校的Portal应用,学校有一个生产环境的部署,也有一个用于测试的预发布环境部署。学校将同一套代码先在预发布服务器上部署,进行初步评估,然后再发布到正式生产服务器上。图1-6一份基准代码多份部署(2)显式声明依赖关系(Dependency)应用程序不会隐式依赖系统级类库。它一定通过依赖清单确切地声明所有依赖项。此外,应用程序在运行过程中通过依赖隔离工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法在生产和开发环境中都是统一的。例如Node.js应用程序通过package.json来声明依赖项,Maven项目使用pom.xml来声明依赖项。遵循该要素的应用程序也不会隐式依赖系统级工具,例如ImageMagick和curl等工具,即使这些工具在Linux不同版本中都存在,但无法保证所有未来的系统都部署了该工具,例如Docker中的Linux就不一定存在这两个工具。如果要使用这些工具,则必须包括在应用程序中。例如Drupal中的命令工具drush就包含在bin目录下。(3)在环境中存储配置十二要素应用推荐将应用的配置存储于环境变量中,如图1-7所示。这允许应用程序非常方便地在不同的部署间修改,而不需要改动一行代码。例如wget用的环境变量HTTP_PROXY。还有一种做法是使用配置文件但把该配置文件从版本控制中排除。例如Drupal站点的settings.php文件,里面含有数据库连接信息,为了保证安全,必须将该文件排除在版本控制外。但是有时仍然难免将该文件加入版本控制,从而造成了数据库连接信息泄露。图1-7在环境中存储配置在Kubernetes中,系统会自动将服务根据名称创建多个不同的细粒度环境变量。(4)把后端服务(backingservices)当作附加资源后端服务是指程序运行所需要的通过网络调用的各种服务,如数据库(MySQL、CouchDB),消息/队列系统(RabbitMQ、Beanstalkd),以及缓存系统(Memcached)。符合规则的应用程序应该可以在不进行任何代码改动的情况下,将本地数据库切换至异地或者云上的数据库服务。(5)严格分离构建、发布和运行基准代码通过构建、发布和运行三个阶段转化成一份部署。构建阶段是指将代码进行编译、打包等操作,生成可执行文件。而发布则是将构建的结果和相关配置发布到运行环境中投入使用。运行阶段则是在执行环境中启动一系列应用程序。例如Node.js应用程序,其构建步骤较为简单,只需要复制相关文件即可。而发布到运行环境时,则通过npminstall安装相关依赖项;在运行阶段可以通过Node.js进程管理工具pm2安装或者重启服务。(6)以一个或多个无状态进程运行应用符合十二要素的应用程序的进程必须是无状态且无共享的。任何需要持久化的数据都需要存储在后端服务内。例如ApereoCAS,所有认证的Ticket均保存在后端数据库中,如memcached集群。而需要处理的是session状态,这个也是需要通过后端memcached或者redis进行统一存储,或者通过前端负载均衡粘性路由到同一个应用进程中。(7)通过端口绑定(Portbinding)来提供服务符合十二要素的应用程序可以自我加载而不依赖于任何网络服务器。例如Java代码可以直接使用JVM的Jetty,而不依赖于Tomcat。这一点就像Node.js不需要Apache一样。还是以ApereoCAS为例,最新版本的CAS可以自我加载运行,而不依赖Tomcat。如果查看常用软件的Dockerfile,会发现这些Docker的执行命令不再是以后端程序的方式运行,而是直接以前端运行。例如PHP的Docker镜像,命令为apache2-foreground。(8)通过进程模型进行扩展在十二要素应用中的进程主要借鉴了UNIX守护进程模型,不同的工作分配给不同类型的进程处理。尤其是无共享、水平分区的特性让并发处理更加简单。十二要素应用的进程不需要守护进程,也不需要写入PID文件,而是借助操作系统的进程管理器(如systemd)进行输出流控制、进程崩溃响应,以及进程的重启和关闭的请求。(9)快速启动和优雅终止可最大化健壮性十二要素应用的进程是可分解的(disposable),它可以瞬间开启或者停止。这有利于快速、弹性伸缩应用,迅速部署变化的代码或配置。进程应当追求最短的启动时间,一旦接收到终止信号则会优雅地终止。进程还应当合理处理意外终止,例如可以在客户端断开或者超时连接后自动退回任务。(10)尽可能地保持开发、预发布和线上环境相同开发人员可能使用Macintosh开发,也可能使用Windows开发,这就造成各种环境的不一致,尤其是开发环境和生产环境。即便同样的操作系统,也有可能随着时间变化、工具差异、人员差异等出现不一致。十二要素应用要求必须缩小本地和生产环境的差异,企业可以使用Docker来进行环境的统一,无论是开发环境还是生产环境,都使用Docker来进行测试和正式运行。十二要素应用要求不同环境下的后端服务也要一致,例如开发环境使用MariaDB,则生产环境亦应使用MariaDB。(11)把日志当作事件流日志使得应用程序运行的动作变得透明。在基于服务器的环境中,日志通常被写在硬盘的一个文件里,但这只是一种输出格式。在十二要素应用中则不应该考虑存储到自己的输出流,不应该试图去写或者管理日志文件。相反,每一个运行的进程都会直接将日志存储到标准输出(stdout)事件流。开发环境中,开发人员可以通过这些数据流,实时在终端看到应用的活动。这点在Docker环境下尤其如此。每个Docker中的应用不应该自己进行日志的管理,而应该直接提交给标准输出和标准错误事件流。下面是PHP镜像的Dockerfile代码:这段代码改造了Apache2的日志,默认情况下,Apache2将访问日志写入access.log文件,错误日志写入error.log,而通过ln软链接命令,实现了将这些日志流直接重定向为标准事件流。这样,这些应用的日志流将被Docker或者Kubernetes捕获。(12)后台管理任务当作一次性进程运行进程构成(processformation)是指用来处理应用的常规业务(如处理Web请求)的一组进程。与此不同,开发人员经常希望执行一些管理或维护应用的一次性任务,例如开源软件OwnCloud。升级OwnCloud可以在Web界面下操作,但更建议通过occupgrade命令进行升级。在这个命令中,使用了Apache2进程的用户www-data,保证了命令行和Web方式的环境一致。这也是十二要素的要求:一次性管理进程应该和正常的常驻进程使用同样的环境。这些管理进程和任何其他进程一样使用相同的代码和配置,基于某个发布版本运行。后台管理代码应该随其他应用程序代码一起发布,从而避免同步问题。要实现高质量的微服务环境,可以不用严格遵循这些要素。但是,通过牢记这些要素,用户可以在持续交付环境中构建和维护可移植应用程序或服务。这是非常重要的,读者一定要充分理解这十二要素。在本书后续的描述和案例中,读者可以看到十二要素的实战。1.6实现云原生模式云原生基础架构由应用程序来维护,而云原生应用则由基础架构来维护,两者密不可分。这就要求基础架构和应用程序设计必须是简单的。如果一个应用程序比较复杂,则应该采用微服务模式,将复杂功能拆分为细微的服务,然后通过集成这些细微服务来组装成一个应用系统。但由微服务构成的如此复杂的系统,势必无法通过人工管理,应该采用自动化管理,这也是云原生应用的一个基本特征。在传统单体应用中,企业所用开发语言是单一的,例如Java体系或者.Net体系,但是在众多微服务进行开发时,语言限定得到了解放。负责某一个微服务的开发人员擅长使用.Net语言,负责另外一个微服务的开发人员擅长Node.js,这就出现了多元化。云原生应用并不限定语言,它只对诸如弹性、服务发现、配置、日志记录、健康检查和度量检查等模式有要求。针对两种不同情况,目前常用的做法主要有两类。(1)单一语言情况下,可以通过导入标准库的形式在程序代码中声明云原生特征。例如Java语言系的SpringCloud,可以通过类声明来实现配置、服务发现、熔断机制等功能。(2)多语言情况下,则可以通过伴生(sidecar)模式来解决。该模式将实现各种功能的微服务应用通过容器化部属捆绑在一起。常见例子如Envoyproxy为服务增加弹性和指标,Registrator通过外部服务发现服务,Configuration监视配置更改并通知服务进程重新加载。Healthendpoint提供用于检查应用程序健康状况的HTTP端点。这些都简化了云原生架构的开发难度并提高了组件复用率。在云原生架构下,应用的生命周期也是由软件来进行控制的,普通用户无须关心应用的生命周期。应用程序的集成、测试和部署应该是自动化、自助式的,按照DevOps文化来进行。1.7何时采用云原生云原生架构是一个阶段性产物,它符合技术的生命周期,有流行时期,也有淘汰的时间点。是否采用云原生要看各自场景的需求以及是否具有使用云原生的基础条件。另外,云原生架构不是银弹,如果不了解情况就贸然上云原生架构,会带来各种成本极大浪费,也解决不了所有问题。在选择上云原生之前,读者可以问自己几个问题:(1)企业的现有基础架构是否敏捷?所谓敏捷是指可以通过API来自动分配、销毁资源,也就是说,现有IaaS层是不是API可控制的。云原生应用需要系统抽象,在应用中不能硬编码系统主机名,也不能捆绑应用到特定机器,从而排除人为操作应用和系统之间的映射。换句话说,当应用不再关注底层系统的情况时,就可以尝试云原生架构。(2)企业的开发团队、部署团队、运维团队是否独立?技能是否相通?如果多个团队各自独立运作,互相之间技术不了解,这种情况下采用云原生架构,则势必带来磨合成本和高昂的学习成本。如果采用云原生架构,将打破这种独立运作的组织架构,由传统纵向分割团队改为横向分割团队,每个小组可以自己负责纵向的所有事宜,从而更好地协作。(3)企业的业务是否需要更快地迭代,是慢步速应用还是快步速应用?如果是慢步速应用,则完全可以不采用云原生架构,直接在一台物理服务器或者云服务器上一次性部署会更加节约成本。采用云原生架构的应用,就是为了快速响应业务变化,并快速部署应用,只有业务变化快的业务才能充分发挥云原生架构的作用。(4)企业是否有云原生应用?是否有满足十二要素的应用?是否有微服务等应用?如果以上都没有,那么企业可能还需要做更多工作才能采用云原生架构。适合云原生架构的应用必须职能单一、与系统无绑定,能够动态扩展实例数量。这就要求能够以无人值守的方式扩展应用实例,也要求状态持久化的存储服务独立于应用所在的服务器。符合十二要素是最好的实践。如果以上问题的答案都是“是”,那么企业完全可以毫无顾虑地采用云原生架构。如果以上问题的回答有“否”,也不是说企业不能采用云原生架构了。实际上,对于一个非互联网企业或者高校、政府机关来讲,能够部分采用云原生架构,能够部分借鉴云原生应用的理念,也是一种改进的成果,为转向云原生架构做准备工作。1.8云设计模式为了在云中构建可靠、可扩展、安全的应用程序,Microsoft从可用性、数据管理、设计与实施、消息、管理和检测、性能和可伸缩性、弹性、安全等方面总结了如表1-1所示的34种模式。表1-1云设计模式列表以上模式虽然不是云原生应用设计模式,但是有些原则和云原生应用设计模式类似,可以借鉴。1.9服务网格(ServiceMesh)服务网格是用于处理服务到服务通信的专用基础设施层。它负责通过包含现代云原生应用程序的复杂服务拓扑来可靠地传递请求。实际上,服务网格通常实现为多个轻量级网络代理,这些代理与应用程序代码一起部署,但不需要知道应用程序。服务网格作为独立层的概念与云原生应用程序的兴起有关。在云原生架构中,借助于Kubernetes这样的编排器,单个应用程序可能包含数百个服务,每个服务可能有数千个实例,并且每个实例可能处于不断变化的状态。这就使得这些服务实例间的通信不仅非常复杂,而且确保端到端的性能和可靠性至关重要。目前,服务网格已成为云原生堆栈的关键组件。Paypal、Ticketmaster和CreditKarm等高流量公司都为其生产应用程序添加了服务网格,2017年1月,Linkerd(云原生应用程序的开源服务网格)成为云原生计算基金会的官方项目,同年5月IBM和Google共同发布开源Istio。服务网格并没有给软件开发和部署带来新功能,它解决的是其他工具已经解决过的问题,只不过这次是针对云原生架构下的Kubernetes环境的实现。服务网格的主要特点有:●应用程序间通信的中间层。●轻量级网络代理。●应用程序无感知。●解耦应用程序的重试/超时、监控、追踪和服务发现。目前两款流行的服务网格开源软件Istio和Linkerd都已经在Kubernetes中集成,但是Istio的接受度和采用量更多一些。Istio是一个源代码开放的平台,用于管理和保护微服务。Istio与编排器(如Kubernetes)配合使用,可管理和控制服务之间的通信。Istio使用伴生模式来运行。伴生模式(Envoy代理)是一个单独进程,与应用程序一起使用。伴生可管理与服务之间的所有往来通信,并将公共级别的功能应用于所有服务,与用于构建服务的编程语言或框架无关。实际上,Istio提供了一种机制,以集中方式配置路由和安全策略,以分散方式通过伴生来应用这些策略。在大多数情况下,本书建议使用Istio提供的功能,而不要使用不同编程语言或框架提供的类似功能。例如,基础架构能以更一致的方式对负载均衡和其他路由策略进行定义、管理和强制实施。在某些情况下,与分布式跟踪一样,Istio和应用程序级别的库是互补的,可以同时使用这两者来改进操作。对于分布式跟踪,Istio只能确保在请求中包含跟踪信息;应用程序库提供了有关请求之间关系的重要上下文。将Istio与支持库或框架库一起使用时,可使读者对系统请求的路由过程有一个总体了解。Istio从最高层上扩展了Kubernetes平台,提供了额外的管理概念、可视性和安全性。Istio的功能可以细分为以下四个类别:●流量管理:控制微服务之间的流量,以执行流量分割、故障恢复和金丝雀发布。●安全性:在微服务之间提供基于身份的强认证、授权和加密。●可观察性:收集度量值和日志,以更好地了解集群中运行的应用程序。●策略:强制实施访问控制、速率限制和配额,以保护应用程序。具体内容可以参阅Istio官方文档。1.10云原生的未来2019年5月,著名分析机构Gartner发布了一份有关云原生基础设施的报告。该报告指出容器和Kubernetes是构建云原生基础设施的关键,有助于提升软件效能和开发生产率。该报告预计2020年所有领先的容器管理软件均内置服务融合技术,到2022年,全球化企业在生产中使用容器化的应用比例将从当前不足30%发展到75%,应用软件采用容器化技术适应多云环境的比例从现在的少于20%发展到50%。云原生应用不适合在传统的基础设施中运行,因为它需要更高程度的服务发现、可编程性、自动化、可观测性、强大的网络通信及安全性等。从Kubernetes诞生到现在已经过去五年,容器化技术的迅猛发展,推动着云原生基础设施发展并产生重大变革。这些变革主要出现了三种新兴趋势:新用例、超越核心构建的技术演进、生态系统成熟,具体有:(1)混合云环境中使用云原生基础设施架构。(2)在边缘计算中引入云原生技术,简化管理。(3)服务网格继续发展,并以Istio领先。(4)发展基于Kubernetes的融合函数即服务的技术fPaaS(又称FaaS)。(5)基于成本考虑,云原生技术更多部署在裸机或者针对容器化定制的微虚拟机上。(6)越来越多的第三方软件提供商采用容器化技术轻量级部署。(7)对有状态应用的支持越来越丰满。(8)跨Kubernetes的成熟项目将会越来越多。第2章Kubernetes核心对象Kubernetes这个名字源于希腊语,意思是舵手。在2014年,谷歌开放了Kubernetes项目。它是建立在谷歌运行大规模生产系统的基础之上,结合社区的最佳创意和实践构建的一个可移植、可扩展的开源平台。Kubernetes主要是通过API或者声明式配置管理容器化工作负载和服务的一整套系统。Kubernetes主要提供了以下功能:●服务发现和负载均衡。Kubernetes可以使用DNS名称或使用自己的IP地址公开容器。如果容器的流量很高,Kubernetes也支持将这些流量均衡分配,以确保系统稳定。●存储编排。Kubernetes允许用户自动加载自选的存储系统,例如本地存储、NFS存储等。●自动部署和回滚。Kubernetes可以描述已部署容器的所需状态,并且可以以受控的方式更新现有状态到预期状态。●管理资源。Kubernetes允许用户指定每个容器请求的资源,以便更好地管理容器的资源。●自我修复。Kubernetes可以重新启动失败的容器、替换容器,也可以终止不响应用户自定义的运行状况检查的容器。●密钥和配置管理。Kubernetes允许用户存储和管理敏感信息,例如密码、TLS证书等。用户可以部署和更新机密信息而无须重建容器,也不会泄露机密信息。Kubernetes不是一个传统PaaS平台,它提供的功能包括部署、扩展、负载平衡、日志记录和监控,且解决方案都是可选和可插拔的。本章内容的主旨不是全面讲述Kubernetes部件,而是进行提炼,讲述与后续部署以及云原生架构相关的关键点。具体如何使用、管理Kubernetes还请参考官方文档。2.1Kubernetes架构Kubernetes分控制节点(MasterNode)和工作节点(WorkerNode),如图2-1所示。其对外提供的操作接口全部通过APIServer对接。无论是图形界面还是命令行工具,都是通过访问APIServer与Kubernetes交互,这样就能符合云原生架构的要求——通过API来操作基础架构。在Kubernetes中,Master节点可以是一个,也可以是通过KeepAlived技术组建的MasterCluster,以保证高可用性。图2-1Kubernetes架构2.1.1工作节点工作节点(Node)是在Kubernetes中承载业务工作的节点。在后面部署Kubernetes集群时可以看到,节点可以是一个虚拟机,也可以是一台裸机。每个节点上都运行Docker、kubelet和kube-proxy等服务,从而保障Pod的正常运行。所有工作节点由Master组件进行统一管理。1.查看节点通过以下命令可以查看节点运行状态:ROLES为master的表示该节点上运行了管理控制器。2.创建节点严格意义来说,节点不能通过命令创建。只能按照部署的方法准备好一台虚拟机或裸机,然后通过kubeadmjoin命令加入到Kubernetes集群中。2.1.2Master节点Master节点是一个Kubernetesmaster组件,管理工作节点的方方面面。这个节点的任务非常重要,所以在生产环境下,一般通过KeepAlived等技术手段组件集群(一般是3个节点组成)来确保master组件的正常运行和持续提供管理功能。2.1.3Docker镜像库Kubernetes中运行的所有镜像都来源于某个镜像库,可以是DockerHub,也可以是客户自建的私有Docker镜像库。节点在收到创建Pod的命令后,将去Docker镜像库中拉取镜像,因此每个节点与Docker镜像库之间的网络链接必须是通畅的。2.2命名空间命名空间(Namespace)是Kubernetes中的一个重要概念,如同编程语言中的命名空间,它把系统内部的对象归集到不同的逻辑小组中,从而便于分别管理。Kubernetes默认有一个default命名空间,在操作时没有指明命名空间的对象都在default下。一般情况下,还会有一个kube-system命名空间,Kubernetes中管理方面的对象基本都在该命名空间下,一般不建议用户放置普通应用对象在该命名空间下。1.查看命名空间获取命名空间列表可以通过如下命令查看:2.创建命名空间可以通过命令来创建命名空间,如创建kube-log命名空间。也可以通过声明文件来创建命名空间。3.使用命名空间如果要查找某个命名空间下的对象,必须在kubectl参数中指明namespace。如下命令是查询在kube-log命名空间下的Pod对象。4.命名空间和DNS创建服务时,也会创建相应的DNS条目<service-name>.<namespace-name>.svc.cluster.local,这在跨命名空间中使用Service时就比较有用了,此时必须使用完全限定的域名(FQDN)。2.3PodPod是Kubernetes中创建应用的最小、最简单的基本执行单元。Pod封装了应用程序的容器(一个或多个)、存储资源、网络以及其他相关选项。这表明:●Kubernetes直接管理Pod,而不是容器。●Pod可以封装多个协作的容器,类似于DockerStack。●每个Pod仅运行某个应用程序的单个实例,如果要水平扩展,不建议使用Pod部署。2.3.1创建Pod尽管在Kubernetes中可以通过命令来创建对象,但是如果创建对象的参数比较多,本书建议通过声明文件来创建。下面的声明文件用来创建一个镜像为busybox的Pod。2.3.2Pod内部多个容器Pod支持多个协作容器组成一个有凝聚力的服务单元。Pod中的容器自动放置在同一个节点上,共同调度,共享资源和依赖关系,彼此通信,并协调何时可以终止,以及如何终止。Pod具有这种能力,不代表我们可以随意使用这种模式,毕竟在云原生应用中,需要尽量确保每个部件可以自动扩展,并减少彼此的依赖性。而聚合多个容器的Pod则增加了依赖性,所以只能在特定的场景下使用该模式。例如伴生模式下的容器,后文会提到两个容器共享同一个存储卷,从而形成内容管理和内容发布两个容器聚合在同一个Pod中对外透明服务。图2-2演示了一个Pod内有两个容器,分别是Drupal站点和Drupal后端数据库。但在这种模式下无法横向扩展,只有Drupal站点系统和MySQL数据库分离后在不同的Pod中才能进行扩展。图2-2一个Pod多个容器2.3.3初始化容器Pod能够聚合多个容器,应用在容器里面运行,但是它也可能有一个或多个先于应用容器启动的初始化容器(Initcontainer)。初始化容器与普通容器非常像,除了如下两点:●它们总是运行到完成。●每个都必须在下一个启动之前成功完成。如果Pod的初始化容器失败,Kubernetes会不断地重启该Pod,直至初始化容器成功。当然,如果Pod对应的restartPolicy值为Never,则不会重新启动。在本书所提及的Elasticsearch部署案例中,使用了三个初始化容器,按照以下顺序执行:●修正存储卷的权限。●修改系统参数vm.max_map_count。●修改系统参数ulimit的值。描述初始化容器:修正存储卷的权限:增加系统参数vm.max_map_count到262144:增加ulimit值:2.3.4状态探针在Kubernetes中,通过kubelet对容器进行持续探测来判断容器是否可用,一旦容器不可用,kubelet将重启该容器。为了更精确地判断容器状态,Kubernetes中提供了就绪探针(ReadinessProbe)和存活探针(LivenessProbe)。存活探针用于判断容器启动就绪后是否还在持续正常服务。业务有可能会因为某种错误而导致系统不可用,或者普通的探测方法不足以判断业务是否正常工作,此时可以通过设置自定义的存活探针来检测。就绪探针用于判断容器是否可以接受流量,是针对有前端服务的容器来讲的。有些容器可能已经启动完毕,但是业务系统还不能正常处理请求。例如Tomcat启动需要1min,此时要进行存活状态检测将返回不可用,前端服务就不会将请求转给容器。存活探针的事例代码如下,在该代码中,使用了httpGet方法去探测,访问的path是/healthz,并且在容器启动3s后进行判断,之后每隔3s进行一次探测。就绪探针和存活探针非常类似,只是将livenessProbe换成readinessProbe。其中几个关键参数说明如下:●initialDelaySeconds:容器启动后第一次执行探测需要等待多少秒。●periodSeconds:执行探测的频率。默认间隔是10s,最小1s。●timeoutSeconds:探测超时时间。默认1s,最小1s。●successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。●failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。2.3.5测试工具Kubernetes中容器所在的网络与客户端所在的网络是不能直接通信的,这就导致部署一个Pod后,如果需要测试其功能将非常麻烦。为此,Google推出了一个busybox镜像,该镜像含有基本的网络工具,用于在容器网络中测试。例如,可以通过命令来ping一个名称为test的Pod:也可以访问容器内的某个网站:2.4部署Kubernetes中的部署是指如何控制一组Pod的运行状态使其满足生产需要。部署分为无状态部署和有状态部署。无论哪种部署,其内部都有副本集控制功能。首先了解ReplicaSet是如何控制副本数量的。2.4.1ReplicaSetReplicaSet的目的是维护一组状态稳定的Pod副本,从而保证指定数量的相同Pod的可用性。它主要通过以下声明来控制副本数量:之前曾有ReplicationController,后来逐渐被ReplicaSet替代。ReplicaSet声明文件中,需要Pod模板以进行复制,同时也需要标签选择器.spec.selector.matchLabels以选择当前Pod的副本。在nfs-provisioner的模板声明文件中有标签为app:nfs-provisioner的选择器,部分代码如下:请注意,.spec.template.metadata.labels必须和.spec.selector.matchLabels匹配,否则无法创建ReplicaSet。在Pod运行过程中,也可以通过kubectlscale命令手动调整副本数量:也可以自动调整ReplicaSet的副本数量,下面的命令是对foo这个ReplicaSetController设置自动调整规则——最多5个副本,而且在CPU使用率达到80%的时候需要增加副本。在Kubernetes中,自动分配副本数量的算法如下:例如当前副本数量是2,CPU度量值为200MHz,期望度量值为100MHz,则应当的副本数量为200/100=2。如果当前CPU度量值为300MHz,而期望度量值为200MHz,则应当的副本数量为300/200=1.5,进位取整后为2。所以不需要调整副本数量。除了通过命令来控制Pod副本数量,还可以通过声明文件来控制,其类型为HorizontalPodAutoscaler。以下声明和命令的效果是一致的。请注意,自动调整Pod副本数量的依据是度量值。在上面的例子中是通过CPU的averageUtilization来进行判断的,也可以根据Value、AverageValue、requests-per-second、packets-per-second等度量值来进行判断。Kubernetes从1.8版本开始使用额外的工具MetricsServer(/kubernetes-incubator/metrics-server)收集度量指标,因此需要单独安装MetricsServer。安装完成后,若出现无法收集指标的故障,则需要修改metrics-server-depolyment.yaml文件,添加args参数,然后重新应用该文件。修改部分代码如下:2.4.2部署部署(Deployment)是一个拥有ReplicaSet并通过声明来控制Pod滚动、更新的对象。虽然ReplicaSet可以独立使用,但是它主要被用作协调Pod创建、删除和更新的机制。使用部署时,用户不必担心副本集,因为部署通过ReplicaSet进行管理,所以,本书建议使用部署而不是ReplicaSet。下面是一个部署的声明文件,部署了3个nginx的Pod副本:这个例子与ReplicaSet的示例是一样的,这是因为部署通过ReplicaSet来控制副本数量。但是如何更新副本数量,则是部署的职责,其通过StrategyType、RollingUpdateStrategy等属性来控制如何更新Pod副本。.spec.strategy.type的可选值有重建(Recreate)和滚动更新(RollingUpdate)。Recreate是指重建所有Pod,其过程为先终止Pod所有的副本,然后重新创建指定数量的Pod副本。而RollingUpdate则采取一定的控制策略来逐步更新Pod副本。.spec.strategy.rollingUpdate.maxUnavailable是一个可选字段,是指更新过程中最大不可用的Pod数量。该值可以是绝对数值,也可以是百分比。其默认值为25%。例如,如果该值为25%,则原有部署中的ReplicaSet立刻将副本数量缩减为75%,然后准备新的Pod副本,再继续控制25%的不可用的比例,逐步缩减原有Pod副本,直至所有Pod更新完成。.spec.strategy.rollingUpdate.maxSurge也是一个可选字段。它指定了Pod副本的最大副本数量。例如取默认值为25%,则在更新部署时可创建的Pod副本数量是期望副本数量的125%。.spec.minReadySeconds是一个可选字段,默认为0。它指明新创建的Pod在没有任何容器崩溃的情况下到内部应用所需的时间。例如作者所在学校部署ApereoCAS时,在Pod创建完成并running状态下,CAS启动正常还需要约1min,则需设置.spec.minReadySeconds=60。下面是影响升级过程的几个重要参数:(1)新的ReplicaSet创建maxSurge所指定数量的Pod副本,此时新旧Pod副本数量为期望副本数量和maxSurge个副本数量之和。(2)在创建新的Pod副本时,马上从旧的ReplicaSet中删除maxUnavailable个Pod。这时可用Pod副本数量为期望副本数量减去maxUnavailable。(3)当新创建的Pod副本有一个可用时,马上从旧的ReplicaSet中删除一个Pod,如此反复直至所有旧的Pod被新的Pod替换。这就要求maxUnavailable和maxSurge不能同时为0。如果在版本升级过程中又触发了更新的版本升级,则Kubernetes会暂停之前版本的替换过程,用最新的版本替换之前刚刚升级的版本,然后再用最新的版本替换还未升级的版本。部署可以回滚到以前的版本,也支持扩展和自动扩展。2.4.3有状态部署有状态部署(StatefulSets)是用于管理有状态应用程序工作负载的一种部署方法。区别于无状态部署(Deployment),StatefulSets可以对Pod副本进行排序并保证每个Pod的唯一性。在无状态部署中,删除一个Pod,新建一个Pod,对于所有Pod来讲都是一致的。但是在StatefulSets中,每个Pod都有唯一的持久标识符,即使在重建后也会继续保留该标识符。有状态部署适合以下场景:●需要独特的网络标识符。●需要独立持久的存储。●需要有序的部署和扩展。●需要有序的升级。下面演示创建一个nginx的StatefulSet部署。主要内容有:●名称为nginx的无头服务。●名称为web的StatefulSet。以上声明文件与无状态部署(Deployment)一致,只是系统在创建后的Pod标识符是唯一且有序数的。通过kubebctlgetpods命令查看,可以看到每个Pod的名称为web-<序数>,而不是web-<随机字符串>。这样,每个Pod也都有自己独立易记且固定的主机名称,例如web-0,其FQDN为web-0.nginx.default.svc.cluster.local。每个Pod的存储卷也是特定的,不能混用。而且删除Pod时,为了保留该状态,持久卷不会自动删除。在StatefulSet中Pod的部署过程与无状态部署完全不同。在无状态部署中,Pod副本并发创建,而在有状态部署中,Pod是依次顺序创建。在上例中,web-0、web-1和web-2是依次创建,而且web-1是在web-0创建完成并且正常运行后再创建。如果要删除部署,则顺序恰好相反,最晚创建的容器被最早删除。2.4.4DaemonSet一个DaemonSet确保每个节点上只运行一个副本。若有节点添加到集群中,将在新增的节点上运行唯一一个Pod,若节点删除,则从该节点上终止Pod。DaemonSet适合以下场景:●每个节点上运行集群存储后台驻留程序,例如glusterd、ceph。●每个节点上运行日志守护程序,例如fluentd、logstash。●每个节点上运行Prometheusnodeexporter、sisdig、collectd等代理。DaemonSet的示例在此不再详述,在讲解日志和监控时会详细描述DaemonSet。2.5服务Kubernetes内部的部署只能在集群内部访问,若要暴露这些工作负载,Kubernetes提供了工作在ISO/OSI模型的传输控制层的服务和工作在应用层的Ingress两种方式暴露后端工作负载。2.5.1关于服务Kubernetes的Pod是有生命周期的,它可以被系统自动创建和销毁,IP是动态分配的,且仅限集群内网访问。这就产生了一个问题:前端客户如何访问这些Pod呢?Kubernetes服务(Service)定义了这样一种抽象:在逻辑上通过标签来选定一组Pod,提供一种策略,让外网和前端客户能够访问这组Pod。例如在StatefulSet中定义的nginx服务,通过app:nginx标签来选定拥有此标签的Pod,然后对外提供80端口的Web服务。服务将根据一定的策略将外网的Web请求转发给后端Pod,这样就对前端用户隐藏了后端Pod的存在。服务不仅可以指向集群内部的Pod,也可以指向集群外部的资源。通过指向外部资源的服务,集群内部的Pod可以像访问内部资源一样方便地访问外部资源,尤其是外部资源后续需要迁移到集群内部的场景下更是如此。下例是指向外网资源的一个示例。1.无头服务(HeadlessService)在有些场景下业务不需要负载均衡,或者不需要单独的ServiceIP,此时业务可以使用HeadlessService。在HeadlessService中,.spec.clusterIP需要设置为“None”。这也就决定了HeadlessService只能在集群内部使用。HeadlessService可以有选择器,也可以没有选择器。一般情况下服务都会配置选择器。通过配置选择器,服务会在DNS中为每个Pod配置A记录,通过访问服务名称,DNS会返回后端Pod的地址,这可以用于Pod之间通过域名互相访问。2.服务类型服务根据暴露方式可以分为4种类型,默认为ClusterIP类型。类型通过Type的取值来描述:●ClusterIP:通过集群的内部IP暴露服务。选择该值,服务只能在集群内部访问。●NodePort:通过在每个节点上创建相同的端口来暴露服务。NodePort服务会路由到ClusterIP服务,这个ClusterIP会自动创建,也可以手工指定。●LoadBalancer:使用云提供商的负载均衡设备向外暴露服务。例如GoogleCloud、OracleCloud等厂商都提供外部负载均衡设备,外部均衡设备路由到ClusterIP服务。Google开源了一个MetalLB项目,用于裸机上的负载均衡服务。●ExternalName:通过返回CNAME和它的值,可以将服务映射到externalName字段指定的内容。3.NodePort类型.spec.type的值为NodePort时,Kubernetes会在给定的配置范围内(默认30000~32767)分配端口,也可以直接指定在该范围内的端口。每个节点将该端口代理到ClusterIP服务。下例通过app:nginx选择Pod,并开启30080端口进行访问。4.LoadBalancer类型若要使用支持外部负载均衡设备的云提供商的服务,请设置.spec.type为LoadBalancer。具体的配置需要参照各云提供商的说明。5.外部IP可以在服务中设置外部IP,将服务暴露给这个外部IP,从而通过外部IP进入集群。外部IP必须和节点IP在同一个网段。注意:Kubernetes无法管理这些外部IP,它属于集群管理员的职责范畴。下例是为my-site
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年广东省韶关市单招职业适应性测试题库及完整答案详解1套
- 2026年郑州体育职业学院单招职业技能测试题库参考答案详解
- 2026年浙江理工大学单招职业倾向性考试题库及参考答案详解
- 四川省遂宁市射洪中学2024-2025学年高二上学期期中考试地理试题含答案地理答案
- 医院笔试面试题目及答案
- 2025年·锦州市部分事业单位赴高校公开招聘应届毕业生备考题库(第二批)及一套答案详解
- 2026年龙游县机关事业单位编外人员招聘备考题库及1套完整答案详解
- 昆明市第十二中学教育集团2025年12月聘用制教师招聘备考题库有答案详解
- 2025年成都市金牛国投人力资源服务有限公司公开招聘26名网格员备考题库及1套参考答案详解
- 中国铁建投资集团有限公司2026届校园招聘30人备考题库完整答案详解
- 钻井工程防漏堵漏技术演示文稿
- GB/T 27806-2011环氧沥青防腐涂料
- GB/T 12618.1-2006开口型平圆头抽芯铆钉10、11级
- FZ/T 52051-2018低熔点聚酯(LMPET)/聚酯(PET)复合短纤维
- 设备吊装方案编制受力计算
- 食品工程原理概述经典课件
- 养老院机构组织架构图
- 财经法规与会计职业道德
- 会计学本-财务报表分析综合练习
- 传播学概论教学课件
- 《中国传统文化心理学》课件第五章 传统文化与心理治疗(修)
评论
0/150
提交评论