Kubernetes 學(xué)習(xí)筆記(七)--- K8S存儲(chǔ)卷、ConfigMap、Secrets

目錄

emptyDir
gitRepo
hostPath
nfs
pvc
    1. 配置NFS共享存儲(chǔ):
    2. 創(chuàng)建PV
    3. 定義PVC,并使用

accessModes <[]string>
存儲(chǔ)類(StorageClass)

configmap
    1. 通過(guò)命令行創(chuàng)建ConfigMap
    2. 通過(guò)yaml文件創(chuàng)建ConfigMap
    3. 使用ConfigMap
secret

存儲(chǔ)卷是屬于Pod,不屬于容器。但是可以在容器中去掛載存儲(chǔ)卷來(lái)使用。

K8S上可用的存儲(chǔ)卷類型:

emptyDir

空目錄,只在節(jié)點(diǎn)本地使用,一旦Pod被刪除,則這個(gè)存儲(chǔ)卷也會(huì)隨之刪除;所以,emptyDir這種存儲(chǔ)卷不是做為持久化而設(shè)計(jì)的,可以做為臨時(shí)目錄,按需創(chuàng)建。也可以當(dāng)做緩存空間來(lái)使用。emptyDir存儲(chǔ)卷的生命周期同Pod容器。
使用示例:https://kubernetes.io/docs/concepts/storage/volumes/#emptydir

gitRepo

在Pod創(chuàng)建時(shí),會(huì)自動(dòng)連接至Git倉(cāng)庫(kù)(需要確保宿主機(jī)有g(shù)it命令,它是基于宿主機(jī)來(lái)驅(qū)動(dòng)的。),將Git倉(cāng)庫(kù)里的代碼克隆至宿主機(jī)的某個(gè)目錄,并把這個(gè)目錄做為存儲(chǔ)卷掛載至Pod上。實(shí)質(zhì)上gitRepo是建立在emptyDir之上的。gitRepo本質(zhì)上也是emptyDir。
使用示例:https://kubernetes.io/docs/concepts/storage/volumes/#gitrepo

hostPath

宿主機(jī)路徑,將宿主機(jī)文件系統(tǒng)上的路徑做為存儲(chǔ)卷掛載至Pod容器中。Pod刪除后,此存儲(chǔ)卷不會(huì)被刪除,數(shù)據(jù)不會(huì)丟失。不過(guò)在跨節(jié)點(diǎn)調(diào)度時(shí),必須保證每個(gè)節(jié)點(diǎn)主機(jī)上的相同路徑有相同的數(shù)據(jù)。
使用示例:https://kubernetes.io/docs/concepts/storage/volumes/#hostpath

nfs

通過(guò)命令:kubectl explain pod.spec.volumes.nfs查看用法 。

image.png

pvc

PVC (Persistent Volume Claim)持久化卷請(qǐng)求。

PVC示意圖:


image.png

存儲(chǔ)設(shè)備由存儲(chǔ)管理員去管理,pv由K8S集群管理員定義,pvc由K8S用戶或開發(fā)者定義


image.png

使用PVC的流程:

  1. 配置存儲(chǔ)空間 --- 由存儲(chǔ)管理員配置存儲(chǔ)設(shè)備(如NFS,iSCSI,Ceph RBD,Glusterfs),并且劃割好了很多可被獨(dú)立使用的存儲(chǔ)空間;
  2. 定義PV --- K8S集群管理員將配置好的那些存儲(chǔ)空間引入至K8S集群中,定義成PV (Persistent Volume,持久化卷);
  3. 定義PVC --- K8S用戶在創(chuàng)建Pod時(shí)如果要用到PVC時(shí),必須先創(chuàng)建PVC( 在K8S集群中找一個(gè)能符合條件的存儲(chǔ)卷PV來(lái)用)。注意:PV和PVC是一一對(duì)應(yīng)關(guān)系,一旦某個(gè)PV被一個(gè)PVC占用,那么這個(gè)PV就不能再被其他PVC占用,被占用的PV的狀態(tài)會(huì)顯示為Bound。PVC創(chuàng)建以后,就相當(dāng)于一個(gè)存儲(chǔ)卷,可以被多個(gè) Pod所使用。
  4. 使用PVC --- 在Pod中去使用PVC,如果符合PVC條件的PV不存在,而這時(shí)去使用這個(gè)PVC,則Pod這時(shí)會(huì)顯示Pending(掛起)狀態(tài)。

