API 从开发到生产 - 第 1 部分 - Docker
系列介绍
欢迎来到本系列博客文章,我们将从最基本的 .NET 5 C# Web API 示例入手,逐步讲解如何运用左移思维将项目从开发阶段迁移到生产阶段。我们将使用Azure、Docker、GitHub和GitHub Actions进行持续集成/持续交付 (CI/CD) 部署,并使用Pulumi实现基础设施即代码 (IaC) 。
这将是一个篇幅很长的多集系列节目,几乎涵盖所有内容……我希望如此!
我们的目标是打造一个遵循现代实践的 API,包括采用左移理念将所有内容都作为代码来实现,涵盖测试、安全和基础设施;以便工程团队能够拥有更高程度的自主权。
我们将使用 PaaS 服务在 Microsoft Azure 上托管我们的服务。您可能会想,该如何实现呢?难道我们一定要用 Kubernetes 吗?答案是否定的。在全面使用 Kubernetes 之前,还有其他一些不错的过渡方案。Azure 中的 AppService 支持容器(当然还有其他产品,例如 ACI)。这是一个非常棒的产品,熟悉“标准”AppService 的用户都知道它的优势,例如 SSL、可扩展性等等。如果将 AppService 与容器的优势结合起来,它就成为了迈向容器化工作负载的良好跳板;之后,您可以再过渡到 Kubernetes,例如 AKS(Azure Kubernetes 服务)。
这是一段从开发到生产的实践性🤲之旅。
太长不看
Visual Studio Code 是一款优秀的编辑器,它拥有丰富的扩展功能,可以极大地简化 Docker 等工具的使用。我们使用 `dotnet new` 创建 C# 项目,生成 Dockerfile,稍作修改,然后构建、运行并测试,确保项目正常运行。我们还会学习一些 .NET CLI 和 Docker CLI 的基本命令。
GitHub 仓库
peteking / Samples.WeatherForecast-Part-1
本仓库是 dev.to 网站上“API 从开发到生产 - 第 1 部分”系列博客文章的一部分。基于标准的 .NET 标准天气 API 示例。
为什么选择 Docker?
稳定且隔离的环境
借助容器,开发者可以创建与其他应用程序隔离的可预测环境。无论应用程序部署在何处,所有内容都保持一致,这极大地提高了生产力:减少了调试时间,从而有更多时间为用户推出新功能。
成本效益高,部署速度快
基于 Docker 的容器以将部署时间缩短至几秒而闻名。无论从哪个角度来看,这都是一项令人印象深刻的成就。传统上,诸如配置、启动和运行硬件等工作需要数天甚至更长时间。此外,还会面临巨大的开销和额外的工作量。当每个进程都被放入容器中时,它就可以与其他新应用程序共享。部署过程变得迅速,您基本上可以立即投入使用。
机动性——能够随心所欲地奔跑
Docker 镜像不受环境限制,这使得任何部署都具有一致性、可移动性(可移植性)和可扩展性。容器的另一个优势在于,只要目标操作系统是 Windows、macOS、Linux、虚拟机、本地部署或公有云,容器就可以在任何地方运行,这对于开发和部署来说都是巨大的优势。Docker 镜像格式在容器领域的广泛普及也进一步推动了这一优势。包括亚马逊云服务 (AWS)、谷歌计算平台 (GCP) 和微软 Azure 在内的领先云服务提供商都已采用 Docker。此外,还有 Kubernetes 等强大的编排系统,以及 AWS ECS 或 Azure 容器实例等产品,它们在移动性方面也发挥了重要作用。
重复性和自动化
您正在使用可重复的基础设施和配置构建代码,这极大地加快了开发流程。值得一提的是,Docker 镜像通常很小。因此,您可以快速交付,并再次缩短新应用程序容器的部署时间。另一个优势是维护简便。当应用程序容器化后,它与其他运行在同一系统中的应用程序隔离。换句话说,应用程序之间不会相互干扰,应用程序维护也变得更加容易。这有利于自动化;重复操作越快,出错就越少,您就越能专注于业务或应用程序的核心价值。
测试、回滚和部署
正如我们所说,Docker 环境从始至终都保持着更高的一致性。Docker 镜像易于版本控制,因此在需要时可以轻松回滚。如果当前镜像版本出现问题,只需回滚到旧版本即可。整个过程意味着您正在创建持续集成和持续部署 (CI/CD) 的理想环境。Docker 容器内部会保留所有配置和依赖项。现在,您可以快速轻松地检查差异。
灵活性
如果在产品发布周期内需要进行升级,您可以轻松地对 Docker 容器进行必要的更改,进行测试,然后部署新容器。这种灵活性是使用 Docker 的另一项关键优势。Docker 真正实现了构建、测试和发布可跨多个服务器部署的镜像。即使有新的安全补丁可用,流程也保持不变。您可以应用补丁、进行测试,然后将其发布到生产环境。此外,Docker 还允许您快速启动和停止服务或应用程序,这在云环境中尤其有用。
协作、模块化和可扩展性
Docker 容器化方法允许您对应用程序进行分段,从而可以在不关闭整个应用程序的情况下进行刷新、清理和修复。此外,借助 Docker,您可以构建由多个小型进程组成的应用程序架构,这些进程通过 API 相互通信。开发人员可以在此基础上共享和协作,快速解决任何潜在问题。至此,开发周期完成,所有问题都得到解决,无需进行大规模的重构——这极其经济高效且节省时间。
参见参考文献[1]
要求
-
Visual Studio Code - https://code.visualstudio.com/download
-
WSL 2(仅限 Windows 10) - https://docs.microsoft.com/en-us/windows/wsl/install-win10
我使用的是 Windows 10 系统,对于其他操作系统,例如 MacOS 和 Linux,会有一些细微的差别,这里没有提及。
VS Code 扩展
-
C# - https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp
-
.gitignore 文件生成器 - https://marketplace.visualstudio.com/items?itemName=piotrpalarz.vscode-gitignore-generator
-
Docker - https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker
项目初始创建
-
在 Git 中创建仓库 → Samples.WeatherForecast
-
创建“src”目录
-
在“src”中执行:
dotnet new webapi -n Samples.WeatherForecast.Api
至此,你应该已经拥有一个漂亮的 .net 5 Web API 了。
只需输入一个简单命令,即可在终端中启动 VS Code。
code .
.指的是文件路径。在本例中,指的是当前目录。您可以指定其他位置,或者直接在终端输入代码,这将打开上次打开的工作区。
如果系统提示安装 C# 扩展,请务必选择“是”;这将创建一个 .vscode 文件夹。
GitIgnore
我猜你可能还没有创建.gitignore.gitignore文件,VS Code中有一个非常有用的扩展程序叫做“.gitignore Generator”。我建议你安装它。
在 VS Code 中 - 命令面板 - 窗口 (Ctrl+Shift+P) → .gitignore 生成器。
对于这个项目,我们最好从列表中选择 4 个项目:
- Visual Studio Code
- Visual Studio
- .NET核心
- C#
文件生成后.gitignore,应该类似于下图:
Dockerfile
Docker 扩展的好处在于它可以为你做很多事情,它非常节省时间;是 Docker 的真正好帮手。
首先,我们可以生成 Dockerfile,它还可以生成 docker-compose 文件!
VS Code - 命令面板 - 窗口 (Ctrl+Shift+P) → Docker:将 Docker 文件添加到工作区
选择“是”以包含 docker-compose 文件,我们稍后会用到它们。
完成以上步骤后,您应该会得到以下所有文件:
- Dockerfile
- docker-compose.debug.yml
- docker-compose.yml
- .dockerignore

