kubernetes-基礎理論-1

devops概念

  • 應用程序交付在運維人員之前,一般來講需要一個開發團隊,做架構設計、做開發、開發完成之後還要做構建然後測試,回滾,測試,驗收,上線等等流程,在交付給運維之前開發完成之後這個過程,如果它能夠自動實現,我們就把它稱爲持續集成的過程,整個環境的需要人工的環節只有一個就是開發代碼。
  • 集成完成之後就該交付給運維進行部署了,那麼交付給運維是這樣的,測試通過後自動打包到一個可以被運維拿到的一個共享的文件服務上,或者是一個倉庫當中,讓我們運維人員能夠得到打包好的構建好的最終產品,把這一步也能自動實現,那這就叫做持續交付。
  • 我們運維拿到最終產品之後就是做部署的,假設我們運維人員拿到之後也不需要做部署,一旦交付完成之後,我們有一款工具能夠自動把這套代碼拖出來,把它自動發佈到對應的線上環境,那麼這就叫持續部署,而這一切能自動循環實現,就稱之爲Devops;
  • 正是因爲這種自動持續的流水作業,使得容器技術的實現可以讓這些流程得以落地,原因在於,我們構建好的產品,要能夠部署在對應的平臺上,如有些環境是 windows、linux或ubuntu,這種複雜的異構環境, 原始的方式會使得在構建部署真正的不同平臺時,代碼是無法通用的,而最終要實現交付部署是非常困難的;
  • 我們爲了每一種目標環境,就不得不構建一種適用的目標版本來,但是有了容器之後,這就變得簡單了,只要我們的目標平臺能夠適用容器,那麼我們就可以直接將我們的應用程序打包成鏡像直接啓動起來,而後不管是什麼平臺,把鏡像運行爲容器即可,使得自動部署變得極爲簡單,因此正式容器技術的出現,使得devops在落地上,就完全實現了可能,這就是容器技術帶來的好處;
  • 正是因爲有了容器編排工具纔有了devops, 但又因爲devops才使得容器編排工具得以流行, 以打通開發與運維之間的瓶礙
  1. CI: 持續集成

​ 持續集成的目的,就是讓產品可以快速迭代,同時還能保持高質量。它的核心措施是,代碼集成到主幹之前,必須通過自動化測試,只要有一個測試用例失敗,就不能集成。

  1. CD: 持續交付

​ **持續交付(Continuous delivery)指的是,頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供評審。**如果評審通過,代碼就進入生產階段, 持續交付可以看作持續集成的下一步。它強調的是,不管怎麼更新,軟件是隨時隨地可以交付的

  1. CD: 持續部署

​ **持續部署(continuous deployment)是持續交付的下一步,指的是代碼通過評審以後,自動部署到生產環境。**持續部署的目標是,代碼在任何時刻都是可部署的,可以進入生產階段, 持續部署的前提是能自動化完成測試、構建、部署等步驟

  1. 架構設計 --> 開發 --> 構建(測試env) --> 測試 --> 部署(線上env)

容器優勢

  • **快速創建/部署應用:**與VM虛擬機相比,容器鏡像的創建更加容易。
  • **持續開發、集成和部署:**提供可靠且頻繁的容器鏡像構建/部署,並使用快速和簡單的回滾(由於鏡像不可變性)。
  • **開發和運行相分離:**在build或者release階段創建容器鏡像,使得應用和基礎設施解耦。
  • **開發,測試和生產環境一致性:**在本地或外網(生產環境)運行的一致性。
  • **雲平臺或其他操作系統:**可以在 Ubuntu、RHEL、 CoreOS、on-prem、Google Container Engine或其它任何環境中運行。
  • **Loosely coupled,分佈式,彈性,微服務化:**應用程序分爲更小的、獨立的部件,可以動態部署和管理。
  • 資源隔離
  • **資源利用:**更高效

編排工具

  1. kubernetes
  2. docker swarm : docker公司開發的編排工具
  3. apache mesos and marathon: idc/os 數據中心管控工具

容器編排工具應當具有的功能

  • 服務自動發現
  • 負載均衡
  • 安全、配置、存儲管理
  • 健康檢查
  • 自動 [掃描/重啓/心跳] 配置 節點
  • 零down機部署

K8S是什麼