接下來(lái)演示一個(gè)使用NFS做為后端存儲(chǔ)的PVC使用示例:

1. 配置NFS共享存儲(chǔ):

這里用192.168.100.132做為NFS共享存儲(chǔ)服務(wù)器。

# 安裝NFS軟件包
yum install nfs-utils -y

mkdir /data/nfs/volumes/v{1,2,3,4,5} -p

# 編輯/etc/exports文件
[root@fh-db nfs]# cat /etc/exports
/data/nfs/volumes/v1    192.168.100.0/24(rw,no_root_squash)
/data/nfs/volumes/v2    192.168.100.0/24(rw,no_root_squash)
/data/nfs/volumes/v3    192.168.100.0/24(rw,no_root_squash)
/data/nfs/volumes/v4    192.168.100.0/24(rw,no_root_squash)
/data/nfs/volumes/v5    192.168.100.0/24(rw,no_root_squash)


# 導(dǎo)出共享目錄
[root@fh-db nfs]# exportfs -arv
exporting 192.168.100.0/24:/data/nfs/volumes/v5
exporting 192.168.100.0/24:/data/nfs/volumes/v4
exporting 192.168.100.0/24:/data/nfs/volumes/v3
exporting 192.168.100.0/24:/data/nfs/volumes/v2
exporting 192.168.100.0/24:/data/nfs/volumes/v1

# 啟動(dòng)nfs
[root@fh-db nfs]# systemctl start nfs

[root@fh-db nfs]# showmount -e localhost
Export list for localhost:
/data/nfs/volumes/v5 192.168.100.0/24
/data/nfs/volumes/v4 192.168.100.0/24
/data/nfs/volumes/v3 192.168.100.0/24
/data/nfs/volumes/v2 192.168.100.0/24
/data/nfs/volumes/v1 192.168.100.0/24

注意:K8S集群節(jié)點(diǎn)上也需要安裝nfs:yum install nfs-utils -y,否則在使用nfs做為存儲(chǔ)卷時(shí)不能正常掛載。

2. 創(chuàng)建PV

PV也是標(biāo)準(zhǔn)的K8S資源,但是PV是K8S集群級(jí)別的資源,而不是namespace(名稱空間)級(jí)別的資源。所以在定義PV時(shí),不需要指定namespace。這就意味著PV不限名稱空間,所有名稱空間都可使用。需要注意的是PVC是namespace級(jí)別的資源。

PV的訪問(wèn)模式(accessModes <[]string>

  • ReadWriteOnce --- 單路讀寫,顯示簡(jiǎn)寫:RWO
  • ReadOnlyMany --- 多路只讀,顯示簡(jiǎn)寫:ROX
  • ReadWriteMany --- 多路讀寫,顯示簡(jiǎn)寫:RWX

    注意:定義PV清單文件時(shí),訪問(wèn)模式不支持簡(jiǎn)寫,簡(jiǎn)寫僅用于顯示時(shí)。

需要注意的是,有些后端存儲(chǔ)設(shè)備是不支持多路讀寫的,在定義PV的訪問(wèn)模式時(shí),需要確認(rèn)后端存儲(chǔ)設(shè)備支持的訪問(wèn)模式。PV的訪問(wèn)模式只能是存儲(chǔ)設(shè)備支持的訪問(wèn)模式的子集。參考如下:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes

image.png

capacity: 指定PV的可用存儲(chǔ)容量,單位:M | G | T | P | E (1000換算),Mi | Gi | Ti | Pi | Ei (1024換算)

PV的回收策略(persistentVolumeReclaimPolicy <string>):
如果某個(gè)已經(jīng)綁定PV的PVC被刪除了,那么這個(gè)PV將被回收,回收策略有以下三種:

  • Retain --- 默認(rèn),表示保留PV中存在的數(shù)據(jù),在PV下次被PVC綁定時(shí),數(shù)據(jù)還存在;通常都使用這種回收策略。
  • Recycle --- 回收,表示將刪除PV里面的數(shù)據(jù),并將其狀態(tài)置為空閑狀態(tài),供其他PVC去綁定;危險(xiǎn)!
  • Delete --- 刪除,表示如果PVC刪除了,那么PV也隨之刪除,數(shù)據(jù)會(huì)被清除。危險(xiǎn)!

編輯PV清單文件:vim pv-demo.yaml

---
apiVersion: v1
kind: PersistentVolume
metadata: 
  name: pv001
  labels:
    name: pv001
spec: 
  nfs:
    path: /data/nfs/volumes/v1
    server: 192.168.100.132
  accessModes: ['ReadWriteOnce', 'ReadWriteMany', 'ReadOnlyMany']
  capacity:
    storage: 20Gi

---
apiVersion: v1
kind: PersistentVolume
metadata: 
  name: pv002
  labels:
    name: pv002
spec: 
  nfs:
    path: /data/nfs/volumes/v2
    server: 192.168.100.132
  accessModes: ['ReadWriteOnce', 'ReadWriteMany']
  capacity:
    storage: 10Gi

---
apiVersion: v1
kind: PersistentVolume
metadata: 
  name: pv003
  labels:
    name: pv003
spec: 
  nfs:
    path: /data/nfs/volumes/v3
    server: 192.168.100.132
  accessModes: ['ReadOnlyMany']
  capacity:
    storage: 5Gi

---
apiVersion: v1
kind: PersistentVolume
metadata: 
  name: pv004
  labels:
    name: pv004
spec: 
  nfs:
    path: /data/nfs/volumes/v4
    server: 192.168.100.132
  accessModes: ['ReadOnlyMany', 'ReadWriteOnce']
  capacity:
    storage: 15Gi

---
apiVersion: v1
kind: PersistentVolume
metadata: 
  name: pv005
  labels:
    name: pv005
spec: 
  nfs:
    path: /data/nfs/volumes/v5
    server: 192.168.100.132
  accessModes: ['ReadWriteOnce', 'ReadWriteMany', 'ReadOnlyMany']
  capacity:
    storage: 10Gi

應(yīng)用PV清單文件pv-demo.yaml

[root@k8s-master manifests]# kubectl apply -f pv-demo.yaml 
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
persistentvolume/pv004 created
persistentvolume/pv005 created

查看生成的PV:

[root@k8s-master manifests]# kubectl get pv 
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
pv001     20Gi       RWO,ROX,RWX    Retain           Available                                      7m
pv002     10Gi       RWO,RWX        Retain           Available                                      7m
pv003     5Gi        ROX            Retain           Available                                      7m
pv004     15Gi       RWO,ROX        Retain           Available                                      7m
pv005     10Gi       RWO,ROX,RWX    Retain           Available                                      7m

3. 定義PVC,并使用

accessModes <[]string>

PVC也需要定義訪問(wèn)模式,且PVC的訪問(wèn)模式必須得是PV的子集。也就是說(shuō)只有符合PVC訪問(wèn)模式的PV,才能夠與PVC進(jìn)行綁定。注意:PVC必須與Pod在同一名稱空間才能被Pod使用。

編輯清單文件pod-vol-pvc.yaml

---
# 定義PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata: 
  name: mypvc
  namespace: default
spec:
  accessModes: ['ReadWriteMany']
  resources:
    requests:
      storage: 8Gi

---
# 定義Pod
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-pvc
  namespace: default
spec:
  containers:
  - name: myapp-pvc
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    persistentVolumeClaim:
      claimName: mypvc          # 使用上述定義的PVC名稱

應(yīng)用清單文件:

[root@k8s-master manifests]# kubectl apply -f pod-vol-pvc.yaml 
persistentvolumeclaim/mypvc created
pod/pod-vol-pvc created

再來(lái)查看PV列表:


image.png

從上圖可以看出,名為pv002的PV符合PVC定義的條件被綁定了。

查看PVC:

[root@k8s-master manifests]# kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc     Bound     pv002     10Gi       RWO,RWX                       22

注意:如果此時(shí)發(fā)現(xiàn)Pod沒(méi)有正常運(yùn)行,查看pod描述信息中的Events,顯示Pod掛載volume pv002失敗。去檢查Pod調(diào)度到的那個(gè)節(jié)點(diǎn)主機(jī)是否安裝了nfs-utils包。然后安裝即可:yum install -y nfs-utils。

image.png

在kubernetes 1.9+ ,只要PV被PVC綁定著,那么PV就不能被刪除。

存儲(chǔ)類(StorageClass)

使用上述PVC時(shí),有一個(gè)弊端:當(dāng)K8S用戶創(chuàng)建要使用PVC時(shí),必須確保K8S集群中已經(jīng)存在符合PVC條件的PV,否則Pod就會(huì)處于Pending(掛起)狀態(tài)。

存儲(chǔ)類(StorageClass)就是來(lái)解決這個(gè)問(wèn)題的。使用存儲(chǔ)類時(shí),無(wú)需事先創(chuàng)建好PV。而是在使用PVC時(shí),根據(jù)PVC的條件,動(dòng)態(tài)創(chuàng)建PV供PVC綁定。

定義存儲(chǔ)類,可以從任意維度去給存儲(chǔ)分類:如存儲(chǔ)性能、存儲(chǔ)所在區(qū)域等等。。。

定義好存儲(chǔ)類以后,PVC再去申請(qǐng)PV時(shí),不再直接針對(duì)PV進(jìn)行綁定,而是通過(guò)存儲(chǔ)類去動(dòng)態(tài)創(chuàng)建符合PVC條件的PV,再進(jìn)行綁定。

但是后端的存儲(chǔ)設(shè)備必須要支持RESTful 風(fēng)格的創(chuàng)建請(qǐng)求接口,才能通過(guò)存儲(chǔ)類實(shí)現(xiàn)PV的動(dòng)態(tài)供給。支持RESTful 有后端存儲(chǔ)設(shè)備有Ceph,Glusterfs通過(guò)第三方接口也可以實(shí)現(xiàn)RESTful風(fēng)格的接口。但是去部署這樣的后端存儲(chǔ)設(shè)備,也不是一件容易的事件。所以存儲(chǔ)類(StorageClass)的操作先暫時(shí)放下,后續(xù)再說(shuō)。。。

configmap

secret和configmap可以理解為特殊的存儲(chǔ)卷,但是它們不是給Pod提供存儲(chǔ)功能的,而是提供了從集群外部向集群內(nèi)部的應(yīng)用注入配置信息的功能。ConfigMap扮演了K8S集群中配置中心的角色。ConfigMap定義了Pod的配置信息,可以以存儲(chǔ)卷的形式掛載至Pod中的應(yīng)用程序配置文件目錄,從configmap中讀取配置信息;也可以基于環(huán)境變量的形式,從ConfigMap中獲取變量注入到Pod容器中使用。但是ConfigMap是明文保存的,如果用來(lái)保存數(shù)據(jù)庫(kù)賬號(hào)密碼這樣敏感信息,就非常不安全。一般這樣的敏感信息配置是通過(guò)secret來(lái)保存。secret的功能和ConfigMap一樣,不過(guò)secret是通過(guò)Base64的編碼機(jī)制保存配置信息。

1. 通過(guò)命令行創(chuàng)建ConfigMap

使用nginx_port=8080nginx_server_name=myapp.magedu.com創(chuàng)建名為my-config的新ConfigMap

kubectl create configmap my-config --from-literal=nginx_port=8080 --from-literal=nginx_server_name=myapp.magedu.com

創(chuàng)建一個(gè)新ConfigMap名為my-www,指定key名為key1,value為file1.txt的內(nèi)容

kubectl create configmap my-www --from-file=www_conf=./www.conf

創(chuàng)建一個(gè)新ConfigMap名為my-www,key名默認(rèn)為文件名www.conf,value為文件www.conf的內(nèi)容。

kubectl create configmap my-www --from-file=./www.conf

2. 通過(guò)yaml文件創(chuàng)建ConfigMap

編輯文件:nginx-cm.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-cm-yaml
  namespace: default
data:
  nginx_server_port: "8088"
  nginx_server_name: "myapp01.magedu.com"

注意:如上,ConfigMap的清單文件相對(duì)較簡(jiǎn)單,它沒(méi)有spec字段,data字段的內(nèi)容就是配置信息數(shù)據(jù),配置信息數(shù)據(jù)的值必須用引號(hào)包含(如:nginx_server_port: "8088"),否則創(chuàng)建時(shí)會(huì)報(bào)錯(cuò)。

根據(jù)清單文件創(chuàng)建ConfigMap

kubectl apply -f nginx-cm.yaml

獲取前兩步創(chuàng)建的ConfigMap

[root@k8s-master manifests]# kubectl get cm
NAME            DATA      AGE
my-config       2         4h
my-www          1         1h
nginx-cm-yaml   2         50m

注意:cmconfigmap的簡(jiǎn)寫??赏ㄟ^(guò)kubectl api-resources命令查看K8S所有資源和對(duì)應(yīng)簡(jiǎn)寫。

3. 使用ConfigMap

從ConfigMap中獲取配置信息的方法有兩種:

  • 一種是利用環(huán)境變量將配置信息注入Pod容器中的方式,這種方式只在Pod創(chuàng)建的時(shí)候生效,這就意味著在ConfigMap中的修改配置信息后,更新的配置不能被已經(jīng)創(chuàng)建Pod容器所應(yīng)用。
  • 另一種是將ConfigMap做為存儲(chǔ)卷掛載至Pod容器內(nèi),這樣在修改ConfigMap配置信息后,Pod容器中的配置也會(huì)隨之更新,不過(guò)這個(gè)過(guò)程會(huì)有稍微的延遲。

先來(lái)看看通過(guò)環(huán)境變量注入配置信息的方式:
vim pod-configmap-env.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp-configmap
  labels:
    name: myapp-configmap
    config: configmap
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    env:
    - name: NGINX_SERVER_PORT
      valueFrom:
        configMapKeyRef:
          name: my-config
          key: nginx_port
    - name: NGINX_SERVER_NAME          # 傳入Pod容器中的變量名為NGINX_SERVER_NAME,值為      
      valueFrom:
        configMapKeyRef:
          name: my-config              # 選擇需要的configmap的名稱
          key: nginx_server_name            

要點(diǎn):NGINX_SERVER_PORTNGINX_SERVER_NAME是傳入Pod容器內(nèi)的變量名,它的值是從名為my-config(ConfigMap)中對(duì)應(yīng)的KEY獲取。NGINX_SERVER_NAME=nginx_server_name=myapp.magedu.com

應(yīng)用清單文件創(chuàng)建Pod:

kubectl apply -f pod-configmap-env.yaml 

進(jìn)入Pod容器中驗(yàn)證變量是否存在:

# 進(jìn)入指定Pod的命令
kubectl exec -it myapp-configmap -- /bin/sh
image.png

從上圖可以看出變量已經(jīng)傳入Pod容器中了。

接下來(lái)再看一下把ConfigMap當(dāng)作存儲(chǔ)卷掛載至Pod中的用法:

編輯vim pod-configmap-vol-2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap-vol-2
  labels:
    name: pod-configmap-vol-2
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: my-cm-www
      mountPath: /etc/nginx/conf.d/       # 將名為my-www的configmap掛載至Pod容器的這個(gè)目錄下。
  volumes:
  - name: my-cm-www
    configMap:               # 存儲(chǔ)卷類型選configMap
      name: my-www           # 選擇一個(gè)configmap

應(yīng)用清單文件創(chuàng)建Pod:

kubectl apply -f pod-configmap-vol-2.yaml

進(jìn)入名為pod-configmap-vol-2的Pod中驗(yàn)證:

image.png

從上圖中可以看出ConfigMap已經(jīng)掛載至Pod容器中了。

secret

待續(xù)。。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容