配置项目的Docker支持

对于VS中Docker的配置,依旧重复一些废话。

给项目添加Docker支持,VS2015可以直接使用Docker for VS插件,VS2017在安装时选择容器支持。VS配置好容器支持后,右键点击项目,添加菜单中就可看到Docker Support选项。

VS2015的Docker for VS插件会把Dockerfile加入到package.json的publishOptions中。这样一次dotnet publish操作就可以获得含有Dockerfile可以直接用于生成Image的输出。

而VS2017中,使用“添加-Docker支持”菜单添加的Dockerfile文件不会自动配置为输出到输出目录,可以选择Dockerfile并右击属性,在属性选项卡中,选择“如果较新则复制”。

在Linux使用cron定时运行.NETCore App

一个坑

如果直接在crontab -e中通过下面的方法添加任务:

*/2 * * * * dotnet /publish/your.app.dll #2分钟运行一次,用于测试

肯定是没有办法执行的,通过tail -f /var/log/cron可以看到如下错误输出(CentOS):

(root) CMDOUT (/bin/sh: dotnet: 未找到命令)

爬坑

我们需要使用如下脚本来帮助运行.NetCore应用:

#!/bin/sh
export PATH=$PATH:/publish:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
cd /publish
dotnet your.app.dll >> /var/log/cron.log 2>&1 #将应用的输出重定向(可选),默认输出到`/var/log/cron`
exit;
EOF

一些已知限制,应用程序目录中不能含有.

为避免在cron输出日志时遇到No MTA installed, discarding output这样的错误,建议重定向应用的输出到指定的文件

将这个文件保存为rundotnet.sh并设置输出到发布文件中。这个文件将被cron调用定时来运行.NetCore程序。

将使用crontab -e修改cron任务如下(添加后可使用crontab -l验证添加结果):

*/2 * * * * /publish/rundotnet.sh

注意修改rundotnet.sh的权限使其具有执行权限

另一种方式是直接将应用发布为可执行程序。

亲测使用VS2017发布.NetCore App(.NETCore版本1.0.4),可以在安装有.NetCore SDK 1.0.3的Linux上使用下面的cron配置正常执行。

*/2 * * * * /publish/your.app

同样需要赋予your.app文件执行权限

而VS2015发布.NetCore App(.NETCore版本1.0.0),在安装有.NetCore SDK 1.0.1的Linux上就不能正常执行。

整合到Docker中

创建一个名为crontab的文件用于保存cron命令,内容就是我们之前使用crontab -e添加的任务:

*/2 * * * root /publish/rundotnet.sh # 用户名root在这里不可少,根据需要修改定时执行的时间
# 合法的cron文件需要留一行空行

可能有眼尖的园友发现为什么这里有root这个用户名而前文没有,前文的测试是在一台RedHat系(CentOS7)上进行的。而微软的.NETCore Docker Iamge基于Debian系系统,这里必须有用户名,不然会报类似“crontab文件格式不合法“类似的错误。

创建好文件后将其配置为发布到输出目录,以便可以在dotnet pulish后被docker build所使用

然后添加一个文件runcron.sh,这将作为docker container的执行入口

rsyslogd
cron
touch /var/log/cron.log
tail -F /var/log/syslog /var/log/cron.log

最后一行分别输出系统日志(cron执行情况,在syslog中)和dotnet app的输出(在cron.log中,前提是前面添加了输出的重定向)

tail命令将保证container一致执行,不会退出

也可以用docker的--restart=always参数控制容器的运行

修改VS创建的Dockerfile文件中的内容为类似如下的样子:

