Kubernetes基本功能


說明
目前kubernetes的資料介紹很多也很深刻,本文只是做一個針對自己學習k8s過程的介紹,僅僅是學習筆記的記錄。

一、基本使用

1. 命令行

  • 集群信息

  • Namespace 信息

  • Controller 信息

Deployment 控制器

Replicaset 控制器

Statefulset 控制器

Daemonset 控制器

Job 控制器

  • Service

  • Pod

  • 參數

-o wide 查看更多信息,Pod 可以查看到 ip 地址,node 節點。Service 可以查看到選擇器,控制器可以看到鏡像,選擇器等。

--all-namespaces 查看所有 namespace 下的資源

K8s 出錯排查三大步:

kubectl get componentstatus
查看 scheduler/controller-manager/etcd 等組件 Healthy

Kubectl get nodes
查看節點的狀態,判斷是不是有出錯的節點

Kubectl get pod --namespace=kube-system
查看系統命名空間 kube-system 里組件的狀態

2.Dashboard

  • 集群信息

Namespace 所有信息


應用信息

容器信息

副本信息

服務信息

二、架構分析

1. 資源架構

Kubernetes 資源架構圖:

uploading-image-748371.png

資源分析

Cluster

Cluster 是計算、存儲和網絡資源的集合,Kubernetes 利用這些資源運行各種基於容器的應用。

Master

Master 是 Cluster 的大腦,它的主要職責是調度,即決定將應用放在哪里運行。Master 運行 Linux 操作系統,可以是物理機或者虛擬機。為了實現高可用,可以運行多個 Master。

Node

Node 的職責是運行容器應用。Node 由 Master 管理,Node 負責監控並匯報容器的狀態,並根據 Master 的要求管理容器的生命周期。Node 運行在 Linux 操作系統,可以是物理機或者是虛擬機。

Namespace

Namespace 可以將一個物理的 Cluster 邏輯上划分成多個虛擬 Cluster,每個 Cluster 就是一個 Namespace。不同 Namespace 里的資源是完全隔離的。

Controller

Kubernetes 通常不會直接創建 Pod,而是通過 Controller 來管理 Pod 的。Controller 中定義了 Pod 的部署特性,比如有幾個副本,在什么樣的 Node 上運行等。為了滿足不同的業務場景,Kubernetes 提供了多種 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等。
1.Deployment 是最常用的 Controller,Deployment 可以管理 Pod 的多個副本,並確保 Pod 按照期望的狀態運行。
2.ReplicaSet 實現了 Pod 的多副本管理。使用 Deployment 時會自動創建 ReplicaSet,也就是說 Deployment 是通過 ReplicaSet 來管理 Pod 的多個副本,通常不需要直接使用 ReplicaSet。
3.DaemonSet 用於每個 Node 最多只運行一個 Pod 副本的場景。DaemonSet 通常用於運行守護進程的服務。
4.StatefuleSet 能夠保證 Pod 的每個副本在整個生命周期中名稱是不變的。而其他 Controller 不提供這個功能,當某個 Pod 發生故障需要刪除並重新啟動時,Pod 的名稱會發生變化。同時 StatefuleSet 會保證副本按照固定的順序啟動、更新或者刪除。
5.Job 用於運行結束就刪除的應用。而其他 Controller 中的 Pod 通常是長期持續運行。

Service

Kubernetes Service 定義了外界訪問一組特定 Pod 的方式。Service 有自己的 IP 和端口,為 Pod 的訪問提供了負載均衡。

Pod

Pod 是 Kubernetes 的最小工作單元。每個 Pod 包含一個或多個容器。Kubernetes 管理的也是 Pod 而不是直接管理容器。Pod 中的容器會作為一個整體被 Master 調度到一個 Node 上運行。Pod 的設計理念是支持多個容器在一個 Pod 中共享網絡地址和文件系統,可以通過進程間通信和文件共享這種簡單高效的方式組合完成服務。
Pod 有兩種使用方式:
(1) 運行單一容器。
one-container-per-Pod 是 Kubernetes 最常見的模型,這種情況下,只是將單個容器簡單封裝成 Pod,即便是只有一個容器。
(2) 運行多個容器。
這些容器聯系必須非常緊密,而且需要直接共享資源。

Volume

