相关背景
在调试mysql-operator和mysql,在部署mysql的过程中,一直出现,mysqld: File ‘/var/lib/mysql-bin.index’ permission deined或者报错Can’t find error-message file ‘/usr/local/mysql/errmsg.sys’
cluster.yaml
apiVersion: mysql.presslabs.org/v1alpha1
kind: MysqlCluster
metadata:
name: my-cluster
spec:
replicas: 2
secretName: my-secret
volumeSpec:
hostPath:
path: /data/mysql
type: DirectoryOrCreate
mysqlConf:
innodb-buffer-pool-size: 1Gi
通过kubectl describe pod podname查看到pod是卡在了mysql-init-log或mysql容器启动过程中。
通过kubectl logs podname -c containername查看到容器的报错都为无法读写容器内/var/lib/mysql目录,而导致容器执行异常退出,而且镜像都在percona镜像。
服务器/data/mysql挂载了容器中的/var/lib/mysql。
思路
- 判断是服务器上的/data/mysql权限配置不对,导致容器挂载后无权限。容器的默认用户为mysql,uid为999,gid为999。通过将/data/mysql权限设置为777,以及将目录用户和组设置为999:999,问题依旧存在。分析有误。
- 通过手动模拟容器挂载,复现该问题,判断是否为容器启动时候的权限问题。
docker run -v /data/mysql:/var/lib/mysql -it percona bash,进入容器后,/var/lib/mysql目录用户就为999,可以访问并读写文件,无问题。分析有误。 - 通过改变挂载目录/data/mysql变为/data,很奇怪,可以通过init-container,但是无法执行mysql的逻辑。问题依旧存在。
- 可能是k8s启动有问题,通过模拟mysql容器化启动逻辑,启动后进入pod,判断问题能否复现。
执行kubectl apply -f pod.yaml,让容器一直在sleep中,并进入容器kubectl exec -it podname – bash,发现/var/lib/mysql的目录用户和组都为root,则确认问题。k8s启动pod和docker启动容器的逻辑不同,k8s会默认使用root来创建设置挂载目录,而docker是使用宿主机上的目录的用户和组。
相关代码:
apiVersion: v1
kind: Pod
metadata:
name: mytest
spec:
containers:
- name: percona
image: percona
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql
imagePullPolicy: IfNotPresent
command:
- /usr/bin/bash
- -c
- sleep 200000000
volumes:
- name: mysql
hostPath:
path: /data/mysql
- 修复
使用init-container挂载相同目录来修改目录权限解决。相关代码:
apiVersion: mysql.presslabs.org/v1alpha1
kind: MysqlCluster
metadata:
name: my-cluster
spec:
replicas: 2
secretName: my-secret
volumeSpec:
hostPath:
path: /data/mysql
type: DirectoryOrCreate
mysqlConf:
innodb-buffer-pool-size: 1Gi
podSpec:
initContainers:
- name: volume-permissions
image: busybox
securityContext:
runAsUser: 0
command:
- sh
- -c
- chmod 750 /datea/mysqlk; chown 999:999 /data/mysql
volumeMounts:
- name: data
mountPath: /data/mysql