练习 - 为 .NET 微服务生成容器映像

已完成

在此练习中,你将了解如何创建微服务终结点,并使用 .NET SDK 和 Docker 对其进行容器化。

注意

可在预安装了 Docker.NET SDK 的 GitHub Codespace 实例中完成此练习。 当你在自己的开发环境中使用这些工具和技术时,请确保已安装这些先决条件。

打开开发环境

可以选择使用托管练习的 GitHub codespace,或者在 Visual Studio Code 中本地完成练习。

若要使用 codespace,请使用此 Codespace 创建链接创建预配置的 GitHub Codespace

GitHub 需要几分钟时间来创建和配置 codespace。 完成此过程后,会显示练习的代码文件。 用于本模块其余部分的代码位于 /dotnet-docker 目录中

要使用 Visual Studio Code,请将 https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative 存储库克隆到本地计算机。 然后:

  1. 安装任何系统要求以在 Visual Studio Code 中运行开发容器。
  2. 确保 Docker 正在运行。
  3. 在新的 Visual Studio Code 窗口中,打开克隆存储库的文件夹
  4. Ctrl+Shift+P,打开命令面板。
  5. 搜索:>开发容器:在容器中重新生成和重新打开
  6. 从下拉列表中选择“eShopLite - dotnet-docker”。 Visual Studio Code 会在本地创建你的开发容器。

使用 .NET 发布创建产品后端映像

最新的 .NET 8 版本改进了对容器化的支持。 可以使用 dotnet publish 命令为微服务创建 Docker 映像。 该命令创建一个在 app 帐户下运行服务的无根容器映像。 运行无根容器有助于提高安全性和性能。 该命令知道如何通过检查项目文件中的设置来选取最佳基础映像。

  1. 要为所有 eShopLite 服务创建映像,请转到“终端”选项卡并运行以下命令:

    cd ./dotnet-docker 
     dotnet publish /p:PublishProfile=DefaultContainer
    

    你会看到类似于以下消息的输出:

    DataEntities -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/DataEntities/bin/Release/net8.0/publish/
    Products -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Products/bin/Release/net8.0/Products.dll
    Products -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Products/bin/Release/net8.0/publish/
    Store -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Store/bin/Release/net8.0/Store.dll
    Store -> /workspaces/mslearn-dotnet-cloudnative/dotnet-docker/Store/bin/Release/net8.0/publish/
    Building image 'store' with tags 'latest' on top of base image 'mcr.microsoft.com/dotnet/aspnet:8.0'.
    Building image 'products' with tags 'latest' on top of base image 'mcr.microsoft.com/dotnet/aspnet:8.0'.
    Pushed image 'store:latest' to local registry via 'docker'.
    Pushed image 'products:latest' to local registry via 'docker'.
    

    该命令读取解决方案文件,确定了其包含三个项目,生成了这些项目,并为应用商店和产品项目创建了映像。 映像以项目命名,并发布到本地 Docker 注册表中。

  2. 检查映像是否在 docker 中可用:

    docker images
    

    你会看到类似于以下消息的输出:

    REPOSITORY                          TAG       IMAGE ID       CREATED              SIZE
    products                            latest    63614e340088   About a minute ago   293MB
    store                               latest    e9458c3abdb1   About a minute ago   218MB
    

使用 Dockerfile 创建产品后端映像

