持續部署入門:基於 Kubernetes 實現滾動發布


前言

軟件世界比以往任何時候都更快。為了保持競爭力,需要盡快推出新的軟件版本,而不會中斷活躍用戶訪問,影響用戶體驗。越來越多企業已將其應用遷移到 Kubernetes。

在 Kubernetes 中有幾種不同的方式發布應用,所以為了讓應用在升級期間依然平穩提供服務,選擇一個正確的發布策略就非常重要了,本篇文章將講解如何在 Kubernetes 使用滾動更新的方式更新鏡像。

原理

策略定義為 RollingUpdate 的 Deployment。滾動更新通過逐個替換實例來逐步部署新版本的應用,直到所有實例都被替換完成為止,會有新版舊版同時存在的情況。

spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0			# 決定了配置中期望的副本數之外,最多允許超出的 pod 實例的數量
      maxUnavailable: %25	# 決定了在滾動升級期間,相對於期望副本數能夠允許有多少 pod 實例處於不可用狀態

上述更新策略執行結果如下圖所示

實踐

使用 Kubernetes 原生方式升級應用

准備

image

bebullish/demo:v1
bebullish/demo:v2

deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-dp
spec:
  selector:
    matchLabels:
      app: demo
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  template:
    metadata:
      labels:
        app: demo
    spec: 
      containers:
      - name: demo
        image: bebullish/demo:v1
        ports:
        - containerPort: 8080

service

apiVersion: v1
kind: Service
metadata:
  name: demo-service
spec:
  selector:
    app: demo
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

將上述 deployment 以及 service 保存為 yaml 文件,使用 kubectl apply -f 命令創建 yaml 資源,等待創建成功后,使用 kubectl get svc 獲取 EXTERNAL-IP。

測試

如果使用瀏覽器測試的話,你會發現每次調用都會返回同一個 pod 的名字,那是因為瀏覽器發出的請求包含 keepAlive,所以需要使用 curl 來保證每次發出的請求都是重新創建的。

curl -X GET http://${EXTERNAL-IP}

升級

升級之前先執行命令,以便查看鏡像更新過程

while true; do curl -X GET http://${EXTERNAL-IP} ; done

更新鏡像

kubectl set image deployment demo-dp demo=bebullish/demo:v2

查看日志

請求流量

結論

首先可以發現在更新過程中,程序保持一直可用的狀態,在出現了 v2 版本之后,還會出現 v1 版本的日志,說明在這個期間 v1 和 v2 版本是同時存在的,等到 v2 版本的 pod 全部處於就緒狀態之后,可以看到所有的請求就都是 v2 版本的了。

使用 CODING CD 方式升級應用

配置制品

使用 docker 官方鏡像需要以 docker.io 開頭

配置 yaml 及綁定制品

deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-dp
spec:
  selector:
    matchLabels:
      app: demo
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  template:
    metadata:
      labels:
        app: demo
    spec: 
      containers:
      - name: demo
        image: docker.io/bebullish/demo
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 30           # 延遲 30 秒檢測,以便更好的觀察更新過程
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 30           # 延遲 30 秒檢測,以便更好的觀察更新過程
          periodSeconds: 5
      terminationGracePeriodSeconds: 1      # 處於 Terminating 狀態多久后,強制殺死 pod

階段中選擇 部署(Manifest) ,輸入上述 yaml 文件(主要增加了就緒探針和存活探針),這里需要把鏡像的版本刪除掉,在需要綁定的制品選擇之前配置的制品。這樣配置之后,每次執行的時候版本是動態傳入的。

發布制品

選擇應用和部署流程,輸入版本 v1。

查看結果

等待一小段時間后,就可以在部署控制台中看到發布的資源了。

更新鏡像版本

再次執行發布,版本輸入 v2。

更新過程

可以看到此時 v2 版本的 pod 有一個正在啟動,而 v1 版本的 pod 全部處於就緒狀態。

v2 版本的 pod 有一個已經就緒,同時正在啟動另一個新的 pod,與此同時 v1 版本的有一個 pod 已經關機了,而另外兩個 pod 仍處於就緒狀態。

v2 版本的 pod 有兩個已經就緒,同時正在啟動最后一個新的 pod,與此同時 v1 版本的有兩個 pod 已經關機了,而另外一個 pod 仍處於就緒狀態。

v2 版本的 pod 已經全部處於就緒狀態了,同時 v1 版本的 pod 已經全部關機,至此,一次滾動更新結束。

總結

使用 Kubernetes 原生方式實現滾動更新更加簡單方便,但也容易出錯(人工),推薦使用 coding.net 提供的 CD 功能,配置一次,永久使用。不僅可以直觀的觀察到 pod 更新過程,還提供了非常豐富的 CD 功能,推薦使用哦~

參考文章

Kuerbenetes

CODING 持續部署

【騰訊雲原生】雲說新品、雲研新術、雲游新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM