Docker文檔整理與匯總

寫這篇文章主要是為了今后畢業論文素材上的整理,同時對docker進行鞏固溫習。
大綱:

  • docker簡介
    docker出現的背景、docker是什么。

  • docker生態系統和應用場景
    哪些工作與社區與docker有關,docker有哪些具體實用價值。

  • docker原理
    docker與linux究竟有何淵源,從技術層面進行介紹。

  • docker與虛擬機性能對比
    docker與vm技術有哪些區別,本文將進行對比,并總結出docker優缺點。

  • docker技術點
    docker安裝、dockerfile編寫、常用docker命令。

  • 容器管理工具kubernetes介紹
    巨頭谷歌開源的解決方案k8s介紹,k8s環境搭建和小案例

  • docker學習總結與展望

                               一、docker簡介

Docker是一個由GO語言寫的程序運行的“容器”(Linux containers, LXCs); 目前云服務的基石是操作系統級別的隔離,在同一臺物理服務器上虛擬出多個主機。Docker則實現了一種應用程序級別的隔離; 它改變我們基本的開發、操作單元,由直接操作虛擬主機(VM),轉換到操作程序運行的“容器”上來。
Docker是2013年Docker 是 PaaS提供商 dotCloud 開源的一個基于 LXC 的高級容器引擎,源代碼托管在 Github上, 基于go語言并遵從Apache2.0協議開源,是dotCloud公司的絕處逢生之作,目前該公司以[docker]為名。
從2013年3月20日,第一個版本的Docker正式發布到 2014年6月Docker 1.0 正式發布,經歷了15個月。 雖然發展歷程很短,但Docker正在有越來越流行的趨勢。
其實Container技術并非Docker的創新,HeroKu, NodeJitsu 等云服務商都采用了類似這種輕量級的虛擬化技術,但Docker是第一個將這這種Container技術大規模開源并被社區廣泛接受的。
截止2016年9月1日,docker版本已經發展到了1.12,支持容器管理功能。

docker版本
                       二、docker生態系統和應用場景

2.1 docker生態系統

docker生態系統如下圖所示。


docker生態系統

Docker具備大量的合作用戶如亞馬遜、jekins等公司,社區活躍度也非常高。
Docker提供的平臺主要有Docker Hub和Docker Engine(Docker Engine是一系列linux技術的集合體現,之后會有詳細介紹)。
Docker生態系統需要了解的核心概念主要有三大組件。

  • Docker 鏡像 - Docker images
  • Docker 倉庫 - Docker registeries
  • Docker 容器 - Docker containers
2.1.1 Docker鏡像

Docker 鏡像是 Docker 容器運行時的只讀模板,每一個鏡像由一系列的層 (layers) 組成。Docker 使用 UnionFS 來將這些層聯合到單獨的鏡像中。UnionFS 允許獨立文件系統中的文件和文件夾(稱之為分支)被透明覆蓋,形成一個單獨連貫的文件系統。正因為有了這些層的存在,Docker 是如此的輕量。當你改變了一個 Docker 鏡像,比如升級到某個程序到新的版本,一個新的層會被創建。因此,不用替換整個原先的鏡像或者重新建立(在使用虛擬機的時候你可能會這么做),只是一個新 的層被添加或升級了。現在你不用重新發布整個鏡像,只需要升級,層使得分發 Docker 鏡像變得簡單和快速。

docker image construct
2.1.2 Docker倉庫

Docker Hub是類似于Github的一種代碼倉庫,同樣的,Docker 倉庫也有公有和私有的概念。公有的 Docker 倉庫名字是 Docker Hub。Docker Hub 提供了龐大的鏡像集合供使用。這些鏡像可以是自己創建,或者在別人的鏡像基礎上創建。Docker 倉庫是 Docker 的分發部分。

docker registries
2.1.3 Docker 容器

Docker 容器和文件夾很類似,一個Docker容器包含了所有的某個應用運行所需要的環境。每一個 Docker 容器都是從 Docker 鏡像創建的。Docker 容器可以運行、開始、停止、移動和刪除。每一個 Docker 容器都是獨立和安全的應用平臺,Docker 容器是 Docker 的運行部分。

