【云原生|K8s系列第5篇】:实战使用Service暴露应用
本期文章是K8s系列第5篇,主要是實戰使用Service暴露應用。通過本期文章:我們將學習了解 Kubernetes 中的 Service,學習標簽(Label) 和 標簽選擇器(Label Selector) 對象如何與 Service 關聯,最后在 Kubernetes 集群外用 Service 暴露應用。
在前期的文章中,已經介紹了一些云原生入門的知識及簡單實戰,感興趣的同學可以去我的云原生專欄中學習,任意門:云原生學習專欄
實戰使用Service暴露應用
- 前言:學習目標
- 1、K8s Service介紹
- 2、Service 和 Label 關系示意圖
- 3、實戰使用Service暴露應用
- 3.1 創建新服務
- 3.2 使用labels
- 3.3 刪除服務
前言:學習目標
本期的學習目標是:
- 學習 Kubernetes 中的 Service。
- 學習標簽(Label) 和 標簽選擇器(Label Selector) 對象如何與 Service 關聯。
- 在 Kubernetes 集群外用 Service 暴露應用。
1、K8s Service介紹
Kubernetes Pod 實際上是擁有生命周期的。 當一個工作 Node 掛掉后, 在 Node 上運行的 Pod 也會消亡。 ReplicaSet 會自動地通過創建新的 Pod 驅動集群回到目標狀態,以此可以保證應用程序正常運行。
換一個例子來說明,目前有一個具有3個副本數的用作圖像處理的后端程序。這些副本是可替換的,前端系統不應該關心后端副本,即使 Pod 丟失或重新創建。
這也就是說,Kubernetes 集群中的每個 Pod (即使是在同一個 Node 上的 Pod )都有一個唯一的 IP 地址,因此需要一種方法自動協調 Pod 之間的變更,以便應用程序保持運行。
Kubernetes 中的服務(Service)是一種抽象概念,它定義了 Pod 的邏輯集和訪問 Pod 的協議。Service 使從屬 Pod 之間的松耦合成為可能。 和其他 Kubernetes 對象一樣, Service 用 YAML (更推薦) 或者 JSON 來定義. Service 下的一組 Pod 通常由 LabelSelector 來標記。
盡管每個 Pod 都有一個唯一的 IP 地址,但是如果沒有 Service ,這些 IP 不會暴露在集群外部。Service 允許你的應用程序接收流量。Service 也可以用在 ServiceSpec 標記type的方式暴露。
-
ClusterIP (默認) - 在集群的內部 IP 上公開 Service 。這種類型使得 Service 只能從集群內訪問。
-
NodePort - 使用 NAT 在集群中每個選定 Node 的相同端口上公開 Service 。使用: 從集群外部訪問Service。是 ClusterIP 的超集。
-
LoadBalancer - 在當前云中創建一個外部負載均衡器(如果支持的話),并為 Service 分配一個固定的外部IP。是 NodePort 的超集。
-
ExternalName - 通過返回帶有該名稱的 CNAME 記錄,使用任意名稱(由 spec 中的externalName指定)公開 Service。不使用代理。這種類型一般需要kube-dns的v1.7或更高版本。
2、Service 和 Label 關系示意圖
Service 通過一組 Pod 路由通信。Service 是一種抽象,它允許 Pod 死亡并在 Kubernetes 中復制,而不會影響應用程序。在依賴的 Pod (如應用程序中的前端和后端組件)之間進行發現和路由是由Kubernetes Service 處理的。
Service 匹配一組 Pod 是使用 標簽(Label)和選擇器(Selector), 它們是允許對 Kubernetes 中的對象進行邏輯操作的一種分組原語。標簽(Label)是附加在對象上的鍵/值對,可以以多種方式使用,如:
- 指定用于開發,測試和生產的對象
- 嵌入版本標簽
- 使用 Label 將對象進行分類
3、實戰使用Service暴露應用
接下來,我們將實戰如何使用kubectl expose命令在集群外公開Kubernetes應用程序。我們還將學習如何使用kubectl label命令查看并將標簽應用到對象。
實戰使用的環境是在線終端是預先配置好的Linux環境,可以作為常規控制臺使用(可以輸入命令)
3.1 創建新服務
讓我們驗證一下應用程序是否正在運行。我們將使用kubectl get命令并查找現有的Pods:、
$ kubectl get pods NAME READY STATUS RESTARTS AGE kubernetes-bootcamp-fb5c67579-pgxxl 1/1 Running 0 51s $我們有一個名為kubernetes的服務,它是在minikube啟動集群時默認創建的。為了創建一個新服務并將其公開給外部通信,我們將使用expose命令,將NodePort作為參數(minikube還不支持LoadBalancer選項)。
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080接下來,讓我們列出集群中當前的服務:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7m37s kubernetes-bootcamp NodePort 10.110.52.119 <none> 8080:30349/TCP 97s現在有一個服務叫做kubernetes-bootcamp。這里我們看到服務接收了一個唯一的集群IP、一個內部端口和一個外部IP(節點的IP)。
要找出外部打開了哪些端口(通過NodePort選項),我們將運行如下的describe service命令:
$ kubectl describe services/kubernetes-bootcamp Name: kubernetes-bootcamp Namespace: default Labels: app=kubernetes-bootcamp Annotations: <none> Selector: app=kubernetes-bootcamp Type: NodePort IP Families: <none> IP: 10.110.52.119 IPs: 10.110.52.119 Port: <unset> 8080/TCP TargetPort: 8080/TCP NodePort: <unset> 30349/TCP Endpoints: 172.18.0.6:8080 Session Affinity: None External Traffic Policy: Cluster Events: <none>創建一個名為NODE_PORT的環境變量,分配節點端口的值:
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}') $ echo NODE_PORT=$NODE_PORT NODE_PORT=30349現在我們可以使用curl、節點的IP和外部暴露的端口來測試應用程序是否暴露在集群外:
$ curl $(minikube ip):$NODE_PORT Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-fb5c67579-pgxxl | v=13.2 使用labels
部署自動為Pod創建了一個標簽。使用description部署命令,我們可以看到標簽的名稱:
kubectl describe deployment讓我們使用這個標簽來查詢Pods列表。我們將使用kubectl get pods命令,參數是-l,后面是標簽值:
$ kubectl get pods -l app=kubernetes-bootcamp NAME READY STATUS RESTARTS AGE kubernetes-bootcamp-fb5c67579-pgxxl 1/1 Running 0 15m我們也可以這樣做來列出現有的服務:
$ kubectl get services -l app=kubernetes-bootcamp NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes-bootcamp NodePort 10.110.52.119 <none> 8080:30349/TCP 10m獲取Pod的名稱并將其存儲在POD_NAME環境變量中:
$ export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') $ echo Name of the Pod: $POD_NAME Name of the Pod: kubernetes-bootcamp-fb5c67579-pgxxl接下來要應用一個新標簽,我們使用label命令,后面跟著對象類型、對象名稱和新標簽:
$ kubectl label pods $POD_NAME version=v1 pod/kubernetes-bootcamp-fb5c67579-pgxxl labeled這將為我們的Pod應用一個新標簽(我們把應用版本釘在了Pod上),我們可以用describe Pod命令來檢查它:
kubectl describe pods $POD_NAME我們在這里看到標簽現在連接到我們的Pod。現在我們可以使用新標簽查詢:
$ kubectl get pods -l version=v1 NAME READY STATUS RESTARTS AGE kubernetes-bootcamp-fb5c67579-pgxxl 1/1 Running 0 18m3.3 刪除服務
需要刪除服務,使用delete service命令。標簽也可以在這里使用:
$ kubectl delete service -l app=kubernetes-bootcamp service "kubernetes-bootcamp" deleted確認服務已消失:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20m這證實了我們的服務已被刪除。為了確認路由沒有暴露,我們可以查詢之前暴露的IP和端口:
$ curl $(minikube ip):$NODE_PORT curl: (7) Failed to connect to 10.0.0.12 port 30349: Connection refused這證明了應用程序從集群外部無法再訪問。我們可以確認應用程序仍在運行,并在pod內卷起:
$ kubectl exec -ti $POD_NAME -- curl localhost:8080 Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-fb5c67579-pgxxl | v=1我們在這里看到,應用程序啟動了。這是因為部署正在管理應用程序。如果要關閉應用程序,還需要刪除Deployment。
總結
以上是生活随笔為你收集整理的【云原生|K8s系列第5篇】:实战使用Service暴露应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS checkbox 选中事件
- 下一篇: DSA_C++