在一切皆容器的時代,Kubernetes無疑是一個時代寵兒。越來越多的企業和個人開始使用Kubernetes來虛擬化自己的業務,管理自己的容器。那麼如何在Kubernetes部署應用,以及對執行中的叢集出現故障如何排查就成了大家日益關注的問題了。本文蟲蟲給大家以直觀圖示方式介紹如何在Kubernetes中部署一個應用以及如何排查Kubernetes的故障(下一篇,請等待)。
概述當希望在Kubernetes中部署應用程式時,通常要定義三個元件:
部署(Deployment):這是建立Pod應用程式副本的方法
服務(Service):將流量排程到Pods的內部負載平衡器
入口(Ingress):描述流量如何從群集外部流到服務。
直觀圖示首先,在Kubernetes中,應用程式應該通過兩層負載均衡對外公開:內部負載均衡器和外部負載均衡器。
其次,內部的負載均衡器又被稱為服務,而外部的負載均衡器稱為入口。
最後:Pods不會直接部署。相反,Deployment會在其上建立Pods和觀察者。
應用YAML示例一個簡單的Hello World應用程式為例,該應用程式的YAML如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
labels:
track: canary
spec:
selector:
matchLabels:
any-name: my-app
template:
metadata:
labels:
any-name: my-app
spec:
containers:
- name: cont1
image: learnk8s/app:1.0.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
name: app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
serviceName: app
servicePort: 80
path: /
該定義很長,不好發現元件之間的相互聯絡。
比如下這些問題:
什麼時候應該使用埠80,什麼時候應該使用埠8080?
為了避免衝突,是否應要為每個服務都建立一個新埠?
標籤名稱重要嗎?各處命名是否都應該一致?
要回答這些問題,請接著往下看:
連線部署和服務實際上服務和部署沒有直接連線,服務跳過部署直接指向Pod。因此,要注意的實際上是Pod和服務之間的相互關係。
關鍵點他們關係中要注意:
服務選擇器應至少與Pod的一個標籤匹配;
服務的目標埠(targetPort)應該與Pod內容器的容器埠(containerPort)匹配;
服務埠可以是任何數字。多個服務也可以使用同一埠,因為它們分配了不同的IP地址。
直觀圖示1. 考慮服務下Pod公開的埠
2.建立Pod時,應為Pod中的每個容器定義埠containerPort。
3.建立服務時,可以定義埠和目標埠。但是隻能用目標埠連線容器
4.目標埠和容器埠應該匹配。
5. 如果容器公開了埠3000,則targetPort應該與該數字匹配。
如果檢視YAML,則標籤和ports/targetPor應該匹配:
常見問題那麼部署頂部track: canary標籤是幹什麼的?
需要應該匹配嗎?
部署的track: canary標籤屬於部署,服務選擇器沒有使用它來做流量排程。所以這個標籤完全可以刪除,或者為它分配其他值。
matchLabels選擇器呢?
它必須與Pod標籤匹配,部署用它來跟蹤Pod。
Pod配置修改,如何測試?
我們可以使用以下命令檢查Pod的標籤是否正確:
kubectl get pods --show-labels
對於屬於多個應用程式的Pod使用:
kubectl get pods --selector any-name=my-app --show-labels
其中any-name = my-app表示標籤any-name:my-app。
或者可以直接連線到Pod:可以使用kubectl port-forward命令連線到服務並測試連線。
kubectl port-forward service/<service name> 3000:80
其中,service/<service name>是服務的名稱,比如示例中為" my-service";3000是希望在計算機上開啟的埠;80是"服務"在"埠"欄位中公開的埠。
如果可以連線,則說明設定正確。如果不能,則很可能配置了標籤,或者埠不匹配。
服務和入口連線應用程式釋出的最後一個一步是配置Ingress入口。
關鍵點入口必須知道如何檢索服務,然後檢索Pod並將流量排程到它們。入口按名稱和公開的埠來檢索服務。
在入口和服務中應該匹配兩件事:
Ingress的servicePort應該與Service的埠匹配
Ingress的serviceName應該與Service的名稱匹配
直觀圖示首先,已經該服務釋出了一個埠。
其次,入口中有一個名為服務埠(servicePort)的欄位。
在次,服務埠和入口服務埠應始終匹配。
最後,如果為服務分配了埠80,也應將其servicePort更改為80。
先示例配置要注意的欄位:
常見問題如何測試入口的功能?
可以對kubectl port-forward使用與之前相同的策略,但是應該連線到Ingress控制器,而不是連線到服務。
首先,使用以下命令檢索Ingress控制器的Pod名稱:
kubectl get pods --all-namespaces
對確認的Ingress Pod(可能在不同的名稱空間中)執行下面命令:
kubectl describe pod nginx-ingress-controller-6fc5bcc --namespace kube-system|grep Ports
用得到埠連線到Pod:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system
這樣訪問計算機上的埠3000時,請求都會被轉發到Ingress控制器Pod上的埠80。你訪問localhost:3000,就能看到釋出的應用程式。
總結最後,我們總結回顧一下哪些埠和標籤應該匹配點:
服務選擇器應與Pod的標籤匹配;
服務目標埠(targetPort)應該與Pod內的容器的容器埠(containerPort)相匹配;
服務埠可以是任何數字。多個服務可以使用同一埠,因為它們分配了不同的IP地址;
入口的服務埠servicePort應該與服務中的埠相匹配;
服務的名稱應與入口中的欄位服務名(serviceName)相匹配。