《k8s權威指南》讀書筆記-核心原理篇

看完本章能掌握的知識

  • k8s基本架構圖
  • k8s重要組件的功能和原理
  • k8s各個組件之間如何交互
  • k8s網絡模型
  • k8s網絡解決了docker網絡的哪些侷限性

一. 架構圖回顧

  • apiServer:資源統一入口和管理
  • etcd:資源存儲
  • controller-manager:狀態控制
  • scheduler:調度
  • kubelet:容器生命週期管理

二. 核心組件原理

1. APIServer

1.1 功能和做用

  • 整個系統的數據總線和數據中心,負責各模塊通信
  • 提供各種資源對象(pod,service等)的增、刪、改、查等Restful接口
  • 集羣內各個功能模塊之間數據交互和通訊的中心樞紐
  • 集羣的API入口
  • 資源配額入口
  • 提供安全機制

1.2 存在形式

  • 運行在master節點上的一個叫 kube-apiserver 的進程提供服務
  • 暴露的端口:http-8080,https-6443

1.3 如何交互

  • 經過kubectl命令行工具
  • 經過curl命令訪問
  • 經過編程調用

apiserver在k8s中也是一個Service對象,名字叫作kubernetes, 經過kubectl get svc命令能夠查看node

1.4 工做原理

  • 做爲集羣的核心,負責各功能模塊之間的通信
  • 各功能模塊經過ApiServer將信息寫入Etcd
  • 獲取數據時,經過ApiServer提供的Restful接口實現

爲了緩解集羣訪問壓力,各模塊都使用緩存,按期從ApiServer獲取資源信息,保存到本地linux

2. Controller-Manager

2.1 功能和做用

  • 集羣內部的管理控制中心
  • 負責集羣內資源對象的管理,好比:pod,service,node,namespace
  • 內部包含各類Controller,每種Controller負責一種具體的控制流程

2.2 經常使用的控制器

2.3 ReplicationController

  • 確保集羣中Pod副本一直保持預設狀態
  • 確保集羣中有正確數量的副本(spec.replicas)
  • 經過修改spec.replicas實現擴容和縮容
  • 經過修改pod模板實現系統滾動升級

2.4 NodeController

  • 做用:經過apiserver實時獲取node相關信息,實現管理和監控Node的功能
  • 監控、管理功能舉例:
    • 設置節點狀態信息:Ready、Not Ready、UnKnown
    • 長時間未收到kubelet的心跳信息則刪除etcd中的存儲信息

2.5 ResourceQuotaController

  • 做用:聽資源配額管理,確保資源佔用不會超過系統物理資源
  • 管理維度包括:
    • 容器級別:對CPU和Memory進行限制
    • Pod級別:對pod內全部容器的可用資源進行限制
    • Namespace級別:
      • pod數量
      • service數量
      • secret數量
      • pv數量

2.6 NamespaceController

  • 做用:定時經過Apiserver獲取保存在etcd中的namespace,並控制namespace的建立、刪除等操做

2.7 Endpoints Controller

什麼是endpoints? 一個service對應的全部pod的訪問地址算法

  • 做用:負責生成和維護全部的endpoint對象,供給kube-proxy作負載均衡

2.8 Service Controller

  • 做用:k8s與外部雲平臺之間的接口控制器,監聽service的變化,確保正確的loadbalance被建立

3. Scheduler

3.1 概述

  • 做用:將待調度的pod按照調度算法綁定到合適的Node上

3.2 默認調度流程

  • 預選調度:遍歷全部節點,選出符合要求的候選節點
  • 肯定最優節點:基於上一步,採用優選策略,計算出候選節點積分,最高分爲分配的節點

3.3 預選策略

  • 默認的預選策略包括5個維度的篩選,只有都經過了才做爲候選節點
  • 預選策略說明:
    • NoDiskConfilct:Volume相關衝突檢測
    • PodFitsResources:資源是否知足的檢測
    • PodSelectorMatches:pod標籤選擇器的檢測
    • PodFitsHost:是否指定被調度到特定Node的檢測
    • CheckNodeLabelPresense:判斷label設定備選節點時,是否選擇備選節點

