版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
云原生架構進階實戰(zhàn)目錄TOC\h\h第1章云原生架構\h1.1云計算的演化\h1.2什么是云原生\h1.3云原生基礎架構\h1.4云原生應用\h1.4.1微服務\h1.4.2健康狀況報告\h1.4.3自動測量數(shù)據(jù)\h1.4.4彈性處理故障\h1.4.5聲明式通信\h1.5十二要素應用\h1.6實現(xiàn)云原生模式\h1.7何時采用云原生\h1.8云設計模式\h1.9服務網(wǎng)格(ServiceMesh)\h1.10云原生的未來\h第2章Kubernetes核心對象\h2.1Kubernetes架構\h2.1.1工作節(jié)點\h2.1.2Master節(jié)點\h2.1.3Docker鏡像庫\h2.2命名空間\h2.3Pod\h2.3.1創(chuàng)建Pod\h2.3.2Pod內(nèi)部多個容器\h2.3.3初始化容器\h2.3.4狀態(tài)探針\h2.3.5測試工具\h2.4部署\h2.4.1ReplicaSet\h2.4.2部署\h2.4.3有狀態(tài)部署\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創(chuàng)建并使用NPMRegistry\h3.1.5創(chuàng)建并使用DockerRepository\h3.1.6創(chuàng)建Maven2LocalRepository\h3.1.7總結\h3.2部署Kubernetes\h3.2.1環(huán)境準備\h3.2.2安裝DockerCE\h3.2.3安裝kube工具\h3.2.4構建Master節(jié)點\h3.2.5在客戶端設置環(huán)境\h3.2.6部署Flannel網(wǎng)絡\h3.2.7加入工作節(jié)點\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創(chuàng)建磁盤分區(qū)\h3.4.5安裝軟件\h3.4.6配置防火墻\h3.4.7配置信任池\h3.4.8創(chuàng)建GlusterFS卷\h3.4.9GlusterFS卷安全\h3.4.10GlusterFS快照\h3.4.11vSAN與GlusterFS的比較\h3.5使用GlusterFS卷\h3.5.1靜態(tài)卷的使用\h3.5.2動態(tài)卷的使用\h3.6使用NFS卷\h3.6.1前提條件\h3.6.2授權\h3.6.3創(chuàng)建provisioner和StorageClass\h3.6.4測試\h3.7升級Kubernetes\h3.7.1升級Master節(jié)點\h3.7.2升級工作節(jié)點\h3.7.3查看升級結果\h第4章DevOps實戰(zhàn)\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模式的優(yōu)勢\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上創(chuàng)建Elasticsearch集群\h5.4部署Kibana\h5.4.1在Docker中部署Kibana\h5.4.2在Kubernetes上部署Kibana應用\h5.5部署fluentd作為syslogserver\h5.5.1創(chuàng)建fluentd服務\h5.5.2創(chuàng)建fluentd應用\h5.5.3測試\h第6章云原生下的監(jiān)控\h6.1Prometheus簡介\h6.1.1Prometheus組成及架構\h6.1.2使用Prometheus的場景\h6.1.3Prometheus相關概念\h6.2使用Exporter采集數(shù)據(jù)\h6.2.1常用Exporter\h6.2.2Exporter的運行方式\h6.2.3NodeExporter\h6.2.4容器監(jiān)控cAdvisor\h6.2.5黑盒監(jiān)控BlackboxExporter\h6.3在Kubernetes中部署Prometheus\h6.3.1創(chuàng)建RBAC文件\h6.3.2創(chuàng)建服務\h6.3.3創(chuàng)建配置文件\h6.3.4部署Prometheus\h6.4部署B(yǎng)lackboxExporter\h6.4.1BlackboxExporter配置文件\h6.4.2BlackboxExporter部署文件\h6.5NodeExporter\h6.5.1創(chuàng)建NodeExporter服務\h6.5.2創(chuàng)建NodeExporterDaemonSet\h6.6Grafana\h6.7在Kubernetes中部署Grafana\h6.7.1創(chuàng)建持久卷聲明\h6.7.2部署Grafana\h6.7.3Grafana配置文件\h6.7.4創(chuàng)建Service\h6.8案例:監(jiān)控Drupal站點\h6.8.1Drupal準備\h6.8.2準備鏡像\h6.8.3準備stack文件\h6.8.4設置Grafana\h第7章服務網(wǎng)格應用\h7.1Istio架構\h7.1.1Istio的目標\h7.1.2服務網(wǎng)格資源\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分布式調(diào)用追蹤\h7.4.2遙測度量收集\h7.4.3灰度發(fā)布應用\h7.4.4熔斷\h7.4.5故障注入\h7.5總結\h第8章案例\h8.1在Kubernetes中部署Drupal8站點\h8.1.1準備GlusterFS卷\h8.1.2創(chuàng)建PersistentVolumeClaim\h8.1.3創(chuàng)建數(shù)據(jù)庫部署(Deployment)\h8.1.4創(chuàng)建Drupal部署\h8.1.5安裝Drupal\h8.1.6總結\h8.2云原生架構下的Node.js自動CI/CD方法\h8.2.1Node.js示例\h8.2.2在Kubernetes集群中創(chuàng)建GitLab賬戶\h8.2.3部署DockerRegistry\h8.2.4配置GitLab\h8.2.5通過GitLab構建Docker\h8.2.6部署應用到Kubernetes集群中\(zhòng)h8.3ApereoCAS自動橫向縮放部署策略\h8.3.1CAS簡介\h8.3.2前提條件\h8.3.3準備環(huán)境\h8.3.4CAS模板修改\h8.3.5持續(xù)集成\h8.3.6持續(xù)部署\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持續(xù)交付\h8.5.4微服務\h8.5.5困難第1章云原生架構1.1云計算的演化在云原生概念之前,讀者已經(jīng)熟知虛擬化技術、云計算方法。虛擬化是將不存在的事物或現(xiàn)象虛擬成存在的事物或現(xiàn)象的方法,在計算機領域則是指軟硬件資源的虛擬化。硬件資源的虛擬化包括計算資源虛擬化、存儲資源虛擬化和網(wǎng)絡資源虛擬化。利用虛擬化技術,可以將物理資源抽象為統(tǒng)一的邏輯表示,例如通過VMware的虛擬化技術,所有虛擬服務器都擁有統(tǒng)一的設備型號。利用虛擬化技術,也可以使得虛擬資源不受物理資源的限制,例如一臺物理服務器可以虛擬成多臺服務器,多臺物理服務器也可以虛擬成一臺服務器,從而整合硬件資源,提高資源利用率。虛擬化技術目前做得較好的公司有VMware、Citrix、Microsoft、RedHat和Oracle等公司。虛擬化技術的發(fā)展如圖1-1所示。從1998年VMware引入x86虛擬化技術用于普通PC的虛擬,到2001年發(fā)布ESX實現(xiàn)服務器的虛擬,之后Citrix發(fā)布了Xen;Microsoft發(fā)布了VirtualPC和Hyper-V;RedHat借助Linux的優(yōu)勢發(fā)布了KVM;而Oracle則收購了VirtualBox。各大廠商都有了自己的虛擬化技術。圖1-1虛擬化技術的發(fā)展盡管虛擬化技術可以有效地簡化數(shù)據(jù)中心管理,降低數(shù)據(jù)中心的運營成本,但是并不能取消為了使用IT系統(tǒng)而進行的數(shù)據(jù)中心構建、硬件采購、軟件安裝和系統(tǒng)維護等環(huán)節(jié),企業(yè)仍需要配備較多IT運維人員去從事物理資源的相關準備工作、軟件系統(tǒng)的部署工作。此時人們更希望出現(xiàn)一種能夠?qū)τ嬎?、存儲和網(wǎng)絡等資源的按需自動分配、按使用量付費的服務,這就催生了云計算模式。云計算借助虛擬化技術的伸縮性和靈活性,進一步提高了資源利用率,簡化了資源和服務的管理與維護,減少了數(shù)據(jù)中心的運營成本。根據(jù)云計算服務提供的內(nèi)容,業(yè)界把云計算分成三層:基礎架構即服務(IaaS)、平臺即服務(PaaS)和軟件即服務(SaaS)。根據(jù)云計算服務提供的來源和服務對象,云計算分為公有云和私有云。云計算的發(fā)展如圖1-2所示。2006年Amazon(亞馬遜)開始提供S3存儲和EC2虛擬服務器的云服務;2009年Heroku提供了第一款PaaS云服務。2011年誕生了開源的IaaS實現(xiàn)——OpenStack,同年Pivotal開源了PaaS的實現(xiàn)——CloudFoundry。2014年誕生了第一款商用函數(shù)即服務(FaaS),更加推動了云服務的深度應用。圖1-2云計算的發(fā)展在虛擬化計算和云計算服務蓬勃發(fā)展的階段,人們也意識到了虛擬化技術的弊端。虛擬化技術虛擬出來的是一個完整操作系統(tǒng),它的底層包括宿主機操作系統(tǒng)和虛擬化層,勢必導致虛擬機的性能低于物理機的性能。此外,完整的操作系統(tǒng)所占用的存儲空間較大,而且啟動一個虛擬機,等同于啟動一個完整操作系統(tǒng)。但是往往在虛擬服務器中可能僅僅是為了運行某一個軟件而已。為此,LXC(LinuxContainer)技術和Docker技術開始出現(xiàn)。它摒棄了啟動完整系統(tǒng)的弊端,在現(xiàn)有操作系統(tǒng)上對任務進行隔離,并實現(xiàn)資源按需分配。它允許多個容器共享一個操作系統(tǒng)內(nèi)核,容器內(nèi)存儲的僅僅是與某個應用緊密相關的資源,其空間占用往往只有幾十到幾百MB。單獨容器化如同虛擬PC一樣會面臨高可用性不足、管理低級等問題。為此,業(yè)界推出了容器編排技術,其發(fā)展如圖1-3所示。2014年Google開源了Kubernetes(簡稱K8S),它是一種容器編排工具。容器編排工具將容器生命周期管理能力擴展到部署在大量機器集群上復雜的多容器工作負載,并且為開發(fā)人員和基礎設施團隊提供了一個抽象層來處理大規(guī)模的容器化部署。眾多公司加入到了容器編排技術大戰(zhàn)中,但是到了2017年,MESOS和Docker相繼宣布支持Kubernetes,徹底奠定了Kubernetes在容器編排工具中的地位。2018年,Kubernetes從云原生計算基金會中畢業(yè)。圖1-3容器技術和編排技術的發(fā)展隨著虛擬化技術、云計算服務以及容器化技術的發(fā)展,越來越多的開發(fā)者和IT設施運維人員開始團隊協(xié)作,改變過往獨立運作的傳統(tǒng),開始對現(xiàn)有基礎架構、運維人員的職責、開發(fā)團隊的文化以及軟件開發(fā)模式進行思考和研究,逐漸形成了云原生的概念。1.2什么是云原生云原生(CloudNative)概念是由Pivotal的MattStine在2013年首次提出的。這個概念得到了社區(qū)的不斷完善,內(nèi)容越來越豐富,目前已經(jīng)包括了DevOps(Development和Operations的組合)、持續(xù)交付(ContinuousDelivery,CD)、微服務(MicroServices)、敏捷基礎設施(AgileInfrastructure)和十二要素(TheTwelve-FactorApp)等幾大主題。這個概念不但包括根據(jù)業(yè)務能力對企業(yè)(高校)進行文化、組織架構的重組與建設,也包括方法論和原則,以及具體的操作工具。采用基于云原生的技術和管理方法,可以更好地從云中誕生業(yè)務,也可以把業(yè)務遷移到不同的云中,從而享受云的高效與持續(xù)服務的能力。2015年云原生計算基金會(CNCF)成立,對云原生定義進行了修改,認為云原生需要包含應用容器化、面向微服務架構以及支持容器編排調(diào)度等方面的內(nèi)容。2018年,隨著云原生生態(tài)的壯大,主流云計算供應商都加入了該基金會,隨之云原生定義又進一步得到完善。云原生技術增強了公司和機構在現(xiàn)代動態(tài)的環(huán)境中構建和運行可彈性擴展的應用,這些環(huán)境主要是公有云、私有云和混合云的環(huán)境。容器、服務網(wǎng)格、微服務、敏捷基礎結構和聲明性API都是這些方法的例證。這些技術能夠構建可彈性擴展的、可管理的、可觀察的松耦合系統(tǒng)。結合自動化手段,云原生技術可以使得開發(fā)者以最低的成本對系統(tǒng)進行頻繁并可預測的重大變更。云三層模型與云原生架構的對比如圖1-4所示,原先的IaaS層升級為敏捷基礎設施,而PaaS和SaaS層則合并為微服務架構。敏捷基礎設施和微服務都屬于技術范疇的架構。在整個云原生架構中,也少不了自動化的持續(xù)交付和DevOps等管理措施。圖1-4云原生架構在傳統(tǒng)的應用系統(tǒng)開發(fā)過程中,軟件開發(fā)商喜歡聚焦在業(yè)務系統(tǒng),專注于系統(tǒng)如何開發(fā)、如何閉源成一個獨立的整體系統(tǒng)。但是隨著開源軟件的盛行,全球合作背景下的分工細化,再加之GitHub的影響力越來越大,一個軟件開發(fā)商很難在短時間內(nèi)處理所有問題。軟件開發(fā)商應該充分利用第三方開源或不開源的組件,自己僅僅實現(xiàn)必要的代碼,再借助敏捷基礎架構進行靈活多變的必要集成,從而節(jié)省大量人力、物力和時間,以便更加聚焦業(yè)務開發(fā),同時又能利用整體協(xié)作快速部署業(yè)務。云原生的意義就在于此,按照云原生的理念進行頂層架構設計、實施、部署,即可實現(xiàn)快速迭代,投入生產(chǎn)使用。云原生主要包括兩部分內(nèi)容:云原生基礎架構和云原生應用。1.3云原生基礎架構云原生基礎架構是隱藏在抽象背后的由軟件管理并由API進行控制的基礎架構,它的目標是運行應用系統(tǒng)。這也就興起了一種新的管理模式——通過這些特性以可擴展、高效的方式進行基礎設施管理。有用的抽象是具有重要意義的,它可以讓開發(fā)者專注于自己的業(yè)務而無須了解底層、實現(xiàn)底層,更可以避免重復實現(xiàn)底層。由軟件來管理基礎架構是與云的一個關鍵區(qū)別。軟件控制的基礎架構使得基礎架構能夠擴展,也就實現(xiàn)了資源彈性處理、資源置備和資源可維護。這種軟件管理基礎架構的模式不僅影響了基礎架構的管理和運行,也影響了在其上運行的應用系統(tǒng),從系統(tǒng)架構到系統(tǒng)開發(fā)、部署、運維都有了重大變化。云原生基礎架構不僅僅是在公有云上運行基礎架構,也不是在容器中運行應用程序,所以公有云和容器化不是云原生基礎架構的代名詞。但是云原生基礎架構可以借助容器化技術和公有云技術去實現(xiàn)。公有云僅僅是IaaS層的實現(xiàn),一般的公有云還是要借助人力去申請、分配。而云原生基礎架構則是用程序代碼自動去申請。容器僅僅是應用程序的一種打包方式,這并不意味著這些應用程序具備自治功能。即使應用程序是通過持續(xù)集成和持續(xù)交付等DevOps流水線自動構建和部署的,也并不一定就是云原生基礎架構。Kubernetes也不能簡單地稱為云原生基礎架構。Kubernetes的容器編排技術為云原生基礎架構提供了必要的平臺支撐功能。是否是云原生基礎架構的關鍵在于是否使用自動化處理的方式。例如在Kubernetes中手工分配物理卷,就不能稱為云原生基礎架構,因為物理卷不是自動分配的。而如果使用動態(tài)卷,依靠卷聲明來分配容量,進而分配使用該卷的容器,則滿足了云原生基礎架構的要求。云原生應用對基礎架構的基本要求有:●運行時間和隔離?!褓Y源分配和調(diào)度。●環(huán)境隔離?!穹瞻l(fā)現(xiàn)。●狀態(tài)管理?!癖O(jiān)測和日志記錄?!穸攘烤酆稀!裾{(diào)試和追蹤。云應用程序肯定會依賴一個或多個服務來提供業(yè)務價值。提供一種讓服務在每個環(huán)境的基礎上找到彼此的方法是基礎架構的責任。有些應用的服務發(fā)現(xiàn)需要調(diào)用API來實現(xiàn),而有些應用則通過DNS或者網(wǎng)絡代理透明地發(fā)現(xiàn)。具體的實現(xiàn)方式不重要,重要的是使用服務發(fā)現(xiàn)服務。云原生應用程序和基礎架構協(xié)作以發(fā)現(xiàn)其相關依賴服務。例如Prometheus抓取監(jiān)控信息的動作主要在配置文件中描述,但是如果Prometheus監(jiān)控的目標是動態(tài)的,則需要部署人員每次去修改Prometheus配置文件,這是非常麻煩的,而且人工操作易出錯。為此,Prometheus實現(xiàn)了一種服務發(fā)現(xiàn)方式,主動感知系統(tǒng)監(jiān)控目標的變化,自動添加、刪除和更新服務。以下是一個Kubernetes上的服務允許Prometheus自動發(fā)現(xiàn)的代碼,其中的prometheus.io/scrape:"true"就是為了讓Prometheus感知到該服務。該服務暴露了HTTP協(xié)議訪問,端口為8080,端點為/metrics。1.4云原生應用云原生應用程序的關鍵在于提供彈性、敏捷性、可操作性和可觀察性。彈性的概念隱含了允許應用程序失敗而不是試圖阻止程序失敗的意思。敏捷性允許應用快速部署和快速迭代,這就需要引入DevOps文化。可操作性是指從應用程序內(nèi)部控制應用程序的生命周期,而不是依賴外部進程和監(jiān)視器??捎^察性是指應用程序需要提供信息以反映應用程序的狀態(tài)。目前實現(xiàn)云原生應用程序所需特性的常用方法有:●微服務?!窠】禒顩r報告?!褡詣訙y量數(shù)據(jù)?!駨椥浴!衤暶髂J蕉皇琼憫J健?.4.1微服務傳統(tǒng)應用程序是以單個實體為目標進行管理和部署的,這也是國內(nèi)軟件行業(yè)常用的開發(fā)方式,簡稱為單體應用程序。單體應用程序的好處是顯而易見的,但是它無法解決面向大量互聯(lián)網(wǎng)用戶提供服務的并發(fā)量問題,且使得開發(fā)過程變得臃腫,開發(fā)進程變得緩慢,維護也越來越困難。解決這些問題最好的方法之一就是分解單體應用為眾多小的服務模塊。如圖1-5所示,這些服務模塊相互獨立,使得開發(fā)人員可以獨立維護這些小系統(tǒng),而且開發(fā)和維護過程也變得敏捷。分解成微服務后,各服務的編寫語言也可以自行確定,只需要遵守總體的API優(yōu)先和通信要求即可。圖1-5微服務架構微服務更像是UNIX哲學的實踐和改造。UNIX哲學是“程序應該只關注一個目標,并盡可能把它做好。讓程序能夠互相協(xié)同工作?!崩鏤NIX命令行上的統(tǒng)計文件數(shù)量,通過下面的命令管道就可以把列表和統(tǒng)計兩個命令串聯(lián)起來使用。微服務也是如此,服務更專注于其用途,也就是只應做一件事,并把這件事做好。但是微服務不能等同于云原生架構,微服務只是云原生文化的一種實現(xiàn)。1.4.2健康狀況報告為了能夠由軟件控制一切,應用程序必須提供可供管理軟件監(jiān)測的度量指標。而一個應用程序的度量指標只有創(chuàng)建應用程序的作者最清楚,因此在應用程序中內(nèi)置度量指標是最好的設計方式。這要求各應用程序提供必要的端點,供管理軟件訪問以判斷應用程序狀態(tài)。例如Kubernetes、ETCD都通過HTTP提供了大量的度量指標。此外,應用程序應該提供更加豐富且必要的狀態(tài)報告。在云原生架構下,一切皆是代碼,一切皆可由軟件控制。為了可以控制,各應用程序必須提供度量接口讓管理軟件獲知應用程序運行狀態(tài)以做出必要的反應,例如應用程序崩潰時,管理程序可做出停掉當前應用程序?qū)嵗缓髥有聦嵗牟僮?。應用程序的健康狀況只是能夠自動執(zhí)行應用程序聲明周期的一部分,管理程序還需要知道應用程序是否正在工作。1.4.3自動測量數(shù)據(jù)自動測量數(shù)據(jù)是做出決定所必需的信息,這些數(shù)據(jù)與健康狀況報告的數(shù)據(jù)是有重疊的,但是它們的用途不一樣。健康報告是告知管理程序所轄應用程序的生命周期狀態(tài),而自動測量數(shù)據(jù)是告知應用程序的業(yè)務度量指標。度量的指標一般稱為服務級別指標(ServiceLevelIndicator,SLI)或關鍵績效指標(KeyPerformanceIndicator,KPI)。這些指標是特定于應用程序的數(shù)據(jù),讓管理程序監(jiān)測應用程序的性能在服務級別目標(ServiceLevelObjectives,SLO)內(nèi)。自動測量數(shù)據(jù)可以解決以下問題:●應用程序每分鐘收到的請求數(shù)。●是否有任何錯誤?!駪贸绦蜓舆t多久?!駱I(yè)務處理需要多長時間。監(jiān)測數(shù)據(jù)經(jīng)常被抓取或推送到時間序列數(shù)據(jù)庫(如Prometheus或InfluxDB),然后再由度量指標模型進行處理分析,以便后續(xù)提醒或者大屏展示。有一點需要注意的是,自動測量數(shù)據(jù)應該用于提醒場景而不是健康監(jiān)測。在一個動態(tài)可自我修復的環(huán)境中,管理程序幾乎不關心單個應用程序的生命周期,而更多關心應用程序的SLO,因為若是一個程序崩潰,管理程序可以動態(tài)重啟應用程序?qū)嵗曰謴驼_\行狀態(tài)。舉一個例子,在Kubernetes中運行以下命令可以看到coredns重啟過兩次和3次,但是管理程序不關心這個行為,只關心它是否在正常運轉,因為管理程序的SLO就是要正常運轉。1.4.4彈性處理故障云原生應用程序應當正視故障而不是竭力避免故障。唯一不應該有故障的系統(tǒng)是那些維持生命的系統(tǒng)。任何系統(tǒng)都應該有一個合理的SLO,如果無視SLO而去避免故障發(fā)生,則花費的成本將非常巨大。為此,必須假設應用程序可能發(fā)生故障,并采取必要的措施應對故障,這是云原生應用的一種模式。無論發(fā)生什么樣的故障,云原生應用都必須適應,并采取合理的調(diào)整措施應對。此外,云原生應用還需要設計一種方法應對過載,這也是互聯(lián)網(wǎng)應用面臨的常見問題,例如12306售票、淘寶雙11活動時的并發(fā)訪問過載。處理過載的一種常見方法是適度降級。在《SiteReliabilityEngineering》一書中對于應用程序的優(yōu)雅降級做了詳細描述。書中指出在負載過重的情況下,可以采取降低準確性、反饋少量數(shù)據(jù)等方式給用戶適度響應,而不是拒絕服務。盡管減少應用程序負載可以通過負載均衡設備或者動態(tài)擴展等基礎架構進行處理,但是應用程序仍有可能接收到超負載的請求。所以云原生應用要求具備服務優(yōu)雅降級的能力。最現(xiàn)實的處理方式是服務降級,返回部分回應或使用本地緩存中的舊信息進行回應。這部分內(nèi)容在ServiceMesh中得到了很好的解決。1.4.5聲明式通信由于云原生應用程序在云環(huán)境中運行,因此它們與基礎架構和支持應用程序的交互方式與傳統(tǒng)應用程序不同。在云本機應用程序中,與任何內(nèi)容進行通信的方式都是通過網(wǎng)絡。很多時候,網(wǎng)絡通信是通過RESTfulHTTP調(diào)用完成的,但也可以通過其他接口實現(xiàn),例如遠程過程調(diào)用(RPC)。傳統(tǒng)應用程序可以通過消息隊列、共享存儲上的文件或觸發(fā)shell命令的本地腳本來自動執(zhí)行任務。事件發(fā)生后,通信方法根據(jù)本地服務器上的信息做出反應。例如,如果用戶點擊提交,則運行本地服務器上的提交腳本。在傳統(tǒng)應用程序中,通信的介質(zhì)可能是文件或者消息隊列,但是這些方式都是嘗試構建避免失敗的方式,它們在云原生架構下存在一些問題。例如應用程序把結果寫入到文件,寫完后應用程序崩潰了。此時會出現(xiàn)了一種情況:應用程序崩潰之前,計算結果已經(jīng)寫入文件中。按照云原生理念,此時應用程序?qū)⒅貑?,再次?zhí)行計算過程,計算結果再次寫到文件中。因此,開發(fā)人員應該停止使用反應式通信,開始使用聲明式通信,從而提高應用程序的健壯性,并且減少應用程序的依賴。1.5十二要素應用十二要素應用程序方法是Heroku的開發(fā)者起草的。十二要素中提到的特征并不特定于云提供者、平臺或語言。這些要素代表了針對云環(huán)境中蓬勃發(fā)展的可移植彈性應用程序(特別是“軟件即服務”應用程序)的一組準則或最佳實踐。下面列出了這十二要素。(1)一份基準代碼(Codebase),多份部署(Deploy)企業(yè)一般會采用代碼版本控制系統(tǒng)來跟蹤管理所有修訂版本的代碼庫,這樣就只需要一份代碼,卻可以同時存在多份部署,如圖1-6所示。每份部署相當于運行了一個應用的實例。例如作者所在學校的Portal應用,學校有一個生產(chǎn)環(huán)境的部署,也有一個用于測試的預發(fā)布環(huán)境部署。學校將同一套代碼先在預發(fā)布服務器上部署,進行初步評估,然后再發(fā)布到正式生產(chǎn)服務器上。圖1-6一份基準代碼多份部署(2)顯式聲明依賴關系(Dependency)應用程序不會隱式依賴系統(tǒng)級類庫。它一定通過依賴清單確切地聲明所有依賴項。此外,應用程序在運行過程中通過依賴隔離工具來確保程序不會調(diào)用系統(tǒng)中存在但清單中未聲明的依賴項。這一做法在生產(chǎn)和開發(fā)環(huán)境中都是統(tǒng)一的。例如Node.js應用程序通過package.json來聲明依賴項,Maven項目使用pom.xml來聲明依賴項。遵循該要素的應用程序也不會隱式依賴系統(tǒng)級工具,例如ImageMagick和curl等工具,即使這些工具在Linux不同版本中都存在,但無法保證所有未來的系統(tǒng)都部署了該工具,例如Docker中的Linux就不一定存在這兩個工具。如果要使用這些工具,則必須包括在應用程序中。例如Drupal中的命令工具drush就包含在bin目錄下。(3)在環(huán)境中存儲配置十二要素應用推薦將應用的配置存儲于環(huán)境變量中,如圖1-7所示。這允許應用程序非常方便地在不同的部署間修改,而不需要改動一行代碼。例如wget用的環(huán)境變量HTTP_PROXY。還有一種做法是使用配置文件但把該配置文件從版本控制中排除。例如Drupal站點的settings.php文件,里面含有數(shù)據(jù)庫連接信息,為了保證安全,必須將該文件排除在版本控制外。但是有時仍然難免將該文件加入版本控制,從而造成了數(shù)據(jù)庫連接信息泄露。圖1-7在環(huán)境中存儲配置在Kubernetes中,系統(tǒng)會自動將服務根據(jù)名稱創(chuàng)建多個不同的細粒度環(huán)境變量。(4)把后端服務(backingservices)當作附加資源后端服務是指程序運行所需要的通過網(wǎng)絡調(diào)用的各種服務,如數(shù)據(jù)庫(MySQL、CouchDB),消息/隊列系統(tǒng)(RabbitMQ、Beanstalkd),以及緩存系統(tǒng)(Memcached)。符合規(guī)則的應用程序應該可以在不進行任何代碼改動的情況下,將本地數(shù)據(jù)庫切換至異地或者云上的數(shù)據(jù)庫服務。(5)嚴格分離構建、發(fā)布和運行基準代碼通過構建、發(fā)布和運行三個階段轉化成一份部署。構建階段是指將代碼進行編譯、打包等操作,生成可執(zhí)行文件。而發(fā)布則是將構建的結果和相關配置發(fā)布到運行環(huán)境中投入使用。運行階段則是在執(zhí)行環(huán)境中啟動一系列應用程序。例如Node.js應用程序,其構建步驟較為簡單,只需要復制相關文件即可。而發(fā)布到運行環(huán)境時,則通過npminstall安裝相關依賴項;在運行階段可以通過Node.js進程管理工具pm2安裝或者重啟服務。(6)以一個或多個無狀態(tài)進程運行應用符合十二要素的應用程序的進程必須是無狀態(tài)且無共享的。任何需要持久化的數(shù)據(jù)都需要存儲在后端服務內(nèi)。例如ApereoCAS,所有認證的Ticket均保存在后端數(shù)據(jù)庫中,如memcached集群。而需要處理的是session狀態(tài),這個也是需要通過后端memcached或者redis進行統(tǒng)一存儲,或者通過前端負載均衡粘性路由到同一個應用進程中。(7)通過端口綁定(Portbinding)來提供服務符合十二要素的應用程序可以自我加載而不依賴于任何網(wǎng)絡服務器。例如Java代碼可以直接使用JVM的Jetty,而不依賴于Tomcat。這一點就像Node.js不需要Apache一樣。還是以ApereoCAS為例,最新版本的CAS可以自我加載運行,而不依賴Tomcat。如果查看常用軟件的Dockerfile,會發(fā)現(xiàn)這些Docker的執(zhí)行命令不再是以后端程序的方式運行,而是直接以前端運行。例如PHP的Docker鏡像,命令為apache2-foreground。(8)通過進程模型進行擴展在十二要素應用中的進程主要借鑒了UNIX守護進程模型,不同的工作分配給不同類型的進程處理。尤其是無共享、水平分區(qū)的特性讓并發(fā)處理更加簡單。十二要素應用的進程不需要守護進程,也不需要寫入PID文件,而是借助操作系統(tǒng)的進程管理器(如systemd)進行輸出流控制、進程崩潰響應,以及進程的重啟和關閉的請求。(9)快速啟動和優(yōu)雅終止可最大化健壯性十二要素應用的進程是可分解的(disposable),它可以瞬間開啟或者停止。這有利于快速、彈性伸縮應用,迅速部署變化的代碼或配置。進程應當追求最短的啟動時間,一旦接收到終止信號則會優(yōu)雅地終止。進程還應當合理處理意外終止,例如可以在客戶端斷開或者超時連接后自動退回任務。(10)盡可能地保持開發(fā)、預發(fā)布和線上環(huán)境相同開發(fā)人員可能使用Macintosh開發(fā),也可能使用Windows開發(fā),這就造成各種環(huán)境的不一致,尤其是開發(fā)環(huán)境和生產(chǎn)環(huán)境。即便同樣的操作系統(tǒng),也有可能隨著時間變化、工具差異、人員差異等出現(xiàn)不一致。十二要素應用要求必須縮小本地和生產(chǎn)環(huán)境的差異,企業(yè)可以使用Docker來進行環(huán)境的統(tǒng)一,無論是開發(fā)環(huán)境還是生產(chǎn)環(huán)境,都使用Docker來進行測試和正式運行。十二要素應用要求不同環(huán)境下的后端服務也要一致,例如開發(fā)環(huán)境使用MariaDB,則生產(chǎn)環(huán)境亦應使用MariaDB。(11)把日志當作事件流日志使得應用程序運行的動作變得透明。在基于服務器的環(huán)境中,日志通常被寫在硬盤的一個文件里,但這只是一種輸出格式。在十二要素應用中則不應該考慮存儲到自己的輸出流,不應該試圖去寫或者管理日志文件。相反,每一個運行的進程都會直接將日志存儲到標準輸出(stdout)事件流。開發(fā)環(huán)境中,開發(fā)人員可以通過這些數(shù)據(jù)流,實時在終端看到應用的活動。這點在Docker環(huán)境下尤其如此。每個Docker中的應用不應該自己進行日志的管理,而應該直接提交給標準輸出和標準錯誤事件流。下面是PHP鏡像的Dockerfile代碼:這段代碼改造了Apache2的日志,默認情況下,Apache2將訪問日志寫入access.log文件,錯誤日志寫入error.log,而通過ln軟鏈接命令,實現(xiàn)了將這些日志流直接重定向為標準事件流。這樣,這些應用的日志流將被Docker或者Kubernetes捕獲。(12)后臺管理任務當作一次性進程運行進程構成(processformation)是指用來處理應用的常規(guī)業(yè)務(如處理Web請求)的一組進程。與此不同,開發(fā)人員經(jīng)常希望執(zhí)行一些管理或維護應用的一次性任務,例如開源軟件OwnCloud。升級OwnCloud可以在Web界面下操作,但更建議通過occupgrade命令進行升級。在這個命令中,使用了Apache2進程的用戶www-data,保證了命令行和Web方式的環(huán)境一致。這也是十二要素的要求:一次性管理進程應該和正常的常駐進程使用同樣的環(huán)境。這些管理進程和任何其他進程一樣使用相同的代碼和配置,基于某個發(fā)布版本運行。后臺管理代碼應該隨其他應用程序代碼一起發(fā)布,從而避免同步問題。要實現(xiàn)高質(zhì)量的微服務環(huán)境,可以不用嚴格遵循這些要素。但是,通過牢記這些要素,用戶可以在持續(xù)交付環(huán)境中構建和維護可移植應用程序或服務。這是非常重要的,讀者一定要充分理解這十二要素。在本書后續(xù)的描述和案例中,讀者可以看到十二要素的實戰(zhàn)。1.6實現(xiàn)云原生模式云原生基礎架構由應用程序來維護,而云原生應用則由基礎架構來維護,兩者密不可分。這就要求基礎架構和應用程序設計必須是簡單的。如果一個應用程序比較復雜,則應該采用微服務模式,將復雜功能拆分為細微的服務,然后通過集成這些細微服務來組裝成一個應用系統(tǒng)。但由微服務構成的如此復雜的系統(tǒng),勢必無法通過人工管理,應該采用自動化管理,這也是云原生應用的一個基本特征。在傳統(tǒng)單體應用中,企業(yè)所用開發(fā)語言是單一的,例如Java體系或者.Net體系,但是在眾多微服務進行開發(fā)時,語言限定得到了解放。負責某一個微服務的開發(fā)人員擅長使用.Net語言,負責另外一個微服務的開發(fā)人員擅長Node.js,這就出現(xiàn)了多元化。云原生應用并不限定語言,它只對諸如彈性、服務發(fā)現(xiàn)、配置、日志記錄、健康檢查和度量檢查等模式有要求。針對兩種不同情況,目前常用的做法主要有兩類。(1)單一語言情況下,可以通過導入標準庫的形式在程序代碼中聲明云原生特征。例如Java語言系的SpringCloud,可以通過類聲明來實現(xiàn)配置、服務發(fā)現(xiàn)、熔斷機制等功能。(2)多語言情況下,則可以通過伴生(sidecar)模式來解決。該模式將實現(xiàn)各種功能的微服務應用通過容器化部屬捆綁在一起。常見例子如Envoyproxy為服務增加彈性和指標,Registrator通過外部服務發(fā)現(xiàn)服務,Configuration監(jiān)視配置更改并通知服務進程重新加載。Healthendpoint提供用于檢查應用程序健康狀況的HTTP端點。這些都簡化了云原生架構的開發(fā)難度并提高了組件復用率。在云原生架構下,應用的生命周期也是由軟件來進行控制的,普通用戶無須關心應用的生命周期。應用程序的集成、測試和部署應該是自動化、自助式的,按照DevOps文化來進行。1.7何時采用云原生云原生架構是一個階段性產(chǎn)物,它符合技術的生命周期,有流行時期,也有淘汰的時間點。是否采用云原生要看各自場景的需求以及是否具有使用云原生的基礎條件。另外,云原生架構不是銀彈,如果不了解情況就貿(mào)然上云原生架構,會帶來各種成本極大浪費,也解決不了所有問題。在選擇上云原生之前,讀者可以問自己幾個問題:(1)企業(yè)的現(xiàn)有基礎架構是否敏捷?所謂敏捷是指可以通過API來自動分配、銷毀資源,也就是說,現(xiàn)有IaaS層是不是API可控制的。云原生應用需要系統(tǒng)抽象,在應用中不能硬編碼系統(tǒng)主機名,也不能捆綁應用到特定機器,從而排除人為操作應用和系統(tǒng)之間的映射。換句話說,當應用不再關注底層系統(tǒng)的情況時,就可以嘗試云原生架構。(2)企業(yè)的開發(fā)團隊、部署團隊、運維團隊是否獨立?技能是否相通?如果多個團隊各自獨立運作,互相之間技術不了解,這種情況下采用云原生架構,則勢必帶來磨合成本和高昂的學習成本。如果采用云原生架構,將打破這種獨立運作的組織架構,由傳統(tǒng)縱向分割團隊改為橫向分割團隊,每個小組可以自己負責縱向的所有事宜,從而更好地協(xié)作。(3)企業(yè)的業(yè)務是否需要更快地迭代,是慢步速應用還是快步速應用?如果是慢步速應用,則完全可以不采用云原生架構,直接在一臺物理服務器或者云服務器上一次性部署會更加節(jié)約成本。采用云原生架構的應用,就是為了快速響應業(yè)務變化,并快速部署應用,只有業(yè)務變化快的業(yè)務才能充分發(fā)揮云原生架構的作用。(4)企業(yè)是否有云原生應用?是否有滿足十二要素的應用?是否有微服務等應用?如果以上都沒有,那么企業(yè)可能還需要做更多工作才能采用云原生架構。適合云原生架構的應用必須職能單一、與系統(tǒng)無綁定,能夠動態(tài)擴展實例數(shù)量。這就要求能夠以無人值守的方式擴展應用實例,也要求狀態(tài)持久化的存儲服務獨立于應用所在的服務器。符合十二要素是最好的實踐。如果以上問題的答案都是“是”,那么企業(yè)完全可以毫無顧慮地采用云原生架構。如果以上問題的回答有“否”,也不是說企業(yè)不能采用云原生架構了。實際上,對于一個非互聯(lián)網(wǎng)企業(yè)或者高校、政府機關來講,能夠部分采用云原生架構,能夠部分借鑒云原生應用的理念,也是一種改進的成果,為轉向云原生架構做準備工作。1.8云設計模式為了在云中構建可靠、可擴展、安全的應用程序,Microsoft從可用性、數(shù)據(jù)管理、設計與實施、消息、管理和檢測、性能和可伸縮性、彈性、安全等方面總結了如表1-1所示的34種模式。表1-1云設計模式列表以上模式雖然不是云原生應用設計模式,但是有些原則和云原生應用設計模式類似,可以借鑒。1.9服務網(wǎng)格(ServiceMesh)服務網(wǎng)格是用于處理服務到服務通信的專用基礎設施層。它負責通過包含現(xiàn)代云原生應用程序的復雜服務拓撲來可靠地傳遞請求。實際上,服務網(wǎng)格通常實現(xiàn)為多個輕量級網(wǎng)絡代理,這些代理與應用程序代碼一起部署,但不需要知道應用程序。服務網(wǎng)格作為獨立層的概念與云原生應用程序的興起有關。在云原生架構中,借助于Kubernetes這樣的編排器,單個應用程序可能包含數(shù)百個服務,每個服務可能有數(shù)千個實例,并且每個實例可能處于不斷變化的狀態(tài)。這就使得這些服務實例間的通信不僅非常復雜,而且確保端到端的性能和可靠性至關重要。目前,服務網(wǎng)格已成為云原生堆棧的關鍵組件。Paypal、Ticketmaster和CreditKarm等高流量公司都為其生產(chǎn)應用程序添加了服務網(wǎng)格,2017年1月,Linkerd(云原生應用程序的開源服務網(wǎng)格)成為云原生計算基金會的官方項目,同年5月IBM和Google共同發(fā)布開源Istio。服務網(wǎng)格并沒有給軟件開發(fā)和部署帶來新功能,它解決的是其他工具已經(jīng)解決過的問題,只不過這次是針對云原生架構下的Kubernetes環(huán)境的實現(xiàn)。服務網(wǎng)格的主要特點有:●應用程序間通信的中間層?!褫p量級網(wǎng)絡代理?!駪贸绦驘o感知。●解耦應用程序的重試/超時、監(jiān)控、追蹤和服務發(fā)現(xiàn)。目前兩款流行的服務網(wǎng)格開源軟件Istio和Linkerd都已經(jīng)在Kubernetes中集成,但是Istio的接受度和采用量更多一些。Istio是一個源代碼開放的平臺,用于管理和保護微服務。Istio與編排器(如Kubernetes)配合使用,可管理和控制服務之間的通信。Istio使用伴生模式來運行。伴生模式(Envoy代理)是一個單獨進程,與應用程序一起使用。伴生可管理與服務之間的所有往來通信,并將公共級別的功能應用于所有服務,與用于構建服務的編程語言或框架無關。實際上,Istio提供了一種機制,以集中方式配置路由和安全策略,以分散方式通過伴生來應用這些策略。在大多數(shù)情況下,本書建議使用Istio提供的功能,而不要使用不同編程語言或框架提供的類似功能。例如,基礎架構能以更一致的方式對負載均衡和其他路由策略進行定義、管理和強制實施。在某些情況下,與分布式跟蹤一樣,Istio和應用程序級別的庫是互補的,可以同時使用這兩者來改進操作。對于分布式跟蹤,Istio只能確保在請求中包含跟蹤信息;應用程序庫提供了有關請求之間關系的重要上下文。將Istio與支持庫或框架庫一起使用時,可使讀者對系統(tǒng)請求的路由過程有一個總體了解。Istio從最高層上擴展了Kubernetes平臺,提供了額外的管理概念、可視性和安全性。Istio的功能可以細分為以下四個類別:●流量管理:控制微服務之間的流量,以執(zhí)行流量分割、故障恢復和金絲雀發(fā)布。●安全性:在微服務之間提供基于身份的強認證、授權和加密?!窨捎^察性:收集度量值和日志,以更好地了解集群中運行的應用程序。●策略:強制實施訪問控制、速率限制和配額,以保護應用程序。具體內(nèi)容可以參閱Istio官方文檔。1.10云原生的未來2019年5月,著名分析機構Gartner發(fā)布了一份有關云原生基礎設施的報告。該報告指出容器和Kubernetes是構建云原生基礎設施的關鍵,有助于提升軟件效能和開發(fā)生產(chǎn)率。該報告預計2020年所有領先的容器管理軟件均內(nèi)置服務融合技術,到2022年,全球化企業(yè)在生產(chǎn)中使用容器化的應用比例將從當前不足30%發(fā)展到75%,應用軟件采用容器化技術適應多云環(huán)境的比例從現(xiàn)在的少于20%發(fā)展到50%。云原生應用不適合在傳統(tǒng)的基礎設施中運行,因為它需要更高程度的服務發(fā)現(xiàn)、可編程性、自動化、可觀測性、強大的網(wǎng)絡通信及安全性等。從Kubernetes誕生到現(xiàn)在已經(jīng)過去五年,容器化技術的迅猛發(fā)展,推動著云原生基礎設施發(fā)展并產(chǎn)生重大變革。這些變革主要出現(xiàn)了三種新興趨勢:新用例、超越核心構建的技術演進、生態(tài)系統(tǒng)成熟,具體有:(1)混合云環(huán)境中使用云原生基礎設施架構。(2)在邊緣計算中引入云原生技術,簡化管理。(3)服務網(wǎng)格繼續(xù)發(fā)展,并以Istio領先。(4)發(fā)展基于Kubernetes的融合函數(shù)即服務的技術fPaaS(又稱FaaS)。(5)基于成本考慮,云原生技術更多部署在裸機或者針對容器化定制的微虛擬機上。(6)越來越多的第三方軟件提供商采用容器化技術輕量級部署。(7)對有狀態(tài)應用的支持越來越豐滿。(8)跨Kubernetes的成熟項目將會越來越多。第2章Kubernetes核心對象Kubernetes這個名字源于希臘語,意思是舵手。在2014年,谷歌開放了Kubernetes項目。它是建立在谷歌運行大規(guī)模生產(chǎn)系統(tǒng)的基礎之上,結合社區(qū)的最佳創(chuàng)意和實踐構建的一個可移植、可擴展的開源平臺。Kubernetes主要是通過API或者聲明式配置管理容器化工作負載和服務的一整套系統(tǒng)。Kubernetes主要提供了以下功能:●服務發(fā)現(xiàn)和負載均衡。Kubernetes可以使用DNS名稱或使用自己的IP地址公開容器。如果容器的流量很高,Kubernetes也支持將這些流量均衡分配,以確保系統(tǒng)穩(wěn)定。●存儲編排。Kubernetes允許用戶自動加載自選的存儲系統(tǒng),例如本地存儲、NFS存儲等?!褡詣硬渴鸷突貪L。Kubernetes可以描述已部署容器的所需狀態(tài),并且可以以受控的方式更新現(xiàn)有狀態(tài)到預期狀態(tài)?!窆芾碣Y源。Kubernetes允許用戶指定每個容器請求的資源,以便更好地管理容器的資源?!褡晕倚迯?。Kubernetes可以重新啟動失敗的容器、替換容器,也可以終止不響應用戶自定義的運行狀況檢查的容器?!衩荑€和配置管理。Kubernetes允許用戶存儲和管理敏感信息,例如密碼、TLS證書等。用戶可以部署和更新機密信息而無須重建容器,也不會泄露機密信息。Kubernetes不是一個傳統(tǒng)PaaS平臺,它提供的功能包括部署、擴展、負載平衡、日志記錄和監(jiān)控,且解決方案都是可選和可插拔的。本章內(nèi)容的主旨不是全面講述Kubernetes部件,而是進行提煉,講述與后續(xù)部署以及云原生架構相關的關鍵點。具體如何使用、管理Kubernetes還請參考官方文檔。2.1Kubernetes架構Kubernetes分控制節(jié)點(MasterNode)和工作節(jié)點(WorkerNode),如圖2-1所示。其對外提供的操作接口全部通過APIServer對接。無論是圖形界面還是命令行工具,都是通過訪問APIServer與Kubernetes交互,這樣就能符合云原生架構的要求——通過API來操作基礎架構。在Kubernetes中,Master節(jié)點可以是一個,也可以是通過KeepAlived技術組建的MasterCluster,以保證高可用性。圖2-1Kubernetes架構2.1.1工作節(jié)點工作節(jié)點(Node)是在Kubernetes中承載業(yè)務工作的節(jié)點。在后面部署Kubernetes集群時可以看到,節(jié)點可以是一個虛擬機,也可以是一臺裸機。每個節(jié)點上都運行Docker、kubelet和kube-proxy等服務,從而保障Pod的正常運行。所有工作節(jié)點由Master組件進行統(tǒng)一管理。1.查看節(jié)點通過以下命令可以查看節(jié)點運行狀態(tài):ROLES為master的表示該節(jié)點上運行了管理控制器。2.創(chuàng)建節(jié)點嚴格意義來說,節(jié)點不能通過命令創(chuàng)建。只能按照部署的方法準備好一臺虛擬機或裸機,然后通過kubeadmjoin命令加入到Kubernetes集群中。2.1.2Master節(jié)點Master節(jié)點是一個Kubernetesmaster組件,管理工作節(jié)點的方方面面。這個節(jié)點的任務非常重要,所以在生產(chǎn)環(huán)境下,一般通過KeepAlived等技術手段組件集群(一般是3個節(jié)點組成)來確保master組件的正常運行和持續(xù)提供管理功能。2.1.3Docker鏡像庫Kubernetes中運行的所有鏡像都來源于某個鏡像庫,可以是DockerHub,也可以是客戶自建的私有Docker鏡像庫。節(jié)點在收到創(chuàng)建Pod的命令后,將去Docker鏡像庫中拉取鏡像,因此每個節(jié)點與Docker鏡像庫之間的網(wǎng)絡鏈接必須是通暢的。2.2命名空間命名空間(Namespace)是Kubernetes中的一個重要概念,如同編程語言中的命名空間,它把系統(tǒng)內(nèi)部的對象歸集到不同的邏輯小組中,從而便于分別管理。Kubernetes默認有一個default命名空間,在操作時沒有指明命名空間的對象都在default下。一般情況下,還會有一個kube-system命名空間,Kubernetes中管理方面的對象基本都在該命名空間下,一般不建議用戶放置普通應用對象在該命名空間下。1.查看命名空間獲取命名空間列表可以通過如下命令查看:2.創(chuàng)建命名空間可以通過命令來創(chuàng)建命名空間,如創(chuàng)建kube-log命名空間。也可以通過聲明文件來創(chuàng)建命名空間。3.使用命名空間如果要查找某個命名空間下的對象,必須在kubectl參數(shù)中指明namespace。如下命令是查詢在kube-log命名空間下的Pod對象。4.命名空間和DNS創(chuàng)建服務時,也會創(chuàng)建相應的DNS條目<service-name>.<namespace-name>.svc.cluster.local,這在跨命名空間中使用Service時就比較有用了,此時必須使用完全限定的域名(FQDN)。2.3PodPod是Kubernetes中創(chuàng)建應用的最小、最簡單的基本執(zhí)行單元。Pod封裝了應用程序的容器(一個或多個)、存儲資源、網(wǎng)絡以及其他相關選項。這表明:●Kubernetes直接管理Pod,而不是容器?!馪od可以封裝多個協(xié)作的容器,類似于DockerStack?!衩總€Pod僅運行某個應用程序的單個實例,如果要水平擴展,不建議使用Pod部署。2.3.1創(chuàng)建Pod盡管在Kubernetes中可以通過命令來創(chuàng)建對象,但是如果創(chuàng)建對象的參數(shù)比較多,本書建議通過聲明文件來創(chuàng)建。下面的聲明文件用來創(chuàng)建一個鏡像為busybox的Pod。2.3.2Pod內(nèi)部多個容器Pod支持多個協(xié)作容器組成一個有凝聚力的服務單元。Pod中的容器自動放置在同一個節(jié)點上,共同調(diào)度,共享資源和依賴關系,彼此通信,并協(xié)調(diào)何時可以終止,以及如何終止。Pod具有這種能力,不代表我們可以隨意使用這種模式,畢竟在云原生應用中,需要盡量確保每個部件可以自動擴展,并減少彼此的依賴性。而聚合多個容器的Pod則增加了依賴性,所以只能在特定的場景下使用該模式。例如伴生模式下的容器,后文會提到兩個容器共享同一個存儲卷,從而形成內(nèi)容管理和內(nèi)容發(fā)布兩個容器聚合在同一個Pod中對外透明服務。圖2-2演示了一個Pod內(nèi)有兩個容器,分別是Drupal站點和Drupal后端數(shù)據(jù)庫。但在這種模式下無法橫向擴展,只有Drupal站點系統(tǒng)和MySQL數(shù)據(jù)庫分離后在不同的Pod中才能進行擴展。圖2-2一個Pod多個容器2.3.3初始化容器Pod能夠聚合多個容器,應用在容器里面運行,但是它也可能有一個或多個先于應用容器啟動的初始化容器(Initcontainer)。初始化容器與普通容器非常像,除了如下兩點:●它們總是運行到完成?!衩總€都必須在下一個啟動之前成功完成。如果Pod的初始化容器失敗,Kubernetes會不斷地重啟該Pod,直至初始化容器成功。當然,如果Pod對應的restartPolicy值為Never,則不會重新啟動。在本書所提及的Elasticsearch部署案例中,使用了三個初始化容器,按照以下順序執(zhí)行:●修正存儲卷的權限。●修改系統(tǒng)參數(shù)vm.max_map_count?!裥薷南到y(tǒng)參數(shù)ulimit的值。描述初始化容器:修正存儲卷的權限:增加系統(tǒng)參數(shù)vm.max_map_count到262144:增加ulimit值:2.3.4狀態(tài)探針在Kubernetes中,通過kubelet對容器進行持續(xù)探測來判斷容器是否可用,一旦容器不可用,kubelet將重啟該容器。為了更精確地判斷容器狀態(tài),Kubernetes中提供了就緒探針(ReadinessProbe)和存活探針(LivenessProbe)。存活探針用于判斷容器啟動就緒后是否還在持續(xù)正常服務。業(yè)務有可能會因為某種錯誤而導致系統(tǒng)不可用,或者普通的探測方法不足以判斷業(yè)務是否正常工作,此時可以通過設置自定義的存活探針來檢測。就緒探針用于判斷容器是否可以接受流量,是針對有前端服務的容器來講的。有些容器可能已經(jīng)啟動完畢,但是業(yè)務系統(tǒng)還不能正常處理請求。例如Tomcat啟動需要1min,此時要進行存活狀態(tài)檢測將返回不可用,前端服務就不會將請求轉給容器。存活探針的事例代碼如下,在該代碼中,使用了httpGet方法去探測,訪問的path是/healthz,并且在容器啟動3s后進行判斷,之后每隔3s進行一次探測。就緒探針和存活探針非常類似,只是將livenessProbe換成readinessProbe。其中幾個關鍵參數(shù)說明如下:●initialDelaySeconds:容器啟動后第一次執(zhí)行探測需要等待多少秒?!駊eriodSeconds:執(zhí)行探測的頻率。默認間隔是10s,最小1s?!駎imeoutSeconds:探測超時時間。默認1s,最小1s。●successThreshold:探測失敗后,最少連續(xù)探測成功多少次才被認定為成功。默認是1。對于liveness必須是1。最小值是1。●failureThreshold:探測成功后,最少連續(xù)探測失敗多少次才被認定為失敗。默認是3。最小值是1。2.3.5測試工具Kubernetes中容器所在的網(wǎng)絡與客戶端所在的網(wǎng)絡是不能直接通信的,這就導致部署一個Pod后,如果需要測試其功能將非常麻煩。為此,Google推出了一個busybox鏡像,該鏡像含有基本的網(wǎng)絡工具,用于在容器網(wǎng)絡中測試。例如,可以通過命令來ping一個名稱為test的Pod:也可以訪問容器內(nèi)的某個網(wǎng)站:2.4部署Kubernetes中的部署是指如何控制一組Pod的運行狀態(tài)使其滿足生產(chǎn)需要。部署分為無狀態(tài)部署和有狀態(tài)部署。無論哪種部署,其內(nèi)部都有副本集控制功能。首先了解ReplicaSet是如何控制副本數(shù)量的。2.4.1ReplicaSetReplicaSet的目的是維護一組狀態(tài)穩(wěn)定的Pod副本,從而保證指定數(shù)量的相同Pod的可用性。它主要通過以下聲明來控制副本數(shù)量:之前曾有ReplicationController,后來逐漸被ReplicaSet替代。ReplicaSet聲明文件中,需要Pod模板以進行復制,同時也需要標簽選擇器.spec.selector.matchLabels以選擇當前Pod的副本。在nfs-provisioner的模板聲明文件中有標簽為app:nfs-provisioner的選擇器,部分代碼如下:請注意,.spec.template.metadata.labels必須和.spec.selector.matchLabels匹配,否則無法創(chuàng)建ReplicaSet。在Pod運行過程中,也可以通過kubectlscale命令手動調(diào)整副本數(shù)量:也可以自動調(diào)整ReplicaSet的副本數(shù)量,下面的命令是對foo這個ReplicaSetController設置自動調(diào)整規(guī)則——最多5個副本,而且在CPU使用率達到80%的時候需要增加副本。在Kubernetes中,自動分配副本數(shù)量的算法如下:例如當前副本數(shù)量是2,CPU度量值為200MHz,期望度量值為100MHz,則應當?shù)母北緮?shù)量為200/100=2。如果當前CPU度量值為300MHz,而期望度量值為200MHz,則應當?shù)母北緮?shù)量為300/200=1.5,進位取整后為2。所以不需要調(diào)整副本數(shù)量。除了通過命令來控制Pod副本數(shù)量,還可以通過聲明文件來控制,其類型為HorizontalPodAutoscaler。以下聲明和命令的效果是一致的。請注意,自動調(diào)整Pod副本數(shù)量的依據(jù)是度量值。在上面的例子中是通過CPU的averageUtilization來進行判斷的,也可以根據(jù)Value、AverageValue、requests-per-second、packets-per-second等度量值來進行判斷。Kubernetes從1.8版本開始使用額外的工具MetricsServer(/kubernetes-incubator/metrics-server)收集度量指標,因此需要單獨安裝MetricsServer。安裝完成后,若出現(xiàn)無法收集指標的故障,則需要修改metrics-server-depolyment.yaml文件,添加args參數(shù),然后重新應用該文件。修改部分代碼如下:2.4.2部署部署(Deployment)是一個擁有ReplicaSet并通過聲明來控制Pod滾動、更新的對象。雖然ReplicaSet可以獨立使用,但是它主要被用作協(xié)調(diào)Pod創(chuàng)建、刪除和更新的機制。使用部署時,用戶不必擔心副本集,因為部署通過ReplicaSet進行管理,所以,本書建議使用部署而不是ReplicaSet。下面是一個部署的聲明文件,部署了3個nginx的Pod副本:這個例子與ReplicaSet的示例是一樣的,這是因為部署通過ReplicaSet來控制副本數(shù)量。但是如何更新副本數(shù)量,則是部署的職責,其通過StrategyType、RollingUpdateStrategy等屬性來控制如何更新Pod副本。.spec.strategy.type的可選值有重建(Recreate)和滾動更新(RollingUpdate)。Recreate是指重建所有Pod,其過程為先終止Pod所有的副本,然后重新創(chuàng)建指定數(shù)量的Pod副本。而RollingUpdate則采取一定的控制策略來逐步更新Pod副本。.spec.strategy.rollingUpdate.maxUnavailable是一個可選字段,是指更新過程中最大不可用的Pod數(shù)量。該值可以是絕對數(shù)值,也可以是百分比。其默認值為25%。例如,如果該值為25%,則原有部署中的ReplicaSet立刻將副本數(shù)量縮減為75%,然后準備新的Pod副本,再繼續(xù)控制25%的不可用的比例,逐步縮減原有Pod副本,直至所有Pod更新完成。.spec.strategy.rollingUpdate.maxSurge也是一個可選字段。它指定了Pod副本的最大副本數(shù)量。例如取默認值為25%,則在更新部署時可創(chuàng)建的Pod副本數(shù)量是期望副本數(shù)量的125%。.spec.minReadySeconds是一個可選字段,默認為0。它指明新創(chuàng)建的Pod在沒有任何容器崩潰的情況下到內(nèi)部應用所需的時間。例如作者所在學校部署ApereoCAS時,在Pod創(chuàng)建完成并running狀態(tài)下,CAS啟動正常還需要約1min,則需設置.spec.minReadySeconds=60。下面是影響升級過程的幾個重要參數(shù):(1)新的ReplicaSet創(chuàng)建maxSurge所指定數(shù)量的Pod副本,此時新舊Pod副本數(shù)量為期望副本數(shù)量和maxSurge個副本數(shù)量之和。(2)在創(chuàng)建新的Pod副本時,馬上從舊的ReplicaSet中刪除maxUnavailable個Pod。這時可用Pod副本數(shù)量為期望副本數(shù)量減去maxUnavailable。(3)當新創(chuàng)建的Pod副本有一個可用時,馬上從舊的ReplicaSet中刪除一個Pod,如此反復直至所有舊的Pod被新的Pod替換。這就要求maxUnavailable和maxSurge不能同時為0。如果在版本升級過程中又觸發(fā)了更新的版本升級,則Kubernetes會暫停之前版本的替換過程,用最新的版本替換之前剛剛升級的版本,然后再用最新的版本替換還未升級的版本。部署可以回滾到以前的版本,也支持擴展和自動擴展。2.4.3有狀態(tài)部署有狀態(tài)部署(StatefulSets)是用于管理有狀態(tài)應用程序工作負載的一種部署方法。區(qū)別于無狀態(tài)部署(Deployment),StatefulSets可以對Pod副本進行排序并保證每個Pod的唯一性。在無狀態(tài)部署中,刪除一個Pod,新建一個Pod,對于所有Pod來講都是一致的。但是在StatefulSets中,每個Pod都有唯一的持久標識符,即使在重建后也會繼續(xù)保留該標識符。有狀態(tài)部署適合以下場景:●需要獨特的網(wǎng)絡標識符。●需要獨立持久的存儲?!裥枰行虻牟渴鸷蛿U展。●需要有序的升級。下面演示創(chuàng)建一個nginx的StatefulSet部署。主要內(nèi)容有:●名稱為nginx的無頭服務。●名稱為web的StatefulSet。以上聲明文件與無狀態(tài)部署(Deployment)一致,只是系統(tǒng)在創(chuàng)建后的Pod標識符是唯一且有序數(shù)的。通過kubebctlgetpods命令查看,可以看到每個Pod的名稱為web-<序數(shù)>,而不是web-<隨機字符串>。這樣,每個Pod也都有自己獨立易記且固定的主機名稱,例如web-0,其FQDN為web-0.nginx.default.svc.cluster.local。每個Pod的存儲卷也是特定的,不能混用。而且刪除Pod時,為了保留該狀態(tài),持久卷不會自動刪除。在StatefulSet中Pod的部署過程與無狀態(tài)部署完全不同。在無狀態(tài)部署中,Pod副本并發(fā)創(chuàng)建,而在有狀態(tài)部署中,Pod是依次順序創(chuàng)建。在上例中,web-0、web-1和web-2是依次創(chuàng)建,而且web-1是在web-0創(chuàng)建完成并且正常運行后再創(chuàng)建。如果要刪除部署,則順序恰好相反,最晚創(chuàng)建的容器被最早刪除。2.4.4DaemonSet一個DaemonSet確保每個節(jié)點上只運行一個副本。若有節(jié)點添加到集群中,將在新增的節(jié)點上運行唯一一個Pod,若節(jié)點刪除,則從該節(jié)點上終止Pod。DaemonSet適合以下場景:●每個節(jié)點上運行集群存儲后臺駐留程序,例如glusterd、ceph?!衩總€節(jié)點上運行日志守護程序,例如fluentd、logstash?!衩總€節(jié)點上運行Prometheusnodeexporter、sisdig、collectd等代理。DaemonSet的示例在此不再詳述,在講解日志和監(jiān)控時會詳細描述DaemonSet。2.5服務Kubernetes內(nèi)部的部署只能在集群內(nèi)部訪問,若要暴露這些工作負載,Kubernetes提供了工作在ISO/OSI模型的傳輸控制層的服務和工作在應用層的Ingress兩種方式暴露后端工作負載。2.5.1關于服務Kubernetes的Pod是有生命周期的,它可以被系統(tǒng)自動創(chuàng)建和銷毀,IP是動態(tài)分配的,且僅限集群內(nèi)網(wǎng)訪問。這就產(chǎn)生了一個問題:前端客戶如何訪問這些Pod呢?Kubernetes服務(Service)定義了這樣一種抽象:在邏輯上通過標簽來選定一組Pod,提供一種策略,讓外網(wǎng)和前端客戶能夠訪問這組Pod。例如在StatefulSet中定義的nginx服務,通過app:nginx標簽來選定擁有此標簽的Pod,然后對外提供80端口的Web服務。服務將根據(jù)一定的策略將外網(wǎng)的Web請求轉發(fā)給后端Pod,這樣就對前端用戶隱藏了后端Pod的存在。服務不僅可以指向集群內(nèi)部的Pod,也可以指向集群外部的資源。通過指向外部資源的服務,集群內(nèi)部的Pod可以像訪問內(nèi)部資源一樣方便地訪問外部資源,尤其是外部資源后續(xù)需要遷移到集群內(nèi)部的場景下更是如此。下例是指向外網(wǎng)資源的一個示例。1.無頭服務(HeadlessService)在有些場景下業(yè)務不需要負載均衡,或者不需要單獨的ServiceIP,此時業(yè)務可以使用HeadlessService。在HeadlessService中,.spec.clusterIP需要設置為“None”。這也就決定了HeadlessService只能在集群內(nèi)部使用。HeadlessService可以有選擇器,也可以沒有選擇器。一般情況下服務都會配置選擇器。通過配置選擇器,服務會在DNS中為每個Pod配置A記錄,通過訪問服務名稱,DNS會返回后端Pod的地址,這可以用于Pod之間通過域名互相訪問。2.服務類型服務根據(jù)暴露方式可以分為4種類型,默認為ClusterIP類型。類型通過Type的取值來描述:●ClusterIP:通過集群的內(nèi)部IP暴露服務。選擇該值,服務只能在集群內(nèi)部訪問?!馧odePort:通過在每個節(jié)點上創(chuàng)建相同的端口來暴露服務。NodePort服務會路由到ClusterIP服務,這個ClusterIP會自動創(chuàng)建,也可以手工指定?!馤oadBalancer:使用云提供商的負載均衡設備向外暴露服務。例如GoogleCloud、OracleCloud等廠商都提供外部負載均衡設備,外部均衡設備路由到ClusterIP服務。Google開源了一個MetalLB項目,用于裸機上的負載均衡服務。●ExternalName:通過返回CNAME和它的值,可以將服務映射到externalName字段指定的內(nèi)容。3.NodePort類型.spec.type的值為NodePort時,Kubernetes會在給定的配置范圍內(nèi)(默認30000~32767)分配端口,也可以直接指定在該范圍內(nèi)的端口。每個節(jié)點將該端口代理到ClusterIP服務。下例通過app:nginx選擇Pod,并開啟30080端口進行訪問。4.LoadBalancer類型若要使用支持外部負載均衡設備的云提供商的服務,請設置.spec.type為LoadBalancer。具體的配置需要參照各云提供商的說明。5.外部IP可以在服務中設置外部IP,將服務暴露給這個外部IP,從而通過外部IP進入集群。外部IP必須和節(jié)點IP在同一個網(wǎng)段。注意:Kubernetes無法管理這些外部IP,它屬于集群管理員的職責范疇。下例是為my-site
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030全球離網(wǎng)房車行業(yè)調(diào)研及趨勢分析報告
- 2025-2030全球高脈沖能量皮秒激光器行業(yè)調(diào)研及趨勢分析報告
- 月齡嬰兒情緒情感與社會性親子活動設計創(chuàng)造性撫觸游戲講解
- 2025【合同范本】建筑工程設計協(xié)議書
- 蔬菜配送合作合同范本
- 分期付款合同模板集錦
- 會簽單合同模板
- 全新對講機服務合同下載
- 勞務出資合伙協(xié)議合同
- 個人租車租賃合同范本
- 區(qū)域經(jīng)理年終工作總結匯報
- 2019版新人教版高中英語必修+選擇性必修共7冊詞匯表匯總(帶音標)
- 初中八年級音樂-勞動號子《軍民大生產(chǎn)》
- 中層領導的高績效管理
- 小小銀行家-兒童銀行知識、理財知識培訓
- 機械基礎知識競賽題庫附答案(100題)
- 閱讀理解特訓卷-英語四年級上冊譯林版三起含答案
- 國庫集中支付培訓班資料-國庫集中支付制度及業(yè)務操作教學課件
- 屋面及防水工程施工(第二版)PPT完整全套教學課件
- 2023年上海青浦區(qū)區(qū)管企業(yè)統(tǒng)一招考聘用筆試題庫含答案解析
- 2023年高一物理期末考試卷(人教版)
評論
0/150
提交評論