k8s擴展docker單個容器的管理功能,實現誇多主機的問題,容器編排要負責網絡,存儲,安全等問題。前端
容器編排系統,完成如下功能:node
1.爲docker提供私有的Registrymysql
2.提供網絡功能nginx
3.提供共享存儲git
4.確保容器間的安全github
5.TeleMetrysql
容器編排的三個主要工具docker
1.docker的三劍客:docker machine+swarm+compose數據庫
docker machine,快速構建docker容器,加入集羣。後端
swarm:把容器加入到集羣中來
compose:面向swarm,實現容器的編排
2.mesos+marathon:系統資源調度框架,能夠調度hadoop或者容器,不是專門爲容器編排設定的
3.kubernetes:把容器歸類到一塊兒,最小調度單位是容器集(Pod)
本文主要介紹kubernetes的相關內容
k8s,可監控系統的資源使用狀況,進行容器的自動增長或者收縮,這就是所謂的容器編排
kubernetes:舵手,飛行員,參考谷歌內部的大規模內部容器調度系統Borg實現,使用Go語言開發。代碼託管在github上,連接:https://github.com/kubernetes/kubernetes
k8s特性以下:
1.自動裝箱,自動容器的部署,不影響可用性
2.自我修復,如容器崩潰後快速從新啓動新的容器
3.自動實現水平擴展
4.自動實現服務發現和負載均衡
5.自動發佈和回滾
6.支持密鑰和配置管理,把應用程序的配置信息經過服務來加載,而不是加載本地的配置。實現配置的統一
7.實現存儲編排
8.任務的批處理運行
k8s的集羣至少有兩個主機組成:master + node ,即爲master/node架構,master爲集羣的控制面板,master主機須要作冗餘,通常建議爲3臺,而node主機不須要,由於node的主要做用是運行pod,貢獻計算能力和存儲能力,而pod控制器會自動管控pod資源,若是資源少,pod控制器會自動建立pod,即pod控制器會嚴格按照用戶指定的副原本管理pod的數量。客戶端的請求下發給master,即把建立和啓動容器的請求發給master,master中的調度器分析各node現有的資源狀態,把請求調用到對應的node啓動容器。
能夠理解爲k8s把容器抽象爲pod來管理1到多個彼此間有很是緊密聯繫的容器,可是LAMP的容器主機A,M,P只是有關聯,不能說是很是緊密聯繫,所以A,M,P都要運行在三個不一樣的pod上。
在k8s中,要運行幾個pod,是須要定義一個配置文件,在這個配置文件裏定義用哪一個控制器啓動和控制幾個pod,在每一個pod裏要定義那幾臺容器,k8s經過這個配置文件,去建立一個控制器,由此控制器來管控這些pod,若是這些pod的某幾個down掉後,控制器會經過健康監控功能,隨時監控pod,發現pod異常後,根據定義的策略進行操做,便可以進行自愈。
k8s內部須要5套證書,手動建立或者自動生成,分別爲,etcd內部通訊須要一套ca和對應證書,etcd與外部通訊也要有一套ca和對應證書。APIserver間通訊須要一套證書,apiserver與node間通訊須要一套證書,node和pod間通訊須要一套ca
目前而言,還不能實現把全部的業務都遷到k8s上,如存儲,由於這個是有狀態應用,出現錯誤排查很麻煩,目前並且,k8s主要是運行無狀態應用。
因此通常而言,負載均衡器運行在K8s以外,nginx或者tomcat這種無狀態的應用運行於k8s集羣內部,而數據庫,如mysql,zabbix,zoopkeeper,有狀態的,通常運行於k8s外部,經過網絡鏈接,實現k8s集羣的pod調用這些外部的有狀態應用。
k8s集羣架構以下
k8s的master和node的詳細架構以下
k8s的集羣組件以下:
master: apiserver,scheduler,controller-manager,etcd
node:kubelet(agent),kube-proxy,docker(container engine)
Registry:harbor,屬於集羣外部的
Addons(附件):kube-dns,UI(如 dashboard)等等。在集羣運行正常後,在集羣上運行pod實現。
k8s部署集羣總體環境架構
注意,下圖的ip可根據實際環境調整
master 有三個最關鍵的組件,apiserver,scheduler,controller-manager,運行爲三個守護進程:
apiserver:負責接入請求的入口,解析請求,處理請求,即網關,任何到達請求必須通過apiserver
scheduler:請求到達後,由scheduler計算後端node的相關資源,如cpu或者內存使用狀況後,負責調度到合適的node,並啓動pod,即選定某一節點後,有節點的kubelet負責節點上的操做如啓動pod,即scheduler會先作預選,選擇知足條件的node,而後再作優選,最合適的node,啓動pod
controller-manager:控制器管理器,統一管控不一樣類型的資源,監控master上每一個控制器的健康性,能夠在每一個master集羣上作冗餘高可用。其中,控制器用於確保已建立的容器處於健康狀態。
controller:控制器,自動建立pod資源(容器啓動),根據用戶的需求啓動和建立pod,能夠在m個節點上運行n個容器,控制器根據label來識別pod。,使得pod可以按照指定的數量運行。
controller 經過 label selector 來關聯 pod (lable),注意controller只是用來管理pod的健康性,不能進行pod流量導向,即管理pod,確保pod副本數量嚴格符合用戶的定義。
每一組pod都須要獨立的控制器來運行,實現跨節點自愈,管控pod的生命週期。控制器也是經過便籤和便籤選擇器來實現感知本身管控組內的pod
在k8s環境中,推薦使用控制器管理的pod,控制器有以下幾種:
ReplicationController。嚴格控制容器的副本數和滾動更新pod,在更新過程臨時超出副本數。也支持滾動回滾操做。
RelicaSet:聲明更新控制器
Deployment:負責無狀態應用pod控制,支持二級控制器(HPA,HorizontalPodAutoscaler水平pod自動控制器)。
StatefulSet:負責有狀態應用pod控制
DeamonSet:守護進程集,做用是在集羣中每個node上都啓用一個pod副本,若是pod down了,DeamonSet會自動重啓這個pod,若是新增node,會自動添加。即自動下載鏡像,在這個node上啓用這個pod。
Job,Ctonjob:週期性pod控制,如臨時任務的job。
不一樣的控制器,知足客戶不一樣類型的pod資源運行。
master 主機其餘組件:
label selector ;標籤選擇器,根據標籤來選擇符合條件的資源對象的機制,不只僅用於pod資源,全部的對象均可以打上標籤。k/v格式的數據。service和controller都是根據標籤和標籤控制器來識別pod資源。
etcd:分佈式的高性能的鍵值存儲的數據庫系統,保存集羣的對象狀態信息,如apiserver對全部主機的操做結果,如建立pod,刪除pod,調度pod的結果狀態信息都保存在etcd中,若是這個插件異常,則整個集羣運行都將異常,由於etcd異常後,整個集羣的狀態協議都將不能正常工做。所以etcd須要作高可用,防止單點故障。專門的組件,另一個主機上安裝的組件,建議至少三個節點,爲restfull風格的集羣。爲https協議。
master示意圖以下
注意,API,UI,CLI都想API Server發送請求
node節點上主要有三個主鍵,kubelet,kube-proxy,container engine(這裏用docker),介紹以下
kubelet:至關於k8s的節點級的agent,執行當地任務,如當前節點的啓動和當前節點的狀態狀態監測,和apiserver進行交互。
kube-proxy:爲當前節點的pod生成iptables或者ipvs規則,實現了將用戶請求調度到後端pod,爲service組件服務,負責與apiserver隨時保持通訊,一旦發現某一service後的pod發生改變,須要將改變保存在apiserver中,而apiserver內容發生改變後,會生成通知事件,使得全部關聯apiserver的組件都能收到,而 kube-proxy能夠收到這個通知事件,一旦發現某一service背後的pod信息發生改變,kube-proxy就會把改變反應在本地的iptables或者ipvs規則上,實現動態的變化。kube-proxy有三個模型,userspace(名稱空間,和docker的名稱空間有區別,),iptables,ipvs,負責實現service的定義
container engine:做用是負責啓動或者運行有kubelete啓動的容器,如docker
此外,node節點上還有addons(附件),如dns,能夠動態變更dns解析內容,如service的名稱改了,會自動觸發dns的記錄進行更改。
node示意圖以下
除了master和node上的關鍵組件,還有邏輯組件介紹以下
service:
service 經過 label selector 來關聯 pod (lable) ,提供一個固定端點,使得用戶的請求流量導向後端的pod,service爲pod中的應用的客戶端提供一個固定的訪問端點,即clusterIP:ServicePort實現、另外經過DNS Addons實現服務把主機名和clusterIP作解析,使得訪問可以經過主機名和端口來實現
service是在應用前面加一個代理層,這個代理層的主機名對應的ip不變,手動建立,好比nginx要配置後端的tomcat,那麼配置文件上寫入的後端tomcat的ip應該是代理層上(service)的主機名(由於ip也可能變化),防止tomcat重建後ip變化。代理層上經過service的後端pod的label來感知後端pod,因此,不管pod的ip地址怎麼變化,只要label不變,service經過便籤選擇器(label selector)來動態關聯後端的pod。同理,因爲應用可能被刪掉從新建立,所以,在全部的應用前,都須要有service,至關因而提供其餘應用統一訪問的入口。實際上,service,提供穩定的訪問入口和調度功能,根據label來調度,只要pod的label不變,那麼即便pod的ip和端口變化了,都能被service識別,由於service根據label來識別pod對象。能夠跨主機實現的,service至關因而由kube-proxy建立的iptables的dnat規則或者ipvs規則。k8s1.11版本中,已經把規則調整爲ipvs規則。當一個請求到達service後,service會調度到對應的node上。若是service被誤刪了,那麼ip地址可能會變化,爲了防止這種狀況發生,k8s有一個附件,dns服務,完成服務發現,動態按需完成資源的遷移和改變,如每次建立一個service,就會把service對應的名稱和ip關係,放入到這個dns的解析庫中,那麼當service被刪掉時,對應解析記錄就會被刪掉,當service重建後,就會在這個解析庫中新建對應的解析記錄。所以只要前端應用配置的是service的主機名,那麼即便service重建,ip變動也不影響請求的調度。若是沒有了service,那麼先後端應用的銜接就不能固定,服務異常。
當客戶端發起請求,請求都先到servcie,service收到請求後,經過本地的iptables或者ipvs規則調度到後端的pod,若是pod不在同一node上,那麼存在一個跨主機調度問題。使用疊加網絡(overlay)解決不一樣主機上網絡問題,全部的pod都在同一網段,service才能實現正常調度。當宿主機把請求送出去後,報文封裝了兩個ip,容器ip和宿主機網卡的ip,這樣,容器才能實現跨主機間的網絡訪問。即k8s要求全部的pod在同一網段,並且可使用這個網絡直接通訊。注意,service的ip和pod的ip不在同一網段,並且service的ip不是真的ip,即不配在某一個網卡上,僅僅是iptables上的某一個符號。所以service的ip是不能被ping通,service的ip被稱爲cluster ip, pod的ip稱爲 pod ip。
service做爲k8s的對象有service的名稱,service的名稱,至關因而服務的名稱,而名稱能夠被dns解析。service有兩種類型,一種是隻能pod內部訪問,一種是能夠供k8s外部訪問。
每一個應用的pod都要有專用的service進行調度。
存儲卷,pod級別的卷,pod間存在卷的問題,所以,數據建議使用外部的專用卷,而不要使用掛載的本地容器的卷。當容器重建時,須要加載相同的卷。存儲卷有四級概念,pv(持久卷),pvc(持久卷申請),volume(存儲卷),volume mount(存儲卷掛載)。
pod:
Pod指容器集,原子調度單元,一個Pod的全部容器運行於同一節點。k8s調度的目標是pod,,pod能夠理解爲容器的外殼,pod是k8s最小的調度單元。一個pod能夠包含多個容器。一組聯繫很是緊密的容器組成pod,同一組pod共享networks,uts,storage,volumes,經過ipc機制進行通信,跨pod的容器,須要藉助於外部網絡插件進行通信,每個pod有一個podIP。一個pod至關因而傳統意義上的虛擬機。存儲卷屬於pod。通常而言,一個pod僅放一個容器。一個pod內的全部容器只能運行於同一node上。
k8s的最核心功能就是爲了運行pod,其餘組件是爲了pod可以正常運行而執行的。
pod能夠分爲兩類:
1.自主式pod,
2.控制器管理的pod
一個pod上有兩類元數據,label 和 annotation
label:標籤,對數據類型和程度要求嚴格,
annotation:註解,用於存儲本身定義的複雜元數據,用來描述pod的屬性
外部請求訪問內部的pod,有三級轉發,第一級,先到nodeip(宿主機ip)對應的端口,而後被轉爲cluster ip的service 端口,而後轉換爲PodIP的containerPort。
注意,在k8s集羣外部還有一個調度器(load blance),這個調度器跟k8s沒有關係,須要手動管理。這個調度器可藉助keepalive實現高可用。
k8s的運行空間須要分區,即分紅邏輯區域,如用於區分不一樣項目,每一個邏輯區域爲一個名詞空間(usersapce),這裏的名稱空間爲k8s特有的名稱空間,和docker的名稱空間有區別。用於隔離pod。實現了網絡邊界的隔離。提供了管理的邊界。網絡策略能夠實現不一樣名稱空間是否能夠實現網絡訪問。默認狀況下,不須要建立namespace。
service地址和pod地址在不一樣網段,service地址爲虛擬地址,不配在pod上或主機上,外部訪問時,先到節點網絡,再打service網絡,最後代理給pod網絡。
同一pod內的多個容器經過lo通訊
各pod間的通訊,pod經過overlay network的隧道轉發實現跨主機間報文轉發,實現直接通訊。
其中,疊加網絡
1.一個數據包(或幀)封裝在另外一個數據包內;被封裝的包轉發到隧道端點後再被拆裝。
2.疊加網絡就是使用這種所謂「包內之包」的技術安全地將一個網絡隱藏在另外一個 網絡中,而後將網絡區段進行遷移。
pod和service間的通訊,
CNI:容器網絡集接口,網絡解決方案,有三種不一樣ip,ip地址解釋以下
node ip,節點網絡,宿主機物理ip
cluster ip,集羣ip,爲service 網絡,爲固定的接入端口,即service組件的ip地址,不會配置在任何網絡接口上,clusterIP定義在iptables或ipvs規則中。k8s集羣本身管控和提供
pod ip ,屬於pod網絡,爲pod提供ip地址,使得pod間直接通訊,可是,集羣間pod通訊要藉助於 cluster ip,pod和集羣外通訊,還要藉助於node ip。pod網絡要經過CNI規範藉助於外部的虛擬化網絡模型實現,爲pod配置ip地址,使得pod間可以通訊。
其中,虛擬化網絡解決方案有以下幾種較爲著名的插件:
flannel:簡單易用,不支持網絡策略,配置本地網絡協議棧,從而爲運行在這個主機上的pod提供ip,可是,不能提供網絡策略的功能。
project calico:支持網絡策略和網絡配置,默認基於BGP構建網絡,實現直接通信,三層隧道網絡,目前生產主要使用這個模型
Canel:是flannel+calico的結合,用flannel提供網絡,calico實現策略配置
kube-rote
weave network
k8s的網絡模型以下