更多k8s內容,請關注威信公眾好:新猿技術生態圈
一、數據持久化
Pod是由容器組成的,而容器宕機或停止之后,數據就隨之丟了,那么這也就意味着我們在做Kubernetes集群的時候就不得不考慮存儲的問題,而存儲卷就是為了Pod保存數據而生的。存儲卷的類型有很多,
# 一般有四種:emptyDir,hostPath,NFS以及雲存儲(ceph, glasterfs...)等。
1、emptyDir(不能用來做數據持久化)
# emptyDir:是pod調度到節點上時創建的一個空目錄,當pod被刪除時,emptydir中數據也隨之刪除,emptydir常用於容器間分享文件,或者用於創建臨時目錄。
#實例
# 1、編寫配置清單
[root@k8s-m-01 k8s]# vim emptydir.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: emptydir
spec:
selector:
matchLabels:
app: emptydir
template:
metadata:
labels:
app: emptydir
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: /data/ #nginx掛載目錄
name: emptydir-name
- name: php
image: registry.cn-shanghai.aliyuncs.com/aliyun_mm/discuz:php-v1
volumeMounts:
- mountPath: /opt/ # php掛載目錄
name: emptydir-name
volumes:
- name: emptydir-name
emptyDir: {}
# 2、查看pod
[root@k8s-m-01 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
emptydir-6ffc884879-rqlnw 2/2 Running 0 3m52s
# 驗證容器間的數據分享
# 3、進入nginx容器掛載的目錄,創建文件
[root@k8s-m-01 k8s]# kubectl exec -it emptydir-6ffc884879-rqlnw -c nginx -- bash
root@emptydir-6ffc884879-rqlnw:/# df
/dev/mapper/centos-root 103754244 5333064 98421180 6% /data
root@emptydir-6ffc884879-rqlnw:/# cd /data/
root@emptydir-6ffc884879-rqlnw:/data# ls
root@emptydir-6ffc884879-rqlnw:/data# echo 111 > 1.tt
root@emptydir-6ffc884879-rqlnw:/data# ls
1.tt
# 4、進入php掛載的目錄查看是否也有創建的文件
[root@k8s-m-01 k8s]# kubectl exec -it emptydir-6ffc884879-rqlnw -c php -- bash
[root@emptydir-6ffc884879-rqlnw html]# df
/dev/mapper/centos-root 103754244 5333092 98421152 6% /opt
[root@emptydir-6ffc884879-rqlnw html]# cd /opt/
[root@emptydir-6ffc884879-rqlnw opt]# ls
1.tt
[root@emptydir-6ffc884879-rqlnw opt]# cat 1.tt
111
2、hostpath
hostPath類型則是映射node文件系統中的文件或者目錄到pod里。在使用hostPath類型的存儲卷時,也可以設置type字段,支持的類型有文件、目錄、File、Socket、CharDevice和BlockDevice。
# hostPath類似於docker -v參數,將宿主主機中的文件掛載pod中,但是hostPath比docker -v參數更強大,(Pod調度到哪個節點,則直接掛載到當前節點上)
#實例
# 1、編寫配置清單
[root@k8s-m-01 k8s]# vim hostpath.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: hostpath
spec:
selector:
matchLabels:
app: hostpath
template:
metadata:
labels:
app: hostpath
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: /opt/ # 本地必須存在的目錄
name: hostpath-name
volumes:
- name: hostpath-name
hostPath:
path: /opt/hostpath # 隨機在node節點創建
type: DirectoryOrCreate # 類型:沒有就創建,有就不創建
# 2、查看pod
[root@k8s-m-01 k8s]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath-54859ffd84-cqssj 1/1 Running 0 3m40s 10.244.1.25 k8s-n-01 <none> <none>
# 3、進入容器創建(在node節點/opt/目錄創建一樣)
root@k8s-m-01 opt]# kubectl exec -it hostpath-54859ffd84-cqssj -- bash
root@hostpath-54859ffd84-cqssj:/# df
/dev/mapper/centos-root 103754244 5333132 98421112 6% /opt
root@hostpath-54859ffd84-cqssj:/opt# ls
root@hostpath-54859ffd84-cqssj:/opt# echo 111 > 1.tt
root@hostpath-54859ffd84-cqssj:/opt# ls
1.tt
# 4、node節點查看
[root@k8s-n-01 ~]# cd /opt/
[root@k8s-n-01 opt]# ll
drwxr-xr-x 2 root root 18 Aug 9 15:24 hostpath # 默認權限755
[root@k8s-n-01 opt]# cd hostpath/
[root@k8s-n-01 hostpath]# ll
total 4
-rw-r--r-- 1 root root 4 Aug 9 15:24 1.tt
[root@k8s-n-01 hostpath]# cat 1.tt
111
1、hostpath 的type的種類

3、NFS
nfs使得我們可以掛載已經存在的共享搭到我們的pod中
和emptydir不同的是,當pod被刪除時,emptydir也會被刪除。
nfs不會被刪除,僅僅是解除掛在狀態而已,這就意味着NFS能夠允許我們提前對數據進行處理,而且這些數據可以在pod之間互相傳遞,並且nfs可以同時被多個pod掛載並進行讀寫。
# 1、部署NFS(所有節點)
[root@k8s-m-01 k8s]# yum install nfs-utils.x86_64 -y
# 2、配置
[root@k8s-m-01nfs]# mkdir -p /nfs/v{1..10}
[root@k8s-m-01nfs]# cat > /etc/exports <<EOF
/nfs/v1 192.168.15.0/16(rw,sync,all_squash)
/nfs/v2 192.168.15.0/16(rw,sync,all_squash)
/nfs/v3 192.168.15.0/16(rw,sync,all_squash)
/nfs/v4 192.168.15.0/16(rw,sync,all_squash)
/nfs/v5 192.168.15.0/16(rw,sync,all_squash)
EOF
# 3、查看結果
[root@k8s-m-01 k8s]# exportfs -arv
exporting192.168.15.0/16:/nfs/v5
exporting192.168.15.0/16:/nfs/v4
exporting192.168.15.0/16:/nfs/v3
exporting192.168.15.0/16:/nfs/v2
exporting192.168.15.0/16:/nfs/v1
[root@k8s-m-01 k8s]# showmount -e
Export list for k8s-m-01:
/nfs/v5 192.168.15.0/24
/nfs/v4 192.168.15.0/24
/nfs/v3 192.168.15.0/24
/nfs/v2 192.168.15.0/24
/nfs/v1 192.168.15.0/24
# 4、啟動nfs(所有節點)
[root@k8s-m-01 k8s]# systemctl enable --now nfs
# 5、測試k8s使用nfs
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs
spec:
selector:
matchLabels:
app: nfs
template:
metadata:
labels:
app: nfs
spec:
nodeName: gdx3
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
volumeMounts:
- mountPath: /var/lib/mysql
name: nfs
volumes:
- name: nfs
nfs:
path: /nfs/v1
server: 192.168.15.111
# 6、驗證nfs掛載
#進入到nfs數據庫
[root@k8s-m-01 k8s]# kubectl get pods
NAME READY STATUS RESTARTS AGE
emptydir-5dc7dcd9fd-zrb99 2/2 Running 0 9h
nfs-85dff7bb6b-8pgrp 1/1 Running 0 60m
statefulset-test-0 1/1 Running 0 27h
test-6799fc88d8-t6jn6 1/1 Running 0 142m
test-tag 1/1 Running 0 3d15h
wordpress-test-0 2/2 Running 0 26h
[root@k8s-master1 v1]# kubectl exec -it nfs-85dff7bb6b-8pgrp -- bash
root@nfs-85dff7bb6b-8pgrp:/# mysql -u root -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.33 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database discuz; #創建一個數據庫
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| discuz |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
#到宿主機的掛載目錄下查看
[root@k8s-m-01 k8s]# cd /nfs/v1
[root@k8s-master1 v1]# ll
總用量 188484
-rw-r----- 1 polkitd ssh_keys 56 4月 4 19:06 auto.cnf
-rw------- 1 polkitd ssh_keys 1680 4月 4 19:06 ca-key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 4月 4 19:06 ca.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 4月 4 19:06 client-cert.pem
-rw------- 1 polkitd ssh_keys 1680 4月 4 19:06 client-key.pem
drwxr-x--- 2 polkitd ssh_keys 20 4月 4 21:07 discuz #數據庫目錄已經存在
-rw-r----- 1 polkitd ssh_keys 692 4月 4 20:04 ib_buffer_pool
-rw-r----- 1 polkitd ssh_keys 79691776 4月 4 20:04 ibdata1
-rw-r----- 1 polkitd ssh_keys 50331648 4月 4 20:04 ib_logfile0
-rw-r----- 1 polkitd ssh_keys 50331648 4月 4 19:06 ib_logfile1
-rw-r----- 1 polkitd ssh_keys 12582912 4月 4 20:05 ibtmp1
drwxr-x--- 2 polkitd ssh_keys 4096 4月 4 19:06 mysql
drwxr-x--- 2 polkitd ssh_keys 8192 4月 4 19:06 performance_schema
-rw------- 1 polkitd ssh_keys 1680 4月 4 19:06 private_key.pem
-rw-r--r-- 1 polkitd ssh_keys 452 4月 4 19:06 public_key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 4月 4 19:06 server-cert.pem
-rw------- 1 polkitd ssh_keys 1680 4月 4 19:06 server-key.pem
drwxr-x--- 2 polkitd ssh_keys 8192 4月 4 19:06 sys
# 7、測試刪除pod
[root@k8s-master1 discuz]# kubectl delete pods nfs-85dff7bb6b-8pgrp
pod "nfs-85dff7bb6b-8pgrp" deleted
#在回宿主機掛載目錄查看discuz數據庫目錄仍然是存在的
4.PV/PVC
# 1、PersistentVolume(PV)是集群中已由管理員配置的一段網絡存儲。
集群中的資源就像一個節點是一個集群資源。 PV是諸如卷之類的卷插件,但是具有獨立於使用PV的任何單個pod的生命周期。 該API對象捕獲存儲的實現細節,即NFS,iSCSI或雲提供商特定的存儲系統 。
# 2、PersistentVolumeClaim(PVC)是用戶存儲的請求。
PVC的使用邏輯:在pod中定義一個存儲卷(該存儲卷類型為PVC),定義的時候直接指定大小,pvc必須與對應的pv建立關系,pvc會根據定義去pv申請,而pv是由存儲空間創建出來的。pv和pvc是kubernetes抽象出來的一種存儲資源。
1)PV 的訪問模式(accessModes)
| 模式 | 解釋 |
|---|---|
| ReadWriteOnce(RWO) | 可讀可寫,但只支持被單個節點掛載。 |
| ReadOnlyMany(ROX) | 只讀,可以被多個節點掛載。 |
| ReadWriteMany(RWX) | 多路可讀可寫。這種存儲可以以讀寫的方式被多個節點共享。不是每一種存儲都支持這三種方式,像共享方式,目前支持的還比較少,比較常用的是 NFS。在 PVC 綁定 PV 時通常根據兩個條件來綁定,一個是存儲的大小,另一個就是訪問模式。 |
2)PV的回收策略(persistentVolumeReclaimPolicy)
| 策略 | 解釋 |
|---|---|
| Retain | 不清理, 保留 Volume(需要手動清理) |
| Recycle | 刪除數據,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持) |
| Delete | 刪除存儲資源,比如刪除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持) |
3)PV的狀態
| 狀態 | 解釋 |
|---|---|
| Available | 可用 |
| Bound | 已經分配給 PVC。 |
| Released | PVC 解綁但還未執行回收策略。 |
| Failed | 發生錯誤 |
# 1、創建pv (PV集群級資源)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
nfs:
path: /nfs/v2
server: 172.16.1.11
capacity:
storage: 20Gi
persistentVolumeReclaimPolicy: Retain #指定pv的回收策略:不清理保留volume
accessModes: #指定pv的訪問模式
- "ReadWriteOnce" #可讀可寫,但只支持單個節點掛載
- "ReadWriteMany" #多路可讀可寫
# 2、查看pv
[root@k8s-m-01 k8s]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 20Gi RWO,RWX Retain Available 53s
4)PVC指定使用的PV (PVC名稱空間級資源)
# 1、創建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
accessModes:
- "ReadWriteMany" #此內容要在pv的訪問模式中包含
resources:
requests:
storage: "6Gi" #此值要包含在pv的大小內
# 2、再查看pv
[root@k8s-m-01 k8s]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 20Gi RWO,RWX Retain Bound default/pvc1 29m
#注:此時pv已是綁定pv1的狀態
# 3、查看pvc
[root@k8s-m-01 k8s]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound pv1 20Gi RWO,RWX 2m42s
二、部署discuz(使用pv/pvc管理nfs)
# 1、所有機器安裝nfs
# 2、編寫nfs配置文件並啟動
# 3、上傳代碼包
# 4、編寫mysql的yaml文件
# 5、編寫discuz的yaml文件
# 6、生成yaml文件並查看詳情
# 7、Ip訪問
# 8、故障排查
1、所有機器安裝nfs
[root@k8s-m-01 k8s]# yum -y install nfs-utils
2、編寫nfs配置文件並啟動
# 1、創建目錄
[root@k8s-m-01 k8s]# mkdir -p /nfs/v{1..10}
# 2、編寫nfs文件
[root@k8s-m-01 k8s]# vim /etc/exports
/nfs/v1 192.168.15.0/24(rw,sync,all_squash)
/nfs/v2 192.168.15.0/24(rw,sync,all_squash)
/nfs/v3 192.168.15.0/24(rw,sync,all_squash)
/nfs/v4 192.168.15.0/24(rw,sync,all_squash)
/nfs/v5 192.168.15.0/24(rw,sync,all_squash)
# 3、啟動nfs
[root@k8s-m-01 k8s]# systemctl enable --now nfs
3、上傳代碼包
# 1、上傳代碼包
[root@k8s-m-01 k8s]# wget http://www.mmin.xyz:81/package/blog/Discuz_X3.4_SC_UTF8_20210320.zip
# 2、解壓
[root@k8s-m-01 k8s]# unzip Discuz_X3.4_SC_UTF8_20210320.zip
# 3、改名
[root@k8s-m-01 k8s]# mv upload/ discuz
# 4、移動到掛載目錄
[root@k8s-m-01 k8s]# mv discuz/* /nfs/v2
[root@k8s-m-01 k8s]# rm -rf discuz
# 5、授權
[root@k8s-m-01 v2]# chmod 777 -R ./
# 6、查看文件
[root@k8s-m-01 v2]# ll
total 68
-rwxrwxrwx 1 root root 2834 Mar 22 19:44 admin.php
drwxrwxrwx 9 root root 135 Mar 22 19:44 api
-rwxrwxrwx 1 root root 727 Mar 22 19:44 api.php
drwxrwxrwx 2 root root 23 Mar 22 19:44 archiver
drwxrwxrwx 2 root root 141 Aug 9 21:28 config
-rwxrwxrwx 1 root root 1040 Mar 22 19:44 connect.php
-rwxrwxrwx 1 root root 106 Mar 22 19:44 crossdomain.xml
drwxrwxrwx 15 root root 285 Aug 9 21:28 data
-rwxrwxrwx 1 root root 5558 Mar 20 10:36 favicon.ico
-rwxrwxrwx 1 root root 2245 Mar 22 19:44 forum.php
-rwxrwxrwx 1 root root 821 Mar 22 19:44 group.php
-rwxrwxrwx 1 root root 1280 Mar 22 19:44 home.php
-rwxrwxrwx 1 root root 6472 Mar 22 19:44 index.php
drwxrwxrwx 5 root root 64 Mar 22 19:44 install
drwxrwxrwx 2 root root 23 Mar 22 19:44 m
-rwxrwxrwx 1 root root 1025 Mar 22 19:44 member.php
-rwxrwxrwx 1 root root 2371 Mar 22 19:44 misc.php
-rwxrwxrwx 1 root root 1788 Mar 22 19:44 plugin.php
-rwxrwxrwx 1 root root 977 Mar 22 19:44 portal.php
-rwxrwxrwx 1 root root 582 Mar 22 19:44 robots.txt
-rwxrwxrwx 1 root root 1155 Mar 22 19:44 search.php
drwxrwxrwx 10 root root 168 Mar 22 19:44 source
drwxrwxrwx 7 root root 86 Mar 22 19:44 static
drwxrwxrwx 3 root root 38 Mar 22 19:44 template
drwxrwxrwx 7 root root 106 Mar 22 19:44 uc_client
drwxrwxrwx 13 root root 241 Mar 22 19:44 uc_server
4、編寫mysql的yaml文件
[root@k8s-m-01 ~]# vim mysql.yaml
kind: Namespace
apiVersion: v1
metadata:
name: mysql
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysql
namespace: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "123"
- name: MYSQL_DATABASE
value: discuz
livenessProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "cat /etc/mysql/my.cnf"
initialDelaySeconds: 0
periodSeconds: 3
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 30
periodSeconds: 1
timeoutSeconds: 1
successThreshold: 3
failureThreshold: 1
---
kind: Service
apiVersion: v1
metadata:
name: mysql
namespace: mysql
spec:
ports:
- port: 3306
targetPort: 3306
protocol: TCP
name: mysql
selector:
app: mysql
5、編寫discuz的yaml文件
[root@k8s-m-01 ~]# vim discuz.yaml
kind: Namespace
apiVersion: v1
metadata:
name: web
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: discuz
labels:
app: discuz
spec:
nfs:
path: /nfs/v2/
server: 192.168.15.111
accessModes:
- "ReadWriteMany"
capacity:
storage: '10Gi'
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: discuz
namespace: web
spec:
accessModes:
- "ReadWriteMany"
resources:
requests:
storage: '5Gi'
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: discuz
namespace: web
spec:
replicas: 1
selector:
matchLabels:
app: discuz
template:
metadata:
labels:
app: discuz
spec:
containers:
- name: php
image: registry.cn-hangzhou.aliyuncs.com/k8sos/web:discuz-php-v1
imagePullPolicy: Always
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: discuz
livenessProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "cat /etc/php-fpm.d/www.conf"
initialDelaySeconds: 0
periodSeconds: 3
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
readinessProbe:
tcpSocket:
port: 9000
initialDelaySeconds: 10
periodSeconds: 1
timeoutSeconds: 1
successThreshold: 3
failureThreshold: 1
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/k8sos/web:discuz-v1
imagePullPolicy: Always
volumeMounts:
- mountPath: /usr/share/nginx/html/
name: discuz
livenessProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "cat /etc/nginx/nginx.conf"
initialDelaySeconds: 0
periodSeconds: 3
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 1
timeoutSeconds: 1
successThreshold: 3
failureThreshold: 1
volumes:
- name: discuz
persistentVolumeClaim:
claimName: discuz
---
kind: Service
apiVersion: v1
metadata:
name: discuz
namespace: web
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: discuz
type: NodePort
6、生成yaml文件並查看詳情
# 1、生成yaml文件
[root@k8s-m-01 ~]# kubectl apply -f mysql.yaml
[root@k8s-m-01 ~]# kubectl apply -f discuz.yaml
# 2、查看詳請
[root@k8s-m-01 ~]# kubectl get pod -n web
NAME READY STATUS RESTARTS AGE
discuz-fb75c6498-mvjgv 2/2 Running 0 53s
[root@k8s-m-01 ~]# kubectl get pod -n mysql
NAME READY STATUS RESTARTS AGE
mysql-6f9b947c9f-hmdvh 1/1 Running 0 64s
7、Ip訪問
# 1、查看svc
[root@k8s-m-01 ~]# kubectl get svc -n web discuz
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
discuz NodePort 10.106.220.40 <none> 80:31706/TCP 69s
# 2、IP訪問
192.168.15.111:31706


8、故障排查

# 1、解決BUG
# 2、只是因為服務端沒有安裝nfs
[root@k8s-m-01 k8s]# yum -y install nfs-utils

# 1、無法訪問頁面
# 2、解決
[root@k8s-m-01 ~]# vim discuz.yaml |grep v2
path: /nfs/v2/ # 在掛載目錄中寫絕對路徑 /nfs/v2/
# 還有一種可能是代碼包的問題

# 1、無法連接到數據款
# 2、解決
還有一種可能是代碼包的問題,重新上傳一個包即可
更多k8s內容,請關注威信公眾好:新猿技術生態圈
更多k8s內容,請關注威信公眾好:新猿技術生態圈
更多k8s內容,請關注威信公眾好:新猿技術生態圈
