5分鐘讓你理解K8S必備架構概念,以及網路模型(中)

阿風的架構筆記發表於2021-05-23

寫在前面

在這用XMind畫了一張導圖記錄Redis的學習筆記和一些面試解析(原始檔對部分節點有詳細備註和參考資料,歡迎關注我的公眾號:阿風的架構筆記 後臺傳送【導圖】拿下載連結, 已經完善更新):

前言

在上一篇文章中介紹了K8S的基礎架構流程,以及核心的元件;這篇文章繼續K8S的相關的概念。

上篇介紹到了NodePort Service解決了外部請求K8S內部的應用的問題。下面我們看看如何搭建應用服務叢集的?

應用叢集

圖片

在傳統應用中,我們一般利用nginx反向代理,通過配置域名指向多個IP地址,從而實現了應用的叢集。如果需要增加應用或減少應用,都需要調整nginx的配置;還是相當繁瑣的。

那K8S是如何實現應用叢集的呢?

副本集ReplicaSet

圖片

上一篇文章中介紹了利用NodePort Service 的Selector 選擇Label標籤,路由到後端的其中一個Pod。

上圖中由3個Pod組成的應用叢集,那如何保證Pod叢集的高可用呢?如果其中一個Pod掛了,被刪除了,K8S會怎麼處理?

K8S有個Replica Set元件,從字面上面來看就是副本集意思;它的作用就是用來保證Pod的高可用,如果我們在Replica Set中定義了應用數量為3,那麼它會保證應用數量;即使一個pod掛了,它會自動會啟動1個,始終保證pod應用數量為3。

圖片

編寫yaml

apiVersion: extensions/v1beta1  #指定api版本
kind: ReplicaSet       #指定建立資源的角色/型別
metadata: 
  name: mc-user
spec: 
  replicas: 3       #副本集數量
  template:         #pod模板
    metadata:       #資源的後設資料/屬性  
      labels:       #標籤定義
        app: mc-user  #標籤值
    spec:           # 指定該資源的內容
      containers:    #容器定義
        - name: mc-user   #容器的名字  
          image: rainbow/mc-user:1.0.RELEASE    #容器映象

上面就是定義了 mc-user的pod,副本集數始終為3。Service的yaml和之前一樣,注意Selector的Label,可提供給外部訪問埠31001

apiVersion: v1
kind: Service
metadata: 
  name: mc-user
spec: 
  ports:
    - name: http
      port: 8080
      targetPort: 8080
      nodePort: 31001
  selector:
    app: mc-user
  type: NodePort

執行kubectl apply -f 命令,啟動ReplicaSet和Service

我們可以試著檢視啟動的3個pod,並選擇其中一個pod將它刪除。

# kubectl get all
# kubectl delete po mc-user-6adfw

我們再檢視pod

kubectl get all

還是有3個pod,可以看出即使刪除了一個pod;ReplicaSet會又幫我們啟動了一個pod。

這個就是ReplicaSet的自愈能力,自我恢復能力。

滾動釋出Rolling Update

我們先來談談什麼是滾動釋出?滾動釋出是一種高階釋出策略,按批次依次替換老版本,逐步升級到新版本。釋出過程中,應用不中斷,使用者體驗平滑。

圖片

現在Pod中是V1的版本,現在我們想升級到V2版本,整個流程是什麼樣子呢?

圖片

先刪除其中一個V1的pod

圖片

然後釋出V2的Pod

圖片

再刪除一個V1的pod

圖片

再啟動一個V2的Pod

圖片

再刪除最後一個V1的pod

圖片

最終升級完成。

我們可以發現滾動釋出的特點,就是老版本和新版本會共存一段時間。所以此種釋出方式適用版本相容的應用。也可以支援滾動回退。我們來看看和藍綠髮布的區別

圖片

滾動釋出抽象Deployment

之前介紹的ReplicaSet 其實是對Pod的一次包裝,Deployment又在基礎上面對ReplicaSet的又一次包裝。

圖片

注意點:ReplicaSet 和 Deployment是一個軟體概念,它是沒有具體的元件的;是抽象出來的名詞,方便大家理解

圖片

上圖就是描述了deployment滾動釋出的架構;Deployment的滾動釋出,對使用者請求以及Service是透明的,無感知。

Deployment的yaml

apiVersion: apps/v1  #指定api版本,此值必須在kubectl apiversion中
kind: Deployment       #指定建立資源的角色/型別
metadata: 
  name: mc-user
spec: 
  selector:           #此deployment選擇哪個標籤進行滾動的釋出
    matchLabels:      #滾動釋出pod的標籤,要跟下面template中的labels一致
      app: mc-user
  minReadySeconds: 10 #最小10s等待就緒時間,可以方便看到滾動釋出流程
  replicas: 3       #副本集數量
  template:         #pod模板
    metadata:       #資源的後設資料/屬性  
      labels:       #標籤定義
        app: mc-user  #標籤值
    spec:           #指定該資源的內容
      containers:    #容器定義
        - name: mc-user   #容器的名字  
          image: rainbow/mc-user:1.0.RELEASE    #容器映象

