ABP Studio:使用 Kubernetes 工作
你可以使用 Kubernetes 面板来管理你在 Kubernetes 集群中的应用程序。该面板专为微服务项目设计,因此你不必在本地环境中运行所有微服务项目。相反,你可以将它们部署到 Kubernetes 集群中,并在本地调试一个或多个项目。当然,你也可以将此面板用于单体项目。通过点击 ABP Studio 侧边栏中的 Kubernetes 按钮即可访问。
创建项目时会添加预设配置;请在附加选项步骤中查看 Kubernetes 配置。项目结构可能会根据你的选择而变化。例如,一个 MVC 微服务项目看起来如上图所示。你可以根据需要添加或删除图表。
先决条件
Kubernetes 面板仅在 商业版和企业版 许可中可用。你需要安装并配置以下工具才能使用 Kubernetes 面板。
- kubectl
- Helm
- Docker Desktop(如果并非使用真实集群,请启用 Kubernetes 选项)
- NGINX Ingress Controller
- mkcert
当你安装
mkcert以允许 ABP Studio 为你生成证书时,请确保mkcert已安装在 受信任的证书存储区 中,方法是运行以下命令(在 Windows 上,此命令必须以管理员权限执行):mkcert -install
配置文件
你可以创建多个配置文件来管理不同的 Kubernetes 集群或同一集群内的不同命名空间。配置文件是一组可用于连接到 Kubernetes 集群的配置。如果你在附加选项步骤中创建项目时勾选了 Kubernetes 配置,则会默认提供 local 配置文件,其中包含所有项目图表。你可以在组合框中查看所有配置文件并更改当前配置文件。要编辑,请点击右侧的齿轮图标。
更改当前配置文件不会影响 Charts 树。Charts 部分与解决方案相关,而不是配置文件。你可以在 Charts 部分添加或删除图表。
它会打开管理 Kubernetes 配置文件窗口。你可以编辑/删除现有配置文件或添加新的配置文件。
当你点击添加新配置文件按钮时,会打开新配置文件窗口。在配置文件信息选项卡中,你可以提供任意配置文件名称,该名称在所有配置文件中应是唯一的。在上下文组合框中,你将看到现有的 Kubernetes 上下文。选择其中一个。然后,提供一个在所属上下文中唯一的命名空间。创建新配置文件时,它会将 JSON 文件存储在指定的路径。对于微服务项目,你可以指定路径 abp-solution-path/etc/abp-studio/k8s-profiles,对于其他项目类型,则使用 abp-solution-path/etc/k8s-profiles 以遵循标准格式。
在元数据选项卡中,你可以提供有关配置文件的附加信息。我们在诸如 Build Docker Image(s) 和 Install Chart(s) 等命令中使用此信息。例如,dotnetEnvironment 对于 Install Chart(s) 命令是必需的,用于确定环境变量。你还可以通过点击添加按钮来添加更多元数据。它会从根到子级收集所有元数据,并根据层次结构覆盖现有值。例如,如果你在配置文件和图表中定义了两个相同的元数据,它将使用图表元数据。你可以为 Kubernetes 配置文件、主图表 和 子图表 添加元数据。
在密钥选项卡中,你可以为配置文件提供密钥。我们在诸如 wireGuardPassword 等命令中使用此信息。与元数据选项卡类似,你可以通过点击添加按钮来添加更多密钥。它会从根到子级收集所有密钥,并根据层次结构覆盖现有值。
你可以通过点击工具栏中的 Tools -> Global Secrets 来添加全局密钥,通过 Solution Explorer 根上下文菜单中的 Solution -> Manage Secrets 添加解决方案密钥,以及通过 Kubernetes 面板中的 Add or Edit Profile -> Secrets tab 添加Kubernetes 配置文件密钥。出于安全考虑,Secrets 信息保存在本地文件系统中,而不是解决方案文件中。因此,默认情况下你无法与团队成员共享。
要在配置文件信息选项卡中创建新配置文件,名称、上下文和命名空间就足够了。但是,你应该提供 dotnetEnvironment 元数据信息以使用 Install Chart(s) 命令。点击保存按钮以创建新配置文件。它会将配置文件添加到组合框中。同样,你可以编辑或删除现有配置文件。
当你创建新配置文件时,你还应该在 abp-solution-path/etc/helm/chart 文件夹中创建一个 values.{chart.name}-{profile.name}.yaml 文件来覆盖默认值。例如,values.bookstore-staging.yaml 用于 staging Kubernetes 配置文件中的 bookstore 图表。
图表
在 Helm 选项卡中,我们有解决方案中所有图表的树形视图。图表类型有三种:图表根、主图表 和 子图表。
图表根
它是所有主图表的根。你可以在根中拥有多个主图表。要向根添加新图表,请点击 Chart Root 上下文菜单中的 Add Chart 按钮。它会打开选择 Helm 图表窗口。从指定位置选取图表并选择主 helm 图表。将 helm 图表存储在 abp-solution-path/etc/helm/chart-name 文件夹中;否则,命令将无法工作。此外,主 chart name 和文件夹名称应相同。例如,如果主图表名称为 notebookstore,则文件夹名称也应为 notebookstore。与创建新的 kubernetes 配置文件类似,你还应该在 abp-solution-path/etc/helm/chart-name 文件夹中创建一个 values.{chart.name}-{profile.name}.yaml 文件来覆盖默认值。例如,values.notebookstore-staging.yaml 用于 staging Kubernetes 配置文件中的 notebookstore 图表。
如果你有多个主图表,你可以为所有图表执行集体命令。为此,请右键点击 Chart Root 的上下文菜单。以下选项可用于 Chart Root。
命令:你有几个选项可以为所有主图表执行命令。构建 Docker 镜像:如果子图表有可用的构建 docker 镜像,它会构建所有镜像。安装图表:将所有图表安装到所选配置文件。卸载图表:从所选配置文件卸载所有图表。创建自签名 TLS 密钥:它为应用程序创建自签名证书并将其添加到 Kubernetes 集群。当你为应用程序指定用户时很有用。
添加图表:它打开选择 Helm 图表窗口。从指定位置选取图表并选择主 helm 图表以向根添加新的主图表。
主图表
它是所有子图表的根。当你向根添加新的主图表时,它会自动添加与该主图表相关的子图表。右键单击主图表并从上下文菜单中选择命令。以下选项可用于 Main Chart。
命令:你有几个选项可以为选定的主图表执行命令。构建 Docker 镜像:如果子图表有可用的构建 docker 镜像,它会为所选主图表构建所有 docker 镜像。安装图表:将所选图表安装到当前配置文件。卸载图表:从当前配置文件卸载所选图表。
属性:它打开图表属性窗口。你可以在图表信息选项卡中查看图表信息。在元数据选项卡中,你可以为所选主图表添加元数据。它将覆盖配置文件中的元数据。在 Kubernetes Services 选项卡中,你可以将 Kubernetes 服务与主图表关联;但是,由于主图表通常不创建 kubernetes 服务,我们可以将其留空。刷新子图表:刷新所选主图表的子图表。打开方式:你可以使用 Visual Studio Code 或 文件资源管理器 打开所选图表。移除:从解决方案中移除所选主图表。
子图表
子图表是与主图表关联的组件。当你向根添加新的主图表时,它会自动添加与该主图表相关的子图表。子图表具有特定的配置和功能,这些配置和功能有助于主图表的整体功能。右键单击子图表并从上下文菜单中选择命令。以下选项可用于 Subchart。
命令构建 Docker 镜像:为所选子图表构建 docker 镜像。仅当子图表具有 projectPath、imageName 和 projectType 元数据时才可见。Project Type 只接受angular或dotnet值。它使用指定的 imageName 和 projectPath 构建 docker 镜像。
属性:它打开图表属性窗口。你可以在图表信息选项卡中查看图表信息。在元数据选项卡中,你可以为所选子图表添加元数据。它将覆盖配置文件以及主图表中的元数据。在 Kubernetes Services 选项卡中,你可以将 Kubernetes 服务与子图表关联;这样,当你连接到 Kubernetes 集群时,你可以在上下文菜单中看到 浏览 选项。浏览:它打开浏览器并导航到 Kubernetes 服务 URL。仅当子图表 Kubernetes Services 正则表达式模式与 Kubernetes 服务 匹配时才可见。打开方式:你可以使用 Visual Studio Code 或 文件资源管理器 打开所选子图表。
添加新的子图表
当你向解决方案添加新的微服务模块时,你还应该为其创建一个子图表。但是,模块类型无关紧要。同样,当你想出于任何原因创建子图表时,可以按照以下步骤操作:
- 使用 Visual Studio Code 打开主图表。
- 在 charts 文件夹中创建一个文件夹。
- 根据你的需要编辑文件夹中的文件。
- 编辑完成后,子图表模板即已完成;打开 ABP Studio 并在主图表的上下文菜单中执行 Refresh Sub Charts。你可以在 Charts 树中看到新的子图表。
- 如果添加的子图表具有 projectPath、imageName 和 projectType 元数据,你可以为子图表 Build Docker Image。
- 如果添加的子图表具有 Kubernetes Services 正则表达式模式,当你连接到 Kubernetes 集群时,你可以 浏览 Kubernetes 服务。
连接到 Kubernetes 集群
在我们 构建 Docker 镜像 并 安装图表 之后,我们可以连接到 Kubernetes 集群。为此,请点击 Kubernetes 选项卡中的链条图标或 Connect 按钮以与选定的 Kubernetes 集群建立连接。在初始连接期间,可能需要一段时间来准备;你可以在后台任务面板中监控进度。
连接时,无法更改当前配置文件。连接后,Kubernetes 选项卡中现有的应用程序服务将变得可见。要断开连接,可以点击链条图标。
当你连接到 Kubernetes 集群时,它会自动将 WireGuard VPN 安装到 Kubernetes 集群以确保安全连接。你可以在 Kubernetes Profile -> Secrets 选项卡或更高级别(例如 Solution Secrets 或 Global Secrets)中指定 wireGuardPassword。如果你不提供密码,它会生成一个随机密码并将其存储在 Kubernetes Profile -> Secrets 中。但是,如果你尝试连接到已安装 WireGuard VPN 的集群,那么你应该提供相同的密码;否则,它将无法连接。要查看随机密码,你可以点击 Kubernetes Profile -> Secrets 选项卡中的眼睛图标。
由于我们使用 WireGuard VPN 连接到 Kubernetes 集群,我们会自动将 Kubernetes 服务追加到你的 hosts 文件中。这使得你可以使用指定的 Kubernetes Service 名称无缝访问服务,包括 ClusterIP 类型的服务。例如,在此场景中,可以使用服务器名称 bookstore-local-sqlserver 通过诸如 SQL Server Management Studio (SSMS) 等工具连接到 SQL Server。SQL 服务器的默认 sa 密码设置为 myPassw@rd。
连接到 SQL Server 后,我们可以在 对象资源管理器 面板中看到数据库。
当连接到 Kubernetes 集群时,应用程序会建立连接并开始向 ABP Studio 发送遥测信息。在监控面板中,你可以轻松检查应用程序的状态和其他详细信息。此外,在解决方案运行器面板中,查找带有 (external) 信息的链条图标。
与集群断开连接后,我们会清理 hosts 文件,不包括 ingress hosts。这样,你仍然可以通过浏览器访问 ingress hosts。例如,在此场景中,我们可以访问 https://bookstore-local-web。
当你使用
kubectl get svc命令列出 Kubernetes 集群中的服务时,你应该看到 abp-wg-easy 和 abp-wg-easy-vpn 服务。每个 WireGuard 安装都有相关服务的唯一端口号。如果你有多个针对不同 Kubernetes 配置文件或解决方案的 WireGuard 安装,当使用kubectl get svc命令列出它们时,你可以在 PORT(S) 字段中看到端口号。
连接到 Kubernetes 集群在同一时间仅限于一个 ABP Studio 实例。同时尝试使用另一个实例连接将无法按预期工作。
拦截服务
Kubernetes 面板的最佳功能之一是你能够拦截服务。通过这种方式,你可以在本地环境中调试和开发特定的应用程序,而无需运行所有服务。要拦截服务,请右键单击服务并从上下文菜单中选择 Enable Interception。
拦截服务时,它会在后台启动拦截过程。完成后,你应该会看到服务名称旁边出现拦截图标。
拦截服务后,所有对该服务的请求都将被重定向到本地环境。例如,在此场景中,bookstore-local-auditlogging 服务被拦截。当尝试在浏览器中访问 https://bookstore-local-web/AuditLogs 时,会发生 Bad Gateway 异常,因为 bookstore-local-auditlogging 服务未在本地环境中运行。要解决此问题,请在 IDE(例如 Visual Studio)中打开 Acme.BookStore.AuditLoggingService .NET 解决方案,将 Acme.BookStore.AuditLoggingService 设置为启动项目,然后运行它(使用 F5 进入调试模式或 CTRL+F5 运行而不调试)。
你应该使用 Kestrel 启动应用程序,而不是 IIS Express。否则,它将无法按预期工作。为此,请在 IDE 中选择 Acme.BookStore.AuditLoggingService 启动配置文件。
应用程序在你的本地机器上启动后,重新访问应用程序中的审计日志页面,你会注意到它按预期工作。ABP Studio 处理你的机器和应用程序的配置,使其能够像在 Kubernetes 集群内部一样无缝运行。
利用 ABP Studio 的拦截功能,你可以灵活地在 Kubernetes 集群中运行整个解决方案,同时使用 IDE 在本地机器上仅运行一个(或几个)服务。这种方法使你能够专注于运行、测试和调试你的服务,而无需关心系统其余部分的配置和启动细节。
你可以通过右键单击服务并从上下文菜单中选择 Disable Interception 来禁用拦截。与 Kubernetes 集群断开连接会自动禁用所有拦截。
在调试被拦截的应用程序时,如果你遇到
Volo.Authorization:010001 (Authorization failed! Given policy has not granted.)异常,你应该运行abp-solution-path/etc/helm文件夹中的create-tls-secret.ps1脚本。它会为应用程序创建自签名证书并将其添加到 Kubernetes 集群。之后,你应该重启应用程序。
重新部署图表
在对项目进行一些更改后,你可以将图表重新部署到 Kubernetes 集群。为此,请右键单击服务并从上下文菜单中选择 Redeploy。它会为所选项目构建 docker 镜像并重新安装。
指定用户
当你连接到 Kubernetes 集群时,它会使用所选配置文件中的 Kubernetes Context 和 Namespace 信息。之后,当你拦截服务时,它会创建一些 Kubernetes 资源并将请求重定向到本地环境。但是,如果有两个或更多开发人员在同一项目上工作,他们无法同时拦截同一服务。为了解决这个问题,你可以指定用户。为此,它使用在 Tools -> Global Metadata 或其他级别(例如 Solution Metadata 和 Kubernetes Profile Metadata)中定义的 Metadata 键值对。当你定义名为 k8ssuffix 的元数据及其所需值时,它会附加到命名空间。例如,如果你定义值为 arthur 的 k8ssuffix 元数据,则命名空间变为 bookstore-local-arthur。之后,不同的用户可以使用相同的 Kubernetes 配置文件。
定义用户后,你应在图表根上执行 Create Self-Signed TLS secret 命令,以为应用程序创建自签名证书并将其添加到 Kubernetes 集群。这对于拦截服务是必需的。
当你在 Global Metadata 中定义元数据时,它对所有解决方案都可用,并且不会与你的团队成员共享。但是,如果你在 Solution Metadata 或 Kubernetes Profile Metadata 中定义元数据,则它仅对当前解决方案或 Kubernetes 配置文件可用,并且将与你的团队成员共享。
高级主题
添加自定义命令
自定义命令可以添加到 Kubernetes 面板的 Helm 和 Kubernetes 选项卡中。例如,在重新部署图表时,它涉及构建 Docker 镜像并重新安装它。但是,如果你使用的 Kubernetes 集群不是 Docker Desktop,则需要在安装过程之前将 Docker 镜像推送到注册表。这可以通过在 Kubernetes services 中加入自定义命令来实现。自定义命令可以添加到 Helm 选项卡中的 Chart Root、Main Chart 和 Subchart,以及 Kubernetes 选项卡中的 Service。
为此,使用 Visual Studio Code 打开 ABP 解决方案 (.abpsln) 文件,这是一个 JSON 文件,你将在 commands 部分看到现有命令。在添加新命令之前,在 abp-solution-path/etc/helm 文件夹中创建一个 powershell 脚本。例如,我们创建一个 push-image.ps1 脚本,将 docker 镜像推送到注册表。然后,将以下命令添加到 commands 部分。
"kubernetesRedeployWithPushImage": {
"triggerTargets": [
"KUBERNETES_SERVICE"
],
"executionTargets": [
"KUBERNETES_SERVICE"
],
"displayName": "重新部署并推送镜像",
"workingDirectory": "etc/helm",
"terminalCommand": "./build-image.ps1 -ProjectPath {{chart.metadata.projectPath}} -ImageName {{chart.metadata.imageName}} -ProjectType {{chart.metadata.projectType}} &&& ./push-image.ps1 -ImageName {{chart.metadata.imageName}} &&& ./install.ps1 -ChartName {{mainChart.name}} -Namespace {{profile.namespace}} -ReleaseName {{mainChart.name}}-{{profile.name}} -DotnetEnvironment {{mainChart.metadata.dotnetEnvironment}}",
"requireConfirmation": "true",
"confirmationText": "你确定要重新部署并推送服务 '{{name}}' 的相关图表 '{{chart.name}}' 吗?",
"condition": "{{chart != null && chart.metadata.projectPath != null && chart.metadata.imageName != null && chart.metadata.projectType != null}}"
}
添加命令后,从工具栏中的 File -> Reload Solution 重新加载解决方案。重新加载后,你将在服务的上下文菜单中找到 重新部署并推送镜像 命令。
JSON 对象具有以下属性:
triggerTargets:指定命令的触发目标。添加的命令将出现在这些目标中。你可以添加一个或多个触发目标,接受诸如 HELM_CHARTS_ROOT、HELM_MAIN_CHART、HELM_SUB_CHART 和 KUBERNETES_SERVICE 等值。executionTargets:指定命令的执行目标。当在根项上执行命令时,它将递归地为所有子项执行命令。可接受的值包括 HELM_CHARTS_ROOT、HELM_MAIN_CHART、HELM_SUB_CHART 和 KUBERNETES_SERVICE。displayName:指定命令的显示名称。workingDirectory:指定命令的工作目录。相对于解决方案路径。terminalCommand:指定自定义命令的终端命令。可以使用&&&运算符在终端中运行多个命令。利用 Scriban 语法访问输入数据,输入数据因执行目标而异。requireConfirmation:指定命令在执行前是否需要确认消息。可接受的值包括 true 和 false。confirmationText:指定命令的确认文本。利用 Scriban 语法访问输入数据,输入数据因执行目标而异。condition:指定命令的条件。如果条件返回 false,它将跳过当前项并尝试为下一项或子项执行命令。利用 Scriban 语法访问输入数据,输入数据因执行目标而异。
你可以根据执行目标在 Scriban 语法中使用以下变量:
HELM_CHARTS_ROOT: profile, metadata, secretsHELM_MAIN_CHART: profile, chart, metadata, secretHELM_SUB_CHART: profile, chart, metadata, secretKUBERNETES_SERVICE: name, profile, mainChart, chart, metadata, secret
抠丁客


























