Kubernetes基本功能

說明
目前kubernetes的資料介紹不少也很深入,本文只是作一個針對本身學習k8s過程的介紹,僅僅是學習筆記的記錄。前端

1、基本使用

1. 命令行

  • 集羣信息

  • Namespace 信息

  • Controller 信息

Deployment 控制器
node

Replicaset 控制器mysql

Statefulset 控制器
nginx

Daemonset 控制器算法

Job 控制器sql

  • Service

  • Pod

  • 參數

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

--all-namespaces 查看全部 namespace 下的資源
數據庫

K8s 出錯排查三大步:json

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

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

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

2.Dashboard

  • 集羣信息

Namespace 全部信息


應用信息

容器信息

副本信息

服務信息

2、架構分析

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 提供集羣日誌採集、存儲與查詢

3、集羣建立

詳見 Kubernetes 部署博客

4、部署應用

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

部署模板

5、訪問應用

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。

解析 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 實例到服務器池, 也能夠經過虛
    擬服務器組或主備服務器組來批量添加和管理。

6、負載均衡

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 對後端運行的服務(Service一、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。
相關文章
相關標籤/搜索