docker container

2.2 Docker應用場景

Docker的生態系統如此龐大和受歡迎,那么它的應用場景在哪些方面呢?
我查閱資料,整理了一些場景如下。

  • 權衡資源隔離和低消耗的場景
    在AVOS平臺上,一臺 16 核 32G 內存的虛擬機上,需要跑 500+ 個用戶的應用(每個應用的功能可以認為是一個網站 + 一系列的 RESTful API),有兩個事情很重要:

  • 資源隔離:比如限制應用最大內存使用量,或者資源加載隔離等。

  • 低消耗:虛擬化本身帶來的損耗需要盡量的低。
    我們不可能在一臺機器上開 500 個虛擬機,雖然可以在資源隔離方面做的很好,但這種虛擬化本身帶來的資源消耗太嚴重。
    另一個方面,我們可以考慮使用語言級別沙箱,雖然這種「虛擬化」本身的消耗可以低到忽略不計,但是資源隔離方面絕對是噩夢,比如你打算在一個 JVM 里隔離內存的使用。
    而 Docker 很好的權衡了兩者,即擁有不錯的資源隔離能力,又有很低的虛擬化開銷。

  • 孫宏亮:從輕量級工具、持續集成到微服務架構

    • 就我個人所知,早在14年國內有一些公司,開始嘗試docker,當時畢竟docker是一個新事物,很多新特性方面的優點,并沒有被大大的利用起來,這個也可以理解。那時docker對一些企業的價值在于計算的輕量級,也就是對于一些計算型的任務,通過docker的形式來分發,部署快,隔離性好,這樣的任務包括:消息傳遞,圖像處理等。
    • 14下半年到15年初,docker的價值被更大化,應用的運行,服務的托管,外界的接受度也變高,國內也出現了一些startup公司,比如DaoCloud,靈雀云等。但這些僅僅是這些公司的第一步,后續緊跟的更多的是基于代碼與鏡像之間的CI/CD,縮減開發測試發布的流程,這方面的實踐逐漸成熟。
    • 微服務架構的興起。微服務會對現階段的軟件架構有一些沖擊,同樣也是軟件系統設計方法論的內容。這些方面國外討論的要多一些,相信這一點也會近年來多家公司發力的地方。
  • 需要配置多種不同環境的場景
    這是Docker公司宣傳的Docker的主要使用場景。虛擬機的最大好處是能在你的硬件設施上運行各種配置不一樣的平臺(軟件、系統),Docker在降低額外開銷的情況下提供了同樣的功能。它能讓你將運行環境和配置放在代碼中然后部署,同一個Docker的配置可以在不同的環境中使用,這樣就降低了硬件要求和應用環境之間耦合度。

  • 快速部署和整合服務器的場景
    正如通過虛擬機來整合多個應用,Docker隔離應用的能力使得Docker可以整合多個服務器以降低成本。由于沒有多個操作系統的內存占用,以及能在多個實例之間共享沒有使用的內存,Docker可以比虛擬機提供更好的服務器整合解決方案。在虛擬機之前,引入新的硬件資源需要消耗幾天的時間。Docker的虛擬化技術將這個時間降到了幾分鐘,Docker只是創建一個容器進程而無需啟動操作系統,這個過程只需要秒級的時間。這正是Google和Facebook都看重的特性。
    你可以在數據中心創建銷毀資源而無需擔心重新啟動帶來的開銷。通常數據中心的資源利用率只有30%,通過使用Docker并進行有效的資源分配可以提高資源的利用率。

  • 李肇中:利用Docker體驗不易安裝的場景,提高工作效率
    我認為docker的出現對于linux開發者是重大利好,我們都知道在linux上面做開發,配置環境變量異常繁瑣,尤其是在設置交叉編譯環境的時候。
    舉個例子比如我要設置mips的編譯環境,而我宿主機是debian.有些優秀的工具只存在于gentoo平臺,而gentoo又不好安裝,我們使用docker只要從docker hub上面pull下鏡像,就可以完美使用,這使得開發人員效率最大化。

