start jenkins docker 常见问题

1. 手工启动 jenkins:

(jenkins_url)/safeRestart     # Allows all running jobs to complete. New jobs will remain in the queue to run after the restart is complete.
(jenkins_url)/restart         # Forces a restart without waiting for builds to complete.

2. 增加对javamail client 对(Exchange/outlook)smtp.office365.com 使用tls加密的支持:


# 在启用jenkins 是传入环境参数:
docker run -p 8082:8080 -p 50000:50000 -v /usr/local/share/jenkins:/var/jenkins_home --env JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dmail.smtp.starttls.enable=true"  --env JENKINS_ARGS="-Dmail.smtp.starttls.enable=true" jenkins:latest

3. 打开robot report|log.html 遇到web CSP安全策略组织javascript 远程执行 而失败:

在 Docker 环境下,jenkins参数配置无效:
  <arguments>-Xrs -Xmx512m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -Dhudson.model.DirectoryBrowserSupport.CSP= -jar "%BASE%\jenkins.war" --httpPort=8080</arguments>
  
便捷但有失安全的做法是,在浏览器设置中关闭CSP缺略,以Firefox 为例:
     打开about:config, security.csp.enable = ture 改为false。即可,改配置会立刻生效

5. Jenkins 挂载本地配置目录无权限的问题:

docker-machine ssh default

# 启动Jenkins官方镜像,并检查日志
docker run -d -p 8080:8080 -p 50000:50000 --name jenkins jenkins

docker logs jenkins
# 我们可以发现"jenkins"容器日志显示结果一切正常

# 然而为了持久化Jenkins配置数据,当我们把宿主机当前目录下的data文件夹挂载到容器中的目录"/var/jenkins_home"的时候,问题出现了:

docker rm -f jenkins
docker run -d -p 8080:8080 -p 50000:50000 -v $(pwd)/data:/var/jenkins_home --name jenkins jenkins
docker logs jenkins
  • 错误日志如下
touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?

# 我们检查一下之前启动方式的"/var/jenkins_home"目录权限,查看Jenkins容器的当前用户: 当前用户是"jenkins"而且"/var/jenkins_home"目录是属于jenkins用户拥有的

docker@default:~$ docker run -ti --rm --entrypoint="/bin/bash" jenkins -c "whoami && id"
jenkins
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)

docker@default:~$ docker run -ti --rm --entrypoint="/bin/bash" jenkins -c "ls -la /var/jenkins_home"
total 20
drwxr-xr-x  2 jenkins jenkins 4096 Jun  5 08:39 .
drwxr-xr-x 28 root    root    4096 May 24 16:43 ..
-rw-r--r--  1 jenkins jenkins  220 Nov 12  2014 .bash_logout
-rw-r--r--  1 jenkins jenkins 3515 Nov 12  2014 .bashrc
-rw-r--r--  1 jenkins jenkins  675 Nov 12  2014 .profile

# 而当映射本地数据卷时,/var/jenkins_home目录的拥有者变成了root用户

docker run -ti --rm -v $(pwd)/data:/var/jenkins_home --entrypoint="/bin/bash" jenkins -c "ls -la /var/jenkins_home"
total 4
drwxr-sr-x  2 root staff   40 Jun  5 08:32 .
drwxr-xr-x 28 root root  4096 May 24 16:43 ..
# 这就是当"jenkins"用户的进程访问"/var/jenkins_home"目录时,会出现 Permission denied 的问题

# 我们再检查一下宿主机上的数据卷目录,当前路径下"data"目录的拥有者是"root",因为这个目录是Docker进程缺省创建出来的。

docker@default:~$ ls -la data
total 0
drwxr-sr-x    2 root     staff           40 Jun  5 08:32 ./
drwxr-sr-x    5 docker   staff          160 Jun  5 08:32 ../
  • 发现问题之后,解决方法也很简单:把当前目录的拥有者赋值给uid 1000,再启动"jenkins"容器就一切正常了。
sudo chown -R 1000 data
docker start jenkins
# 这时浏览器访问 "http://192.168.99.100:8080/" 就可以看到Jenkins的Web界面了。

