Kubernetes
  • 序言
  • 基礎入門
    • Kubernetes 簡介
    • Kubernetes 基本概念
    • Kubernetes 101
    • Kubernetes 201
    • Kubernetes 集群
  • 核心原理
    • 核心原理
    • 架構原理
    • 設計理念
    • 核心組件
      • etcd
      • kube-apiserver
      • kube-scheduler
      • kube-controller-manager
      • kubelet
      • kube-proxy
      • kube-dns
      • Federation
      • kubeadm
      • hyperkube
      • kubectl
    • 資源對象
      • Autoscaling
      • ConfigMap
      • CronJob
      • CustomResourceDefinition
      • DaemonSet
      • Deployment
      • Ingress
      • Job
      • LocalVolume
      • Namespace
      • NetworkPolicy
      • Node
      • PersistentVolume
      • Pod
      • PodPreset
      • ReplicaSet
      • Resource Quota
      • Secret
      • SecurityContext
      • Service
      • ServiceAccount
      • StatefulSet
      • Volume
  • 部署配置
    • 部署指南
    • kubectl 安裝
    • 單機部署
    • 特性開關
    • 最佳配置
    • 版本支持
    • 集群部署
      • kubeadm
      • kops
      • Kubespray
      • Azure
      • Windows
      • LinuxKit
      • kubeasz
    • 附加組件
      • Addon-manager
      • DNS
      • Dashboard
      • 監控
      • 日誌
      • Metrics
      • GPU
      • Cluster Autoscaler
      • ip-masq-agent
    • Kubernetes-The-Hard-Way
      • 準備部署環境
      • 安裝必要工具
      • 創建計算資源
      • 配置創建證書
      • 配置生成配置
      • 配置生成密鑰
      • 部署 Etcd 群集
      • 部署控制節點
      • 部署計算節點
      • 配置 Kubectl
      • 配置網絡路由
      • 部署 DNS 擴展
      • 煙霧測試
      • 刪除集群
  • 插件擴展
    • API 擴展
      • Aggregation
      • CustomResourceDefinition
    • 訪問控制
      • 認證
      • RBAC 授權
      • 准入控制
    • Scheduler 擴展
    • 網絡插件
      • CNI
      • Flannel
      • Calico
      • Weave
      • Cilium
      • OVN
      • Contiv
      • SR-IOV
      • Romana
      • OpenContrail
      • Kuryr
    • 運行時插件 CRI
      • CRI-tools
      • Frakti
    • 存儲插件
      • 容器存儲接口 CSI
      • FlexVolume
      • glusterfs
    • 網絡策略
    • Ingress Controller
      • Ingress + Letsencrypt
      • minikube Ingress
      • Traefik Ingress
      • Keepalived-VIP
    • Cloud Provider 擴展
    • Device 插件
  • 服務治理
    • 服務治理
      • 一般準則
      • 滾動升級
      • Helm
      • Operator
      • Service Mesh
      • Linkerd
      • Linkerd2
    • Istio
      • 安裝
      • 流量管理
      • 安全管理
      • 策略管理
      • 度量管理
      • 排錯
      • 社區
    • Devops
      • Draft
      • Jenkins X
      • Spinnaker
      • Kompose
      • Skaffold
      • Argo
      • Flux GitOps
  • 實踐案例
    • 實踐概覽
    • 資源控制
    • 集群高可用
    • 應用高可用
    • 調試
    • 端口映射
    • 端口轉發
    • 用戶管理
    • GPU
    • HugePage
    • 安全
    • 審計
    • 備份恢復
    • 證書輪換
    • 大規模集群
    • 大數據與機器學習
      • Spark
      • Tensorflow
    • Serverless
  • 排錯指南
    • 排錯概覽
    • 集群排錯
    • Pod 排錯
    • 網絡排錯
    • PV 排錯
      • AzureDisk
      • AzureFile
    • Windows 排錯
    • 雲平臺排錯
      • Azure
    • 排錯工具
  • 社區貢獻
    • 開發指南
    • 單元測試和集成測試
    • 社區貢獻
  • 附錄
    • 生態圈
    • 學習資源
    • 國內鏡像
    • 如何貢獻
    • 參考文檔
