据说在 Linux Docker中无法使用 systemd(systemctl) 相关命令的原因是 1号进程不是 init ,而是其他例如 /bin/bash ,所以导致缺少相关文件无法运行。(System has not been booted with systemd as init system (PID 1). Can’t operat)
解决方案:/sbin/init
例如:Ubuntu 18.04 ,
docker run -tid –name test –privileged=true ubuntu:18.04 /sbin/init docker exec -it test /bin/bash
PS:–privilaged=true一定要加上的。
目标 项目需要用到Xvfb,而安装Xvfb需要systemctl权限。
安装Xvfb 参考自这个文章:https://serverdiary.com/linux/how-to-install-xvfb-and-create-systemd-xvfb-service-on-centos-7-8-or-rhel-7-8/
先通过yum安装Xvfb
/etc/systemd/system/xvfb.service里面有个默认的浏览器大小?
docker run –network=host -tid xvfb
一直到这一步,报错了:
1 2 systemctl daemon-reload Failed to get D-Bus connection: Operation not permitted
这个文章提到,需要重新制作镜像,并设置权限参数:
https://serverfault.com/questions/824975/failed-to-get-d-bus-connection-operation-not-permitted
/home/share/dockerfile/xvfb.Dockerfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 FROM xvfb MAINTAINER "zhouchangju" <zhouchangju@myhexin.com> ENV container docker# RUN yum -y update; yum clean all RUN yum -y install systemd; yum clean all; \ (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ rm -f /lib/systemd/system/multi-user.target.wants/*;\ rm -f /etc/systemd/system/*.wants/*;\ rm -f /lib/systemd/system/local-fs.target.wants/*; \ rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ rm -f /lib/systemd/system/basic.target.wants/*;\ rm -f /lib/systemd/system/anaconda.target.wants/*; VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"]
构建镜像:
1 docker build --rm -t xvfb-systemd - < xvfb.Dockerfile
启动新的镜像:
1 docker run --privileged --network=host -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup xvfb-systemd /usr/sbin/init
但是启动时,我又遇到一个新的问题:
1 2 Couldn't find an alternative telinit implementation to spawn. /usr/sbin/init exited 1
这是执行/usr/sbin/init的时候报的错误;如果不执行这个,无法获取systemctl权限
网上说是因为需要包含 Volume(卷) /sys/fs/cgroup;但是我已经加了,还是不行
是否不用加入系统服务? 可以直接启动:
1 2 3 docker run --privileged --name xvfb --network=host -tid -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup -v /opt/google/chrome/chrome_extension:/opt/google/chrome/chrome_extension -v /home/share/puppeteer/:/home/share/puppeteer/ -v /home/share/video/:/root/Downloads/ xvfb-systemd docker exec -ti xvfb /bin/bash
启动Xvfb:
1 2 # 注意这里设置的分辨率,是会影响最终生成的视频的分辨率的,这个待琢磨 Xvfb -ac :7 -screen 0 1280x1024x8
然后执行node puppeteer.js录屏,发现报错了:Unable to open X display
经测试,发现还需要我们主动启动浏览器:
1 export DISPLAY=:7 (和上一步的number号相同)
现在执行node puppeteer.js,就可以录屏了。
但是查看录制好的视频,只有20K,播放是一片白的。怀疑是Puppeteer启动浏览器的时候设置太大了,导致屏幕中间的位置并没有内容。
将Puppeteer打开的浏览器页面设置小之后再测试,果然有内容了。
但是有个新的问题:scale似乎针对录制没效果,怀疑是因为没有重启Xvfb,导致修改的插件内容没有重新加载生效。
重启Xvfb,再次录屏,还是不对,页面中的绘图部分仍然很小,看起来是没有scale的效果。
将Puppeteer打开的浏览器设置小一点,发现就可以了。
问题:
我将Xvfb的启动分辨率设置大了后,确实录制的界面大了,但是帧数非常低,最终生成的文件反而比低分辨率更小了。
1 Xvfb -ac :7 -screen 0 4800x2500x8
Xvfb文档:https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml#heading4
当Xvfb启动的分辨率设置大了后,效果非常明显,很清晰,就是帧数严重下降了。因此我们需要一个强劲的CPU才行。不知道线上docker的CPU怎么样。
经测试,Xvfb设置的分辨率越大,耗费的CPU和性能就越高,因此我们应该合理设置这个数值,否则会导致资源浪费,帧数降低。