天天看點

不背鍋運維:一文搞清楚應用釋出到k8s叢集的基本流程

作者:不背鍋運維

1. 使用yaml檔案建立資源對象

每種資源的apiVersion和kind可通過 kubectl api-resources 指令進行檢視

tantianran@test-b-k8s-master:~$ kubectl api-resources | grep Deployment
deployments                       deploy       apps/v1                                true         Deployment
tantianran@test-b-k8s-master:~$ 
           

goweb-demo.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: test-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 10
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3
---
apiVersion: v1
kind: Service
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb-demo
  type: NodePort
           

關于标簽的主要作用:标記、過濾、關聯(主要展現在deployment、pod、service,3者标簽保持一緻),可設定多個标簽,建議設定至少2個标簽,一個為項目标簽,一個為應用标簽。

不背鍋運維:一文搞清楚應用釋出到k8s叢集的基本流程
  • 關于建立、更新和删除的指令
# 隻用于建立
kubectl create -f xxx.yaml

# 建立和更新(需要yaml檔案裡的字段支援更新,并不是所有字段都支援更新)
kubectl apply -f xxx.yaml

# 解除安裝
kubectl delete -f xxx.yaml
           

2. 編寫yaml的套路分享

  • 套路1:可以直接手寫,但容易出錯
  • 套路2:參考官方示例,然後改成自己的
  • 套路3:通過指令行來擷取,也是有2個方式,一是利用嘗試運作(--dry-run)的機制再配合-o來輸出一個yaml檔案),二是通過get來得到yaml檔案,得到yaml檔案後再自行修改

下面示範通過create來得到yaml

# 在kubectl級别上進行驗證
kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=client

# 指的是送出到apiserver進行驗證
kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=server

# 下面來一個deployment的例子,得到其他資源的yaml也是這個套路
tantianran@test-b-k8s-master:~$ kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 5
  selector:
    matchLabels:
      app: web1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

# 還可以配合重定向輸出到yaml檔案
kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=client -o yaml > test.yaml
           

下面示範通過get指令來得到yaml檔案,使用-o來指定yaml的格式輸出,其他資源也是這個套路

kubectl get pods -n test-a -o yaml
           

編寫yaml的時候,字段名太多記不住或者想不起來怎麼辦?可以使用explain來檢視字段層級

# 找第一級
kubectl explain deployment

# 找第二級
kubectl explain deployment.spec

# 再比如查pod相關的
kubectl explain pods.spec.containers
           

3. 應用生命周期管理

deployment是最常用的k8s工作負載控制器(Workload Controllers),是k8s的一個抽象概念,用于更進階層次對象,部署和管理Pod,卡控制器還有DaemonSet、StatefulSet等。

3.1 Deployment

「Deployment主要功能:」

  • 管理Pod和ReplicaSet
  • 具有上線部署、副本設定、滾動更新、復原等功能

「Deployment應用場景:」 網站、API、微服務

「Pod與控制器的關系圖:」

不背鍋運維:一文搞清楚應用釋出到k8s叢集的基本流程

「應用生命周期管理流程:」

不背鍋運維:一文搞清楚應用釋出到k8s叢集的基本流程

3.2 應用部署的基本流程

部署->更新->復原->删除

3.2.1 部署

# 推薦的方式
kubectl apply -f xxx.yaml

# 或者
kubectl create deployment web --image=nginx --replicas=3
           

在本示例中,部署的是我自己使用go語言寫的一個很簡單的web demo

不背鍋運維:一文搞清楚應用釋出到k8s叢集的基本流程

通路一下看看

不背鍋運維:一文搞清楚應用釋出到k8s叢集的基本流程

3.2.2 更新

所謂的更新,其實就是更新鏡像,且有3種方式,自動觸發滾動更新

# 方式1:直接修改yaml檔案中的鏡像,然後apply
kubectl apply -f xxx.yaml
# 方式2:使用指令設定deployment使用的鏡像
kubectl set image deployment/web nginx=nginx1.17
# 使用系統編輯器打開進行編輯
kubectl edit deployment
           

「釋出方式有3種:」 滾動釋出、藍綠釋出、灰階釋出(金絲雀、A/B測試、冒煙測試。灰階釋出是最複雜的方式,釋出的方式是為了避免上線後出現的問題。)

「K8S預設是滾動更新:」 滾動釋出是指每次隻更新一個或多個服務,更新完成後加入生産環境,不斷執行這個過程,直到叢集中的全部舊版本更新新版本。

「滾動更新在k8s中的實作:」 它是通過1個Deployment和2個ReplicaSet來實作的,滾動更新一次隻更新一小部分pod,成功後,再更新一部分pod,最終完成所有Pod更新,整個過程始終有Pod在運作,進而保證了業務的連續性。

「ReplicaSet:」 副本集,主要維護Pod副本數量,不斷對比目前Pod數量于期望Pod數量。「ReplicaSet用途:」 Deployment每次釋出都會建立一個RS(ReplicaSet的縮寫)作為記錄,用于實作滾動更新和復原

可以檢視deployment的詳情,詳情裡其實是記錄了更新的過程

kubectl get deployment -n test-a
kubectl describe deployment goweb-demo -n test-a
           

檢視ReplicaSet(RS)記錄(初次的部署和後續更新都會新建立一個RS,更新多少次就會建立多少個)

tantianran@test-b-k8s-master:~$ kubectl get rs -n test-a
NAME                    DESIRED   CURRENT   READY   AGE
goweb-demo-6fbb74fdbb   0         0         0       41m
goweb-demo-7b6649f789   20        20        20      32m # 此處DESIRED和CURRENT以及READY字段有值的話,表示是目前正在使用的RS
goweb-demo-8665796599   0         0         0       24h

# 檢視正在使用的RS的詳情
kubectl describe rs goweb-demo-7b6649f789 -n test-a
           

注意:更新後,舊的RS會被保留,主要用于後面復原使用,且每次隻能有一個RS在使用。

「當新版的鏡像已經做好需要滾動更新的時候,那就要修改deployment中指定的鏡像,修改的方式有2種:使用指令和直接修改yaml檔案」方式1:使用指令

# 指令格式
kubectl set image deployment <DeploymentName> <ContainerName>=<Image> -n <Namespace>

# 例子
# step 1:擷取deployment
kubectl get deployment -n test-a

# step 2:檢視deployment詳情
kubectl describe deployment goweb-demo -n test-a
...
Pod Template:
  Labels:  app=goweb-demo
  Containers:
   goweb-demo: # 容器名字
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3 # 鏡像
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
...

# step 3:設定deployment的鏡像
kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v3 -n test-a
           

方式2:直接修改yaml(推薦)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo # deployment名稱
  namespace: test-a
spec:
  replicas: 50 # 副本
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3 # 鏡像
           

「水準擴縮容,也就是修改副本的數量,也有2種方式,指令和修改yaml檔案」方式1:指令

kubectl scale deployment goweb-demo --replicas=5 -n test-a
           

方式2:修改yaml檔案中的replicas參數,再apply

apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 5 #修改副本數量
...
...
           

3.2.3 復原

當應用釋出失敗,需要復原時。

檢視發過有哪些版本

# 檢視曆史
kubectl rollout history deployment -n test-a
deployment.apps/goweb-demo 
REVISION  CHANGE-CAUSE
4         <none>
6         <none>
8         <none>
9         <none>

# 通過指令修改deployment的鏡像進行更新時,後面加--record參數,再檢視曆史後就會記錄這條指令
kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v2 -n test-a --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/goweb-demo image updated

# 上面加了--record參數,再檢視曆史,可以看到記錄的這條指令
kubectl rollout history deployment -n test-a

deployment.apps/goweb-demo 
REVISION  CHANGE-CAUSE
4         <none>
6         <none>
9         <none>
10        kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v2 --namespace=test-a --record=true # 就是這裡
           

檢視版本号和RS的對應關系,以及和鏡像的對應關系

# 檢視RS
tantianran@test-b-k8s-master:~$ kubectl get rs -n test-a
NAME                    DESIRED   CURRENT   READY   AGE
goweb-demo-6fbb74fdbb   0         0         0       5h15m
goweb-demo-7b6649f789   0         0         0       5h6m
goweb-demo-8665796599   0         0         0       29h
goweb-demo-b98869456    5         5         5       4h22m # 目前使用的RS

# 檢視目前使用的RS詳情
tantianran@test-b-k8s-master:~$ kubectl describe rs goweb-demo-b98869456 -n test-a
...
Annotations:    deployment.kubernetes.io/desired-replicas: 5
                deployment.kubernetes.io/max-replicas: 7
                deployment.kubernetes.io/revision: 11 # 這個11就是目前版本号
                deployment.kubernetes.io/revision-history: 7,9 # 曆史版本
                kubernetes.io/change-cause:
                  kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v3 --namespace=test-a --record=true
Controlled By:  Deployment/goweb-demo
Replicas:       5 current / 5 desired
Pods Status:    5 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=goweb-demo
           pod-template-hash=b98869456
  Containers:
   goweb-demo:
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3 # 使用的鏡像
    Port:         <none>
    Host Port:    <none>
...

# 檢視曆史版本
tantianran@test-b-k8s-master:~$ kubectl rollout history deployment -n test-a
deployment.apps/goweb-demo 
REVISION  CHANGE-CAUSE
4         <none>
6         <none>
10        kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v2 --namespace=test-a --record=true
11        kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v3 --namespace=test-a --record=true # 這個REVISION是11
           

通過過濾來擷取到釋出版本和對應的鏡像

# 過濾revision和Image
tantianran@test-b-k8s-master:~$ kubectl describe $(kubectl get rs -o name -n test-a | grep "goweb-") -n test-a | grep -E "revision:|Image:"
                deployment.kubernetes.io/revision: 4
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v1
                deployment.kubernetes.io/revision: 10
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v2
                deployment.kubernetes.io/revision: 6
    Image:        192.168.11.247/web-demo/goweb-demo:20221228v1
                deployment.kubernetes.io/revision: 11
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3
tantianran@test-b-k8s-master:~$ 

# 過濾更詳細的,過濾revision、Image、Name、Replicas
tantianran@test-b-k8s-master:~$ kubectl describe $(kubectl get rs -o name -n test-a | grep "goweb-") -n test-a | grep -E "revision:|Image:|Name:|Replicas:"
Name:           goweb-demo-6fbb74fdbb
                deployment.kubernetes.io/revision: 4
Replicas:       0 current / 0 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v1

Name:           goweb-demo-7b6649f789
                deployment.kubernetes.io/revision: 10
Replicas:       0 current / 0 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v2

Name:           goweb-demo-8665796599
                deployment.kubernetes.io/revision: 6
Replicas:       0 current / 0 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221228v1

Name:           goweb-demo-b98869456
                deployment.kubernetes.io/revision: 11
Replicas:       5 current / 5 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3
           

隻復原到上一個版本

tantianran@test-b-k8s-master:~$ kubectl rollout undo deployment goweb-demo -n test-a
deployment.apps/goweb-demo rolled back
           

復原到指定的曆史版本

# 檢視目前正在使用哪個版本
tantianran@test-b-k8s-master:~$ kubectl describe $(kubectl get rs -o name -n test-a | grep "goweb-") -n test-a | grep -E "revision:|Replicas:"
                deployment.kubernetes.io/revision: 4
Replicas:       0 current / 0 desired
                deployment.kubernetes.io/revision: 14 # 目前正在使用的版本,版本号14,且副本是5
Replicas:       5 current / 5 desired # 副本數量
                deployment.kubernetes.io/revision: 6
Replicas:       0 current / 0 desired
                deployment.kubernetes.io/revision: 13
Replicas:       0 current / 0 desired

# 假設要復原到最初的版本,也就是版本号是4
tantianran@test-b-k8s-master:~$ kubectl rollout undo deployment goweb-demo --to-revision=4 -n test-a
deployment.apps/goweb-demo rolled back
tantianran@test-b-k8s-master:~$ 
           

3.2.4 删除(當項目需要下線時)

# 如果該項目是直接編寫yaml的,可這樣删除(下線)
kubectl delete -f goweb-demo.yaml

# 如果該項目的命名空間、deployment、service是用指令的,那就需要手動删除下線
kubectl delete deployment goweb-demo -n test-a
kubectl delete svc goweb-demo -n test-a
kubectl delete ns test-a
           

最後

如需要go開發的web demo源碼的朋友可私信我,一起交流,感謝!

本文轉載于(喜歡的盆友關注我們):https://mp.weixin.qq.com/s/jBJTLYvXkCtd__yO4Ap9UA

繼續閱讀