Powered by GitBook
On this page
  • ReplicationController 與 Deployment 的關係
  • ReplicationController
  • Deployment
  • 創建測試鏡像
  • 測試
  • 使用 ReplicationController 創建的 Pod 如何 RollingUpdate
  • 參考
  1. 服務治理
  2. 服務治理

滾動升級

Previous一般準則NextHelm

Last updated 1 year ago

當有鏡像發佈新版本,新版本服務上線時如何實現服務的滾動和平滑升級?

如果你使用 ReplicationController 創建的 pod 可以使用 kubectl rollingupdate 命令滾動升級,如果使用的是 Deployment 創建的 Pod 可以直接修改 yaml 文件後執行 kubectl apply 即可。

Deployment 已經內置了 RollingUpdate strategy,因此不用再調用 kubectl rollingupdate 命令,升級的過程是先創建新版的 pod 將流量導入到新 pod 上後銷燬原來的舊的 pod。

Rolling Update 適用於 Deployment、Replication Controller,官方推薦使用 Deployment 而不再使用 Replication Controller。

使用 ReplicationController 時的滾動升級請參考官網說明:

ReplicationController 與 Deployment 的關係

ReplicationController 和 Deployment 的 RollingUpdate 命令有些不同,但是實現的機制是一樣的,關於這兩個 kind 的關係我引用了 中的部分內容如下,詳細區別請查看原文。

ReplicationController

Replication Controller 爲 Kubernetes 的一個核心內容,應用託管到 Kubernetes 之後,需要保證應用能夠持續的運行,Replication Controller 就是這個保證的 key,主要的功能如下:

  • 確保 pod 數量:它會確保 Kubernetes 中有指定數量的 Pod 在運行。如果少於指定數量的 pod,Replication Controller 會創建新的,反之則會刪除掉多餘的以保證 Pod 數量不變。

  • 確保 pod 健康:當 pod 不健康,運行出錯或者無法提供服務時,Replication Controller 也會殺死不健康的 pod,重新創建新的。

  • 彈性伸縮 :在業務高峯或者低峯期的時候,可以通過 Replication Controller 動態的調整 pod 的數量來提高資源的利用率。同時,配置相應的監控功能(Hroizontal Pod Autoscaler),會定時自動從監控平臺獲取 Replication Controller 關聯 pod 的整體資源使用情況,做到自動伸縮。

  • 滾動升級:滾動升級爲一種平滑的升級方式,通過逐步替換的策略,保證整體系統的穩定,在初始化升級的時候就可以及時發現和解決問題,避免問題不斷擴大。

Deployment

Deployment 同樣爲 Kubernetes 的一個核心內容,主要職責同樣是爲了保證 pod 的數量和健康,90% 的功能與 Replication Controller 完全一樣,可以看做新一代的 Replication Controller。但是,它又具備了 Replication Controller 之外的新特性:

  • Replication Controller 全部功能:Deployment 繼承了上面描述的 Replication Controller 全部功能。

  • 事件和狀態查看:可以查看 Deployment 的升級詳細進度和狀態。

  • 回滾:當升級 pod 鏡像或者相關參數的時候發現問題,可以使用回滾操作回滾到上一個穩定的版本或者指定的版本。

  • 版本記錄: 每一次對 Deployment 的操作,都能保存下來,給予後續可能的回滾使用。

  • 暫停和啓動:對於每一次升級,都能夠隨時暫停和啓動。

  • 多種升級方案:Recreate:刪除所有已存在的 pod, 重新創建新的; RollingUpdate:滾動升級,逐步替換的策略,同時滾動升級時,支持更多的附加參數,例如設置最大不可用 pod 數量,最小升級間隔時間等等。

創建測試鏡像

我們來創建一個特別簡單的 web 服務,當你訪問網頁時,將輸出一句版本信息。通過區分這句版本信息輸出我們就可以斷定升級是否完成。

Web 服務的代碼 main.go

package main

import (
  "fmt"
  "log"
  "net/http"
)

func sayhello(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "This is version 1.") // 這個寫入到 w 的是輸出到客戶端的
}

func main() {
  http.HandleFunc("/", sayhello) // 設置訪問的路由
  log.Println("This is version 1.")
  err := http.ListenAndServe(":9090", nil) // 設置監聽的端口
  if err != nil {
    log.Fatal("ListenAndServe:", err)
  }
}

創建 Dockerfile

FROM alpine:3.5
ADD hellov2 /
ENTRYPOINT ["/hellov2"]

