入門系列之Kubernetes部署

騰訊雲加社群發表於2018-07-13

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

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

容器例項服務(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,然後部署到您的叢集。以便在未來您將擴充套件應用程式以滿足不斷增長的需求。

準備

要完成本文,您需要:

第一步,使用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: 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。

第三步,將Node.JS Web App部署為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地址:

img

獲得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 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

問答

如何使用Kubernetes?

相關閱讀

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

MySQL 8.0 版本功能變更介紹

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

此文已由作者授權騰訊雲+社群釋出,原文連結:https://cloud.tencent.com/developer/article/1158254?fromSource=waitui

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

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

相關文章