1. 程式人生 > 實用技巧 >Kubernetes服務型別淺析:從概念到實踐

Kubernetes服務型別淺析:從概念到實踐

本文轉自Rancher Labs

在Kubernetes中,服務總是能使其網路訪問到一個或一組Pod上。服務將會根據標籤選擇Pod並且當對這些服務建立網路時,它會選擇叢集中所有與服務的selector相匹配的Pod,並選擇其中的一個,然後將網路請求轉發給它。

Kubernetes 服務vs Deployment

在K8S中我們應該如何區分Deployment和服務呢?

  • Deployment主要負責讓一組pod在叢集中保持執行

  • 服務主要負責在叢集中啟用對一組pod的網路訪問

我們可以使用deployment而不使用服務,所以我們可以保持幾個相同的Pod在K8S叢集中執行。此外,Deployment的規模可以擴大和縮小,pod也可以複製。在Kubernetes中,單個pod可以直接通過網路請求單獨訪問,因此要跟蹤pod會有些困難。

我們也可以使用一個服務型別而不需要deployment。如果我們這樣做,將建立一個單一的pod,而不是像我們在deployment中那樣一起建立所有pod。不過,我們還有另一種替代方案,即我們的服務能夠根據分配給它們的標籤進行選擇,從而將網路請求路由到這些Pod。

我們如何發現Kubernetes服務呢?

在Kubernetes中,有兩種方式可以發現服務:

  • DNS型別。DNS server被新增到叢集中,以便觀察Kubernetes API為每個新服務建立DNS record set。當整個叢集啟用DNS後,所有的Pod都應該能夠自動進行服務名稱解析。

  • ENV變數。在這一發現方法中,一個pod執行在一個節點上,所以 kubelet為每個active服務新增環境變數。

ClusterIP、NodePort和LoadBalancer是什麼?

服務規範中的型別屬性決定了服務如何暴露在網路中。比如,ClusterIP、NodePort和LoadBalancer。

  • ClusterIP—預設值。該服務只能從Kubernetes叢集內訪問。

  • NodePort—這使得服務可以通過叢集中每個節點上的靜態埠訪問。

  • LoadBalancer—服務通過雲提供商的負載均衡器功能可以從外部訪問。阿里雲、AWS、Azure都提供了這一功能。

如何建立一個服務

通過deployment kind的幫助,以“Hello World” App形式的簡單示例將會幫助你更好地理解如何建立服務。

我們的操作流程是,當我們看到應用程式已經部署完成並且以up狀態執行的時候,我們將建立服務(Cluster IP)來訪問Kubernetes中的應用程式。

現在,讓我們建立一個正在執行的deployment

“kubectl run hello-world –replicas=3 –labels=”run=load-balancer-example” –image=gcr.io/google-samples/node-hello:1.0 –port=8080”. 

這裡,這個命令在Kubernetes中建立了一個有兩個應用程式副本的deployment。

接下來,

run "kubectl get deployment hello-world" so see that the deployment is running.
Now we can check the replicaset and pods that the deployment created.
$ kubectl get deployments hello-world
NAME          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE       AGE
hello-world    3          3            3        3              76s

應用程式現在正在執行,如果你想要訪問新建立的應用程式,我們需要建立ClusterIP型別的服務:

  • 為服務建立一個YAML manifest並應用它,或

  • 使用kubectl expose命令,這是一個更為簡單的選項。因為這一命令可以無需建立YAML檔案即可建立一個服務。

$ kubectl expose deployment hello-world --type=ClusterIP --name=example-service
service "example-service" exposed

在這裡,我們將建立一個名為example-service的服務,型別為ClusterIP。

那麼,現在我們將訪問我們的應用程式:

run “kubectl get service example-service” to get our port number.

然後,我們需要執行port-forward命令。因為我們的服務型別是ClusterIP,所以只能在叢集內訪問,因此我們必須通過轉發埠到叢集中的本地端口才能訪問我們的應用程式。

我們可以使用其他型別,如LoadBalancer,這將在AWS或GCP中建立一個LB,然後我們可以使用給LB的DNS地址和我們埠號來訪問應用程式。

$ kubectl get service example-service

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
example-service   ClusterIP   100.20.167.76   <none>        8080/TCP   1h

$ kubectl port-forward service/example-service 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080

現在我們可以從工作站瀏覽http://localhost:8080,並且我們應該會看到:

Hello Kubernetes!

Kubernetes 服務 NodePort YAML示例

此示例YAML建立了可用於外部網路請求的服務。在這裡,我們提到了帶Value的NodePort,因此服務被對映到叢集中每個節點上的埠。

下面是一個yaml的例子,它將展示我們如何在Kubernetes中使用NodePort服務型別。

kind: Service 
apiVersion: v1 
metadata:
  name: hostname-service 
spec:
  # Expose the service on a static port on each node
  # so that we can access the service from outside the cluster 
  type: NodePort
# When the node receives a request on the static port (30163)
  # "select pods with the label 'app' set to 'echo-hostname'"
  # and forward the request to one of them
  selector:
    app: echo-hostname
ports:
    # Three types of ports for a service
    # nodePort - a static port assigned on each the node
    # port - port exposed internally in the cluster
    # targetPort - the container port to send requests to
    - nodePort: 30163
      port: 8080 
      targetPort: 80