溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Step by Step!Kubernetes持續(xù)部署指南

發(fā)布時間:2020-05-10 03:11:15 來源:網(wǎng)絡 閱讀:678 作者:RancherLabs 欄目:云計算

本文是作者通過親身實踐,從零基礎開始,一步一步總結出來的Kubernetes持續(xù)部署工作流程。文章從前期的工具準備開始,到復刻存儲庫、測試、構建鏡像、構建流水線最后進行部署,所有的工作流程都一一展現(xiàn)在文章中,對于想要擁有全自動持續(xù)交付流水線的用戶將有很大的借鑒意義。
 
Step by Step!Kubernetes持續(xù)部署指南

 

 
在很久很久以前的一份工作中,我的任務是將老式的LAMP堆棧切換到Kubernetes上。那會兒我的老板總是追逐新技術,認為只需要幾天時間就能夠完成新舊技術的迭代——鑒于那時我們甚至對容器的工作機制一無所知,所以不得不說老板的想法真的很大膽。

 

在閱讀了官方文檔并且搜索了很多信息之后,我們開始感到不知所措——有許多新的概念需要學習:pod、容器以及replica等。對我而言,Kubernetes似乎只是為一群聰明的開發(fā)者而設計的。

 

然后我做了我在這一狀況下常做的事:通過實踐來學習。通過一個簡單的例子可以很好地理解錯綜復雜的問題,所以我自己一步一步完成了整個部署過程。

 

最后,我們做到了,雖然遠未達到規(guī)定的一周時間——我們花了將近一個月的時間來創(chuàng)建三個集群,包括它們的開發(fā)、測試和生產(chǎn)。

 

本文我將詳細介紹如何將應用程序部署到Kubernetes。閱讀完本文之后,你將擁有一個高效的Kubernetes部署和持續(xù)交付工作流程。
 

持續(xù)集成與交付

 

持續(xù)集成是在每次應用程序更新時構建和測試的實踐。通過以少量的工作,更早地檢測到錯誤并立即解決。
 

集成完成并且所有測試都通過之后,我們就能夠添加持續(xù)交付到自動化發(fā)布和部署的流程中。使用CI/CD的項目可以更頻繁、更可靠地發(fā)布。

 

我們將使用Semaphore,這是一個快速、強大且易用地持續(xù)集成和交付(CI/CD)平臺,它能夠自動執(zhí)行所有流程:

 

1、 安裝項目依賴項

2、 運行單元測試

3、 構建一個Docker鏡像

4、 Push鏡像到Docker Hub

5、 一鍵Kubernetes部署

 

對于應用程序,我們有一個Ruby Sinatra微服務,它暴露一些HTTP端點。該項目已包含部署所需的所有內(nèi)容,但仍需要一些組件。
 

準備工作

 

在開始操作之前,你需要登錄Github和Semaphore賬號。此外,為后續(xù)方便拉取或push Docker鏡像,你需要登錄Docker Hub。

 

接下來,你需要在計算機上安裝一些工具:

 

  • Git:處理代碼

  • curl:網(wǎng)絡的“Swiss Knife”

  • kubectl:遠程控制你的集群

 

當然,千萬不要忘了Kubernetes。大部分的云供應商都以各種形式提供此服務,選擇適合你的需求的即可。最低端的機器配置和集群大小足以運行我們示例的app。我喜歡從3個節(jié)點的集群開始,但你可以只用1個節(jié)點的集群。
 

集群準備好之后,從你的供應商中下載kubeconfig文件。有些允許你直接從其web控制臺下載,有些則需要幫助程序。我們需要此文件才能連接到集群。

 

有了這個,我們已經(jīng)可以開始了。首先要做的是fork存儲庫。
 

Fork存儲庫

 

在這篇文章中fork我們將使用的演示應用程序。

 

  1. 訪問semaphore-demo-ruby-kubernetes存儲庫,并且點擊右上方的Fork按鈕

  2. 點擊Clone or download按鈕并且復制地址

  3. 復制存儲庫:$ git clone https://github.com/your_repository_path…

 

使用Semaphore連接新的存儲庫

 

1、 登錄到你的Semaphore

2、 點擊側邊欄的鏈接,創(chuàng)建一個新項目

3、 點擊你的存儲庫旁【Add Repository】按鈕
 

使用Semaphore測試

 

持續(xù)集成讓測試變得有趣并且高效。一個完善的CI 流水線能夠創(chuàng)建一個快速反饋回路以在造成任何損失之前發(fā)現(xiàn)錯誤。我們的項目附帶一些現(xiàn)成的測試。

 

打開位于.semaphore/semaphore.yml的初始流水線文件,并快速查看。這個流水線描述了Semaphore構建和測試應用程序所應遵循的所有步驟。它從版本和名稱開始。
 

