Jenkins部署出现Permission denied

Jenkins部署出现Permission denied,第1张

突然记起上周应用部署的一个小问题,发版失败弄了蛮久,在此记录一下

用Jenkins发版旧的服务没杀掉,新的服务一直没起来,看了日志出现Permission denied,看到这个的第一反应是账号权限不够,但是反复看也不知道是哪里权限不够

找大佬看了之后其实主要有两个地方

1 、 系统 参数

(1)构建服务器访问路径: 

(2)JDK版本(根据各产品的具体要求选择):

1) jdk170_60

(3)Maven版本(根据各产品的具体要求选择):

1) apache-maven-323

2) apache-maven-322

3) apache-maven-321

4) apache-maven-cif

(4)Jenkins信息:

1) Jenkins version 1609   可升级

2) $Jenkins_home:  home/ciserver/jenkins

3)Jenkins工作目录:/app/Jenkins/

2 、 授权 策略

(1)Configure Global Security中的授权策略,采用Role_Based_Strategy方式;

   (2)根据人员的角色和职责建立Global roles;

   (3)根据不同的产品系统及其开发阶段,建立project_roles;

(4)为jenkins账户建立global role和project role的授权矩阵,即用户访问权限矩阵;

(5)用户界面是基于他拥有的权限和任务所属的阶段和所归属的视图(View)进行显示;

Jenkins构件任务命名规范参考32章节,jenkins账户管理参考第4章节。

3、构建管理

3 1 构建 命名 规范

用户登录后,界面所能执行的 *** 作的基于以下2点,缺一不可:

(1)用户所拥有的权限;

(2)根据命名规则过滤后的任务视图和任务;

请务必按照下面的命名规范进行任务的创建和修改。

3 11 任务视图 命名

任务视图命名格式:

产品/系统名称(缩写)_阶段,阶段缩如(DEV、ST、UAT、PRD),如下图红线标注所示:

图3-1 任务视图命名示例

3 1 2 任务 命名

任务的命名格式:  

系统任务:阶段缩写_产品/系统(缩写);

子系统和模块任务:阶段缩写_产品/系统缩写_子系统/模块缩写

3 2 参数化构建

321   构建 参数列表

321 常 用 的参数 配置

3 3 分布式构建

     考虑到构建效率和后续构建任务的扩张;通过配置jenkins Master-slave架构进行分布式构建;

DEV阶段的构建在slave进行。

3 31 slave节点 配置

3 32 slave节点任务 配置

(1)DEV阶段的构建,在20610jenkins服务器上建立slave节点,将各产品部的构建任务分配到对应的节点去运行(包括工作空间,本地仓库,编译运行环境);

在DEV阶段的任务配置中,勾选“Retrict where this project can be run”, Label Expression填写各slave标签名。

4 、 jenkins账户 管理

(1)jenkins账户统一由组织级管理员建立和维护,jenkins账户命名格式为:姓名全拼;用户可登陆后修改;

(2)jenkins账户按照用户类别分为,admin,系统管理员,构建人员,guest;

     1) Admin负责整个jenkins服务器的管理;

2)系统管理员的具有其负责的产品库的4个阶段所有任务的创建,配置权限;

3)构建人员为产品开发人员,根据需要开放四个阶段的构建任务的执行和配置权限;

4)guest账户仅供有查看需求的员工使用;

5)普通用户账户权限申请和权限变更,由系统管理员或分支管理员向组织级CM申请。

5、J enkins基本 *** 作

51 登录jenkins

申请账户后,在浏览器中输入 >

Docker 提供了数据卷 绑定挂载 的机制(volume bind mounts)来将主机上的文件 (file) 或者目录 (directory) 挂载进容器 (container)。也就是 docker run 命令中熟知的 -v 参数。根据 Docker 官方文档,绑定挂载一般适合于 三种场景 :

但是实际使用时,会遇到文件权限问题:

譬如执行如下命令创建一个容器,挂载当前目录到容器内,并在容器内向主机当前目录创建 tmptxt:

主机当前目录出现了容器内创建的 tmptxt,但是其权限、用户和组均是 root,其他用户不可写。

常见解决方法是可以通过 Docker 提供的 User 命令、 --user 参数 来指定容器内部的用户和组的 id,譬如:

可以看到输出,current_user 处会显示主机当前用户的名字,所以解决了主机用户对挂载的卷没有权限的问题。

