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

已完成

在本练习中,你将使用 .NET SDK 和 Docker 创建微服务终结点并将其容器化。

注释

可以在预安装 Docker.NET SDK 的 GitHub Codespaces 实例中完成此练习。 在自己的开发环境中使用这些工具和技术时,请确保已安装这些必备组件。

开放开发环境

可以选择使用托管练习的 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 publish 创建产品后端镜像

最新的 .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
    • 将本地 产品 目录中的所有内容复制到映像。
    • 在项目上调用 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。
    • 将创建生成映像的应用目录中的所有内容复制到此映像的应用目录中。
    • 将此图像的入口点设置为dotnet,并将Products.dll作为参数传递。

创建 Docker 映像

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

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

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

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

  2. 大量输出后,将生成映像。 输入 docker images 会显示代码空间中所有图像的列表,包括 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 和必须手动为应用中每个微服务创建 Dockerfiles 之间的差异。

运行容器并测试服务

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

  1. 若要 从新产品映像 创建和运行容器并在端口 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"
        },
        ...
    ]