存儲卷是 Kubernetes 集群中的存儲解決方案,主要用於兩個方面:1. 當 pod 中容器故障重建之后,之前寫入容器的文件丟失;2. 同一個 Pod 中的多個容器之間共享文件。Docker 有存儲卷的概念卷,但 Docker 中存儲卷只是磁盤的或另一個容器中的目錄,並沒有對其生命周期進行管理。Kubernetes 的存儲卷有自己的生命周期,它的生命周期與使用的它 Pod 生命周期一致。因此,相比於在 Pod 中運行的容器來說,存儲卷的存在時間會比的其中的任何容器都長,並且在容器重新啟動時會保留數據。當然,當 Pod 停止存在時,存儲卷也將不再存在。
Kubernetes 支持非常多的存儲卷類型,特別的,支持多種公有雲平台的存儲,包括 AWS,Google 和 Azure 雲;支持多種分布式存儲包括 GlusterFS 和 Ceph;也支持較容易使用的主機本地目錄 hostPath 和 NFS。Kubernetes 還支持使用 Persistent Volume Claim 即 PVC 這種邏輯存儲,使用這種存儲,使得存儲的使用者可以忽略后台的實際存儲技術(例如 AWS,Google 或 GlusterFS 和 Ceph),而將有關存儲實際技術的配置交給存儲管理員通過 Persistent Volume 來配置。
用戶帳戶(User Account)和服務帳戶(Service Account)
用戶帳戶為人提供賬戶標識,而服務賬戶為計算機進程和 Kubernetes 集群中運行的 Pod 提供賬戶標識。用戶帳戶和服務帳戶的一個區別是作用范圍;用戶帳戶對應的是人的身份,人的身份與服務的 namespace 無關,所以用戶賬戶是跨 namespace 的;而服務帳戶對應的是一個運行中程序的身份,與特定 namespace 是相關的。

RBAC 訪問授權

Kubernetes 使用基於角色的訪問控制(Role-based Access Control,RBAC)的授權模式。相對於基於屬性的訪問控制(Attribute-based Access Control,ABAC),RBAC 主要是引入了角色(Role)和角色綁定(RoleBinding)的抽象概念。在 ABAC 中,Kubernetes 集群中的訪問策略只能跟用戶直接關聯;而在 RBAC 中,訪問策略可以跟某個角色關聯,具體的用戶在跟一個或多個角色相關聯。

2. 系統架構

Kubernetes 系統架構圖

在 Master 節點上運行的服務有:

  1. API Server:提供 Restful api。
    apiserver 提供集群管理的 REST API 接口,包括認證授權、數據校驗以及集群狀態變更等。
    只有 API Server 才直接操作 etcd,其他模塊通過 API Server 查詢或修改數據。apiserver 是提供其他模塊之間的數據交互和通信的樞紐。

  2. Scheduler:調度服務,決定將容器創建在哪個 Node 上。
    scheduler 負責分配調度 Pod 到集群內的 node 節點,監聽 apiserver。查詢還未分配 Node 的 Pod,根據調度策略為這些 Pod 分配節點。

  3. Controller Manager:管理系統中各種資源,保證資源處於預期的狀態。
    Controller-manager 由一系列的控制器組成,它通過 apiserver 監控整個集群的狀態,並確保集群處於預期的工作狀態。

  4. Etcd: 保存系統的配置信息和各種資源的狀態信息。
    etcd 是一個高可用的分布式鍵值 (key-value) 數據庫。etcd 內部采用 raft 協議作為一致性算法。etcd 基於 Go 語言實現,用於持久化存儲集群中所有的資源對象,如 Node、Service、Pod、RC、Namespace 等;API Server 提供了操作 etcd 的封裝接口 API,這些 API 基本上都是集群中資源對象的增刪改查及監聽資源變化的接口。

  5. Pod 網絡:提供資源之間互相訪問的網絡。可以是 macvlan、flannel、weave、calico 等其中的一種。

Node 節點的服務:

  1. kubelet:接收 Master 節點發來的創建請求信息,並向 Master 報告運行狀態。
    負責 Node 節點上 Pod 的創建、修改、監控、刪除等全生命周期的管理定時上報本 Node 的狀態信息給 API Server。

  2. kube-proxy:訪問控制。
    Proxy 是為了解決外部網絡能夠訪問跨機器集群中容器提供的應用服務而設計的,運行在每個 Node 上。Proxy 提供 TCP/UDP sockets 的 proxy,每創建一種 Service,Proxy 主要從 etcd 獲取 Services 和 Endpoints 的配置信息,然后根據配置信息在 Node 節點上上啟動一個 Proxy 的進程並監聽相應的服務端口,當外部請求發生時,Proxy 會根據 Load Balancer 將請求分發到后端正確的容器處理。

  3. Pod 網絡:提供資源之間互相訪問的網絡。可以是 macvlan、flannel、weave、calico 等其中的一種。

創建資源工作流程:

各組件配合流程:

  1. 客戶端發出創建 Deployment 請求
  2. API Server 接收到客戶端的調用
  3. API Server 通知 Controller Manager 創建一個 deployment 資源。
  4. Scheduler 執行調度任務,將兩個副本 Pod 分發到 node1 和 node2。
  5. node1 和 node2 上的 kubelet 在各自的節點上創建並運行 Pod。

除了以上核心組件之外,Kubernetes 系統還有一些推薦的組件:

  1. kube-dns 負責為整個集群提供 DNS 服務。在 1.13 中,CoreDNS 現在將 kube-dns 替換為 Kubernetes 的默認 DNS 服務器。
  2. Ingress Controller 為服務提供外網入口
  3. Heapster 提供資源監控
  4. Dashboard 提供 GUI
  5. Federation 提供跨可用區的集群
  6. Fluentd-elasticsearch 提供集群日志采集、存儲與查詢

三、集群創建

詳見 Kubernetes 部署博客

四、部署應用

Kubernetes 部署應用的方式有多種,如:命令行,dashboard,客戶端等。以命令行的形式為例子來說明應用的部署。命令行有兩種方式能夠創建資源,一是使用 kubectl 命令,二是使用 yaml 文件。兩種創建創建方式的特點對比:

基於命令的方式:

  1. 簡單直觀快捷,上手快。
  2. 適合臨時測試或實驗。

基於 yaml 配置文件的方式:
1.所見即所得,配置文件描述的即應用最終要達到的狀態。
2.配置文件提供了創建資源的模板,能夠重復部署。
3.可以像管理代碼一樣管理部署。
4.適合正式的、跨環境的、規模化部署。
5.要求熟悉 yaml 配置文件的語法。

1.Kubectl 命令

Kubectl 使用規則:

kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...] [options]

最簡單的創建應用的命令只需要指定應用的名字和使用的鏡像即可,默認創建 deployment 的資源

kubectl run NAME --image=image
Kubectl run cmd-kubectl --image=nginx

查看創建資源

指定創建的應用的副本為 3 個,鏡像使用 nginx
kubectl run cmd-kubectl-replicas --image=nginx --replicas=3

查看創建資源,副本為 3 個

2.YAML 文件部署

YAML 是專門用來寫配置文件的語言,非常簡潔和強大,使用比 json 更方便。它實質上是一種通用的數據串行化格式。
YAML 語法規則:

  • 大小寫敏感
  • 使用縮進表示層級關系
  • 縮進時不允許使用 Table 鍵,只允許使用空格
  • 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
  • ”#” 表示注釋,從這個字符一直到行尾,都會被解析器忽略
    在 Kubernetes 中,只需要知道兩種結構類型:Lists 和 Maps。

Map 顧名思義指的是字典,即一個 Key:Value 的鍵值對信息

apiVersion: v1
kind: Pod
即 {apiVersion:v1,kind:Pod}

List 即列表,可以理解為是數組

args
 -beijing
 -shanghai
 -shenzhen
 -guangzhou

即 args:[‘beijing’,’shanghai’,’shenzhen’,’guangzhou’]

經典 Yaml 模板文件:

Kubernetes 的官方文檔中並沒有對 apiVersion 的詳細解釋,而且因為 K8S 本身版本也在快速迭代,有些資源在低版本還在 beta 階段,到了高版本就變成了 stable。

Alpha(第一版)

  • 該軟件可能包含錯誤。啟用一個功能可能會導致 bug
  • 隨時可能會丟棄對該功能的支持,恕不另行通知