user 参数的缺陷

使用 user 参数有一些缺陷,如果你进入容器内部的 terminal,会显示如下内容:

bash 的用户名会显示 I have no name!,这是因为我们通过 --user 参数指定了容器内部的用户 id,但该 id 不存在于容器内的 /etc/passwd 文件中。

除此之外,使用 user 参数仍然存在权限问题:

除了绑定挂载的主机路径之外的所有路径,对于容器内部的用户都没有写权限。

这也是不可接受的,因为容器运行过程中我们可能会进行一些临时文件的写入,这些临时文件我们并不想要写到主机的挂载目录,但除了挂载路径之外的任何路径容器都没有写入权限。

譬如我们在主机上创建 models 目录。

我们使用 Docker 挂载 models 目录,然而在 Docker 容器内部除了 models 文件夹都没有访问权限。

这可以通过增加挂载路径:

这样容器运行过程往 /project 写的临时文件都会出现在主机上。

可见, user 参数并不能解决所有问题。它存在两个问题:

我们需要一种手段,既可以像 user 参数一样在容器运行时可以将用户切换到和主机相同的用户,又希望 Docker 容器保留 root 用户,并给主机用户想要访问的目录授权(对特定目录 chown 、 chmod 等)。

Docker 官方文档对 Entrypoint 介绍时给出了 一种最佳实践 。

编写如下的 Dockerfile:

该 Dockerfile 中安装了一个 gosu 的工具,并设置了程序的 Entrypoint。由于 Docker 内使用 sudo 可能导致一些不可预知的 TTY 和信号转发问题,所以 Docker 官方推荐了使用 gosu 这个工具,用于保持容器在 root 用户下运行,并用 sudo 来切换到指定用户。

其中 docker-entrypointsh 内容如下:

可以看到 docker-entrypointsh 中创建了一个名为 user 的用户,该用户的 uid 由 docker run 的参数传入,这里利用了 linux 系统的一个特点,容器内外用户权限的记录和用户的名字无关,只和 uid 有关,因此容器内我们将用户命名为 user 没有影响。docker-entrypointsh 最后一行调用 gosu 来切换到 user 用户并执行 Dockerfile 中的用户命令。

有了如上两个脚本,我们构建镜像并执行:

运行容器时指定 LOCAL_USER_ID 参数:

可见不仅容器内往挂载目录 /project/models 写入的文件 modeltxt 所有者是主机用户,而且在容器内往非挂载目录 /project/tmptxt 写入文件也不会遇到权限问题。

Docker 运行时容器内默认使用 root 用户运行,但是我们不是总是想要用 root 用户,因为有时候我们希望容器计算产生一些文件,并通过 volume 的绑定挂载在主机上获取。特别是我们用 jenkins 等工具写一些持续集成的脚本时候。容器内用 root 用户运行会导致产生的文件也是 root 用户的,主机上没有读取权限。因此我们需要让容器在运行的时候切换到主机上的用户。

Docker 对于这种情况仍然没有提供足够便利的基础设施,我们采用了 Docker 官方目前推荐的一个方式,通过编写一个 docker-entrypointsh 脚本作为 Dockerfile 的 Entrypoint,脚本中创建和主机上相同 uid 的用户,并通过 gosu 工具切换到该用户执行命令。 uid 需要在 docker run 阶段通过参数传入。我们在脚本中设置了缺省 uid ,上面的脚本随机选择了一个 9001,注意要将该缺省值避免设置成和 Docker 镜像中存在的用户冲突的 uid。

参考链接:

如果你安装好了Role-based Authorization Strategy插件后, 没有找到下面的菜单 是因为你跳过了一步, 没有在安全全局配置中开启Role-based

在Authorization 策略列表中勾选Role-based

这里定义了不同的角色:admin, developer, job, pack。 他们的全局权限不一,而且必须勾选Overall的Read一项。

Project Roles , 是针对不同的项目名称匹配,定义不同的项目角色。这里需要说明的是," "匹配任意字符,而不是" "。

好处是,只要项目的名称规则统一,不需要逐个项目设置权限。

这里的人员,填入的是LDAP的ou组,而不是逐个人员进行添加。

点击Test LDAP setttings , 输入组内的用户和密码,测试验证,结果如下。

1、启用了LDAP,默认的admin用户,也即jenkins的本地用户数据就被禁用了,不能继续登录。

2、在设置Group membership的时候,选择第二项,不要选择第一项。

jenkins集成LDAP相对比较简单,缘于jenkins的权限管理比较简单。下面给出LDAP的树形结构。

补充: 上面只是实现了账号的统一管理,jenkins的权限管理,请参考:基于Role-based Authorization Strategy的用户权限管理。

按项目名的前缀,采用模糊匹配的方法,将权限分组,赋予不同的角色(“权限组”)。

很显然你当前用户对/usr/local/weikuaiyun-tomcat-7069/没有写执行权限,解决这个问题只要把/usr/local/weikuaiyun-tomcat-7069/权限对jenkins对应的管理员放开所有权限就行了

问题:Jenkins默认使用jenkins用户去启动,jenkins用户并没有权限去执行ssh免密登陆,所以导致执行失败

注:配置linux双机互信后,jenkins也需要将公钥加入到目标机器,才能达到shell脚本中scp免密传输的条件

一、验证登录

1、切换jenkins用户

# su jenkins

切换后还是root账号

2、分析解决:

21 应该是/etc/passwd文件中的/bin/bash被yum安装的时候变成了/bin/false

# vim /etc/passwd

jenkins:x:990:988:Jenkins Automation Server:/var/lib/jenkins:/bin/false( bash)

将bin/false改为/bin/bash

再次执行切换

# su jenkins

bash-41$

22  结果命令提示符的用户名不是jenkins而变成了 bash-41$,原因是在安装jenkins时,jenkins只是创建了jenkins用户,并没有为其创建home目录

# vim ~/bash_profile

在文件的最后添加 export PS1='[\u@\h \W]\$',执行文件使修改项起作用

# source ~/bash_profile

验证是否成功   # su jenkins

二、为jenkins系统用户开启免密登录

1、在Jenkins的使用过程中,如果在脚本中使用到sudo命令,有可能出现如下所示的错误:

sudo: no tty present and no askpass program specified

这是因为Jenkins服务器在执行sudo命令时的上下文有误,导致这个命令执行的异常。

21 解决方法:

# sudo visudo

在文件末尾加上jenkins ALL=(ALL) NOPASSWD: ALL

22 重启jenkins,测试

# su jenkins

# sudo su -s /bin/bash jenkins

测试成功,jenkins免密登录成功。

PS:如果误 *** 作修改了/etc/sudoers的权限来修改上述文件,则会导致如下所示的错误:

sudo :/etc/sudoers is world writable

sudo : no valid sudoers source found, quitting

sudo : unable to initialize poling plugin

这是Linux的一种保护机制。因此,如果出现上述误 *** 作,则需要执行如下命令来解决:

$ pkexec chmod 0440 /etc/sudoers

三、jenkins用户开通ssh免密登录

1、安装ssh

# yum install ssh

11 将ssh服务设置开机自启

# sudo systemctl enable sshd

12 启动ssh

# sudo systemctl start sshd

2、生成jenkins用户秘钥证书

# su jenkins

# ssh-keygen -t rsa

21 查看是否生成成功

# /var/lib/jenkins/ssh/

# ls

3、将公钥传输到目标linux系统

ssh-copy-id -i /var/lib/jenkins/ssh/id_rsapub root@目标ip:path

------------------------------------------------------------------------------------------

参考:>

进入JENKINS_HOME目录,找到configxml文件,找到了<useSecurity>和<authorizationStrategy>节点。<useSecurity>节点代表是否使用用户权限,<authorizationStrategy>节点代表用户权限是怎么划分的。 下面提供2种方法: 1、恢复默认设置 直接删除<useSecurity>和<authorizationStrategy>节点 2、配置管理员权限 这种方法适用于已经存在一堆的权限,重新配置麻烦。 在<authorizationStrategy>节点中添加内容如下: <permission>hudsonmodelHudsonAdminister:anonymous</permission> <permission>hudsonmodelHudsonConfigureUpdateCenter:anonymous</permission> <permission>hudsonmodelHudsonRead:anonymous</permission> <permission>hudsonmodelHudsonRunScripts:anonymous</permission> <permission>hudsonmodelHudsonUploadPlugins:anonymous</permission>

以上就是关于Jenkins部署出现Permission denied全部的内容,包括:Jenkins部署出现Permission denied、Jenkins持续集成使用指南、解决 Docker 数据卷挂载的文件权限问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10097900.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存