歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~javascript
容器實例服務(Container Instance Service , CIS)能夠幫您在雲上快捷、靈活的部署容器,讓您專一於構建程序和使用容器而非管理設備上。無需預購 CVM,您就能夠在幾秒內啓動一批容器來執行任務。您也能夠經過 kubernetes API 把已有 kubernetes 集羣的 pod 調度到 CIS 上以處理突增業務。CIS 根據您實際使用的資源計費,能夠幫您節約計算成本。使用 CIS 能夠極大下降您部署容器的門檻,下降您執行 batch 型任務或處理業務突增的成本。css
本文將介紹Kubernetes部署和容器工做負載的相關內容。包含管理容器生命週期,部署多容器應用程序,擴展工做負載以及與Kubernetes進行協同工做。本文包括一些概念和命令,教你們快速入門Kubernetes,併入門CIS。html
Kubernetes是一個用於管理容器化應用程序的開源容器資源編排工具。前端
本文中,您將應用一些容器化的概念來構建、部署和管理Kubernetes中端到端的微服務應用程序。本文中使用的示例Web應用程序是一個用Node.js編寫的「待辦事項列表」應用程序,它使用MongoDB做爲數據庫。html5
本次將從Dockerfile中爲此應用程序構建容器鏡像,將鏡像推送到Docker Hub,而後部署到您的集羣。以便在將來您將擴展應用程序以知足不斷增加的需求。java
要完成本文,您須要:node
首先咱們將經過Web應用打包到Docker鏡像中。git
首先切換到您的主目錄,而後使用Git從GitHub上的克隆本文的示例Web應用程序。github
cd ~
git clone https://github.com/janakiramm/todo-app.git
複製代碼
從Dockerfile構建容器鏡像。使用-t
命令註冊用戶名,鏡像名稱和可選標記標記鏡像。
docker build -t sammy/todo .
複製代碼
確認鏡像已成功構建並正確標記。
Sending build context to Docker daemon 8.238MB
Step 1/7 : FROM node:slim
---> 286b1e0e7d3f
Step 2/7 : LABEL maintainer = "jani@janakiram.com"
---> Using cache
---> ab0e049cf6f8
Step 3/7 : RUN mkdir -p /usr/src/app
---> Using cache
---> 897176832f4d
Step 4/7 : WORKDIR /usr/src/app
---> Using cache
---> 3670f0147bed
Step 5/7 : COPY ./app/ ./
---> Using cache
---> e28c7c1be1a0
Step 6/7 : RUN npm install
---> Using cache
---> 7ce5b1d0aa65
Step 7/7 : CMD node app.js
---> Using cache
---> 2cef2238de24
Successfully built 2cef2238de24
Successfully tagged sammy/todo-app:latest
複製代碼
經過運行docker images
命令驗證是否已建立鏡像。
$ docker images
複製代碼
您能夠看到鏡像的大小以及建立的時間。
REPOSITORY TAG IMAGE ID CREATED SIZE
sammy/todo-app latest 81f5f605d1ca 9 minutes ago 236MB
複製代碼
接下來,將您的鏡像推送到Docker Hub上。請登陸Docker Hub賬戶:
docker login
複製代碼
輸入正確的用戶名及密碼,使用Docker Hub用戶名存儲您的鏡像:
docker tag your_docker_hub_username/todo-app
複製代碼
而後將鏡像推送到Docker Hub:
docker push
複製代碼
您能夠登陸Docker Hub官網搜索查看你的鏡像,來驗證新鏡像是否可用。
將Docker鏡像推送到Docker Hub後,接下來咱們能夠將應用程序打包爲Kubernetes。
這個應用程序使用MongoDB存儲經過Web應用程序建立的待辦事項列表。要在Kubernetes中運行MongoDB,咱們須要將其打包爲Pod。當咱們啓動這個Pod時,它將運行一個MongoDB實例。
建立一個名爲db-pod.yaml的新YAML文件:
nano db-pod.yaml
複製代碼
添加如下代碼,該代碼使用基於MongoDB的一個容器定義Pod。同時,咱們打開了MongoDB使用的標準端口port。請注意,定義包含名爲name和app的標籤。咱們將使用這些標籤來識別和配置特定的Pod。
apiVersion: v1
kind: Pod
metadata:
name: db
labels:
name: mongo
app: todoapp
spec:
containers:
- image: mongo
name: mongo
ports:
- name: mongo
containerPort: 27017
volumeMounts:
- name: mongo-storage
mountPath: /data/db
volumes:
- name: mongo-storage
hostPath:
path: /data/db
複製代碼
數據存儲在調用的卷中,該卷映射到節點的位置。有關卷的更多信息,請參閱Kubernetes官方文檔。
運行如下命令以建立Pod。
kubectl create -f db-pod.yml
複製代碼
你會看到這個輸出:
pod "db" created
複製代碼
如今咱們看看Pod是否建立。
kubectl get pods
複製代碼
顯示這個Pod正在運行:
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 2m
複製代碼
接下來咱們讓集羣的內部人員能夠管理訪問這個Pod。
建立一個名爲db-service.yaml的新文件,其中包含定義了MongoDB服務的代碼:
apiVersion: v1
kind: Service
metadata:
name: db
labels:
name: mongo
app: todoapp
spec:
selector:
name: mongo
type: ClusterIP
ports:
- name: db
port: 27017
targetPort: 27017
複製代碼
此服務將可以發現與name:db標籤相匹配的同一命名空間中的全部Pod 。YAML文件中的selector部分明確地定義了這種關聯關係。
咱們經過聲明type: ClusterIP可使服務在集羣中可見 。
保存文件並退出編輯器。而後使用kubectl將其提交到集羣。
kubectl create -f db-service.yml
複製代碼
您將看到此輸出指示服務已成功建立:
service "db" created
複製代碼
讓咱們來看看Pod可用的端口。
kubectl get services
複製代碼
您將看到如下的輸出結果:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.109.114.243 <none> 27017/TCP 14s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47m
複製代碼
從上圖的輸出結果中,您能夠看到該服務在端口27017上。Web應用程序能夠經過此服務訪問MongoDB。當它使用主機名db的時候,在Kubernetes中運行的DNS服務將解析與服務關聯的IP的地址。這種機制容許Pod之間相互檢測並通訊。
接下來咱們可使用數據庫Pod和Service,爲Web應用程序建立一個額外的Pod。
咱們將在本文第一步中建立的Docker鏡像打包爲Pod並將其部署到集羣。這將被做爲最終用戶可訪問的前端Web應用程序層。
建立一個名爲的新YAML文件:web-pod.yaml
nano web-pod.yaml
複製代碼
添加如下代碼,該代碼根據sammy/todo-app
的Docker鏡像定義具備一個容器的Pod 。它經過TCP協議展示在端口3000
上。
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
name: web
app: todoapp
spec:
containers:
- image: sammy/todo-app
name: myweb
ports:
- containerPort: 3000
複製代碼
運行如下命令以建立Pod:
kubectl create -f web-pod.yaml
複製代碼
pod "web" created
複製代碼
看看pod是否建立?
kubectl get pods
複製代碼
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 8m
web 1/1 Running 0 9s
複製代碼
咱們將MongoDB數據庫和Web應用程序都做爲Pod運行。
如今,咱們將使web Pod能夠訪問互聯網。
服務會在內部或外部公開一組Pod。讓咱們定義一個使web Pod能夠公開使用的服務。咱們將經過NodePort公開它。NodePort是一種經過在集羣的每一個節點上打開任意端口用來訪問Pod的方案。
建立一個名爲web-service.yaml的新文件,其中包含定義應用服務的代碼:
apiVersion: v1
kind: Service
metadata:
name: web
labels:
name: web
app: todoapp
spec:
selector:
name: web
type: NodePort
ports:
- name: http
port: 3000
targetPort: 3000
protocol: TCP
複製代碼
服務發現同一名稱空間中與Label匹配的全部Pod都具備名稱web。YAML文件的選擇器部分定義了此關聯。
咱們經過聲明type: NodePort指定NodePort的服務類型。
用kubectl將此提交到羣集。
kubectl create -f web-service.yml
複製代碼
您將看到此輸出指示服務已成功建立:
service "web" created
複製代碼
讓咱們來看看Pod可用的端口。
kubectl get services
複製代碼
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.109.114.243 <none> 27017/TCP 12m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 59m
web NodePort 10.107.206.92 <none> 3000:30770/TCP 12s
複製代碼
今後輸出中,咱們看到該服務在端口30770上可用。讓咱們嘗試鏈接到其中一個工做節點。
使用騰訊雲控制檯獲取與你服務器的IP地址:
得到IP地址後,使用curl命令向端口30770上的一個節點發出HTTP請求:
curl http://your_worker_ip_address:30770
複製代碼
您將看到以下的輸出:
<!DOCTYPE html>
<html>
<head>
<title>Containers Todo Example</title>
<link rel='stylesheet' href='/stylesheets/screen.css' />
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div id="layout">
<h1 id="page-title">Containers Todo Example</h1>
<div id="list">
<form action="/create" method="post" accept-charset="utf-8">
<div class="item-new">
<input class="input" type="text" name="content" />
</div>
</form>
</div>
<div id="layout-footer"></div>
</div>
<script src="/javascripts/ga.js"></script>
</body>
</html>
複製代碼
截至到此,您已經定義了Web Pod和服務。如今讓咱們看看如何使用副本集來縮放它。
副本集能夠確保始終在羣集中運行最少數量的Pod。當Pod被打包爲副本集時,Kubernetes將始終運行規範中定義的最小數量的Pod。
讓咱們刪除當前的Pod並經過副本集從新建立兩個Pod。若是咱們讓當前的Pod運行,它將不會是副本集的一部分。所以,咱們最好經過副本集啓動Pod,即便只有一個Pod。
首先,刪除現有的Pod。
kubectl delete pod web
複製代碼
pod "web" deleted
複製代碼
如今建立一個新的副本集聲明。副本集的定義與Pod相同。關鍵的區別在於它包含定義須要運行的Pod數量的replica
元素。與Pod同樣,它還包含有助於服務發現的元數據來做爲標籤。
建立web-rs.yaml
文件並將此代碼添加到文件中
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: web
labels:
name: web
app: todoapp
spec:
replicas: 2
template:
metadata:
labels:
name: web
spec:
containers:
- name: web
image: sammy/todo-app
ports:
- containerPort: 3000
複製代碼
保存並關閉文件。
如今建立副本集:
kubectl create -f web-rs.yaml
複製代碼
replicaset "web" created
複製代碼
而後檢查Pod的數量:
kubectl get pods
複製代碼
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 18m
web-n5l5h 1/1 Running 0 25s
web-wh6nf 1/1 Running 0 25s
複製代碼
當咱們經過NodePort訪問服務時,請求將被髮送到由副本集管理一個Pod中。
讓咱們經過刪除其中一個Pod,並查看發生的狀況來測試副本集的功能:
kubectl delete pod web-wh6nf
複製代碼
pod "web-wh6nf" deleted
複製代碼
讓咱們再來看一下Pods:
kubectl get pods
複製代碼
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 19m
web-n5l5h 1/1 Running 0 1m
web-wh6nf 1/1 Terminating 0 1m
web-ws59m 0/1 ContainerCreating 0 2s
複製代碼
刪除Pod後,Kubernetes會建立另外一個Pod副本,以確保其可以維持所需的計數。
咱們能夠擴展副本集以運行其餘的Web Pod。
運行如下命令將Web應用程序擴展爲10個Pod。
kubectl scale rs/web --replicas=10
複製代碼
replicaset "web" scaled
複製代碼
檢查Pod計數:
kubectl get pods
複製代碼
您將會會看到以下輸出:
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 22m
web-4nh4g 1/1 Running 0 21s
web-7vbb5 1/1 Running 0 21s
web-8zd55 1/1 Running 0 21s
web-f8hvq 0/1 ContainerCreating 0 21s
web-ffrt6 1/1 Running 0 21s
web-k6zv7 0/1 ContainerCreating 0 21s
web-n5l5h 1/1 Running 0 3m
web-qmdxn 1/1 Running 0 21s
web-vc45m 1/1 Running 0 21s
web-ws59m 1/1 Running 0 2m
複製代碼
此時,Kubernetes已經啓動了擴展web Pod 的過程。當請求經過NodePort到達服務時,它將被路由到副本集中的一個Pod。
當流量和負載消退時,咱們能夠恢復到兩個Pod的原始配置。
kubectl scale rs/web --replicas=2
複製代碼
replicaset "web" scaled
複製代碼
此命令將終止其他全部的Pod。
kubectl get pods
複製代碼
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 24m
web-4nh4g 1/1 Terminating 0 2m
web-7vbb5 1/1 Terminating 0 2m
web-8zd55 1/1 Terminating 0 2m
web-f8hvq 1/1 Terminating 0 2m
web-ffrt6 1/1 Terminating 0 2m
web-k6zv7 1/1 Terminating 0 2m
web-n5l5h 1/1 Running 0 5m
web-qmdxn 1/1 Terminating 0 2m
web-vc45m 1/1 Terminating 0 2m
web-ws59m 1/1 Running 0 4m
複製代碼
要驗證副本集的可用性,請嘗試刪除其中一個Pod並檢查計數。
kubectl delete pod web-ws59m
複製代碼
pod "web-ws59m" deleted
複製代碼
kubectl get pods
複製代碼
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 25m
web-n5l5h 1/1 Running 0 7m
web-ws59m 1/1 Terminating 0 5m
web-z6r2g 0/1 ContainerCreating 0 5s
複製代碼
一旦Pod計數發生變化,Kubernetes就會調整它以匹配YAML文件中定義的計數。刪除副本集中的一個Web Pod時,會當即建立另外一個Pod以保持所需的計數。這是經過確保最小數量的Pod可以持續運行來確保應用程序的高可用性。
您可使用如下命令刪除在本文中建立的全部對象:
kubectl delete -f db-pod.yaml -f db-service.yaml -f web-rs.yaml -f web-service.yaml
複製代碼
pod "db" deleted
service "db" deleted
replicaset "web" deleted
service "web" deleted
複製代碼
本文就先寫到這裏,歡迎你們使用騰訊雲CIS產品,產品連接:cloud.tencent.com/document/pr…
參考文獻:《Webinar Series: Deploying and Scaling Microservices in Kubernetes》
翻譯:Zach展,審校:Techeek
問答
相關閱讀
此文已由做者受權騰訊雲+社區發佈,原文連接:https://cloud.tencent.com/developer/article/1158254?fromSource=waitui
歡迎你們前往騰訊雲+社區或關注雲加社區微信公衆號(QcloudCommunity),第一時間獲取更多海量技術實踐乾貨哦~
海量技術實踐經驗,盡在雲加社區!