k8s部署canal-server使用configMap挂载方式报Read Only file System
1.1、问题复现
由于部署canal-server时,需要修改主库master的数据库连接信息以及配置zookeeper,所以为了后续操作方便,于是使用了configMap挂载配置文件的方式,如下图所示:
但是,在编写好deployment文件之后,部署时,发现在k8s容器中,不能部署成功,报错问题如下:
1.2、问题分析
看到上述报错,下意识的感觉应该是没有写操作权限,因为挂载的文件并没有覆盖掉镜像中指定路径下的文件,然后去dockerhub上找到镜像的文件,发现canal-server镜像创建了 admin:admin用户和用户组,如下图所示:
而当前k8s容器的用户和用户组为root:root,针对这种情况,网上也有类似的解决方案,说是要在配置的pod中添加相关的安全配置,指定用户和用户组进行操作,但是前提是需要知道对应的UID和GID,关于UID和GID,k8s中root用户默认的UID和GID都是0,当然,你也可以通过 cat /etc/passwd查看。关于cat /etc/passwd指令查询的用户信息解释,可以参看下面解释:
以root用户信息为例: root:x:0:0:root:/root:/bin/bash共7个字段,并以 : 进行了分割,下表为字段从左到右含义依次说明
字段 | 说明 |
用户名 | 用户登录系统使用的用户名 |
密码 | 密码位 |
UID | 用户标识号 |
GID | 用户组标识号 |
注释性描述 | 例如:存放用户全名等信息 |
宿主目录 | 用户登录系统后的缺省目录 |
命令解释器 | 用户使用的shell命令,默认为bash |
然后获取到对应的UID和GID之后,k8s官方文档中,针对用户不一致这种情况有对应的说明,通过设置pod容器对应的安全上下文操作,可以指定用户执行,如下所示:
官方文档链接如下:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/security-context/
然后看到这之后,于是便参照官方文档添加对应的配置
securityContext: runAsUser: 0 runAsGroup: 0 fsGroup: 0
修改完配置之后,满怀期待等待部署执行结果,后面发现这样操作,还是报上面的问题。于是感觉这种操作不对,然后就在github上去查看issues,找了好久,换各种搜索词,终于看到了这篇
然后,准备根据解决方法操作时,发现并没有对应的官方解决方案
虽然没有官方解决方案吧,但是看到了相关的解决思路,查看了app.sh文件的内容,发现与自己之前的猜想是一致的,原因找到了,解决方案又很令人头疼......
1.3、问题解决
关于configMap挂载文件这部分,如果是采用默认的k8s容器用户进行创建操作,挂载文件的用户和用户组都是root,如果修改挂载的路径可以以root用户挂载成功,这部分还是修改上面挂载路径时发现的。同时,在github上面看到了前辈留下的解决思路,又结合dockerfile中的文件执行命令,于是自己就准备通过覆盖app.sh文件内容,并修改掉当前/home/admin/app.sh文件中的授权操作,这部分结合当前使用configMap挂载文件操作。
说明:操作说明也同步写在了github 3262 issue下,也可以查看(https://github.com/alibaba/canal/issues/3262),如下图所示
1.3.1、添加configMap挂载配置
- mountPath: /home/admin/app.sh name: conf subPath: app.sh
1.3.2、添加app.sh文件内容
1、复制canal/docker/image/app.sh文件内容,修改如下图位置
2、全局搜索 su admin,将此替换为 su root,以容器默认的root用户权限操作
3、完整的app.sh文件内容如下:
1 #!/bin/bash 2 set -e 3 4 source /etc/profile 5 export JAVA_HOME=/usr/java/latest 6 export PATH=$JAVA_HOME/bin:$PATH 7 touch /tmp/start.log 8 host=`hostname -i` 9 10 # waitterm 11 # wait TERM/INT signal. 12 # see: http://veithen.github.io/2014/11/16/sigterm-propagation.html 13 waitterm() { 14 local PID 15 # any process to block 16 tail -f /dev/null & 17 PID="$!" 18 # setup trap, could do nothing, or just kill the blocker 19 trap "kill -TERM ${PID}" TERM INT 20 # wait for signal, ignore wait exit code 21 wait "${PID}" || true 22 # clear trap 23 trap - TERM INT 24 # wait blocker, ignore blocker exit code 25 wait "${PID}" 2>/dev/null || true 26 } 27 28 # waittermpid "${PIDFILE}". 29 # monitor process by pidfile && wait TERM/INT signal. 30 # if the process disappeared, return 1, means exit with ERROR. 31 # if TERM or INT signal received, return 0, means OK to exit. 32 waittermpid() { 33 local PIDFILE PID do_run error 34 PIDFILE="${1?}" 35 do_run=true 36 error=0 37 trap "do_run=false" TERM INT 38 while "${do_run}" ; do 39 PID="$(cat "${PIDFILE}")" 40 if ! ps -p "${PID}" >/dev/null 2>&1 ; then 41 do_run=false 42 error=1 43 else 44 sleep 1 45 fi 46 done 47 trap - TERM INT 48 return "${error}" 49 } 50 51 52 function checkStart() { 53 local name=$1 54 local cmd=$2 55 local timeout=$3 56 cost=5 57 while [ $timeout -gt 0 ]; do 58 ST=`eval $cmd` 59 if [ "$ST" == "0" ]; then 60 sleep 1 61 let timeout=timeout-1 62 let cost=cost+1 63 elif [ "$ST" == "" ]; then 64 sleep 1 65 let timeout=timeout-1 66 let cost=cost+1 67 else 68 break 69 fi 70 done 71 echo "start $name successful" 72 } 73 74 75 function start_canal() { 76 echo "start canal ..." 77 managerAddress=`perl -le 'print $ENV{"canal.admin.manager"}'` 78 if [ ! -z "$managerAddress" ] ; then 79 # canal_local.properties mode 80 adminPort=`perl -le 'print $ENV{"canal.admin.port"}'` 81 if [ -z "$adminPort" ] ; then 82 adminPort=11110 83 fi 84 85 su root -c 'cd /home/admin/canal-server/bin/ && sh restart.sh local 1>>/tmp/start.log 2>&1' 86 sleep 5 87 #check start 88 checkStart "canal" "nc 127.0.0.1 $adminPort -w 1 -z | wc -l" 30 89 else 90 metricsPort=`perl -le 'print $ENV{"canal.metrics.pull.port"}'` 91 if [ -z "$metricsPort" ] ; then 92 metricsPort=11112 93 fi 94 95 destination=`perl -le 'print $ENV{"canal.destinations"}'` 96 if [[ "$destination" =~ ',' ]]; then 97 echo "multi destination:$destination is not support" 98 exit 1; 99 else 100 if [ "$destination" != "" ] && [ "$destination" != "example" ] ; then 101 if [ -d /home/admin/canal-server/conf/example ]; then 102 mv /home/admin/canal-server/conf/example /home/admin/canal-server/conf/$destination 103 fi 104 fi 105 fi 106 107 su root -c 'cd /home/admin/canal-server/bin/ && sh restart.sh 1>>/tmp/start.log 2>&1' 108 sleep 5 109 #check start 110 checkStart "canal" "nc 127.0.0.1 $metricsPort -w 1 -z | wc -l" 30 111 fi 112 }app.sh文件内容 标签:canal,configMap,admin,System,server,sh,挂载,root From: https://www.cnblogs.com/cndarren/p/16746300.html