上面的yaml和ReplicaSet很類似,需要注意的

selector:        #此deployment選擇哪個標籤進行滾動的釋出
   matchLabels:  #滾動釋出pod的標籤,要跟下面template中的labels一致
      app: mc-user

定義deployment管理哪個標籤pod

Service的yaml

Service的yaml沒有變化,需要定義selector,選擇標籤就行了

apiVersion: v1
kind: Service
metadata: 
  name: mc-user
spec: 
  ports:
    - name: http
      port: 8080
      targetPort: 8080
      nodePort: 31000
  selector:
    app: mc-user
  type: NodePort

我們用kubectl apply -f命令執行 deployment和service

我們再用kubectl get all獲取執行情況,我們就可以發現有兩個型別

deployment.apps/mc-user 以及 replicaset.apps/mc-user-4345afaa

要升級的時候,只需要更改deployment中的image名稱,再執行apply

image: rainbow/mc-user:1.1.RELEASE    #容器映象

我們用kubectl get all檢視,就會發現replicaset 有2個;一個是老版本的,一個是新版本的。 老版本的pod數逐漸減少,新版本的pod數量逐漸增加,一直到新版本為3,老版本為0。

回退版本

如果發現版本有問題,我們可以回退版本,可以使用下面命令

kubectl rollout undo deployment/mc-user

這個我們就回退到V1.0的老版本了。

ConfigMap配置

在我們日常業務過程中,需要會配置一些配置引數,如:一次性的靜態配置(資料庫連線字串,使用者名稱,密碼),以及可以執行過程中的動態配置(如:限購數量)等;那K8S中的Pod如何獲得外部的配置資訊呢?

圖片

上圖中,K8S提供了ConfigMap這個功能,提供使用者在外部進行配置,然後K8S把ConfigMap以環境變數的方式提供給Pod中的容器或者也可以通過Volume檔案持久化的方式提供給Pod容器。

共享配置

因為我們會有很多服務的配置是相同的,那實現微服務之間共享一份配置資訊,如下圖

圖片

一份ConfigMap可以提供給多個服務使用,ConfigMap會把配置資訊以env方式存在於每個服務的環境變數中。

ConfigMap的yaml

apiVersion: v1  #指定api版本,此值必須在kubectl apiversion中
kind: ConfigMap       #指定建立資源的角色/型別
metadata: 
  name: mc-user-config
data: #定義配置資訊
  DATASOURCE_URL: jdbc:mysql://mysql/mc-user
  DATASOURCE_USERNAME: root
  DATASOURCE_PASSWORD: 123456

修改Deployment配置檔案

增加envFrom屬性

apiVersion: apps/v1  #指定api版本,此值必須在kubectl apiversion中
kind: Deployment     #指定建立資源的角色/型別
metadata: 
  name: mc-user
spec: 
  selector:           #此deployment選擇哪個標籤進行滾動的釋出
    matchLabels:      #滾動釋出pod的標籤,要跟下面template中的labels一致
      app: mc-user
  minReadySeconds: 10 #最小10s等待就緒時間,可以方便看到滾動釋出流程
  replicas: 3       #副本集數量
  template:         #pod模板
    metadata:       #資源的後設資料/屬性  
      labels:       #標籤定義
        app: mc-user  #標籤值
    spec:           #指定該資源的內容
      containers:    #容器定義
        - name: mc-user   #容器的名字  
          image: rainbow/mc-user:1.0.RELEASE    #容器映象
          envFrom:  #環境變數來源
            - configMapRef: #容器應用的configmap引用
                name: mc-user-config #configMap的名稱

envFrom中的configMapRef配置引用名稱;這樣我們就可以在pod容器中獲取到configmap的配置資訊了。我們可以用

kubectl exec mc-user-34wrwq-3423 printenv | grep DATASOURCE_NAME

獲得pod容器中的環境變數。

configMap變更

圖片

如果服務已經執行中,我們更新了ConfigMap的配置資訊,那麼POD中的容器會即時獲得新的配置資訊嗎?

很不幸,更新了configMap;再用kubectl apply -f 重新發布configmap;之前的pod容器是不會獲得最新的配置資訊的。

那如何讓pod容器用最新的ConfigMap配置值呢?我們可以刪除pod,因為replicaset會保證pod數量,會自動重啟,那新的pod就會應用新的配置資訊了。

總結

今天介紹K8S的副本集ReplicaSet、滾動釋出Deployment、配置ConfigMap的概念;下一篇會介紹網路相關的模型。謝謝!!!

看完三件事❤️


如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:

  1. 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
  2. 關注公眾號 『 阿風的架構筆記 』,不定期分享原創知識。
  3. 同時可以期待後續文章ing?
  4. 關注後回覆【666】掃碼即可獲取架構進階學習資料包

相關文章