新手指南:通过 Docker 在 Linux 上托管 .NET Core

这篇文章基于我之前的文章 .NET Core 入门[1]。首先,我把 RESTful API 从 .NET Core RC1 升级到了 .NET Core 1.0,然后,我增加了对 Docker 的支持并描述了如何在 Linux 生产环境里托管它。

我是首次接触 Docker 并且距离成为一名 Linux 高手还有很远的一段路程。因此,这里的很多想法是来自一个新手。

安装

按照 https://www.qixoo.qixoo.com/net/core 上的介绍在你的电脑上安装 .NET Core 。这将会同时在 Windows 上安装 dotnet 命令行工具以及最新的 Visual Studio 工具。

源代码

你可以直接到 GitHub[2] 上找最到最新完整的源代码。

转换到 .NET CORE 1.0

自然地,当我考虑如何把 API 从 .NET Core RC1 升级到 .NET Core 1.0 时想到的第一个求助的地方就是谷歌搜索。我是按照下面这两条非常全面的指导来进行升级的:

  • 从 DNX 迁移到 .NET Core CLI[3]
  • 从 ASP.NET 5 RC1 迁移到 ASP.NET Core 1.0[4]

当你迁移代码的时候,我建议仔细阅读这两篇指导,因为我在没有阅读第一篇指导的情况下又尝试浏览第二篇,结果感到非常迷惑和沮丧。

我不想描述细节上的改变因为你可以看 GitHub 上的提交[5]。这儿是我所作改变的总结:

  • 更新 global.json 和 project.json 上的版本号
  • 删除 project.json 上的废弃章节
  • 使用轻型 ControllerBase 而不是 Controller, 因为我不需要与 MVC 视图相关的方法(这是一个可选的改变)。
  • 从辅助方法中去掉 Http 前缀,比如:HttpNotFound -> NotFound
  • LogVerbose -> LogTrace
  • 名字空间改变: Microsoft.AspNetCore.*
  • 在 Startup 中使用 SetBasePath(没有它 appsettings.json 将不会被发现)
  • 通过 WebHostBuilder 来运行而不是通过 WebApplication.Run 来运行
  • 删除 Serilog(在写文章的时候,它不支持 .NET Core 1.0)

唯一令我真正头疼的事是需要移动 Serilog。我本可以实现自己的文件记录器,但是我删除了文件记录功能,因为我不想为了这次操作在这件事情上花费精力。

不幸的是,将有大量的第三方开发者扮演追赶 .NET Core 1.0 的角色,我非常同情他们,因为他们通常在休息时间还坚持工作但却依旧根本无法接近靠拢微软的可用资源。我建议阅读 Travis Illig 的文章 .NET Core 1.0 发布了,但 Autofac 在哪儿[6]?这是一篇关于第三方开发者观点的文章。

做了这些改变以后,我可以从 project.json 目录恢复、构建并运行 dotnet,可以看到 API 又像以前一样工作了。

通过 Docker 运行

在我写这篇文章的时候, Docker 只能够在 Linux 系统上工作。在 Windows[7] 系统和 OS X[8] 上有 beta 支持 Docker,但是它们都必须依赖于虚拟化技术,因此,我选择把 Ubuntu 14.04 当作虚拟机来运行。如果你还没有安装过 Docker,请按照指导[9]来安装。

我最近阅读了一些关于 Docker 的东西,但我直到现在还没有真正用它来干任何事。我假设读者还没有关于 Docker 的知识,因此我会解释我所使用的所有命令。

HELLO DOCKER

在 Ubuntu 上安装好 Docker 之后,我所进行的下一步就是按照 https://www.microsoft.com/net/core#docker 上的介绍来开始运行 .NET Core 和 Docker。

首先启动一个已安装有 .NET Core 的容器。

  1. docker run -it microsoft/dotnet:latest

-it 选项表示交互,所以你执行这条命令之后,你就处于容器之内了,可以如你所希望的那样执行任何 bash 命令。

然后我们可以执行下面这五条命令来在 Docker 内部运行起来微软 .NET Core 控制台应用程序示例。

  1. mkdir hwapp
  2. cd hwapp
  3. dotnet new
  4. dotnet restore
  5. dotnet run

你可以通过运行 exit 来离开容器,然后运行 Docker ps -a 命令,这会显示你创建的那个已经退出的容器。你可以通过上运行命令 Docker rm <container_name> 来清除容器。

挂载源代码

我的下一步骤是使用和上面相同的 microsoft/dotnet 镜像,但是将为我们的应用程序以数据卷[10]的方式挂载上源代码。

首先签出有相关提交的仓库:

  1. git clone https://github.com/niksoper/aspnet5-books.git
  2. cd aspnet5-books/src/MvcLibrary
  3. git checkout dotnet-core-1.0