​ Kubernetes是容器集羣管理系統,是一個開源的平臺,可以實現容器集羣的自動化部署、自動擴縮容、維護等功能。 (容器本身僅提供託管運行應用的邏輯, 而容器編排纔是真正產生價值的所在),Kubernetes是Google 2014年創建管理的,是Google 10多年大規模容器管理技術Borg的開源版本。 其中openshift是k8s的發行版, 下載地址

通過k8s可以

  • 快速部署應用
  • 快速擴展應用
  • 無縫對接新的應用功能
  • 節省資源,優化硬件資源的使用

Kubernetes 特性

  • 可移植: 支持公有云,私有云,混合雲,多重雲 (multi-cloud)
  • 可擴展: 模塊化, 插件化, 可掛載, 可組合
  • 自動化: 自動部署,自動重啓,自動複製,自動伸縮/擴展
    • 自動裝箱: 基於資源極其依賴約束,能夠自動完成容器的部署而且不影響其可用性;
    • 自我修復: 當某一個容器掛了, 它可以自動一秒重啓一個新的容器, 假設有一個應用程序(容器)掛了, 我們可以直接刪除它創建一個新的,不必要修復, 所以有了k8s這個編排工具後,我們更多關注於羣體而不是個體了;
    • **自動發佈和回滾:**當上線代碼出現問題的時候,可以自動實現發佈和回滾;
    • **密鑰和配置管理:**容器化應用程序的最大的問題在於,我們所配置應用程序比較苦難,我們基於鏡像啓動一個容器之後,我們如果期望容器中的應用程序換一種配置文件,那麼我們就可以使用配置管理來實現,類似我們的docker的環境腳本,實現雲配置的集中化;
    • **存儲編排:**把存儲卷實現動態供給,也就意味着,某一個容器需要用到存儲卷的時候,根據容器自身的需求創建能夠滿足它需要的存儲卷,實現存儲編排;

Kubernetes 架構

​ k8s其實就是一個集羣,組合多臺主機整合成一個大的資源池並統一對外提供計算,存儲的集羣,我們將N個主機在每臺主機之上都安裝上Kubernetes的相關應用程序,然後在這個程序之上進行通信,從而完成彼此間的協調,並通過這個應用程序協同工作,把多個主機當一個主機來使用;
​ 集羣有兩種常用模型,第一種是P2P沒有中心節點,每一個節點都能夠接受用戶請求,第二種是有中心節點的集羣,比如像MySQL的主從複製,只有一個是主節點,其他都與他進行同步,這就是中心節點。在Kubernetes就是屬於這種有中心節點架構的集羣系統,從這個維度上來講,它被叫做master/nodes集羣

  • master: 由一個或一組節點組成, 主節點是集羣的唯一入口,
  • node: 每一個節點都會貢獻一部分計算能力、存儲能力等相關資源, node其實就是運行容器的節點;
  • 分佈式必須最少滿足 一個master, 二個node, 生產環境最少得要滿足兩個master,架構圖如下
    在這裏插入圖片描述

​ 用戶通過api server 將請求提交給master, master中有一個調度器會分析各node的可用資源狀態,找一個最佳適配的node節點,然後由這個node本地的docker或其它容器引擎將這個容器啓動,這個node會先判斷檢查本地是否有這個鏡像,如果沒有會先去docker register中Pull,而register也可以做爲容器運行,所以我們的register也可以交給k8s,這就是所謂的k8s功能模型,接收請求的只能kubernetes Cluster, 對外提供服務的爲API Server (curd)

k8s-master組件

提供的服務: API Server, Scheduler, Controller-manage, etcd

在這裏插入圖片描述

Api Server

接收並處理請求,提供對外的增刪改查接口, 如果用戶請求是CURD,那麼這個請求不應該運行在master之上,而是在node, 具體那個node可用由調度器來決定, Kubernetes的API Server是一個restfull風格的API,通過http向外提供服務,因此restfull當中所有向外輸出的都是對象,所有的對象都可以擁有標籤,所有的標籤都可以使用標籤選擇器進行篩選

Scheduler

  • 負責觀察每個node的計算資源, 如(cpu/mem/disk), 調度容器的請求,
  • k8s不但能夠設定資源上限還能設置資源下限,我們稱爲請求量,意思就是一旦請求那麼必須確保對應的node上有能夠支撐的資源量,所以調度器就需要進行評估,哪一個節點更合適;
  • 爲此Kubernetes設計了一個兩級調度的方式來做調度,第一步先做預選,哪些服務器是符合要求的,比如有10臺服務器,選出來有3臺符合,然後再對這三個進行優選,從這個三個中再選擇一個最優的節點;

Controller-manage

​ Controller Manager作爲集羣內部的管理控制中心,負責集羣內的Node、Pod副本、服務端點(Endpoint)、命名空間(Namespace)、服務賬號(ServiceAccount)、資源定額(ResourceQuota)的管理,當某個Node意外宕機時,Controller Manager會及時發現並執行自動化修復流程,確保集羣始終處於預期的工作狀態。

每個Controller通過API Server提供的接口實時監控整個集羣的每個資源對象的當前狀態,當發生各種故障導致系統狀態發生變化時,會嘗試將系統狀態修復到“期望狀態”。

Replication Controller

副本控制器的作用即保證集羣中一個RC所關聯的Pod副本數始終保持預設值, 支持自動滾動更新以及回滾操作

  1. 只有當Pod的重啓策略是Always的時候(RestartPolicy=Always),副本控制器纔會管理該Pod的操作(創建、銷燬、重啓等)如果一個Pod失敗重啓,重啓的Node由Replication Controller決定,不一定是原先的Node
  2. RC中的Pod模板就像一個模具,模具製造出來的東西一旦離開模具,它們之間就再沒關係了。一旦Pod被創建,無論模板如何變化,也不會影響到已經創建的Pod。
  3. Pod可以通過修改label來脫離RC的管控,該方法可以用於將Pod從集羣中遷移,數據修復等調試。
  4. 刪除一個RC不會影響它所創建的Pod,如果要刪除Pod需要將RC的副本數屬性設置爲0或直接刪除控制器
  5. 不要越過RC創建Pod,因爲RC可以實現自動化控制Pod,提高容災能力。

RC職責

  1. 確保集羣中有且僅有N個Pod實例,N是RC中定義的Pod副本數量。
  2. 通過調整RC中的spec.replicas屬性值來實現系統擴容或縮容。
  3. 通過改變RC中的Pod模板來實現系統的滾動升級。

RC使用場景

使用場景 說明 使用命令
重新調度 當發生節點故障或Pod被意外終止運行時,可以重新調度保證集羣中仍然運行指定的副本數。
彈性伸縮 通過手動或自動擴容代理修復副本控制器的spec.replicas屬性可以實現彈性伸縮。 kubectl scale
滾動更新 創建一個新的RC文件,通過kubectl 命令或API執行,則會新增
一個新的副本同時刪除舊的副本,當舊副本爲0時,刪除舊的RC。
kubectl rolling-update

etcd

kv存儲數據庫, 與redis差不多, 具有rest協議可實現節點選舉, 類似於zk, 存儲master狀態信息, 內部端口https用於內部通信,  外口端口http用於客戶端通信。

k8s-node組件

工作節點, kubelet, docker(或者說容器引擎), kube-proxy

服務名稱 狀態說明
kubelet pod對應的容器的創建、啓停等任務,同時與master節點密切協作,實現集羣管理的相關功能
docker docker引擎, 負責本機的容器創建和管理工作
kube-proxy 實現kubernetes service的通信與負載均衡機制

POD

​ k8s上調度最小的邏輯單元,pod主要就是用來放容器的,一個pod可以包含多個 容器,而容器之間可以共享名稱空間( ipc, net, uts),而mount,pid,user相互隔離, pod存儲卷也可以共享。 k8s通過label-select識別pod節點是否屬於哪個控制器
​ node是 k8s集羣node節點負責運行,並且是由k8s集羣中master指派的任務,而最根本的是它的最核心的任務是以Pod的形式去運行容器的,理論上講,node可以是任何形式的計算設備,只要有傳統意義上的CPU、內存啊等並且能夠裝上Kubernetes集羣的代理程序它都可以作爲整個Kubernetes集羣的一個份子來進行工作,因此Kubernetes的實現效果就類似於如圖

在這裏插入圖片描述

名稱 說明
label 爲了統一管理在同一個集羣的大量資源,添加的元數據,kv類型
label-select 定義過濾條件,來挑選出所符合條件的pod資源

一個容器加入到pod, 都會屬於同一個infra, 服務發現:當一個pod生成之後,會自動註冊到控制器上

自主式POD

​ 自我管理,提交給api server, 藉助Scheduler到指定的node節點, 由node啓動節點,如果節點故障該pod也會消失,無法實現全局調度

控制器管理的Pod

  1. Replication Controller: 副本控制器
  2. ReplicaSet 副本集 不直接使用
    • Depolyment: 只能管理無狀態應用控制器
      • HPA: 水平Pod自動伸縮控制器
    • StatefulSet: 有狀態控制器
    • DaemonSet: 每個node上都運行一個副本
    • job、Ctonjob: 特殊控制器, 如: 備份, 清理日誌

Service

​ Kubernetes爲每一組提供同類服務的Pod和客戶端之間添加了一箇中間層,這個中間層是固定的,這個中間層就叫Service,Service只要不刪除,它的地址和名稱就是固定的,而後當客戶端需要寫在配置文件當中訪問某一個服務的時候也不需要發現,不用自動發現某一個功能,他只需要在配置文件當中寫入服務的名稱和服務的地址即可,而這個服務是一個調度器,還能提供調度的功能,不但能提供穩定的訪問入口還能提供調度Pod,一旦Pod宕機,新建的Pod會立即加入Service裏面來,並把這個Pod作爲後端的可用訪問入口之一;

​ Service是靠標籤選擇器來關聯Pod對象的,所以只要Pod存在只要屬於這一組標籤選擇器就能立即被Service作爲後端組件存在,並且Service把Pod關聯進來之後還會動態探測IP地址是什麼,端口是什麼,並作爲自己調度的後端可用接口,因此客戶端的請求到達Service,由Service代理至後端的Pod來實現;如圖
在這裏插入圖片描述

服務訪問流程

​ 客戶端 訪問 --> service 代理至後端的pod, 當pod故障, service會自動根據label-select加入pod, 而sevice最終也只是一個iptables的DNAT規則或ipvs的規則,客戶端也可以直接訪問service的名稱, 該名稱會通過dns解析,如果service的地址或名稱發生改變 dns會實時修改狀態。

總結

k8s是master/node框架,組件列表

組件 列表
master API Server、Scheduler、Controller-Manager
node kubelet、容器引擎(Docker)、kube-proxy
Pod Label、Label Selector

k8s三個核心: pod 、控制器、service
控制器三要素: replicas, template, selector
service要素: 各種轉發
Kubernetes域名解析:服務名.命名空間.svc.cluster.local

k8s網絡模型

pod通信: pod與pod之間,pod與容器,pod與serivce, pod與集羣外

  1. 節點網絡: 節點地址
  2. service: 集羣網絡,虛擬地址,存在於ipvs或iptables中
  3. pod: pod網絡
    • 同一個pod內的多個容器間: lo通信
    • 各pod之間通信
    • pod與service之間的通信 service通過kube-proxy隨時與api server通信, 當pod發生改變時,其結果會非常保存API server中, 而 api service通信內容發生改變時會立即生成一個事件,kube-proxy當發現改變時會直接修改客戶端 的iptables、ipvs規則

在這裏插入圖片描述

pod與pod之間通信

Pod和Pod之間通信,在Kubernetes內還存在三種通信網絡,

  1. 一個Pod內可能有多個網絡,所以同一Pod內的多個容器直接通過lo進行通信就行了;
  2. 各Pod之間的通信可直接使用對應Pod的地址進行通信,但是如果Pod過多可能會產生廣播風暴;
  3. 通過隧道的方式轉發二層報文,使得兩臺主機雖然跨主機但好像工作在同一個二層網絡中一樣,疊加有二層疊加跟三層疊加,我們可以轉發對方的二層報文或隧道轉發對方的三層報文從而實現疊加網絡,這樣就能實現Pod與Pod之間通信了;

Pod與Service通信

​ Pod有Pod獨立的網絡,Service也有Service的獨立網絡,那他們之間的通信從原理上來講是不可達的,因爲Service只不過是主機之上的iptables的規則地址,所以只需要將容器的報文指向網關, 網關假如是我們的docker0橋, 因爲我們當前宿主機就有iptabels規則, 而每臺主機之上都會有iptables策略, 所以在創建Service時,這個Service要反映在Kubernetes的每個node上的,每個node都應該有相應的iptables或ipvs規則,如果有一個容器視圖去訪問Service地址時,它應該把請求送給網關,一般是docker0橋的地址,而docker0橋收到以後發現這個地址需要通過我們的iptables規則表進行檢查就知道它到底在哪兒,就找到了它

  • 因爲Service隨時也會產生變動,比如刪除了Service或Pod改變了,那麼Service規則中的目標地址也會改變, 如果Pod發生改變那麼Service就需要使用標籤選擇器進行匹配並且獲取地址;
  • 但是Service如何改變所有node的相關規則呢,那這個就需要一個專門的組件來實現,所以每一個node節點上需要一個組件,這個組件在node之上做爲一個守護進程,它被稱爲kube-proxy,它負責隨時與Api Server進行通信;
  • 因爲每一個Pod發生變化之後這個結果需要保存在API Server當中的,對於API Server來說Pod發生改變之後會生成一個通知事件,這個事件可以被任何關聯的組件接受到,比如我們的kube-proxy,一旦發現某一個Service背後的Pod地址發生改變,對應的由kube-proxy負責反映在對應node的iptables或ipvs規則上;
  • 所以Service的管理是靠kube-proxy來實現的,創建一個Service需要靠kube-proxy在每一個node上創建規則,每一個Service的變動也需要kube-proxy來反應到規則上;

在這裏插入圖片描述
​ kube-proxy說白了,它也是我們的Kubernetes一個客戶端,它隨時wath,監視者Kubernetes ApiServer上的變動,尤其是Service的資源的變動,它會把每一個Service資源的變動反應在當前節點上的對應的iptables或Ipvs規則

​ 這樣一來我們的API Service需要存儲整個集羣當中的各組件的狀態信息,那我們其他的master如何進行數據同步呢,那就涉及到共享存儲,對於master主機來講,所有的數據並不放置在master本地,而是放在共享存儲裏面,這個存儲我們叫做Kubernetes的DB,也就是etcd,而etcd是一個鍵值存儲系統,還支持各種協調工作,比如實現節點的選舉啊等,所以etcd更像zookeeper,那etcd如果宕機了,那麼整個集羣就宕機了,所以etcd需要集羣;

​ etcd也是restfull風格的集羣,可以通過http或https通信,etcd有三個端口 一個端口集羣內部通信,一個端口向客戶的提供服務,也就意味着其內部通信需要點對點通信的證書,

  1. 要想向客戶的通信的需要另外一套證書來實習,而Kubernetes的API Server也需要使用https加密,所以從這個角度來講,etcd自身需要一套證書,etcd作爲服務端來講它的客戶端是API Server;
  2. 而API Server需要向外部通信也需要一套證書。每個node組件有三個組件,API Server與kubelet進行通信使用https通信,所以我們要手動搭建Kubernetes是極其複雜的需要五套證書;

網絡插件

無論是哪個服務商提供的網絡管理方案它都應該負責管理兩種網絡,Pod網絡和Service網絡,

CNI: container network interface 容器網絡接口

  • flannel: 網絡配置, (配置簡單,不支持策略)
  • calico: 網絡配置,網絡策略 (配置複雜)
  • canel: flannel+calico 功能合集 , 也可以做爲容器或daemon運行

​ 其實我們網絡需要兩個維度,第一就是提供網絡功能,給Pod提供IP地址給Service提供IP地址,第二Kubernetes的網絡解決方案還要求它能夠提供Network策略功能,來進行網絡策略管理,進行容器隔離等,實際上也就是一些訪問規則,因此我們要引入Kubernetes另外一個邏輯組件,叫做名稱空間,Kubernetes的名稱空間,整個Kubernetes是作爲一個集羣存在,我們將來可以在集羣內部運行無數個Pod,都在同一個網絡中,這麼多的Pod,極有可能互相干擾,所以我們可以把他們切割成多個名稱空間(namespace),一類Pod只運行在一個空間中,實現網絡策略的管理;

es的網絡解決方案還要求它能夠提供Network策略功能,來進行網絡策略管理,進行容器隔離等,實際上也就是一些訪問規則,因此我們要引入Kubernetes另外一個邏輯組件,叫做名稱空間,Kubernetes的名稱空間,整個Kubernetes是作爲一個集羣存在,我們將來可以在集羣內部運行無數個Pod,都在同一個網絡中,這麼多的Pod,極有可能互相干擾,所以我們可以把他們切割成多個名稱空間(namespace),一類Pod只運行在一個空間中,實現網絡策略的管理;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章