1. 程式人生 > >Docker系列(九):kubernetes架構深度解析

Docker系列(九):kubernetes架構深度解析

Kubernetes重要概念

Docker解決了打包和隔離的問題,但我們需要更多:排程的問題,生命週期及健康狀況,服務發現,監控,認證,容器聚合。

Kubernetes概述

開源DOcker容器編排系統
輕量級,簡單
公有云,私有云以及混合雲中部署
模組化,可插拔化,可掛接,可組合
自動恢復,自動重啟,自動複製
在這裡插入圖片描述
master管理節點,所有的使用者都是跟master進行互動的
kubernetes從多個動作節點上(node)排程應用。

Namingspace

在這裡插入圖片描述
多租戶,每個租戶的物件是相互隔離的,只能看到自己的名稱空間內定義的資源

Names

命名的物件(pods、service、rc等的命名),是一個全域性唯一的值

Annotations

key value值,不作為可選擇的,可過濾的引數,有時候想定義一些key value值去pods一個簡單的記錄,簡單的用途。

Resource

在這裡插入圖片描述

Lable

在這裡插入圖片描述
在這裡插入圖片描述

簡介

用以標識物件(如Pod)的key/value 對
組織並選擇物件子集
lables使使用者可以使用鬆耦合的方式來對映子集應用的組織結構,而不需要儲存這些對映表, 與命名和uid不同的是,lable不需要提供唯一性,反而我們希望多個物件使用相同的lable,通過lable選擇器,使用者可以指定一些物件子集,來進行分組合並。

示例

vi lables.yaml

在這裡插入圖片描述

kunectl create -f lables.yaml //建立
kubectl get pods //檢視所有的pods
kubectl get pods  -l app=nginx //給檢視的pods加上lable,相當於加了過濾器

Master節點

在這裡插入圖片描述

Node

在這裡插入圖片描述
在這裡插入圖片描述

Pod

在這裡插入圖片描述
在這裡插入圖片描述

簡介

建立、排程以及管理的最小單元
共存的一組容器的集合
容器共享pid,網路,IPC以及UTS名稱空間(共享pid:同一個pods內的容器可以看到彼此的程序,共享網路:同一個pods內的容器可以共用相同的ip地址和埠,也可以通過localhost來訪問,共享IPC:同一個pods內的容器可以通過systemvipc和訊息佇列的方式進行通訊,共享UTS名稱空間:同一個pods內的容器使用了相同的主機名。)
容器共享儲存卷
短暫存在

生命週期

Pending:pods已經被系統接受但是一個或多個容器映象還沒有建立。包括容器被排程之前的時間以及下載映象的時間。
Runnning:pods已經被部署到一個節點上了,並且所有的容器都已經被建立了。
Successded:pods中的容器都已經被成功的停止了,並且不會被重啟
Failed:pods中所有的容器都被停止了,並且有至少一個容器停止的時候出現了錯誤。

示例

vi pod.ymal   k8s中通過ymal檔案定義物件的

在這裡插入圖片描述

kubectl create  -f pod.ymal    
建立上面的pod
kubectl get pods
檢視所有的pods,發現上面的nginx已經運行了

在這裡插入圖片描述

kubectl delete pods nginx    //刪除pods 
kubectl get pods

Service

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

簡介

每個pods都有自己的IP地址,並且這些地址並不是固定的,如果一些pods是為另一些pods提供服務的,該如何被發現呢?
抽象一系列pod並定義其訪問規則,
固定ip地址和dns域名
通過環境變數和dns發現服務
負載均衡
外部服務:
ClusterIp(當前叢集內訪問)
NodePort (是使用了clusterIp同時還會在叢集的每一個節點上暴露一個服務的埠,可以通過叢集上的某一個工作節點 和IP地址和埠來訪問這個服務)
Loadbalancer(如果雲服務提供商支援web服務的話)

示例

vi service.yaml

在這裡插入圖片描述

kubectl create -f service.ymal //建立service
kubectl get services