注:如无法访问,可能需要通过docker-machine ip命令获得当前Docker宿主机的IP地址。

# 当我们再进入容器内部查看"/var/jenkins_home"目录的权限,其拥有者已经变成 "jenkins"

docker@default:~$ docker exec jenkins ls -la /var/jenkins_home
total 24
drwxr-sr-x 11 jenkins staff  340 Jun  5 09:00 .
drwxr-xr-x 28 root    root  4096 May 24 16:43 ..
drwxr-sr-x  3 jenkins staff   60 Jun  5 08:59 .java
-rw-r--r--  1 jenkins staff  289 Jun  5 08:59 copy_reference_file.log

# 而有趣的是在宿主机上我们看到的 "data"目录的拥有者是"docker",这是因为"docker"用户在"boot2docker"宿主机上的uid也是"1000"。

docker@default:~$ ls -la data
total 20
drwxr-sr-x    2 docker   staff           40 Jun  5 11:55 ./
drwxr-sr-x    6 docker   staff          180 Jun  5 11:55 ../

这时我们已经可以知道:容器的本地数据卷中文件/目录的权限是和宿主机上一致的,只是uid/gid在Docker容器和宿主机中可能映射为不同的用户/组名称。

在上文,我们使用了一个常见的技巧,即在宿主机上执行chown命令时采用了uid而不是具体的用户名,这样就可以保证设置正确的拥有者。

问题虽然解决了,但思考并没有结束。因为当使用本地数据卷时,Jenkins容器会依赖宿主机目录权限的正确性,这会给自动化部署带来额外的工作。有没有方法让Jenkins容器为数据卷自动地设置正确的权限呢?这个问题对很多以non-root方式运行的应用也都有借鉴意义。

  • 为 non-root 应用正确地挂载本地数据卷

参考: http://stackoverflow.com/questions/23544282/what-is-the-best-way-to-manage-permissions-for-docker-shared-volumes

其中的基本思路有两个:

  • 一个是利用Data Container的方法在容器间共享数据卷。这样就规避了解决宿主机上数据卷的权限问题。由于在1.9版本之后,Docker提供了named volume来取代纯数据容器,我们还需要真正地解决这个问题。
    另外一个思路就是让容器中以root用户启动,在容器启动脚本中利用"chown"命令来修正数据卷文件权限,之后切换到non-root用户来执行程序
    我们来参照第二个思路来解决这个问题

    下面是一个基于Jenkins镜像的Dockerfile:它会切换到"root"用户并在镜像中添加"gosu"命令,和新的入口点"/entrypoint.sh"

FROM jenkins:latest
USER root
RUN GOSU_SHA=5ec5d23079e94aea5f7ed92ee8a1a34bbf64c2d4053dadf383992908a2f9dc8a \
  && curl -sSL -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.9/gosu-$(dpkg --print-architecture)" \
  && chmod +x /usr/local/bin/gosu \
  && echo "$GOSU_SHA  /usr/local/bin/gosu" | sha256sum -c - 
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# 注释:gosu 是经常出现在官方Docker镜像中的一个小工具。它是"su"和"sudo"命令的轻量级替代品,并解决了它们在tty和信号传递中的一些问题。
  • 新入口点的"entrypoint.sh"的内容如下:它会为"JENKINS_HOME"目录设置"jenkins"的拥有权限,并且再利用"gosu"命令切换到"jenkins"用户来执行"jenkins"应用。
#! /bin/bash
set -e
chown -R 1000 "$JENKINS_HOME"
exec gosu jenkins /bin/tini -- /usr/local/bin/jenkins.sh
  • 您可以直接从 https://github.com/denverdino/docker-jenkins 获得相关代码,并构建自己的Jenkins镜像。执行命令如下:
git clone https://github.com/AliyunContainerService/docker-jenkins
cd docker-jenkins/jenkins
docker build -t denverdino/jenkins .
# 然后基于新镜像启动Jenkins容器

docker rm -f jenkins
docker run -d -p 8080:8080 -p 50000:50000 -v $(pwd)/data:/var/jenkins_home --name jenkins denverdino/jenkins
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值