《後端學運維》- k8s之數據存儲

你們好,我是小菜,一個渴望在互聯網行業作到蔡不菜的小菜。可柔可剛,點贊則柔,白嫖則剛!
死鬼~看完記得給我來個三連哦!nginx

本文主要介紹 K8s中數據存儲的使用docker

若有須要,能夠參考shell

若有幫助,不忘 點贊vim

微信公衆號已開啓,小菜良記,沒關注的同窗們記得關注哦!後端

k8s 的進程到這裏咱們已經完成了 NamespacePodPodController 幾種資源的使用方式,已通過大半了哦~這篇文章咱們就繼續來了解一下在k8s 中怎麼進行數據存儲!api

kubernetes的最小控制單元,容器都是運行在 pod 中的,一個pod中能夠有 1 個或多個容器服務器

這個概念咱們早已瞭解,不難明白容器的生命週期會很短暫,當pod出現問題的時候,pod控制器會頻繁的建立和銷燬,而每一個pod都是獨立的,所以存儲在容器中的數據也會被清除,這種結果無疑是致命打擊。這時,可能就會有小夥伴說了,docker 中存在數據掛載,k8s 確定也存在,咱們能夠利用數據掛載來解決該問題~那麼,恭喜你答對了,k8s 中不只支持數據掛載,並且支持的功能還至關強大,話很少說,咱們接下來就進入數據世界~微信

數據存儲

k8s中有個 Volume 的概念,VolumnPod 中可以被多個容器訪問的共享目錄,K8sVolume 定義在 pod 上,而後被一個 pod裏的多個容器掛載到具體的文件目錄下,k8s經過 Volume 實現同一個 pod 中不一樣容器之間的數據共享以及數據的持久化存儲,Volume的生命週期不與pod中單個容器的生命週期相關,當容器終止或重啓的時候,Volume中的數據也不會被丟失。網絡

Volume 支持常見的類型以下:app

除了上面列出來的這些,還有 gcePersistentDisk、awsElasticBlockStore、azureFileVolume、azureDisk 這些存儲,可是由於使用較少,因此不作過多瞭解。下面咱們就來詳細看看每一個存儲該如何使用!

1、基本存儲

1)EmptyDir

這是個最基礎的 Volume類型,一個 EmptyDir 就是 Host 上的一個空目錄。
概念:

它是在 Pod 被分配到 Node 節點上時纔會被建立,初始內容爲空,而且無需指定宿主機上對應的目錄文件,它會自動在宿主機上分配一個目錄

值得關注的是

Pod 銷燬時,EmptyDir 中的數據也會被永久刪除!

用處:

  1. 用做臨時空間,好比 Web 服務器寫日誌或者 tmp 文件須要的臨時目錄。
  2. 用做多容器之間的共享目錄(一個容器須要從另外一個容器中獲取數據的目錄)
實戰:

咱們以nginx爲例,準備一份資源清單

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: cbuc-test
  labels:
    app: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14-alpine
    ports:
       - containerPort: 80
       volumeMounts:    # 將 nginx-Log 掛載到nginx容器中,容器內目錄爲/var/log/nginx
       - name: nginx-log
         mountPath: /var/log/nginx
  volumes:    #在此聲明volume
  - name: nginx-log
    emptyDir: {}

而後咱們建立後能夠看看emptyDir存儲卷在宿主機的位置。默認狀況下宿主機中聲明volume的目錄位置是在 /var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 類型 >/<Volume 名字 > 中。

2)HostPath

概念:

HostPath 就是將 Node 節點上一個實際目錄掛載到pod中,供容器使用,這種好處就是在 pod 銷燬後,該目錄下的數據依然存在!

實戰:

咱們以 nginx 爲例,準備一份資源清單:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: cbuc-test
  labels:
    app: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nginx-log
      mountPath: /var/log/nginx
  volumes:
  - name: nginx-log
    hostPath:           # 指定宿主機目錄爲 /data/nginx/log
      path: /data/nginx/log
      type: DirectoryOrCreate   # 建立類型

spec.volumes.hostPath.type(建立類型):

  • DirectoryOrCreate:目錄存在就是用,不存在就先建立後使用
  • Directory: 目錄必須存在
  • FileOrCreate: 文件存在就是用,不存在就建立後使用
  • File: 文件必須存在
  • Socket: unix 套接字必須存在
  • CharDevice: 字符設備必須存在
  • BlockDevice: 塊設備必須存在

咱們根據該資源清單能夠建立出一個 pod,而後經過 podIp 訪問該pod,再查看 /data/nginx/log 下的日誌文件,發現已有日誌產生

3)NFS

HostPath 是咱們平常中比較常用到的存儲方式了,已經能夠知足基本的使用場景。目前爲止咱們小小的總結一下:EmptyDir 是針對 pod,若是 pod 被銷燬了,那麼改數據就會丟失。針對該問題,HostPath 進行了改進,存儲變成是針對 Node ,可是若是 Node 宕機了,那麼數據仍是會丟失。這個時候就須要準備單獨的網絡存儲系統了,而比較經常使用的即是 NFS、CIFS

概念:

NFS 是一個網絡存儲系統,能夠搭建一臺 NFS 服務器,而後將 Pod 中的存儲直接鏈接到 NFS 系統上,這樣的話,不管pod在節點上如何轉移,只要 Node 節點和 NFS服務器對接沒問題,數據就不會出現問題。

實戰:

既然須要 NFS 服務器,那確定須要本身搭建一個。咱們選取 master 節點來安裝NFS 服務器

# 安裝 nfs 服務器
yum install -y nfs-utils
# 準備共享目錄
mkdir -p /data/nfs/nginx
# 將共享目錄以讀寫權限暴露給 192.168.108.0/24 網段的全部主機
vim /etc/exports
# 添加如下內容
/data/nfs/nginx    192.168.108.0/24(rw,no_root_squash)
# 啓動 nfs 服務器
systemctl start nfs

而後咱們在各個節點上一樣安裝 NFS,以供驅動 NFS 設備

yum install -y nfs-utils

作好以上準備後咱們就能夠準備資源清單文件了:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: cbuc-test
  labels:
    app: nginx
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.14-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nginx-log
      mountPath: /var/log/nginx
    volumes:
    - name: nginx-log
      nfs:
        server: 192.168.108.100     # NFS服務器地址,也就是master地址
        path: /data/nfs/nginx        # 共享文件路徑

建立完pod後,咱們能夠進入到 /data/nfs 目錄下查看到兩個日誌文件了

2、高級存儲

管理存儲是管理計算的一個明顯問題,該部分須要抽象出如何根據消費方式來提供存儲的詳細信息。而 k8s 也很好的支持了,引入了兩個新的 API 資源:PersistenVolumePersistentVolumeClaim

PersistenVolume(PV)是持久化卷的意思,是對底層共享存儲的一種抽象,通常狀況下PV由 k8s 管理員進行建立和配置,它與底層具體的共享存儲技術有關,並經過插件完成與共享存儲的對象。

PersistentVolumeClaim(PVC)是持久卷聲明的意思,是用戶對存儲需求的一種聲明,換句話說,PVC其實就是用戶向 k8s 系統發出的一種資源需求申請。

1)PV

PV 是集羣中由管理員配置的一段網絡存儲,它也是集羣中的一種資源,資源清單模板以下:

apiVersion: v1
kind: PersistentVolume
meatadata:
  name: pv
spec:
  nfs:                     # 存儲類型,能夠是 CIFS、GlusterFS
  capacity:                # 存儲空間的設置
    storage: 2Gi
  accessModes:          # 訪問模式
  storageClassName:      # 存儲類別
  persistentVolumeReclaimPolicy:    # 回收策略

每一個屬性真的是又長又難記,咱們先來看看每一個屬性的含義:

  • 存儲類型

底層實際存儲的類型,k8s 支持多種存儲類型,每種存儲類型的配置都有所差別

  • 存儲能力(capacity)