以上場景應用摘自知乎問答https://www.zhihu.com/question/22969309

小結:個人認為在linux進行學習時,可以將學習內容進行docker化打包保存到docker hub或者私有倉庫,這樣就不怕在環境丟失時重新配置環境。當然,實際應用時,一個用戶數不大的web應用放在docker上操作也簡單,是可以作為一個備份保存下來的。

                            三、Docker原理

Docker核心解決的問題是利用LXC來實現類似VM的功能,從而利用更加節省的硬件資源提供給用戶更多的計算資源。同VM的方式不同, LXC其并不是一套硬件虛擬化方法 - 無法歸屬到全虛擬化、部分虛擬化和半虛擬化中的任意一個,而是一個操作系統級虛擬化方法, 理解起來可能并不像VM那樣直觀。所以我們從虛擬化到docker要解決的問題出發,看看他是怎么滿足用戶虛擬化需求的。
用戶需要考慮虛擬化方法,尤其是硬件虛擬化方法,需要借助其解決的主要是以下4個問題:

  • 隔離性 - 每個用戶實例之間相互隔離, 互不影響。 硬件虛擬化方法給出的方法是VM, LXC給出的方法是container,更細一點是kernel namespace
  • 可配額/可度量 - 每個用戶實例可以按需提供其計算資源,所使用的資源可以被計量。硬件虛擬化方法因為虛擬了CPU, memory可以方便實現, LXC則主要是利用cgroups來控制資源
  • 移動性 - 用戶的實例可以很方便地復制、移動和重建。硬件虛擬化方法提供snapshot和image來實現,docker(主要)利用AUFS實現
  • 安全性 - 這個話題比較大,這里強調是host主機的角度盡量保護container。硬件虛擬化的方法因為虛擬化的水平比較高,用戶進程都是在KVM等虛擬機容器中翻譯運行的, 然而對于LXC, 用戶的進程是lxc-start進程的子進程, 只是在Kernel的namespace中隔離的, 因此需要一些kernel的patch來保證用戶的運行環境不會受到來自host主機的惡意入侵, dotcloud(主要是)利用kernel grsec patch解決的。
docker原理結構

3.1 Namespace

Namespace主要負責資源隔離,可以保障一個容器中運行一個進程而且不能看到和影響容器外的其它進程。

Namespace

有了以上5種namespace從進程、網絡、IPC、文件系統、UTS和用戶角度的隔離,一個container就可以對外展現出一個獨立計算機的能力,并且不同container從OS層面實現了隔離。然而不同namespace之間資源還是相互競爭的,仍然需要類似ulimit來管理每個container所能使用的資源 - LXC 采用的是cgroup。

3.2 Control Groups(cgroup)

cgroups 實現了對資源的配額和度量。 cgroups 的使用非常簡單,提供類似文件的接口,在 /cgroup目錄下新建一個文件夾即可新建一個group,在此文件夾中新建task文件,并將pid寫入該文件,即可實現對該進程的資源控制。具體的資源配置選項可以在該文件夾中新建子 subsystem ,{子系統前綴}.{資源項} 是典型的配置方法.
通過cgroup限制資源如cpu、內存、硬盤I/O的使用。

3.3 Linux 容器 (LXC)

借助于namespace的隔離機制和cgroup限額功能,LXC提供了一套統一的API和工具來建立和管理container。
LXC 旨在提供一個共享kernel的 OS 級虛擬化方法,在執行時不用重復加載Kernel, 且container的kernel與host共享,因此可以大大加快container的 啟動過程,并顯著減少內存消耗。在實際測試中,基于LXC的虛擬化方法的IO和CPU性能幾乎接近 baremetal 的性能, 大多數數據有相比 Xen具有優勢。當然對于KVM這種也是通過Kernel進行隔離的方式, 性能優勢或許不是那么明顯, 主要還是內存消耗和啟動時間上的差異。

