k8s是什么
Kubernetes一個用于容器集群的自動化部署、擴(kuò)容以及運維的開源平臺。通過Kubernetes,你可以快速有效地響應(yīng)用戶需求;快速而有預(yù)期地部署你的應(yīng)用;極速地擴(kuò)展你的應(yīng)用;無縫對接新應(yīng)用功能;節(jié)省并優(yōu)化硬件資源的使用。為容器編排管理提供了完整的開源方案。
幾個關(guān)鍵詞:
快速有效地響應(yīng)
個人理解為兩個方面:一方面、新增或者修改需求時,可以快速進(jìn)行部署測試(CICD);另一方面、kubernetes可以根據(jù)不同條件進(jìn)行動態(tài)擴(kuò)縮容,kubernetes會自動將用戶服務(wù)模塊增加更多實例以保證當(dāng)前的系統(tǒng)訪問量。
快速而有預(yù)期地
Kubernetes在更新升級的時候支持滾動升級、藍(lán)綠發(fā)布等機制;同時配合Istio服務(wù)網(wǎng)格還能夠?qū)崿F(xiàn)A/B測試,根據(jù)發(fā)布者的需求進(jìn)行應(yīng)用發(fā)布。
急速的擴(kuò)展
Kubernetes內(nèi)部有完善的服務(wù)注冊發(fā)現(xiàn)機制,當(dāng)某個服務(wù)的實例增加時,kubernetes會自動將其加入服務(wù)列表中,免除在傳統(tǒng)運維中需要人工維護(hù)服務(wù)列表的問題。
對接新應(yīng)用
kubernetes是一個通用的容器編排框架,支持不同類型的語言,或者是語言無關(guān)的,新增加的應(yīng)用都會以一個新的對象進(jìn)行接入。
節(jié)省并優(yōu)化硬件資源
kubernetes在部署應(yīng)用時會自動檢查各個服務(wù)器的cpu與內(nèi)存使用量,同時會根據(jù)服務(wù)申請的cpu與內(nèi)存資源,將服務(wù)部署到最合適的服務(wù)器。
因kubernetes名字過長,一般簡稱為k8s,因為k與s之間有8個字母,故而稱之。
誕生原因
通過之前的章節(jié)我們了解到:一個正在運行的 Linux 容器,其實可以被“一分為二,動靜分離”地看待:
一組聯(lián)合掛載在 /var/lib/docker/aufs/mnt 上的 rootfs,這一部分我們稱為“容器鏡像”(Container Image),是容器的靜態(tài)視圖;
一個由 Namespace+Cgroups 構(gòu)成的隔離環(huán)境,這一部分我們稱為“容器運行時”(Container Runtime),是容器的動態(tài)視圖。
從一個開發(fā)者和單一的容器鏡像,到無數(shù)開發(fā)者和龐大的容器集群,容器技術(shù)實現(xiàn)了從“容器”到“容器云”的飛躍,標(biāo)志著它真正得到了市場和生態(tài)的認(rèn)可。
這其中,最具代表性的容器編排工具,當(dāng)屬 Docker 公司的 Compose+Swarm 組合,以及 Google 與 RedHat 公司共同主導(dǎo)的 Kubernetes 項目。
k8s整體架構(gòu)
Kubernetes主要由以下幾個核心組件組成:
- etcd保存了整個集群的狀態(tài);
- apiserver提供了資源操作的唯一入口,并提供認(rèn)證、授權(quán)、訪問控制、API注冊和發(fā)現(xiàn)等機制;
- controller manager負(fù)責(zé)維護(hù)集群的狀態(tài),比如故障檢測、自動擴(kuò)展、滾動更新等;
- scheduler負(fù)責(zé)資源的調(diào)度,按照預(yù)定的調(diào)度策略將Pod調(diào)度到相應(yīng)的機器上;
- kubelet負(fù)責(zé)維護(hù)容器的生命周期,同時也負(fù)責(zé)Volume(CVI)和網(wǎng)絡(luò)(CNI)的管理;
- Container runtime負(fù)責(zé)鏡像管理以及Pod和容器的真正運行(CRI);
- kube-proxy負(fù)責(zé)為Service提供cluster內(nèi)部的服務(wù)發(fā)現(xiàn)和負(fù)載均衡;
除了核心組件,還有一些推薦的Add-ons:
- kube-dns負(fù)責(zé)為整個集群提供DNS服務(wù)
- Ingress Controller為服務(wù)提供外網(wǎng)入口
- Heapster提供資源監(jiān)控
- Dashboard提供GUI
- Federation提供跨可用區(qū)的集群
- Fluentd-elasticsearch提供集群日志采集、存儲與查詢
基于docker的流程
基于k8s的流程
master節(jié)點(控制節(jié)點)
master節(jié)點由三個緊密協(xié)作的獨立組件組合而成,它們分別是:
- 負(fù)責(zé) API 服務(wù)的 kube-apiserver
- 負(fù)責(zé)調(diào)度的 kube-scheduler
- 負(fù)責(zé)容器編排的 kube-controller-manager。
整個集群的持久化數(shù)據(jù),則由 kube-apiserver 處理后保存在 Etcd 中。
node節(jié)點(計算節(jié)點)
node節(jié)點上最核心的部分,則是一個叫作 kubelet 的組件。
kubelet 一方面負(fù)責(zé)同Docker打交道,另一方面負(fù)責(zé)調(diào)用網(wǎng)絡(luò)插件和存儲插件為容器配置網(wǎng)絡(luò)和持久化存儲。
k8s設(shè)計理念
所以,Kubernetes 項目最主要的設(shè)計思想是,從更宏觀的角度,以統(tǒng)一的方式來定義任務(wù)之間的各種關(guān)系,并且為將來支持更多種類的關(guān)系留有余地。
比如,Kubernetes 項目對容器間的“訪問”進(jìn)行了分類,首先總結(jié)出了一類非常常見的“緊密交互”的關(guān)系,即:這些應(yīng)用之間需要非常頻繁的交互和訪問;又或者,它們會直接通過本地文件進(jìn)行信息交換。
在常規(guī)環(huán)境下,這些應(yīng)用往往會被直接部署在同一臺機器上,通過 Localhost 通信,通過本地磁盤目錄交換文件。而在 Kubernetes 項目中,這些容器則會被劃分為一個“Pod”,Pod 里的容器共享同一個 Network Namespace、同一組數(shù)據(jù)卷,從而達(dá)到高效率交換信息的目的。
而對于另外一種更為常見的需求,比如 Web 應(yīng)用與數(shù)據(jù)庫之間的訪問關(guān)系,Kubernetes 項目則提供了一種叫作“Service”的服務(wù)。像這樣的兩個應(yīng)用,往往故意不部署在同一臺機器上,這樣即使 Web 應(yīng)用所在的機器宕機了,數(shù)據(jù)庫也完全不受影響??墒?,我們知道,對于一個容器來說,它的 IP 地址等信息不是固定的,那么 Web 應(yīng)用又怎么找到數(shù)據(jù)庫容器的 Pod 呢?
所以,Kubernetes 項目的做法是給 Pod 綁定一個 Service 服務(wù),而 Service 服務(wù)聲明的 IP 地址等信息是“終生不變”的。這個Service 服務(wù)的主要作用,就是作為 Pod 的代理入口(Portal),從而代替 Pod 對外暴露一個固定的網(wǎng)絡(luò)地址。
這樣,對于 Web 應(yīng)用的 Pod 來說,它需要關(guān)心的就是數(shù)據(jù)庫 Pod 的 Service 信息。不難想象,Service 后端真正代理的 Pod 的 IP 地址、端口等信息的自動更新、維護(hù),則是 Kubernetes 項目的職責(zé)。
像這樣,圍繞著容器和 Pod 不斷向真實的技術(shù)場景擴(kuò)展,我們就能夠摸索出一幅如下所示的 Kubernetes 項目核心功能的“全景圖”。
Kubernetes 項目如何啟動一個容器化任務(wù)呢?
比如,我現(xiàn)在已經(jīng)制作好了一個 Nginx 容器鏡像,希望讓平臺幫我啟動這個鏡像。并且,我要求平臺幫我運行兩個完全相同的 Nginx 副本,以負(fù)載均衡的方式共同對外提供服務(wù)。
如果沒有 Kubernetes 的話,可能需要啟動兩臺虛擬機,分別安裝兩個 Nginx,然后使用一個類lb應(yīng)用為這兩個虛擬機做一個虛擬 IP。
而如果使用 Kubernetes 項目呢?你需要做的則是編寫如下這樣一個 YAML 文件(比如名叫 nginx-deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
在上面這個 YAML 文件中,我們定義了一個 Deployment 對象,它的主體部分(spec.template 部分)是一個使用 Nginx 鏡像的 Pod,而這個 Pod 的副本數(shù)是 2(replicas=2)。
kubectl create -f nginx-deployment.yaml
搭建k8s集群
- kubeadm
- minikube
- kops
- tectonic
- play-with-k8s.com