快速瞭解Kubernetes

關於Kubernetes

起源

Kubernetes 源自於 Google 內部的服務編排系統 - Borg,誕生於2014年。它汲取了Google 十五年生產環境的經驗積累,並融合了社區優秀的idea和實踐經驗。html

名字

Kubernetes這個單詞起源於古希臘是舵手的意思,因此它的logo是一個漁網狀的七邊形,裏面還有一個羅盤。Google選擇這樣一個名字也是有必定的深意:既然docker把本身比做一隻鯨魚託着集裝箱在大海中遨遊,Google就要用Kubernetes去掌握去掌握大航海時代的話語權,去捕獲和指引着這條鯨魚按照主人設定的路線去巡遊。算法

核心

得益於 Docker 的特性,服務的建立和銷燬變得很是快速、簡單。Kubernetes 正是以此爲基礎,實現了集羣規模的管理、編排方案,使應用的發佈、重啓、擴縮容可以自動化。docker


Kubernetes的架構設計

Kubernetes 能夠管理大規模的集羣,使集羣中的每個節點彼此鏈接,可以像控制一臺單一的計算機同樣控制整個集羣。後端

在k8s集羣中有兩種角色,一種是 Master ,一種是 Node(也叫worker):網絡

  • Master 是集羣的"大腦",負責管理整個集羣,例如應用的調度、更新、擴縮容等。
  • Node 就是具體"幹活"的,一個Node通常是一個虛擬機或物理機,它上面事先運行着 docker 服務和 kubelet 服務( Kubernetes 的一個組件),當接收到 master 下發的"任務"後,Node 就要去完成任務(用 docker 運行一個指定的應用)

以下圖:
快速瞭解Kubernetes架構

瞭解了集羣中的兩大角色後,咱們再看看Kubenetes的架構示意圖:
快速瞭解Kubernetesapp

Kubenetes Master節點剖析圖:
快速瞭解Kubernetes負載均衡

在上文也說了Master節點至關於Kubenetes集羣中的大腦,在Master節點具有四個主要模塊:分佈式

  • API Server:提供外部訪問能力,使得咱們能夠經過UI或CLI工具(如kubectl)與Kubenetes集羣進行交互
  • Scheduler:負責資源調度,當咱們在集羣上建立一個容器時,該模塊的調度算法會決定Pod被建立在哪一個集羣節點上
  • Controller:以守護進程形式存在的控制模塊,相似事件循環的處理器,用於處理各類集羣中的事件,控制並調節集羣的指望狀態。例如接收到某個服務掛掉的事件,就會自動去從新拉起這個服務,知足服務可用的狀態。又或者某個服務的實例副本數是2,當掛掉一個實例時,也會自動恢復,以知足實例副本數爲2這個狀態
  • etcd:這是一個分佈式的key-value存儲系統,主要用於存儲Kubenetes集羣的狀態、資源和配置等信息

Kubenetes Node節點剖析圖:
快速瞭解Kuberneteside

  • Pod:Pod是Kubenetes集羣中調度的最小單位,所謂Pod就是具備相同namespace的一個或多個container的組合
  • Docker:底層的容器技術,由於除了Docker外還有其餘的容器技術
  • kubelet:運行在每一個節點上的主要的「節點代理」,每一個節點都會啓動 kubelet 進程,用來處理 Master 節點下發到本節點的任務,按照 PodSpec 描述來管理 Pod 和其中的容器的生命週期(PodSpec 是用來描述一個 pod 的 YAML 或者 JSON 對象)。也就是說在Node中負責去調用Docker拉取鏡像、運行、中止容器等工做是由 kubelet 完成的。
  • kube-proxy:用於節點的網絡代理,主要實現端口轉發、負載均衡、service服務發現等功能
  • Fluentd:負責日誌的採集、存儲及查詢

Kubernetes的核心概念

Pod - Kubernetes中的最小調度單位

Kubernetes 的 Node 作的事情也並非簡單的 docker run 一個容器。出於像易用性、靈活性、穩定性等的考慮,Kubernetes 提出了一個叫作 Pod 的東西,做爲 Kubernetes 的最小調度單位。因此咱們的應用在每一個 Node 上運行的實際上是一個 Pod。Pod 也只能運行在 Node 上。以下圖:

快速瞭解Kubernetes

Pod中會包含一個或多個容器。容器自己就是一個小盒子了,Pod 至關於在容器上又包了一層小盒子。這個盒子裏面的容器有什麼特色呢?

  • 能夠直接經過 volume 共享存儲。
  • 有相同的網絡命名空間(network namespace),通俗點說就是有同樣的ip地址,有同樣的網卡和網絡設置。例如A容器監聽了80端口,B容器監聽了8080端口,A容器直接經過127.0.0.1:8080就能夠訪問到B容器的服務,反之亦然。
  • 多個容器之間能夠「瞭解」對方,好比知道其餘人的鏡像,知作別人定義的端口等。

快速瞭解Kubernetes

Pause容器

每一個Pod裏都會有一個特殊的Pause容器有時候也稱爲Infra容器,它與用戶容器」捆綁「運行在同一個 Pod 中,最大的做用是維護 Pod 網絡協議棧,將用戶容器link到一塊兒。這也是爲何同一個Pod裏的容器之間僅需經過localhost就能互相通訊的緣由。除此之外,Pause容器還會負責Pod的健康檢查,而後彙報給k8s。

Pause容器主要爲每一個用戶容器提供如下功能:

  • PID命名空間:Pod中的不一樣應用程序能夠看到其餘應用程序的進程ID。
  • 網絡命名空間:Pod中的多個容器可以訪問同一個IP和端口範圍。
  • IPC命名空間:Pod中的多個容器可以使用SystemV IPC或POSIX消息隊列進行通訊。
  • UTS命名空間:Pod中的多個容器共享一個主機名;Volumes(共享存儲卷):
    • Pod中的各個容器能夠訪問在Pod級別定義的Volumes。

關於Pause容器更多的內容能夠參考:

ReplicaSet(RS)

Pod的上一層是ReplicaSet(副本集),簡稱RS。ReplicaSet負責維護應用的實例副本,因此ReplicaSet裏的每個Replica就是一個Pod而不是容器,由於Pod是最小調度單位。例如某個應用的ReplicaSet數量是2,當某一個節點上的Pod掛掉了,那麼ReplicaSet就會檢測到副本數量不知足2,此時k8s就會從新根據調度算法在其餘節點建立並運行一個新的Pod,通俗來講就是再拉起一個Pod。

快速瞭解Kubernetes

Deployment - 應用管理者

當咱們擁有一個 Kubernetes 集羣后,就能夠在上面跑咱們的應用了,前提是咱們的應用必須支持在 Docker 中運行,也就是咱們要事先準備好Docker鏡像。

有了鏡像以後,通常咱們會經過Kubernetes的 Deployment 的配置文件去描述應用,好比應用叫什麼名字、使用的鏡像名字、要運行幾個實例、須要多少的內存資源、cpu 資源等等。

有了配置文件就能夠經過Kubernetes提供的命令行客戶端 - kubectl 去管理這個應用了。kubectl 會跟 Kubernetes 的 master 經過RestAPI通訊,最終完成應用的管理。

好比咱們建立並配置好的 Deployment 配置文件叫 app.yaml,咱們就能夠經過"kubectl create -f app.yaml" 命令來建立這個應用,以後就由 Kubernetes 來保證咱們的應用處於運行狀態,當某個實例運行失敗了或者運行着應用的 Node 忽然宕機了,Kubernetes 會自動發現並在新的 Node 上調度一個新的實例,保證咱們的應用始終達到咱們預期的結果。

快速瞭解Kubernetes

RollingUpdate - 滾動升級

滾動升級是Kubernetes中最典型的服務升級方案,主要思路是一邊增長新版本應用的實例數,一邊減小舊版本應用的實例數,直到新版本的實例數達到預期,舊版本的實例數減小爲0,滾動升級結束。在整個升級過程當中,服務一直處於可用狀態。而且能夠在任意時刻回滾到舊版本。

快速瞭解Kubernetes

咱們之因此不會直接將應用定義爲Pod,而是定義爲 Deployment 的一個重要緣由就是由於只有將應用定義成 Deployment 時才能支持滾動升級。當 Deployment 中的容器須要升級更新時,Deployment 會先建立一個新的 ReplicaSet 及Pod,而後中止並刪除舊的 ReplicaSet 中的一個Pod,接着再新建一個新版本Pod,而後再刪除一箇舊版本的Pod......以此實現滾動式的更新,因此在更新過程當中應用能夠實現不中斷地服務。

Service - 服務發現 - 找到每一個Pod

假設咱們上面介紹的 Deployment 建立了,Pod 也運行起來了。如何才能訪問到咱們的應用呢?

最直接想到的方法就是直接經過 Pod的 ip + 端口號去訪問,但若是實例數不少呢?好,拿到全部的 Pod - ip 列表,配置到負載均衡器中,輪詢訪問。但上面咱們說過,Pod 可能會死掉,甚至 Pod 所在的 Node 也可能宕機,Kubernetes 會自動幫咱們從新建立新的Pod。再者每次更新服務的時候也會重建 Pod。而每一個 Pod 都有本身的 ip。因此 Pod 的ip 是不穩定的,會常常變化的,不可能每次ip變化都去修改一下負載均衡中的ip列表。

面對這種變化咱們就要藉助另外一個概念:Service。它就是來專門解決這個問題的。無論Deployment的Pod有多少個,無論它是更新、銷燬仍是重建,Service老是能發現並維護好它的ip列表。Service對外也提供了多種入口:

  • ClusterIP:Service 在集羣內的惟一 ip 地址,咱們能夠經過這個 ip,均衡的訪問到後端的 Pod,而無須關心具體的 Pod。
  • NodePort:Service 會在集羣的每一個 Node 上都啓動一個端口,咱們能夠經過任意Node 的這個端口來訪問到 Pod。
  • LoadBalancer:在 NodePort 的基礎上,藉助公有云環境建立一個外部的負載均衡器,並將請求轉發到 NodeIP:NodePort
  • ExternalName:將服務經過 DNS CNAME 記錄方式轉發到指定的域名(經過 spec.externlName 設定)。

快速瞭解Kubernetes

好,看似服務訪問的問題解決了。但你們有沒有想過,Service是如何知道它負責哪些 Pod 呢?是如何跟蹤這些 Pod 變化的?

最容易想到的方法是使用 Deployment 的名字。一個 Service 對應一個 Deployment 。固然這樣確實能夠實現。但Kubernetes 使用了一個更加靈活、通用的設計 - Label 標籤,經過給 Pod 打標籤,Service 能夠只負責一個 Deployment 的 Pod 也能夠負責多個 Deployment 的 Pod 了。Deployment 和 Service 就能夠經過 Label 解耦了。

快速瞭解Kubernetes


Kubernetes的認證與受權

關於Kubernetes的認證與受權機制內容比較多也比較複雜,因此這裏引用一些文章做爲參考:

也能夠直接翻閱官方文檔:

相關文章
相關標籤/搜索