入門系列之Kubernetes部署

入門系列之Kubernetes部署

來自專欄騰訊雲+社區11 人贊了文章

歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~

本文由林岑影 發表於雲+社區專欄

容器實例服務(Container Instance Service , CIS)可以幫您在雲上快捷、靈活的部署容器,讓您專註於構建程序和使用容器而非管理設備上。無需預購 CVM,您就可以在幾秒內啟動一批容器來執行任務。您也可以通過 kubernetes API 把已有 kubernetes 集群的 pod 調度到 CIS 上以處理突增業務。CIS 根據您實際使用的資源計費,可以幫您節約計算成本。使用 CIS 可以極大降低您部署容器的門檻,降低您執行 batch 型任務或處理業務突增的成本。

本文將介紹Kubernetes部署和容器工作負載的相關內容。包含管理容器生命周期,部署多容器應用程序,擴展工作負載以及與Kubernetes進行協同工作。本文包括一些概念和命令,教大家快速入門Kubernetes,併入門CIS。

介紹

Kubernetes是一個用於管理容器化應用程序的開源容器資源編排工具。

本文中,您將應用一些容器化的概念來構建、部署和管理Kubernetes中端到端的微服務應用程序。本文中使用的示例Web應用程序是一個用Node.js編寫的「待辦事項列表」應用程序,它使用MongoDB作為資料庫。

本次將從Dockerfile中為此應用程序構建容器鏡像,將鏡像推送到Docker Hub,然後部署到您的集群。以便在未來您將擴展應用程序以滿足不斷增長的需求。

準備

要完成本文,您需要:

  • Kubernetes集群,您可以參考騰訊雲開發者實驗室產品進行入門。
  • 用於存儲鏡像的Docker Hub帳戶。
  • 在本地機器安裝docker,您也可以參考騰訊雲開發者實驗室產品進行入門。

第一步,使用Dockerfile構建鏡像

首先我們將通過Web應用打包到Docker鏡像中。

首先切換到您的主目錄,然後使用Git從GitHub上的克隆本文的示例Web應用程序。

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。

第二步,在Kubernetes中部署MongoDB Pod

這個應用程序使用MongoDB存儲通過Web應用程序創建的待辦事項列表。要在Kubernetes中運行MongoDB,我們需要將其打包為Pod。當我們啟動這個Pod時,它將運行一個MongoDB實例。

創建一個名為db-pod.yaml的新YAML文件:

nano db-pod.yaml

添加以下代碼,該代碼使用基於MongoDB的一個容器定義Pod。同時,我們打開了MongoDB使用的標準埠port。請注意,定義包含名為name和app的標籤。我們將使用這些標籤來識別和配置特定的Pod。

apiVersion: v1kind: Podmetadata: 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 AGEdb 1/1 Running 0 2m

接下來我們讓集群的內部人員可以管理訪問這個Pod。

創建一個名為db-service.yaml的新文件,其中包含定義了MongoDB服務的代碼:

apiVersion: v1kind: Servicemetadata: 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) AGEdb ClusterIP 10.109.114.243 <none> 27017/TCP 14skubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47m

從上圖的輸出結果中,您可以看到該服務在埠27017上。Web應用程序可以通過此服務訪問MongoDB。當它使用主機名db的時候,在Kubernetes中運行的DNS服務將解析與服務關聯的IP的地址。這種機制允許Pod之間相互檢測並通信。

接下來我們可以使用資料庫Pod和Service,為Web應用程序創建一個額外的Pod。

第三步,將Node.JS Web App部署為Pod

我們將在本文第一步中創建的Docker鏡像打包為Pod並將其部署到集群。這將被作為最終用戶可訪問的前端Web應用程序層。

創建一個名為的新YAML文件:web-pod.yaml

nano web-pod.yaml

添加以下代碼,該代碼根據sammy/todo-app的Docker鏡像定義具有一個容器的Pod 。它通過TCP協議展現在埠3000上。

apiVersion: v1kind: 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.yamlpod "web" created

看看pod是否創建?

kubectl get podsNAME READY STATUS RESTARTS AGEdb 1/1 Running 0 8mweb 1/1 Running 0 9s

我們將MongoDB資料庫和Web應用程序都作為Pod運行。

現在,我們將使web Pod可以訪問互聯網。

服務會在內部或外部公開一組Pod。讓我們定義一個使web Pod可以公開使用的服務。我們將通過NodePort公開它。NodePort是一種通過在集群的每個節點上打開任意埠用來訪問Pod的方案。

創建一個名為web-service.yaml的新文件,其中包含定義應用服務的代碼:

apiVersion: v1kind: Servicemetadata: 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 servicesNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdb ClusterIP 10.109.114.243 <none> 27017/TCP 12mkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 59mweb 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和服務。現在讓我們看看如何使用副本集來縮放它。

第5步 - 擴展Web應用程序

副本集可以確保始終在群集中運行最少數量的Pod。當Pod被打包為副本集時,Kubernetes將始終運行規範中定義的最小數量的Pod。

讓我們刪除當前的Pod並通過副本集重新創建兩個Pod。如果我們讓當前的Pod運行,它將不會是副本集的一部分。因此,我們最好通過副本集啟動Pod,即使只有一個Pod。