现在启动一个容器来运行 .NET Core 1.0,并将源代码放在 /book 下。注意更改 /path/to/repo 这部分文件来匹配你的电脑:

  1. docker run -it \
  2. -v /path/to/repo/aspnet5-books/src/MvcLibrary:/books \
  3. microsoft/dotnet:latest

现在你可以在容器中运行应用程序了!

  1. cd /books
  2. dotnet restore
  3. dotnet run

作为一个概念性展示这的确很棒,但是我们可不想每次运行一个程序都要考虑如何把源代码安装到容器里。

增加一个 DOCKERFILE

我的下一步骤是引入一个 Dockerfile,这可以让应用程序很容易在自己的容器内启动。

我的 Dockerfile 和 project.json 一样位于 src/MvcLibrary 目录下,看起来像下面这样:

  1. FROM microsoft/dotnet:latest
  2. # 为应用程序源代码创建目录
  3. RUN mkdir -p /usr/src/books
  4. WORKDIR /usr/src/books
  5. # 复制源代码并恢复依赖关系
  6. COPY . /usr/src/books
  7. RUN dotnet restore
  8. # 暴露端口并运行应用程序
  9. EXPOSE 5000
  10. CMD [ "dotnet", "run" ]

严格来说,RUN mkdir -p /usr/src/books 命令是不需要的,因为 COPY 会自动创建丢失的目录。

Docker 镜像是按层建立的,我们从包含 .NET Core 的镜像开始,添加另一个从源代码生成应用程序,然后运行这个应用程序的层。

添加了 Dockerfile 以后,我通过运行下面的命令来生成一个镜像,并使用生成的镜像启动一个容器(确保在和 Dockerfile 相同的目录下进行操作,并且你应该使用自己的用户名)。

  1. docker build -t niksoper/netcore-books .
  2. docker run -it niksoper/netcore-books

你应该看到程序能够和之前一样的运行,不过这一次我们不需要像之前那样安装源代码,因为源代码已经包含在 docker 镜像里面了。

暴露并发布端口

这个 API 并不是特别有用,除非我们需要从容器外面和它进行通信。 Docker 已经有了暴露和发布端口的概念,但这是两件完全不同的事。

据 Docker 官方文档[11]:

EXPOSE 指令通知 Docker 容器在运行时监听特定的网络端口。EXPOSE 指令不能够让容器的端口可被主机访问。要使可被访问,你必须通过 -p 标志来发布一个端口范围或者使用 -P 标志来发布所有暴露的端口

EXPOSE 指令只是将元数据添加到镜像上,所以你可以如文档中说的认为它是镜像消费者。从技术上讲,我本应该忽略 EXPOSE 5000 这行指令,因为我知道 API 正在监听的端口,但把它们留下很有用的,并且值得推荐。

在这个阶段,我想直接从主机访问这个 API ,因此我需要通过 -p 指令来发布这个端口,这将允许请求从主机上的端口 5000 转发到容器上的端口 5000,无论这个端口是不是之前通过 Dockerfile 暴露的。

  1. docker run -d -p 5000:5000 niksoper/netcore-books

通过 -d 指令告诉 docker 在分离模式下运行容器,因此我们不能看到它的输出,但是它依旧会运行并监听端口 5000。你可以通过 docker ps 来证实这件事。

因此,接下来我准备从主机向容器发起一个请求来庆祝一下:

  1. curl http://localhost:5000/api/books

它不工作。

重复进行相同 curl 请求,我看到了两个错误:要么是 curl: (56) Recv failure: Connection reset by peer,要么是 curl: (52) Empty reply from server

我返回去看 docker run 的文档[12],然后再次检查我所使用的 -p 选项以及 Dockerfile 中的 EXPOSE指令是否正确。我没有发现任何问题,这让我开始有些沮丧。

重新振作起来以后,我决定去咨询当地的一个 Scott Logic DevOps 大师 - Dave Wybourn(也在这篇 Docker Swarm 的文章[13]里提到过),他的团队也曾遇到这个实际问题。这个问题是我没有配置过 Kestral[14],这是一个全新的轻量级、跨平台 web 服务器,用于 .NET Core 。

默认情况下, Kestrel 会监听 http://localhost:5000。但问题是,这儿的 localhost 是一个回路接口。

据维基百科[15]:

在计算机网络中,localhost 是一个代表本机的主机名。本地主机可以通过网络回路接口访问在主机上运行的网络服务。通过使用回路接口可以绕过任何硬件网络接口。

时间: 2024-12-25 05:46:36

新手指南:通过 Docker 在 Linux 上托管 .NET Core的相关文章

