所在位置:首頁 -- 物聯網/云計算 -- 正文

使用Rancher在Kubernetes上進行微服務部署


發布時間:2017-4-1  來源:admin

 大多數人在生產環境中運行Docker,是把它作為構建和移動部署配置的一種方式。然而,他們的部署模型要么非常整體化,要么有幾個大的服務模塊組成。使用真實的容器化微服務最大的障礙在于,很多人不太清楚如何管理和協調容器大規模負載。今天我們將探討如何基于微服務部署來構建Kubernetes。作為google 長期經營的Borg項目的開源的繼承者,Kubernetes有將近10年的運行大規模負載的歷史了。雖然也存在一些缺點,但Kubernetes是現今最成熟的容器編排系統之一。

啟動Kubernetes環境

在Kubernetes官方文檔中可以找到如何在不同環境下創建Kubernetes集群,本文中我主要講解使用Rancher容器管理平臺來部署Kubernetes。首先設置Rancher server,選擇環境/默認>環境管理>添加環境。從容器編排選項中選擇并創建環境。然后選擇基礎設施(Infrastructure)>主機(Hosts) >添加主機(Add Host),且為Kubernetes創立幾個節點以便運行。

注意:為了運行Rancher 代理容器,我們建議至少添加3臺主機。當主機創建成功,你將會看到以下屏幕內容,幾分鐘內集群創建成功并準備就緒。

使用Rancher來運行Kubernetes有很多優勢。大多數情況下能使用戶和IT團隊部署和管理工作更加方便。Rancher自動在Kubernetes后端實現etcd 的HA,并且將所需要的服務部署到此環境下的任何主機中。在設置訪問控制,可以輕易連接到現有的LDAP和AD基礎構架。Rancher還可以自動實現容器聯網以及為Kubernetes提供負載均衡服務。通過使用Rancher,你將會在幾分鐘內有擁有Kubernetes的HA實現。

命名空間

現在我們的集群已經運行了,讓我們進入并查看一些基本的Kubernetes資源吧。你可以訪問Kubernetes集群也可以直接通過kubectl CLI訪問,或者通過Rancher UI 訪問。Rancher的訪問管理圖層控制可以訪問集群,所以你需要在訪問CLI前從Rancher UI那里生成API密匙。

我們來看下第一個Kubernetes資源命名空間,在給定的命名空間中,所有資源名稱必須有唯一性。此外,標簽是用來連接劃定到單個命名空間的資源。這就是為什么同一個Kubernetes集群上可以用命名空間來隔離環境。例如,你想為應用程序創建Alpha, Beta和生產環境,以便可以測試最新的更改且不會影響到真正的用戶。最后創建命名空間,復制下面的文本到namespace.yaml文件,并且運行kubectl -f namespace.yaml命令,來創建一個beta命名空間。

kind: Namespace
apiVersion: v1
metadata:
name: beta
labels:
name: beta

當然你還可以使用頂部的命名空間菜單欄從Rancher UI上創建、查看和選擇命名空間。

你可以使用下面的命令,用kubectl來為CLI交互設置命名空間:

$ kubectl config set-context Kubernetes --namespace=beta.

 

為了驗證目前context是否已經被設置好,你可以使用config view命令,驗證一下輸出的命名空間是否滿足你的期望。

$ kubectl config view | grep namespace command
namespace: beta

Pods

現在我們已經定義好了命名空間,接下來開始創建資源。首先我們要看的資源是Pod。一組一個或者多個容器的Kubernetes稱為pod,容器在pod 里按組來部署、啟動、停止、和復制。在給定的每個主機種類里,只能有一個Pod,所有pod里的容器只能在同一個主機上運行,pods可以共享網絡命名空間,通過本地主機域來連接。Pods也是基本的擴展單元,不能跨越主機,因此理想狀況是使它們盡可能接近單個工作負載。這將消除pod在擴展或縮小時產生的副作用,以及確保我們創建pods不太耗資源而影響到主機。

我們來給名為mywebservice的pod定義,在規范命名web-1-10中它有一個容器并使用nginx容器鏡像,然后把端口為80下的文本添加至pod.yaml文檔中。

apiVersion: v1
kind: Pod
metadata:
name: mywebservice
spec:
containers:
- name: web-1-10
image: nginx:1.10
ports:
- containerPort: 80

使用kubetl create命令創建pod,如果您使用set-context command設置了您的命名空間,pods將會在指定命名空間中被創立。在通過運行pods命令去驗證pod狀態。完成以后,我們可以通過運行kubetl delete命令刪除pod。

$ kubectl create -f ./pod.yaml
pod "mywebservice" created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mywebservice 1/1 Running 0 37s
$ kubectl delete -f pod.yaml
pod "mywebservice" deleted

在Rancher UI 中查看pod,通過頂端的菜單欄選擇Kubernetes > Pods。

Replica Sets

Replica Sets,顧名思義,它定義了每個pod副本運行有多少。Replica Sets還能監控并保障所需要pods數量正在運行,并將那些停止的pods替換掉。需要注意的一點是,Replica Sets是Replication Controllers的替代者,然而,在大部分案例中將不能直接使用Replica Sets設置,而是要使用Deployments。Deployments包裝了Replica Sets,在應用程序中設置并添加回滾更新升級功能。

部署

部署是一個用于管理你的應用程序回滾及更新的聲明機制。基于這點,我們用上述對pod 的定義來定義我們的第一次部署。唯一的區別是,我們采用name parameter作為我們容器的名稱,這個名稱將會被部署自動收集。下面的文本顯示我們用于部署的配置。你可以將它復制到deployment.yaml的文檔中。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mywebservice-deployment
spec:
replicas: 2 # We want two pods for this deployment
template:
metadata:
labels:
app: mywebservice
spec:
containers:
- name: web-1-10
image: nginx:1.10
ports:
- containerPort: 80