首先,刪除現有的Pod。

kubectl delete pod webpod "web" deleted

現在創建一個新的副本集聲明。副本集的定義與Pod相同。關鍵的區別在於它包含定義需要運行的Pod數量的replica元素。與Pod一樣,它還包含有助於服務發現的元數據來作為標籤。

創建web-rs.yaml文件並將此代碼添加到文件中

apiVersion: extensions/v1beta1kind: ReplicaSetmetadata: name: web labels: name: web app: todoappspec: replicas: 2 template: metadata: labels: name: web spec: containers: - name: web image: sammy/todo-app ports: - containerPort: 3000

保存並關閉文件。

現在創建副本集:

kubectl create -f web-rs.yamlreplicaset "web" created

然後檢查Pod的數量:

kubectl get podsNAME READY STATUS RESTARTS AGEdb 1/1 Running 0 18mweb-n5l5h 1/1 Running 0 25sweb-wh6nf 1/1 Running 0 25s

當我們通過NodePort訪問服務時,請求將被發送到由副本集管理一個Pod中。

讓我們通過刪除其中一個Pod,並查看發生的情況來測試副本集的功能:

kubectl delete pod web-wh6nfpod "web-wh6nf" deleted

讓我們再來看一下Pods:

kubectl get podsNAME READY STATUS RESTARTS AGEdb 1/1 Running 0 19mweb-n5l5h 1/1 Running 0 1mweb-wh6nf 1/1 Terminating 0 1mweb-ws59m 0/1 ContainerCreating 0 2s

刪除Pod後,Kubernetes會創建另一個Pod副本,以確保其能夠維持所需的計數。

我們可以擴展副本集以運行其他的Web Pod。

運行以下命令將Web應用程序擴展為10個Pod。

kubectl scale rs/web --replicas=10replicaset "web" scaled

檢查Pod計數:

kubectl get pods

您將會會看到如下輸出:

NAME READY STATUS RESTARTS AGEdb 1/1 Running 0 22mweb-4nh4g 1/1 Running 0 21sweb-7vbb5 1/1 Running 0 21sweb-8zd55 1/1 Running 0 21sweb-f8hvq 0/1 ContainerCreating 0 21sweb-ffrt6 1/1 Running 0 21sweb-k6zv7 0/1 ContainerCreating 0 21sweb-n5l5h 1/1 Running 0 3mweb-qmdxn 1/1 Running 0 21sweb-vc45m 1/1 Running 0 21sweb-ws59m 1/1 Running 0 2m

此時,Kubernetes已經啟動了擴展web Pod 的過程。當請求通過NodePort到達服務時,它將被路由到副本集中的一個Pod。

當流量和負載消退時,我們可以恢復到兩個Pod的原始配置。

kubectl scale rs/web --replicas=2replicaset "web" scaled

此命令將終止其餘所有的Pod。

kubectl get podsNAME READY STATUS RESTARTS AGEdb 1/1 Running 0 24mweb-4nh4g 1/1 Terminating 0 2mweb-7vbb5 1/1 Terminating 0 2mweb-8zd55 1/1 Terminating 0 2mweb-f8hvq 1/1 Terminating 0 2mweb-ffrt6 1/1 Terminating 0 2mweb-k6zv7 1/1 Terminating 0 2mweb-n5l5h 1/1 Running 0 5mweb-qmdxn 1/1 Terminating 0 2mweb-vc45m 1/1 Terminating 0 2mweb-ws59m 1/1 Running 0 4m

要驗證副本集的可用性,請嘗試刪除其中一個Pod並檢查計數。

kubectl delete pod web-ws59mpod "web-ws59m" deletedkubectl get podsNAME READY STATUS RESTARTS AGEdb 1/1 Running 0 25mweb-n5l5h 1/1 Running 0 7mweb-ws59m 1/1 Terminating 0 5mweb-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.yamlpod "db" deletedservice "db" deletedreplicaset "web" deletedservice "web" deleted

本文就先寫到這裡,歡迎大家使用騰訊雲CIS產品,產品鏈接:cloud.tencent.com/docum


參考文獻:《Webinar Series: Deploying and Scaling Microservices in Kubernetes》

翻譯:Zach展,審校:Techeek

問答

如何使用Kubernetes?

相關閱讀

GAME-TECH降落長沙,騰訊遊戲雲全面解析遊戲技術生態

MySQL 8.0 版本功能變更介紹

為你的網站加一道防線,騰訊雲伺服器安裝配置SimpleSAMLphp指南

此文已由作者授權騰訊雲+社區發布,原文鏈接:cloud.tencent.com/devel

歡迎大家前往騰訊雲+社區或關注云加社區微信公眾號(QcloudCommunity),第一時間獲取更多海量技術實踐乾貨哦~

海量技術實踐經驗,盡在雲加社區!


推薦閱讀:

圖引擎,了解他的強大
七劍合璧——聚通達攜七大產品亮相中國雲計算技術應用大會
微軟的決絕:抱緊雲與 AI 的未來
OpenStack juno版 安裝配置——第九章(Cinder)
OpenStack juno版 安裝配置——第五章(Nova)

TAG:Docker | Kubernetes | 雲計算 |