更多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內容,請關注威信公眾好:新猿技術生態圈