入门 Amazon App Mesh 和 Kubernetes - Amazon App Mesh
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

入门 Amazon App Mesh 和 Kubernetes

当你使用适用于 Kubernetes 的 App Mesh 控制器 Amazon App Mesh 与 Kubernetes 集成时,你可以管理应用网格资源,例如网格、虚拟服务、虚拟节点、虚拟路由器和通过 Kubernetes 的路由。您也可以自动向 Kubernetes 容器组 (pod) 规范中添加 App Mesh sidecar 容器映像。本教程指导您完成适用于 Kubernetes 的 App Mesh 控制器的安装,以便启用此集成。

以下 Kubernetes 自定义资源定义的部署附带了控制器:meshesvirtual servicesvirtual nodesvirtual routers。控制器密切注意自定义资源的创建、修改和删除,并通过 API 更改相应的 App Mesh 服务网格 虚拟服务虚拟节点虚拟网关网关路由虚拟路由器(包括 路由)资源。要了解更多信息或为控制器做出贡献,请参阅GitHub项目

控制器还会安装一个 Webhook,将以下容器注入标有您指定名称的 Kubernetes 容器组 (pod) 中。

  • App Mesh Envoy 代理 - Envoy 使用在 App Mesh 控制面板中定义的配置来确定将应用程序流量发送到何处。

  • App Mesh 代理路由管理器 - 更新容器组 (pod) 网络命名空间中通过 Envoy 路由传入和传出流量的 iptables 规则。此容器作为 Kubernetes init 容器运行在容器组 (pod) 中。

先决条件

  • 已了解 App Mesh 概念。有关更多信息,请参阅 什么是 Amazon App Mesh?

  • 已对 Kubernetes 概念有所了解。有关更多信息,请参阅 Kubernetes 文档中的 什么是 Kubernetes

  • 现有 Kubernetes 集群。如果您还没有集群,请参阅《Amazon EKS 用户指南》中的 Amazon EKS 入门。如果您在亚马逊 EC2 上运行自己的 Kubernetes 集群,请确保 Docker 已通过 Envoy 镜像所在的 Amazon ECR 存储库的身份验证。有关更多信息,请参阅 Envoy 镜像、《亚马逊弹性容器注册表用户指南》中的注册表身份验证和 Kubernetes 文档中的从私有注册表中提取镜像

  • App Mesh 支持在 DNS 中注册的 Linux 服务 Amazon Cloud Map,或者两者兼而有之。要使用此入门指南,我们建议您提供三项已注册到 DNS 的现有服务。该主题的剩余步骤假定现有服务命名为 serviceAserviceBserviceBv2,并且可以在名为 apps.local 的命名空间中发现所有服务。

    即使服务不存在,您也可以创建服务网格及其资源,但在部署实际服务之前,您无法使用网格。

  • 已安装 Amazon CLI 版本 1.18.116 或更高版本或 2.0.38 或更高版本。要安装或升级 Amazon CLI,请参阅安装 Amazon CLI

  • 配置为与您的 Kubernetes 集群通信的 kubectl 客户端。如果您正在使用 Amazon Elastic Kubernetes Service,则可以使用用于安装 kubectl 和配置 kubeconfig 文件的说明。

  • Helm 版本 3.0 或更高版本已安装。如果您没有安装 Helm,请参阅《亚马逊 EKS 用户指南》中的将 Helm 与亚马逊 EKS 配合使用

  • Amazon EKS 目前 IPv6_ONLY 仅支持 IPv4_ONLY 且仅支持 IP 首选项,因为 Amazon EKS 目前仅支持能够仅提供 IPv4 流量或仅 IPv6 流量的容器组 (pod)。

剩余步骤假定实际服务命名为 serviceAserviceBserviceBv2,并且可以在名为 apps.local 的命名空间中发现所有服务。

步骤 1:安装集成组件

在要托管与 App Mesh 结合使用的容器组 (pod) 的每个集群中,安装一次集成组件。