目前只支持存儲空間的設置,將來可能會加入 IOPS、吞吐量等指標的設置

  • 訪問模式(accessModes)

用於描述用戶應用對存儲資源的訪問權限,有如下幾種訪問權限:

  1. ReadWriteOnce(RWO):讀寫權限,可是隻能被單個節點掛載
  2. ReadOnlyMany(ROM):只讀權限,能夠被多個節點掛載
  3. ReadWriteMany(RWM):讀寫權限,能夠被多個節點掛載
  • 存儲類別

PV 能夠經過storageClassName參數指定一個存儲類別

  1. 具備特定類別的PV只能與請求了該類別的PVC進行綁定
  2. 未設定類別的PV則只能與不請求任何類別的PVC進行綁定
  • 回收策略(persistentVolumeReclaimPolicy)

當PV沒有再被使用的時候,須要對其處理的方式(不一樣的存儲類型支持的策略也會不一樣),有如下幾種回收策略:

  1. Retain(保留):保留數據。須要管理員手動清理數據
  2. Recycle(回收):清除PV中的數據,效果至關於 rm -rf
  3. Delete(刪除):與 PV 相連的後端存儲完成 volume 的刪除操做,常見於雲服務商的存儲服務
生命週期:

一個 PV 的生命週期可能會處於4種不一樣的階段:

  • Available(可用): 表示可用狀態,還未被任何PVC綁定
  • Bound(已綁定): 表示PV已經被PVC綁定
  • Released(已釋放): 表示PVC已被刪除,可是資源還未被集羣從新聲明
  • Failed(失敗): 表示該PV的自動回收失敗
實戰:

咱們前面已經認識了NFS存儲服務器,所以咱們這裏也依然使用 NFS 服務器作底層存儲。首先咱們須要建立1個PV,也對應着NFS中1個須要暴露的路徑。

# 建立目錄
mkdir /data/pv1 -pv

# 向NFS暴露路徑
vim /etc/exports
/data/pv1   192.168.108.0/24(rw,no_root_squash)

完成以上步驟後咱們就須要建立1個 PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv01
  namespace: cbuc-test
  labels:
    app: pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /data/pv1
    server: 192.168.108.100

經過建立後咱們能夠查看到PV:

2)PVC

PVC是資源的申請,用來聲明對存儲空間,訪問模式,存儲類別的需求信息,資源清單模板以下:

apiVersion: v1
kind: persistentVolumeClaim
metadata:
  name: pvc
  namespace: cbuc-test
  labels:
    app: pvc
spec:
  accessModes:          # 訪問模式
  selector:                # 採用標籤對PV選擇
  storageClassName:        # 存儲類別
  resources:                # 請求空間
    request:
      storage: 1Gi

不少屬性咱們在PV中已經瞭解到了,這裏咱們簡單過一下~

  • 訪問模式(accessModes)

用於描述用戶應用對存儲資源的訪問權限

  • 選擇條件(selector)

經過 Labels Selector的設置,對於系統中已經存在的PV進行篩選管理

  • 資源類別(storageClassName)

pvc在定義時能夠設定須要的後端存儲的類別,只有設置了該class的pv才能被系統選出

  • 資源請求(resources)

描述對存儲資源的請求

實戰:

準備1份PVC的資源清單模板:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc01
  namespace: cbuc-test
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

建立後咱們先查看PVC是否建立成功

而後再查看pv是否已經被pvc綁定上

3)實際使用

上面咱們已經成功建立了 PV 和 PVC,可是還沒說明如何使用,接下來咱們就準備一份pod清單:

apiVersion: v1
kind: Pod
metadata:
  name: pod-pvc
  namespace: cbuc-test
spec:
  containers:
  - name: nginx01
    image: nginx:1.14-alpine
    volumeMounts:
    - name: test-pv
      mountPath: /var/log/nginx
  volumes:
  - name: test-pv
    persistentVolumeClaim:
      claimName: pvc01
      readOnly: true

4)生命週期

萬物皆有生命週期,PV與PVC也不例外,生命週期以下:

  • 資源供應

管理員手動建立底層存儲和PV

  • 資源綁定

用戶建立PVC,k8s負責根據PVC的聲明去尋找PV,並綁定。

  1. 若是找到,則會成功進行綁定,用戶的應用就可使用這個PVC了
  2. 若是找不到,PVC則會無限處於Pending的狀態,直到等到系統管理員建立了一個符合其要求的PV

PV一旦綁定到某個PVC上,就會被這個PVC獨佔,不能再與其餘PVC進行綁定了

  • 資源使用

用戶可在Pod中想 volume 同樣使用pvc

  • 資源釋放

用戶經過刪除PVC來釋放PV,當存儲資源使用完畢後,用戶能夠刪除PVC,與該PVC綁定的PV將會標記爲 已釋放,但還不能馬上與其餘PVC進行綁定,經過以前PVC寫入的數據可能還留在存儲設備上,只有在清除以後該PV才能再次使用

  • 資源回收

k8s 會根據pv設置的回收策略進行資源的回收

上面列出了 PV和PVC 的生命週期,與其說是生命週期,但不如是PV和PVC的使用過程!

3、配置存儲

配置存儲,顧名思義就是用來存儲配置的,其中包括了兩種配置存儲,分別是 ConfigMapSecret

1)ConfigMap

ConfigMap 是一種比較特殊的存儲卷,它的主要做用是用來存儲配置信息的。資源清單模板以下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cmp
  namespace: cbuc-test
data:
  info:
    username:cbuc
    sex:male

使用方式很簡單,少了 spec,多了 data.info,只需在 info 下級以 key: value 的方式存儲本身想要配置的配置文件便可

經過kubectl create -f configMap.yaml命令可建立出一個 ConfigMap

具體使用以下,咱們須要建立一個Pod:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: cbuc-test
spec:
  containers:
  - name: nginx
    image: nginx:1.14-apline
    volumeMounts:        # 將 configMap 掛載到目錄中
    - name: config
      mountPath: /var/configMap/config
  volumes:
  - name: config
    configMap:
      name: cmp  # 上面咱們建立 configMap 的名稱

而後經過命令kubectl create -f pod-cmp.yaml建立出測試Pod,而後可查看pod中的配置文件:

2)Secret

在 k8s 中,還存在一種和 ConfigMap 很是相似的對象,稱之爲 Secret 對象。它主要用於存儲敏感信息,例如密碼、祕鑰、證書等信息。

咱們首先對想要配置的數據進行 base64 加密:

# 加密用戶名
[root@master test]# echo -n 'cbuc' | base64
Y2J1Yw==
# 加密密碼
[root@master test]# echo -n '123456' | base64
MTIzNDU2

而後準備 Secret 資源清單文件

apiVersion: v1
kind: Secret
metadata:
  name: secret
  namespace: cbuc-test
type: Opaque    # 表示base64編碼格式的Secret
data:
  username: Y2J1Yw==
  password: MTIzNDU2

經過命令kubectl create -f secret.yaml建立 Secret,而後咱們再準備一份Pod資源清單:

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
  namespace: cbuc-test
spec:
  containers:
  - name: nginx
    image: nginx:1.14-apline
    volumeMounts:
    - name: config
      mountPath: /var/secret/config
  volumes:
  - name: config
    secret:
      secretName: secret

建立後咱們進入pod查看配置文件,能夠發現配置文件的信息已是解碼後的

END

這篇咱們就介紹了 k8s 的數據存儲,篇幅較短,是否是意猶未盡,咱們下篇再見(Server和Ingress)!路漫漫,小菜與你一同求索~

看完不讚,都是壞蛋

今天的你多努力一點,明天的你就能少說一句求人的話!

我是小菜,一個和你一塊兒學習的男人。 💋

微信公衆號已開啓,小菜良記,沒關注的同窗們記得關注哦!

相關文章
相關標籤/搜索