容器幾個知識點
容器做用
• 能夠把應用程序代碼及運行依賴環境打包成鏡像,做爲交付介質,在各環境部署
• 能夠將鏡像(image)啓動成爲容器(container),而且提供多容器的生命週期進行管理(啓、停、刪)
• container容器之間相互隔離,且每一個容器能夠設置資源限額
• 提供輕量級虛擬化功能,容器就是在宿主機中的一個個的虛擬的空間,彼此相互隔離,徹底獨立
• 三大核心要素 鏡像(Image)、容器(Container)、倉庫(Registry)
• 容器1號進程覺定容器存活
Docker指令:
• COPY|ADD 添加本地文件到鏡像中,不一樣的是,若是是壓縮包,ADD會解壓,是連接,ADD會下載
cp 能夠從宿主機拷貝文件到容器,也能夠從容器拷貝鏡像到宿主機
• CMD 構建容器後調用,也就是在容器啓動時才進行調用,CMD不一樣於RUN,CMD用於指定在容器啓動時所
要執行的命令,而RUN用於指定鏡像構建時所要執行的命令。啓同容器後執行的命令會覆蓋CMD命令
• ENTRYPOINT 設置容器初始化命令,使其可執行化 ENTRYPOINT與CMD很是相似,不一樣的是經過docker run執行的命令不會覆蓋ENTRYPOINT,而docker run命令中指定的任何參數,都會被當作參數再次傳遞給ENTRYPOINT。Dockerfile中只容許有一個ENTRYPOINT命令,多指定時會覆蓋前面的設置,而只執行最後的ENTRYPOINT指令
• ENV 設置環境變量node
- UnionFS 聯合文件系統
• Linux namespace和cgroup分別解決了容器的資源隔離與資源限制
• 在最新的 Docker 中,overlay2 取代了 aufs 成爲了推薦的存儲驅動
• 鏡像就是由這些層一層一層堆疊起來的,鏡像中的這些層都是隻讀的,當咱們運行容器的時候,就能夠在這些基
礎層至上添加新的可寫層,也就是咱們一般說的容器層
,對於運行中的容器所作的全部更改(好比寫入新文件、
修改現有文件、刪除文件)都將寫入這個容器層。
• 對容器層的操做,主要利用了寫時複製(CoW)技術。CoW就是copy-on-write,表示只在須要寫時纔去複製,
這個是針對已有文件的修改場景。 CoW技術可讓全部的容器共享image的文件系統,全部數據都從image中讀
取,只有當要對文件進行寫操做時,才從image裏把要寫的文件複製到本身的文件系統進行修改。因此不管有多
少個容器共享同一個image,所作的寫操做都是對從image中複製到本身的文件系統中的複本上進行,並不會修
改image的源文件,且多個容器操做同一個文件,會在每一個容器的文件系統裏生成一個複本,每一個容器修改的都
是本身的複本,相互隔離,相互不影響。使用CoW能夠有效的提升磁盤的利用率。
- Docker網絡
• Host模式,容器內部不會建立網絡空間,共享宿主機的網絡空間。容器啓動後,會默認監聽3306端口,因爲網絡模式是host,由於能夠直接經過宿主機的3306端口進行訪問服務,效果等同於在宿主機中直接啓動mysqld的進程。
• Conatiner模式 這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新建立的容器不會建立本身的網卡,配置本身的 IP,而是和一個指定的容器共享 IP、端口範圍等。一樣,兩個容器除了網絡方面,其餘的如文件系統、進程列表等仍是隔離的。兩個容器的進程能夠經過 lo 網卡設備通訊。
• none模式,使用--net=none指定 網絡模式爲空,即僅保留網絡命名空間,可是不作任何網絡相關的配置(網卡、IP、路由等)
• bridge模式 使用--net=bridge指定,默認設置 bridge本意是橋的意思,其實就是網橋模式。咱們能夠把網橋當作一個二層的交換機設備,Docker 建立一個容器的時候,建立一對虛擬接口/網卡,也就是veth pair;本地主機一端橋接 到默認的 docker0 或指定網橋上,並具備一個惟一的名字,如 veth9953b75;容器一端放到新啓動的容器內部,並修更名字做爲 eth0,這個網卡/接口只在容器的命名空間可見;從網橋可用地址段中(也就是與該bridge對應的network)獲取一個空閒地址分配給容器的 eth0
k8s核心組件
ETCD:分佈式高性能鍵值數據庫,存儲整個集羣的全部元數據
ApiServer: API服務器,集羣資源訪問控制入口,提供restAPI及安全訪問控制
Scheduler:調度器,負責把業務容器調度到最合適的Node節點
Controller Manager:控制器管理,確保集羣資源按照指望的方式運行
kubelet:運行在每一個節點上的主要的「節點代理」,髒活累活
• pod生命週期管理,建立銷燬容器
• 容器監控,監控所在節點的資源使用狀況,並定時向 master報告,資源使用數據都是經過 cAdvisor 獲取的
kube-proxy:維護節點中的iptables或者ipvs規則
K8S工做流程
一、用戶準備一個資源文件(記錄了業務應用的名稱、鏡像地址等信息),經過調用APIServer執行建立
Pod
二、APIServer收到用戶的Pod建立請求,將Pod信息寫入到etcd中
三、調度器經過list-watch的方式,發現有新的pod數據,可是這個pod尚未綁定到某一個節點中
四、調度器經過調度算法,計算出最適合該pod運行的節點,並調用APIServer,把信息更新到etcd中
五、kubelet一樣經過list-watch方式,發現有新的pod調度到本機的節點了,所以調用容器運行時,去
根據pod的描述信息,拉取鏡像,啓動容器,同時生成事件信息
六、同時,把容器的信息、事件及狀態也經過APIServer寫入到etcd中
架構設計的幾點思考
一、系統各個組件分工明確(APIServer是全部請求入口,CM是控制中樞,Scheduler主管調度,而
Kubelet負責運行),配合流暢,整個運行機制一鼓作氣。
二、除了配置管理和持久化組件ETCD,其餘組件並不保存數據。意味除ETCD外其餘組件都是無狀態
的。所以從架構設計上對kubernetes系統高可用部署提供了支撐。
三、同時由於組件無狀態,組件的升級,重啓,故障等並不影響集羣最終狀態,只要組件恢復後就能夠
從中斷處繼續運行。
四、各個組件和kube-apiserver之間的數據推送都是經過list-watch機制來實現。
POD
一、pod是什麼
pod是集羣能夠調度的最小單元
一個pod能夠包含一個或多個容器
二、健康檢查
• 存活性探測
• 就緒性探測
三種類型:
exec:經過執行命令來檢查服務是否正常,返回值爲0則表示容器健康
httpGet方式:經過發送http請求檢查服務是否正常,返回200-399狀態碼則代表容器健康
tcpSocket:經過容器的IP和Port執行TCP檢查,若是可以創建TCP鏈接,則代表容器健康
三、資源限制
• requests: 容器使用的最小資源需求,做用於schedule階段,做爲容器調度時資源分配的判斷依賴
只有當前節點上可分配的資源量 >= request 時才容許將容器調度到該節點,request參數不限制容
器的最大可以使用資源
• limits:容器能使用資源的最大值,設置爲0表示對使用的資源不作限制, 可無限的使用,當pod 內存超過limit時,會被oom,當cpu超過limit時,不會被kill,可是會限制不超過limit值
四、調度策略
• cordon 標記節點爲不調度
• nodeName 調度到某一臺定義的節點名字服務器
• nodeSelector 調度到打了標籤的節點服務器
• Taints and Tolerations 污點與容忍,只有可以容忍污點的容器才能被調用
• drain 維護模式,不容許調度並排關全部容器關閉kubelet
五、安全上下文
如:設置容器內進程root用戶啓動
七、pod數據持久化
• hostpath
• nfs
• ceph
• emptyDir
八、pod驅逐策略
Kube-controller-manager:週期性檢查全部節點狀態,當節點處於 NotReady 狀態超過一段時間後,驅逐該節點上全部 pod。停掉kubelet
pod-eviction-timeout:NotReady 狀態節點超過該時間後,執行驅逐,默認 5 min
Kubelet: 週期性檢查本節點資源,當資源不足時,按照優先級驅逐部分 pod
• 節點可用內存
• 根盤可用存儲空間
• 可用數量
• 鏡像存儲盤的可用空間
• 鏡像存儲盤的inodes可用數量
九、Pod控制器
Workload (工做負載),控制器又稱工做負載是用於實現管理pod的中間層,確保pod資源符合預期的狀態,pod的資源出現故障時,會嘗試 進行重啓,當根據重啓策略無效,則會從新新建pod的資源。
• ReplicaSet: 代用戶建立指定數量的pod副本數量,確保pod副本數量符合預期狀態,而且支持滾動式自動擴容和縮容功能
• Deployment:工做在ReplicaSet之上,用於管理無狀態應用,目前來講最好的控制器。支持滾動更新和回滾功能,提供聲明式配置
• DaemonSet:用於確保集羣中的每個節點只運行特定的pod副本,一般用於實現系統級後臺任務。好比EFK服務
• Job:只要完成就當即退出,不須要重啓或重建
• Cronjob:週期性任務控制,不須要持續後臺運行
• StatefulSet:管理有狀態應用
service
一、Kubernetes服務訪問之Service
service是一組pod的服務抽象,至關於一組pod的LB,負責將請求分發給對應的pod。service會爲這個LB提供一個IP,通常稱爲cluster IP 。使用Service對象,經過selector進行標籤選擇,找到對應的Pod:
二、Service負載均衡之NodePort
cluster-ip爲虛擬地址,只能在k8s集羣內部進行訪問,集羣外部若是訪問內部服務,實現方式之一爲使用NodePort方式。NodePort會默認在 30000-32767 ,不指定的會隨機使用其中一個。
三、服務發現
在k8s集羣中,組件之間能夠經過定義的Service名稱實現通訊。
四、Service與Pod如何關聯:
service對象建立的同時,會建立同名的endpoints對象,若服務設置了readinessProbe, 當readinessProbe檢測失敗時,endpoints列表中會剔除掉對應的pod_ip,這樣流量就不會分發到健康檢測失敗的Pod中
kube-proxy幾種模式
運行在每一個節點上,監聽 API Server 中服務對象的變化,再經過建立流量路由規則來實現網絡的轉發
一、User space
讓 Kube-Proxy 在用戶空間監聽一個端口,全部的 Service 都轉發到這個端口,而後 Kube-Proxy 在內部應用層對其進行轉發 , 全部報文都走一遍用戶態,性能不高,k8s v1.2版本後廢棄。
二、Iptables
當前默認模式,徹底由 IPtables 來實現, 經過各個node節點上的iptables規則來實現service的負載均衡,可是隨着service數量的增大,iptables模式因爲線性查找匹配、全量更新等特色,其性能會顯著降低。
三、IPVS
與iptables一樣基於Netfilter,可是採用的hash表,所以當service數量達到必定規模時,hash查表的速度優點就會顯現出來,從而提升service的服務性能。 k8s 1.8版本開始引入,1.11版本開始穩定,須要開啓宿主機的ipvs模塊。
Kubernetes服務訪問之Ingress
對於Kubernetes的Service,不管是Cluster-Ip和NodePort均是四層的負載,集羣內的服務如何實現七層的負載均衡,這就須要藉助於Ingress,Ingress控制器的實現方式有不少,好比nginx, Contour, Haproxy, trafik, Istio
Ingress-nginx是7層的負載均衡器 ,負責統一管理外部對k8s cluster中Service的請求。主要包含:
• ingress-nginx-controller:根據用戶編寫的ingress規則(建立的ingress的yaml文件),動態的去更改nginx服務的配置文件,而且reload重載使其生效(是自動化的,經過lua腳原本實現);
• Ingress資源對象:將Nginx的配置抽象成一個Ingress對象
實現邏輯
1)ingress controller經過和kubernetes api交互,動態的去感知集羣中ingress規則變化2)而後讀取ingress規則(規則就是寫明瞭哪一個域名對應哪一個service),按照自定義的規則,生成一段nginx配置3)再寫到nginx-ingress-controller的pod裏,這個Ingress controller的pod裏運行着一個Nginx服務,控制器把生成的nginx配置寫入/etc/nginx/nginx.conf文件中4)而後reload一下使配置生效。以此達到域名分別配置和動態更新的問題。
configMap
一般用來管理應用的配置文件或者環境變量
Kubernetes認證與受權
APIServer安全控制
Authentication:身份認證
- 這個環節它面對的輸入是整個http request,負責對來自client的請求進行身份校驗,支持的方法包括:
• basic auth
• client證書驗證(https雙向驗證)
• jwt token(用於serviceaccount)
secret
• rbac:基於角色認證,建立一個sa帳戶或user,配置基於角色的權限[get,list,watch,...],把帳戶與角色權限綁定,便可操做k8s的資源
• 經過證書與apiserver進行通訊
• secret:管理敏感類的信息,默認會base64編碼存儲,有三種類型
一、generic:通用型secret,指定一個文件,文件內容指定用戶名,密碼
二、docker registry: 用來存儲私有docker registry的認證信息。
三、tls:把證書加載進secret
四、Service Account :用來訪問Kubernetes API,由Kubernetes自動建立,而且會自動掛載到Pod
的/run/secrets/kubernetes.io/serviceaccount目錄中;建立ServiceAccount後,Pod中指定
serviceAccount後,自動建立該ServiceAccount對應的secret;
五、Opaque : base64編碼格式的Secret,用來存儲密碼、密鑰等;
Kubernetes調度
Kubernetes Scheduler 的做用是將待調度的 Pod 按照必定的調度算法和策略綁定到集羣中一個合適的 Worker Node 上,並將綁定信息寫入到 etcd 中,以後目標 Node 中 kubelet 服務經過 API Server 監聽到 Scheduler 產生的 Pod 綁定事件獲取 Pod 信息,而後下載鏡像啓動容器。
調度的過程
Scheduler 提供的調度流程分爲預選 (Predicates) 和優選 (Priorities) 兩個步驟:
• 預選,K8S會遍歷當前集羣中的全部 Node,篩選出其中符合要求的 Node 做爲候選
• 優選,K8S將對候選的 Node 進行打分
通過預選篩選和優選打分以後,K8S選擇分數最高的 Node 來運行 Pod,若是最終有多個 Node 的分數最高,那麼 Scheduler 將從當中隨機選擇一個 Node 來運行 Pod。
Kubernetes集羣的網絡實現
一、CNI介紹及集羣網絡選型
容器網絡接口(Container Network Interface),實現kubernetes集羣的Pod網絡通訊及管理。包括:
• CNI Plugin負責給容器配置網絡,它包括兩個基本的接口:配置網絡: AddNetwork(net NetworkConfig, rt RuntimeConf) (types.Result, error)清理網絡: DelNetwork(net NetworkConfig, rt RuntimeConf) error
• IPAM Plugin負責給容器分配IP地址,主要實現包括host-local和dhcp。
以上兩種插件的支持,使得k8s的網絡能夠支持各式各樣的管理模式,當前在業界也出現了大量的支持方案,其中比較流行的好比flannel、calico等。
kubernetes配置了cni網絡插件後,其容器網絡建立流程爲:
• kubelet先建立pause容器生成對應的network namespace
• 調用網絡driver,由於配置的是CNI,因此會調用CNI相關代碼,識別CNI的配置目錄爲/etc/cni/net.d
• CNI driver根據配置調用具體的CNI插件,二進制調用,可執行文件目錄爲/opt/cni/bin,項目
• CNI插件給pause容器配置正確的網絡,pod中其餘的容器都是用pause的網絡
能夠在此查看社區中的CNI實現,https://github.com/containernetworking/cni
通用類型:flannel、calico等,部署使用簡單
二、Flannel三種模型
一、host-gw模型
host-gw模型即網關模式,在服務器直接添加一條靜態路由便可,效率高,各節點必須在同一網段
10.4.7.21經過172.7.22.0這條靜態路由鏈接10.4.7.22這臺主機再鏈接172.7.21網段,反之亦是
二、VxLAN模型
在不一樣網段,能夠用VxLAN模式,主機A會生成一個flannel.1網卡,經過封裝頭從flannel.1網卡出去經過flanne隧道傳出,從flannel.1網卡傳入拆包,到達目標主機網卡到指向的靜態路由,效率低
三、Directrouting模型
• 直接路由模式,結合了VxLAN和host-gw模型
• 自動識別服務器,若是同網段,則使用host-gw模型,若是不一樣網段則使用VxLAN模型
經過HPA實現業務應用的動態擴縮容
基於CPU的動態伸縮
基於內存的動態伸縮
基於自定義指標的動態伸縮
kubernetes對接分部式存儲
PersistentVolume(持久化卷),是對底層的存儲的一種抽象,它和具體的底層的共享存儲技術的實現方式有關,好比 Ceph、GlusterFS、NFS 等
由於PV是直接對接底層存儲的,就像集羣中的Node能夠爲Pod提供計算資源(CPU和內存)同樣,PV能夠爲Pod提供存儲資源。所以PV不是namespaced的資源,屬於集羣層面可用的資源。Pod若是想使用該PV,須要經過建立PVC掛載到Pod中。
PVC全寫是PersistentVolumeClaim(持久化卷聲明),PVC 是用戶存儲的一種聲明,建立完成後,能夠和PV實現一對一綁定。對於真正使用存儲的用戶不須要關心底層的存儲實現細節,只須要直接使用 PVC 便可。
storageClass實現動態掛載
建立pv及pvc過程是手動,且pv與pvc一一對應,手動建立很繁瑣。所以,經過storageClass + provisioner的方式來實現經過PVC自動建立並綁定PV。
動態pvc驗證及實現分析
使用流程: 建立pvc,指定storageclass和存儲大小,便可實現動態存儲。
EFK
Elasticsearch
Elasticsearch一個開源的分佈式、Restful 風格的搜索和數據分析引擎,它的底層是開源庫Apache Lucene。它能夠被下面這樣準確地形容:
• 一個分佈式的實時文檔存儲,每一個字段能夠被索引與搜索;
• 一個分佈式實時分析搜索引擎;
• 能勝任上百個服務節點的擴展,並支持 PB 級別的結構化或者非結構化數據。
Kibana
Kibana是一個開源的分析和可視化平臺,設計用於和Elasticsearch一塊兒工做。能夠經過Kibana來搜索,查看,並和存儲在Elasticsearch索引中的數據進行交互。也能夠輕鬆地執行高級數據分析,而且以各類圖標、表格和地圖的形式可視化數據。
Fluentd
Fluentd一個針對日誌的收集、處理、轉發系統。經過豐富的插件系統,能夠收集來自於各類系統或應用的日誌,轉化爲用戶指定的格式後,轉發到用戶所指定的日誌存儲系統之中。
Fluentd 經過一組給定的數據源抓取日誌數據,處理後(轉換成結構化的數據格式)將它們轉發給其餘服務,好比 Elasticsearch、對象存儲、kafka等等。Fluentd 支持超過300個日誌存儲和分析服務,因此在這方面是很是靈活的。主要運行步驟以下
- 首先 Fluentd 從多個日誌源獲取數據
- 結構化而且標記這些數據
- 而後根據匹配的標籤將數據發送到多個目標服務爲何推薦使用fluentd做爲k8s體系的日誌收集工具?將日誌文件JSON化可插拔架構設計極小的資源佔用極強的可靠性• 基於內存和本地文件的緩存• 強大的故障轉移Prometheus監控監控接口:xx.xx.xx.xx:xx/metrics監控類型 :靜態監控、動態監控(自動發現)自動發現資源類型:node、ingress、service、pod、endpoint監控對像:• 基礎監控:node_exporter CPU、內存、磁盤、IO• 集羣狀態:kube-state-metrics k8s集羣中各類控制器資源狀態• 容器存活:blackbox-exporter 檢查容器存活(http、tcp)是否可用• 容器資源利用:cadvisor 容器消耗了服務器多少資源• 核心組件:etcd、kube-apiserver、kubelet、corednsDevOpsdevops = 提倡開發、測試、運維協同工做來實現持續開發、持續交付的一種軟件交付模式 + 基於工具和技術支撐的自動化流程的落地實踐。所以devops不是某一個具體的技術,而是一種思想+自動化能力,來使得構建、測試、發佈軟件可以更加地便捷、頻繁和可靠的落地實踐。