前言php
容器技術目前的市場現狀是一家獨大、百花齊放。 關於容器技術,看看青雲QingCloud 王淵命(老王)是如何看待它的,本文來自他在青雲QingCloud 深圳站實踐課堂的演講。全文 2780字,閱讀時長約爲 11 分鐘。node
容器是什麼nginx
容器的概念外延比較廣,討論的時候容易產生分歧,雖然你們都在說容器,但各自的角度不一樣,表達的具體內容也徹底不同。總結來看容器有兩個視角,一是資源,二是應用。編程
一是從資源隔離的角度。容器技術常常被拿來跟虛擬化技術做對比,從技術角度來講,容器是一種跟VM 相似的資源隔離技術,它比 VM 的資源損耗小,但隔離性和安全性不如 VM ,等等。安全
二是從應用封裝的角度。Docker 之因此興起,緣由在於其重點關注應用的標準化,而不是資源的隔離。Docker 的鏡像機制提供了一種更高級的通用的應用製品包,也就是你們說的集裝箱能力。原來各類操做系統或編程語言都有各本身的製品機制,各自的依賴管理,製品庫都不相同。應用從源碼打包,分發到製品庫,再部署到服務器,很難抽象出一種通用的流程和機制。服務器
而有了 Docker 的鏡像以及鏡像倉庫標準以後,這個流程終於能夠標準化了。同時Docker 將進程的管理,好比啓動中止也標準化了。相似杯子、筐、集裝箱都是容器,它們的共同特色是能把雜物打包,標準化,方便運輸和訂價。在此之上,容器能夠作更高級的邏輯分裝和調度。網絡
容器生態圈現狀架構
容器技術目前的市場現狀是一家獨大、百花齊放。容器的解決方案很是多,以 Docker 爲首佔據了大部分的市場,此外還有各類解決方案如 Rocket、Mesos Universal container、LXC、Hyper Container 等。負載均衡
容器主流的調度系統 Kubernetes、Mesos和 Docker Swarm 是三足鼎立的狀態,他們各有優點。Kubernetes 偏重於應用的抽象和規範的定義,Mesos關注可擴展性及資源混合部署,Swarm 關注於開發環境和線上環境的一體化,更方便使用。運維
能夠看出,容器市場的競爭現已上升到調度層,這也是爲何 Docker 把 Swarm 嵌在內部,使得Docker 再也不是一個單機容器,而變成了調度系統的解決方案。
青雲QingCloud 容器解決方案
從資源視角和應用視角分析一下青雲QingCloud 提供的容器解決方案。
就資源視角來講,用戶但願 VM 能像 Docker 同樣,可對標準進程進行封裝,使得 VM 也是一個完整的操做系統。爲延續用戶對VM 的操做體驗,青雲QingCloud 在統一的 IaaS平臺上同時支持 VM(Virtual Machine 虛擬主機)與 CM(Container Machine 容器主機),使得用戶對虛擬化的部署習慣得以沿襲,同時還可享受容器資源輕量隔離的特色。
就應用視角來講,青雲QingCloud 支持容器編排系統,體如今兩方面:一是AppCenter 應用支持 Docker 鏡像,二是容器編排系統能夠做爲一個應用放在AppCenter 上。容器能夠在 VM 之上部署集羣,Mesos、Kubernetes、Swarm 也能夠做爲雲應用放在 AppCenter 之上,讓用戶能夠自主選擇。
Kuberneteson QingCloud AppCenter
咱們第一步作的是在 AppCenter 上部署 Kubernetes。爲何選擇 Kubernetes 呢?主要是由於 Kubernetes 部署比較複雜,若是最爲複雜的 Kubernetes 可以在青雲QingCloud AppCenter 上運行,其餘集羣也同樣能夠部署到 AppCenter 上。
QingCloud支持用戶一鍵部署 Kubernetes 集羣,不只解決了用戶很大的痛點,同時也驗證了 AppCenter 支持應用的普遍性。
爲此,咱們解決了四大難題:容器調度系統的網絡、數據本地存儲的讀取、容器平臺與負載均衡器集成以及實現 Kubernetes 應用的彈性伸縮能力。
接下來總體介紹一下 Kubernetes。
Kubernetes 概覽
Kubernetes 集羣包含兩種角色,一是 master, 二是 node,至關於 worker 或者 slave。
Master 有三個主要的組件:
一是 API Server(APIs),其底層是分佈式存儲(etcd),存儲集羣全部的數據;
二是 Controller Manager,承擔了 master 的主要職能,管控全部的節點以及 Kubernetes 之上的 pod,service 等;
三是調度器 Scheduler,能夠根據調度規則來分配節點最適合部署的位置。
如圖有兩個 Node,其上的 Kubelet 是節點的守護進程,用以管理 Node 上的全部 Pod。
Kubernetes 的 Pod 和 Docker Container 有點區別,這裏特殊說明下,Pod 裏包含多個 Container。Kubernetes 這樣設計主要有兩方面緣由:
1. 爲了和 Docker 解耦。Docker 啓動時會先初始化網絡,而後再啓動容器進程,由於不少應用啓動後若是沒有網絡就會報錯。但 Kubernetes 想用本身的網絡方案,就必須是先啓動容器,再建立網絡。
因而 Kubernetes 會先啓動一個空進程(pause進程,啓動後就一直 sleep),佔據容器的一個命名空間,在網絡、存儲建立出來後掛載到這個空容器上,而後才啓動用戶定義的容器,而這個容器直接複用 pause 容器的網絡和存儲。
2. 經過 Pod 打包多個 Container,使之共享同一個生命週期。這樣的解決方案也很是有利於多個容器有強依賴關係的場景,好比 nginx 和 php-fpm 進程,好比 Kubernetes 的內置 dns 的多個組件,kube-dns 負責監聽 Kubernetes 的 service 變動,而後轉換成 dns 記錄,寫入到 dnsmasq 中。這種場景下,任何一個組件獨立存活都是沒有意義的。
Kubernetes 抽象概念
Kubernetes 的目標在於制定一個標準和規範,可讓你來描述集羣的架構,定義服務的最終狀態,它來幫助你的系統達到和維持在這個狀態。這個其實和 Puppet/Ansible 等配置管理工具的目的是一致的,只是配置管理工具只能作達到某個狀態,無法實現維持到這個狀態(由於沒有動態的伸縮以及故障遷移等調度能力)。因此 Kubernetes 提出了許多抽象的概念,用來實現這種描述能力。如 Service、Job、ReplicaSet、Deployment等。
Kubernetes 網絡設計
Kubernetes 對於網絡有三點要求:一是容器之間能夠直接互通,不須要 NAT;二是節點能夠和容器直接互通,不需 NAT;三是容器看到本身的 IP 應該和其餘容器看到的是一致的,即中間不能作IP轉換,避免複雜的分佈式架構應用節點之間的鏈接複雜問題。
Kubernetes 網絡之 Cluster IP
Kubernetes 的 Service 概念大概是,一組服務有多個容器,經過同樣的端口運行,暴露出來的 IP 都是同樣的。經過一個鬆耦合的選擇器把後面的容器或者 Pod 所有概括在這個 Service 之下。
Cluster IP 是一個虛IP,能夠自動分配,也能夠指定。當用戶向這個 IP 的service port (好比例子中是 80) 發送數據的時候,iptables 會攔截這個數據包,而後把數據包隨機分發至其中一個 Pod。這至關因而內部的一種負載均衡器,但它是自動的,即定義Service 的時候,會自動建立一個輕量的負載均衡器。
同時,Kubernetes 內置了 dns 服務,每一個 service 都會有一個和 service name 同樣的 dns 記錄,解析到 service 的 Cluster IP 上。這樣一來,就實現了服務之間依賴的解耦。當請求一個服務的時候,不須要知道服務後面 Pod 的真實 IP 是多少,只須要請求 Cluster IP 或者 DNS。
Kubernetes 之 Flannel
先想象一下,若是咱們要自行實現一個容器的網絡,每一個主機上有一個 Docker 容器,並自行分配一個 DockerBridge 的 IP。這樣一來,若是在多個主機上啓動Docker 就會發現:
第一,它會產生 IP 衝突,怎麼解決這個 IP 衝突呢?首先得有一個機制協調,協調每一個主機分別用什麼 IP。
第二,從某個主機裏的容器發出來的數據包,它須要有一種轉發機制,肯定這個包應該如何轉發到另一個容器所在的主機上。
爲了解決 IP 衝突,它首先須要 IP 分配策略,經過共享的 etcd 存儲。也就是說,Flannel 會給每一個主機分配一個 IP 段,把它捆到 etcd 裏,使得每個主機都知道另外主機的 IP 段是多少。這樣就能確保 IP 不會衝突,使某個容器發出的數據可以準確傳給對應主機的目標容器上,而且是經過 Kubernetes 分配 IP 的規則。
怎麼去轉發數據包呢?一種方法是經過 etcd 隧道,建立一個連接直接轉發數據包;還有一種方法是經過雲服務提供的路由規則,修改路由表便可。
Kubernetes 網絡之 QingCloud
Kubernetes 的網絡是如何發揮青雲QingCloud IaaS 層網絡的優點以及 SDN Passthrough(網絡直通)的特性呢?
首先,一個主機可掛多個網卡,將一個網卡給這個主機,其餘的網卡直接綁到容器裏,使得在 VPC 環境中每一個容器的 IP 和對應主機的 IP 是對等的。這樣一來,主機之間、主機和容器之間、容器之間能夠實現互通,同時省去了 Flannel 解決方案的損耗。
其次,青雲QingCloud 的負載均衡器能感知到容器網絡,而傳統的方案在內部還須要再作一層虛擬網絡,IaaS 層的負載均衡器沒法感知容器網絡。
Kubernetes 存儲
容器的存儲解決方案是影射一個本地硬盤到容器中,本地硬盤的生命週期和容器是脫離的,容器刪了以後數據還在。可是當咱們用調度系統的時候會發現,若是把容器從這個節點遷移到這個節點的時候,若是直接把本地硬盤路徑掛上去以後,數據就沒了,說明它的數據是遷移不過來的。
爲此,Kubernetes 採用了分佈式的存儲,好比 nfs、ceph、glusterfs,PersistentVolume plugin。
此外,Kubernetes 還提供了存儲插件,支持谷歌、AWS,以及青雲QingCloud(QingCloudStore) 。有了這些插件,用戶能夠在主機上掛載一個硬盤,再將硬盤映射到容器。當容器從一個節點遷到另一個節點的時候,這個硬盤也跟着遷過來,使得容器的數據實現遷移。
Kubernetes 存儲之 QingCloudStore
Kubernetes 有一個抽象的配置文件,配置文件標明 QingCloudStore,它能夠關聯一個 volumeID。這種方式的缺點在於配置文件和資源是綁定的、強關聯的,配置文件用一次以後就不能用了,使得測試環境和現場環境不同。因此,爲解決這個問題,須要在 Kubernetes 中聲明須要多大的空間、是否讀寫、什麼權限、提供方是誰,再加上 StorageClass 的配置。
有了這樣的聲明以後有什麼好處呢?使得環境和具體的資源不綁定了,當集羣發現該聲明尚未知足的狀況下,它會自動建立一個盤,關聯到你的 Pod 上。當 Pod 刪除的時候,它會回收資源。這樣,實現瞭解耦。
Kubernetes 負載均衡器
Kubernetes 自己的負載均衡器提供了一種插件,讓雲服務商實現插件和 IaaS 層整合。由於最終用戶暴露的時候須要一個公網 IP,這個實現和各雲廠商的服務是息息相關的,而 Kubernetes 本身比較難直接提供這樣的服務,因此它就提供插件讓雲服務商去實現。
可是雲廠商的負載均衡器只能感知到節點主機這一層,對主機裏面的容器是無感的,因此大多數狀況下只能把 Kubernetes 集羣下全部的節點都掛載到 LoadBalancer以後。前面講到 Service 時說到,Kubernetes 爲每個 Service 都在全部主機上監聽一個隨機的端口,也就是 NodePort,這個請求會轉發到主機的隨機端口上,由隨機端口轉發到 ClusterIP 上,再由 ClusterIP 轉發到後面的容器,能夠看出,這樣就多了幾層轉發。
若是負載均衡器能感知到容器的網絡,就能夠直接透傳請求到容器中。咱們的負載均衡器後面直接掛在的是容器網卡,這樣就省去了幾層轉發。同時咱們的支持公網和私網兩種 Load Balancer。由於通常不可能把全部的服務遷到 Kubernetes,有一部分遷進去了,有一部分服務可能在外面。這種狀況下外部服務訪問不了Kubernetes Service 的 Cluster IP 和 DNS ,這個時候須要私網的 Load Balancer 去轉發這種請求。
Kubernetes 自動伸縮
Kubernetes 提供了自己一種機制,經過相應命令可自動增長 Pod 的節點數。但光有這一層伸縮是不夠的,部署 Kubernetes 集羣的時候,節點數是提早規劃好的。當自動伸縮使 Kubernetes 容量達到上限的時候,就沒法伸縮了。這個時候集羣自己須要有自動伸縮的功能,當前只有谷歌雲實現了集羣的伸縮能力。
當 Kubernetes 集羣的資源不夠了,它會觸發一個事件,IaaS 層監聽這個事件,收到事件請求以後增長集羣的節點。這樣就實現了業務應用層的自動伸縮以及 Kubernetes 資源池的伸縮。
『充電時間』上海、杭州、重慶、成都,讓大家久等了!實踐課堂立刻與你見面,還不報名?本次課程內容仍以技術實踐爲主,以用戶場景爲切入,主要圍繞QingCloud 的技術理念、功能特性和使用技巧展開,話題將涵蓋如何高效構建原生雲應用,雲端容器部署,微服務架構,應用感知,自動化運維等業內熱點話題。
報名請掃描下方二維碼哦