kubernetes(k8s) 配置nfs動態卷實現StatefulSet的持久化存儲
參考:
1、https://blog.csdn.net/weixin_41004350/article/details/90168631
2、https://blog.csdn.net/weixin_41004350/article/details/78492351
我們知道,平時kubernetes在部署無狀態服務的時候,並不需要太多考慮持久化存儲的事情,直接通過volume掛載網絡存儲,比如常見的nfs就能實現文件共享存儲。
但是如果在有狀態服務中,你就會需要很多的問題,比如:當你部署一些集羣服務的時候:
-
不可以用共享存儲,因爲每個服務的數據都不能相同。
-
不可以直接用node的本地路徑進行掛載,因爲pod的隨機性,一個node可能會跑多個pod副本,則會造成衝突。
-
數據量可能會很大,可能需要使用外部存儲,或者獨立的磁盤,雲盤等
-
就算用pv,pvc也很不方便,需要你提前手動創建,不方便擴展。
然後我們細數一下k8s裏的持久化存儲,總的分爲兩種,靜態卷和動態卷。靜態卷就是剛纔我們說的,volume掛載,或者通過手動創建pv,pvc進行掛載。都屬於靜態卷。而動態卷,則是將一個網絡存儲作爲一個StorageClass類,通過自己的配置,來動態的創建pv,pvc並進行綁定,這樣就可以實現動態的存儲生成與持久化保存。
具體詳細的k8s的存儲系統知識可以查看官方文檔
下面我們就說一下,怎麼通過nfs動態捲來實現有狀態服務的儲存。
1. centos7.6 配置NFS文件服務器,遠程共享文件
NFS 文件服務器,是可以遠程共享文件,將遠程文件掛載到本地,然後就可以作爲本地文件一樣進操作,所做更改則會同步到nfs遠程服務器上,在跨主機的共享文件上非常方便,比建立一個集中的ftp服務器要方便很多。之前的FTP文件文件服務器用於遠程驗證下載,上傳文件,但是需要驗證並登陸,才能進行操作,而且不能直接在另外一臺主機上直接下載網絡文件並保存在ftp上,而要先保存在本地,然後傳到ftp服務器上,繁瑣而不方便。
1.1 服務端安裝配置(也就是文件實際存放的位置)
1.1.1 安裝nfs 和 rpcbind(使用nfs服務,都需要安裝的rpc服務),並配置開機啓動
yum install nfs-utils
yum install rpcbind
systemctl enable nfs-server
systemctl enable rpcbind
1.1.2 啓動nfs 和rpcbind
systemctl start nfs
systemctl start rpcbind
systemctl status rpcbind # 查看服務狀態
1.1.3 創建要共享的文件,也可以是原先已經存在的文件夾
mkdir /mydata
1.1.4 爲文件夾設置用戶和用戶組,需要設爲nfsnobody
chown nfsnobody.nfsnobody /mydata
1.1.5 編輯nfs配置文件
添加配置,將本機的這個路徑的文件作爲nfs共享文件,共享給指定IP,或指定IP段
cat > /etc/exports <<\EOF
/mydata xxx.xxx.xxx.xxx(rw,sync,all_squash)
EOF
比如:
/mydata 10.177.106.0/24(rw,sync,all_squash)
1.1.6 重載配置
exportfs -rv
1.1.7 查看本地掛載情況
showmount -e localhost
1.2 客戶端安裝與配置(需要在nfs-provisioner pod所在節點安裝)
1.2.1 同樣需要先下載安裝nfs,rpcbind,並設爲開機啓動
yum install nfs-utils
yum install rpcbind
systemctl enable nfs
systemctl enable rpcbind
1.2.2 創建想要掛載的目錄文件
mkdir /usr/local/mydata
1.2.3 將服務端的目錄掛載到本地的對應目錄下
mount -t nfs xxx.xxx.xxx.xxx:/usr/local/mydata usr/local/mydata # xxx.xxx.xxx.xxx爲nfs服務IP
1.2.4 查看掛載情況
df -h
1.2.5 卸載掛載方式
umount /usr/local/mydata
注意:
(1)如果沒有關閉nfs服務端的防火牆,則會掛載失敗。需要在服務端開啓需要的端口,在centos7上,用firewalld防火牆直接開放nfs服務即可自動通過。
firewall-cmd --add-service=nfs --permanent firewall-cmd --reload
1.3 服務端參數詳解
1.3.1 配置可參考的參數如下
NFS客戶端地址:
指定IP: 192.168.0.1
指定子網所有主機: 192.168.0.0/24
指定域名的主機: test.com
指定域名所有主機: *.test.com
所有主機: *
1.3.2 參數
ro:目錄只讀
rw:目錄讀寫
1.3.3 這兩個影響性能的設置
sync:將數據同步寫入內存緩衝區與磁盤中,效率低,但可以保證數據的一致性
async:將數據先保存在內存緩衝區中,必要時才寫入磁盤
1.3.4 其他參數解釋
all_squash:將遠程訪問的所有普通用戶及所屬組都映射爲匿名用戶或用戶組(nfsnobody)
no_all_squash:與all_squash取反(默認設置)
root_squash:將root用戶及所屬組都映射爲匿名用戶或用戶組(默認設置)
no_root_squash:與rootsquash取反
anonuid=xxx:將遠程訪問的所有用戶都映射爲匿名用戶,並指定該用戶爲本地用戶(UID=xxx)
anongid=xxx:將遠程訪問的所有用戶組都映射爲匿名用戶組賬戶
2. k8s配置使用nfs作爲網絡存儲
2.1 創建namespace,用作測試的命名空間
apiVersion: v1
kind: Namespace
metadata:
name: test
labels:
name: test
2.2 創建RBAC授權
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
namespace: test
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get","create","list", "watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: test
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
2.3 創建nfs-provisioner
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
namespace: test
labels:
app: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-provisioner
- name: NFS_SERVER
value: xxx.xxx.xxx.xxx
- name: NFS_PATH
value: /mydata
volumes:
- name: nfs-client-root
nfs:
server: xxx.xxx.xxx.xxx
path: /mydata
2.4 創建storageclass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: nfs-provisioner
parameters:
archiveOnDelete: "true"
2.5 測試使用
在StatefulSet中,通過配置volumeClaimTemplates來配置使用動態卷
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: tomcat
namespace: test
labels:
app: statefulset
spec:
serviceName: tomcat-svc-headless
replicas: 4
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 3
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: hub.c.163.com/library/tomcat:8.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: tomcat
volumeMounts:
- name: webpath
mountPath: /usr/local/tomcat/webapps/test
volumeClaimTemplates:
- metadata:
name: webpath
annotations:
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" #這裏managed-nfs-storage就是我們創建的storageclass的name
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc-headless
namespace: test
labels:
app: statefulset
spec:
ports:
- port: 8080
name: tomcat
clusterIP: None
selector:
app: statefulset