docker stack滾動更新web應用

lightTrace發表於2018-08-30

滾動更新是我們線上上發行版本常用的方式之一,Swarm 將按照如下步驟執行滾動更新:

  • 停止第一個副本。
  • 排程任務,選擇 worker node。
  • 在 worker 上用新的映象啟動副本。
  • 如果副本(容器)執行成功,繼續更新下一個副本;如果失敗,暫停整個更新過程。

滾動更新降低了應用更新的風險,如果某個副本更新失敗,整個更新將暫停,其他副本則可以繼續提供服務。同時,在更新的過程中,總是有副本在執行的,因此也保證了業務的連續性。

基於已經搭建好的swarm mode環境:搭建swarm mode

1.新建web服務
在任意檔案下(我這裡是/home/go)新建main.go

package main

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

func main() {
    http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {
        hostName, _ := os.Hostname()
        fmt.Fprintf(w, "HostName1: %s", hostName)
    })

    log.Fatal(http.ListenAndServe(":8000", nil))
}

2.新建Dockerfile

FROM golang

# Copy the current directory contents into the container
COPY . /go/src/github.com/lpxxn/godockerswarm/

WORKDIR /go/src/github.com/lpxxn/godockerswarm/

RUN go build

EXPOSE 8000

CMD ["./godockerswarm"]

3.編譯成映象

docker build . -t goweb:1.0

4.執行新映象並測試

docker run -p 8100:8000 -d goweb:1.0

瀏覽器訪問ip:8100 返回主機資訊

5.將映象打包並推到私有倉庫

如何搭建docker私有倉庫

docker tag goweb:1.0 192.168.1.101:5000/goweb:1.0  #他跟新映象

docker push 192.168.1.101:5000/goweb:1.0  #推送新映象到私有倉庫

6.編輯docker-compose.yml檔案
還是在go資料夾下編輯:

version: "3"
services:
  web:
    image: 192.168.1.101:5000/goweb:1.0
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "8111:8000"
    networks:
      - gowebnet
networks:
  gowebnet:

執行service

docker stack deploy -c docker-compose.yml mygoweb

7.在另一臺機器上訪問
在192.168.1.102上執行命令不斷訪問服務:

 sh -c "while true; do curl 192.168.1.101:8111/hi&&sleep 1; done"

會列印:

HostName1: cd9d3bf61aabHostName1: 6090c7594f3fHostName1: 6fc0951a708dHostName1: 715b839f3852HostName1: 544318a3749bHostName1: cd9d3bf61aabHostName1: 6090c7594f3fHostName1: 6fc0951a708dHostName1: 715b839f3852HostName1: 544318a3749bHostName1: cd9d3bf61aab

這裡發現swarm叢集還自動做了負載均衡,因為每次訪問的主機名都不同
8.更新映象更新docker-compose.yml實現滾動更新

更新main.go程式碼,就把 fmt.Fprintf(w, "HostName1: %s", hostName) 換成fmt.Fprintf(w, "HostName2: %s", hostName)

使得輸出不同的內容,就HostName1和HostName2的區別

然後重新編譯並且tag映象,上傳到伺服器,修改docker-compose.yml,最後重新啟動服務

vim main.go  #修改HostName1為HostName2

docker build . -t goweb:2.0   #編譯映象2.0

docker tag goweb:2.0 192.168.1.101:5000/goweb:2.0    #打包映象2.0

docker push 192.168.1.101:5000/goweb:2.0   #推送映象2.0

vim docker-compose.yml  #修改拉取的映象為2.0

docker stack deploy -c docker-compose.yml mygoweb  #重新部署

然後過一會發現192.168.1.102機器上面列印了:


HostName1: 6fc0951a708dHostName1: 715b839f3852HostName1: 544318a3749bHostName2: 3f1df083e22fHostName1: 6090c7594f3fHostName1: 6fc0951a708dHostName1: 715b839f3852HostName1: 544318a3749bHostName2: 3f1df083e22fHostName1: 6090c7594f3f

會發現有的主機已經慢慢改為HostName2,過一會就全部變成HostName2

相關文章