安装集成组件
  1. 此过程的剩余步骤需要一个没有安装预发行版控制器的集群。如果您已安装预发行版,或者不确定是否已安装,则可以下载并运行一个脚本,检查您的集群是否安装了预发行版。

    curl -o pre_upgrade_check.sh https://raw.githubusercontent.com/aws/eks-charts/master/stable/appmesh-controller/upgrade/pre_upgrade_check.sh sh ./pre_upgrade_check.sh

    如果脚本返回 Your cluster is ready for upgrade. Please proceed to the installation instructions,则可以继续执行下一步。如果返回不同的消息,则需要先完成升级步骤,然后再继续。有关升级预发行版本的更多信息,请参阅升级。 GitHub

  2. eks-charts 存储库添加到 Helm。

    helm repo add eks https://aws.github.io/eks-charts
  3. 安装 App Mesh Kubernetes 自定义资源定义 (CRD)。

    kubectl apply -k "https://github.com/aws/eks-charts/stable/appmesh-controller/crds?ref=master"
  4. 为控制器创建一个 Kubernetes 命名空间。

    kubectl create ns appmesh-system
  5. 设置以下变量,以便在后续步骤中使用。将 cluster-nameRegion-code 替换为现有集群的值。

    export CLUSTER_NAME=cluster-name export AWS_REGION=Region-code
  6. (可选)如果您想在 Fargate 上运行控制器,则需要创建一个 Fargate 配置文件。如果您尚未 eksctl 安装,请参阅 《Amazon EKS 用户指南》eksctl中的安装或升级。如果您希望使用控制台创建配置文件,请参阅《Amazon EKS 用户指南》中的创建 Fargate 配置文件

    eksctl create fargateprofile --cluster $CLUSTER_NAME --name appmesh-system --namespace appmesh-system
  7. 为您的集群创建 OpenID Connect (OIDC) 身份提供商。如果未安装 eksctl,则可以按照《Amazon EKS 用户指南》安装或升级 eksctl上的说明安装它。如果您希望使用控制台创建提供商,请参阅《Amazon EKS 用户指南》中的在集群上为服务账户启用 IAM 角色

    eksctl utils associate-iam-oidc-provider \ --region=$AWS_REGION \ --cluster $CLUSTER_NAME \ --approve
  8. 创建 IAM 角色,为其附加AWSAppMeshFullAccessAWSCloudMapFullAccess Amazon 托管策略,然后将其绑定到 appmesh-controller Kubernetes 服务账户。该角色使控制器能够添加、删除和更改 App Mesh 资源。

    注意

    该命令使用自动生成的名称创建一个 Amazon IAM 角色。您无法指定创建的 IAM 角色名称。

    eksctl create iamserviceaccount \ --cluster $CLUSTER_NAME \ --namespace appmesh-system \ --name appmesh-controller \ --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapFullAccess,arn:aws:iam::aws:policy/AWSAppMeshFullAccess \ --override-existing-serviceaccounts \ --approve

    如果您更喜欢使用 Amazon Web Services Management Console 或创建服务账户 Amazon CLI,请参阅 A mazon EKS 用户指南中的为您的服务账户创建 IAM 角色和策略。如果您使用 Amazon Web Services Management Console 或 Amazon CLI 来创建账户,则还需要将该角色映射到 Kubernetes 服务帐号。有关更多信息,请参阅《Amazon EKS 用户指南》中的为集群上的服务账户指定 IAM 角色

  9. 部署 App Mesh 控制器。有关所有配置选项的列表,请参阅上的配置 GitHub。
    1. 要为私有集群部署 App Mesh 控制器,必须先对链接的私有子网启用 App Mesh 和服务发现 Amazon VPC 端点。您还需要设置 accountId

      --set accountId=$AWS_ACCOUNT_ID

      要在私有集群中启用 X-Ray 跟踪,请启用 X-Ray 和 Amazon ECR Amazon VPC 端点。控制器默认使用 public.ecr.aws/xray/aws-xray-daemon:latest,因此请将此映像拉到本地并将其推送到您的个人 ECR 存储库

      注意

      Amazon VPC 端点目前不支持 Amazon ECR 公有存储库。

      以下示例显示如何使用 X-Ray 配置部署控制器。

      helm upgrade -i appmesh-controller eks/appmesh-controller \ --namespace appmesh-system \ --set region=$AWS_REGION \ --set serviceAccount.create=false \ --set serviceAccount.name=appmesh-controller \ --set accountId=$AWS_ACCOUNT_ID \ --set log.level=debug \ --set tracing.enabled=true \ --set tracing.provider=x-ray \ --set xray.image.repository=your-account-id.dkr.ecr.your-region.amazonaws.com/your-repository \ --set xray.image.tag=your-xray-daemon-image-tag

      在将应用程序部署与虚拟节点或网关绑定时,请验证 X-Ray 进程守护程序是否成功注入。

      有关更多信息,请参阅《Amazon EKS 用户指南》中的私有集群

    2. 为其他集群部署 App Mesh 控制器。有关所有配置选项的列表,请参阅上的配置 GitHub。

      helm upgrade -i appmesh-controller eks/appmesh-controller \ --namespace appmesh-system \ --set region=$AWS_REGION \ --set serviceAccount.create=false \ --set serviceAccount.name=appmesh-controller
    注意

    如果您的 Amazon EKS 集群系列是 IPv6,请在部署 App Mesh 控制器时通过在前面的命令中添加以下选项来设置集群名称 --set clusterName=$CLUSTER_NAME

    重要

    如果您的集群位于 cn-north-1cn-northwest-1 中,则需要在前面的命令中添加以下选项。

    账户 ID区域代码替换为相应的值集之一。

    --set sidecar.image.repository=account-id.dkr.ecr.Region-code.amazonaws.com.cn/aws-appmesh-envoy
    • 919366029133.dkr。ecr.cn-north-1.amazonaws.com .cn/: v1.27.3.0-prod aws-appmesh-envoy

    • 919830735681.dkr。ecr.cn-northwest-1.amazonaws.com .cn/: v1.27.3.0-prod aws-appmesh-envoy

    --set init.image.repository=account-id.dkr.ecr.Region-code.amazonaws.com.cn/aws-appmesh-proxy-route-manager
    • 919366029133.dkr。ecr.cn-north-1.amazonaws.com .cn/-manager: v7-prod aws-appmesh-proxy-route

    • 919830735681.dkr。ecr.cn-northwest-1.amazonaws.com .cn/-manager: v7-prod aws-appmesh-proxy-route

    --set image.repository=account-id.dkr.ecr.Region-code.amazonaws.com.cn/appmesh-controller
    • 918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/amazon/appmesh-controller

    • 961992271922.dkr.ecr.cn-northwest-1.amazonaws.com.cn/amazon/appmesh-controller

    重要

    如果您的集群位于me-south-1ap-east-1ap-southeast-3eu-south-1il-central-1af-south-1 区域中,则需要在前面的命令中添加以下选项:

    账户 ID区域代码替换为相应的值集之一。

    • 对于 sidecar 映像:
      • --set image.repository=account-id.dkr.ecr.Region-code.amazonaws.com/amazon/appmesh-controller
      • 772975370895.dkr。ecr.me-south-1.amazonaws.com/: v1.27.3.0-prod aws-appmesh-envoy

      • 856666278305.dkr。ecr.ap-east-1.amazonaws.com/: v1.27.3.0-prod aws-appmesh-envoy

      • 909464085924.dkr。ecr.ap-southeast-3.amazonaws.com/: v1.27.3.0-prod aws-appmesh-envoy

      • 422531588944.dkr。ecr.eu-south-1.amazonaws.com/: v1.27.3.0-prod aws-appmesh-envoy

      • 564877687649.dkr。ecr.il-central-1.amazonaws.com/: v1.27.3.0-prod aws-appmesh-envoy

      • 924023996002.dkr。ecr.af-south-1.amazonaws.com/: v1.27.3.0-prod aws-appmesh-envoy

    • 可以在更改日志中找到较旧的图像 URI。 GitHub显示图像的 Amazon 账户版本已更改v1.5.0旧版本的镜像托管在亚马逊 Elastic Kubernetes Service 亚马逊容器镜像注册表上的 Amazon 账户中。

    • 对于控制器映像:
      • --set sidecar.image.repository=account-id.dkr.ecr.Region-code.amazonaws.com/aws-appmesh-envoy
      • 772975370895.dkr.ecr.me-south-1.amazonaws.com/amazon/appmesh-controller:v1.12.3

      • 856666278305.dkr.ecr.ap-east-1.amazonaws.com/amazon/appmesh-controller:v1.12.3

      • 909464085924.dkr.ecr.ap-southeast-3.amazonaws.com/amazon/appmesh-controller:v1.12.3

      • 422531588944.dkr.ecr.eu-south-1.amazonaws.com/amazon/appmesh-controller:v1.12.3

      • 564877687649.dkr.ecr.il-central-1.amazonaws.com/amazon/appmesh-controller:v1.12.3

      • 924023996002.dkr.ecr.af-south-1.amazonaws.com/amazon/appmesh-controller:v1.12.3

    • 对于 sidecar 初始化映像:
      • --set sidecar.image.repository=account-id.dkr.ecr.Region-code.amazonaws.com/aws-appmesh-envoy
      • 772975370895.dkr。ecr.me-south-1.amazonaws.com /-manager: v7-prod aws-appmesh-proxy-route

      • 856666278305.dkr。ecr.ap-east-1.amazonaws.com /-manager: v7-prod aws-appmesh-proxy-route

      • 909464085924.dkr。ecr.ap-southeast-3.amazonaws.com /-manager: v7-prod aws-appmesh-proxy-route

      • 422531588944.dkr。ecr.eu-south-1.amazonaws.com /-manager: v7-prod aws-appmesh-proxy-route

      • 564877687649.dkr。ecr.il-central-1.amazonaws.com /-manager: v7-prod aws-appmesh-proxy-route

      • 924023996002.dkr。ecr.af-south-1.amazonaws.com /-manager: v7-prod aws-appmesh-proxy-route

    重要

    仅支持将版本 v1.9.0.0-prod 或更高版本与 App Mesh 一起使用。

  10. 确认控制器版本为 v1.4.0 或更高版本。您可以登录查看变更日志 GitHub。

    kubectl get deployment appmesh-controller \ -n appmesh-system \ -o json | jq -r ".spec.template.spec.containers[].image" | cut -f2 -d ':'
    注意

    如果您查看正在运行的容器的日志,您可能会看到有一行包含以下文本,这行文本可以安全地忽略。

    Neither -kubeconfig nor -master was specified. Using the inClusterConfig. This might not work.