3.4 優選策略

  • LeastRequestedPriority:選出資源消耗最小的節點
  • CalcuateNodeLabelPriority:經過調用用戶註冊的策略計算
  • BalancedResourceAllocation:選出各項資源使用率最均衡的節點

4. Kubelet

4.1 概述

  • 每一個Node節點上都會啓動一個kubelet服務進程
  • 用於處理Master節點下發到該節點的任務,管理pod及pod中的容器

4.2 kubelet與ApiServer交互原理

  • kubelet按期調用ApiServer的接口,彙報自身狀態。ApiServer收到信息後將狀態信息更新到etcd
  • kubelet經過監聽ApiServer的watch接口監聽pod信息,若是監聽到pod信息變動,會在本機作相應的操做

4.3 Pod管理

kublet經過ApiServer監聽pod的變化:docker

  • 若是發現有新的綁定到該Node的pod,則建立pod
    • 建立pod的數據目錄
    • 從ApiServer獲取pod信息
    • 爲pod掛載volume
    • 下載pod的secret
    • 檢查運行在節點中的pod,並刪除無效的
    • 爲pod建立pasue容器
    • 下載鏡像,啓動業務容器
  • 若是發現有刪除該Node的pod,則刪除pod

4.4 容器健康檢查

pod經過兩類探針檢查容器的監控情況編程

  • LivenessProbe:判斷容器是否健康,按期調用
  • ReadnessProbe:判斷容器是否啓動完成

4.5 資源監控

  • k8s提供基本的監控平臺,由Heapster項目提供
  • Heapster做爲pod運行在k8s中
  • Heapster經過kublet發現集羣信息,並查看資源情況
  • kubelet經過cAdvisor獲取節點和容器的數據,並推送到可配置的後端
  • cAdvisor採集cpu,文件,內存等指標信息

5. Kube-Porxy

5.1 概述

  • kube-proxy運行在每一個Node節點上
  • 做爲Service的代理和負載均衡器
  • 核心功能是將Service的請求轉發到後端多個pod實例
  • 默認負載均衡策略是輪詢
5.2 實現細節
  • kube-proxy檢查和監聽APIServer中Service與Endpoint的變化
  • kube-proxy爲每一個service都創建服務代理對象
  • 服務代理對象是kube-proxy的數據結構,內部包含SocketServer,用來接收請求
  • kube-proxy內部也建立一個負載均衡器LoadBalance
  • LoadBalance保存service到endpoint的動態轉發路由表

三. 網絡原理

1. k8s網絡模型

1.1 k8s網絡模型的原則:

  • 每一個pod都擁有惟一個獨立的ip地址,稱Ip-Per-Pod模型
  • 全部pod都在一個可連通的網絡環境中
  • 不論是否在同一個node,均可以經過ip直接通信
  • pod被看做一臺獨立的物理機或虛擬機

目前原生docker和kubernetes還不能打通容器與容器的通信,以支持該模型,必須依靠第三方網絡插件實現,好比:flannel後端

1.2 設計這個原則的緣由:

  • 用戶不須要額外考慮如何創建pod之間的鏈接
  • 用戶不須要考慮將容器端口映射到主機端口的問題
  • 能夠兼容過去跑在宿主機和KVM的應用

1.3 Ip-Per-Pod與Docker端口映射的區別

  • docker:端口映射到宿主機會引入端口管理的複雜性
  • docker:最終被訪問的ip和端口,與提供的不一致,引發配置的複雜性

2. docker網絡基礎

docker技術依賴於linux內核虛擬化技術的發展,對linux內核特性有很強依賴。docker用到的linux技術包括:api

  • network namespace
  • veth設備對
  • iptables、netfliter
  • 網橋
  • 路由

2.1 netork namespace

  • 爲了支持網絡協議棧多個實例,linux在網絡棧中引入了命名空間
  • 處於不一樣命名空間的網絡棧是彼此隔離,沒法通訊的
  • 爲了隔離協議棧,須要歸入命名空間的元素有:
    • 進程
    • 套接字
    • 網絡設備
  • 實現核心:
    • 將全局變量變爲net namespace的成員
    • 函數都加入namespace的參數