version: v1.0
name: CI

 
接下來是agent,它是為job提供動力的虛擬機。我們可以從3種類型中選擇:
 

agent:
  machine:
    type: e1-standard-2
    os_image: ubuntu1804

 
Block(塊)、任務以及job定義了在流水線的每個步驟中要執(zhí)行的操作。在Semaphore,block按照順序運行,與此同時,在block中的job也會并行運行。流水線包含2個block,一個是用于庫安裝,一個用于運行測試。
 
Step by Step!Kubernetes持續(xù)部署指南
 
第一個block下載并安裝了Ruby gems。
 

- name: Install dependencies
  task:
    jobs:
      - name: bundle install
        commands:
          - checkout
          - cache restore gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),gems-$SEMAPHORE_GIT_BRANCH,gems-master
          - bundle install --deployment --path .bundle
          - cache store gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock) .bundle

 
Checkout復制了Github里的代碼。既然每個job都在完全隔離的機器里運行,那么我們必須依賴緩存(cache)來在job運行之間存儲和檢索文件。
 


blocks:
  - name: Install dependencies
    task:
      jobs:
        - name: bundle install
          commands:
            - checkout
            - cache restore gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),gems-$SEMAPHORE_GIT_BRANCH,gems-master
            - bundle install --deployment --path .bundle
            - cache store gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock) .bundle

 
第二個block進行測試。請注意我們重復使用了checkout和cache的代碼以將初始文件放入job中。最后一個命令用于啟動RSpec測試套件。
 

- name: Tests
  task:
    jobs:
      - name: rspec
        commands:
          - checkout
          - cache restore gems-$SEMAPHORE_GIT_BRANCH-$(checksum Gemfile.lock),gems-$SEMAPHORE_GIT_BRANCH,gems-master
          - bundle install --deployment --path .bundle
          - bundle exec rspec

 
最后一個部分我們來看看Promotion。Promotion能夠在一定條件下連接流水線以創(chuàng)建復雜的工作流程。所有job完成之后,我們使用 auto_promote_on來啟動下一個流水線。
 

promotions:
  - name: Dockerize
    pipeline_file: docker-build.yml
    auto_promote_on:
      - result: passed

 
工作流程繼續(xù)執(zhí)行下一個流水線。

 

構建Docker鏡像

 

我們可以在Kubernetes上運行任何東西,只要它打包在Docker鏡像中。在這一部分,我們將學習如何構建鏡像。
 

我們的Docker鏡像將包含應用程序的代碼、Ruby以及所有的庫。讓我們先來看一下Dockerfile:
 

FROM ruby:2.5

RUN apt-get update -qq && apt-get install -y build-essential

ENV APP_HOME /app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

ADD Gemfile* $APP_HOME/
RUN bundle install --without development test

ADD . $APP_HOME

EXPOSE 4567

CMD ["bundle", "exec", "rackup", "--host", "0.0.0.0", "-p", "4567"]

 
Dockerfile就像一個詳細的菜譜,包含所有構建容器鏡像所需要的步驟和命令:

 

1、 從預構建的ruby鏡像開始

2、 使用apt-get安裝構建工具

3、 復制Gemfile,因為它具有所有的依賴項

4、 用bundle安裝它們

5、 復制app的源代碼

6、 定義監(jiān)聽端口和啟動命令
 

我們將在Semaphore環(huán)境中bake我們的生產(chǎn)鏡像。然而,如果你想要在計算機上進行一個快速的測試,那么請輸入:
 

$ docker build . -t test-image

 
使用Docker運行和暴露內(nèi)部端口4567以在本地啟動服務器
 

$ docker run -p 4567:4567 test-image

 
你現(xiàn)在可以測試一個可用的HTTP端點:
 

$ curl -w "\n" localhost:4567
hello world :))

 

添加Docker Hub賬戶到Semaphore

 

Semaphore有一個安全的機制以存儲敏感信息,如密碼、令牌或密鑰等。為了能夠push鏡像到你的Docker Hub鏡像倉庫中,你需要使用你的用戶名和密碼來創(chuàng)建一個Secret:

 

  1. 打開你的Semaphore

  2. 在左側導航欄中,點擊【Secret】

  3. 點擊【Creat New Secret】

  4. Secret的名字應該是Dockerhub,鍵入登錄信息(如下圖所示),并保存。

 
Step by Step!Kubernetes持續(xù)部署指南
 

構建Docker流水線

 

這個流水線開始構建并且push鏡像到Docker Hub,它僅僅有1個block和1個job:
 
Step by Step!Kubernetes持續(xù)部署指南
 
