初步認識 k8s

GetaChan發表於2020-04-08

本文參考 Kubernetes 指南

初步認識

使用Kubernetes能做什麼?

可以在物理或虛擬機器的Kubernetes叢集上執行容器化應用,Kubernetes能提供一個以“容器為中心的基礎架構”,滿足在生產環境中執行應用的一些常見需求,如:

  • 多個程式(作為容器執行)協同工作。(Pod)
  • 儲存系統掛載
  • Distributing secrets
  • 應用健康檢測
  • 應用例項的複製
  • Pod自動伸縮/擴充套件
  • Naming and discovering
  • 負載均衡
  • 滾動更新
  • 資源監控
  • 日誌訪問
  • 除錯應用程式
  • 提供認證和授權

容器優勢總結:

  • 快速建立/部署應用:與VM虛擬機器相比,容器映象的建立更加容易。
  • 持續開發、整合和部署:提供可靠且頻繁的容器映象構建/部署,並使用快速和簡單的回滾(由於映象不可變性)。
  • 開發和執行相分離:在build或者release階段建立容器映象,使得應用和基礎設施解耦。
  • 開發,測試和生產環境一致性:在本地或外網(生產環境)執行的一致性。
  • 雲平臺或其他作業系統:可以在 Ubuntu、RHEL、 CoreOS、on-prem、Google Container Engine或其它任何環境中執行。
  • Loosely coupled,分散式,彈性,微服務化:應用程式分為更小的、獨立的部件,可以動態部署和管理。
  • 資源隔離
  • 資源利用:更高效

核心元件

Kubernetes 主要由以下幾個核心元件組成:

  • etcd 儲存了整個叢集的狀態;
  • apiserver 提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API 註冊和發現等機制;
  • controller manager 負責維護叢集的狀態,比如故障檢測、自動擴充套件、滾動更新等;
  • scheduler 負責資源的排程,按照預定的排程策略將 Pod 排程到相應的機器上;
  • kubelet 負責維護容器的生命週期,同時也負責 Volume(CVI)和網路(CNI)的管理;
  • Container runtime 負責映象管理以及 Pod 和容器的真正執行(CRI);
  • kube-proxy 負責為 Service 提供 cluster 內部的服務發現和負載均衡

Etcd

Etcd 是 CoreOS 基於 Raft 開發的分散式 key-value 儲存,可用於服務發現、共享配置以及一致性保障(如資料庫選主、分散式鎖等)。

主要功能

  • 基本的 key-value 儲存
  • 監聽機制
  • key 的過期及續約機制,用於監控和服務發現
  • 原子 CAS 和 CAD,用於分散式鎖和 leader 選舉

kube-apiserver

kube-apiserver 是 Kubernetes 最重要的核心元件之一,主要提供以下的功能

  • 提供叢集管理的 REST API 介面,包括認證授權、資料校驗以及叢集狀態變更等
  • 提供其他模組之間的資料互動和通訊的樞紐(其他模組通過 API Server 查詢或修改資料,只有 API Server 才直接操作 etcd)

kube-scheduler

kube-scheduler 負責分配排程 Pod 到叢集內的節點上,它監聽 kube-apiserver,查詢還未分配 Node 的 Pod,然後根據排程策略為這些 Pod 分配節點(更新 Pod 的 NodeName 欄位)。

排程器需要充分考慮諸多的因素:

  • 公平排程
  • 資源高效利用
  • QoS
  • affinity 和 anti-affinity
  • 資料本地化(data locality)
  • 內部負載干擾(inter-workload interference)
  • deadlines

kube-controller-manager

Controller Manager 由 kube-controller-manager 和 cloud-controller-manager 組成,是 Kubernetes 的大腦,它通過 apiserver 監控整個叢集的狀態,並確保叢集處於預期的工作狀態。

kube-controller-manager 由一系列的控制器組成:

  • Replication Controller
  • Node Controller
  • CronJob Controller
  • Daemon Controller
  • Deployment Controller
  • Endpoint Controller
  • Garbage Collector
  • Namespace Controller
  • Job Controller
  • Pod AutoScaler
  • RelicaSet
  • Service Controller
  • ServiceAccount Controller
  • StatefulSet Controller
  • Volume Controller
  • Resource quota Controller

cloud-controller-manager 在 Kubernetes 啟用 Cloud Provider 的時候才需要,用來配合雲服務提供商的控制,也包括一系列的控制器,如

  • Node Controller
  • Route Controller
  • Service Controller

從 v1.6 開始,cloud provider 已經經歷了幾次重大重構,以便在不修改 Kubernetes 核心程式碼的同時構建自定義的雲服務商支援。

Kubelet

每個Node節點上都執行一個 Kubelet 服務程式,預設監聽 10250 埠,接收並執行 Master 發來的指令,管理 Pod 及 Pod 中的容器。每個 Kubelet 程式會在 API Server 上註冊所在Node節點的資訊,定期向 Master 節點彙報該節點的資源使用情況,並通過 cAdvisor 監控節點和容器的資源。

kube-proxy

每臺機器上都執行一個 kube-proxy 服務,它監聽 API server 中 service 和 endpoint 的變化情況,並通過 iptables 等來為服務配置負載均衡(僅支援 TCP 和 UDP)。

kube-proxy 可以直接執行在物理機上,也可以以 static pod 或者 daemonset 的方式執行。