Beta(測試版)

  • 軟件經過很好的測試。啟用功能被認為是安全的。
  • 默認情況下功能是開啟的
  • 細節可能會改變,但功能在后續版本不會被刪除

Stable(穩定版)

  • 該版本名稱命名方式:vX 這里 X 是一個整數
  • 穩定版本、放心使用
  • 將出現在后續發布的軟件版本中

v1

Kubernetes API 的穩定版本,包含很多核心對象:pod、service 等

apps/v1beta2

在 kubernetes1.8 版本中,新增加了 apps/v1beta2 的概念,apps/v1beta1 同理
DaemonSet,Deployment,ReplicaSet 和 StatefulSet 的當時版本遷入 apps/v1beta2,兼容原有的 extensions/v1beta1

apps/v1

apps/v1 代表:包含一些通用的應用層的 api 組合,如:Deployments, RollingUpdates, and ReplicaSets

batch/v1

代表 job 相關的 api 組合
在 kubernetes1.8 版本中,新增了 batch/v1beta1,后 CronJob 已經遷移到了 batch/v1beta1,然后再遷入 batch/v1

使用 yaml 文件創建應用
Kubectl create -f nginx.yaml

3. 五種 Controller 使用

1.Deployment

Deployment 中文意思為部署、調度。通過在 Deployment yaml 文件中描述所期望的集群狀態,Deployment 會將現在的集群狀態在一個可控的速度下逐步更新成所期望的集群狀態。即定義了一個期望的場景,Pod 的副本數量在任意時刻都符合某個預期值。Deployment 將 Pod 和 ReplicaSet 的實際狀態改變到目標狀態,減少了系統管理員在傳統 IT 環境中需要完成的許多手工運維工作(如主機監控、應用監控和故障恢復等)。
ReplicationController 是早期 Kubernetes 版本中主要使用的一項技術,簡稱 RC。在較新版本中,RC 的功能已經逐漸被功能更強大的 ReplicaSet 和 Deployment 的組合所替代。

Deployment 功能:

  • 確保 Pod 數量
    它會確保 Kubernetes 中有指定數量的 Pod 在運行。如果少於指定數量的 Pod,deployment 會創建新的,反之則會刪除掉多余的以保證 Pod 數量不變。

  • 確保 Pod 健康
    當 Pod 不健康,運行出錯或者無法提供服務時,deployment 會銷毀不健康的 Pod,重新創建新的。

  • 彈性伸縮
    在業務高峰或者低峰期的時候,可以通過 deployment 動態的調整 Pod 的數量來提高資源的利用率。同時,配置相應的監控功能(Hroizontal Pod Autoscaler),會定時自動從監控平台獲取 deployment 關聯 Pod 的整體資源使用情況,做到自動伸縮。

  • 滾動升級
    滾動升級為一種平滑的升級方式,通過逐步替換的策略,保證整體系統的穩定,在初始化升級的時候就可以及時發現和解決問題,避免問題不斷擴大。
    kubectl rolling-update my-nginx -f nginx-rc.yaml

  • 事件和狀態查看
    可以查看 Deployment 的升級詳細進度和狀態。

  • 版本記錄
    每一次對 Deployment 的操作,都能保存下來,給予后續可能的回滾使用。

  • 回滾
    當升級 Pod 鏡像或者相關參數的時候發現問題,可以使用回滾操作回滾到上一個穩定的版本或者指定的版本。

1.創建 deploment 時增加加 --recorder,記錄版本

2.第二個版本

3.第三個版本

查看當前 http 的版本,為第三個 yaml 文件定義的 1.4.18

4.回滾到第一個版本

查看當前 http 的版本為 2.4.16,是第一個版本。回滾成功

  • 暫停和啟動
    對於每一次升級,都能夠隨時暫停和啟動。
  • 多種升級方案
    (1)Recreate:刪除所有已存在的 Pod, 重新創建新的;
    (2)RollingUpdate:滾動升級,逐步替換的策略,同時滾動升級時,支持更多的附加參數,例如設置最大不可用 Pod 數量,最小升級間隔時間等等;

2.ReplicaSet

ReplicaSet 代替用戶創建指定數量的 Pod 副本數量,確保 Pod 副本數量符合預期狀態,並且支持滾動式自動擴容和縮容功能。ReplicaSets 能夠確保在某個時間點上,一定數量的 Pod 在運行。ReplicaSet 主要三個組件組成:
(1) 用戶期望的 Pod 副本數量
(2) 標簽選擇器,判斷哪個 Pod 歸自己管理
(3) 當現存的 Pod 數量不足,會根據 Pod 資源模板進行新建
從操作規范上來講 RelicaSet 不是直接使用的控制器,而是使用 Deployment。Deployment 是 ReplicaSets 更高一層的抽象,用於更新 Pods 以及其他一些特性。ReplicaSet 主要作用是協調 Deployment 創建、刪除和更新 Pods。
查看 deployment 和 replicaset,可以看到 replicaset 的名字是 deployment 名字之后的延伸。

雖然 ReplicaSets 可以獨立使用,建議使用 Deployment 而不是直接使用 ReplicaSets。

3.StatefulSet

StatefulSet 是 Kubernetes 提供的管理有狀態應用的負載管理控制器 API。在 Pods 管理的基礎上,保證 Pods 的順序和一致性。StatefulSet 創建的 Pods 在生命周期中會保持持久的標記(例如 Pod Name,動態創建和銷毀的過程中 Pod Name 也是不斷變化)。
現實中很多服務是有狀態的,如 MySQL 集群、kafka 集群、ZooKeeper 集群等,這些應用集群有以下特點:
(1) 每個節點都有固定的身份 ID,通過這個 ID,集群中的成員可以相互發現和通信;
(2) 集群的規模是相對固定的,且不能隨意變動;
(3) 集群里每個節點都是有狀態的,通常會持久化數據到永久存儲中;
(4) 如果磁盤損壞導致集群里某個節點無法正常運行,則集群功能會部分受損;
StatefulSet 是 Deployment/RC 的一個特殊變種,有如下特性:
(1)StatefulSet 里每個 Pod 都有穩定、唯一的網絡標識,可以用來發現集群內其他成員。假設 StatefulSet 名字叫 kafka,那么第 1 個 Pod 會命名為 kafka-0,第 2 個 Pod 叫 kafka-1,以此類推。
(2)StatefulSet 控制的 Pod 副本的啟停順序是受控的,操作第 n 個 Pod 時,前 n-1 個 Pod 已經是運行且准備好的狀態。
(3)StatefulSet 里的 Pod 采用穩定的持久化存儲卷,通過 PV/PVC 實現,刪除 Pod 時默認不會刪除與 StatefulSet 相關的存儲卷。
(4)StatefulSet 需要與 Headless Service 配合使用,需要在每個 StatefulSet 的定義中聲明它屬於哪個 Headless Service(一種特殊的 Service)。

StatefulSet 適用於具有以下特點的應用:

  • 具有固定的網絡標記(主機名)
  • 具有持久化存儲
  • 需要按順序部署和擴展
  • 需要按順序終止及刪除
  • 需要按順序滾動更新

部署模板

4.Deamonset

DaemonSet 確保集群中每個 node 中運行一份 Pod 副本,副本覆蓋整個集群。當 node 加入集群時創建 Pod,當 node 離開集群時回收 Pod。如果刪除 DaemonSet,其創建的所有 Pod 也被刪除,當需要在集群內每個 node 運行同一個 Pod,使用 DaemonSet 是有價值的,以下是典型使用場景:
(1) 運行集群存儲守護進程,如 glusterd、ceph。
(2) 運行集群日志收集守護進程,如 fluentd、logstash。
(3) 運行節點監控守護進程,如 Prometheus Node Exporter, collectd, Datadog agent, New Relic agent, or Ganglia gmond。

部署模板

5.Job

Job 負責處理僅執行一次的任務。在有些場景下要運行一些容器執行某種特定的任務,任務一旦執行完成,容器也就沒有存在的必要了。在這種場景下,創建 Pod 就顯得不那么合適。於是就是了 Job,Job 指的就是那些一次性任務。通過 Job 運行一個容器,當其任務執行完以后,就自動退出,集群也不再重新將其喚醒。
從程序的運行形態上來區分,可以將 Pod 分為兩類:長時運行服務(jboss、mysql 等)和一次性任務(數據計算、測試)。Deployment 創建的 Pod 都是長時運行的服務,Job 多用於執行一次性任務、批處理工作等,執行完成后便會停止,Pods 狀態從 Running 變為 Completed。

重啟策略
支持兩種重啟策略:

  • OnFailure: 在出現故障時其內部重啟容器,而不是創建。
  • Never: 會在出現故障時創建新的,且故障 job 不會消失。

並行

  • spec.completions:這個 job 運行 Pod 的總次數
  • spec.parallelism:並發數,每次同時運行多少個 Pod
    當 completions 少於 parallelism,parallelism 的值為 completions

部署模板

五、訪問應用

Kubernetes 訪問應用使用的是 Service 資源,而不是直接使用 ip 地址或者域名。假設 Pod 中的容器很可能因為各種原因發生故障而死掉, 每個 Pod 都有自己的 IP 地址。當 Controller 用新 Pod 替代發生故障的 Pod 時,新 Pod 會分配到新的 IP 地址,服務的 ip 地址就發生了變化。Service 資源用於解決 IP 地址動態變化的問題。

1.Service 概念

Service:擁有固定 IP 的服務,從邏輯上代表了一組 Pod。Pod 的 IP 地址會變化,但是 Service 的 IP 是不變的。客戶端只需要訪問 Service 的 IP,Kubernetes 則負責建立和維護 Service 與 Pod 的映射關系。無論后端 Pod 如何變化,Service IP 不會變,對客戶端就不會有任何影響。
Service 通過標簽來選取服務后端,一般配合 Controller 來保證后端容器的正常運行。擁有標簽的 Pods 的 ip 和端口組成 endpoints,由 kube-proxy 負責將 Service IP 負載均衡到這些 endpoints 上。
根據訪問應用的來源不同,可以分為內部訪問和外部訪問。Service 的類型有如下兩種:

  • ClusterIP  內部訪問
  • NodePort  外部訪問

2.ClusterIP

1.Service 通過集群內部的 IP 對外提供服務,只有集群內的節點和 Pod 可訪問,這是默認的 Service 類型。使用場景:
(1) 使用 Kubernetes proxy 來訪問服務:
(2) 調試服務,或者是因為某些原因需要從電腦直接連接服務;
(3) 允許內部流量,顯示內部儀表盤等。

創建 Service 的 yaml 文件

創建好 Service 之后,使用 Service 的 ip + 端口號即 10.68.131.65:8080,可以訪問對應的 Pod。

Node 節點中訪問

使用 10.68.213.112:8080 可以訪問到 Service nginx 指向的一組 Pod 的 80 端口

Service 工作流程圖:

Service 使用流程分析:

  1. 管理員或用戶創建 Service。
    2.Kube-proxy 監聽到 Service 變化,創建相應的 iptables 規則,同步到所有 Node 節點上。
  2. 用戶訪問 Service 的 ip 和端口號,Service 將流量轉向 Node 節點的 Pod 的端口。
    4.Node 節點根據 iptables 規則,轉發流量到 Pod 的端口上。
  3. 流量轉到 Pod 里的 docker 中

域名訪問

除了使用 ip:8080 可以訪問到應用外,在 Pod 中還允許使用域名的方式訪問服務,即 Service name:8080 的方式。如下在 Pod 中使用 wget 訪問。

環境部署時會默認安裝 coredns 組件,該組件提供 Service name 到 ip 的域名映射。

域名訪問原理:
coredns 是一個 DNS 服務器,運行在 kube-system 命名空間下的 Pod,使用 deployment 控制器管理。每當有新的 Service 被創建,coredns 會添加該 Service 的 DNS 記錄。Cluster 中的 Pod 可以通過  <Service_NAME>.<NAMESPACE_NAME > 訪問 Service。

解析 dns 域名。使用 nslookup 解析 nginx 的 ip 地址,ip 為 10.68.131.65

使用對比:
使用域名訪問更加安全。因為 Service 是一個 Pod,也可能會發生故障和重建,所以 ip 地址會可能發生變化,但是 Service 重建名稱也不會變化,重建過程中 coredns 會重新記錄域名和 ip 的對應關系。所以名稱不會變,就能找到 Service 的 ip。

3.NodePort

