docker中/dev/stdout的理解

以nginx.conf为例子

我们通常看到的日志都是输入到一个文件中,类似access.log,error.log。只要产生相关日志日志就会出现对应的文件中。

error_log /etc/nginx/logs/error.log info;
access_log /etc/nginx/logs/access.log;

而我们在docker容器中,nginx.conf文件如下

error_log /dev/stdout info;
access_log /dev/stdout;

supervisord.conf文件如下

[program:nginx]
command=/usr/sbin/nginx -g "daemon off; error_log /dev/stderr info;"
autostart=true
autorestart=true
priority=10
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT

可以看到日志并不是输出到一个文件内,而是/dev/stdout/dev/stderr。它的作用就是日志输出docker日志中,而不输入到具体的文件中。docker日志就是使用以下命令在前台输入的内容

docker-compose logs -f

或者是我们docker前台启动后,输出的内容

docker-compose up

现在有个问题,如果不是在docker上,在云上时,把nginx.conf配置成/dev/stdout时,相关日志输出在哪里?

如docker前台启动一样,日志也会输出到nginx前台启动,通过nginx二进制命令启动

[root@002 sbin]# ./nginx    
[root@002 sbin]# 119.119.76.13 - - [15/Oct/2019:14:40:27 +0800] "GET / HTTP/1.1" 200 24725 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
119.119.76.13 - - [15/Oct/2019:14:40:27 +0800] "GET /animated_favicon.gif HTTP/1.1" 200 207 "http://114.115.146.64:666/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
119.119.76.13 - - [15/Oct/2019:14:41:04 +0800] "GET / HTTP/1.1" 200 24725 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"
119.119.76.13 - - [15/Oct/2019:14:41:04 +0800] "GET /animated_favicon.gif HTTP/1.1" 200 207 "http://114.115.146.64:666/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"

nginx查看标准输出的日志通过前台启动时可以看到,其他服务也是一样,通过前台启动时即可查看到。

/dev/stdout 标准输出
/dev/stdin 标准输入
/dev/stderr 标准错误
/dev/null 不输入输出

还有一个问题,就是起了一个容器后,该容器有nginx和php进程,而俩进程都是使用supervisord来守护进程的。nginx日志都可以在docker里面正常输出,当我有一个需求,需要开启定时执行任务。这时需要在dockerfile文件中新增CMD命令,因为dockerfile中只能执行一条CMD命令,该命令就是容器的主进程。所以我门既要保证原来的服务能正常启动,我们还要启动crontab。所以命令如下

CMD /usr/bin/supervisord -c /etc/supervisord.conf && crond && tail -f /etc/supervisord.conf

提到CMD就不得不提应用在前台执行和后台执行的问题。docker中的所有应用后应该是前台执行,而不是像虚拟机里面用server/systemd去启动后台服务,容器里面没后台服务的概念。一般初学者将CMD写为CMD service nginx start.然后容器执行就退出了。对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去意义,所以退出,其他辅助进程不是它所关心的。

CMD /usr/bin/supervisord -c /etc/supervisord.conf && crond

如果执行上条命令的话,会报code为0的问题,表示容器退出,也就是后台启动完进程就退出了,所以容器也就没有存在的意义,也就退出了。所以我们加tail命令,tail可阻塞,挂起一个主进程,类似前台启动。

CMD /usr/bin/supervisord -c /etc/supervisord.conf && crond && tail -f /etc/supervisord.conf

注意:这时意味着和之前相比,主进程发生了变化,也就意味着,此时nginx的相关日志就不会输出在docker前台了。可以想象成原来开启的是nginx服务,现在开启了一个mysql服务,nginx的相关日志信息也理所当然的不会出现在mysql的服务中了。

重要:如果使用CMD后改变主进程,类似nginx日志将不会输出到console,此时我们应该修改nginx的配置文件,让其log输出到文件中

rsync

使用ssh 传输rsync 流量具有下述优点:可通过网络加密数据,也可利用使用ssh 客户端密钥建立的任何信任关系。如果要在两台计算机之间保持大型、复杂目录结构的同步性(尤其是两者间的差异很小时),那么rsync 就是一种使用起来极为方便(并且执行速度很快)、随心所欲的工具。

