1. 概览
ASP.NET Core 是一个开源的跨平台框架,可让您使用 C# 编程语言构建基于云和联网的现代应用。
Kubernetes 是一个开源系统,用于自动部署、扩缩和管理容器化应用。Istio 是一个用于连接、保护、管理和监控服务的开放式框架。
在本实验的第一部分中,您需要将一个简单的 ASP.NET Core 应用部署到在 Google Kubernetes Engine (GKE) 上运行的 Kubernetes,并将其配置为由 Istio 管理。
在本实验的第二部分,您将进一步探索 Istio 的功能,例如指标、跟踪、动态流量管理、故障注入等。
学习内容
- 如何创建 ASP.NET Core 应用并将其打包到 Docker 容器中。
- 如何使用 Google Kubernetes Engine (GKE) 创建 Kubernetes 集群。
- 如何在 GKE 上的 Kubernetes 集群上安装 Istio。
- 如何部署 ASP.NET Core 应用并将其流量配置为由 Istio 管理。
所需条件
您打算如何使用本教程?
如何评价您的 Google Cloud Platform 使用体验?
<ph type="x-smartling-placeholder">2. 设置和要求
自定进度的环境设置
请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID
。
- 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。
运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分部分,其中会指导您如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 300 美元的免费试用计划的条件。
启动 Cloud Shell
虽然 Google Cloud 可以通过笔记本电脑远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在 Google Cloud 中运行的命令行环境。
激活 Cloud Shell
- 在 Cloud Console 中,点击激活 Cloud Shell。
如果您以前从未启动过 Cloud Shell,系统会显示一个中间屏幕(非首屏)来介绍 Cloud Shell。如果是这种情况,请点击继续(此后您将不会再看到此通知)。一次性屏幕如下所示:
预配和连接到 Cloud Shell 只需花几分钟时间。
这个虚拟机装有您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。只需使用一个浏览器或 Google Chromebook 即可完成本 Codelab 中的大部分(甚至全部)工作。
在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID:
- 在 Cloud Shell 中运行以下命令以确认您已通过身份验证:
gcloud auth list
命令输出
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- 在 Cloud Shell 中运行以下命令,以确认 gcloud 命令了解您的项目:
gcloud config list project
命令输出
[core] project = <PROJECT_ID>
如果不是上述结果,您可以使用以下命令进行设置:
gcloud config set project <PROJECT_ID>
命令输出
Updated property [core/project].
3. 在 Cloud Shell 中创建 ASP.NET Core 应用
在 Cloud Shell 提示符中,您可以通过检查 dotnet 命令行工具的版本来验证其是否已安装。此命令应输出已安装的 dotnet 命令行工具的版本:
dotnet --version
接下来,创建一个新的 ASP.NET Core Web 框架应用。
dotnet new mvc -o HelloWorldAspNetCore
系统会创建一个项目并恢复其依赖项。您应该会看到如下所示的消息:
Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.
Restore succeeded.
4. 运行 ASP.NET Core 应用
我们很快就可以运行应用了。前往应用文件夹。
cd HelloWorldAspNetCore
最后,运行应用。
dotnet run --urls=http://localhost:8080
该应用随即便开始监听端口 8080。
Hosting environment: Production
Content root path: /home/atameldev/HelloWorldAspNetCore
Now listening on: http://[::]:8080
Application started. Press Ctrl+C to shut down.
如需验证该应用是否正在运行,请点击右上角的网页预览按钮,然后选择“在端口 8080 上预览”。
您会看到默认的 ASP.NET Core 网页:
确认应用正在运行后,按 Ctrl+C 关闭应用。
5. 将 ASP.NET Core 应用打包到 Docker 容器中
接下来,准备好您的应用,使其以容器的形式运行。第一步是定义容器及其内容。
在应用的基本目录中,创建一个 Dockerfile
来定义 Docker 映像。
touch Dockerfile
使用您喜爱的编辑器(vim,
nano,emacs
或 Cloud Shell 的代码编辑器)将以下代码添加到 Dockerfile
。
# Use Microsoft's official build .NET image. # https://hub.docker.com/_/microsoft-dotnet-core-sdk/ FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build WORKDIR /app # Install production dependencies. # Copy csproj and restore as distinct layers. COPY *.csproj ./ RUN dotnet restore # Copy local code to the container image. COPY . ./ WORKDIR /app # Build a release artifact. RUN dotnet publish -c Release -o out # Use Microsoft's official runtime .NET image. # https://hub.docker.com/_/microsoft-dotnet-core-aspnet/ FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS runtime WORKDIR /app COPY --from=build /app/out ./ # Make sure the app binds to port 8080 ENV ASPNETCORE_URLS http://*:8080 # Run the web service on container startup. ENTRYPOINT ["dotnet", "HelloWorldAspNetCore.dll"]
Dockerfile 中包含的一项重要配置是应用监听传入流量 (8080) 的端口。这是通过设置 ASPNETCORE_URLS
环境变量实现的,ASP.NET Core 应用使用该变量确定要监听的端口。
保存此Dockerfile
。现在,我们来构建映像:
docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1 .
此操作完成后(下载和提取所有内容需要一些时间),您可以看到映像已构建并保存到本地:
docker images REPOSITORY TAG gcr.io/yourproject-XXXX/hello-dotnet v1
使用以下命令在本地测试映像,该命令将在端口 8080 上从新创建的容器映像在本地运行 Docker 容器:
docker run -p 8080:8080 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1
再次充分利用 CloudShell 的网页预览功能:
您应该会在新标签页中看到默认的 ASP.NET Core 网页。
确认应用可在 Docker 容器本地正常运行后,您可以通过 Ctrl-> C
停止正在运行的容器。
现在映像按预期运行,接下来您可以将它推送到 Google Container Registry,这是一个私有代码库,用于存储 Docker 映像,该代码库可从每个 Google Cloud 项目(以及从 Google Cloud Platform 外部访问)进行访问:
docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1
如果一切进展顺利,一段时间后,您应该能够看到 Container Registry 部分中列出的容器映像。此时,您已经有一个项目范围的 Docker 映像可用,Kubernetes 可以访问和编排该映像,几分钟后您就会看到。
如果您想浏览存储在 Google Cloud Storage 中的容器映像,可以点击以下链接:https://console.cloud.google.com/storage/browser/(得到的完整链接应采用以下格式:https://console.cloud.google.com/project/PROJECT_ID/storage/browser/)。
6. 使用 Istio 创建 Kubernetes/GKE 集群
首先,确保已启用 Kubernetes Engine API:
gcloud services enable container.googleapis.com
创建 Kubernetes 集群。如果愿意,您可以将区域更改为附近的某个区域:
gcloud container clusters create hello-istio \ --cluster-version=latest \ --machine-type=n1-standard-2 \ --num-nodes=4 \ --region europe-west1
请稍等片刻,我们正在为您设置集群。它将显示在 Google Cloud Platform 控制台的 Kubernetes Engine 部分中。
对于此 Codelab,我们将从 istio.io 下载并安装 Istio。还有其他安装选项,包括适用于 GKE 的 Istio 插件和 Anthos Service Mesh。此步骤之后的应用步骤适用于所有 Istio 安装。
我们先下载 Istio 客户端和示例。Istio 发布页面提供了适用于多个操作系统的下载工件。在本例中,我们可以使用便捷的命令下载并提取适用于当前平台的最新版本:
curl -L https://istio.io/downloadIstio | sh -
该脚本将告诉您已下载的 Istio 版本:
Istio has been successfully downloaded into the istio-1.8.1 folder on your system.
安装目录包含示例应用和 istioctl
客户端二进制文件。切换到该目录:
cd istio-1.8.1
复制并粘贴提供的命令,将 bin
目录添加到 PATH
,以便您可以使用 istioctl
:
export PATH="$PATH:/home/<YOURHOMEID>/istio-1.8.1/bin"
检查您的集群是否已准备好使用 Istio,以验证 istioctl
是否可用:
istioctl x precheck
您应该会看到如下消息:Install Pre-Check passed! The cluster is ready for Istio installation.
使用演示配置文件安装 Istio:
istioctl install --set profile=demo
Istio 现已安装在您的集群中。
自动 Sidecar 注入
要开始使用 Istio,您无需对应用进行任何更改。当您配置和运行服务时,Envoy Sidecar 会自动注入该服务的每个 Pod。
为此,您需要为用于微服务的命名空间(“默认”)启用 Sidecar 注入。您可以通过应用标签来实现此目的:
kubectl label namespace default istio-injection=enabled
如需验证标签是否已成功应用,请运行以下命令:
kubectl get namespace -L istio-injection
输出结果会确认已为默认命名空间启用 Sidecar 注入:
NAME STATUS AGE ISTIO-INJECTION default Active 3m enabled istio-system Active 63s disabled ...
7. 验证安装
Istio 提供三项服务:istiod
控制平面,以及入站流量和出站流量网关(您可以将它们视为“互联网其余部分的 Sidecar 代理”),这些服务分别命名为 istio-ingressgateway
和 istio-egressgateway
。
kubectl get svc -n istio-system
输出的内容应如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP AGE istio-egressgateway ClusterIP 10.55.252.182 <none> istio-ingressgateway LoadBalancer 10.55.250.185 35.233.118.42 istiod ClusterIP 10.55.253.217 <none>
入站网关的类型为 LoadBalancer
,因此可通过互联网访问;其他的则只需从集群内访问即可。
接下来,确保已部署相应的 Kubernetes Pod,并且所有容器都已启动并运行:
kubectl get pods -n istio-system
当所有 Pod 都处于运行时,您可以继续操作。
NAME READY STATUS istio-egressgateway-674988f895-m6tk4 1/1 Running istio-ingressgateway-6996f7dcc8-7lvm2 1/1 Running istiod-6bf5fc8b64-j79hj 1/1 Running
istiod
:Istio 控制平面。处理代理 Sidecar 的配置和编程、服务发现、证书分发和 Sidecar 注入ingress gateway
:处理从集群外部传入的请求。egress gateway
::处理发送到集群外部端点的传出请求。
8. 部署应用
现在您已确认 Istio 已安装并且正在运行,接下来您可以部署 ASP.NET Core 应用了。
部署和服务
首先,使用您喜爱的编辑器(vim, nano,emacs
或 Cloud Shell 的代码编辑器)创建一个 aspnetcore.yaml
文件,然后为应用定义 Kubernetes Deployment 和 Service:
apiVersion: v1 kind: Service metadata: name: aspnetcore-service labels: app: aspnetcore spec: ports: - port: 8080 name: http selector: app: aspnetcore --- apiVersion: apps/v1 kind: Deployment metadata: name: aspnetcore-v1 spec: replicas: 1 selector: matchLabels: app: aspnetcore version: v1 template: metadata: labels: app: aspnetcore version: v1 spec: containers: - name: aspnetcore image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 8080
该文件的内容是用于部署应用的标准 Deployment 和服务,不包含任何 Istio 特有的内容。
使用 kubectl
将服务部署到默认命名空间:
kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" created deployment.extensions "aspnetcore-v1" created
验证 Pod 是否正在运行:
kubectl get pods
NAME READY STATUS RESTARTS AGE aspnetcore-v1-6cf64748-mddb 2/2 Running 0 34s
Gateway 和 VirtualService
如需允许入站流量到达网格,您需要创建网关和 VirtualService。
网关为 HTTP/TCP 流量配置负载平衡器,通常在网格边缘运行,以便为应用启用入站流量。VirtualService 定义的规则用于控制服务请求在 Istio 服务网格中路由的方式。
创建 aspnetcore-gateway.yaml
文件来定义网关:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: aspnetcore-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
创建一个 aspnetcore-virtualservice.yaml
文件来定义 VirtualService:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: aspnetcore-virtualservice spec: hosts: - "*" gateways: - aspnetcore-gateway http: - route: - destination: host: aspnetcore-service
运行 kubectl 命令,使用以下命令部署网关:
kubectl apply -f aspnetcore-gateway.yaml
该命令会生成以下输出:
gateway.networking.istio.io "aspnetcore-gateway" created
接下来,运行以下命令来部署 VirtualService:
kubectl apply -f aspnetcore-virtualservice.yaml
该命令会生成以下输出:
virtualservice.networking.istio.io "aspnetcore-virtualservice" created
验证一切是否正在运行:
kubectl get gateway
NAME AGE aspnetcore-gateway 28s
kubectl get virtualservice
NAME AGE aspnetcore-virtualservice 33s
恭喜!您刚刚部署了一个已启用 Istio 的应用。接下来,您会看到使用中的应用。
9. 测试应用
您最终可以看到该应用的实际运行情况。您需要获取网关的外部 IP 和端口。它列在 EXTERNAL-IP
下:
kubectl get svc istio-ingressgateway -n istio-system
将外部 IP 和端口导出到 GATEWAY_URL
变量:
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}') export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
使用 curl
测试应用。服务应以 200
作为响应代码进行响应:
curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/
或者,您也可以打开浏览器,前往 http://<gatewayurl>
以查看应用:
10. 恭喜!
您刚刚为在 Google Kubernetes Engine (GKE) 上运行的 Kubernetes 部署了一个简单的 ASP.NET Core 应用,并将其配置为由 Istio 管理。
您可能想知道“Istio 有什么优势?”。好问题!目前为止,让 Istio 管理此应用还没有任何优势。在本实验的第二部分中,我们将进一步探索 Istio 的功能,例如指标、跟踪、动态流量管理、服务可视化和故障注入。
后续步骤
- 使用 Istio 将 ASP.NET Core 应用部署到 GKE(第 2 部分)。
- 详细了解 Istio。
- 详细了解 Kubernetes。
- 详细了解 Google Kubernetes Engine。
- 详细了解 Google Cloud Platform 上的 .NET。
许可
此作品已获得 Creative Commons Attribution 2.0 通用许可授权。
11. 清理
如果您不想继续本实验的第二部分,可以删除该应用并卸载 Istio,也可以直接删除 Kubernetes 集群。
删除应用
如需删除应用,请执行以下操作:
kubectl delete -f aspnetcore-gateway.yaml Kubectl delete -f aspnetcore-virtualservice.yaml kubectl delete -f aspnetcore.yaml
如需确认该应用已不复存在,请执行以下操作:
kubectl get gateway kubectl get virtualservices kubectl get pods
卸载 Istio
如需删除 Istio,请执行以下操作:
kubectl delete -f install/kubernetes/istio-demo-auth.yaml
如需确认 Istio 是否已消失,请运行以下命令:
kubectl get pods -n istio-system
删除 Kubernetes 集群
gcloud container clusters delete hello-istio