假設目前有一項服務叫做 Public Service,這時若要進行新版本的佈署,可以透過藍綠佈署的方式來進行
Step 1. 建立Blue-Green測試所需的服務
透過docker-compose先建立 nginx-blue
與 nginx-green
這兩個images
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| version: '3.7'
services:
blue: container_name: nginx-blue image: nginx-blue build: context: ./blue dockerfile: blue.dockerfile ports: - 8080:80
green: container_name: nginx-green image: nginx-green build: context: ./green dockerfile: green.dockerfile ports: - 8081:80
|
在有這份docker-compose.yml
的資料夾底下,使用 docker-compose build
建立blue app與green app的images
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| $ docker-compose build
Building blue Step 1/6 : FROM nginx:alpine Step 2/6 : LABEL author="Dan Wahlin" Removing intermediate container f14a42375dd7 Step 3/6 : WORKDIR /usr/share/nginx/html Removing intermediate container 8108e1b74f33 Step 4/6 : COPY . . Step 5/6 : EXPOSE 80 Removing intermediate container 01d9b4572d23 Step 6/6 : CMD ["nginx", "-g", "daemon off;"] Removing intermediate container 71b9417682ff
Successfully built e2d289a6c692 Successfully tagged nginx-blue:latest
Building green Step 1/6 : FROM nginx:alpine Step 2/6 : LABEL author="Dan Wahlin" Step 3/6 : WORKDIR /usr/share/nginx/html Step 4/6 : COPY . . Step 5/6 : EXPOSE 80 Removing intermediate container 93bdaa313166 Step 6/6 : CMD ["nginx", "-g", "daemon off;"] Removing intermediate container ce2847a75363
|
Step 2. 定義Public服務要作切換的Blue-Green 設定檔
Public主要會使用分別定義Service與Deployment的yaml檔案的模板,其中 metadata
與 spec/selector/role
分別都設置了 $TARGET_ROLE
供指定是要部署藍色版本或綠色版的服務
nginx.service.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| kind: Service apiVersion: v1 metadata: name: nginx-service labels: app: nginx role: $TARGET_ROLE env: prod spec: type: LoadBalancer selector: app: nginx role: $TARGET_ROLE ports: - port: 80 targetPort: 80
|
其中 metadata
、 spec/selector/role
、spec/template/metadata/labels/role
分別都設置了 $TARGET_ROLE
供抽換
在containers
中,亦定義了 $IMAGE_VERSION
供指定是要用blue版的image, 或是green版的image
nginx.deployment.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment-$TARGET_ROLE spec: replicas: 2 selector: matchLabels: app: nginx role: $TARGET_ROLE template: metadata: labels: app: nginx role: $TARGET_ROLE spec: containers: - name: nginx-$TARGET_ROLE image: $IMAGE_VERSION imagePullPolicy: IfNotPresent ports: - containerPort: 80 readinessProbe: httpGet: path: / port: 80 livenessProbe: httpGet: path: / port: 80 resources: limits: memory: "128Mi" cpu: "200m"
|
Blue與Green的測試設定部署檔案
以下定義blue與green的Service設定檔
nginx-blue-test.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| kind: Service apiVersion: v1 metadata: name: nginx-blue-test labels: app: nginx role: blue-test env: test spec: type: LoadBalancer selector: app: nginx role: blue ports: - port: 9000 targetPort: 80
|
nginx-green-test.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| kind: Service apiVersion: v1 metadata: name: nginx-green-test labels: app: nginx role: green-test env: test spec: type: LoadBalancer selector: app: nginx role: green ports: - port: 9001 targetPort: 80
|
Step 3. 進行Blue-Green佈署
這份腳本config.sh
會負責解析yaml檔內,若有 $TARGET_ROLE 更換成環境變數 $TARGET_ROLE的值, $IMAGE_VERSION也是一樣
config.sh
1 2 3
| sed 's/\$TARGET_ROLE'"/$TARGET_ROLE/g" | sed 's/\$IMAGE_VERSION'"/$IMAGE_VERSION/g" | tee
|
佈署Public版本
先在環境變數下設置 $TARGET_ROLE
為blue, 與 $IMAGE_VERSION
為nginx-blue
1 2
| $ export TARGET_ROLE=blue $ export IMAGE_VERSION=nginx-blue
|
使用 nginx.deployment.yml模板,建立出blue版本的deployment
1 2 3
| $ cat nginx.deployment.yml | sh config.sh | kubectl create --save-config -f -
deployment.apps/nginx-deployment-blue created
|
接著再使用 nginx.service.yml模板,建立出 Public版本的service (使用blue template)
nginx.service.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| kind: Service apiVersion: v1 metadata: name: nginx-service labels: app: nginx role: $TARGET_ROLE -> 置換成blue env: prod spec: type: LoadBalancer selector: app: nginx role: $TARGET_ROLE -> 置換成nginx-blue ports: - port: 80 targetPort: 80
|
1 2 3
| $ cat nginx.service.yml | sh config.sh | kubectl create --save-config -f -
service/nginx-service created
|
打開 http://localhost
可看到Public App的畫面
部署Blue版本
創建Blue版本的service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| kind: Service apiVersion: v1 metadata: name: nginx-blue-test labels: app: nginx role: blue-test env: test spec: type: LoadBalancer selector: app: nginx role: blue ports: - port: 9000 targetPort: 80
|
創建blue-test的service
1 2 3
| $ kubectl create -f nginx-blue-test.service.yml
service/nginx-blue-test created
|
最後在http://localhost:9000
可看到部署Blue App的畫面
Green版本的佈署
調整環境變數為green
1 2
| $ export TARGET_ROLE=green $ export IMAGE_VERSION=nginx-green
|
使用deployment模板,部署Green的Deployment環境
1 2 3
| $ cat nginx.deployment.yml | sh config.sh | kubectl create --save-config -f -
deployment.apps/nginx-deployment-green created
|
接著創建Green的Service
1 2 3
| $ kubectl create -f nginx-green-test.service.yml --save-config
service/nginx-green-test created
|
這時就可以在 http://localhost:9001
看到Green App的畫面
Step 4. 執行移轉
若Green App版本若測試完畢,可以將Public環境,移轉至Green APP上
透過更改Public原先設定的 nginx.service.yml檔案,改變Service內 role為green即可
nginx.service.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| kind: Service apiVersion: v1 metadata: name: nginx-service labels: app: nginx role: $TARGET_ROLE -> 置換成green env: prod spec: type: LoadBalancer selector: app: nginx role: $TARGET_ROLE -> 置換成nginx-green ports: - port: 80 targetPort: 80
|
使用 kubectl apply -f
套用Green的設定
1 2 3
| $ cat nginx.service.yml | sh config.sh | kubectl apply -f -
service/nginx-service configured
|
這時就可以看到 http:localhost
成功移轉為 Green App了
Step 5. 將舊環境Blue App 移除掉
透過 kubectl delete -f [yaml]
指定deployment 的yaml檔案,即可以將blue app環境下的depoloyment和service給移除掉
1 2
| $ kubectl delete -f nginx-blue-test.service.yml service "nginx-blue-test" deleted
|
流程總結
- 準備好要移轉的images.
- 假設原本已經有運作的環境,叫做Public,先建立Blue Test版本的Deployment,創建出與Public一樣的環境 (Service都是指到原始版本的Pods)
- 建立Blue Test的版本的用意是,先拷貝出Production環境,以此作為移植,若後續Production移轉過去Green後,若有問題的話還可以在倒回到Blue Test上。
- 創建Green Test版本的Deployment,創建新版的環境
- Green Test環境測試完畢後,調整Public的service,導引到Green deployment環境下的
pods
- 最後若沒問題的話,可以將Blue Test的deployment環境給移除掉
參考
Pluralsight: Kubernetes for Developers: Deploying Your Code
https://app.pluralsight.com/library/courses/kubernetes-developers-deploying-code/table-of-contents