参数:

-a 归档模式,表示以递归方式传输文件,并保持所有属性,等同于-rlptgoD, -a选项后面可以跟一个 –no-OPTION 这个表示关闭-rlptgoD中的某一个例如 -a–no-l 等同于-rptgoD;

-r 对子目录以递归模式处理,主要是针对目录来说的,如果单独传一个文件不需要加-r,但是传输的是目录必须加-r选项;

-t 保持文件的时间属性;

-p 保持文件的权限属性;

-l 保留软链接;

-L 同步软链接的同时同步其源文件;

-g 保存文件数组;

-o 保持文件的属主;

-D 保存设备文件信息;

-v =visual,可视化;

-P 显示同步过程,比v更详细;

-u =update,加上该选项,如果DEST中文件比SRC中的新,则不同步;

-z =zip,传输时压缩;

–delete 删除DEST中SRC没有的文件;

–exclude 过滤指定文件,不同步;

–progress 在同步的过程中可以看到同步的过程状态,比如统计要同步的文件数量、同步的文件传输速度等等;

-e 指定端口;

-e:通过 ssh 传递文件

例:加上端口信息的ssh传输:

-e "ssh -p 2234"

rsync -arvP -e "ssh -p 2234" localdir host:remotedir

--delete:删除目标副本中的文件和目录。

默认情况下,rsync 只复制文件和目录,但如果从源主机删除了文件和目
录,那就不会从目标副本中删除这些文件和目录。要精确保存副本,须
包含 标志:

root@rover:~# rsync -ave ssh greendome:/home/ftp/pub/ /home/ftp/pub/

-v:是 verbose模式,输出更详细log。默认不输出这些信息。

-a:archive模式。在做备份的时候必备这个参数。(并不代表打包目标副本。)

-t:更新时间戳。

-z:压缩模式。With this option, rsync compresses any data from the files that it sends to the destination machine. This option is useful on slow connections. The compression method used is the same method that gzip uses.

-l:在目标服务器上重建主机上的link。

-n, --dry-run:不实施任何传输。只是报告模拟的传输结果。

实例:

rsync -avze ssh /home/me/public_html/contents/ user@toku:/home/tenten/contents/

Shell 例子:

#!/bin/sh

# -------- sync_contents.sh ----------
# Synchronization for user contents.
# This program is copyright (c) 2006
# Kreny
# Ver. 1.0.0 2006/8/3 16:53:30
#

# Date for logging
DATE=date +'%Y-%m-%d %T'

# Log file full pathname
LOG_FILE='/home/user/rsync_contents.log'

if [ ! -f $LOG_FILE ]; then
echo "ERROR:"
echo "Please check whether the log file $LOG_FILE exists and the writting permission."
exit
fi

# Contents path in original Server. No backslash at the end of the path.
CONTENTS_PATH_ORGINAL='/homeuser/public_html/contents'

# Contents path in target Server. Enter the backslash at the end of the path.
CONTENTS_PATH_TARGET='/homeuser/public_html/'

# Target server list
TARGET_SERVER='toku toku toku'

# ssh login username
USER_NAME='user'

# rsync 's path
RSYNC='/usr/bin/rsync'

echo "----------- $DATE -----------" >> $LOG_FILE

for cur_server in $TARGET_SERVER
do
echo "Synchronization for Server $cur_server ..." >> $LOG_FILE
$RSYNC -zave ssh $CONTENTS_PATH_ORGINAL $USER_NAME@$cur_server:$CONTENTS_PATH_TARGET >> $LOG_FILE
done

echo "----------- END -----------" >> $LOG_FILE

Rsync 使用数据备份完成后该操作会自行终止。对于此,最好是在上述命令的基础上再添加一个“-a”选项(对于文件)和“-e”选 项,指定使用远程的shell程序,以保障安全。此时,远端的shell将使用一个加密协议,比如ssh,以便远程的shell可以使用-e ssh格式。

