準(zhǔn)備
首先確保nfs服務(wù)端搭建成功。由于資源限制,我們的nfs服務(wù)器和k8s集群不在同一局域網(wǎng)內(nèi),所以k8s中pv使用公網(wǎng)ip連接nfs,且nfs服務(wù)器的帶寬為10M。
- 創(chuàng)建nfs pv
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /mysql-data
server: 39.105.232.177
- 創(chuàng)建pvc
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mysql-pvc
namespace: laravel
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
- 查看pv和pvc的狀態(tài)
pv屬于bound狀態(tài)
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
mysql-nfs 10Gi RWO Recycle Bound laravel/mysql-pvc 16d
pvc也屬于bound狀態(tài)
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pvc Bound mysql-nfs 10Gi RWO 16d
如果沒有使用storageclass,pv和pvc通過相同的
storage
存儲大小和accessModes
訪問策略倆個元素來實現(xiàn)自動綁定。可以看到圖中pv和pvc已經(jīng)自動綁定。
- 創(chuàng)建mysql的deployment
使用的 harbor.maigengduo.com/laravel/mysql5.7鏡像是基于docker官方的mysql:5.7鏡像build的,mysql的data目錄為/var/lib/mysql。
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: mysql
namespace: laravel
labels:
name: mysql
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 1
selector:
matchLabels:
name: mysql
template:
metadata:
labels:
name: mysql
spec:
containers:
- name: mysql
image: harbor.maigengduo.com/laravel/mysql5.7:202007071543
ports:
- name: mysql-port
containerPort: 3306
protocol: TCP
imagePullPolicy: Always
env:
- name: MYSQL_ROOT_PASSWORD
value: root
volumeMounts:
- name: mysql-pvc
mountPath: "/var/lib/mysql"
restartPolicy: Always
volumes:
- name: mysql-pvc
persistentVolumeClaim:
claimName: mysql-pvc
部署完之后我開始認(rèn)為,容器內(nèi)的/var/lib/mysql目錄下的數(shù)據(jù)會‘直接同步’
到nfs服務(wù)端的/mysql-data目錄下,注意:這里是我認(rèn)為的,后面會驗證我還是年輕啊,哈哈。
但是發(fā)現(xiàn),容器內(nèi)的數(shù)據(jù)文件并沒有同步到nfs服務(wù)端,nfs服務(wù)端的共享目錄只看到倆個文件,分別為ibdata1和ib_logfile0,而且導(dǎo)致mysql服務(wù)不可用,最嚴(yán)重的時候直接導(dǎo)致了整個k8s的pod都處于pendding狀態(tài)了。
為了確定問題,我將容器內(nèi)別的目錄(目錄大小比較小)重新掛載到nfs上,發(fā)現(xiàn)是可以正常同步的,證明是/var/lib/mysql目錄特殊,特殊點有倆個,第一個該目錄的用戶和所屬組都是mysql,第二點是該目錄比較大。
root@mysql-85bc98b4d9-gg4q2:/var/lib# ls -l
total 32
drwxr-xr-x 1 root root 4096 Aug 14 2019 apt
drwxr-xr-x 1 root root 4096 Aug 14 2019 dpkg
drwxr-xr-x 2 root root 4096 Mar 28 2019 misc
drwxr-xr-x 6 mysql mysql 4096 Jul 24 01:10 mysql
drwxrwx--- 2 mysql mysql 4096 Aug 14 2019 mysql-files
drwxr-x--- 2 mysql mysql 4096 Aug 14 2019 mysql-keyring
drwxr-xr-x 2 root root 4096 Aug 12 2019 pam
drwxr-xr-x 1 root root 4096 Aug 12 2019 systemd
root@mysql-85bc98b4d9-gg4q2:/var/lib/mysql# du -sh
422M .
.
于是這里提出有幾個問題
- nfs服務(wù)端為什么只同步過倆個文件?
- 為什么mysql服務(wù)會不可用?為什么嚴(yán)重時整個k8s中的pod都處于pendding狀態(tài)了呢?
帶著上面的倆個問題,多次實驗首先發(fā)現(xiàn)了下面這個問題
nfs服務(wù)端共享文件夾權(quán)限問題
現(xiàn)象:nfs服務(wù)端的共享目錄/mysql-data原本的用戶和所屬組都是root,如下
[root@iZ2zebwwgp62jma838rfc4Z /]# ls -l
drwxr-xr-x 6 root root 4096 Jul 24 09:10 mysql-data
但是當(dāng)部署deployment后,也就是客戶端掛載后,服務(wù)端的共享目錄/mysql-data的用戶變?yōu)榱藀olkitd,用戶組變成了input,如下
[root@iZ2zebwwgp62jma838rfc4Z /]# ls -l
drwxr-xr-x 6 polkitd input 4096 Jul 24 09:10 mysql-data
為什么呢?感覺有點不正常。
- 首先查看容器內(nèi)的/var/lib/mysql目錄的權(quán)限,看到該目錄所屬用戶和用戶組都為mysql
root@mysql-85bc98b4d9-gg4q2:/var/lib# ls -l
total 32
drwxr-xr-x 1 root root 4096 Aug 14 2019 apt
drwxr-xr-x 1 root root 4096 Aug 14 2019 dpkg
drwxr-xr-x 2 root root 4096 Mar 28 2019 misc
drwxr-xr-x 6 mysql mysql 4096 Jul 24 01:10 mysql
然后查看用戶為mysql的相關(guān)信息,發(fā)現(xiàn)用戶myql所屬id為999,所屬組id也為999
root@mysql-85bc98b4d9-gg4q2:/var/lib# cat /etc/passwd | grep mysql
mysql:x:999:999::/home/mysql:
- 查看宿主機上用戶id為999的信息,發(fā)現(xiàn)用戶id為999的用戶為polkitd。
[root@iZ2zebwwgp62jma838rfc4Z /]# cat /etc/passwd | grep 999
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
繼續(xù)查看用戶組id為999的組名,發(fā)現(xiàn)用戶組id為999的組名為input。
[root@iZ2zebwwgp62jma838rfc4Z /]# cat /etc/group | grep 999
input:x:999:
到這里你肯定明白了宿主機上共享目錄的權(quán)限怎么變成用戶為polkitd,用戶組變成了input。
- 總結(jié)
宿主機使用volume映射到容器內(nèi)時,宿主機和容器內(nèi)的文件或文件夾的權(quán)限是相同的,準(zhǔn)備的說是用戶id和用戶組id是相同的。
解決
似乎上面那個現(xiàn)象對我們上面提的倆問題并沒有什么幫助,但是上面那個現(xiàn)象是真實存在的,我們必須搞清楚。接下來進入正題。。。
- nfs服務(wù)端為什么只同步過倆個文件?
剛開始時這個問題真的很棘手,后來靜下來想想,這個目錄大小將近500M,是不是目錄太大的問題,同步需要時間呢?所以并不是只同步過來倆個文件,而是正在同步中
,接下來驗證這個猜想。
首先在宿主機的共享目錄下查看文件夾大小,發(fā)現(xiàn)為100M
[root@iZ2zebwwgp62jma838rfc4Z mysql-data]# du -sh
100M .
在過2秒查看一遍,發(fā)現(xiàn)大小變?yōu)?01M
[root@iZ2zebwwgp62jma838rfc4Z mysql-data]# du -sh
101M .
此時真的驗證了我們的猜想,nfs服務(wù)端的數(shù)據(jù)是正在同步中
,只是nfs的寫速度真的很慢,讓我們以為就同步過來倆個文件,被表象所迷惑。
同步速度慢主要有幾個原因,首先io同步就是耗時的,其次nfs服務(wù)器和k8s不在一個局域網(wǎng)內(nèi),然后nfs服務(wù)器的帶寬也很低,最主要的還是nfs服務(wù)寫速度真的很慢。
- 為什么mysql服務(wù)會不可用?為什么嚴(yán)重時整個k8s中的pod都處于pendding狀態(tài)了呢?
寫io是很耗cpu的
,更何況這種大量復(fù)制。既然服務(wù)不可用了,我們使用top命令查看下k8s worker節(jié)點機器的各項性能,如下圖。發(fā)現(xiàn)nfs在同步過程有一個nginx的command的進程cpu竟然達到了99%,us的cpu達到了23.5%,sy的cpu達到了48.6%,很顯然,io同步時消耗了大量的cpu,導(dǎo)致mysql服務(wù)不可用了,而k8s的pod都會占用宿主機的cpu的資源的,如果宿主機的cpu資源不夠pod所申明的cpu,pod將會重新構(gòu)建,進而進入pod的生命周期中的pendding狀態(tài),所有pod都在爭搶宿主機cpu的資源。
總結(jié):寫io是很耗cpu資源,為了k8s集群服務(wù)的可用性,我們需要將k8s的node節(jié)點的cpu調(diào)大點。
如果你了解k8s resource,你就會知道,
只有當(dāng)節(jié)點擁有足夠滿足 Pod 內(nèi)存請求的內(nèi)存和cpu請求的cpu時,才會將 Pod 調(diào)度至節(jié)點上運行
,顯然上面這種情況消耗了大量的cpu,導(dǎo)致pod都調(diào)度不到節(jié)點上,以至于處于pendding狀態(tài)。可以看到我們上面的mysql deployment中并沒有設(shè)置resource相關(guān)cpu和memory配置,pod默認(rèn)limit為節(jié)點的所有cpu個memory。當(dāng)nfs數(shù)據(jù)復(fù)制時,將大量消耗pod內(nèi)的cpu,以至于node節(jié)點的cpu被消耗完,這是出現(xiàn)這個問題的根本原因,體現(xiàn)了pod設(shè)置resource資源的重要性,不然某個pod類似我們的這種情況將會消耗光節(jié)點的所有資源。
上面?zhèn)z個問題解決后,等到mysql的數(shù)據(jù)文件全部同步到nfs上時,理應(yīng)mysql服務(wù)和其他服務(wù)都能正常訪問了,但是并沒有預(yù)期的那么好,又出現(xiàn)了下面這個問題。。
mysql connection is not allowed
在集群外連接mysql時報以下錯誤。
rHost '172-17-208-115.calico-typha.kube-system.svc.cluster.local' is
not allowed to connect to this MySQL serverConnection closed by foreign host.
- 解決
這個原因是因為索要鏈接的mysql數(shù)據(jù)庫只允許其所在的服務(wù)器連接,需要在mysql服務(wù)器上設(shè)置一下允許的ip權(quán)限
grant all privileges on *.* to 'root'@'%' identified by 'root';
flush privileges;