2.2 veth設備對

  • veth能夠將兩個命名空間連通,實現通訊
  • veth設備成對出現,像一根管子,連通兩端

2.3 網橋

  • 網橋將liunx不一樣的端口鏈接起來,實現多對多通訊
  • 網橋解析收到的報文,讀取mac地址,決定轉發的端口
  • 網橋的實現:
    • 經過一個虛擬的網橋設備實現橋接
    • 虛擬設備能夠綁定多個以太網設備
    • 虛擬網橋充當代理的角色

2.4 iptables/netfilter

  • linux提供一套機制對網絡協議棧中關心的數據進行操做
  • 實現:經過回調函數的掛載點,掛接鉤子函數對數據進行過濾、修改、丟棄等操做。掛節點技術叫iptables和netfilter
  • netfilter工做在內核模式,執行各類掛接規則
  • iptables工做在用戶模式的進程,協助維護netfilter規則表

2.5 路由

  • ip層處理數據或轉發時,會使用路由表決定發往哪裏
  • 路由功能由ip層維護的路由表實現
  • 路由表格式:
    • 目的ip地址:主機地址或網絡地址
    • 下一個路由器的ip地址
    • 標誌:下一個路由器是真實路由仍是直連端口、目的ip是主機地址仍是網絡地址等
    • 網絡接口規範:與報文一塊兒轉發
  • 路由查看:ip route list

3. Docker的網橋實現

標準docker支持四種網絡模式:緩存

  • host模式
  • container模式
  • none模式
  • bridge模式,默認模式

3.1 docker的Bridge網橋模型

  • docker第一次啓動時,會建立虛擬網橋docker0
  • 爲docker0分配一個子網
  • docker建立每一個容器時,會建立veth設備對,一端關聯到網橋上,另外一端使用linux的網絡命名空間技術鏈接到容器內,並給容器內eth0設備分配一個ip地址

docker網絡模型安全

3.2 Docker網絡的侷限性

  • Docker網絡模型沒有考慮到多主機互聯的網絡解決方案,崇尚簡單爲美
  • 同一機器內的容器之間能夠直接通信,可是不一樣機器直接容器沒法通信
  • 爲了跨節點通信,必須在主機的地址上分配端口,經過端口路由或代理到容器
  • 分配和管理容器特別困難,特別是水平擴展時

4. K8s的網絡實現

k8s網絡實現網絡

4.1 容器與容器的通信

  • 同一個容器的pod直接共享同一個linux協議棧
  • 就像在同一臺機器上,可經過localhost訪問
  • 可類比一個物理機上不一樣應用程序的狀況

4.2 pod與pod的通信

同一Node內的pod之間通信
  • 同一Node內的pod都是經過veth鏈接在同一個docker0網橋上,地址段相同,因此能夠直接通信
不一樣Node的pod之間通信
  • docker0網段與宿主機不在同一個網段,因此不一樣pod之間的pod不能直接通信
  • 不一樣node之間通信只能經過宿主機物理網卡
  • 前面說過k8s網絡模型須要不一樣的pod之間能通信,因此ip不能重複,這就要求k8s部署時要規劃好docker0的網段
  • 同時,要記錄每一個pod的ip地址掛在哪一個具體的node上
  • 爲了達到這個目的,有不少開源軟件加強了docker和k8s的網絡

5. 開源網絡組件

5.1 Flannel

實現的功能
  • 協助k8s給每一個Node上的docker容器分配互不衝突的ip地址
  • 能在這些ip地址之間創建覆蓋網絡(Overlay Network),將數據傳遞到目標容器
底層原理
  • Flannel建立名爲flannel0的網橋
  • flannel0網橋一端鏈接docker0網橋,另外一端鏈接flanneld進程
  • flanneld進程一端鏈接etcd,利用etcd管理分配的ip地址資源,同時監控pod地址,創建pod節點路由表
  • flanneld進程一端鏈接docker0和物理網絡,配合路由表,完成數據包投遞,完成pod之間通信
缺點
  • 引入多個網絡組件,帶來網絡時延和損耗
  • 默認使用udp做爲底層傳輸協議,具備不可靠性

5.2 其餘網絡組件

  • Open vSwitch
  • Calico
相關文章
相關標籤/搜索