一個目標:容器操作;兩地三中心;四層服務發現;五種 Pod 共享資源;六個 CNI 常用插件;七層負載均衡;八種隔離維度;九個網絡模型原則;十類 IP 地址;百級產品線;千級物理機;萬級容器;相如無億,k8s 有億:億級日服務人次。
一個目標:容器操作
Kubernetes(k8s)是自動化容器操作的開源平臺。這些容器操作包括:部署、調度和節點集群間擴展。
具體功能:
自動化容器部署和復制。
實時彈性收縮容器規模。
容器編排成組,并提供容器間的負載均衡。
調度:容器在哪個機器上運行。
組成:
kubectl:客戶端命令行工具,作為整個系統的操作入口。
kube-apiserver:以 REST API 服務形式提供接口,作為整個系統的控制入口。
kube-controller-manager:執行整個系統的后臺任務,包括節點狀態狀況、Pod 個數、Pods 和Service 的關聯等。
kube-scheduler:負責節點資源管理,接收來自 kube-apiserver 創建 Pods 任務,并分配到某個節點。
etcd:負責節點間的服務發現和配置共享。
kube-proxy:運行在每個計算節點上,負責 Pod 網絡代理。定時從 etcd 獲取到 service 信息來做相應的策略。
kubelet:運行在每個計算節點上,作為 agent,接收分配該節點的 Pods 任務及管理容器,周期性獲取容器狀態,反饋給 kube-apiserver。
DNS:一個可選的 DNS 服務,用于為每個 Service 對象創建 DNS 記錄,這樣所有的 Pod 就可以通過 DNS 訪問服務了。
下面是 k8s 的架構拓撲圖:
兩地三中心
兩地三中心包括本地生產中心、本地災備中心、異地災備中心。
兩地三中心要解決的一個重要問題就是數據一致性問題。
k8s 使用 etcd 組件作為一個高可用、強一致性的服務發現存儲倉庫。用于配置共享和服務發現。
它作為一個受到 Zookeeper 和 doozer 啟發而催生的項目。除了擁有他們的所有功能之外,還擁有以下 4 個特點:
四層服務發現
先一張圖解釋一下網絡七層協議:
k8s 提供了兩種方式進行服務發現:
環境變量:當創建一個 Pod 的時候,kubelet 會在該 Pod 中注入集群內所有 Service 的相關環境變量。需要注意的是,要想一個 Pod 中注入某個 Service 的環境變量,則必須 Service 要先比該 Pod 創建。這一點,幾乎使得這種方式進行服務發現不可用。
比如,一個 ServiceName 為 redis-master 的 Service,對應的 ClusterIP:Port 為 10.0.0.11:6379,則對應的環境變量為:
DNS:可以通過 cluster add-on 的方式輕松的創建 KubeDNS 來對集群內的 Service 進行服務發現。
以上兩種方式,一個是基于 TCP,DNS 基于 UDP,它們都是建立在四層協議之上。
五種 Pod 共享資源
Pod 是 k8s 最基本的操作單元,包含一個或多個緊密相關的容器。
一個 Pod 可以被一個容器化的環境看作應用層的“邏輯宿主機”;一個 Pod 中的多個容器應用通常是緊密耦合的,Pod 在 Node 上被創建、啟動或者銷毀;每個 Pod 里運行著一個特殊的被稱之為 Volume 掛載卷,因此他們之間通信和數據交換更為高效。在設計時我們可以充分利用這一特性將一組密切相關的服務進程放入同一個 Pod 中。
同一個 Pod 里的容器之間僅需通過 localhost 就能互相通信。
一個 Pod 中的應用容器共享五種資源:
PID 命名空間:Pod 中的不同應用程序可以看到其他應用程序的進程 ID。
網絡命名空間:Pod 中的多個容器能夠訪問同一個IP和端口范圍。
IPC 命名空間:Pod 中的多個容器能夠使用 SystemV IPC 或 POSIX 消息隊列進行通信。
UTS 命名空間:Pod 中的多個容器共享一個主機名。
Volumes(共享存儲卷):Pod 中的各個容器可以訪問在 Pod 級別定義的 Volumes。
Pod 的生命周期通過 Replication Controller 來管理;通過模板進行定義,然后分配到一個 Node 上運行,在 Pod 所包含容器運行結束后,Pod 結束。
Kubernetes 為 Pod 設計了一套獨特的網絡配置,包括為每個 Pod 分配一個IP地址,使用 Pod 名作為容器間通信的主機名等。在公眾號頂級架構師回復“架構整潔”,獲取驚喜禮包。
六個 CNI 常用插件
CNI(Container Network Interface)容器網絡接口是 Linux 容器網絡配置的一組標準和庫,用戶需要根據這些標準和庫來開發自己的容器網絡插件。CNI 只專注解決容器網絡連接和容器銷毀時的資源釋放,提供一套框架。所以 CNI 可以支持大量不同的網絡模式,并且容易實現。
下面用一張圖表示六個 CNI 常用插件:
七層負載均衡
提負載均衡就不得不先提服務器之間的通信。
IDC(Internet Data Center)也可稱數據中心、機房,用來放置服務器。IDC 網絡是服務器間通信的橋梁。
上圖里畫了很多網絡設備,它們都是干啥用的呢?
路由器、交換機、MGW/NAT 都是網絡設備,按照性能、內外網劃分不同的角色。
內網接入交換機:也稱為 TOR(top of rack),是服務器接入網絡的設備。每臺內網接入交換機下聯 40-48 臺服務器,使用一個掩碼為 /24 的網段作為服務器內網網段。
內網核心交換機:負責 IDC 內各內網接入交換機的流量轉發及跨 IDC 流量轉發。
MGW/NAT:MGW 即 LVS 用來做負載均衡,NAT 用于內網設備訪問外網時做地址轉換。
外網核心路由器:通過靜態互聯運營商或 BGP 互聯美團統一外網平臺。
先說說各層負載均衡:
這里用一張圖來說說四層和七層負載均衡的區別:
上面四層服務發現講的主要是 k8s 原生的 kube-proxy 方式。k8s 關于服務的暴露主要是通過 NodePort 方式,通過綁定 minion 主機的某個端口,然后進行 Pod 的請求轉發和負載均衡,但這種方式有下面的缺陷:
理想的方式是通過一個外部的負載均衡器,綁定固定的端口,比如 80;然后根據域名或者服務名向后面的 Service IP 轉發。
Nginx 很好的解決了這個需求,但問題是如果有的新的服務加入,如何去修改并且加載這些Nginx 配置?
Kubernetes 給出的方案就是 Ingress。這是一個基于七層的方案。
八種隔離維度
k8s 集群調度這邊需要對上面從上到下、從粗粒度到細粒度的隔離做相應的調度策略。
九個網絡模型原則
k8s 網絡模型要符合四個基礎原則、三個網絡要求原則、一個架構原則、一個 IP 原則。
每個 Pod 都擁有一個獨立的 IP 地址,而且假定所有 Pod 都在一個可以直接連通的、扁平的網絡空間中,不管是否運行在同一 Node 上都可以通過 Pod 的 IP 來訪問。
k8s 中的 Pod 的 IP 是最小粒度 IP。同一個 Pod 內所有的容器共享一個網絡堆棧,該模型稱為 IP-per-Pod 模型。
IP-per-Pod 模型從端口分配、域名解析、服務發現、負載均衡、應用配置等角度看,Pod 可以看做是一臺獨立的虛擬機或物理機。
要符合下面的架構:
由上圖架構引申出來 IP 概念從集群外部到集群內部:
十類IP地址
大家都知道 IP 地址分為 ABCDE 類,另外還有五類特殊用途的 IP。
第一類
A 類:1.0.0.0-1226.255.255.255,默認子網掩碼/8,即255.0.0.0。
B 類:128.0.0.0-191.255.255.255,默認子網掩碼/16,即255.255.0.0。
C 類:192.0.0.0-223.255.255.255,默認子網掩碼/24,即255.255.255.0。
D 類:224.0.0.0-239.255.255.255,一般用于組播。
E 類:240.0.0.0-255.255.255.255(其中255.255.255.255為全網廣播地址)。E 類地址一般用于研究用途。
第二類
0.0.0.0
嚴格來說,0.0.0.0 已經不是一個真正意義上的 IP 地址了。它表示的是這樣一個集合:所有不清楚的主機和目的網絡。這里的不清楚是指在本機的路由表里沒有特定條目指明如何到達。作為缺省路由。
127.0.0.1 本機地址。
第三類
224.0.0.1 組播地址。
如果你的主機開啟了IRDP(internet路由發現,使用組播功能),那么你的主機路由表中應該有這樣一條路由。
第四類
169.254.x.x
使用了 DHCP 功能自動獲取了 IP 的主機,DHCP 服務器發生故障,或響應時間太長而超出了一個系統規定的時間,系統會為你分配這樣一個 IP,代表網絡不能正常運行。
第五類
10.xxx、172.16.x.x~172.31.x.x、192.168.x.x 私有地址。
大量用于企業內部。保留這樣的地址是為了避免亦或是哪個接入公網時引起地址混亂。