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

PV&PVC&HeadlessService

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

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

4.2、服務部署

4.2.1、無狀態服務部署

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

4.2.2、有狀態服務部署

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

4.3、Volume 數據卷

//kubernetes.io/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume/#local-temporary-directory

4.3.1 數據卷結構

image.png
Volume數據卷生命周期:(volume數據卷是kubernetes資源對象,本身並不存儲數據,而僅僅是提供把數據掛載到容器中的能力)
1、pod內部容器宕機,volume數據卷及數據不會丟失;
2、pod宕機,此時volume數據卷消失了,數據也丟失了,重建的pod無法找回數據了。
image.png
Volume 數據卷是Kubernetes抽象出來的一個資源對象,它本身不存儲數據,它主要實現數據掛載(把不同存儲介質中的數據給掛載到pod內部容器中)

4.3.2 數據卷的類型

image.png

4.3.3 本地掛載卷

  1. emptyDir 數據卷空掛載方式
    image.png
    驗證:進入容器內部,發現有/cache目錄,但是沒有數據
    image.png
    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中數據引入到環境變數中;
image.png
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

查看容器內部是否掛載成功:
image.png
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目錄中;
    image.png
    image.png

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

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

  • kubernetes.io/tls:用於為SSL通訊模式存儲證書和私鑰文件,命令式創建類型標識為tls。

image.png
當我們採用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屬性
image.png
確實是我們進行加密後的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原理

企業中服務部署需要存儲數據:前期規劃數據大小,需要多少存儲空間?? 然後由運維幫助創建持久化數據卷,根據需求大小進行創建.
image.png
可以把pv對象看做一個一個虛擬存儲塊,是一種虛擬化的概念,在邏輯上實現對物理資源隔離,同時實現對底層物理存儲介質的抽象,使得k8s更加方便的管理存儲空間,想使用哪個存儲塊,由k8s實現自由的調度。
image.png
Pv是k8s抽象出來的資源對象,k8s自由控制自己的資源對象
Pv存儲塊是根據業務需求,事先由運維先規劃,創建好存儲塊,項目需要,從存儲塊中獲取數據即可。
問題: 創建pod服務時候,需要存儲數據,但是pv存儲對象有上萬個,pod應該是哪個pv存儲塊?

4.5.3 PVC匹配PV

Pvc(persistent volume claim) 持久化的數據卷聲明卷,代理pod發送請求,幫助pod匹配一個合適的pv對象;
image.png
疑問:pvc是如何找到合適的pv資源對象?
image.png
創建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 掛載流程

image.png

4.7 headlessService

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

4.8 storageClass

根據需求: 創建pv存儲塊對象,可以想像:在開發中,需要大量的存儲塊,如果使用人工創建,非常低效,且沒有含金量。
因此根據解放生產力指標:讓pv按需動態創建,再也不需要人為的方式創建。使用storageclass實現pv對象動態創建。
image.png
Storageclass 動態創建pv存儲塊實現的部署方案:
image.png
要想實現pv按需動態創建,那必須先完成環境配置:
1、安裝storageclass
2、安裝persistent volume provisioner