看下圖會分配一個虛擬ip
在這裡插入圖片描述
切換到一個工作節點:curl http://10.247.252.165:8000,發現是成功的
通過serviece的方式我們並不需要知道pods的id,service的ip是一個固定的ip,可以通過kubenetes提供的dns的服務去進行查詢 ,service通過負載均衡到每一個pods上,使用者只需要知道kubenetes提供的唯一的ip就可以了。

Replication Controller

在這裡插入圖片描述
在這裡插入圖片描述

簡介:

在任何時刻執行指定數目的pod ,當pods所在的問題出現問題的時候,會被排程到其他正常的節點上執行。
容器重新排程。
規模調整( 只需要修改指定的數目,rc便會刪除多餘的容器,或者啟動新的容器,以達到指定的數目)
線上升級(可以增加一個新版本的pod,刪除一箇舊版本的pod,最後在pod的數目為零的時候,可以刪除rc,需要注意新版本和舊版本的rc需要至少有一處不同的lable以標記不同版本的pods
多釋出版本跟蹤

示例

vi rc.yaml

在這裡插入圖片描述
template是對pods的定義

kubectl crate -f rc.yaml
kubectl get rc //檢視rc
kubectl get pods -l app=nginx //檢視lable過濾的pods,會發現有兩個,因為上圖中的replicas設定的2
kubectl delete pods nginx //刪除一個
kubectl get pods -l app=nginx//會發現還是有兩個

Volumes

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
容器中的檔案是短暫存在的,當容器crash的時候資料將會被丟失

簡介

資料持久化
pod中容器共享資料
生命週期,和pod的生命週期相同,當pod停止退出的時候volume也會停止退出
支援多種型別的資料卷
emptyDIr(本地主機生成,pod被排程到一個節點上的時候生成,只要pods執行在當前節點上,並一直存在,其初始是一個空資料夾, pods內的容器可以讀寫此資料夾中的檔案。當此pod被從此節點上刪除的時候,資料卷也會相應的被刪除,此處注意容器crash的時候資料卷是不會被刪除的)
hostpath(本地主機生成,將當前宿主機上的一個路徑 對映到pods內)gcepersistentDidsk(雲端雲端儲存的支援)
awsElasticBlockStore(雲端雲端儲存的支援)
nfs(網路磁碟)
iscsi(網路磁碟)
glusterfs(網路磁碟)
secrets(儲存比較敏感的資料,不希望別人看到,比如使用者的密碼。)

示例

vi pod.ymal  //修改ymal檔案

在這裡插入圖片描述

kubectl get pods redis -o yaml //-o yaml 輸出是yaml,更詳細的檢視pods 資訊。

Kuberetes架構及原理

典型的分散式架構
在這裡插入圖片描述

簡介

APIserver負責與外界進行通訊
kubctl通過rest命令kubenetes中物件的操作傳送到APIserver
排程器Scheduler
控制器Controller Manager
所有的物件持久化儲存到分散式的key value中etcd
docker容器試執行在工作節點上的(node)
node上有kubelet定期和APIserver進行通訊,proxy為容器提供網路的代理
在這裡插入圖片描述

etcd

儲存了kubenetes中所有可用的映象
高可用的key value儲存
只有APIserver有許可權讀寫
使用etc叢集確保資料可靠性

APIserver

作為kubenetes系統的入口,對外童工了基於restful的管理介面,支援對kubenetes物件(pod、service等)進行增減改 查以及監控的操作 ,維護的物件將會被持久化道etcd中
APIs的訪問需要通過認證,目前支援認證的方式包括客戶證書認證,basic認證、tocken認證
在認證的基礎上有授權的模組,可以對http的請求設定alwaysdenied(永遠拒絕,測試環境) 、alwaload(永遠接受)、abac(設定不同使用者的訪問許可權)三種模式
訪問控制:任何請求在訪問APIserver的時候,都要經過一系列的驗證,任何一個環節拒絕了請求, 都會返回錯誤,包括全不允許、全部拒絕、資源限制確保了資源不會違反本名稱空間的資源限制以及資源分配的規則,安全限制 確保了請求不違反本名稱空間中對安全的策略
服務賬號:當pods裡面的程序需要訪問APIserver或其他需要認證的服務的時候使用服務賬號作為pods id
資源限制

kube-scheculer

負責叢集的資源排程, 為新建的pod提供機器
資源需求
服務需求
硬體、軟體、策略限制
關聯性和非關聯性
資料本地化

kube-controller-manager

負責執行各種控制器,分為四類
Replication controller:定期關聯replication controller和pod,確保replication controller定義的數量與實際執行的pod的數量總和是一致的
Endpoint controller:定期掛鏈service和pods,關聯資訊是由endpoint物件維護的保證service到pod的對映總是最新的
Namespace controller :名稱空間
ServiceCount controller:服務賬號

kubelet

管控docker容器,啟動停止,監控執行狀態等,它會定期的通過APIserver從etcd獲取分配到本機的pod,並根據pod資訊,啟動或停止相應的容器,同時會接受APIserver的http請求,回報pods的執行狀態。
節點管理器
確保排程到本節點的pod的執行和健康

kube-porxy

pod網路代理,定期從APIserver通過etcd獲取所有的service,並根據service的資訊提供代理,當某個客戶pod需要訪問其他pod的時候,請求會經過本機的proxy做轉發,
TCP\UDP轉發
負載均衡(Round Robin外掛的形式)

服務發現

一開始通過環境變數來服務發現,但是會環境變數氾濫的問題
後來是DNS kube2sky (從apiserver上獲取當前所有的service的名稱以及IP地址,並將資料持久化到etcd中)etcd skydns(定期訪問etcd上的內容,修改自己dns伺服器上的資訊,注意這裡的etcd和我們master上的etcd是不同的,)

Kuberetes架構及原理——執行機制

在這裡插入圖片描述

Kuberetes架構及原理——網路機制

首先看一下docker的網路:
預設情況下,docker會建立一個虛擬的網橋,所有的docker容器連線到這個網橋上,通過dhcp分配一個在同一個自網內的ip,這種情況下docker容器只能與 部署在同一臺主機上的docker容器進行通訊,無法做到跨主機的docker容器通訊,而且從外部訪問容器則需要,在主機上對映一個埠,多個容器對映同一個埠會導致主機埠衝突, 應設隨機的埠又對管理帶來很大的隱患
kubenetes的通訊主要包括以下幾個方面:
耦合度非常高的容器間的通訊,通過pods的概念,將耦合度非常高的容器放在了同一個名稱空間當中,可以通過localhost訪問,pod間的通訊是不需要net的,pod到service的通訊通過kubeproxy實現的,kubeproxy通過APIserver得知指定的service下的幾個pod其ip分別是多少。
支援:
容器間的通訊
節點和容器間的相互通訊
每個pod使用全域性唯一的ip
openseich的方式:
在這裡插入圖片描述
docker網橋被一個linux網橋所代替,pod連線到子網橋上,同時建立一個ovs的網橋,並以一個埠的形式新增到docker使用的網橋上, 所有節點上的ovs之間,通過jretone進行連線,所以每個pods都會有自己唯一的ip,通過ip可以訪問到其他節點上pods,在每一個工作節點上添加了路由的規則導向其他節點的子網,
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

高可用

保證每一個master加點的正常進行
系統監控程式確保kubenetes正常執行
etcd叢集保證資料高可用和資料的備份
多個APIserver進行負載均衡
master選舉確保kube-scheduler和kube-controlle-maanager高可用
在這裡插入圖片描述
多個master節點,裡面的APIserver通過load balance實現高可用,每個節點上的etcd組成etcd叢集,通過選舉確保scheduler和controller manager,通過kubelet監控,kubelet通過monit(系統程式)來監控,來達到高可用