用kubectl create命令啟動你的部署,然后驗證你的部署是否使用get deployments命令而成功了。

$ kubectl create -f ./deployment.yaml
deployment "mywebservice-deployment" create
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
mywebservice-deployment 2 2 2 2 7m

你可以使用describe deployment命令來顯示deployment的細節。在describe命令下,其中一個有用的輸出項目是一組事件。由describe命令得出的輸出,請見以下經刪減的例子。目前你的部署應顯示以下信息:擴展replica set 2。

$ kubectl describe deployment mywebservice
Name: mywebservice-deployment
Namespace: beta
CreationTimestamp: Sat, 13 Aug 2016 06:26:44 -0400
Labels: app=mywebservice
.....
..... Scaled up replica set mywebservice-deployment-3208086093 to 2

擴展部署

你可以及早的更新deployment.yaml文檔,用replicas:3替換replicas:2,來修改部署的規模,然后如下圖展示:運行apply命令。如果你再次運行describe deployment 命令,將會第二次看到這個信息:擴展replica set mywebservice-deployment-3208086093 to 3。

$ kubectl apply -f deployment.yaml
deployment "mywebservice-deployment" configured

更新部署

你可以靠改變鏡像版本來使用apply命令更新你的應用程序。先將鏡像nginx:1.10 替換成鏡像nginx:1.11,運行kubectl apply命令來修改deployment.yaml 文檔。如果你再次運行了describe deployment命令,你會看到如下信息。你可以看出來新的deployment (2303032576)是如何一步步進行擴展的,也可以看到舊的deployment (3208086093)如何縮小的。雖然圍繞在deployment的pod總數保持不變,但pods正逐漸從舊的deployment向新的deployment移動,這使得我們不中斷服務的情況下運行負載deployment。

Scaled up replica set mywebservice-deployment-2303032576 to 1
Scaled down replica set mywebservice-deployment-3208086093 to 2
Scaled up replica set mywebservice-deployment-2303032576 to 2
Scaled down replica set mywebservice-deployment-3208086093 to 1
Scaled up replica set mywebservice-deployment-2303032576 to 3
Scaled down replica set mywebservice-deployment-3208086093 to 0

如果在deployment過程中或之后你意識到出現錯誤或者已經出現問題,可以使用rollout命令來取消之前deployment,這將執行反向操作,將負載移動至之前版本的容器。

$ kubectl rollout undo deployment/mywebservice-deployment
deployment "mywebservice-deployment" rolled back

Health check

利用部署,我們已經了解如何擴展我們的service,以及如何對他們進行部署。然而,當在生產環境中運行服務的時候,其中實時監控或更換服務實例也是非常重要的。Kubernetes提供Health check來解決問題。你可以在規定部分添加livenessProbe配置,來更新deployment.yaml文檔。有三種liveness probe可供選擇:http、tcp和container exec。前兩者檢查Kubernetes是否能使http或者tcp連接至指定端口。container exec probe可用來運行容器里的指定命令,并維護容器里的停止響應代碼。如下所示的代碼片段中,我們使用http probe發送Root URL,使用 GET請求到端口80。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mywebservice-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: mywebservice
spec:
containers:
- name: web-1-11
image: nginx:1.11
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
timeoutSeconds: 1

如果你用額外的health check重新創建你的部署,并且運行describe deployment的話,你將會看到Kubernetes現在會辨認出有3個replicas是不能使用的。如果你在初始延遲30秒后再次運行deployment,你會發現replicas現在標記為可用。在Kubernetes 開始路由擁堵前給你的應用程序啟動時間,這是為了確保你的容器是健康的。

$ kubectl create -f deployment.yaml
deployment "mywebservice-deployment" created
$ kubectl describe deployment mywebservice
...
Replicas: 3 updated | 3 total | 0 available | 3 unavailable

服務

既然現在我們擁有了在負載情況下可更新可擴展并且被監控著了的部署,現在是時候將這些服務展現給真實用戶了。拷貝以下內容至service.yaml的文檔中。你的集群中的每個節點暴露的端口都可使用Kube Proxy將路由堵塞轉移至replicas。

apiVersion: v1
kind: Service
metadata:
name: mywebservice
labels:
run: mywebservice
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
name: http
selector:
app: mywebservice

通過service.yaml文檔,我們創建一個create命令服務,然后我們可以使用describe service 命令查找Node Port。例如,在我們服務中可以使用任何 Kubernetes/Rancher 代理節點(agent nodes)訪問端口31673的應用程序。如果節點規模變大或者縮小,或變得不健康甚至重新啟動,Kubernetes將自動將流量路由到可用節點。

$ kubectl create -f service.yaml
service "mywebservice" created
$ kubectl describe service mywebservice | grep NodePort
NodePort: http 31673/TCP

在今天的文章里,今天我們研究了命名空間,pods,Deployments,和Services等一些基本的Kubernetes資源。我們看了如何手動擴展或縮小應用程序的規模,以及如何執行應用程序的回滾更新。最后為了從外部展示我們的應用程序,我們看來配置服務。在后續文章中,我們將關注如何協調使用這些并編排一個更實際的部署。今天我們將著眼于資源覆蓋的更多細節,包括如何設置SSL / TLS終端,multi-service deployments, service discovery和當應用失敗后的場景中如何應對。

中国北京单场足球彩票