# 第5章 示例:Beanstalk環境
目前,大多數軟件公司內部都有多套基礎設施環境。這些環境具有典型的3層結構:測試、預演和生產環境。部分公司在此之外還有預生產甚至是公測(canary)環境,不過這些都是特例。不同的環境為新代碼甚至是基礎設施組件的生命周期提供了隔離。這些環境通常由至少一個用于應用程序邏輯和展示的Web服務器層和一個數據庫層組成。過去的10多年里,這些環境在不同公司內部已經相當穩定。我們在RelateIQ發現了另外一個極佳的Docker環境示例。他們正在做的事情很有趣,有可能打破這種標準的環境模式。
RelateIQ使用AWS Beanstalk為每個分支完整地編排出一個Web環境。這是通過其CI/CD基礎設施使用Docker技術創造出來的一個全新的基礎設施環境。他們從根本上把Web層與數據層分開。將典型的3層模型轉換成僅剩數據存儲。這一點一開始可能有點兒難以想象,我們來直觀地看一下(如圖5-1所示)。

圖5-1
圖5-1展示了3個不同的分支,即PerfTest、新的APD及新的UI分支。每個分支通過CI/CD系統來構建自己的Web容器。容器被構建和測試后,將被推送到倉庫中。任何開發人員或團隊,都能根據需要構建各個分支的Web環境。這還允許用戶以不同的方式考慮如何使用容器,同時重新考慮環境的各個部分。SaaS公司采用這種模式的巨大優勢之一是適應快速變化的能力。試想一下,如果將這類環境用于持續交付模型中,產品經理和設計師會如何利用這些環境。
舉個例子,RelateIQ在2014年夏季通過Docker使用這種新模式,用一個全新的外觀取代CSS,完全重新設計了整個Web應用程序。他們可以在并排的Web服務器中運行A/B測試,以對新舊版本進行比較。由于開發人員會在15~30分鐘內提交代碼,設計師和產品經理能夠在一個隔離的環境中看到最近生效的變化。使用環境變量,還能夠將Web服務器后端從預演數據服務器重定向到生產數據服務器上。Docker容器快速重啟后,他們就能在幾分鐘內看到生產數據的最近生效的變化。當RelateIQ準備上線新設計的網站時,他們只需將容器從預演數據切換到生產數據。這樣,開發人員就能確保數據與新UI正確匹配。
在這個環境中,RelateIQ使用Teamcity構建和部署應用程序。他們使用VCS觸發器來監控GitHub倉庫中特定的分支名稱,以執行自動構建。例如,他們使用了“`docker-<分支>`”這樣的名稱。如果倉庫中創建了一個以“`docker-`”開頭的分支,那么這個分支自身的Docker容器將會自動被構建。為了快速啟動,大多數開發人員會在預演時直接創建分支。分支一旦創建,Teamcity就會構建這個容器并推送到一個本地倉庫中。他們使用亞馬遜AWS的Beanstalk服務來部署和更新容器。
“AWS Elastic Beanstalk 是一項易于使用的服務,用于在熟悉的服務器(如 Apache 、Nginx、Passenger 和 IIS )上部署和擴展使用 Java、.NET、PHP、Node.js、Python、Ruby、GO 和 Docker 開發的 Web 應用程序和服務。
您只需上傳代碼,Elastic Beanstalk 即可自動處理從容量預置、負載均衡、自動擴展到應用程序健康監控的部署。同時,您能夠完全控制為應用程序提供支持的 AWS 資源,并可隨時訪問基礎資源。”
——來源于[亞馬遜](http://aws.amazon.com/cn/elasticbeanstalk/)
Beanstalk將自動部署一臺負載均衡器,設置自動擴展組,根據設置配備相應數量的實例/服務器,拉取并運行Docker容器,提供健康監控,并且使用安全組加固服務器。對剛剛起步的公司而言,這將使其在基礎設施方面走得很遠。如果將其與“一個Web服務一個容器”組合起來,對SaaS公司來說,這將變成一個非常有用的環境。
部署的執行有多種方式,從Elastic Beanstalk到使用S3存儲桶(bucket)的JSON文件或對服務自身的API調用。在本示例中,使用的是在Teamcity配置中創建的S3存儲桶的JSON文件。構建步驟之一將寫新文件,并將變化推送給S3存儲桶。文件包含了容器的位置、需要打開的端口,以及容器的名稱。新文件被上傳后,Elastic Beanstalk環境將自動啟動一臺新服務器,在這臺服務器上拉取容器并進行設置,然后在健康檢查通過后停止舊的容器和服務器(如圖5-2所示),基本上創造了新服務的零停機時間部署。

圖5-2
Elastic Beanstalk的使用表明,基礎設施供應商真正開始運行自有容器只是時間問題,就像他們之前運行虛擬化基礎設施一樣。
Elastic Beanstalk容器的日志是全自動化的,就像該基礎設施的其他部分一樣。可以通過GUI工具拉取日志,并選擇拉取的是服務器上的完整日志還是標準輸出的最后100行。這兩個選項只在排錯時才有用,因此他們提供了一個新選項用于將日志尾部發送到S3存儲桶中。使用能讀取S3服務日志的集中式日志服務讓公司能將這些日志直接集成到現有日志方案中。圍繞日志部分有幾個注意事項。日志的名稱與容器名稱無關。其名稱是根據一個作為服務唯一標識而隨機生成的服務名稱所創建的。要追蹤哪個唯一標識屬于哪個Elastic Beanstalk將非常麻煩。
所有通過亞馬遜AWS提供的服務都內置了各自的云監控方案,也支持Elastic Beanstalk。不過,監控非常基礎。能獲取ELB指標和服務器指標,但無法從容器本身獲取任何東西。這是由于Elastic Beanstalk服務中容器與服務器比例為1:1。這意味著網絡、CPU、磁盤以及內存指標通常來自于運行于宿主機上的容器指標。如果機器出現異常,只能SSH登錄到服務中進行排錯或部署新版本。
Beanstalk通過安全組和IAM角色提供了自動化防火墻端口安全,以加固用戶訪問。由于Beanstalk使用一個很低的容器宿主機比例,就像普通的應用程序和服務器環境一樣,要將容器與其他容器隔離開非常容易。Beanstalk模板保證了跨新部署時新環境的一致性,可以輕松進行跨多臺宿主機的安全性修改。
通過使用Docker以及亞馬遜AWS的Elastic Beanstalk自動化基礎設施,RelateIQ能夠在一個可擴展的模板環境中為每一位前端工程師提供一個Web環境。這個環境非常容易創建,加上CI/CD系統的一點編排,它是完全自動化的。注意:如果想在自己的基礎設施中做嘗試,這個環境還有很多部分處于構建狀態。日志可以做得更好,因為Beanstalk環境提供的唯一標識非常難用,截至本書編寫時,每個服務上已經運行一個容器(很快就能支持多容器)。請記住,使用Docker可以讓環境變得異常靈活,并為推動開發速度提供新的創新方法。
在第6章中,我們將深入講述Docker的安全性話題。
- 版權信息
- 版權聲明
- 內容提要
- 對本書的贊譽
- 譯者介紹
- 前言
- 本書面向的讀者
- 誰真的在生產環境中使用Docker
- 為什么使用Docker
- 開發環境與生產環境
- 我們所說的“生產環境”
- 功能內置與組合工具
- 哪些東西不要Docker化
- 技術審稿人
- 第1章 入門
- 1.1 術語
- 1.1.1 鏡像與容器
- 1.1.2 容器與虛擬機
- 1.1.3 持續集成/持續交付
- 1.1.4 宿主機管理
- 1.1.5 編排
- 1.1.6 調度
- 1.1.7 發現
- 1.1.8 配置管理
- 1.2 從開發環境到生產環境
- 1.3 使用Docker的多種方式
- 1.4 可預期的情況
- 為什么Docker在生產環境如此困難
- 第2章 技術棧
- 2.1 構建系統
- 2.2 鏡像倉庫
- 2.3 宿主機管理
- 2.4 配置管理
- 2.5 部署
- 2.6 編排
- 第3章 示例:極簡環境
- 3.1 保持各部分的簡單
- 3.2 保持流程的簡單
- 3.3 系統細節
- 利用systemd
- 3.4 集群范圍的配置、通用配置及本地配置
- 3.5 部署服務
- 3.6 支撐服務
- 3.7 討論
- 3.8 未來
- 3.9 小結
- 第4章 示例:Web環境
- 4.1 編排
- 4.1.1 讓服務器上的Docker進入準備運行容器的狀態
- 4.1.2 讓容器運行
- 4.2 連網
- 4.3 數據存儲
- 4.4 日志
- 4.5 監控
- 4.6 無須擔心新依賴
- 4.7 零停機時間
- 4.8 服務回滾
- 4.9 小結
- 第5章 示例:Beanstalk環境
- 5.1 構建容器的過程
- 部署/更新容器的過程
- 5.2 日志
- 5.3 監控
- 5.4 安全
- 5.5 小結
- 第6章 安全
- 6.1 威脅模型
- 6.2 容器與安全性
- 6.3 內核更新
- 6.4 容器更新
- 6.5 suid及guid二進制文件
- 6.6 容器內的root
- 6.7 權能
- 6.8 seccomp
- 6.9 內核安全框架
- 6.10 資源限制及cgroup
- 6.11 ulimit
- 6.12 用戶命名空間
- 6.13 鏡像驗證
- 6.14 安全地運行Docker守護進程
- 6.15 監控
- 6.16 設備
- 6.17 掛載點
- 6.18 ssh
- 6.19 私鑰分發
- 6.20 位置
- 第7章 構建鏡像
- 7.1 此鏡像非彼鏡像
- 7.1.1 寫時復制與高效的鏡像存儲與分發
- 7.1.2 Docker對寫時復制的使用
- 7.2 鏡像構建基本原理
- 7.2.1 分層的文件系統和空間控管
- 7.2.2 保持鏡像小巧
- 7.2.3 讓鏡像可重用
- 7.2.4 在進程無法被配置時,通過環境變量讓鏡像可配置
- 7.2.5 讓鏡像在Docker變化時對自身進行重新配置
- 7.2.6 信任與鏡像
- 7.2.7 讓鏡像不可變
- 7.3 小結
- 第8章 存儲Docker鏡像
- 8.1 啟動并運行存儲的Docker鏡像
- 8.2 自動化構建
- 8.3 私有倉庫
- 8.4 私有registry的擴展
- 8.4.1 S3
- 8.4.2 本地存儲
- 8.4.3 對registry進行負載均衡
- 8.5 維護
- 8.6 對私有倉庫進行加固
- 8.6.1 SSL
- 8.6.2 認證
- 8.7 保存/載入
- 8.8 最大限度地減小鏡像體積
- 8.9 其他鏡像倉庫方案
- 第9章 CI/CD
- 9.1 讓所有人都進行鏡像構建與推送
- 9.2 在一個構建系統中構建所有鏡像
- 9.3 不要使用或禁止使用非標準做法
- 9.4 使用標準基礎鏡像
- 9.5 使用Docker進行集成測試
- 9.6 小結
- 第10章 配置管理
- 10.1 配置管理與容器
- 10.2 面向容器的配置管理
- 10.2.1 Chef
- 10.2.2 Ansible
- 10.2.3 Salt Stack
- 10.2.4 Puppet
- 10.3 小結
- 第11章 Docker存儲引擎
- 11.1 AUFS
- 11.2 DeviceMapper
- 11.3 BTRFS
- 11.4 OverlayFS
- 11.5 VFS
- 11.6 小結
- 第12章 Docker 網絡實現
- 12.1 網絡基礎知識
- 12.2 IP地址的分配
- 端口的分配
- 12.3 域名解析
- 12.4 服務發現
- 12.5 Docker高級網絡
- 12.6 IPv6
- 12.7 小結
- 第13章 調度
- 13.1 什么是調度
- 13.2 調度策略
- 13.3 Mesos
- 13.4 Kubernetes
- 13.5 OpenShift
- Red Hat公司首席工程師Clayton Coleman的想法
- 第14章 服務發現
- 14.1 DNS服務發現
- DNS服務器的重新發明
- 14.2 Zookeeper
- 14.3 基于Zookeeper的服務發現
- 14.4 etcd
- 基于etcd的服務發現
- 14.5 consul
- 14.5.1 基于consul的服務發現
- 14.5.2 registrator
- 14.6 Eureka
- 基于Eureka的服務發現
- 14.7 Smartstack
- 14.7.1 基于Smartstack的服務發現
- 14.7.2 Nerve
- 14.7.3 Synapse
- 14.8 nsqlookupd
- 14.9 小結
- 第15章 日志和監控
- 15.1 日志
- 15.1.1 Docker原生的日志支持
- 15.1.2 連接到Docker容器
- 15.1.3 將日志導出到宿主機
- 15.1.4 發送日志到集中式的日志平臺
- 15.1.5 在其他容器一側收集日志
- 15.2 監控
- 15.2.1 基于宿主機的監控
- 15.2.2 基于Docker守護進程的監控
- 15.2.3 基于容器的監控
- 15.3 小結
- DockOne社區簡介
- 看完了