如果希望更好地控制映像的生成方式,可以使用 Dockerfile 为产品 Web 服务创建映像。

  1. 在“资源管理器”窗格中,在 ./dotnet-docker/Products 中创建名为 Dockerfile 的文件。 文件为空。

  2. 输入以下代码:

    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    
    WORKDIR /DataEntities
    COPY "DataEntities/DataEntities.csproj" .
    RUN dotnet restore
    COPY "DataEntities" .
    RUN dotnet publish -c release -o /app
    

    完成以下步骤后,此代码可在 Products docker 映像中设置 DataEntities 库:

    • 拉取 mcr.microsoft.com/dotnet/sdk:8.0 映像并将其命名为 build
    • 将映像中的工作目录设置为 /DataEntities
    • 将在本地找到的名为 DataEntities.csproj 的文件复制到你创建的 /DataEntities 目录中。
    • 在项目上调用 dotnet restore
    • 将本地 DataEntities 目录中的所有内容复制到映像。
    • 在项目上调用 dotnet publish
  3. 现在,在最后一行的正下方输入以下内容:

     WORKDIR /src
     COPY Products/Products.csproj .
     RUN dotnet restore
     COPY Products .
     RUN dotnet publish -c release -o /app
    

    调用此代码时,它将按顺序执行以下步骤:

    • 将映像中的工作目录设置为 /src
    • 将在本地找到的名为 Products.csproj 的文件复制到你创建的 /src 目录中。
    • 在项目上调用 dotnet restore
    • 将本地 Products 目录中的所有内容复制到映像中。
    • 在项目上调用 dotnet publish
  4. 现在,在最后一行的正下方输入以下内容:

     FROM mcr.microsoft.com/dotnet/aspnet:8.0
     WORKDIR /app
     EXPOSE 80
     EXPOSE 443
     COPY --from=build /app .
     ENTRYPOINT ["dotnet", "Products.dll"]
    

    调用此代码时,它将按顺序执行以下步骤:

    • 拉取 mcr.microsoft.com/dotnet/aspnet:8.0 映像。
    • 将映像中的工作目录设置为 /app
    • 公开端口 80 和 443。
    • 将你创建的 build 映像的 app 目录中的所有内容复制到此映像的 app 目录中。
    • 将此映像的入口点设置为 dotnet,并将 Products.dll 作为参数传递。

创建 Docker 映像

完成 Dockerfile 后,下一步是使用它来创建 Docker 映像:

  1. 要为 Products 后端服务创建映像,请转到“终端”选项卡并运行以下命令:

    cd ./dotnet-docker 
     docker build -t productsbackend:latest -f Products/Dockerfile .
    

    这会在当前目录中的 Dockerfile 中运行命令,并将标记 productsbackend 应用到生成的映像。

  2. 大量输出后,将生成映像。 输入 docker images 后会显示你的 codespace 中所有映像的列表,包括 productsbackend。 另一个映像是 codespace 本身的映像。

    你会看到类似于以下消息的输出:

    REPOSITORY                          TAG       IMAGE ID       CREATED              SIZE
    products                            latest    63614e340088   10 minutes ago       293MB
    store                               latest    e9458c3abdb1   10 minutes ago       218MB
    productsbackend                     latest   190783f7e06f    About a minute ago   293MB
    

考虑使用 dotnet publish 与必须为应用中的每个微服务手动创建 Dockerfile 之间的区别

运行容器并测试服务

现在可以使用该映像来运行和托管 Products 服务。

  1. 要从新的 products 映像创建和运行容器并在端口 32001 上公开服务,请运行以下命令:

    docker run -it --rm -p 32001:8080  products
    

    或者,如果要运行使用 Dockerfile 创建的映像,请运行:

    docker run -it --rm -p 32001:8080 productsbackend
    
  2. 要测试服务,请切换到“端口”选项卡,然后在“后端”端口的本地地址右侧选择地球图标。 浏览器会在该地址打开一个新选项卡。

    屏幕截图显示如何连接到后端产品服务。

  3. 要查询某些产品,请向地址追加 /api/product,然后按 Enter。 你应会看到以 JSON 格式列出的一些产品信息。

    [
        {
            "id": 1,
            "name": "Solar Powered Flashlight",
            "description": "A fantastic product for outdoor enthusiasts",
            "price": 19.99,
            "imageUrl": "product1.png"
        },
        {
            "id": 2,
            "name": "Hiking Poles",
            "description": "Ideal for camping and hiking trips",
            "price": 24.99,
            "imageUrl": "product2.png"
        },
        {
            "id": 3,
            "name": "Outdoor Rain Jacket",
            "description": "This product will keep you warm and dry in all weathers",
            "price": 49.99,
            "imageUrl": "product3.png"
        },
        ...
    ]