3.4 AUFS

Docker對container的使用基本是建立在LXC基礎之上的,然而LXC存在的問題是難以移動 - 難以通過標準化的模板制作、重建、復制和移動 container。
在以VM為基礎的虛擬化手段中,有image和snapshot可以用于VM的復制、重建以及移動的功能。想要通過container來實現快速的大規模部署和更新, 這些功能不可或缺。
Docker 正是利用AUFS來實現對container的快速更新 - 在docker0.7中引入了storage driver, 支持AUFS, VFS, device mapper, 也為BTRFS以及ZFS引入提供了可能。 但除了AUFS都未經過dotcloud的線上使用,因此我們還是從AUFS的角度介紹。
AUFS (AnotherUnionFS) 是一種 Union FS, 簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統下(unite several directories into a single virtual filesystem)的文件系統, 更進一步地, AUFS支持為每一個成員目錄(AKA branch)設定'readonly', 'readwrite' 和 'whiteout-able' 權限, 同時AUFS里有一個類似
分層的概念, 對 readonly 權限的branch可以邏輯上進行修改(增量地, 不影響readonly部分的)。通常 Union FS有兩個用途, 一方面可以實現不借助 LVM, RAID 將多個disk和掛在到一個目錄下, 另一個更常用的就是將一個readonly的branch和一個writeable的branch聯合在一起,Live CD正是基于此可以允許在 OS image 不變的基礎上允許用戶在其上進行一些寫操作。Docker在AUFS上構建的container image也正是如此。

AUFS image

如上圖所示,AUFS技術利用了寫時拷貝技術,只讀部分是Image,可寫部分是container.允許read-only和read-write目錄并存;可以實現把多個不同目錄的內容合并在一起。

3.5 GRSEC

grsec是linux kernel安全相關的patch, 用于保護host防止非法入侵。由于其并不是docker的一部分,我們只進行簡單的介紹。
grsec可以主要從4個方面保護進程不被非法入侵:

  • 隨機地址空間 - 進程的堆區地址是隨機的
  • 用只讀的memory management unit來管理進程流程, 堆區和棧區
  • 內存只包含數據結構/函數/返回地址和數據, 是non-executeable
  • 審計和Log可疑活動
  • 編譯期的防護
    安全永遠是相對的,這些方法只是告訴我們可以從這些角度考慮container類型的安全問題可以關注的方面。

3.6 Docker運行原理

Docker本身是基于C/S架構的,有自己的服務器和客戶端,Docker實際上由三大組件構成,如下圖所示。

docker組件

其中,docker client是用戶界面,docker daemon處理服務請求,docker containers負責應用程序的運行。

                              四、Docker與vm性能對比

4.1 Docker性能測試測試環境:

  • 操作系統:CentOS7、openstack nova-docker啟動的centos7、openstack環境啟動的centos7
  • 虛擬機CPU:Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60GHz * 2
  • 內存:Micron 2133MHz 16G * 8
  • 網卡:Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection關鍵字:Linpack、netperf、iometer
    測試從計算效率、內存訪問效率、啟動時間和資源消耗進行比較。
4.1.1 Docker與虛擬機計算效率比較

在測試中是通過運算Linpack程序來獲得計算能力數據的。結果如下圖所示:

計算效率對比

圖中從左往右分別是物理機、docker和虛擬機的計算能力數據。可見docker相對于物理機其計算能力幾乎沒有損耗,而虛擬機對比物理機則有著非常明顯的損耗。虛擬機的計算能力損耗在50%左右。 為什么會有這么大的性能損耗呢?一方面是因為虛擬機增加了一層虛擬硬件層,運行在虛擬機上的應用程序在進行數值計算時是運行在Hypervisor虛擬的CPU上的;另外一方面是由于計算程序本身的特性導致的差異。虛擬機虛擬的cpu架構不同于實際cpu架構,數值計算程序一般針對特定的cpu架構有一定的優化措施,虛擬化使這些措施作廢,甚至起到反效果。比如對于本次實驗的平臺,實際的CPU架構是2塊物理CPU,每塊CPU擁有16個核,共32個核,采用的是NUMA架構;而虛擬機則將CPU虛擬化成一塊擁有32個核的CPU。這就導致了計算程序在進行計算時無法根據實際的CPU架構進行優化,大大減低了計算效率。