這次,我們需要使用更好的性能,因為Docker往往更加耗費資源。我們選擇具有四個CPU,8GB RAM和35GB磁盤空間的中端機器e1-standard-4:
 

version: v1.0
name: Docker build
agent:
  machine:
    type: e1-standard-4
    os_image: ubuntu1804

 
構建block通過登錄到Docker Hub啟動,用戶名和密碼可以從我們剛創(chuàng)建的secret導入。登錄之后,Docker可以直接訪問鏡像倉庫。

 

下一個命令是docker pull,它試圖拉取最新鏡像。如果找到鏡像,那么Docker可能能夠重新使用其中的一些層,以加速構建過程。如果沒有最新鏡像,也無需擔心,只是需要花費長一點的時間來構建。

 

最后,我們push新的鏡像。注意,這里我們使用SEMAPHORE_WORKFLOW_ID 變量來標記鏡像。
 

blocks:
  - name: Build
    task:
      secrets:
        - name: dockerhub
      jobs:
      - name: Docker build
        commands:
          - echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
          - checkout
          - docker pull "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:latest || true
          - docker build --cache-from "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:latest -t "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:$SEMAPHORE_WORKFLOW_ID .
          - docker images
          - docker push "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:$SEMAPHORE_WORKFLOW_ID

 
當鏡像準備完畢,我們進入項目的交付階段。我們將用手動promotion來擴展我們的Semaphore 流水線。
 

promotions:
  - name: Deploy to Kubernetes
    pipeline_file: deploy-k8s.yml

 
要進行第一次自動構建,請進行push:
 

$ touch test-build
$ git add test-build
$ git commit -m "initial run on Semaphore“
$ git push origin master

 
鏡像準備完成之后,我們就可以進入部署階段。
 

部署到Kubernetes

 

自動部署是Kubernetes的強項。我們所需要做的就是告訴集群我們最終的期望狀態(tài),剩下的將由它來負責。
 

然而,在部署之前,你必須將kubeconfig文件上傳到Semaphore。
 

上傳Kubeconfig到Semaphore

 

我們需要第二個secret:集群的kubeconfig。這個文件授予可以對它的管理訪問權限。因此,我們不希望將文件簽入存儲庫。

 

創(chuàng)建一個名為do-k8s的secret并且將kubeconfig文件上傳到/home/semaphore/.kube/dok8s.yaml中:
 
Step by Step!Kubernetes持續(xù)部署指南
 

部署清單

 

盡管Kubernetes已經(jīng)是容器編排平臺,但是我們不直接管理容器。實際上,部署的最小單元是pod。一個pod就好像一群形影不離的朋友,總是一起去同一個地方。因此要保證在pod中的容器運行在同一個節(jié)點上并且有相同的IP。它們可以同步啟動和停止,并且由于它們在同一臺機器上運行,因此它們可以共享資源。

 

pod的問題在于它們可以隨時啟動和停止,我們沒辦法確定它們會被分配到的pod IP。要把用戶的http流量轉發(fā),還需要提供一個公共IP和一個負載均衡器,它負責跟蹤pod和轉發(fā)客戶端的流量。

 

打開位于deploymente.yml的文件。這是一個部署我們應用程序的清單,它被3個dash分離成兩個資源。第一個,部署資源:
 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: semaphore-demo-ruby-kubernetes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: semaphore-demo-ruby-kubernetes
  template:
    metadata:
      labels:
        app: semaphore-demo-ruby-kubernetes
    spec:
      containers:
        - name: semaphore-demo-ruby-kubernetes
          image: $DOCKER_USERNAME/semaphore-demo-ruby-kubernetes:$SEMAPHORE_WORKFLOW_ID

 
這里有幾個概念需要厘清:

 

  • 資源都有一個名稱和幾個標簽,以便組織

  • Spec定義了最終期望的狀態(tài),template是用于創(chuàng)建Pod的模型。

  • Replica設置要創(chuàng)建的pod的副本數(shù)。我們經(jīng)常將其設置為集群中的節(jié)點數(shù)。既然我們使用了3個節(jié)點,我將這一命令行更改為replicas:3

 
第二個資源是服務。它綁定到端口80并且將HTTP流量轉發(fā)到部署中的pod:
 


---

apiVersion: v1
kind: Service
metadata:
  name: semaphore-demo-ruby-kubernetes-lb
spec:
  selector:
    app: semaphore-demo-ruby-kubernetes
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 4567

 
Kubernetes將selector與標簽相匹配以便將服務與pod連接起來。因此,我們在同一個集群中有許多服務和部署并且根據(jù)需要連接他們。
 

部署流水線

 

我們現(xiàn)在進入CI/CD配置的最后一個階段。這時,我們有一個定義在semaphore.yml的CI流水線,以及定義在docker-build.yml的Docker流水線。在這一步中,我們將部署到Kubernetes。

 

