一、理解存儲卷
Volume(存儲卷)是Pod中能夠被多個容器訪問的共享目錄。解決了容器崩潰時文件丟失(容器中的文件默認情況下在磁盤是臨時存放)和多容器共享文件的問題。
<img src="https://confluence.mysre.cn/download/attachments/53852724/image2021-12-14_9-41-23.png?version=1&modificationDate=1639446083199&api=v2" alt="volume" width=680 />
與 docker 存儲卷的區別
docker volume:定義在容器上,生命周期是與容器的生命周期相同;
k8s volume:定義在 pod 上,與 pod 的生命周期相同,容器終止或重啟,卷的數據是不會丟失的。
k8s存儲卷類型
常用的存儲卷類型有:emptyDir、hostPash、NFS、secret、configMap、persistentVolumeClaim。
更多請參考官方鏈接。
emptyDir
在 Pod 分配到 Node 時創建,初始內容為空,并且無須指定宿主機上對應的目錄文件,因為這是 Kubernetes 自動分配的一個目錄,當Pod 從 Node 上移除時,emptyDir 中的數據也會被永久刪除。
emptyDir 的一些用途如下:
1、臨時空間,例如用于某些應用程序運行時所需的臨時目錄,且無須永久保留。例如用于基于磁盤的歸并排序。
2、長時間任務的中間過程的臨時保存目錄。檢查點用于從崩潰中恢復的長時間計算。
3、一個容器需要從另一個容器中獲取數據的目錄(多容器共享目錄)。保存內容管理器容器獲取的文件,而網絡服務器容器提供數據。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
volumes: 指定卷的名稱和類型等卷配置;
volumeMounts: 指定掛載那個卷及掛載目錄等。
使用數據卷流程:鏡像里程序寫的目錄 -> mountPath 掛載到寫的目錄 -> 引用的volumes對應的name -> 相關卷的配置
persistentVolumeClaim(重要)
持久卷聲明類型。通過這個聲明,可以在不知道存儲卷類型的情況下進行申請持久化存儲。需要和PV一起搭配。
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: xxx.xxx.xx.xx
path: "/"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: manual
resources:
requests:
storage: 1Gi
---
...(省略)
spec:
containers:
- name: nginx-demo
image: nginx
imagePullPolicy: Always
volumeMounts:
- name: nfs-pvc-vol
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc-vol
persistentVolumeClaim:
claimName: nfs
pv/pvc完成綁定的條件:
- 第一個條件,檢查 PV 和 PVC 的 spec 字段。比如,PV 的存儲(storage)大小,就必須滿足 PVC 的要求。
- 第二個條件,則是 PV 和 PVC 的 storageClassName 字段必須一樣。
hostPath
hostPath 為在 Pod 上掛載宿主機上的文件或目錄,它通常可以用于以下幾方面:
1、容器應用程序生成的日志文件需要永久保存時,可以使用宿主機的高速文件系統進行存儲。
2、 需要訪問宿主機上Docker引擎內部數據結構的容器應用時,可以通過定義hostPath為宿主機/var/lib/docker目錄,使容器內部應用可以直接訪問Docker的文件系統。
注意: 在不同的Node上具有相同配置的Pod,可能會因為宿主機上的目錄和文件不同而導致對Volume上目錄和文件的訪問結果不一致。
官方地址-ctrl+f搜索關鍵字
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
type取值 | 行為 |
---|---|
空字符串(默認)用于向后兼容,這意味著在安裝 hostPath 卷之前不會執行任何檢查。 | |
DirectoryOrCreate | 如果在給定路徑上什么都不存在,那么將根據需要創建空目錄,權限設置為 0755,具有與 kubelet 相同的組和屬主信息。 |
Directory | 在給定路徑上必須存在的目錄。 |
FileOrCreate | 如果在給定路徑上什么都不存在,那么將在那里根據需要創建空文件,權限設置為 0644,具有與 kubelet 相同的組和所有權。 |
File | 在給定路徑上必須存在的文件。 |
Socket | 在給定路徑上必須存在的 UNIX 套接字。 |
CharDevice | 在給定路徑上必須存在的字符設備。 |
BlockDevice | 在給定路徑上必須存在的塊設備 |
NFS
不像 emptyDir 那樣會在刪除 Pod 的同時也會被刪除,nfs 卷的內容在刪除 Pod 時會被保存,卷只是被卸載。 這意味著 nfs 卷可以被預先填充數據,并且這些數據可以在 Pod 之間共享。
volumes:
- name: nfs-volume
nfs:
server: xxx.xx.xxx.xx # 服務地址
path: /path # 存放路徑
secret
secret 卷用來給 Pod 傳遞敏感信息,例如密碼、OAuth 令牌和 SSH 密鑰,它們不會被寫到持久化的存儲器里面,是以文件的形式掛在到 Pod 中,且無需直接與 Kubernetes 耦合。
- 作為掛載到一個或多個容器上的 卷 中的文件
- 以環境變量的形式使用 Secrets
- 由 kubelet 在為 Pod 拉取鏡像時使用
secret type類型
- Service Account:Kubernetes 自動創建包含訪問 API 憑據的 secret,并自動修改 pod 以使用此類型的 secret。
- Opaque:使用base64編碼存儲信息,可以通過base64 --decode解碼獲得原始數據,因此安全性弱。
- kubernetes.io/dockerconfigjson:用于存儲docker registry的認證信息。
configMap
提供了向 Pod 注入配置數據的方法,用來將非機密性的數據保存到鍵值對中,比如存儲卷中的配置文件。 ConfigMap 對象中存儲的數據可以被 configMap 類型的卷引用,然后被 Pod 中運行的 容器化應用使用(以key-value的形式)。
示例實踐:configMap引用
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
---
apiVersion: v1
kind: ConfigMap
metadata:
name: log-config
namespace: default
data:
log_level: INFO
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
---
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
<img src="https://confluence.mysre.cn/download/attachments/53852724/image2021-12-15_11-41-47.png?version=1&modificationDate=1639539707531&api=v2" alt="configMap" width=680 />
實踐一:【掛載NFS卷】
- step1:在master節點執行 NFS 工具包安裝命令:
yum install -y nfs-utils
systemctl enable rpcbind
systemctl enable nfs
systemctl start rpcbind
systemctl start nfs
- step2: 創建 NFS 目錄并授權:
mkdir -p /data/nfs/pv-1 && mkdir -p /data/nfs/pv-2 && mkdir -p statefulSet-1
chmod -R 755 /data/nfs
- step3:配置NFS目錄權限(這里我們直接設置成可讀寫):
vim /etc/exports
加入下面兩行配置
/data/nfs/pv-1 *(rw,sync,no_root_squash,no_all_squash)
/data/nfs/pv-2 *(rw,sync,no_root_squash,no_all_squash)
/data/nfs/statefulSet-1 *(rw,sync,no_root_squash,no_all_squash)
# 立即生效
exportfs -rv
step3參數exports說明:
rw 讀寫
ro 只讀
sync 數據直接寫入磁盤
async 數據先寫入內存
no_root_squash 對root用戶不壓制,在服務端都映射為服務端的root用戶,即僅使用普通用戶授權。
root_squash 如果客戶端是用戶root操作,會被壓制成nobody用戶,即可以使用 root 授權。
all_squash 不管客戶端的使用nfs的用戶是誰,都會壓制成nobody用戶
nonuid=uid: 指定uid的值
anongid=gid:指定gid的值
- step4: 查看NFS服務的掛載卷列表
[root@master configMap]# showmount -e
Export list for master:
/data/nfs/pv-2 *
/data/nfs/pv-1 *
在使用的node節點上分別安裝nfs工具包
yum install nfs-utils
在node節點上檢查master節點的nfs servcie服務是否可用
[root@node2 config]# showmount -e 192.168.23.10
Export list for 192.168.23.10:
/data/nfs/pv-2 *
/data/nfs/pv-1 *
- step5:創建一個pod應用來引用上面的nfs進行掛載
nfs-kdemo.yaml
kind: Pod
apiVersion: v1
metadata:
name: nfs-pod-test
spec:
volumes:
- name: nfs-volume
nfs:
server: 192.168.23.10
path: /data/nfs/pv-1
containers:
- name: nfs-kdemo-test
image: registry.cn-hangzhou.aliyuncs.com/liwb/kdemo:1.9
volumeMounts:
- name: nfs-volume
mountPath: /var/nfs/pv-1
command: ["/bin/sh"]
args: ["-c", "while true; do date >> /var/nfs/pv-1/dates.txt; sleep 5; done"]
不需要進入pod,我們就可以發現在外面的掛載目錄下就能看到同步了pod中輸出的數據
[root@master nfs]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-pod-test 1/1 Running 0 4s
[root@master nfs]# tail -f /data/nfs/pv-1/dates.txt
Wed Dec 15 08:42:28 UTC 2021
Wed Dec 15 08:42:33 UTC 2021
Wed Dec 15 08:42:38 UTC 2021
Wed Dec 15 08:42:43 UTC 2021
Wed Dec 15 08:42:48 UTC 2021
Wed Dec 15 08:42:53 UTC 2021
Wed Dec 15 08:42:58 UTC 2021
Wed Dec 15 08:43:03 UTC 2021
Wed Dec 15 08:43:08 UTC 2021
Wed Dec 15 08:43:13 UTC 2021
Wed Dec 15 08:43:18 UTC 2021
Wed Dec 15 08:43:23 UTC 2021
^C
二、【pv/pvc/storageClass】掛載實踐
pv/pvc/storageClass概念
從yaml文件來解釋,如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: xxx.xxx.xx.xx
path: "/"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pv
spec:
accessModes:
- ReadWriteMany
storageClassName: manual
resources:
requests:
storage: 1Gi
PVC 描述的:是 Pod 想要使用的持久化存儲的屬性,比如存儲的大小、讀寫權限等。
PV 描述的:則是一個具體的 Volume 的屬性,比如 Volume 的類型、掛載目錄、遠程存儲服務器地址等。
PVC 和 PV ,是Kubernetes對于有狀態的容器應用或者對數據需要持久化的應用場景設計的。
PV是對底層網絡共享存儲的抽象,將共享存儲定義為一種“資源”,PVC則是用戶對存儲資源的一個“申請”。
其實跟“面向對象”的思想完全一致。PVC 可以理解為持久化存儲的“接口”,它提供了對某種持久化存儲的描述,但不提供具體的實現;而這個持久化存儲的“實現“部分則由 PV 負責完成。
pv常用配置
存儲能力(Capacity):
描述存儲設備具備的能力,目前僅支持對存儲空間的設置(storage=xx),未來可能加入IOPS、吞吐率等指標的設置。
訪問模式(Access Modes):
對PV進行訪問模式的設置,用于描述用戶的應用對存儲資源的訪問權限。訪問模式如下()里的縮寫,是在CLI中的訪問模式縮寫。
- ◎ ReadWriteOnce(RWO):讀寫權限,并且只能被單個Node掛載。
- ◎ ReadOnlyMany(ROX):只讀權限,允許被多個Node掛載。
- ◎ ReadWriteMany(RWX):讀寫權限,允許被多個Node掛載。
- ◎ ReadWriteOncePod(RWOP):讀寫權限,允許單個pod掛載,這僅支持 CSI 卷和 Kubernetes 1.22+ 版。如果您想確保整個集群中只有一個 Pod 可以讀取該 PVC 或寫入該 PVC,可使用 ReadWriteOncePod 訪問模式。
存儲類別(Class):
用于綁定PVC.具有特定類別的PV只能與請求了該類別的PVC進行綁定。未設定類別的PV則只能與不請求任何類別的PVC進行綁定。其他還有存儲卷模式(Volume Mode)、回收策略(Reclaim Policy)、掛載參數(Mount Options)等。
StorageClass
StorageClass作為對存儲資源的抽象定義,對用戶設置的PVC申請屏蔽后端存儲的細節,
一方面減少了用戶對于存儲資源細節的關注;另一方面減輕了管理員手工管理PV的工作,由系統自動完成PV的創建和綁定(動態資源供應模式),實現了動態的資源供應。
關鍵配置參數:
提供者(Provisioner):
描述存儲資源的提供者,也可以看作后端存儲驅動。目前Kubernetes支持的Provisioner都以 kubernetes.io/ 為開頭,用戶也可以使用自定義的后端存儲提供者。為了符合StorageClass的用法,自定義Provisioner需要符合存儲卷的開發規范。我們用的是阿里云的 alicloud/nas
<img src="https://confluence.mysre.cn/download/attachments/53852724/image2021-12-16_20-2-4.png?version=1&modificationDate=1639656125101&api=v2" alt="sc" width=680 />
Reclaim Policy的三種狀態
- 保持(Retain):刪除PV后后端存儲上的數據仍然存在,如需徹底刪除則需要手動刪除后端存儲volume
- 刪除(Delete):刪除被PVC釋放的PV和后端存儲volume
- 回收(Recycle):保留PV,但清空PV上的數據(已廢棄)
pod啟動的時候pv/pvc做了什么?
1、根據pod聲明的pvc找是否存在符合條件的pv,完成綁定(PV 和 PVC 的 spec 字段相同、PV 和 PVC 的 storageClassName 字段必須一樣);
2、為虛擬機掛載遠程磁盤到宿主機(attach);
3、格式化這個磁盤設備,然后將它掛載到宿主機指定的掛載點上。
<img src="https://confluence.mysre.cn/download/attachments/53852724/image2021-12-16_20-57-47.png?version=1&modificationDate=1639659467583&api=v2" alt="pv-pv-pvc-start-doing" width=680 />
PV生命周期
PV生命周期的各個階段某個PV在生命周期中可能處于以下4個階段(Phaes)之一。
Available:可用狀態,還未與某個PVC綁定。
Bound:已與某個PVC綁定。
Released:綁定的PVC已經刪除,資源已釋放,但沒有被集群回收。
Failed:自動資源回收失敗。
<img src="https://confluence.mysre.cn/download/attachments/53852724/image2021-12-16_20-56-52.png?version=1&modificationDate=1639659412553&api=v2" alt="生命周期" width=680 />
回收策略
當用戶對存儲資源使用完畢后,用戶可以刪除PVC,與該PVC綁定的PV將會被標記為“已釋放”,但還不能立刻與其他PVC進行綁定。通過之前PVC寫入的數據可能還被留在存儲設備上,只有在清除之后該PV才能再次使用。
在啟用動態供應模式的情況下,一旦用戶刪除了PVC,與之綁定的PV也將根據其默認的回收策略“Delete”被刪除。如果需要保留PV(用戶數據),則在動態綁定成功后,用戶需要將系統自動生成PV的回收策略從“Delete”改成“Retain”。
三、pv/pvc實踐
1、聲明一個 pvc,執行kubectl apply -f nfs-pvc.yaml
,內容為:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: "rwx-nfs-pvc"
resources:
requests:
storage: 20Mi
2、查看 pvc 狀態:
kubectl describe pvc nfs
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal FailedBinding 1s (x4 over 42s) persistentvolume-controller no persistent volumes available for this claim and no storage class is set
3、創建一個 statefulSet,執行kubectl apply -f nfs-deploy.yaml
,內容為:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx-demo
image: nginx
imagePullPolicy: Always
volumeMounts:
- name: nfs-pvc-vol
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc-vol
persistentVolumeClaim:
claimName: nfs-pvc
4、觀察 pod 的狀態,可以看到: pvc 在沒有綁定pv的情況會導致pod一直處于pending;
$ kubectl describe pod <pod-name>
5、創建一個 pv,執行kubectl apply -f pv.yaml
,內容為:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 20Mi
accessModes:
- ReadWriteMany
storageClassName: "rwx-nfs-pvc"
nfs:
server: 192.168.23.10
path: "/data/nfs/pv-2"
6、觀察pod狀態,可以看到,容器正常運行。
這里有個PersistentVolumeController的控制器, 會不斷地查看當前每一個 PVC,是不是已經處于 Bound(已綁定)狀態。如果不是,那它就會遍歷所有的、可用的 PV,并嘗試將其與這個“單身”的 PVC 進行綁定。
7、進入容器,執行:
cd /usr/share/nginx/html ** echo "hello nfs!" > index.html
8、退出容器,執行以下命令暴露服務:
kubectl expose deployment nginx-demo --port=80 --type=NodePort --target-port=80 --name=nginx-demo
9、瀏覽器查看頁面。
10、模擬容器掛掉,重啟pod后數據是否會丟失。
11、嘗試刪除pv、pvc,看是否成功。
kubectl delete pvc nfs
kubectl delete pv nfs
12、刪除deploy后再嘗試刪除pvc/pv;
四、使用StatefulSet創建有狀態的應用
StatefulSet
有以下幾個特點
- 穩定,并且具有唯一的網絡標識。
- 穩定,并且可以持久存儲。
- 有序,可優雅的部署和伸縮。
- 有序,可優雅的刪除和停止。
- 有序,可自動滾動更新。
即,我們的應用如有以上的任何一個特點,我們就可以使用stateFulSet控制器來完成應用的部署。
<img src="https://confluence.mysre.cn/download/attachments/53852399/image2021-12-9_1-48-48.png?version=1&modificationDate=1638985728830&api=v2" alt="statefulSet" width=840 />
statefulSet的一些概念
1.網絡標識
- Pod 名:唯一且不會發生變化,由$(stateFulSet name)-(0-N)組成,N為一個無限大的正整數,從0開始。
- 容器主機名:與Pod名稱一致且不會發生變化。
- A記錄:每一個副本都擁有唯一且不變的一條A記錄制定自己,格式為:
(service name).$(namespace name).svc
- Pod標簽,通過StateFulSet創建的每個Pod都擁有一個唯一的標簽,格式為:stateFulSet.kubernetes.io/pod-name=$(pod name),
通常可以將新的service單獨關聯到此標簽,來解決某個Pod的問題等。
2.存儲(pvc)
每個Pod都對應一個PVC,PVC的名稱格式:(pod name)-(0-N),N為一個無限大的正整數,從0開始。
當Pod被刪除的時候不會自動刪除對應的PVC,需要手動刪除。
每次Pod升級,重啟,刪除重新創建后都可以保證使用的是首次使用的PVC,保證數據的唯一性與持久化。
3.有序
- 當部署有N個副本的StatefulSet的時候,嚴格按照從0到N的順序創建,并且下一個Pod創建的前提是上一個Pod已經running狀態。
- 當刪除有N個副本的stateFulSet的時候,嚴格按照從N到0的順序刪除,并且下一個Pod刪除的前提是上一個Pod已經完全Delete。
- 當擴容StateFulSet副本的時候,每增加一個Pod的前提是上一個Pod已經running狀態。
- 當減少stateFulSet副本的時候,每刪除一個Pod的前提是上一個Pod已經完全delete。
- 當升級statefulSet的時候,嚴格按照從N到1的順序升級,并且下一個Pod升級的前提是上一個Pod已經running狀態。
4.無狀態服務(Stateless Service)
該服務運行的實例不會在本地存儲需要持久化的數據,并且多個實例對于同一個請求響應的結果是完全一致的,比如kdemo,我們可以同時啟動多個實例,但是我們訪問任意一個實例得到的結果都是一樣的,因為他唯一需要持久化的數據是存儲在MySQL數據庫中的,所以我們可以說kdemo這個應用是無狀態服務,但是MySQL數據庫就不是了,因為他需要把數據持久化到本地。
5.有狀態服務(Stateful Service)
就和上面的概念是對立的了,該無法運行的實例需要在本地存儲持久化數據,比如上面的MySQL數據庫,你現在運行在節點Node-1,那么他的數據就存儲在Node-1上面的,如果這個時候你把該服務遷移到節點Node-2去的話,那么久沒有之前的數據了,因為他需要去對應的數據目錄里面恢復數據,而此時沒有任何數據。
6.無頭服務(Headless Service)
Headless Service
在定義上和普通的 Service 幾乎一致, 只是他的 clusterIP: None
,所以,這個 Service 被創建后并不會被分配一個 cluster IP,而是會以 DNS 記錄的方式暴露出它所代理的 Pod,而且還有一個非常重要的特性,對于 Headless Service
所代理的所有 Pod 的 IP 地址都會綁定一個如下所示的 DNS 記錄:
<pod-name>.<svc-name>.<namespace>.svc.cluster.local
7.volumeClaimTemplates
用于給StatefulSet的Pod申請PVC,稱為卷申請模板,它會為每個Pod生成不同的PVC,關綁定到PV,從而實現Pod的專有存儲。
實踐四:使用pv/pvc部署statefulSet類型的Deployment
1.準備一個pvc用于綁定pv
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: kdemo-statefulset-pv
spec:
accessModes:
- ReadWriteMany
storageClassName: "rwx-statefulset-pvc"
resources:
requests:
storage: 20Mi
2.準備用于掛載的存儲卷pvpv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: kdemo-statefulset-pv
spec:
capacity:
storage: 20Mi
accessModes:
- ReadWriteMany
storageClassName: "rwx-statefulset-pvc"
nfs:
server: 192.168.23.10
path: "/data/nfs/statefulSet-1"
3.準備用于statefulset綁定的無頭服務headless-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kdemo-statefulset
namespace: default
labels:
app: kdemo-statefulset
spec:
ports:
- name: http
port: 80
targetPort: 80
clusterIP: None
selector:
app: kdemo-statefulset
4.statefulset使用的deployment文件statefulSet.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kdemo-statefulset
namespace: default
spec:
serviceName: "nginx-demo"
replicas: 1
selector:
matchLabels:
app: kdemo-statefulset
template:
metadata:
labels:
app: kdemo-statefulset
spec:
containers:
- name: kdemo-statefulset
image: registry.cn-hangzhou.aliyuncs.com/liwb/kdemo:1.9
imagePullPolicy: Always
volumeMounts:
- name: nfs-statefulset-vol
mountPath: /webser/www/kdemo/web
volumes:
- name: nfs-statefulset-vol
persistentVolumeClaim:
claimName: kdemo-statefulset-pv
依次執行部署
kubectl apply -f pvc.yaml
kubectl apply -f pv.yaml
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfs-pv-2 1Gi RWO Recycle Available slow 8s
# 可以看到成功創建了一個 PV 對象,狀態是:`Available`。
kubectl apply -f headless-svc.yaml
kubectl get svc
kubectl apply -f statefulSet.yaml
kubectl get pvc
通過 Headless Service
,StatefulSet 就保證了 Pod 網絡標識的唯一穩定性,由于 Pod IP 并不是固定的,所以我們訪問有狀態應用
實例的時候,就必須使用 DNS 記錄的方式來訪問
最后我們可以通過刪除 StatefulSet 對象來刪除所有的 Pod,Pod是按照倒序的方式進行刪除的
kubectl delete statefulsets kdemo-statefulset
kubectl get pods -w
五、思考
k8s明明已經有了多種存儲卷方式實現持久化存儲了。為什么還要增加pv/pvc的方式?
從上面的流程看通過pv/pvc的方式其實挺復雜的,這種方式是否過度設計?
六、作業
使用StorageClass的特性實現動態創建pv。