这 样,上述Rsync 使用命令就有了ssh加密协议的保护,具体形式如下:

rsync -a -e "ssh -p 2234" localdir host:remotedir

如果想了解整个文件拷贝过程中所发生的一切,可以使用-v和-progress选项。-v选项表示打印出详细的操作过程。rsync默认的操作是单纯地 拷贝文件,不打印任何东西,尽量不打扰用户,只是简单而快速地完成任务。若只使用一次,-v选项将会报告所有被拷贝的文件,并在最后给 出总量。若使用两次-v选项,即在命令中使用-vv的话,rsync将不仅报告所有被拷贝的文件,还会报告那些勿需拷贝的文件,并在最后给出更 详细的信息。-progress选项的任务则主要是显示当前的拷贝进度,包括当前文件的大小,已完成的百分比,当前的传输速度,剩余时间估计, 等。如果要写一条使用复选项模式和ssh隧道协议的命令,同时还要求有进度指示器的话,则可采用如下形式:

rsync -avv -e ssh -progress localdir host:remotedir

如果在拷贝文件的过程中,传输被中断,Rsync 使用的默认操作是撤消前操作,即从目标机上删除已拷贝的部分文件。如果想在下次拷贝时续传文件 ,不需要重新拷贝所有文件的话,可以使用-partial选项阻止rsync在传输中断时删除已拷贝的部分。如果希望同时使用-partial和-progress 选项的功能,则可以使用-P选项,这是rsync提供的一个更便捷的选项,可以代替上述两者。因此,如果想使用复选项模式的文件拷贝,并关闭 删除选项,同时要求有进度指示器和ssh隧道协议的保护,则可以采用如下命令:

rsync -arvvP -e "ssh -p 2234" localdir host:remotedir

如果希望系统按照预定的调度计划自行处理,可以简单地在后台守护进程任务中添加Rsync 使用命令。如:要添加rsync命令到/etc/crontab文件中 ,方法如下所示:

30 4 * user rsync -aP -e ssh localdir host:remotedir

后台作业任务中的前五项用于定义某个任务何时被调度,第六项告诉后台守护进程哪一个用户将运行该任务。可以把以下例子中的“user”字 符串替换为将运行该任务的实际的用户帐号。例中的后台守护程序被设置为每天早上4:30运行一次。前五个字段的含义依次为秒,小时,月份 中的某一天,年份中的某月和一周中的星期几。时间以0开头,所以秒为0-59,小时为 0-23。接下来的两个字段,月份中的某一天和年份中的 某月,为1-31和1-12。最后一个字段,星期中的某一天,为0-7,不管是0还是7都代表星期天。实际的后台守护进程配置文件都比这复杂,但这 些是用rsync进行数据备份时创建后台程序的基本操作。如果还想了解更多的创建后台守护程序的相关信息,可以通过启动命令man cron,man crontab和man 5 crontab来获取。如果想集中管理数据备份后台守护进程,可以在备份服务器上创建如下的后台守护项:

30 4 * user rsync -aP -e ssh host:remotedir localdir

按照如上所述的方式设置后,Rsync 使用将从某个特定的远程主机上的目录(remotedir)中收集文件信息,并复制这些文件到你所指定的本地 (localdir)目录中。

Windows OVF导入步PVE骤示例

Microsoft为Windows开发提供了虚拟机下载服务。以下将利用这些镜像演示OVF导入功能。

*下载虚拟机镜像压缩包*

在选择同意用户协议后,选择基于VMware的Windows 10 Enterprise(Evaluation-Build),下载zip压缩包。

*从zip压缩包提取磁盘镜像*

使用unzip或其他工具解压缩zip压缩包,通过ssh/scp将ovf和vmdk文件复制到Proxmox VE服务器。

*导入虚拟机*

执行以下命令可以创建新虚拟机,虚拟机的CPU、内存和名称沿用OVF配置文件中的设置,磁盘镜像将导入local-lvm存储。网络配置可以手工完成。

qm importovf 999 WinDev1709Eval.ovf local-lvm

至此,虚拟机导入完成,可以启动使用。