步骤 2:部署 App Mesh 资源

当您在 Kubernetes 中部署应用程序时,您也会创建 Kubernetes 自定义资源,以便控制器可以创建相应的 App Mesh 资源。以下过程可帮助您部署具有某些功能的 App Mesh 资源。您可以在 App Mesh 演练中列出的许多功能文件夹的v1beta2子文件夹中找到部署其他 App Mesh 资源功能的示例清单。 GitHub

重要

控制器创建了 App Mesh 资源后,建议您仅使用控制器对 App Mesh 资源进行更改或删除资源。如果您使用 App Mesh 对资源进行更改或删除,则默认情况下,控制器将在十小时内不会更改或重新创建所更改或删除的 App Mesh 资源。您可以将此持续时间配置为更短的时间。有关更多信息,请参阅上的 “配置” GitHub。

部署 App Mesh 资源
  1. 创建要将 App Mesh 资源部署到的 Kubernetes 命名空间。

    1. 将以下内容保存到计算机上名为 namespace.yaml 的文件中。

      apiVersion: v1 kind: Namespace metadata: name: my-apps labels: mesh: my-mesh appmesh.k8s.aws/sidecarInjectorWebhook: enabled
    2. 创建命名空间。

      kubectl apply -f namespace.yaml
  2. 创建 App Mesh 服务网格

    1. 将以下内容保存到计算机上名为 mesh.yaml 的文件中。该文件用于创建名为 my-mesh 的网格资源。服务网格是一种用于驻留在其内的服务之间的网络流量的逻辑边界。

      apiVersion: appmesh.k8s.aws/v1beta2 kind: Mesh metadata: name: my-mesh spec: namespaceSelector: matchLabels: mesh: my-mesh
    2. 创建网格。

      kubectl apply -f mesh.yaml
    3. 查看已创建的 Kubernetes 网格资源的详细信息。

      kubectl describe mesh my-mesh

      输出

      Name: my-mesh Namespace: Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"Mesh","metadata":{"annotations":{},"name":"my-mesh"},"spec":{"namespaceSelector":{"matchLa... API Version: appmesh.k8s.aws/v1beta2 Kind: Mesh Metadata: Creation Timestamp: 2020-06-17T14:51:37Z Finalizers: finalizers.appmesh.k8s.aws/mesh-members finalizers.appmesh.k8s.aws/aws-appmesh-resources Generation: 1 Resource Version: 6295 Self Link: /apis/appmesh.k8s.aws/v1beta2/meshes/my-mesh UID: 111a11b1-c11d-1e1f-gh1i-j11k1l111m711 Spec: Aws Name: my-mesh Namespace Selector: Match Labels: Mesh: my-mesh Status: Conditions: Last Transition Time: 2020-06-17T14:51:37Z Status: True Type: MeshActive Mesh ARN: arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh Observed Generation: 1 Events: <none>
    4. 查看有关控制器创建的 App Mesh 服务网格的详细信息。

      aws appmesh describe-mesh --mesh-name my-mesh

      输出

      { "mesh": { "meshName": "my-mesh", "metadata": { "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh", "createdAt": "2020-06-17T09:51:37.920000-05:00", "lastUpdatedAt": "2020-06-17T09:51:37.920000-05:00", "meshOwner": "111122223333", "resourceOwner": "111122223333", "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711", "version": 1 }, "spec": {}, "status": { "status": "ACTIVE" } } }
  3. 创建 App Mesh 虚拟节点。虚拟节点充当指向 Kubernetes 部署的逻辑指针。

    1. 将以下内容保存到计算机上名为 virtual-node.yaml 的文件中。该文件用于创建命名my-apps空间 my-service-a 中命名的 App Mesh 虚拟节点。虚拟节点表示在后续步骤中创建的 Kubernetes 服务。hostname 的值是此虚拟节点所代表的实际服务的完全限定 DNS 主机名。

      apiVersion: appmesh.k8s.aws/v1beta2 kind: VirtualNode metadata: name: my-service-a namespace: my-apps spec: podSelector: matchLabels: app: my-app-1 listeners: - portMapping: port: 80 protocol: http serviceDiscovery: dns: hostname: my-service-a.my-apps.svc.cluster.local

      虚拟节点具有本教程中未涉及的功能,例如 end-to-end 加密和运行状况检查。有关更多信息,请参阅 虚拟节点。若要查看可在上述规范中设置的虚拟节点的所有可用设置,请运行以下命令。

      aws appmesh create-virtual-node --generate-cli-skeleton yaml-input
    2. 部署虚拟节点。

      kubectl apply -f virtual-node.yaml
    3. 查看已创建的 Kubernetes 虚拟节点资源的详细信息。

      kubectl describe virtualnode my-service-a -n my-apps

      输出

      Name: my-service-a Namespace: my-apps Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"VirtualNode","metadata":{"annotations":{},"name":"my-service-a","namespace":"my-apps"},"s... API Version: appmesh.k8s.aws/v1beta2 Kind: VirtualNode Metadata: Creation Timestamp: 2020-06-17T14:57:29Z Finalizers: finalizers.appmesh.k8s.aws/aws-appmesh-resources Generation: 2 Resource Version: 22545 Self Link: /apis/appmesh.k8s.aws/v1beta2/namespaces/my-apps/virtualnodes/my-service-a UID: 111a11b1-c11d-1e1f-gh1i-j11k1l111m711 Spec: Aws Name: my-service-a_my-apps Listeners: Port Mapping: Port: 80 Protocol: http Mesh Ref: Name: my-mesh UID: 111a11b1-c11d-1e1f-gh1i-j11k1l111m711 Pod Selector: Match Labels: App: nginx Service Discovery: Dns: Hostname: my-service-a.my-apps.svc.cluster.local Status: Conditions: Last Transition Time: 2020-06-17T14:57:29Z Status: True Type: VirtualNodeActive Observed Generation: 2 Virtual Node ARN: arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps Events: <none>
    4. 查看控制器在 App Mesh 中创建的虚拟节点的详细信息。

      注意

      尽管在 Kubernetes 中创建的虚拟节点的名称为 my-service-a,但在 App Mesh 中创建的虚拟节点的名称为 my-service-a_my-apps。控制器在创建 App Mesh 资源时,将 Kubernetes 命名空间名称附加到 App Mesh 虚拟节点名称。添加命名空间名称是因为在 Kubernetes 中,您可以在不同的命名空间中创建具有相同名称的虚拟节点,但在 App Mesh 中,虚拟节点名称在网格内必须唯一。

      aws appmesh describe-virtual-node --mesh-name my-mesh --virtual-node-name my-service-a_my-apps

      输出

      { "virtualNode": { "meshName": "my-mesh", "metadata": { "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps", "createdAt": "2020-06-17T09:57:29.840000-05:00", "lastUpdatedAt": "2020-06-17T09:57:29.840000-05:00", "meshOwner": "111122223333", "resourceOwner": "111122223333", "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711", "version": 1 }, "spec": { "backends": [], "listeners": [ { "portMapping": { "port": 80, "protocol": "http" } } ], "serviceDiscovery": { "dns": { "hostname": "my-service-a.my-apps.svc.cluster.local" } } }, "status": { "status": "ACTIVE" }, "virtualNodeName": "my-service-a_my-apps" } }
  4. 创建 App Mesh 虚拟路由器。虚拟路由器处理用于您的网格内一个或多个虚拟服务的流量。

    1. 将以下内容保存到计算机上名为 virtual-router.yaml 的文件中。该文件用于创建虚拟路由器,将流量路由到在上一步中创建的名为 my-service-a 的虚拟节点。控制器创建 App Mesh 虚拟路由器和路由资源。您可以为路由指定更多功能,以及使用 http 以外的协议。有关更多信息,请参阅 虚拟路由器路由。请注意,引用的虚拟节点名称是 Kubernetes 虚拟节点名称,而不是控制器在 App Mesh 中创建的 App Mesh 虚拟节点名称。

      apiVersion: appmesh.k8s.aws/v1beta2 kind: VirtualRouter metadata: namespace: my-apps name: my-service-a-virtual-router spec: listeners: - portMapping: port: 80 protocol: http routes: - name: my-service-a-route httpRoute: match: prefix: / action: weightedTargets: - virtualNodeRef: name: my-service-a weight: 1

      (可选)若要查看可在上述规范中设置的虚拟路由器的所有可用设置,请运行以下命令。

      aws appmesh create-virtual-router --generate-cli-skeleton yaml-input

      若要查看可在上述规范中设置的路由的所有可用设置,请运行以下命令。

      aws appmesh create-route --generate-cli-skeleton yaml-input
    2. 部署虚拟路由器。

      kubectl apply -f virtual-router.yaml
    3. 查看已创建的 Kubernetes 虚拟路由器资源。

      kubectl describe virtualrouter my-service-a-virtual-router -n my-apps

      缩减的输出

      Name: my-service-a-virtual-router Namespace: my-apps Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"VirtualRouter","metadata":{"annotations":{},"name":"my-service-a-virtual-router","namespac... API Version: appmesh.k8s.aws/v1beta2 Kind: VirtualRouter ... Spec: Aws Name: my-service-a-virtual-router_my-apps Listeners: Port Mapping: Port: 80 Protocol: http Mesh Ref: Name: my-mesh UID: 111a11b1-c11d-1e1f-gh1i-j11k1l111m711 Routes: Http Route: Action: Weighted Targets: Virtual Node Ref: Name: my-service-a Weight: 1 Match: Prefix: / Name: my-service-a-route Status: Conditions: Last Transition Time: 2020-06-17T15:14:01Z Status: True Type: VirtualRouterActive Observed Generation: 1 Route AR Ns: My - Service - A - Route: arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps/route/my-service-a-route Virtual Router ARN: arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps Events: <none>
    4. 查看控制器在 App Mesh 中创建的虚拟路由器资源。您可以为 name 指定 my-service-a-virtual-router_my-apps,因为当控制器在 App Mesh 中创建虚拟路由器时,它会在虚拟路由器的名称后附加 Kubernetes 命名空间名称。

      aws appmesh describe-virtual-router --virtual-router-name my-service-a-virtual-router_my-apps --mesh-name my-mesh

      输出

      { "virtualRouter": { "meshName": "my-mesh", "metadata": { "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps", "createdAt": "2020-06-17T10:14:01.547000-05:00", "lastUpdatedAt": "2020-06-17T10:14:01.547000-05:00", "meshOwner": "111122223333", "resourceOwner": "111122223333", "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711", "version": 1 }, "spec": { "listeners": [ { "portMapping": { "port": 80, "protocol": "http" } } ] }, "status": { "status": "ACTIVE" }, "virtualRouterName": "my-service-a-virtual-router_my-apps" } }
    5. 查看控制器在 App Mesh 中创建的路由资源。未在 Kubernetes 中创建路由资源,因为该路由是 Kubernetes 中虚拟路由器配置的一部分。路由信息显示在子步骤 c 的 Kubernetes 资源详细信息中。控制器在 App Mesh 中创建路由时,不将 Kubernetes 命名空间名称附加到 App Mesh 路由名称,因为路由名称对虚拟路由器唯一。

      aws appmesh describe-route \ --route-name my-service-a-route \ --virtual-router-name my-service-a-virtual-router_my-apps \ --mesh-name my-mesh

      输出

      { "route": { "meshName": "my-mesh", "metadata": { "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualRouter/my-service-a-virtual-router_my-apps/route/my-service-a-route", "createdAt": "2020-06-17T10:14:01.577000-05:00", "lastUpdatedAt": "2020-06-17T10:14:01.577000-05:00", "meshOwner": "111122223333", "resourceOwner": "111122223333", "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711", "version": 1 }, "routeName": "my-service-a-route", "spec": { "httpRoute": { "action": { "weightedTargets": [ { "virtualNode": "my-service-a_my-apps", "weight": 1 } ] }, "match": { "prefix": "/" } } }, "status": { "status": "ACTIVE" }, "virtualRouterName": "my-service-a-virtual-router_my-apps" } }
  5. 创建 App Mesh 虚拟服务。虚拟服务是一种抽象的实际服务,由虚拟节点直接提供或通过虚拟路由器的方式间接提供。从属服务按名称调用您的虚拟服务。虽然名称对于 App Mesh 并不重要,但建议将虚拟服务命名为虚拟服务所代表的实际服务的完全限定域名。通过这种方式命名虚拟服务,您无需更改应用程序代码即可引用其他名称。请求路由到指定作为虚拟服务提供程序的虚拟节点或虚拟路由器。

    1. 将以下内容保存到计算机上名为 virtual-service.yaml 的文件中。该文件用于创建虚拟服务,使用虚拟路由器提供程序将流量路由到在上一步中创建的名为 my-service-a 的虚拟节点。specawsName 的值是此虚拟服务所提取的实际 Kubernetes 服务的完全限定域名 (FQDN)。Kubernetes 服务在 步骤 3:创建或更新服务 中创建。有关更多信息,请参阅虚拟服务

      apiVersion: appmesh.k8s.aws/v1beta2 kind: VirtualService metadata: name: my-service-a namespace: my-apps spec: awsName: my-service-a.my-apps.svc.cluster.local provider: virtualRouter: virtualRouterRef: name: my-service-a-virtual-router

      若要查看可在上述规范中设置的虚拟服务的所有可用设置,请运行以下命令。

      aws appmesh create-virtual-service --generate-cli-skeleton yaml-input
    2. 创建虚拟服务。

      kubectl apply -f virtual-service.yaml
    3. 查看已创建的 Kubernetes 虚拟服务资源的详细信息。

      kubectl describe virtualservice my-service-a -n my-apps

      输出

      Name: my-service-a Namespace: my-apps Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"appmesh.k8s.aws/v1beta2","kind":"VirtualService","metadata":{"annotations":{},"name":"my-service-a","namespace":"my-apps"}... API Version: appmesh.k8s.aws/v1beta2 Kind: VirtualService Metadata: Creation Timestamp: 2020-06-17T15:48:40Z Finalizers: finalizers.appmesh.k8s.aws/aws-appmesh-resources Generation: 1 Resource Version: 13598 Self Link: /apis/appmesh.k8s.aws/v1beta2/namespaces/my-apps/virtualservices/my-service-a UID: 111a11b1-c11d-1e1f-gh1i-j11k1l111m711 Spec: Aws Name: my-service-a.my-apps.svc.cluster.local Mesh Ref: Name: my-mesh UID: 111a11b1-c11d-1e1f-gh1i-j11k1l111m711 Provider: Virtual Router: Virtual Router Ref: Name: my-service-a-virtual-router Status: Conditions: Last Transition Time: 2020-06-17T15:48:40Z Status: True Type: VirtualServiceActive Observed Generation: 1 Virtual Service ARN: arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualService/my-service-a.my-apps.svc.cluster.local Events: <none>
    4. 查看控制器在 App Mesh 中创建的虚拟服务资源的详细信息。Kubernetes 控制器在 App Mesh 中创建虚拟服务时,不将 Kubernetes 命名空间名称附加到 App Mesh 虚拟服务名称,因为虚拟服务的名称是唯一的 FQDN。

      aws appmesh describe-virtual-service --virtual-service-name my-service-a.my-apps.svc.cluster.local --mesh-name my-mesh

      输出

      { "virtualService": { "meshName": "my-mesh", "metadata": { "arn": "arn:aws:appmesh:us-west-2:111122223333:mesh/my-mesh/virtualService/my-service-a.my-apps.svc.cluster.local", "createdAt": "2020-06-17T10:48:40.182000-05:00", "lastUpdatedAt": "2020-06-17T10:48:40.182000-05:00", "meshOwner": "111122223333", "resourceOwner": "111122223333", "uid": "111a11b1-c11d-1e1f-gh1i-j11k1l111m711", "version": 1 }, "spec": { "provider": { "virtualRouter": { "virtualRouterName": "my-service-a-virtual-router_my-apps" } } }, "status": { "status": "ACTIVE" }, "virtualServiceName": "my-service-a.my-apps.svc.cluster.local" } }

尽管本教程中没有介绍,但控制器也可以部署 App Mesh 虚拟网关网关路由。有关使用控制器部署这些资源的演练,请参阅配置入站网关或包含上 GitHub资源的示例清单

步骤 3:创建或更新服务

您想要和 App Mesh 配合使用的任何容器组 (pod) 必须已经添加了 App Mesh sidecar 容器。注入器会自动将 sidecar 容器添加到使用您指定的标签部署的任意容器组 (pod) 中。

  1. 启用代理授权。我们建议您启用每个 Kubernetes 部署,以仅流式传输自己的 App Mesh 虚拟节点的配置。

    1. 将以下内容保存到计算机上名为 proxy-auth.json 的文件中。请确保将 alternate-colored values 替换为您自己的值。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "appmesh:StreamAggregatedResources", "Resource": [ "arn:aws:appmesh:Region-code:111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps" ] } ] }
    2. 创建 策略。

      aws iam create-policy --policy-name my-policy --policy-document file://proxy-auth.json
    3. 创建 IAM 角色,将您在上一步中创建的策略附加到该角色,创建 Kubernetes 服务账户并将策略绑定到该 Kubernetes 服务账户。该角色使控制器能够添加、删除和更改 App Mesh 资源。

      eksctl create iamserviceaccount \ --cluster $CLUSTER_NAME \ --namespace my-apps \ --name my-service-a \ --attach-policy-arn arn:aws:iam::111122223333:policy/my-policy \ --override-existing-serviceaccounts \ --approve

      如果您更喜欢使用 Amazon Web Services Management Console 或创建服务账户 Amazon CLI,请参阅 A mazon EKS 用户指南中的为您的服务账户创建 IAM 角色和策略。如果您使用 Amazon Web Services Management Console 或 Amazon CLI 来创建账户,则还需要将该角色映射到 Kubernetes 服务帐号。有关更多信息,请参阅《Amazon EKS 用户指南》中的为集群上的服务账户指定 IAM 角色

  2. (可选)如果您的部署要部署到 Fargate 容器组 (pod),则需要创建 Fargate 配置文件。如果未安装 eksctl,则可以按照《Amazon EKS 用户指南》安装或升级 eksctl上的说明安装它。如果您希望使用控制台创建配置文件,请参阅《Amazon EKS 用户指南》中的创建 Fargate 配置文件

    eksctl create fargateprofile --cluster my-cluster --region Region-code --name my-service-a --namespace my-apps
  3. 创建 Kubernetes 服务和部署。如果您有要和 App Mesh 配合使用的现有部署,则需要部署一个虚拟节点,就像在 步骤 2:部署 App Mesh 资源 的子步骤 3 中所做的那样。更新您的部署,确保其标签与您在虚拟节点上设置的标签相匹配,这样 sidecar 容器就会自动添加到容器组 (pod) 中,并重新部署容器组 (pod)。

    1. 将以下内容保存到计算机上名为 example-service.yaml 的文件中。如果您更改命名空间名称并使用 Fargate 容器组 (pod),请确保命名空间名称与您在 Fargate 配置文件中定义的命名空间名称匹配。

      apiVersion: v1 kind: Service metadata: name: my-service-a namespace: my-apps labels: app: my-app-1 spec: selector: app: my-app-1 ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: my-service-a namespace: my-apps labels: app: my-app-1 spec: replicas: 3 selector: matchLabels: app: my-app-1 template: metadata: labels: app: my-app-1 spec: serviceAccountName: my-service-a containers: - name: nginx image: nginx:1.19.0 ports: - containerPort: 80
      重要

      规范中 app matchLabels selector 中的值必须与您在 步骤 2:部署 App Mesh 资源 的子步骤 3 中创建虚拟节点时指定的值相匹配,否则 sidecar 容器将不会注入到容器组 (pod)中。在前面的示例中,标签的值为 my-app-1。如果您部署的是虚拟网关而不是虚拟节点,则 Deployment 清单应仅包含 Envoy 容器。有关要使用的镜像的更多信息,请参阅 Envoy 镜像。如需查看样本 manfest,请参阅中的部署示例。 GitHub

    2. 部署服务。

      kubectl apply -f example-service.yaml
    3. 查看服务和部署。

      kubectl -n my-apps get pods

      输出

      NAME READY STATUS RESTARTS AGE my-service-a-54776556f6-2cxd9 2/2 Running 0 10s my-service-a-54776556f6-w26kf 2/2 Running 0 18s my-service-a-54776556f6-zw5kt 2/2 Running 0 26s
    4. 查看已部署的容器组 (pod) 之一的详细信息。

      kubectl -n my-apps describe pod my-service-a-54776556f6-2cxd9

      缩减的输出

      Name: my-service-a-54776556f6-2cxd9 Namespace: my-app-1 Priority: 0 Node: ip-192-168-44-157.us-west-2.compute.internal/192.168.44.157 Start Time: Wed, 17 Jun 2020 11:08:59 -0500 Labels: app=nginx pod-template-hash=54776556f6 Annotations: kubernetes.io/psp: eks.privileged Status: Running IP: 192.168.57.134 IPs: IP: 192.168.57.134 Controlled By: ReplicaSet/my-service-a-54776556f6 Init Containers: proxyinit: Container ID: docker://e0c4810d584c21ae0cb6e40f6119d2508f029094d0e01c9411c6cf2a32d77a59 Image: 111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager:v2 Image ID: docker-pullable://111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager Port: <none> Host Port: <none> State: Terminated Reason: Completed Exit Code: 0 Started: Fri, 26 Jun 2020 08:36:22 -0500 Finished: Fri, 26 Jun 2020 08:36:22 -0500 Ready: True Restart Count: 0 Requests: cpu: 10m memory: 32Mi Environment: APPMESH_START_ENABLED: 1 APPMESH_IGNORE_UID: 1337 APPMESH_ENVOY_INGRESS_PORT: 15000 APPMESH_ENVOY_EGRESS_PORT: 15001 APPMESH_APP_PORTS: 80 APPMESH_EGRESS_IGNORED_IP: 169.254.169.254 APPMESH_EGRESS_IGNORED_PORTS: 22 AWS_ROLE_ARN: arn:aws:iam::111122223333:role/eksctl-app-mesh-addon-iamserviceaccount-my-a-Role1-NMNCVWB6PL0N AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token ... Containers: nginx: Container ID: docker://be6359dc6ecd3f18a1c87df7b57c2093e1f9db17d5b3a77f22585ce3bcab137a Image: nginx:1.19.0 Image ID: docker-pullable://nginx Port: 80/TCP Host Port: 0/TCP State: Running Started: Fri, 26 Jun 2020 08:36:28 -0500 Ready: True Restart Count: 0 Environment: AWS_ROLE_ARN: arn:aws:iam::111122223333:role/eksctl-app-mesh-addon-iamserviceaccount-my-a-Role1-NMNCVWB6PL0N AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token ... envoy: Container ID: docker://905b55cbf33ef3b3debc51cb448401d24e2e7c2dbfc6a9754a2c49dd55a216b6 Image: 840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.12.4.0-prod Image ID: docker-pullable://840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy Port: 9901/TCP Host Port: 0/TCP State: Running Started: Fri, 26 Jun 2020 08:36:36 -0500 Ready: True Restart Count: 0 Requests: cpu: 10m memory: 32Mi Environment: APPMESH_RESOURCE_ARN: arn:aws:iam::111122223333:mesh/my-mesh/virtualNode/my-service-a_my-apps APPMESH_PREVIEW: 0 ENVOY_LOG_LEVEL: info AWS_REGION: us-west-2 AWS_ROLE_ARN: arn:aws:iam::111122223333:role/eksctl-app-mesh-addon-iamserviceaccount-my-a-Role1-NMNCVWB6PL0N AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulling 30s kubelet, ip-192-168-44-157.us-west-2.compute.internal Pulling image "111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager:v2" Normal Pulled 23s kubelet, ip-192-168-44-157.us-west-2.compute.internal Successfully pulled image "111345817488.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-proxy-route-manager:v2" Normal Created 21s kubelet, ip-192-168-44-157.us-west-2.compute.internal Created container proxyinit Normal Started 21s kubelet, ip-192-168-44-157.us-west-2.compute.internal Started container proxyinit Normal Pulling 20s kubelet, ip-192-168-44-157.us-west-2.compute.internal Pulling image "nginx:1.19.0" Normal Pulled 16s kubelet, ip-192-168-44-157.us-west-2.compute.internal Successfully pulled image "nginx:1.19.0" Normal Created 15s kubelet, ip-192-168-44-157.us-west-2.compute.internal Created container nginx Normal Started 15s kubelet, ip-192-168-44-157.us-west-2.compute.internal Started container nginx Normal Pulling 15s kubelet, ip-192-168-44-157.us-west-2.compute.internal Pulling image "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.12.4.0-prod" Normal Pulled 8s kubelet, ip-192-168-44-157.us-west-2.compute.internal Successfully pulled image "840364872350.dkr.ecr.us-west-2.amazonaws.com/aws-appmesh-envoy:v1.12.4.0-prod" Normal Created 7s kubelet, ip-192-168-44-157.us-west-2.compute.internal Created container envoy Normal Started 7s kubelet, ip-192-168-44-157.us-west-2.compute.internal Started container envoy

      在前面的输出中,您可以看到控制器已将 proxyinitenvoy 容器添加到容器组 (pod)。如果您将示例服务部署到 Fargate,则控制器会将 envoy 容器添加到容器组 (pod) 中,但 proxyinit 容器不是。

  4. (可选)安装插件,例如 Prometheus、Grafana、Jaeger 和 Datadog。 Amazon X-Ray有关更多信息,请参阅 App Mesh 插件 GitHub 和《App Mesh 用户指南》的 “可观察性” 部分。

注意

有关 App Mesh 的更多示例和演练,请参阅 App Mesh 示例存储库

步骤 4:清除

删除本教程中创建的所有示例资源。控制器还会删除在 my-mesh App Mesh 服务网格中创建的资源。

kubectl delete namespace my-apps

如果您为示例服务创建了 Fargate 配置文件,请将其删除。

eksctl delete fargateprofile --name my-service-a --cluster my-cluster --region Region-code

删除网格。

kubectl delete mesh my-mesh

(可选)您可以删除 Kubernetes 集成组件。

helm delete appmesh-controller -n appmesh-system

(可选)如果您将 Kubernetes 集成组件部署到 Fargate,请删除 Fargate 配置文件。

eksctl delete fargateprofile --name appmesh-system --cluster my-cluster --region Region-code