4.1.2 docker與虛擬機內存訪問效率比較

內存訪問效率的比較相對比較復雜一點,主要是內存訪問有多種場景:

  • 大批量的,連續地址塊的內存數據讀寫。這種測試環境下得到的性能數據是內存帶寬,性能瓶頸主要在內存芯片的性能上;
  • 隨機內存訪問性能。這種測試環境下的性能數據主要與內存帶寬、cache的命中率和虛擬地址與物理地址轉換的效率等因素有關。 以下將主要針對這兩種內存訪問場景進行分析。在分析之前我們先概要說明一下docker和虛擬機的內存訪問模型差異。下圖是docker與虛擬機內存訪問模型:
docker與虛擬機內存訪問模型

可見在應用程序內存訪問上,虛擬機的應用程序要進行2次的虛擬內存到物理內存的映射,讀寫內存的代價比docker的應用程序高。

4.1.3 docker與虛擬機啟動時間及資源耗費比較

上面兩個小節主要從運行在docker里的程序和運行在虛擬機里的程序進行性能比較。事實上,docker之所以如此受到開發者關注的另外一個重要原因是啟動docker的系統代價比啟動一臺虛擬機的代價要低得多:無論從啟動時間還是從啟動資源耗費角度來說。docker直接利用宿主機的系統內核,避免了虛擬機啟動時所需的系統引導時間和操作系統運行的資源消耗。利用docker能在幾秒鐘之內啟動大量的容器,這是虛擬機無法辦到的。快速啟動、低系統資源消耗的優點使docker在彈性云平臺和自動運維系統方面有著很好的應用前景。

4.2 docker優缺點總結

4.2.1優點
  • 容積小且速度快,易于分發且能隔離應用
  • cpu/內存的低消耗
  • 可以部署在本地,虛擬機或者云上
  • 支持絕大多數linux系統,windows、mac除了虛擬版,也有beta版投入研發,平臺較為完善
  • Google、微軟、亞馬遜等公司都支持Docker
4.2.2缺點
  • 真實投入生產,還需要多種開源組件和技術的支持,如kubernetes管理容器、etcd管理存儲、應用打包技術dockerfile、容器間的網絡管理flannel、私有倉庫的構建、持續集成jenkins的結合、監控docker的工具等等。

  • docker自身版本迭代較快,國內還未有完善的解決方案

  • docker部署過程中對基礎運維的要求更高,會遇到問題如Docker鏡像熱升級、Docker版本熱升級、監控報警等等。

  • docker對于windows、mac的原生支持尚處在beta版本。

                              五、Docker技術點
    

5.1 Docker安裝

windows、mac、linux版本安裝均可在官網https://docs.docker.com/

5.2 常用docker命令

  • 查看容器日志
    docker logs -f <容器名orID>
  • 查看正在運行的容器
    • docker ps
    • docker ps -a為查看所有的容器,包括已經停止的。
  • 刪除所有容器
    docker rm $(docker ps -a -q)
  • 刪除單個容器
    docker rm <容器名orID>
  • 停止、啟動、殺死一個容器
    • docker stop <容器名orID>
    • docker start <容器名orID>
    • docker kill <容器名orID>
  • 查看所有鏡像
    docker images
  • 拉取鏡像
    docker pull <鏡像名:tag>
    如docker pull sameersbn/redmine:latest
  • 當需要把一臺機器上的鏡像遷移到另一臺機器的時候,需要保存鏡像與加載鏡像。
    機器a
    docker save busybox-1 > /home/save.tar
    使用scp將save.tar拷到機器b上,然后:
    docker load < /home/save.tar
  • 構建自己的鏡像
    docker build -t <鏡像名> <Dockerfile路徑>
    如Dockerfile在當前路徑:
    docker build -t xx/gitlab .
  • 后臺運行(-d)、并暴露端口(-p)
    docker run -d -p 127.0.0.1:33301:22 centos6-ssh