注意修改添加的文件的名稱。

創建 Makefile

修改鏡像倉庫的地址爲你自己的私有鏡像倉庫地址。

修改 Makefile 中的 TAG 爲新的版本號。

all: build push clean
.PHONY: build push clean

TAG = v1

# Build for linux amd64
build:
  GOOS=linux GOARCH=amd64 go build -o hello${TAG} main.go
  docker build -t sz-pg-oam-docker-hub-001.tendcloud.com/library/hello:${TAG} .

# Push to tenxcloud
push:
  docker push sz-pg-oam-docker-hub-001.tendcloud.com/library/hello:${TAG}

# Clean
clean:
  rm -f hello${TAG}

編譯

make all

分別修改 main.go 中的輸出語句、Dockerfile 中的文件名稱和 Makefile 中的 TAG,創建兩個版本的鏡像。

測試

我們使用 Deployment 部署服務來測試。

配置文件 rolling-update-test.yaml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: rolling-update-test
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: rolling-update-test
    spec:
      containers:
      - name: rolling-update-test
        image: sz-pg-oam-docker-hub-001.tendcloud.com/library/hello:v1
        ports:
        - containerPort: 9090
---
apiVersion: v1
kind: Service
metadata:
  name: rolling-update-test
  labels:
    app: rolling-update-test
spec:
  ports:
  - port: 9090
    protocol: TCP
    name: http
  selector:
    app: rolling-update-test

部署 service

kubectl create -f rolling-update-test.yaml

修改 traefik ingress 配置

在 ingress.yaml 文件中增加新 service 的配置。

  - host: rolling-update-test.traefik.io
    http:
      paths:
      - path: /
        backend:
          serviceName: rolling-update-test
          servicePort: 9090

修改本地的 host 配置,增加一條配置:

172.20.0.119 rolling-update-test.traefik.io

注意:172.20.0.119 是我們之前使用 keepalived 創建的 VIP。

打開瀏覽器訪問 http://rolling-update-test.traefik.io 將會看到以下輸出:

This is version 1.

滾動升級

只需要將 rolling-update-test.yaml 文件中的 image 改成新版本的鏡像名,然後執行:

kubectl apply -f rolling-update-test.yaml
kubectl set image deployment/rolling-update-test rolling-update-test=sz-pg-oam-docker-hub-001.tendcloud.com/library/hello:v2

或者使用 kubectl edit deployment/rolling-update-test 修改鏡像名稱後保存。

使用以下命令查看升級進度:

kubectl rollout status deployment/rolling-update-test

升級完成後在瀏覽器中刷新 http://rolling-update-test.traefik.io 將會看到以下輸出:

This is version 2.

說明滾動升級成功。

使用 ReplicationController 創建的 Pod 如何 RollingUpdate

以上講解使用 Deployment 創建的 Pod 的 RollingUpdate 方式,那麼如果使用傳統的 ReplicationController 創建的 Pod 如何 Update 呢?

舉個例子:

$ kubectl -n spark-cluster rolling-update zeppelin-controller --image sz-pg-oam-docker-hub-001.tendcloud.com/library/zeppelin:0.7.1
Created zeppelin-controller-99be89dbbe5cd5b8d6feab8f57a04a8b
Scaling up zeppelin-controller-99be89dbbe5cd5b8d6feab8f57a04a8b from 0 to 1, scaling down zeppelin-controller from 1 to 0 (keep 1 pods available, don't exceed 2 pods)
Scaling zeppelin-controller-99be89dbbe5cd5b8d6feab8f57a04a8b up to 1
Scaling zeppelin-controller down to 0
Update succeeded. Deleting old controller: zeppelin-controller
Renaming zeppelin-controller-99be89dbbe5cd5b8d6feab8f57a04a8b to zeppelin-controller
replicationcontroller "zeppelin-controller" rolling updated

只需要指定新的鏡像即可,當然你可以配置 RollingUpdate 的策略。

參考

所有配置和代碼見 目錄。

也可以參考 中的方法,直接設置新的鏡像。

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment
ReplicationController 與 Deployment 的區別
manifests/test/rolling-update-test
Kubernetes Deployment Concept
Rolling update 機制解析
Running a Stateless Application Using a Deployment
Simple Rolling Update
使用 kubernetes 的 deployment 進行 RollingUpdate