03.02 edx-LFS158x Kubernetes學習筆記(第十章)

Introduction and Learning Objectives

Introduction

儘管微服務驅動的體系結構旨在分離應用程序的組件,但微服務仍然需要代理以邏輯方式將它們綁定或分組在一起,並將流量負載平衡到屬於這種邏輯集的一部分。在本章中,我們將學習Service,這些服務用於將pod分組,以提供從外部世界到容器化應用程序的公共訪問點。我們將瞭解kube-proxy後臺進程,它在每個工作節點上運行,以提供對服務的訪問。我們還將討論服務的發現和服務的類型,它們決定了服務的訪問範圍。

Learning Objectives

在本章結束時,您應該能夠:

  • 討論將pod以邏輯分組形成Service以訪問應用程序的好處。
  • 解釋在每個工作節點上運行的kube-proxy守護進程的角色。
  • 探索Kubernetes中提供的發現服務的選項。
  • 討論不同的服務類型。

Services

Connecting Users to Pods

要訪問應用程序,用戶/客戶端需要連接到Pods。由於pod本質上是短暫的,因此分配給它的資源(如IP地址)不能是靜態的。Pods可突然終止或根據現有要求重新安排。例如,假設用戶/客戶機使用其IP地址連接到Pod。


edx-LFS158x Kubernetes學習筆記(第十章)

用戶通過其IP地址連接到pod的場景
意外地,用戶/客戶機連接到的Pod被終止,控制器創建了一個新的Pod。新的Pod將有一個新的IP地址,先前Pod的用戶/客戶機沒法自動知道這個地址。


edx-LFS158x Kubernetes學習筆記(第十章)

新的Pod是在舊的Pod意外終止後創建的為了克服這種情況,Kubernetes提供了一個稱為Service的更高層次的抽象,它在邏輯上對pod進行分組並定義訪問它們的策略。這個分組是通過labelsSelectors實現的。

Services

在下面的圖形表示中,app是標籤鍵,frontend和db是不同pod的標籤值。


edx-LFS158x Kubernetes學習筆記(第十章)

使用LabelsSelectors對pod進行分組
使用選擇器appfrontend和appdb,我們將Pod分組為兩個邏輯集:一個包含3個Pod,一個包含單個Pod。
我們為邏輯分組指定一個名稱,稱為Service。在我們的示例中,我們創建了兩個服務frontend-svc和db-svc,它們分別具有appfrontend和appdb選擇器。


edx-LFS158x Kubernetes學習筆記(第十章)

使用服務對象對pod進行分組服務可以公開單個pod、 ReplicaSets, Deployments, DaemonSets, 和 StatefulSets。

Service Object Example

以下是服務對象定義的示例:

<code>kind: Service
apiVersion: v1
metadata:
name: frontend-svc
spec:
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 5000
/<code>

在本例中,我們通過選擇標籤key=app設置為value=frontend的所有pod來創建一個frontend-svc服務。默認情況下,每個Service接收一個集群內路由的IP地址,稱為cluster IP。在我們的示例中,172.17.0.4和172.17.0.5分別作為集群分配 frontend-svc和db-svc服務。


edx-LFS158x Kubernetes學習筆記(第十章)

使用服務對象訪問Pods用戶/客戶端現在通過其ClusterIP連接到一個Service,ClusterIP將流量轉發到附加到它的一個pod。默認情況下,Service在為流量轉發選擇Pods時提供負載平衡。當服務將流量轉發到Pods時,我們可以在接收流量的Pod上選擇目標端口。在我們的示例中,前端svc服務接收來自端口80上的用戶/客戶端的請求,然後將這些請求轉發到targetPort 5000上的一個pod。如果未顯式定義targetPort,則流量將轉發到Service接收流量的port的Pods。Pod的IP地址和目標端口的邏輯集稱為服務的end Point, 端點。在我們的示例中,front-svc服務有3個端點:10.0.1.3:5000、10.0.1.4:5000和10.0.1.5:5000。端點由服務自動創建和管理,而不是由Kubernetes集群管理員創建和管理。

kube-proxy

所有工作節點都運行一個名為kube-proxy的守護進程,該守護進程監視主節點上的API Server添加和刪除服務和端點。在下面的示例中,對於每個新服務,在每個節點上,kube-proxy配置iptables規則來捕獲其ClusterIP的流量並將其轉發到服務的一個端點。因此,任何節點都可以接收外部流量,然後根據iptables規則在集群內部路由。當服務被移除時,kube-proxy也會移除所有節點上相應的iptables規則。


edx-LFS158x Kubernetes學習筆記(第十章)

Service Discovery