kube-proxy 當前支援以下幾種實現

  • userspace:最早的負載均衡方案,它在使用者空間監聽一個埠,所有服務通過 iptables 轉發到這個埠,然後在其內部負載均衡到實際的 Pod。該方式最主要的問題是效率低,有明顯的效能瓶頸。
  • iptables:目前推薦的方案,完全以 iptables 規則的方式來實現 service 負載均衡。該方式最主要的問題是在服務多的時候產生太多的 iptables 規則,非增量式更新會引入一定的時延,大規模情況下有明顯的效能問題
  • ipvs:為解決 iptables 模式的效能問題,v1.11 新增了 ipvs 模式(v1.8 開始支援測試版,並在 v1.11 GA),採用增量式更新,並可以保證 service 更新期間連線保持不斷開
  • winuserspace:同 userspace,但僅工作在 windows 節點上

注意:使用 ipvs 模式時,需要預先在每臺 Node 上載入核心模組 nf_conntrack_ipv4, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh 等。

kube-dns

DNS 是 Kubernetes 的核心功能之一,通過 kube-dnsCoreDNS 作為叢集的必備擴充套件來提供命名服務。

從 v1.11 開始可以使用 CoreDNS 來提供命名服務,並從 v1.13 開始成為預設 DNS 服務。CoreDNS 的特點是效率更高,資源佔用率更小,推薦使用 CoreDNS 替代 kube-dns 為叢集提供 DNS 服務。

kube-dns 工作原理

如下圖所示,kube-dns 由三個容器構成:

  • kube-dns:DNS 服務的核心元件,主要由 KubeDNS 和 SkyDNS 組成
    • KubeDNS 負責監聽 Service 和 Endpoint 的變化情況,並將相關的資訊更新到 SkyDNS 中
    • SkyDNS 負責 DNS 解析,監聽在 10053 埠 (tcp/udp),同時也監聽在 10055 埠提供 metrics
    • kube-dns 還監聽了 8081 埠,以供健康檢查使用
  • dnsmasq-nanny:負責啟動 dnsmasq,並在配置發生變化時重啟 dnsmasq
    • dnsmasq 的 upstream 為 SkyDNS,即叢集內部的 DNS 解析由 SkyDNS 負責
  • sidecar:負責健康檢查和提供 DNS metrics(監聽在 10054 埠)

Federation

在雲端計算環境中,服務的作用距離範圍從近到遠一般可以有:同主機(Host,Node)、跨主機同可用區(Available Zone)、跨可用區同地區(Region)、跨地區同服務商(Cloud Service Provider)、跨雲平臺。K8s 的設計定位是單一叢集在同一個地域內,因為同一個地區的網路效能才能滿足 K8s 的排程和計算儲存連線要求。而叢集聯邦(Federation)就是為提供跨 Region 跨服務商 K8s 叢集服務而設計的。

每個 Federation 有自己的分散式儲存、API Server 和 Controller Manager。使用者可以通過 Federation 的 API Server 註冊該 Federation 的成員 K8s Cluster。當使用者通過 Federation 的 API Server 建立、更改 API 物件時,Federation API Server 會在自己所有註冊的子 K8s Cluster 都建立一份對應的 API 物件。在提供業務請求服務時,K8s Federation 會先在自己的各個子 Cluster 之間做負載均衡,而對於傳送到某個具體 K8s Cluster 的業務請求,會依照這個 K8s Cluster 獨立提供服務時一樣的排程模式去做 K8s Cluster 內部的負載均衡。而 Cluster 之間的負載均衡是通過域名服務的負載均衡來實現的。

所有的設計都儘量不影響 K8s Cluster 現有的工作機制,這樣對於每個子 K8s 叢集來說,並不需要更外層的有一個 K8s Federation,也就是意味著所有現有的 K8s 程式碼和機制不需要因為 Federation 功能有任何變化。

Federation 主要包括三個元件

  • federation-apiserver:類似 kube-apiserver,但提供的是跨叢集的 REST API
  • federation-controller-manager:類似 kube-controller-manager,但提供多叢集狀態的同步機制
  • kubefed:Federation 管理命令列工具

Federation 的程式碼維護在 https://github.com/kubernetes/federation

kubeadm

kubeadm 是 Kubernetes 主推的部署工具之一,正在快速迭代開發中。

初始化系統

所有機器都需要初始化容器執行引擎(如 docker 或 frakti 等)和 kubelet。這是因為 kubeadm 依賴 kubelet 來啟動 Master 元件,比如 kube-apiserver、kube-manager-controller、kube-scheduler、kube-proxy 等。

hyperkube

hyperkube是Kubernetes的allinone binary,可以用來啟動多種kubernetes服務,常用在Docker映象中。每個Kubernetes釋出都會同時釋出一個包含hyperkube的docker映象,如gcr.io/google_containers/hyperkube:v1.6.4

hyperkube支援的子命令包括

  • kubelet
  • apiserver
  • controller-manager
  • federation-apiserver
  • federation-controller-manager
  • kubectl
  • proxy
  • scheduler

kubectl

kubectl 是 Kubernetes 的命令列工具(CLI),是 Kubernetes 使用者和管理員必備的管理工具。

kubectl 提供了大量的子命令,方便管理 Kubernetes 叢集中的各種功能。這裡不再羅列各種子命令的格式,而是介紹下如何查詢命令的幫助

  • kubectl -h 檢視子命令列表
  • kubectl options 檢視全域性選項
  • kubectl <command> --help 檢視子命令的幫助
  • kubectl [command] [PARAMS] -o=<format> 設定輸出格式(如 json、yaml、jsonpath 等)
  • kubectl explain [RESOURCE] 檢視資源的定義
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章