Docker基础:指定USER的容器中获得root用户的方法
发布日期:2021-06-30 20:13:31 浏览次数:2 分类:技术文章

本文共 3513 字,大约阅读时间需要 11 分钟。

在很多官方镜像中,为了安全,都会将用户进行限定,而不是缺省使用root。比如Jenkins的官方镜像,docker exec进去之后的用户就是jenkins,但是偶尔有需要在运行态以root权限修改当前容器设置的需求时,可使用-u选项来解决这个问题。

问题描述

以Jenkins的alpine的lts容器为例,进行说明。在官方Alpine的Jenkins镜像中安装NodeJS插件,然后创建一个Free Style 的Job,在此Job中执行node -v和npm -v执行版本的确认,发现无法正常动作,日志输出信息如下:

Started by user adminRunning as SYSTEMBuilding in workspace /var/jenkins_home/workspace/nodejs-freestyle-jobUnpacking https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.gz to /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/nodejs10.15.3 on Jenkins[nodejs-freestyle-job] $ /bin/sh -xe /tmp/jenkins5559044380616609516.sh+ npm -venv: ‘node’: No such file or directoryBuild step 'Execute shell' marked build as failureFinished: FAILURE

详细的问题现象和原因说明请参看:

*

问题对应方法

想定的对应方法:

从其他地方获取一个nodejs的二进制包,然后展开在/usr/local下

问题:

在/usr/local下当前用户没有创建目录的权限。操作日志如下所示

liumiaocn:~ liumiao$ docker ps |grep jenkins |grep alpine6535aece8684        jenkins/jenkins:lts-alpine   "/sbin/tini -- /usr/…"   5 hours ago         Up 5 hours          0.0.0.0:8080->8080/tcp, 0.0.0.0:60000->50000/tcp    mystifying_spenceliumiaocn:~ liumiao$ docker exec -it mystifying_spence sh/ $ iduid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)/ $ mkdir -p /usr/local/nodemkdir: cannot create directory ‘/usr/local/node’: Permission denied/ $ ls -ld /usr/localdrwxr-xr-x 1 root root 4096 Oct 18 07:21 /usr/local/ $

原因:

jenkins的官方镜像通过USER指令限定了缺省用户,可以防止root权限的滥用。但是这同样带来了问题,因为在容器之中,su和sudo均无法直接使用。

注:解决方式有多种,这里只是为了介绍这种类似情况下如何获得root权限并进行操作

对应方法

对应方法:

docker exec -it时通过-u参数指定root作为操作用户即可。操作示例日志如下所示

步骤1: 修改nodejs插件配置

按照如下方式设定nodejs的路径

在这里插入图片描述

步骤2: 以root身份进入到Jenkins镜像中

liumiaocn:~ liumiao$ docker exec -it -u root mystifying_spence sh/ # iduid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)/ #

可以看到只需要指定-u的参数,即可获得了root的权限进行操作。

步骤3: 创建目录并解压nodejs二进制包

将预先获取的Alpine版的nodejs二进制文件放置到上述设定的目录下

liumiaocn:~ liumiao$ docker cp nodejs.10.15.3.tar mystifying_spence:/tmpliumiaocn:~ liumiao$ docker exec -it -u root mystifying_spence sh/ # iduid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)/ # ls -l /tmp/nodejs.10.15.3.tar -rw-r--r-- 1 501 dialout 62127616 Oct 18 01:07 /tmp/nodejs.10.15.3.tar/ #

这里有另外一个有趣的情况,注意上述user的id是501,这个userid从哪里来的呢?宿主机器的当前用户我们来确认一下

liumiaocn:~ liumiao$ iduid=501(liumiao) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh)liumiaocn:~ liumiao$

因为容器中没有id为501的用户,所以才导致无法显示用户名称。

/ # grep 501 /etc/passwd/ # grep 1000 /etc/passwdjenkins:x:1000:1000:Linux User,,,:/var/jenkins_home:/bin/bash/ #

但是由于我们有root的用户权限,这些都不是问题。

/ # mkdir -p /usr/local/node/10.15.3/ # cd /usr/local/node/10.15.3//usr/local/node/10.15.3 # tar xf /tmp/nodejs.10.15.3.tar /usr/local/node/10.15.3 # lsbin  include  lib  share/usr/local/node/10.15.3 # ./bin/node -vv10.15.3/usr/local/node/10.15.3 # ldd bin/node 	/lib/ld-musl-x86_64.so.1 (0x7f22f84b3000)	libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f22f6409000)	libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f22f63f5000)	libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f22f84b3000)/usr/local/node/10.15.3 #

而通过Jenkins再次执行Job,也获取的npm和node的正常版本信息。

在这里插入图片描述

总结

可以看到使用-u root即可获得root的权限进行操作,但是在实际应用时只能作为权益之举,虽然很多时候权益之举会变成例行操作。

转载地址:https://liumiaocn.blog.csdn.net/article/details/102634568 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Jenkins基础:使用NPM构建前端应用3:使用NodeJS构建前端应用
下一篇:Jenkins基础:Jenkinsfile使用实例:13:使用push命令进行镜像推送

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月24日 03时29分59秒