使用 Docker 在 Linux 上托管 ASP.NET Core 应用程序

说在前面 在阅读本文之前,您必须对 Docker 的中涉及的基本概念以及常见命令有一定了解,本文侧重实战,不会对相关概念详述. 同时请确保您本地开发机器已完成如下安装: Docker 18.06 或更高版本的 Docker 客户端 .NET Core SDK 2.2 或更高版本 Visual Studio Code 代码编辑器,以及 C# 语法插件 1.17.1 或更高版本 注:本文实验环境是 Ubuntu 18.04 LTS.如果您的机器是 Window,也可以把 Docker 装在虚拟机或服

Docker在Linux上运行NetCore系列(一)配置运行DotNetCore控制台

转发请注明此文章作者与路径,请尊重原著,违者必究. 本篇文章操作系统信息 Linux:ubuntu 16.04.3 amd64 查看NetCore支持的Linux系统 NetCore不是支持Linux的所有系统,只支持部分,所以在Linux上安装NetCore之前要查看系统与版本是否支持NetCore. 查看NetCore2.0以上各个版本在Linux支持的系统及版本: https://github.com/dotnet/core/blob/master/release-notes/2.0/2.

Docker在Linux上运行NetCore系列(五)更新应用程序

原文:Docker在Linux上运行NetCore系列(五)更新应用程序 转发请注明此文章作者与路径,请尊重原著,违者必究. 本篇文章与其它系列文章不同,为了方便测试,新建了一个ASP.Net Core视图应用. 备注:下面说的应用,只是在容器中运行的应用程序. 查看现在运行的应用 容器中已经运行了一个应用testaspnetcoredockerlinuxname,版本是1.0.我们下面查看一下已经在运行中的应用. 输入命令[sudo docker ps]可以看到运行中的容器. 红色线的就是我们

Nginx知多少系列之(五)Linux下托管.NET Core项目

目录 1.前言 2.安装 3.配置文件详解 4.工作原理 5.Linux下托管.NET Core项目 6.Linux下.NET Core项目负载均衡 7.Linux下.NET Core项目Nginx+Keepalived高可用(主从模式) 8.Linux下.NET Core项目Nginx+Keepalived高可用(双主模式) 9.Linux下.NET Core项目LVS+Keepalived+Nginx高可用集群 10.构建静态服务器 11.日志分析 12.优化策略 13.总结 在这里我就不介

docker在linux上的安装

本文链接:https://blog.csdn.net/zhangbeizhen18/article/details/85239758 报错信息: Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details. 使用命令: sy

idea docker 连接 linux 上的 docker

安装插件 Docker插件,首先需要在你的IDEA中安装Docker插件,定位到File-Setting-Plugins后搜索Docker Integration安装 配置Docker服务器,在IDEA中定位到File-Setting-build,Execution,Deployment-Docker 运行 idea 项目到 远程 linux docker 上 编写 Dockerfile 文件 添加 maven 依赖 <build> <finalName>${project.art

Docker在Linux上运行NetCore系列(四)使用私有Nuget与多个本地包引用运行ASPNetCore

转发请注明此文章作者与路径,请尊重原著,违者必究. 本篇文章演示了使用Dockerfile在Linux(ubuntu16.04)系统上构建ASPNetCore应用,并且在一个解决方案中存在多个项目之间的引用.还会使用到私有Nuget包的引用. 构建项目 为了演示更加全面,这里按照简单的领域驱动模式建立了几个项目. Web端为:TestWebDockerOnLinux.使用swagger对外提供API,并且包含了Dockerfile文件. 基础设施层:TestWebDockerOnLinux.Co

Docker在Linux上运行NetCore系列(二)把本地编译好的镜像发布到线上阿里云仓库

转发请注明此文章作者与路径,请尊重原著,违者必究. 开始 本篇文章结束在本地创建完成镜像后,发布到公共仓库.这里的仓库是阿里云的仓库. 流程是:进入阿里云Docker仓库控制台->新建镜像仓库->按照阿里云教程上传本地镜像到云仓库->到阿里云控制台查看仓库,存在则成功. 进入阿里云仓库 这里使用的是阿里云的存储,可以注册阿里云账号,并且进入仓储,获取私人的存储地址. 设置阿里云仓储,首先进入https://cr.console.aliyun.com/cn-shenzhen/reposit

Docker在Linux上 基本使用

安装环境(Linux) 查看centos版本: uname -r Docker 要求CentOS 系统的内核版本高于 3.08 升级软件包及内核:yum update 安装Docker 安装: yum install docker 启动 docker: systemctl start docker 查询docker版本: docker -v 将docker服务设为开机启动:systemctl enable docker 停止docker: systemctl stop docker 常用操作: