k8s使用nfs持久存储mysql数据的一次踩坑

准备

首先确保nfs服务端搭建成功。由于资源限制,我们的nfs服务器和k8s集群不在同一局域网内,所以k8s中pv使用公网ip连接nfs,且nfs服务器的带宽为10M。

  • 创建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
  • 创建pvc
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-pvc
  namespace: laravel
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  • 查看pv和pvc的状态

pv属于bound状态

NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
mysql-nfs   10Gi       RWO            Recycle          Bound    laravel/mysql-pvc                           16d

pvc也属于bound状态

NAME        STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-pvc   Bound    mysql-nfs   10Gi       RWO                           16d

如果没有使用storageclass,pv和pvc通过相同的storage存储大小和accessModes访问策略俩个元素来实现自动绑定。可以看到图中pv和pvc已经自动绑定。

  • 创建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

部署完之后我开始认为,容器内的/var/lib/mysql目录下的数据会‘直接同步’到nfs服务端的/mysql-data目录下,注意:这里是我认为的,后面会验证我还是年轻啊,哈哈

但是发现,容器内的数据文件并没有同步到nfs服务端,nfs服务端的共享目录只看到俩个文件,分别为ibdata1和ib_logfile0,而且导致mysql服务不可用,最严重的时候直接导致了整个k8s的pod都处于pendding状态了。

为了确定问题,我将容器内别的目录(目录大小比较小)重新挂载到nfs上,发现是可以正常同步的,证明是/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    .
.

于是这里提出有几个问题

  1. nfs服务端为什么只同步过俩个文件?
  2. 为什么mysql服务会不可用?为什么严重时整个k8s中的pod都处于pendding状态了呢?

带着上面的俩个问题,多次实验首先发现了下面这个问题

nfs服务端共享文件夹权限问题

现象:nfs服务端的共享目录/mysql-data原本的用户和所属组都是root,如下

[root@iZ2zebwwgp62jma838rfc4Z /]# ls -l
drwxr-xr-x   6 root root  4096 Jul 24 09:10 mysql-data

但是当部署deployment后,也就是客户端挂载后,服务端的共享目录/mysql-data的用户变为了polkitd,用户组变成了input,如下

[root@iZ2zebwwgp62jma838rfc4Z /]# ls -l
drwxr-xr-x   6 polkitd input  4096 Jul 24 09:10 mysql-data

为什么呢?感觉有点不正常。

  • 首先查看容器内的/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

然后查看用户为mysql的相关信息,发现用户myql所属id为999,所属组id也为999

root@mysql-85bc98b4d9-gg4q2:/var/lib# cat /etc/passwd | grep mysql
mysql:x:999:999::/home/mysql:
  • 查看宿主机上用户id为999的信息,发现用户id为999的用户为polkitd。
[root@iZ2zebwwgp62jma838rfc4Z /]# cat /etc/passwd | grep 999
polkitd:x:999:998:User for polkitd:/:/sbin/nologin

继续查看用户组id为999的组名,发现用户组id为999的组名为input。

[root@iZ2zebwwgp62jma838rfc4Z /]# cat /etc/group | grep 999
input:x:999:

到这里你肯定明白了宿主机上共享目录的权限怎么变成用户为polkitd,用户组变成了input。

  • 总结

宿主机使用volume映射到容器内时,宿主机和容器内的文件或文件夹的权限是相同的,准备的说是用户id和用户组id是相同的。

解决

似乎上面那个现象对我们上面提的俩问题并没有什么帮助,但是上面那个现象是真实存在的,我们必须搞清楚。接下来进入正题。。。

  • nfs服务端为什么只同步过俩个文件?

刚开始时这个问题真的很棘手,后来静下来想想,这个目录大小将近500M,是不是目录太大的问题,同步需要时间呢?所以并不是只同步过来俩个文件,而是正在同步中,接下来验证这个猜想。

首先在宿主机的共享目录下查看文件夹大小,发现为100M

[root@iZ2zebwwgp62jma838rfc4Z mysql-data]# du -sh
100M    .

在过2秒查看一遍,发现大小变为101M

[root@iZ2zebwwgp62jma838rfc4Z mysql-data]# du -sh
101M    .

此时真的验证了我们的猜想,nfs服务端的数据是正在同步中,只是nfs的写速度真的很慢,让我们以为就同步过来俩个文件,被表象所迷惑。
同步速度慢主要有几个原因,首先io同步就是耗时的,其次nfs服务器和k8s不在一个局域网内,然后nfs服务器的带宽也很低,最主要的还是nfs服务写速度真的很慢。

  • 为什么mysql服务会不可用?为什么严重时整个k8s中的pod都处于pendding状态了呢?

写io是很耗cpu的,更何况这种大量复制。既然服务不可用了,我们使用top命令查看下k8s worker节点机器的各项性能,如下图。发现nfs在同步过程有一个nginx的command的进程cpu竟然达到了99%,us的cpu达到了23.5%,sy的cpu达到了48.6%,很显然,io同步时消耗了大量的cpu,导致mysql服务不可用了,而k8s的pod都会占用宿主机的cpu的资源的,如果宿主机的cpu资源不够pod所申明的cpu,pod将会重新构建,进而进入pod的生命周期中的pendding状态,所有pod都在争抢宿主机cpu的资源。

image.png

总结:写io是很耗cpu资源,为了k8s集群服务的可用性,我们需要将k8s的node节点的cpu调大点。

如果你了解k8s resource,你就会知道,只有当节点拥有足够满足 Pod 内存请求的内存和cpu请求的cpu时,才会将 Pod 调度至节点上运行,显然上面这种情况消耗了大量的cpu,导致pod都调度不到节点上,以至于处于pendding状态。

可以看到我们上面的mysql deployment中并没有设置resource相关cpu和memory配置,pod默认limit为节点的所有cpu个memory。当nfs数据复制时,将大量消耗pod内的cpu,以至于node节点的cpu被消耗完,这是出现这个问题的根本原因,体现了pod设置resource资源的重要性,不然某个pod类似我们的这种情况将会消耗光节点的所有资源。

上面俩个问题解决后,等到mysql的数据文件全部同步到nfs上时,理应mysql服务和其他服务都能正常访问了,但是并没有预期的那么好,又出现了下面这个问题。。

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数据库只允许其所在的服务器连接,需要在mysql服务器上设置一下允许的ip权限

grant all privileges on *.* to 'root'@'%' identified by 'root';
flush privileges;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容