其它語法可通過docker命令查詢學習,后面的案例會介紹一些實際命令的使用。

5.3 dockerfile文件的編寫

5.4 Docker應用案例

5.4.1 javeee應用
5.4.2 mysql服務
5.4.3 wordpress博客服務
5.4.4 tomcat的web應用,以現有應用為例
                           六、容器管理工具kubernetes

6.1 kubernetes簡介

Kubernetes是Google開源的容器集群管理系統,其提供應用部署、維護、 擴展機制等功能,利用Kubernetes能方便地管理跨機器運行容器化的應用,其主要功能如下:

  1. 使用Docker對應用程序包裝(package)、實例化(instantiate)、運行(run)。

  2. 以集群的方式運行、管理跨機器的容器。

  3. 解決Docker跨機器容器之間的通訊問題。

  4. Kubernetes的自我修復機制使得容器集群總是運行在用戶期望的狀態。
      它透明地為用戶提供原生態系統,如“需要5個 WildFly服務器和1個 MySQL服務器運行". Kubernetes具有自我修復機制,如重新啟動 重新啟動定時計劃 復制容器以確保恢復狀態,用戶只需要定義狀態,那么 Kubernetes就會確保狀態總是在集群中。
      Docker定義了運行代碼時的容器,有命令用來啟動 停止 重啟 鏈接容器,Kubernetes使用Docker打包以及實例化應用程序。
      一個典型的應用程序必須跨多個主機。 例如,您的web層(Apache )可能運行在一個容器。 同樣地,應用程序層將會運行在另外一組不同的容器中。 web層需要將請求委托給應用程序層。 當然,在某些情況下,你可能將web服務器和應用服務器打包在一起放在相同的容器。 但是數據庫層通常運行在一個單獨層中。 這些容器之間需要相互交互。 使用上面的任何解決方案都需要編制腳本啟動容器,以及監控容器,因防止出現問題。 而Kubernetes在應用程序狀態被定義后將為用戶實現所有這些工作。

6.2 kubernetes原理與架構

6.2.1 kubernetes概念
kubernetes架構
6.2.1.1 Pods

Pod是Kubernetes的基本操作單元,把相關的一個或多個容器構成一個Pod,通常Pod里的容器運行相同的應用。Pod包含的容器運行在同一個Minion(Host)上,看作一個統一管理單元,共享相同的volumes和network namespace/IP和Port空間。

6.2.1.2 Services

Services也是Kubernetes的基本操作單元,是真實應用服務的抽象,每一個服務后面都有很多對應的容器來支持,通過Proxy的port和服務selector決定服務請求傳遞給后端提供服務的容器,對外表現為一個單一訪問接口,外部不需要了解后端如何運行,這給擴展或維護后端帶來很大的好處。

6.2.1.3 Replication Controllers

Replication Controller確保任何時候Kubernetes集群中有指定數量的pod副本(replicas)在運行, 如果少于指定數量的pod副本(replicas),Replication Controller會啟動新的Container,反之會殺死多余的以保證數量不變。Replication Controller使用預先定義的pod模板創建pods,一旦創建成功,pod 模板和創建的pods沒有任何關聯,可以修改pod 模板而不會對已創建pods有任何影響,也可以直接更新通過Replication Controller創建的pods。對于利用pod 模板創建的pods,Replication Controller根據label selector來關聯,通過修改pods的label可以刪除對應的pods。Replication Controller主要有如下用法:

  1. Rescheduling
    如上所述,Replication Controller會確保Kubernetes集群中指定的pod副本(replicas)在運行, 即使在節點出錯時。
  2. Scaling
    通過修改Replication Controller的副本(replicas)數量來水平擴展或者縮小運行的pods。
  3. Rolling updates
    Replication Controller的設計原則使得可以一個一個地替換pods來rolling updates服務。
  4. Multiple release tracks
    如果需要在系統中運行multiple release的服務,Replication Controller使用labels來區分multiple release tracks。