打開位于.semaphore/deploy-k8s.yml的部署流水線:
 

version: v1.0
name: Deploy to Kubernetes
agent:
  machine:
    type: e1-standard-2
    os_image: ubuntu1804

 
兩個job組成最后的流水線:
 
Step by Step!Kubernetes持續(xù)部署指南
 
Job 1開始部署。導入kubeconfig文件之后,envsubst將deployment.yaml中的占位符變量替換為其實際值。然后,kubectl apply將清單發(fā)送到集群。
 


blocks:
  - name: Deploy to Kubernetes
    task:
      secrets:
        - name: do-k8s
        - name: dockerhub

      env_vars:
        - name: KUBECONFIG
          value: /home/semaphore/.kube/dok8s.yaml

      jobs:
      - name: Deploy
        commands:
          - checkout
          - kubectl get nodes
          - kubectl get pods
          - envsubst < deployment.yml | tee deployment.yml
          - kubectl apply -f deployment.yml

 
Job 2將鏡像標記為最新,以讓我們能夠在下一次運行中將其作為緩存使用。
 

- name: Tag latest release
  task:
    secrets:
      - name: dockerhub
    jobs:
    - name: docker tag latest
      commands:
        - echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
        - docker pull "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:$SEMAPHORE_WORKFLOW_ID
        - docker tag "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:$SEMAPHORE_WORKFLOW_ID "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:latest
        - docker push "${DOCKER_USERNAME}"/semaphore-demo-ruby-kubernetes:latest

 
這是工作流程的最后一步了。
 

部署應用程序

 

讓我們教我們的Sinatra應用程序唱歌。在app.rb中的App類中添加以下代碼:
 

get "/sing" do
  "And now, the end is near
   And so I face the final curtain..."
end

 
推送修改的文件到Github:
 

$ git add .semaphore/*
$ git add deployment.yml
$ git add app.rb
$ git commit -m "test deployment”
$ git push origin master

 
等到docker構建流水線完成,你可以查看Semaphore的進度:
 
Step by Step!Kubernetes持續(xù)部署指南
 
是時候進行部署了,點擊Promote按鈕,看它是否工作:
 
Step by Step!Kubernetes持續(xù)部署指南
 
我們已經(jīng)有了一個好的開始,現(xiàn)在就看Kubernetes的了。我們可以使用kubectl檢查部署狀態(tài),初始狀態(tài)是三個所需的pod并且零可用:
 

$ kubectl get deployments
NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
semaphore-demo-ruby-kubernetes   3         0         0            0           15m

 
幾秒之后,pod已經(jīng)啟動,reconciliation已經(jīng)完成:
 

$ kubectl get deployments
NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
semaphore-demo-ruby-kubernetes   3         3         3            3           15m

 
使用get all獲得集群的通用狀態(tài),它顯示了pod、服務、部署以及replica:
 


$ kubectl get all
NAME                                                  READY   STATUS    RESTARTS   AGE
pod/semaphore-demo-ruby-kubernetes-7d985f8b7c-454dh   1/1     Running   0          2m
pod/semaphore-demo-ruby-kubernetes-7d985f8b7c-4pdqp   1/1     Running   0          119s
pod/semaphore-demo-ruby-kubernetes-7d985f8b7c-9wsgk   1/1     Running   0          2m34s

NAME                                        TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)        AGE
service/kubernetes                          ClusterIP      10.12.0.1              443/TCP        24m
service/semaphore-demo-ruby-kubernetes-lb   LoadBalancer   10.12.15.50   35.232.70.45   80:31354/TCP   17m

NAME                                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/semaphore-demo-ruby-kubernetes   3         3         3            3           17m

NAME                                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/semaphore-demo-ruby-kubernetes-7d985f8b7c   3         3         3       2m3

 
Service IP在pod之后展示。對于我來說,負載均衡器被分配到外部IP 35.232.70.45。需要將其更改為你的提供商分配給你的那個,然后我們來試試新的服務器。
 

$ curl -w "\n" http://YOUR_EXTERNAL_IP/sing

 
現(xiàn)在,離結束已經(jīng)不遠了。
 

勝利近在咫尺

 

當你使用了正確的CI/CD解決方案之后,部署到Kubernetes并不是那么困難。你現(xiàn)在擁有一個Kubernetes的完全自動的持續(xù)交付流水線啦。

 

這里有幾個建議可以讓你在Kubernetes上隨意fork并玩轉semaphore-demo-ruby-kubernetes:

 

  • 創(chuàng)建一個staging集群

  • 構建一個部署容器并且在里面運行測試

  • 使用更多微服務擴展項目
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI