将 .NET 微服务部署到 Kubernetes

什么是业务流程协调程序?

微服务的分离式设计与容器的原子性结合,使你可以通过部署更多容器实例来横向扩展应用以及响应增加的需求,并在需求减少时横向缩减。 在复杂的解决方案中,部署、更新、监视和删除容器的过程会带来一些挑战。

容器管理

容器管理是组织、添加、删除或更新大量容器的过程。

Contoso Pizza Company 的网站包含多个微服务,负责处理缓存、数据处理和购物车等任务。 其中每一项任务均托管在一个容器中,可以单独部署、更新和缩放。

如果增加购物车容器实例的数量,并需要部署新版本,必须更新该容器的每个实例。

容器管理可以帮助你处理这些任务。

容器业务流程

容器业务流程协调程序是自动部署和管理容器化应用的系统。 例如,业务流程协调程序可以动态响应环境中的变化,以增加或减少部署的托管应用实例。 或者,如果发布了新版本的服务,则它可以确保所有已部署的容器实例得到更新。

Kubernetes

Kubernetes 是一种可移植且可扩展的开放源代码平台,用于管理和编排容器化工作负载。 Kubernetes 不考虑复杂的容器管理任务,并提供声明性配置,以便在不同的计算环境中协调容器。 此业务流程平台提供与平台即服务 (PaaS) 或基础结构即服务 (IaaS) 产品/服务相同的易用性和灵活性。

优点

使用 Kubernetes 的优势基于多项任务的抽象。

这些任务包括:

  • 容器的自行修复。 例如,重启失败的容器或替换容器。
  • 根据需要动态地纵向扩展或纵向缩减部署的容器计数。
  • 容器的自动滚动更新和回滚。
  • 管理存储。
  • 管理网络流量。
  • 存储并管理敏感信息,如用户名和密码。

由于 Kubernetes 是一个用来协调容器化工作负荷的工具,你可以将 .NET 微服务部署到容器中,也可以使用 Kubernetes 来协调 .NET 微服务。 本模块的其余部分将介绍这些内容。

练习 – 将微服务映像推送到 Docker Hub

为了使 Kubernetes 能够创建容器映像,它需要一个位置来获取映像。 Docker Hub 是上传 Docker 映像的中心位置。 许多产品(包括 Kubernetes)都可以基于 Docker Hub 中的映像创建容器。

重要

要完成此练习,你需要使用 Docker Desktop 应用程序、Docker Hub 帐户和文本编辑器(如 Visual Studio Code)。

可以在此处下载 Docker Desktop

按照此处的说明注册 Docker Hub 帐户

检索 Contoso Pizza Shop 微服务容器映像

已为你创建 Contoso Pizza Shop 的代码和用于构建容器映像的 Dockerfile。 克隆 GitHub 中的存储库以检索代码。

打开命令提示符或终端窗口。

打开你需要将代码下载到的根目录。 代码将下载到该位置的新文件夹中。

运行以下命令,下载或克隆示例存储库。

git clone https://github.com/microsoftdocs/mslearn-dotnet-kubernetes

代码将下载到名为“mslearn-dotnet-kubernetes”的新文件夹中。

通过在本地创建容器来验证 Docker 映像

Contoso Pizza Shop 项目中有 2 个容器。 在将映像推送到 Docker Hub 之前,我们先使用它们在本地创建容器。 创建并运行容器后,我们将能够浏览 Contoso Pizza Company 网站并验证微服务是否正常运行。

按照以下步骤从下载的 Docker 文件创建并运行 Docker 容器。

确保 Docker Desktop 正在运行。

打开命令提示符,转到“mslearn-dotnet-kubernetes”目录。

运行以下命令以生成容器。

docker-compose build

生成容器可能需要一段时间。

运行以下命令以运行应用并附加容器。

docker-compose up

操作完成后,在浏览器选项卡中输入 http://localhost:5902 以查看 Contoso Pizza Shop 菜单。

登录到 Docker Hub

将映像上传到 Docker Hub 的下一步是登录 Docker Hub。 在命令提示符处,输入下列内容:

docker login

重要

使用你在创建 Docker 帐户时提供的相同用户名和密码。 如果需要,可以访问 Docker Hub 网站来重置密码。

将映像上传到 Docker Hub

输入以下代码以重新标记或重命名在 Docker 用户名下创建的 Docker 映像。

docker tag pizzafrontend [YOUR DOCKER USER NAME]/pizzafrontend
docker tag pizzabackend [YOUR DOCKER USER NAME]/pizzabackend

最后,将 Docker 映像上传或推送到 Docker Hub。

docker push [YOUR DOCKER USER NAME]/pizzafrontend
docker push [YOUR DOCKER USER NAME]/pizzabackend

在此练习中,你克隆了 GitHub 中的 Contoso Pizza Shop 代码,使用了该代码中包含的 Dockerfile 创建两个 Docker 映像和容器,然后将这些映像推送到 Docker Hub。

现在,可以使用 Kubernetes 来管理 Contoso Pizza Company 的微服务的部署。

练习 – 将微服务容器部署到 Kubernetes

Kubernetes 会为你运行容器。 你需要通过 YAML 文件描述希望 Kubernetes 执行的操作。 本练习将逐步指导你完成文件创建过程,这样你就可以在 Kubernetes 上部署和运行后端服务了。

重要

在继续操作之前,必须确保已安装 Kubernetes 实现。 我们将使用 Docker Desktop 中包含的实现。 请按照 Docker 中的这些说明启用它。

为后端服务创建部署文件

你可以创建一个文件,使用 YAML 文件管理将容器部署到 Kubernetes 的过程。 我们将创建一个文件来部署后端服务。

打开文本编辑器(例如 Visual Studio Code),并切换到之前将项目文件克隆到的目录。

在名为“backend-deploy.yml”的项目的根目录下,创建一个新文件。

将以下文本复制到该文件,然后保存文件。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pizzabackend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: pizzabackend
    spec:
      containers:
      - name: pizzabackend
        image: [YOUR DOCKER USER NAME]/pizzabackend:latest
        ports:
        - containerPort: 80
        env:
        - name: ASPNETCORE_URLS
          value: http://*:80
  selector:
    matchLabels:
      app: pizzabackend
---
apiVersion: v1
kind: Service
metadata:
  name: pizzabackend
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: pizzabackend

将占位符 [YOUR DOCKER USER NAME] 替换为实际的 Docker 用户名。

此文件的作用如下。

第一部分定义了将部署到 Kubernetes 中的容器的部署规范。 它指定了将会有一个副本,在哪里可以找到容器映像,在容器上打开哪些端口,并设置了一些环境变量。 第一部分还定义了可以引用容器和规范的标签和名称。

然后,第二部分定义了容器将作为 Kubernetes ClusterIP 运行。 对于本模块,你无需了解 ClusterIP 的所有细节,但需要知道此类服务不会公开外部 IP 地址。 只能从在同一 Kubernetes 群集中运行的其他服务访问它。

部署并运行后端微服务

接下来,我们来部署并运行微服务。

打开命令提示符,转到你创建了“backend-deploy.yml”文件的同一目录。

运行以下命令。

kubectl apply -f backend-deploy.yml

此命令将指示 Kubernetes 运行已创建的文件。 它将从 Docker Hub 下载映像并创建容器。

kubectl apply 命令将快速返回。 但容器可能需要一段时间才能创建完成。 若要查看进度,请使用以下代码。

kubectl get pods

在生成的输出中,你将在“名称”列下看到一个包含“pizzabackend”后跟一串随机字符的行。 一切准备就绪后,“就绪”列下会显示“1/1”,“状态”列下会显示“正在运行”。

浏览到 http://localhost/pizzainfo。 它将返回“HTTP 404 未找到”消息。 出现此错误是因为无法从外部访问披萨后端服务。

创建部署文件并运行前端服务

与后端服务类似,我们也需要一个前端的部署文件。

创建一个名为“frontend-deploy.yml”的新文件

将以下代码粘贴到文件中。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pizzafrontend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: pizzafrontend
    spec:
      containers:
      - name: pizzafrontend
        image: [YOUR DOCKER USER NAME]/pizzafrontend:latest
        ports:
        - containerPort: 80
        env:
        - name: ASPNETCORE_URLS
          value: http://*:80
        - name: backendUrl
          value: http://pizzabackend
  selector:
    matchLabels:
      app: pizzafrontend
---
apiVersion: v1
kind: Service
metadata:
  name: pizzafrontend
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: pizzafrontend

将占位符 [YOUR DOCKER USERNAME] 替换为实际的 Docker 用户名。你会注意到,此文件类似于我们为后端微服务创建的文件。 但有三点不同之处:

我们指定了一个不同的容器在部署的 spec.template.spec.containers.image 值下运行。

spec.template.spec.containers.env 部分下有一个新的环境变量。 “pizzafrontend”应用程序中的代码调用后端,但由于我们还没有指定一个完全限定的域名,也不知道后端微服务的 IP 地址,因此我们使用在 Deployment 的 metadata.name 节点下指定的名称。 然后,Kubernetes 将处理其余部分。

在服务部分,我们为 spec.type 指定了 LoadBalancer 值。 并且端口 80 处于打开状态。 我们现在可以通过导航到 http://localhost 来浏览披萨前端。

通过以下命令将容器部署到 Kubernetes。

kubectl apply -f frontend-deploy.yml

同样,可以使用 kubectl get pods 来查看部署状态。 一旦“pizzafrontend”所在的行在“状态”列下显示“正在运行”,说明一切准备就绪。

成功部署容器后,浏览到 http://localhost 可以查看这两个正在运行的微服务。

在本练习中,你创建了一个部署文件,该文件准确描述了你希望容器在 Kubernetes 中的运行方式。 然后,你让 Kubernetes 从 Docker Hub 下载了映像并启动了容器。

练习 – 在 Kubernetes 中缩放容器实例

在一天中的某些时间,微服务可能会负载很大。 Kubernetes 通过为你添加额外的实例来轻松缩放微服务。

运行以下命令,将后端微服务缩放为五个实例。

kubectl scale --replicas=5 deployment/pizzabackend

我们需要指定“deployment/pizzabackend”,而不是只指定“pizzabackend”,因为我们将缩放披萨后端服务的整个 Kubernetes 部署,这将正确缩放各个 Pod 的实例。

要验证五个实例是否启动并正常运行,请运行以下命令。

kubectl get pods

启动所有实例后,你应能在输出中看到五个 Pod 实例(以单独的行表示)。 每行都以“pizzabacken”开头,后跟一个随机字符串。

要减少实例数,请运行以下命令。

kubectl scale --replicas=1 deployment/pizzabackend

练习 – 在 Kubernetes 中证明微服务的恢复能力

Kubernetes 的一大好处是支持声明性配置管理。 你在配置文件中定义的服务会不惜一切代价进行保留。

这意味着,如果出现故障,Kubernetes 将自动重启在发生故障之前运行的服务。

让我们通过删除披萨前端 Pod,然后验证 Kubernetes 是否已重启它,来看看此恢复能力如何发挥作用。

首先运行 kubectl get pods,并记下披萨前端 Pod 的名称(包括随机字符串)。 下面是一个示例输出:

username@computer-name % kubectl get pods

NAME                             READY   STATUS    RESTARTS   AGE
pizzabackend-7445bdb5c9-pnpk6    1/1     Running   0          31m
pizzafrontend-5b6cc765c4-hjpx4   1/1     Running   0          63m

现在,使用 kubectl delete 命令删除披萨前端 Pod。 你需要指定 Pod 的完整名称,包括随机字符串。

kubectl delete pod pizzafrontend-5b6cc765c4-hjpx4

你将立即收到一条消息,指示 Pod 已被删除。

由于 Kubernetes 将保持配置文件中声明的系统状态,因此它将立即启动另一个 Pod 实例。 你可以通过运行 kubectl get pods 来进行验证。

username@computer-name % kubectl get pods

NAME                             READY   STATUS    RESTARTS   AGE
pizzabackend-7445bdb5c9-pnpk6    1/1     Running   0          31m
pizzafrontend-5b6cc765c4-vwmv8   1/1     Running   0          7s

请注意,pizzafrontend 名称后面的随机字符串已发生变化。 指示 Pod 是一个新实例。 此外,“AGE”值也要小得多。

在本练习中,你了解了 Kubernetes 如何自动保持声明的系统状态,即使出现故障也是如此

给TA打赏
共{{data.count}}人
人已打赏
.NET

ASP.NET与ASP.NET Core区别

2022-8-25 15:40:13

.NET

.NET 7 SDK 对容器的内置支持(最新更新)

2022-9-1 9:01:46

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索