如果您像我一样在目录中执行此操作src/Samples.WeatherForecast.API,这些文件就会在那里创建。但是,我们应该将它们移动……
最佳实践是将 Dockerfile 等文件放在仓库的根目录中。
让我们把它们移到根目录,如果你在根目录下打开 VS Code,它应该看起来像下面这样,我们也应该移动忽略文件;两者.gitignore都要移动.dockerignore!
现在,我们需要修改 Dockerfile,为什么呢?因为我们移动了它的位置,而且它现在有点笨拙。所以我们快速修改一下,让它稍微好用一些,然后构建镜像。
WORKDIR我们可以使用COPY . .`--copy` 命令将所有内容从源复制到目标,从而稍微简化文件。
此外,仔细观察你会发现,它先执行了一次“a” ,然后又执行dotnet restore了一次“b” dotnet build,这意味着它会检查是否需要再次恢复。作为这项初始优化的一部分(后续还会有更多优化),我们可以利用这个--no-restore选项。
最终的 Dockerfile 应该如下所示 - 如果您此时已经发现还有进一步的优化空间,请不要担心,我们将在本系列的后续文章中进行许多优化。
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /app
COPY . .
WORKDIR /app/src/Samples.WeatherForecast.Api
RUN dotnet restore "Samples.WeatherForecast.Api.csproj"
RUN dotnet build "Samples.WeatherForecast.Api.csproj" -c Release -o /app/build --no-restore
FROM build AS publish
RUN dotnet publish "Samples.WeatherForecast.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Samples.WeatherForecast.Api.dll"]
我觉得我们现在可以出发了!
如果你还没有这样做,现在正是将代码提交到 Git 仓库的好时机。你可以直接在命令行中使用 Git,也可以使用 VS Code 扩展,甚至可以使用 GitHub Desktop;选择权在你。
让我们构建图像
构建 Docker 镜像所需的命令是:
docker build -t samples-weatherforecast:latest .
请注意,您需要在 Dockerfile 所在的根目录下运行此命令,否则它将无法找到 Dockerfile。-f如有需要,您可以选择指定 Dockerfile 的位置。
如果你已经按照步骤操作到这里,那么一切应该都能顺利完成;如果没有,请仔细检查步骤,这并不需要很长时间。
Docker镜像已构建完成——接下来该做什么?
我们已经构建了镜像,那么接下来我们该做什么呢?让我们列出本地存储库中的镜像,看看我们那里有什么。
在终端中输入以下命令:
docker image ls
有一张名为 latest 的图片samples-weatherforecast,它有一个图片ID,我们甚至可以看到它的大小:210MB -不用担心这个大小,我们稍后会进一步优化它。
开始吧!
我们可以看到镜像文件,一切正常,那么让我们运行一下,确保它能正常工作。我们可以通过几种方式来实现,我个人比较喜欢使用终端和下面的命令。不过,Docker Desktop 最近有了很大的改进,变得更加用户友好,尤其适合初次使用的用户,或者那些喜欢使用图形界面、或者不想输入太多命令的用户。
docker run -it --rm -p 8080:80 samples-weatherforecast:latest
您可以看到我们在命令中使用了一些选项,我们可以逐一解释,以便您了解我们为什么使用它们。
-it实际上有两种选择,i和t。
-i是交互模式;所以我们的终端会等待。
-t是分配一个伪TTY
--rm命令结束后,会自动删除容器镜像。
-p指定端口配置,格式为host:container
您随时可以输入命令
--help来查看有哪些命令可用。
如果您的容器和运行命令一切正常,您应该会看到类似下图的屏幕:
现在我们已经有了一个可以运行的容器,我们可以做很多事情来检查容器等等,我们可以在另一篇博客文章中详细介绍。
别忘了 Docker Desktop 有全新的用户界面,请体验一下,非常棒。
发送请求
容器已经运行,就等着处理请求了,如果不发送一个请求来验证它是否真的有效,那就太可惜了。
对我来说,我最好的朋友就是邮递员(Postman),如果你没听说过它,我真想知道你这十年都去哪儿了!总之,如果你发送类似下面的请求,你的容器应该会回复并返回天气预报。
我们完工了! 🤥
很遗憾,不行😟,我们仍然可以做很多事情来优化容器的大小,而且还有很多 Docker 命令可以帮助你更好地完成日常工程工作。这意味着更多的工作😁,但是,我们会一步一步地进行实践学习,通过阅读本系列博客,这些知识会牢牢地印在你的脑海里🧠
我们学到了什么?
我们学习了如何创建一个全新的 .NET 5 Web API,确保.gitignore文件有效,以及 Docker 的基本知识。我们构建并运行了镜像,并进行了测试,确保其运行符合预期。
此外
Docker 的重要性不容小觑。自 2016 年以来,容器生态系统发生了翻天覆地的变化,我们见证了 Docker Swarm 在容器大战中兴衰更替(如果你还不知道的话,Kubernetes 最终胜出)。尽管 Docker Enterprise 被 Mirantis 收购,但 Docker Swarm 仍然在其企业容器云解决方案中蓬勃发展,此外,Mirantis 还提供安全可靠、零停机时间的托管 Kubernetes 产品。
更不用说还有其他的编排器了,举个例子,还有 Hashicorp 的 Nomad,甚至还有其他类似 Docker 的容器,比如 Podman。
无论你实际构建的是什么,容器的优势都显而易见且至关重要,即使你混合使用了 IaaS 和 PaaS。
接下来
本系列第二部分将讲述:
- 优化 Docker 镜像大小
更多信息
- https://www.azure.com
- https://dotnet.microsoft.com/
- https://www.github.com
- https://www.docker.com
- https://www.docker.com/why-docker
- https://www.pulumi.com
参考
[1] - https://hentsu.com/docker-containers-top-7-benefits/
文章来源:https://dev.to/peteking/api-s-from-dev-to-Production-428i







