本文是Kubernetes系列的第一篇,將介紹Docker和Kubernetes兩大熱門開源產品,主要內容包括:基本概念、基礎組件、Kubernetes架構。html
Docker 起初是 dotCloud 公司創始人 Solomon Hykes 在法國的時候發起的一項公司內部項目,Docker是基於 dotCloud 公司多年雲服務技術的一次革新,在 2013 年 3 月以 Apache 2.0 受權協議進行開源,其項目主要代碼在 GitHub 上進行維護,自從Docker 開源以後,就一直受到了普遍討論和關注。node
Docker 進行開發實現使用的是Google 公司推出的 Go 語言,對進程進行封裝隔離是基於 Linux 內核的 cgroup,namespace,以及 AUFS 類的 Union FS 等技術,這屬於操做系統層面的虛擬化技術。由於隔離的進程獨立於宿主與其它隔離的進程,因此也稱其爲容器(後文會對「容器」的概念進行詳細介紹)。Docker 在容器的基礎上,進行了進一步的封裝,從網絡互聯、文件系統到進程隔離等,大大地簡化了容器的建立和維護,讓 Docker 技術比虛擬機技術更加輕便、快捷。mysql
如下兩張圖片對比了 Docker 與傳統虛擬化方式的不一樣之處。Docker 容器內的應用進程直接運行於宿主的內核,容器內沒有本身的內核,沒有進行硬件虛擬;而傳統虛擬機技術是虛擬出一套硬件後,在其上運行一個完整操做系統,在該系統上再運行所需應用進程。所以容器要比傳統虛擬機更爲輕便。git
Docker是一種新興的虛擬化方式,跟傳統的虛擬化方式相比具備衆多優點。github
由於容器不須要進行硬件虛擬以及運行完整操做系統等額外開銷,因此Docker 對系統資源的利用率更高。sql
Docker 容器應用因爲直接運行於宿主內核,無需啓動完整的操做系統,所以能夠作到秒級、甚至毫秒級的啓動時間。極大地節省了開發、測試,部署的時間。docker
開發過程當中比較常見的問題就是環境一致性問題。由於開發環境、測試環境、生產環境不一致,致使有些 bug 並未在開發過程當中被發現。而 Docker 的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現 「這段代碼在我機器上沒問題啊」 這類問題。數據庫
對開發和運維人員來講,最但願的就是一次建立或配置,能夠在任意地方正常運行。使用 Docker 能夠經過定製應用鏡像來實現持續集成、持續交付、部署。開發人員能夠經過 Dockerfile 來進行鏡像構建,並結合持續集成(Continuous Integration)系統進行集成測試,而運維人員則能夠直接在各類環境中快速部署該鏡像,甚至結合持續部署(Continuous Delivery/Deployment) 系統進行自動部署。json
並且使用 Dockerfile 使鏡像構建透明化,不只開發團隊能夠理解應用運行環境,也方便運維團隊理解應用運行所需條件,幫助更好地在生產環境中部署該鏡像。windows
因爲 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 能夠在不少平臺上運行,不管是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結果是一致的。所以用戶能夠很輕鬆地將在一個平臺上運行的應用,遷移到另外一個平臺上,而不用擔憂運行環境變化致使應用沒法正常運行的狀況。
Docker 使用的分層存儲以及鏡像技術,使得應用重複部分的複用更爲容易,也使得應用的維護更新和基於基礎鏡像進一步擴展鏡像變得很是簡單。此外,Docker 團隊同各個開源項目團隊一塊兒維護了一大批高質量的官方鏡像,既能夠直接在生產環境使用,又能夠做爲基礎進一步定製,大大下降了應用服務的鏡像製做成本。
Docker的口號是「Build, Ship and Run Any App, Anywhere.」,大意是編譯好一個應用後,能夠在任何地方運行,不會像傳統的程序同樣,一旦換了運行環境,每每就會出現缺這個庫,少那個包的問題。那麼Docker是怎麼作到這點的呢?
簡單說就是它在編譯應用的時候把這個應用依賴的全部東西都構建到鏡像裏面(有點像程序的靜態編譯——只是像而已)。咱們把這個編譯構建好的東西叫Docker鏡像(Image),而後當Docker deamon(Docker的守護進程/服務進程)運行這個鏡像的時候,咱們稱其爲Docker容器(Container)。能夠簡單理解Docker鏡像和Docker容器的關係就像是程序和進程的關係同樣(固然實質是不同的)。
每一個Docker鏡像(Image)都引用了一些只讀的(read-only)層(layer),不一樣的文件系統layer也不一樣。這些layer堆疊在一塊兒構成了容器(Container)的根文件系統(root filesystem)。下圖是Ubuntu 15.04的鏡像,共由4個鏡像層(image layer)組成:
容器和鏡像的主要區別就是頂部的那個可寫層(即以前說的那個「container layer」)。容器運行時作的全部操做都會寫到這個可寫層裏面,當容器刪除的時候,這個可寫層也會被刪掉,但底層的鏡像依舊保持不變。因此,不一樣的容器都有本身的可寫層,但能夠共享同一個底層鏡像。下圖展現了多個容器共享同一個Ubuntu 15.04鏡像。
Docker的storage driver負責管理只讀的鏡像層和可寫的容器層,固然不一樣的driver實現的方式也不一樣,但其後都有兩項關鍵技術:可堆疊的鏡像層(stackable image layer)和寫時拷貝技術(copy-on-write, CoW)。
剛開始的時候,Docker通常只適用於無狀態的計算場景使用。但隨着發展,Docker經過data volume技術也能夠作到數據持久化了。Data volume就是咱們將主機的某個目錄掛載到容器裏面,這個data volume不受storage driver的控制,全部對這個data volume的操做會繞過storage driver直接其操做,其性能也只受本地主機的限制。並且咱們能夠掛載任意多個data volume到容器中,不一樣容器也能夠共享同一個data volume。
下圖展現了一個Docker主機上面運行着兩個容器.每個容器在主機上面都有着本身的地址空間(/var/lib/docker/...),除此之外,它們還共享着主機上面的同一個/data目錄。
參考文檔:
yeasy.gitbooks.io/docker_prac… yeasy.gitbooks.io/docker_prac… docs.docker.com/storage/sto…
Kubernetes 是谷歌開源的容器集羣管理系統,是 Google 多年大規模容器管理技術 Borg 的開源版本,主要功能包括:
Kubernetes 發展很是迅速,已經成爲容器編排領域的領導者。
Kubernetes 提供了不少的功能,它能夠簡化應用程序的工做流,加快開發速度。一般,一個成功的應用編排系統須要有較強的自動化能力,這也是爲何 Kubernetes 被設計做爲構建組件和工具的生態系統平臺,以便更輕鬆地部署、擴展和管理應用程序。
用戶可使用 Label 以本身的方式組織管理資源,還可使用 Annotation 來自定義資源的描述信息,好比爲管理工具提供狀態檢查等。
此外,Kubernetes 控制器也是構建在跟開發人員和用戶使用的相同的 API 之上。用戶能夠編寫本身的控制器和調度器,也能夠經過各類插件機制擴展系統的功能。這種設計使得用戶能夠方便地在 Kubernetes 之上構建各類應用系統。
Kubernetes 不是一個傳統意義上,一應俱全的 PaaS (平臺即服務) 系統。它給用戶預留了選擇的自由。
另外,已經有不少 PaaS 系統運行在 Kubernetes 之上,如 Openshift, Deis 和 Eldarion 等。 你也能夠構建本身的 PaaS 系統,或者只使用 Kubernetes 管理你的容器應用。
固然了,Kubernetes 不只僅是一個 「編排系統」,它消除了編排的須要。Kubernetes 經過聲明式的 API 和一系列獨立、可組合的控制器保證了應用老是在指望的狀態,而用戶並不須要關心中間狀態是如何轉換的。這使得整個系統更容易使用,並且更強大、更可靠、更具彈性和可擴展性。
參考文檔:
Kubernetes 主要由如下幾個核心組件組成:
除了核心組件,還有一些推薦的 Add-ons:
Etcd是CoreOS基於Raft開發的分佈式key-value存儲,可用於服務發現、共享配置以及一致性保障(如數據庫選主、分佈式鎖等)。
Etcd主要功能:
kube-apiserver 是 Kubernetes 最重要的核心組件之一,主要提供如下的功能:
Controller Manager由kube-controller-manager和cloud-controller-manager組成,是Kubernetes的大腦,它經過apiserver監控整個集羣的狀態,並確保集羣處於預期的工做狀態。
kube-controller-manager由一系列的控制器組成
在Kubernetes啓用Cloud Provider的時候才須要,用來配合雲服務提供商的控制,也包括一系列的控制器,如:
kube-scheduler 負責分配調度 Pod 到集羣內的節點上,它監聽 kube-apiserver,查詢還未分配 Node 的 Pod,而後根據調度策略爲這些 Pod 分配節點(更新 Pod的 NodeName 字段)。
調度器須要充分考慮諸多的因素:
每一個節點上都運行一個 kubelet 服務進程,默認監聽 10250 端口,接收並執行 master 發來的指令,管理 Pod 及 Pod 中的容器。每一個 kubelet 進程會在 API Server 上註冊節點自身信息,按期向 master 節點彙報節點的資源使用狀況,並經過 cAdvisor 監控節點和容器的資源。
容器運行時(Container Runtime)是 Kubernetes 最重要的組件之一,負責真正管理鏡像和容器的生命週期。Kubelet 經過 Container Runtime Interface (CRI) 與容器運行時交互,以管理鏡像和容器。
每臺機器上都運行一個 kube-proxy 服務,它監聽 API server 中 service 和 endpoint 的變化狀況,並經過 iptables 等來爲服務配置負載均衡(僅支持 TCP 和 UDP)。
kube-proxy 能夠直接運行在物理機上,也能夠以 static pod 或者 daemonset 的方式運行。
kube-proxy 當前支持一下幾種實現:
K8s設置由幾個部分組成,其中一些是可選的,一些是整個系統運行所必需的。下面是k8s的全局架構圖
Master有三個組件:API Server、Scheduler、Controller。API Server提供了友好易用的API供外部調用,同時有不少強大的工具使得API調用更加簡單,如kubectl封裝了大量API調用,使得部署、配置更加簡單。Kubernetes-dashboard可讓用戶在界面上操做Kubernetes,而無需手動輸入各個API的調用地址參數等信息。
當API Server收到部署請求後,Scheduler會根據所需的資源,判斷各節點的資源佔用狀況分配合適的Node給新的容器。判斷依據包括內存、CPU、磁盤等。
Controller負責整個集羣的總體協調和健康,保證每一個組件以正確的方式運行。
在圖的最下邊是ETCD數據庫。如前文所述ETCD是分佈式存儲數據庫,其做爲Kubernetes的中央數據庫,存儲了集羣的狀態,組件能夠經過查詢ETCD瞭解集羣的狀態。
Kubernetes Master分配容器到Node執行,Node將會承受壓力,一般狀況下新容器不會運行在Master上。或者說Master是不可調度的,可是你也能夠選擇把Master同時也做爲Node,可是這並非地道的用法。下面的爲Node的架構圖:
Kube-proxy在Node中管理網絡,其左右相當重要。Kube-proxy經過管理iptables等方式使得pod到pod之間,和pod到node之間網絡可以互通。實質上在跨主機的pod之間網絡也可以互通。
Kubelet負責向api server報告信息,並把健康狀態、指標和節點狀態信息存入ETCD中。
Docker上文已詳細介紹這裏就很少作闡述。
Supervisord保證Docker和kubelet一直在運行中,supervisord並非必須組件,可使用其餘相似組件替換。
Pod是能夠在Kubernetes中建立和管理的最小可部署計算單元。一個POD中能夠包含多個容器,但Kubernetes僅管理pod。若是多個容器運行在一個POD中,就至關於這些容器運行在同一臺主機中,須要注意端口占用問題。
參考資料:
k8s.docker8.com/ www.youtube.com/watch?v=zeS…
Choerodon豬齒魚是一個開源企業服務平臺,是基於Kubernetes的容器編排和管理能力,整合DevOps工具鏈、微服務和移動應用框架,來幫助企業實現敏捷化的應用交付和自動化的運營管理的開源平臺,同時提供IoT、支付、數據、智能洞察、企業應用市場等業務組件,致力幫助企業聚焦於業務,加速數字化轉型。
歡迎你們關注Choerodon,支持開源...
你們也能夠掃描二維碼關注Choerodon的微信和微博: