分类目录归档:Linux

Dockerfile编写使用cron后出现无法执行定时任务的解决方法

最近给自己的项目编写一个Dockerfile,这个项目需要用到Cron定时任务。在Dockerfile里apt安装cron后不论如何使用RUN命令启动cron都无效(包括使用service和直接执行cron命令)。后来将所有任务集成在了一个sh脚本里解决了问题。举例,我要运行的任务是apache。那么我可以写一个脚本startup.sh,把Dockerfile的ENTRYPOINT设为这个脚本。

1
2
3
#!/bin/sh
cron
apache2-foreground

原因是什么呢?

方法1和方法2不能成功,是因为docker只是一个进程隔离的沙箱环境,并不是真正的虚拟机。而service xxx start 和systemctl start xxx 分别是upstart和systemd这两个/sbin/init进程的替代者的服务管理命令。而upstart和systemd都要求系统必须是物理机或虚拟机,并不支持作为container的init进程。方法3存在问题是因为,在正常的系统中,init进程永远占用PID=1的位置,回收僵尸进程、处理未处理的信号等都是由init进程帮我们完成的,一个子进程如果失去了父进程,也会由init进程接管。但是在container中,init进程并不存在,PID=1的进程是我们在Dockerfile中定义的Entrypoint或最后一个CMD指定的命令。

参考资料:https://www.asuri.org/2018/08/25/run-multi-service-in-one-container/

而直接执行cron命令为何失败呢?我推测,Dockerfile设计RUN命令的本义是对文件系统进行一定的操作。而非监控Container在启动时需要开启什么进程。所以一定要把所有需要运行的程序都写到一个shell脚本里并且把其设为入口点才行。

说说用树莓派配置NAS的过程

主要是给自己留个参考。
用的树莓派是B+,原来有无线网卡,和一块160G的SATA硬盘,网上买了个SATA转USB的绿联硬盘盒。然后就开工了。
烧好SD卡。在/boot引导里新建文件ssh,开启ssh连接。默认用户名密码:pi raspberry。然后把debian源换成aliyun。然后apt update。装个frp内网穿透、nginx提供http服务、vsftpd提供ftp服务。就OK了。下面列几个不好配置的点。将来如果再配置就不用麻烦半天了。

1、frp想要搞成开机启动,必须在/etc/rc.local中frp启动之前加上sleep 60好让网卡等外围设备初始化完毕,否则连不上网frp自动退出,就要人工手动了。
2、vsftpd的配置文件列一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
listen_ipv6=YES
local_enable=YES
write_enable=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=ftp
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd.allowed_users
ftpd_banner=Welcome to NAS service.
local_root=/var/www/DISK
use_localtime=yes
pasv_enable=yes
pasv_min_port=5000
pasv_max_port=5050
anonymous_enable=NO
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
allow_writeable_chroot=YES

/etc/vsftpd.chroot_list和/etc/vsftpd.allowed_users都写ftp用户名就可以了。然后添加ftp用户需要useradd -d /var/www/DISK -s /sbin/nologin。就是这样。