kubernetes 入門與實踐
1. kubernetes/K8S 是什么?
Kubernetes 是一個可移植、可擴展的、開源的容器管理平台,可以對容器進行自動化部署、自動化擴縮容、跨主機管理等,簡稱 K8S。K8S 提供了應用程序的升級和回滾的能力,可以對代碼進行灰度發布、金絲雀發布、藍綠發布、滾動更新等。提供了一套完整的監控系統和日志收集平台,具有故障自恢復的能力。利用 service 可以實現服務注冊、發現和四層負載均衡,利用 ingress 可以實現七層負載均衡,通過coredns 可實現域名解析等。K8S 支持在多種平台部署,可在私有雲,公有雲,混合雲,openstack、openshift、VMware vSphere,VMware workstation,物理機、雲主機等環境部署。
docker 官方 logo:
kubernetes 官方 logo:
它是一個舵,舵是輪船的方向盤,船在大海里航行就要靠舵來掌控方向,Docker 是集裝箱,可以把雜亂的貨物整理歸類,那 kubernetes 就是運送集裝箱的船的方向盤,所以叫做舵。
2. kubernetes 起源和發展前景
Kubernetes 單詞起源於希臘語, 是“舵手”或者“領航員、飛行員”的意思。
來源於 Google 的 Borg 項目:
Borg 是谷歌內部的一個容器編排工具,谷歌業務 90%以上都在 Borg 上運行,Borg 在谷歌內部已經使用了大概 15 年。 K8S 是在 Borg 的基礎上開發出來的輕量級容器編排工具。K8S 的根基非常牢固,得益於 Borg 過去十數年間積累的經驗和教訓,是站在巨人的肩膀上發展起來的項目。開源之后,迅速稱霸容器編排技術領域。
Kubernetes 的發展狀況:
京東:
2016 年底,京東業務開始從 OpenStack 切換到 Kubernetes,第一階段遷移 20%的業務到kubernetes,集群規模是 500+物理節點,2w+Pod 容器。
2020 年,京東實現 90%的業務切換到 kubernetes,集群規模達到上萬個節點,百萬 Pod 容器阿里巴巴:管理幾十個 K8S 集群,其中最大的集群約 1 萬個節點,每個集群會運行幾十萬個應用,api 的 QPS 達到1000 萬+。
kubernetes 發展歷史:
- 2014.6
谷歌雲計算專家埃里克·布魯爾(Eric Brewer)在舊金山的發布會宣布開源 kubernetes,它由 Joe Beda、 Brendan Burns 以及 Craig McLuckie 帶頭創建,之后華為、微軟、redhat 等公司紛紛引入 kubernetes。 - 2014.9
Kubernetes 開始內測,發布第一個測試版本 0.2. - 2015.7
Kubernetes 開始正式對外使用,發布第一個正式版本 1.0。 4. 2016.12
發布 1.5 版本。 - 2017.10
Docker 官方宣布支持 Kubernetes。這標志着 kubernetes 將成為容器編排領域的大佬。 - 2018 年
2018.3 發布 1.10 版本,CNCF 宣布 Kubernetes 正式畢業 - 2019 年
2019.3 發布 1.14 版本 - 2020 年
2020.8 發布 1.19 版本
2020.12 發布 1.20 版本,宣布不在支持 docker,由於 Docker 鏡像遵循開放容器倡議(OCI)鏡像規范,所以 Docker 產生的鏡像能在所有 CRI (容器運行時接口標准)兼容運行時的集群中正常使用。也就是說 docker+k8s 這套還可以繼續用,不需要過度擔心。
目前大約是每 100 天更新一次版本,更新速度相當快。常見的容器編排工具: - docker-compose:單機環境下管理 docker
- Docker Swarm:
docker 自己的容器編排工具,可以管理 docker 集群 - Apache Mesos and Marathon:
Mesos 是一個數據中心的資源統一管控的工具,本身沒有編排容器的功能,需要和 Marathon 結合使用。后來 Apache Mesos 自己說不但支持 Marathon 也支持 Kubernetes,且當時 docker 也說不但原生支持 docker swarm 也支持 k8s,k8s 的地位已經顯而易見了。
3. kubernetes 特性
自我修復彈性伸縮
自動部署和回滾
服務發現和負載均衡機密和配置管理
存儲編排批處理
4. kubernetes 架構
先看下 Borg 項目的架構:
k8s 的物理架構是 master/node 模式:
K8S 集群至少需要一個主節點(Master)和多個工作節點(Worker)單 master 節點架構圖如下:
Master 節點是集群的控制節點,負責整個集群的管理和控制,主節點主要用於暴露 API,調度部署和節點的管理。工作節點主要是運行容器的。
5. kubernetes 架構詳細拆分-組件介紹
kubectl:管理 k8s 的命令行工具,可以操作 k8s 中的資源對象。
etcd: 是一個高可用的鍵值數據庫,存儲 k8s 的資源狀態信息和網絡信息的,etcd 中的數據變更是通過
api server 進行的。
apiserver: 提供 k8s api,是整個系統的對外接口,提供資源操作的唯一入口,供客戶端和其它組件調用,提供了 k8s 各類資源對象(pod,deployment,Service 等)的增刪改查,是整個系統的數據總線和數據中心,並提供認證、授權、訪問控制、API 注冊和發現等機制,並將操作對象持久化到 etcd 中。相當於“營業廳”。
scheduler:負責 k8s 集群中 pod 的調度的 , scheduler 通過與 apiserver 交互監聽到創建 Pod 副本的信息后,它會檢索所有符合該 Pod 要求的工作節點列表,開始執行 Pod 調度邏輯。調度成功后將 Pod綁定到目標節點上,相當於“調度室”。
controller-manager:與 apiserver 交互,實時監控和維護 k8s 集群的控制器的健康情況,對有故障的進行處理和恢復,相當於“大總管”。
kubelet: 每個 Node 節點上的 kubelet 定期就會調用 API Server 的 REST 接口報告自身狀態,API
Server 接收這些信息后,將節點狀態信息更新到 etcd 中。kubelet 也通過API Server 監聽 Pod 信息,從而對 Node 機器上的 POD 進行管理,如創建、刪除、更新 Pod
kube-proxy:提供網絡代理和負載均衡,是實現 service 的通信與負載均衡機制的重要組件,kube-
proxy 負責為 Pod 創建代理服務,從 apiserver 獲取所有 service 信息,並根據 service 信息創建代理服務,實現 service 到 Pod 的請求路由和轉發,從而實現 K8s 層級的虛擬轉發網絡,將到 service 的請求轉發到后端的 pod 上。
多 master 節點高可用架構圖如下:
6. kubernets 中的資源對象
6.1 Pod
1.1 Pod是什么?
官方文檔:https://kubernetes.io/docs/concepts/workloads/pods/
Pod是Kubernetes中的最小調度單元,k8s是通過定義一個Pod的資源,然后在Pod里面運行容器,容器需要指定一個鏡像,這樣就可以用來運行具體的服務。一個Pod封裝一個容器(也可以封裝多個容器),Pod里的容器共享存儲、網絡等。也就是說,應該把整個pod看作虛擬機,然后每個容器相當於運行在虛擬機的進程。
Pod是需要調度到k8s集群的工作節點來運行的,具體調度到哪個節點,是根據scheduler調度器實現的。
白話解釋:
可以把pod看成是一個“豌豆莢”,里面有很多“豆子”(容器)。一個豌豆莢里的豆子,它們吸收着共同的營養成分、肥料、水分等,Pod和容器的關系也是一樣,Pod里面的容器共享pod的網絡、存儲等。
pod相當於一個邏輯主機--比方說我們想要部署一個tomcat應用,如果不用容器,我們可能會部署到物理機、虛擬機或者雲主機上,那么出現k8s之后,我們就可以定義一個pod資源,在pod里定義一個把tomcat容器,所以pod充當的是一個邏輯主機的角色。
1.1.1 Pod如何管理多個容器?
Pod中可以同時運行多個容器。同一個Pod中的容器會自動的分配到同一個 node 上。同一個Pod中的容器共享資源、網絡環境,它們總是被同時調度,在一個Pod中同時運行多個容器是一種比較高級的用法,只有當你的容器需要緊密配合協作的時候才考慮用這種模式。例如,你有一個容器作為web服務器運行,需要用到共享的volume,有另一個“sidecar”容器來從遠端獲取資源更新這些文件。
一些Pod有init容器和應用容器。 在應用程序容器啟動之前,運行初始化容器。
1.1.2 Pod網絡
Pod是有IP地址的,每個pod都被分配唯一的IP地址(IP地址是靠網絡插件calico、flannel、weave等分配的),POD中的容器共享網絡名稱空間,包括IP地址和網絡端口。 Pod內部的容器可以使用localhost相互通信。 Pod中的容器也可以通過網絡插件calico與其他節點的Pod通信。
1.1.3 Pod存儲
創建Pod的時候可以指定掛載的存儲卷。 POD中的所有容器都可以訪問共享卷,允許這些容器共享數據。 Pod只要掛載持久化數據卷,Pod重啟之后數據還是會存在的。
1.2 Pod工作方式
在K8s中,所有的資源都可以使用一個yaml文件來創建,創建Pod也可以使用yaml配置文件。或者使用kubectl run在命令行創建Pod(不常用)。
1.2.1 自主式Pod
所謂的自主式Pod,就是直接定義一個Pod資源,如下:
[root@xianchaomaster1 ~]# vim pod-tomcat.yaml
apiVersion: v1
kind: Pod
metadata:
name: tomcat-test
namespace: default
labels:
app: tomcat
spec:
containers:
- name: tomcat-java
ports:
- containerPort: 8080
image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
Pause 容器
每個 pod 中都存在一個 pause 容器。Pod 中除了 Pause 之外的其他容器可以稱之為業務容器。
pause 容器主要為每個業務容器提供以下功能:
PID 命名空間:Pod 中的不同應用程序可以看到其他應用程序的進程 ID。網絡命名空間:Pod 中的多個容器能夠訪問同一個 IP 和端口范圍。
IPC 命名空間:Pod 中的多個容器能夠使用 SystemV IPC 或 POSIX 消息隊列進行通信。
UTS 命名空間:Pod 中的多個容器共享一個主機名和 Volumes(共享存儲卷)。
6.2 label
label 是標簽的意思,k8s 中的資源對象大都可以打上標簽,如 Node、Pod、Service 等,一個資源可以綁定任意多個 label,k8s 通過 Label 可實現多維度的資源分組管理,后續可通過 Label Selector 查詢和篩選擁有某些 Label 的資源對象,例如創建一個 Pod,給定一個 Label 是 app=tomcat,那么service 可以通過 label selector 選擇擁有 app=tomcat 的 pod,和其相關聯,也可通過 app=tomcat刪除擁有該標簽的 Pod 資源。
6.3 Replicaset
Kubernetes 中的副本控制器,管理Pod,使 pod 副本的數量始終維持在預設的個數。
6.4 Deployment
管理Replicaset 和Pod 的副本控制器,Deployment 可以管理多個Replicaset,是比 Replicaset更高級的控制器,也即是說在創建 Deployment 的時候,會自動創建 Replicaset,由 Replicaset再創建 Pod,Deployment 能對Pod 擴容、縮容、滾動更新和回滾、維持 Pod 數量。
6.5 Service
在 kubernetes 中,Pod 是有生命周期的,如果 Pod 重啟 IP 很有可能會發生變化。如果我們的服務都是將 Pod 的 IP 地址寫死,Pod 的掛掉或者重啟,和剛才重啟的 pod 相關聯的其他服務將會找不到它所關聯的 Pod,為了解決這個問題,在 kubernetes 中定義了 service 資源對象,Service 定義了一個服務訪問的入口,客戶端通過這個入口即可訪問服務背后的應用集群實例,service 是一組 Pod 的邏輯集合,這一組 Pod 能夠被 Service 訪問到,通常是通過 Label Selector 實現的。
可以看下面的圖:
6.6 Coredns
在 k8s 中,coredns 會監聽 3 類 k8s 資源,分別是 Service、StatefulSet 和 Pod,並會為這三類資源自動創建(更新/刪除)相應的域名記錄,k8s 中各服務間可以直接通過服務域名的方式進行通信。
6.7 kube-proxy
部署在每個 Node 節點上,它是實現 Kubernetes Service 的通信與負載均衡機制的重要組件, kube- proxy 負責為 Pod 創建代理服務,從 apiserver 獲取所有 server 信息,並根據 service 信息創建代理服務,實現 server 到 Pod 的請求路由和轉發,從而實現 K8s 層級的虛擬轉發網絡。