Service 通過集群節點的靜態端口對外提供服務。集群外部可以通過 NodeIP:NodePort 訪問 Service。通過每個 Node 上的 IP 和靜態端口(NodePort)暴露服務。NodePort 服務會路由到 ClusterIP 服務, ClusterIP 服務會自動創建,並轉發流量到相應的 Pod。通過請求 NodeIP:NodePort,可以從集群的外部訪問一個 NodePort 服務。

創建 NodePort 的 yaml 文件

創建好的 NodePort,24945 為直接訪問的端口,8080 為 ClusterIP 端口。

PORT(S) 為 8080:32312。8080 是 ClusterIP 監聽的端口,24945 則是節點上監聽的端口。Kubernetes 會從 20000-32767 中分配一個可用的端口,每個節點都會監聽此端口並將請求轉發給 Service。
從瀏覽器請求:

NodePort 默認是隨機選擇,不過我們可以用 nodePort 指定某個特定端口。

配置文件中 3 個 port 說明:
(1) nodePort 是節點上監聽的端口。
(2) port 是 ClusterIP 上監聽的端口。
(3) targetPort 是 Pod 監聽的端口。

NodePort 方式有存在的不足之處:
(1) 一個端口只能供一個服務使用;
(2) 只能使用 30000–32767 的端口(安裝時可自定義端口范圍);
(3) 如果節點 / 虛擬機的 IP 地址發生變化,需要進行處理。
(4) 暴露服務較多時,端口管理復雜。

4.LoadBalancer

Service 利用雲提供商特有的 load balancer 對外提供服務,雲提供商負責將 load balancer 的流量導向 Service。目前支持的 cloud provider 有 GCP、AWS、Azur、阿里雲 等。
阿里雲負載均衡架構:

阿里雲負載均衡服務主要有三個核心概念:

  • 負載均衡實例 ( Server Load Balancer instances)
    一個雲負載均衡實例是一個運行的負載均衡服務,用來接收流量並將其分配給后端服務
    器。要使用雲負載均衡服務,您必須創建一個雲負載均衡實例,並至少添加一個監聽和兩台雲服務器實例。
  • 監聽 ( Listeners)
    監聽用來檢查客戶端請求並將請求轉發給后端服務器。監聽也會對后端服務器進行健康
    檢查。
  • 后端服務器( Backend Servers)
    一組接收前端請求的 ECS 實例。 您可以單獨添加 ECS 實例到服務器池, 也可以通過虛
    擬服務器組或主備服務器組來批量添加和管理。

六、負載均衡

Kubernetes 實現負載均衡的方式目前有三種:

  1. Nodeport,kube-proxy 支持
  2. LoadBalancer, 需要雲供應商支持,或者本地 F5 設備支持
  3. Ingress,Kubernetes 一種管理入口流量資源

1.Nodeport

Kube-proxy 實現系統負載均衡。每個 Node 上都會運行一個 kube-proxy 服務進程,這個進程可以看做 Service 的透明代理和負載均衡器。其核心功能是將某個 Service 的訪問請求轉發到后端的某個 Pod 上。

Kube-proxy 的工作原理:

  1. kube-proxy 通過查詢和監聽 API server 中 Service 和 endpoint 的變化, 為每個 Service 都建立了一個服務代理對象, 並自動同步到所有節點的 kube-proxy 服務中。
  2. 服務代理對象是 proxy 程序內部的一種數據結構,它包括一個 socketserver,用於監聽服務請求。socketserver 的端口是隨機選擇的一個本地空閑端口,也可以在創建服務時指定端口。
  3. kube-proxy 內部創建了一個負載均衡器 - LoadBalancer,LoadBalancer 上保存的是 Service 到對應的后端 endpoint 列表的動態轉發路由表。
  4. 對於每一條的具體的路由選擇則取決於負載均衡算法(即 LB 創建的路由表)及 Service 的 session 會話保持這兩個特性。

以 NodePort 為例,說明 kube-proxy 的工作原理
NodePort 的 yaml 文件

Service 創建,端口號 22539

查看 Service 的 endpoint,后端有兩個 Pod。

后端兩個 Pod 的 ip 地址

Node 節點的 iptables 規則:
接收請求端口是 22539 的信息,將發送 22539 的請求轉發給鏈 KUBE-SEP-N4C7F2OUBSWH2BFP 處理

-A KUBE-NODEPORTS -p tcp -m comment --comment "default/nginx-find:" -m tcp --dport 22539 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/nginx-find:" -m tcp --dport 22539 -j KUBE-SVC-YGGX3UAZ364BFXUW
                                                    
-A: 指定鏈名
-p: 指定協議類型
-j: 指定處理動作

該鏈有兩條規則,意思是將 50% 的流量發送鏈 KUBE-SEP-N4C7F2OUBSWH2BFP,剩余 50% 發送 KUBE-SEP-JQYCFTO6ARVB4ENP。

--probability 0.50000000000 參數的意思是 處理 50% 的流量
-A KUBE-SVC-YGGX3UAZ364BFXUW -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-N4C7F2OUBSWH2BFP
-A KUBE-SVC-YGGX3UAZ364BFXUW -j KUBE-SEP-JQYCFTO6ARVB4ENP
該鏈將流量發送 172.20.0.56:80 端口,即 Pod 的端口
-A KUBE-SEP-N4C7F2OUBSWH2BFP -p tcp -m tcp -j DNAT --to-destination 172.20.0.56:80
該鏈將流量發送 172.20.0.57 端口,即 Pod 的端口
-A KUBE-SEP-JQYCFTO6ARVB4ENP -p tcp -m tcp -j DNAT --to-destination 172.20.0.57:80

2.LoadBlancer Service

LoadBlancer Service 是 Kubernetes 結合雲平台的組件,如國外 GCE、AWS、國內阿里雲等等,使用它向使用的底層雲平台申請創建負載均衡器來實現,有局限性,對於使用雲平台的集群比較方便。

3.Ingress

Ingress 是 Kubernetes 中的 API 對象, Ingress 定義了管理對外服務到集群內服務之間規則的集合,它定義規則來允許進入集群的請求被轉發到集群中對應服務上,從來實現服務暴漏。Ingress 能把集群內 Service 配置成外網能夠訪問的 URL,流量負載均衡,終止 SSL,提供基於域名訪問的虛擬主機等等
以 Nginx 為例,Nginx 對后端運行的服務(Service1、Service2)提供反向代理,在配置文件中配置了域名與后端服務 Endpoints 的對應關系。客戶端通過使用 DNS 服務或者直接配置本地的 hosts 文件,將域名都映射到 Nginx 代理服務器。當客戶端訪問 Service1.com 時,瀏覽器會把包含域名的請求發送給 nginx 服務器,nginx 服務器根據傳來的域名,選擇對應的 Service,這里就是選擇 Service 1 后端服務,然后根據一定的負載均衡策略,選擇 Service1 中的某個容器接收來自客戶端的請求並作出響應。Ingress 的工作就是根據配置文件,修改 nginx.conf, 讓 Nginx 靈活指向不同 Service。

Ingress 一般有三個組件組成:
1)Ingress 是 Kubernetes 的一個資源對象,用於編寫定義規則。
2)反向代理負載均衡器,通常以 Service 的 Port 方式運行,接收並按照 Ingress 定義的規則進行轉發,通常為 nginx,haproxy,traefik 等。
3)Ingress-Controller,監聽 apiserver,獲取服務新增,刪除等變化,並結合 Ingress 規則動態更新到反向代理負載均衡器上,並重載配置使其生效。

工作原理圖:

工作原理:

  1. Service 變化。Service 的創建和 Ingress 規則創建。
  2. 感知變化。Ingress Controller 通過和 Kubernetes api 交互,動態的去感知集群中 Ingress 規則變化。
  3. 定義規則。按照定義的規則,規則就是寫明了哪個域名對應哪個 Service,生成一段 nginx 配置。更新規則。將規則寫到 nginx-Ingress-controll 的 Pod 里。該 Pod 運行着一個反向代理負載均衡器(Nginx,haproxy,traefik)服務。以 nginx 為例,控制器會把生成的 nginx 配置寫入 / etc/nginx.conf 文件中,然后 reload 一下使配置生效。以此達到域名分配置和動態更新的問題。
  4. 訪問路由。客戶端訪問域名時,nginx 根據 nginx.conf 配置,將流量轉向到對應的 Service 中。
  5. Service 根據標簽將流量送往對相應的 Pod。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM