k8s之有狀態服務部署基石(基礎知識)

2022-07-05 06:00:48

PV&PVC&HeadlessService

4.1、什麼是無狀態/有狀態服務?

無狀態服務
1、沒有實時的資料需要儲存 (即使有,也是靜態資料)
2、服務叢集網路中,拿掉一個服務後,一段時間後,加入這個服務,對服務叢集沒有任何影響。
比如:
目前開發應用程式(Java程式碼)
有狀態服務
1、有實時的資料需要儲存
2、服務叢集網路中,拿掉一個服務後,一段時間後,加入這個服務,對服務叢集有一定的影響(資料完整性,一致性)
比如:
關係型資料庫(mysql、sqlserver)

4.2、服務部署

4.2.1、無狀態服務部署

kubernetes部署無狀態服務,部署架構,形態:對於無狀態服務部署的幾個關鍵物件:Deployment、ReplicaSet、Pod.

4.2.2、有狀態服務部署

在kubernetes中,服務部署的最小單元都是POD;對於部署有狀態服務,必須對POD容器的資料儲存做持久化處理。需要引入PV(persistent volume)PVC(persistent volume claim)、磁碟等記憶體。

4.3、Volume 資料卷

https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume/

4.3.1 資料卷結構


Volume資料卷生命週期:(volume資料卷是kubernetes資源物件,本身並不儲存資料,而僅僅是提供把資料掛載到容器中的能力)
1、pod內部容器宕機,volume資料卷及資料不會丟失;
2、pod宕機,此時volume資料卷消失了,資料也丟失了,重建的pod無法找回資料了。

Volume 資料卷是Kubernetes抽象出來的一個資源物件,它本身不儲存資料,它主要實現資料掛載(把不同儲存媒介中的資料給掛載到pod內部容器中)

4.3.2 資料卷的型別

4.3.3 本地掛載卷

  1. emptyDir 資料卷空掛載方式

    驗證:進入容器內部,發現有/cache目錄,但是沒有資料

    2)hostpath 磁碟掛載方式:
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # 宿主上目錄位置
      path: /data
      # 此欄位為可選
      type: Directory

4.3.4 網路儲存卷

1)首先自行安裝一臺nfs伺服器。
2)yaml檔案

apiVersion: v1
kind: Pod
metadata:
  name: nfs
spec:
  containers:
  - image: harbor.hyz.com/library/mynginx:v1
    name: test-vo
    volumeMounts:
    - mountPath: /cache
      name: test-nfs
  volumes:
  - name: test-nfs
    nfs:
      server: 192.168.211.13
      path: /data/harbor

4.3、configmap

4.3.1 什麼是configmap?

ConfigMap是k8s提供的一個設定中心,類似於微服務架構中(nacos,zookeeper)設定中心服務,用來儲存一些組態檔。
例如:
1、部署Redis服務,可以把redis.conf組態檔儲存在configmap資源物件中;
2、部署mysql服務,可以把my.cnf組態檔儲存在configmap資源物件中。
ConfigMap資源物件儲存結構:key-value模式,key是關鍵字元,value可以是字串,也可以是一個檔案內容。

4.3.2 建立configmap

Examples:
# Create a new configmap named my-config based on folder bar
kubectl create configmap my-config --from-file=path/to/bar

# Create a new configmap named my-config with specified keys instead of file basenames on disk
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt

# Create a new configmap named my-config with key1=config1 and key2=config2
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2

# Create a new configmap named my-config from the key=value pairs in the file
kubectl create configmap my-config --from-file=path/to/bar

# Create a new configmap named my-config from an env file
kubectl create configmap my-config --from-env-file=path/to/bar.env

1、根據目錄建立
kubect create cm my-config-1 --from-file=/data/config
2、根據檔案建立
kubectl create cm my-config-2 --from-file=/data/config/application.yml
3、根據字面量(key-value)建立
kubectl create cm my-config-3 --from-literal=key=value1 --from-literal=key2=value2

4.3.3 Pod服務參照

1)使用單個 ConfigMap 中的資料定義容器環境變數

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: harbor.hyz.com/library/mynginx:v1
      command: [ "/bin/sh", "-c", "env" ]
      env:
        # 定義環境變數
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              # ConfigMap 包含你要賦給 SPECIAL_LEVEL_KEY 的值
              name: special-config
              # 指定與取值相關的鍵名
              key: special.how
  restartPolicy: Never

經過測試:發現成功的把configmap中資料引入到環境變數中;

2)volume方式掛載:

apiVersion: v1
kind: Pod
metadata:
  name: cm-volume
spec:
  containers:
  - image: harbor.hyz.com/library/mynginx:v1
    name: test-container
    command: [ "/bin/sh", "-c", "sleep 600s" ]
    volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: my-config-2

檢視容器內部是否掛載成功:

my-config-2中的4個檔案都掛載成功。

4.3.4 POD資料熱更新

修改ConfigMap中的資料,pod服務能夠馬上察覺到。

4.4、Secret

4.4.1 Secret是什麼?

Secret是kubernetes本地資料卷的一種,secret提供儲存敏感資料的一種服務,用來把敏感儲存secret物件中,保證服務的安全性。
具體作用:防止一些敏感資料直接保證服務映象中;例如:token, 祕鑰,密碼等等。當pod需要這些資料的時候,動態的從secret資源物件中載入即可。

4.4.2 k8s認證方式

Secret有4種型別:

  • Service Account :用來存取Kubernetes API,由Kubernetes自動建立,並且會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中;

  • Opaque :base64編碼格式的Secret,用來儲存密碼、金鑰、資訊、證書等,型別識別符號為generic;

  • kubernetes.io/dockerconfigjson :用來儲存私有docker registry的認證資訊,型別標識為docker-registry。

  • kubernetes.io/tls:用於為SSL通訊模式儲存證書和私鑰檔案,命令式建立型別標識為tls。


當我們採用rest風格存取k8s api時,需要攜帶一些鑑權資訊,比如token\ca證書\賬號密碼等,之後每臺Node節點會根據鑑權資訊去master鑑權。

4.4.3 Secret使用

[root@k8s-master01 stateful]# echo -n "admin" | base64
YWRtaW4=
[root@k8s-master01 stateful]# echo -n "abcdefgh" | base64
YWJjZGVmZ2g=

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: YWJjZGVmZ2g=
  username: YWRtaW4=

4.4.4 pod服務參照

apiVersion: v1
kind: Pod
metadata:
  name: secret-test
  labels:
    name: secret-test
spec:
  volumes:
    - name: secrets
      secret:
        secretName: mysecret
  containers:
  - image: harbor.hyz.com/library/mynginx:v1
    name: test-container
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true

驗證:進入容器/etc/secrets目錄下,列印username, password屬性

確實是我們進行加密後的2個源字串。

4.5、PV(persistent volume)

4.5.1 PV是什麼?

Pv持久化資料卷,是用來讓服務和儲存媒介解耦(讓volume資料卷和底層的儲存媒介進行解耦,volume資料卷消失了,但是pv不會消失,pv和pod沒有強關聯,當pod被重構後,根據hostname不變性,從而可以再次找回資料,保證資料的不丟失),因此為了部署有狀態服務,kubernetes抽象出來了一個PV持久化資料資源物件,k8s可以自由的控制這個資源物件,其作用就是遮蔽掉底層複雜的儲存媒介的操作,使得kubernetes管理持久化的資料卷更加高效,簡單。

4.5.2 pv原理

企業中服務部署需要儲存資料:前期規劃資料大小,需要多少儲存空間?? 然後由運維幫助建立持久化資料卷,根據需求大小進行建立.

可以把pv物件看做一個一個虛擬儲存塊,是一種虛擬化的概念,在邏輯上實現對物理資源隔離,同時實現對底層物理儲存媒介的抽象,使得k8s更加方便的管理儲存空間,想使用哪個儲存塊,由k8s實現自由的排程。

Pv是k8s抽象出來的資源物件,k8s自由控制自己的資源物件
Pv儲存塊是根據業務需求,事先由運維先規劃,建立好儲存塊,專案需要,從儲存塊中獲取資料即可。
問題: 建立pod服務時候,需要儲存資料,但是pv儲存物件有上萬個,pod應該是哪個pv儲存塊?

4.5.3 PVC匹配PV

Pvc(persistent volume claim) 持久化的資料卷宣告卷,代理pod傳送請求,幫助pod匹配一個合適的pv物件;

疑問:pvc是如何找到合適的pv資源物件?

建立pod服務的時候,儲存資料,繫結一合適的pv物件:
1、向pvc發出請求,讓pvc幫助我們選擇一個合適的pv儲存塊
2、pvc傳送申請請求,請求匹配一個合適的pv儲存物件,匹配方式如下:
1)、存取大小
2)、存取方式

4.6 PV&PVC 案例

4.6.1 建立PV物件

1)建立Pv1

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/hyz
    server: 192.168.66.13

2)建立pv2

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv2
spec:
  capacity:
    storage: 7Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/hyz
    server: 192.168.66.13

4.6.2 建立Pod物件

apiVersion: v1
kind: Pod
metadata:
  name: pv-pod
spec:
  containers:
  - image: harbor.hyz.com/library/mynginx:v1
    name: test-container
    ports:
    - containerPort: 80
    volumeMounts:
      - name: www
        mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc

4.6.3 建立pvc物件

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    request:
      storage: 5Gi

4.6.4 掛載流程

4.7 headlessService

HeadlessService : 字面意思: 無頭服務,內涵含義:沒有ip地址的Service; 也就是說對於有狀態服務部署來說,使用的是headlessService, 不會給service分配ip地址;
HeadlessService作用就是把後端服務的ip地址暴露給前端,便於使用者端使用。

4.8 storageClass

根據需求: 建立pv儲存塊物件,可以想象:在開發中,需要大量的儲存塊,如果使用人工建立,非常低效,且沒有含金量。
因此根據解放生產力指標:讓pv按需動態建立,再也不需要人為的方式建立。使用storageclass實現pv物件動態建立。

Storageclass 動態建立pv儲存塊實現的部署方案:

要想實現pv按需動態建立,那必須先完成環境設定:
1、安裝storageclass
2、安裝persistent volume provisioner