由於服務是Kubernetes中的主要通信模式,我們需要一種在運行時發現它們的方法。Kubernetes支持兩種發現服務的方法:

  • 環境變量
    一旦Pod在任何工作節點上啟動,在該節點上運行的kubelet守護進程就會在Pod中為所有活動服務添加一組環境變量。例如,如果我們有一個名為redis-master的激活狀態的服務,它公開端口是6379,其ClusterIP為172.17.0.6,那麼,在新創建的Pod上,我們可以看到以下環境變量:REDIS_MASTER_SERVICE_主機=172.17.0.6 REDIS_MASTER_服務端口=6379 REDIS_MASTER_PORT=tcp://172.17.0.6:6379 REDIS_MASTER_PORT_6379_TCP=TCP://172.17.0.6:6379 REDIS_MASTER_PORT_6379_TCP_PROTO=TCP REDIS_MASTER_PORT_6379_TCP_PORT=6379 REDIS_MASTER_端口_6379_TCP_地址=172.17.0.6 使用此解決方案,我們在訂閱Service時需要小心,因為Pods不會為創建Pods後創建的服務設置環境變量。
  • 域名服務器
    Kubernetes有一個DNS插件,它為每個服務創建一個DNS記錄,其格式為my-svc.my-namespace.svc.cluster.local。同一命名空間中的服務僅按名稱查找其他服務。如果我們在my-ns名稱空間中添加了一個服務redis-master,那麼同一名稱空間中的所有pod只會按其名稱redis-master查找服務。來自其他命名空間的pod通過添加相應的命名空間名稱為後綴(如redis-master.my-ns)來查找相同的服務。
    這是最常見和最推薦的解決方案。例如,在上一節的圖片中,我們看到配置了一個內部DNS,它將我們的服務frontend-svc和db-svc分別映射到172.17.0.4和172.17.0.5。

ServiceType

在定義Service時,我們還可以選擇其訪問範圍。我們可以決定Service是否:

  • 只能在群集中訪問
  • 可從集群內部和外部世界訪問
  • 映射到位於集群內部或外部的實體。
    訪問範圍由ServiceType決定,ServiceType可以在創建Service時配置。

ServiceType: ClusterIP and NodePort

ClusterIP是默認的ServiceType。服務接收一個虛擬IP地址,稱為其ClusterIP。此虛擬IP地址用於與服務通信,並且只能在集群中訪問。除了ClusterIP之外,還可以使用NodePort ServiceType,它動態地從默認範圍30000-32767中選擇的high-port, 將其映射到來自所有工作節點的相應服務。例如,如果服務frontend-svc的映射NodePort是32233,那麼,如果我們連接到任何工作節點上的端口32233,則該節點會將所有通信重定向到分配的ClusterIP - 172.17.0.4。如果我們更喜歡特定的高端口號,那麼我們可以從端口的默認範圍選一個high-port號指派給NodePort。


edx-LFS158x Kubernetes學習筆記(第十章)

節點端口當我們希望可以從外部世界訪問我們的服務時,NodePort ServiceType非常有用。最終用戶連接到指定的任何工作節點的high-ports上,後者在內部將請求代理到服務的ClusterIP,然後將請求轉發到集群內運行的應用程序。要從外部世界訪問多個應用程序,管理員可以配置反向代理,定義針對集群中服務的規則和入口。

ServiceType: LoadBalancer

使用LoadBalancer ServiceType的話:

  • NodePort和ClusterIP將自動創建,外部負載均衡器將自動路由到它們
  • 對每個工作節點, 服務暴露為靜態端口;
  • 該服務對外暴露時使用底層雲服務提供商的負載均衡器功能。


edx-LFS158x Kubernetes學習筆記(第十章)


  • 負載平衡器
    LoadBalancer ServiceType只有在底層基礎設施支持自動創建負載均衡器並且對Kubernetes中有相應的支持接口時才能工作,就像Google雲平臺和AWS一樣。如果未配置此類功能,則不會填充LoadBalancer IP address字段,並且該服務的工作方式與NodePort類型的服務相同。

  • ServiceType: ExternalIP

    如果服務可以路由到一個或多個工作節點,則可以將其映射到外部地址。使用服務端口上的ExternalIP(作為目標IP)進入集群的流量被路由到一個服務端點。此類服務需要外部雲提供商,如Google雲平臺或AWS。


    edx-LFS158x Kubernetes學習筆記(第十章)

    ExternalIP
    請注意ExternalIP不是由Kubernetes管理的。集群管理員必須配置將外部地址映射到其中哪一個節點的路由。


    ServiceType: ExternalName


    ExternalName是一種特殊的ServiceType,它沒有Selectors,也沒有定義任何endpoints。當在集群內訪問時,它返回外部配置的服務的CNAME記錄。此服務類型的主要使用案例是使外部配置的服務(如my-database.example.com)可用於群集中的應用程序。如果外部定義的服務位於同一命名空間中,則僅使用my-database的名稱, 將使其對同一命名空間中的其他應用程序和服務可用。


    分享到:


    相關文章: