k8s架構以及相關概念普及
為什麼要使用k8s
瞭解openstack
在k8s和容器docker出來之前,最火的技術莫過於開源雲平臺openstack了,那麼openstack做了什麼事情呢?利用虛擬化技術實現資源的彈性使用,如果你是做開發的,你肯定知道資料庫連線池,誰需要誰就拿走連線,用完了就換回去。同理,雲平臺無非就是把計算、儲存、網路這三種資源進行了池化,進而希望達到彈性使用的目的。(彈性就是想啥時要都有,想要多少都行)。
openstack實際上就是利用虛擬化技術(例如KVM)等對伺服器叢集進行管理,管理的目標就是要達到兩個方面的靈活性。哪兩個方面呢?比如有個人需要一臺很小很小的電腦,只有一個CPU,1G記憶體,10G的硬碟,一兆的頻寬,你能給他嗎?像這種這麼小規格的電腦,現在隨便一個膝上型電腦都比這個配置強了,家裡隨便拉一個寬頻都要100M。然而如果去一個雲端計算的平臺上,他要想要這個資源的時候,只要一點就有了。
所以說它就能達到兩個方面靈活性:
- 第一個方面就是想什麼時候要就什麼時候要,比如需要的時候一點就出來了,這個叫做時間靈活性。
- 第二個方面就是想要多少呢就有多少,比如需要一個很小很小的電腦,可以滿足,比如需要一個特別大的空間,以雲盤為例,似乎雲盤給每個人分配的空間動不動就就很大很大,隨時上傳隨時有空間,永遠用不完,這個叫做空間靈活性。
空間靈活性和時間靈活性,就是常說的雲端計算的彈性。
全部內容可以參考另一篇部落格:為什麼需要雲端計算
瞭解docker
首先,雲端計算是為了解決計算、網路、儲存這三種資源的彈性問題,但是它遺留了兩個問題:
- 應用的擴充套件問題。例如我開發一個電商應用,平時的時候10臺機器能扛的住,雙十一的時候需要100臺才能抗的住。那怎麼辦?雲端計算平臺可以實現一點90臺新機器就出來了,但是機器是空的啊,上面什麼應用都沒安裝,還需要人工登到每臺機器上去一臺一臺的部署,非常麻煩。
- 遷移性問題。軟體往往是需要不斷的在不同的環境裡面安裝的,例如開發人員自己會安裝一套,測試人員會安裝一套,線上環境也會安裝一套。然而軟體的安裝是非常複雜的,牽扯到許可權問題,配置問題,檔案路徑問題等,一不小心就會出錯,出錯了軟體的行為就不對了,你上網買東西,用銀行支付都可能出錯,造成大麻煩。
鑑於以上的兩種問題,有人提出了比KVM更加輕量級的虛擬化技術,希望能夠解決上述的問題:
- 應用的彈性擴充套件
- 應用的遷移
docker被人拿到檯面上來,docker主要依賴於兩個技術,分別是cgroup和namespace,這兩個技術保證了容器的隔離性。
docker和KVM的對比:
- 容器撇下os。容器裡面是不安裝作業系統的,因為一個作業系統就很大了,並且os的執行也是非常佔用系統資源的,容器與宿主機共用一個核心,容器之間的遷移不帶核心。
- 容器撇下應用執行產生的本地資料。這些資料如果在容器裡面,容器會變得很大,影響容器在不同環境之間的遷移。不同的環境指的是開發、測試、運維上線這幾種環境的不同。這些資料在不同的環境是沒有意義的,因此這些資料一般放在容器之外的裝置上。
- 所有容器都是與宿主機共用核心的,容器與容器之間的隔離性就會差很多。而虛擬機器的隔離性就要好很多,虛擬機器運轉依靠的是虛擬化技術模擬出了cpu,記憶體,硬碟,網路等。而容器都是使用宿主機的。
- 容器裡面是不存放資料的,容器裡面的資料會隨著容器的生命週期而消失,如果想要持久化的儲存,必須要依靠外部的儲存裝置。
k8s存在的意義
docker如果一直跑單機,自然不需要k8s。可是萬一你想在一個叢集中跑k8s呢?那你就不得不面對兩個問題:
- 跨主機的容器之間的通訊問題
- 容器的排程和管理問題(編排)
k8s的發展就依賴於這股全民皆容器的浪潮當中,k8s是容器的編排工具,所謂編排,就是對容器進行管理,從埠暴露到外網,負載均衡,服務註冊與發現,應用的編排與彈性伸縮,滾動更新,灰度釋出等等。這些內容都交由k8s去實現。
同時,k8s可以說是最好的微服務載體,把一個非常大的單體應用分解為很多小的互相連線的微服務,一個微服務副本後面可能需要多個例項的支撐。副本的數量可以根據系統的負載進行動態的調整,每個微服務獨立開發,升級,擴充套件。最後,k8s具有非常強大的橫向擴充套件能力,這個能力能夠幫助企業從幾個結點的叢集,平滑的擴充套件到幾百個結點的叢集,大大增強了系統的彈性。
k8s的架構解析
基本概念
- pod
Pod是Kubernetes建立或部署的最小/最簡單的基本單位,一個Pod代表叢集上正在執行的一個程序。一個pod裡面可以包含多個容器。這多個容器共享Pod的ip地址。
一個Pod封裝一個應用容器(也可以有多個容器),儲存資源、一個獨立的網路IP以及管理控制容器執行方式的策略選項。Pod代表部署的一個單位:Kubernetes中單個應用的例項,它可能由單個容器或多個容器共享組成的資源。
- label
label是k8s中的鍵值對,使用者可以自己設定key和value。某一個物件可以有多個label,同一個lable也可以打給多個物件。因此,通過選擇label,就能夠選擇一組合適的資源物件。當所有的資源都有了label之後,使用label selector就相當於在資料庫當中使用where語句,最終能夠得到一組相同label的資源。
k8s叢集有兩種叢集角色,一種是Master,一種是Node,Master相當於大腦,控制著整個叢集的運轉,Node是k8s完成實際工作的節點。
Master節點組成詳解
Master節點主要有以下幾個元件:
- kube-apiserver:
API Server提供HTTP/HTTPS RESTful API,即Kubernetes API。 API Server是Kubernetes Cluster的前端介面,各種客戶端工具(CLI或 UI)以及Kubernetes其他元件可以通過它管理Cluster的各種資源。
- kube-scheduler:
Scheduler負責決定將Pod放在哪個Node上執行。Scheduler在排程 時會充分考慮Cluster的拓撲結構,當前各個節點的負載,以及應用對 高可用、效能、資料親和性的需求。是一個內部的排程器。
- kube-controller-manager:
Controller Manager負責管理Cluster各種資源,相當於所有資源的控制中心,保證資源處於預期 的狀態。Controller Manager由多種controller組成,包括replication controller、endpoints controller、namespace controller、serviceaccounts controller等。
- etcd:
etcd負責儲存Kubernetes Cluster的配置資訊和各種資源的狀態資訊。當資料發生變化時,etcd會快速地通知Kubernetes相關元件。相當於一個配置中心,裡面包含了所有元件的配置檔案。
- Pod網路:
Pod要能夠相互通訊,Kubernetes Cluster必須部署Pod網路, flannel是其中一個可選方案。calico也是一種網路方案。二者的區別主要在於,flannel是二層overlay網路,而calico是路由轉發網路。
整個Master結點的運作過程如上圖所示。
- 由API Serve對外提供介面,使得使用者能夠對所有的資源進行增刪改查,也是控制叢集的唯一入口。
- Scheduler負責排程任務到哪一個結點上執行。
- Controller則用來控制和管理叢集中的所有結點上的資源。
- etcd就是配置中心,裡面包含了所有物件的配置檔案(k8s中常見的資源的配置都在這裡面存放)。
Node節點組成詳解
Node節點上一般會執行以下程序:
- kubelet:
kubelet是Node的agent,當Scheduler確定在某個Node上執行Pod 後,會將Pod的具體配置資訊(image、volume等)傳送給該節點的 kubelet,kubelet根據這些資訊建立和執行容器,並向Master報告執行 狀態
- kubeproxy:
service在邏輯上代表了後端的多個Pod,外界通過service訪問 Pod。service接收到的請求是如何轉發到Pod的呢?這就是kube-proxy 要完成的工作.每個Node都會執行kube-proxy服務,它負責將訪問service的 TCP/UPD資料流轉發到後端的容器。如果有多個副本,kube-proxy會 實現負載均衡.
- Pod網路:
Pod要能夠相互通訊,Kubernetes Cluster必須部署Pod網路, flannel是其中一個可選方案(二層overlay網路)。calico也是其中一個方案(依靠路由轉發實現)
命令執行流程
Master結點和Node結點實際的工作流程如上圖所示:
- 1.kubectl傳送部署請求到API Server
- 2.API Server通知Controller Manager建立一個deployment資源。
- 3.Scheduler執行排程任務,將要建立的任務按照一定的策略排程到相關結點上。
- 4.Node結點上的kubelet負責接收排程任務,通過kubelet在各自的結點上接收並執行pod。
其中etcd會將應用的配置和當前的狀態資訊儲存在etcd當中,當執行kubectl get xxx(某種資源)的時候可以讀取etcd當中相關的資訊。