6.2.1.4 Labels

Labels是用于區分Pod、Service、Replication Controller的key/value鍵值對,Pod、Service、 Replication Controller可以有多個label,但是每個label的key只能對應一個value。Labels是Service和Replication Controller運行的基礎,為了將訪問Service的請求轉發給后端提供服務的多個容器,正是通過標識容器的labels來選擇正確的容器。同樣,Replication Controller也使用labels來管理通過pod 模板創建的一組容器,這樣Replication Controller可以更加容易,方便地管理多個容器,無論有多少容器。

6.2.2 kubernetes架構

Kubenetes整體框架如下圖,主要包括kubecfg、Master API Server、Kubelet、Minion(Host)以及Proxy。


Kubernetes High Level構件

具體每部分功能可參考書籍《kubernetes權威指南》。

6.3 kubernetes中算法介紹

6.3.1算法概覽

最新一版的kubernetes release中我們看到了一個令人欣喜的特性:Autoscaling。它實現了replicationcontroller中pod的橫向自動擴容。以下是摘自官方文檔的相關內容:
自動擴容將通過一個新的resource(就像之前的pod,service等等)實現。目前只支持針對cpu使用度進行動態擴容。未來的版本中,將會實現基于另一個resource:metrics(這是說未來監控數據將會有一個更統一的展示?)
主要結構
1.Scale subresourceScale subresource是一個虛擬的resource,用來記錄擴容進度。其主要結構如下:
// represents a scaling request for a resource.
type Scale struct {
unversioned.TypeMeta
api.ObjectMeta

// defines the behavior of the scale.
Spec ScaleSpec

// current status of the scale.
Status ScaleStatus
}

// describes the attributes of a scale subresource
type ScaleSpec struct {
// desired number of instances for the scaled object.
Replicas int json:"replicas,omitempty"
}
// represents the current status of a scale subresource.
type ScaleStatus struct {
// actual number of observed instances of the scaled object.
Replicas int json:"replicas"
// label query over pods that should match the replicas count. Selector map[string]string json:"selector,omitempty"
}

其中ScaleSpec.Replicas表示我們預定的集群實例數目標。ScaleStatus.Replicas表示當前實例數,ScaleStatus.Selector是一個選擇器,選擇對應的pods。
2.HorizontalPodAutoscaler 這個就是真正控制擴容的resource,其結構如下:
// configuration of a horizontal pod autoscaler.
type HorizontalPodAutoscaler struct {
unversioned.TypeMeta
api.ObjectMeta
// behavior of autoscaler.
Spec HorizontalPodAutoscalerSpec
// current information about the autoscaler.
Status HorizontalPodAutoscalerStatus
}
// specification of a horizontal pod autoscaler.
type HorizontalPodAutoscalerSpec struct {
// reference to Scale subresource; horizontal pod autoscaler will learn the current resource
// consumption from its status,and will set the desired number of pods by modifying its spec.
ScaleRef SubresourceReference
// lower limit for the number of pods that can be set by the autoscaler, default 1.
MinReplicas *int
// upper limit for the number of pods that can be set by the autoscaler.
// It cannot be smaller than MinReplicas.
MaxReplicas int
// target average CPU utilization (represented as a percentage of requested CPU) over all the pods;
// if not specified it defaults to the target CPU utilization at 80% of the requested resources.
CPUUtilization *CPUTargetUtilization
}
type CPUTargetUtilization struct {
// fraction of the requested CPU that should be utilized/used, // e.g. 70 means that 70% of the requested CPU should be in use.
TargetPercentage int
}
// current status of a horizontal pod autoscaler
type HorizontalPodAutoscalerStatus struct {
// most recent generation observed by this autoscaler. ObservedGeneration *int64
// last time the HorizontalPodAutoscaler scaled the number of pods;
// used by the autoscaler to control how often the number of pods is changed.
LastScaleTime *unversioned.Time
// current number of replicas of pods managed by this autoscaler.
CurrentReplicas int
// desired number of replicas of pods managed by this autoscaler. DesiredReplicas int
// current average CPU utilization over all pods, represented as a percentage of requested CPU,
// e.g. 70 means that an average pod is using now 70% of its requested CPU.
CurrentCPUUtilizationPercentage *int
}

其中的ScaleRef是一個Scale subresource的引用,MinReplicas, MaxReplicas and CPUUtilization定義了自動擴容的配置(允許的最大實例數,最小實例數,以及cpu使用配額)。
3.HorizontalPodAutoscalerList用于記錄一個namespace下的所有HorizontalPodAutoscaler。本質上是一個結構數組。

6.3.2自動擴容算法

官方文檔給出的并不是算法, 而是實現步驟,整個自動擴容的流程是:1.通過podselector找到要擴容的集群2.收集集群最近的cpu使用情況(CPU utilization)3.對比在擴容條件里記錄的cpu限額(CPUUtilization)4.調整實例數(必須要滿足不超過最大/最小實例數)5.每隔30s做一次自動擴容的判斷(這個日后應該會成為一個擴容條件的參數
CPU utilization的計算方法是用cpu usage(最近一分鐘的平均值,通過heapster可以直接獲取到)除以cpu請求(疑問:這個是是什么意思?)。未來k8s會開放一個api直接獲取heapster收集到的監控數據。
真正的算法是:
A.TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)ceil()表示取大于或等于某數的最近一個整數舉個栗子:我們有一個集群實例數是3 pods。cpu限額,即Target是每個pod分配1.1核,當cpu的使用度CurrentPodsCPUUtilization為1.1,1.4,1.3時,要擴容成多少個呢?ceil((1.1+1.4+1.3)/1.1)= 4 所以擴容成四個實例。
B.由于啟動實例時cpu的使用度會陡增,所以自動擴容會等待一段時間以收集準確的運行時監控數據。每次擴容/縮容后冷卻三分鐘才能再度進行擴容,而縮容則要等5分鐘后。這是因為自動擴容使用保守的方法,盡可能滿足pods業務的正常使用,所以擴容的優先級要大于縮容。
C.當滿足:avg(CurrentPodsConsumption) / Target >1.1 或 <0.9時才會觸發進行擴容/縮容。這也是為了避免出現頻繁的擴容縮容。
擴容條件的相對與絕對度量
為了方便使用,建議采用相對(relative)的度量標準(如 90%的cpu資源)而不是絕對的標準(如0.6個cpu核心)來描述擴容條件。否則,當用戶修改pods的請求資源時還需要去修改這些絕對值。比如:我們創建一個集群時,podtemplate中的resource里填入了cpu為1,即最多分配一個cpu核心給該pod,如果在擴容條件中采用絕對標準,我們必須填一個小于1的數,否則這個條件根本不會被觸發。而當我們要修改分配的資源為0.8個核心時,又必須要修改擴容條件以確保其小于0.8。這就很麻煩了。
kubectl中的支持以及待支持
為了方便使用,在kubectl的cmd命令中加入了 creating/updating/deleting/listing 命令用來操作HorizontalPodAutoscaler
未來可能會加入像kubectl autoscale這樣的命令,對一個已經在跑的集群實時進行動態擴容。

6.4 kubernetes環境搭建與工具介紹

本人已通過此教程搭建單機版kubernetes成功http://dockone.io/article/950
多機版由于條件限制還未成功實施。

                           七、Docker學習總結與展望

7.1 總結

容器技術究竟其成熟與否,也是互聯網發展的一種趨勢,它所提出的理念是值得每一位互聯網工作者去學習和探討的。

7.2 展望

docker官網在容器編排上的持續發力,今年7月份時docker公司將swarm整合進入docker engine層,其實我希望看到docker生態系統不要過多的碎片化,解決方案過多,容易導致迷失方向。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容