FROM microsoft/dotnet:1.0-runtime
COPY . /publish
WORKDIR /publish
# 开始配置cron # microsoft/dotnet:1.0-runtime镜像不包含cron,先安装,顺便安装rsyslog输出日志
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
cron \
rsyslog \
&& rm -rf /var/lib/apt/lists/* # 将我们编辑的crontab任务文件添加到cron配置目录
ADD crontab /etc/cron.d/dotnet-cron
# 赋予crontab文件读权限(rw/r/r)
RUN chmod 0644 /etc/cron.d/dotnet-cron
# 创建日志文件,以便执行tail命令
RUN touch /var/log/cron.log
# 赋予runcron.sh和rundotnet.sh执行权限
RUN chmod +x /publish/rundotnet.sh
RUN chmod +x /publish/runcron.sh
# 执行入口脚本runcron.sh
CMD ["bash","/publish/runcron.sh"]

在Dockerfile中我们向基础容器添加了cron和rsyslog,在debian/ubuntu上(dotnet官方镜像的基础系统)cron需要靠rsyslog来输出日志

最终输出目录要包含下列文件:

"appsettings.json",
"Dockerfile",
"crontab",
"rundotnet.sh",
"runcron.sh"

使用如下命令publish项目

dotnet publish --framework netcoreapp1.0 --configuration release --output publish

将publish中文件传到安装有docker的环境中准备生成docker image

生成Docker映像,运行Container

我们将生成运行(包含清理旧映像)的脚本整合为一个buildhelper.sh:

#!/bin/bash
contName=$1
contName=${contName:="containerName"}
imagName=$2
imagName=${imagName:="orgname/projname:tag"}
docker stop ${contName}
docker rm -f ${contName}
docker rmi ${imagName}
docker ps -a
docker images
sudo docker build --rm -t orgname/projname:tag .
sudo docker run --name containerName -it orgname/projname:tag

依然配置此文件发布到输出到发布目录(在Linux上要赋予执行权限)。

容器运行后可以连接到container的bash查看运行情况

docker exec -it containerName /bin/bash

如果感觉测试时,每次Docker Image都会进行apt-get安装cron很麻烦,可以先生成一个包含cron以及rsyslog的镜像,并以此作为这个例子的基础镜像。(按照博主提供的这些基本可以一次成功)

提示

所有shell脚本文件(xxx.sh),如果是UTF8格式,都要使用无BOM的UTF8编码。或者使用ASCII。不然bash无法正常运行。

一键去BOM的方法: grep -r -I -l $'^\xEF\xBB\xBF' /path | xargs sed -i 's/^\xEF\xBB\xBF//g'


如果在Windows里编辑过sh文件,在linux种可能出现错误:“/bin/bash^M:损坏的解释器: 没有那个文件或目录”

这是由于两种系统换行符不同,Windows为\n\r,Linux为\n,而\r会被显示为^M。

一键替换 sed -i 's/\r$//g' filename

大致有如下文件需要处理:

sed -i 's/\r$//g' crontab
sed -i 's/\r$//g' buildhelper.sh
sed -i 's/\r$//g' rundotnet.sh
sed -i 's/\r$//g' runcron.sh

crontab处理换行很重要,不然在linux会导致必须存在的空行无法被识别而无法正茬加载。


rsyslogd的如下错误提示可以安全忽略:

rsyslogd: imklog: cannot open kernel log(/proc/kmsg): Operation not permitted.

而错误:

Could not open output pipe '/dev/xconsole': No such file or directory

暂时不知道有无影响(实测不会对rsyslog的工作产生影响)


定时任务时间 对于定时任务,要注意如之前使用的基础镜像microsoft/dotnet:1.0.1-core的时区都是UTC时间,对于我们UTC+8的地方要自行在配置cron的时间时加上8个小时。

好办法 在生成镜像的时候直接修改好时区,Dockerfile中加入 RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime


可能会有小朋友质疑,用Docker运行这种定时任务有必要吗,楼主感觉Docker最主要的还是屏蔽不同底层系统的差异。顺便可以让不同的应用的定时任务可以分离。本文也是提供一种方法,供有需要的童鞋参考。

.NET遇上Docker - Docker集成Cron定时运行.NETCore(ConsoleApp)程序.md的更多相关文章

  1. (转)Permission denied: win7下面eclipse上传本地文件到DFS && 运行M/R程序时出现的同样的错误解决方法

    原文地址: http://mntms.iteye.com/blog/2095651 hadoopeclipse远程控制权限  情景一: 当在win7下面的eclipse装好插件,首次运行M/R程序的时 ...

  2. Docker学习笔记-磁盘挂载运行.netcore

    前言: 环境:centos7.5 64 位 正文: 首先我们在宿主机上安装 .NET Core SDK sudo rpm --import https://packages.microsoft.com ...

  3. raspberrypi(树莓派)上安装mono和jexus,运行asp.net程序

    参考网址: http://www.linuxdot.net/ http://www.cnblogs.com/mayswind/p/3279380.html http://www.raspberrypi ...

  4. 当DOCKER遇上ESXI

    特别是你要为DOCKER窗口设置静态IP,且和公司局域网打成一片的时候, 苦逼的测试就会开始,我差不多前前后后测试了四五天,一百多个容器报废. NETNS,NSENTER,PIPWORK,各种镜像合下 ...

  5. .NET遇上Docker - 使用Docker Compose组织Ngnix和.NETCore运行

    本文工具准备: Docker for Windows Visual Studio 2015 与 Visual Studio Tools for Docker 或 Visual Studio 2017 ...

  6. .NET遇上Docker - Harbor的安装与基本使用

    Harbor是一个开源企业级Docker注册中心,可以用于搭建私有的Docker Image仓库.可以实现权限控制等. 安装Harbor 首先,需要安装Docker和Docker Compose,参考 ...

  7. 从零开始搭建Jenkins+Docker自动化集成环境

    本文只简单标记下大概的步骤,具体搭建各个部分的细节,还请自行搜索.第一.二部分只是对Jenkins和Docker的简单介绍,熟悉的同学请直接跳到第三部分. 一.关于Jenkins Jenkins简介 ...

  8. Jenkins + Docker 持续集成

    Jenkins介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 安装部署Jenkins ...

  9. Jenkins+Docker持续集成

    本节内容: Jenkins介绍 安装部署Jenkins Jenkins构建maven风格的job Jenkins邮件通知设置 Sonar Jenkins与Docker结合 一.Jenkins介绍 Je ...

随机推荐

  1. 3391: [Usaco2004 Dec]Tree Cutting网络破坏

    3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 76  Solved: 59[ ...

  2. 3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题

    3407: [Usaco2009 Oct]Bessie's Weight Problem 贝茜的体重问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit:  ...

  3. 腾讯云数据库团队:MySQL AHI 实现解析

    MySQL 定位用户记录的过程可以描述为:打开索引 -> 根据索引键值逐层查找 B+ 树 branch 结点 -> 定位到叶子结点,将 cursor 定位到满足条件的 rec 上:如果树高 ...

  4. HashSet和TreeSet 的区别与分析

    Set是java中一个不包含重复元素的collection.更正式地说,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素.正如其名称所暗示的, ...

  5. Docker 使用指南 (四)—— 数据卷的使用

    一.数据卷的使用 有时候需要使用数据库,但是又希望它的数据能保存在本地,Docker中提供了数据卷可以供你方便的操作数据.数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用 ...

  6. Android学习笔记---前传

    在正式的撰写个人的学习笔记前,先对个人的学习经历做一个简要的介绍.座右铭:诚不欺我 1. 前言 本人非软件工程出身,属于半路出家,误打误撞进入这个行业,初心是软件开发的门槛低,自以为学习过C语言,轻度 ...

  7. Eclipese Mars安装SVN的全步骤

    在做毕业设计的过程中,由于是团队项目,需要用到SVN,而全新的Eclipse Mars从官网下载下来没有SVN插件,需要自己下载. 1.选择Help-->Eclipese MarketPlace ...

  8. Python 获取 网易云音乐热门评论

    最近在研究文本挖掘相关的内容,所谓巧妇难为无米之炊,要想进行文本分析,首先得到有文本吧.获取文本的方式有很多,比如从网上下载现成的文本文档,或者通过第三方提供的API进行获取数据.但是有的时候我们想要 ...

  9. React中使用CSSTransitionGroup插件实现轮播图

    动画效果,是一个页面上必不可少的功能,学习一个新的东西,当然就要学习,如何用新的东西,用它的方法去实现以前的东西啦.今天呢,我就在这里介绍一个试用react-addons-css-transition ...

  10. formvalidation表单验证

    官方文档:http://formvalidation.io var $formEntityProfileSearch = $("form[name=entityProfileSearch]& ...