将 Istio 与 Google Compute Engine 搭配使用

Istio 是一个开源框架,用于连接、监控和保护微服务。这让您可创建部署服务的网络(即“网格”)并进行负载平衡、服务到服务身份验证、监控等,而无需对服务代码进行任何更改。您可以向应用的每个 pod 部署一个特殊的 Envoy Sidecar 代理,从而为各项服务添加 Istio 支持。Envoy 代理拦截微服务之间的所有网络通信,并通过 Istio 的控制平面功能进行配置和管理。

目前,Istio 的控制平面只能安装在 Kubernetes 实现(例如 Google Kubernetes Engine)上,但其网格扩展功能意味着您可以将在非 Kubernetes 平台上运行的服务(包括 Compute Engine 虚拟机上运行的服务)添加到服务网格中。这让您可将 Kubernetes 和虚拟机服务整合为一个网格加以控制。本教程向您介绍如何配置 Istio 以使用网格扩展功能,并配置 Compute Engine 虚拟机以将其添加到 Istio 网格中。此处假定您已经在 Kubernetes Engine 上安装了 Istio。

您可以在 Istio 官方网站(即 istio.io)上找到有关 Istio 及其工作原理的更多信息。如果您有兴趣了解本教程中所用的网格扩展配置的运作方式,可参阅工作原理,尽管您无需阅读该文档也可完成本教程,但仍不妨一读。

目标

  • 在 Kubernetes Engine 上更新目前安装的 Istio 以使用网格扩展功能
  • 配置 Compute Engine 虚拟机以加入 Istio 服务网格
  • 在 Compute Engine 虚拟机上运行 Istio 网格服务

费用

本教程使用 Cloud Platform 的计费组件,包括 Compute Engine。

Cloud Platform 新用户可能有资格免费试用

准备工作

  • 您必须已经在 Kubernetes Engine 上安装了 Istio:您可以参阅在 Google Kubernetes Engine 上安装 Istio,以了解具体操作方法及相关设置和要求。
  • 您必须安装并运行 BookInfo 示例应用(详情也请参阅在 Google Kubernetes Engine 上安装 Istio 中的说明),并确保您的 PATH 中有 istioctl
  • 您必须有足够的 IP 地址和后端服务配额才能运行上一个教程中的四个内部负载平衡器(每个均包含一个负载平衡器和一个 IP 地址)和 BookInfo 的入站流量服务(一个负载平衡器和一个 IP 地址)。
  • 确保已将您的 kubectl 上下文设置为您的 Istio 集群。

    kubectl config current-context              # Display the current-context
    kubectl config use-context [CLUSTER_NAME]   # set the default context to [CLUSTER_NAME]
    

gcloud 命令行工具设置默认值

为了节省您在 gcloud 命令行工具中输入项目 IDCompute Engine 地区选项的时间,您可以设置默认值:
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

设置网格以使用扩展功能

将非 Kubernetes 服务添加到 Istio 网格的第一步是:配置 Istio 安装本身,并生成相应配置文件以便 Compute Engine 虚拟机能够使用 Istio。您的 Istio 下载包中包含了一个脚本,可帮助您在 Kubernetes Engine 上执行上述操作。您可以在 /install/tools/setupMeshEx.sh 中找到该脚本。在 Istio 安装目录和集群凭据所在的机器(这就是您的集群管理机)上执行以下步骤。

  1. 使用所提供的 mesh-expansion 部署,为 PilotMixer、Istio 证书授权机构和 Kubernetes DNS 服务器设置内部负载平衡器。这确保了可以通过虚拟机访问这些服务。

    kubectl apply -f install/kubernetes/mesh-expansion.yaml
    
  2. 确认服务已启动并运行,且所有内部负载平衡器都具有 EXTERNAL-IP 值(您可能需要等待片刻)后,才能继续下一步:

    $ kubectl -n istio-system get services
    NAME              TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                                                  AGE
    istio-ca-ilb      LoadBalancer   10.47.245.69    10.150.0.9       8060:32174/TCP                                           3m
    istio-egress      ClusterIP      10.47.252.251   <none>           80/TCP                                                   7m
    istio-ingress     LoadBalancer   10.47.254.41    35.197.249.113   80:31822/TCP,443:30637/TCP                               7m
    istio-mixer       ClusterIP      10.47.244.179   <none>           9091/TCP,9093/TCP,9094/TCP,9102/TCP,9125/UDP,42422/TCP   8m
    istio-pilot       ClusterIP      10.47.241.19    <none>           8080/TCP,443/TCP                                         7m
    istio-pilot-ilb   LoadBalancer   10.47.243.136   10.150.0.6       8080:30064/TCP                                           3m
    mixer-ilb         LoadBalancer   10.47.242.213   10.150.0.8       9091:31278/TCP                                           3m
  3. 在您的 Istio 安装目录中,使用帮助程序脚本生成要部署在虚拟机中的 Istio cluster.env 配置,指定您自己的集群名称。该文件包含要拦截的集群 IP 地址范围。

    install/tools/setupMeshEx.sh generateClusterEnv [CLUSTER_NAME]
    

    这会创建一个单行文件,如下所示:

    $ cat cluster.env
    ISTIO_SERVICE_CIDR=10.63.240.0/20
  4. 现在,利用相同的脚本生成要在虚拟机中使用的 DNS 配置文件。这可以让 Compute Engine 虚拟机上的应用通过 dnsmasq 来解析集群服务名称,这些名称将被 Sidecar 拦截并转发。

    install/tools/setupMeshEx.sh generateDnsmasq
    

    生成的文件示例:

    $ cat kubedns
    server=/svc.cluster.local/10.150.0.7
    address=/istio-mixer/10.150.0.8
    address=/istio-pilot/10.150.0.6
    address=/istio-ca/10.150.0.9
    address=/istio-mixer.istio-system/10.150.0.8
    address=/istio-pilot.istio-system/10.150.0.6
    address=/istio-ca.istio-system/10.150.0.9

设置网格扩展虚拟机

您设置网格并生成了相关配置文件后,下一步就是配置 Compute Engine 虚拟机以将其加入网格,其中包括将生成的文件复制到虚拟机。在本教程中为了方便起见,您可以再次使用所提供的 setupMeshEx.sh 脚本来复制文件并配置机器。但是,在将您自己的虚拟机添加到实际的网格应用中时,您应该手动执行这些步骤,以便将其集成到您自己的工作流和配置中。您可以在 Istio 的网格扩展指南中找到详细步骤,并在 /install/tools/setupIstioVM.sh 中查看 setupMeshEx.sh 在各虚拟机上运行的脚本。

  1. 首先确保您有一个 Compute Engine 虚拟机,以便在 Istio 所在的项目和网络中用作网格扩展机。如果您还没有,请创建一个:

    gcloud compute instances create istio-vm
    
  2. Istio 可以跨多个 Kubernetes 命名空间管理服务:在本示例中,您会将虚拟机服务(即使该服务不在 Kubernetes 上)放在 vm 命名空间中,因为提供的 BookInfo 路由规则将会在这里查找该服务。像这样使用不同的命名空间可以帮助您将虚拟机服务与常规的 Kubernetes 服务区分开。若要为网格扩展机使用某个非默认命名空间,您需要在运行设置脚本之前指定此命名空间。在集群管理机上的 Istio 安装目录中,首先设置 SERVICE_NAMESPACE 变量:

    export SERVICE_NAMESPACE=vm
    

    然后创建命名空间:

    kubectl create namespace $SERVICE_NAMESPACE
    
  3. 仍然在集群管理机上,通过 setupMeshEx.sh 设置脚本运行以下命令。此脚本将执行以下操作:

    • 将生成的文件和虚拟机设置脚本复制到虚拟机
    • 配置和验证 DNS 设置,将虚拟机连接到 Istio 组件
    • 将 Istio 身份验证密钥复制到虚拟机
    • 在虚拟机上安装 Istio Debian 文件,包括 Istio Sidecar 代理
    install/tools/setupMeshEx.sh machineSetup istio-vm
  4. 使用 gcloud 或相应虚拟机实例详情控制台页面(可在虚拟机实例页面中找到其链接)上的其他任何选项,通过 SSH 登录到 Compute Engine 虚拟机。

    gcloud compute ssh istio-vm
    
  5. 在 Compute Engine 虚拟机上,验证配置好的机器能否访问 Kubernetes Engine 集群中运行的服务。例如,如果您要在 Kubernetes Engine 集群中运行在 Google Kubernetes Engine 上安装 Istio 中的 BookInfo 示例,则应该可以通过 curl 从虚拟机访问 productpage 服务,如以下示例所示:

    $ curl -v -w "\n" http://productpage.default.svc.cluster.local:9080/api/v1/products/0/ratings
    *   Trying 10.63.251.156...
    * Connected to productpage.default.svc.cluster.local (10.63.251.156) port 9080 (#0)
    > GET /api/v1/products/0/ratings HTTP/1.1
    > Host: productpage.default.svc.cluster.local:9080
    > User-Agent: curl/7.47.0
    > Accept: /
    >
    < HTTP/1.1 200 OK
    < content-type: application/json
    < content-length: 54
    < server: envoy
    < date: Sun, 15 Oct 2017 00:04:49 GMT
    < x-envoy-upstream-service-time: 17
    <

    • Connection #0 to host productpage.default.svc.cluster.local left intact {"ratings": {"Reviewer2": 4, "Reviewer1": 5}, "id": 0}
  6. 请注意,在 BookInfo 示例中,此处的产品页面网址中所使用的 default 是在上一个教程里的默认命名空间中创建的;如果您之前选择了使用其他命名空间,则应在此进行替换。

  7. 在虚拟机上再次检查 Istio 进程是否正在运行:

    $ sudo systemctl status istio-auth-node-agent
    istio-auth-node-agent.service - istio-auth-node-agent: The Istio auth node agent
      Loaded: loaded (/lib/systemd/system/istio-auth-node-agent.service; disabled; vendor preset: enabled)
      Active: active (running) since Fri 2017-10-13 21:32:29 UTC; 9s ago
      Docs: http://istio.io/
    Main PID: 6941 (node_agent)
      Tasks: 5
      Memory: 5.9M
      CPU: 92ms
      CGroup: /system.slice/istio-auth-node-agent.service
              └─6941 /usr/local/istio/bin/node_agent --logtostderr
    
    Oct 13 21:32:29 demo-vm-1 systemd[1]: Started istio-auth-node-agent: The Istio auth node agent.
    Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.469314    6941 main.go:66] Starting Node Agent
    Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.469365    6941 nodeagent.go:96] Node Agent starts successfully.
    Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.483324    6941 nodeagent.go:112] Sending CSR (retrial #0) ...
    Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.862575    6941 nodeagent.go:128] CSR is approved successfully. Will renew cert in 29m59.137732603s

在网格扩展机上运行服务

现在我们了解一下在网格扩展机上运行服务需要做些什么。在本示例中,您将使用在上一部分中配置的虚拟机,通过一个在 Compute Engine 虚拟机上运行的 MySQL 评分数据库来扩展在 Google Kubernetes Engine 上安装 Istio 中的 BookInfo 示例。

  1. 如上所述,确保已将 istio-vm 配置为正在运行 BookInfo 的集群的网格扩展虚拟机。

  2. 在 Compute Engine 虚拟机上安装 MySQL 服务器:

    sudo apt-get update && sudo apt-get install --no-install-recommends -y mariadb-server
    
  3. 在本教程中(在实际应用中请不要这样做),配置 MySQL 服务器,将“root”用户的密码设为“password”:

    sudo mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by 'password'; flush privileges"
    
  4. 然后,使用提供的 mysqldb-init.sql 架构来设置 BookInfo 评分数据库。

    curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql| mysql -u root --password=password -h 127.0.0.1
    
  5. 接下来,使用 istioctl 在安装的 Istio 中注册新服务。首先,获取虚拟机的内部主 IP 地址(您可以在控制台中相应的虚拟机实例详情页面上查看此地址,也可以使用 hostname --ip-address)。然后,在您的集群管理机上运行以下命令,注意替换成相应的 IP 地址:

    $ istioctl register -n vm mysqldb 10.150.0.5 3306
    I1014 22:54:12.176972   18162 register.go:44] Registering for service 'mysqldb' ip '10.150.0.5', ports list [{3306 mysql}]
  6. 仍在集群管理机上,更新 BookInfo 部署以改用 MySQL 数据库版的评分服务版本,并更新路由以便将流量发送到该服务。

    $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql-vm.yaml)
    deployment "ratings-v2-mysql-vm" created
    $ kubectl get pods -lapp=ratings
    NAME                                   READY     STATUS    RESTARTS   AGE
    ratings-v1-3016823457-mqbfx            2/2       Running   0          24m
    ratings-v2-mysql-vm-1319199664-9jxkp   2/2       Running   0          19s
    $ istioctl create -f samples/bookinfo/kube/route-rule-ratings-mysql-vm.yaml
    Created config route-rule/default/ratings-test-v2-mysql-vm at revision 4398
    Created config route-rule/default/reviews-test-ratings-v2-vm at revision 4399
  7. 最后,回到 Compute Engine 虚拟机上,配置 istio-vm 的 Istio 代理 Sidecar,以拦截相关端口(注册服务时所指定的端口,在本示例中为 3306)上的流量。您可以通过在 /var/lib/istio/envoy/sidecar.env 文件中添加以下三行代码来配置该 Sidecar。

    $ sudo vi /var/lib/istio/envoy/sidecar.env
    ...
    ISTIO_INBOUND_PORTS=3306
    ISTIO_SERVICE=mysqldb
    ISTIO_NAMESPACE=vm
    

    更改配置后,您需要重新启动 Sidecar。

    sudo systemctl restart istio
    
  8. 在您完成所有这些操作后,BookInfo 应用的评分服务应该已在使用新的网格扩展数据库。尝试更改虚拟机上评分数据库中的值,并查看它们是否会出现在 BookInfo 应用的产品页面中。

    $ mysql -u root -h 127.0.0.1 --password=password test -e "select * from ratings"
    +----------+--------+
    | ReviewID | Rating |
    +----------+--------+
    |        1 |      5 |
    |        2 |      4 |
    +----------+--------+
    # Change to 1 star:
    $ mysql -u root --password=password test -e "update ratings set rating=1 where reviewid=1"
    

    界面中已更新的评分

工作原理

当虚拟机上的应用想要向网格中的其他服务发出请求时,它必须使用 DNS 来解析名称,从而获取服务 IP(或集群 IP,即分配给该服务的 VIP)。在 Istio 的特殊网格扩展虚拟机配置中,虚拟机应用使用 dnsmasq 来解析名称,它会将所有 .cluster.local 地址重定向到 Kubernetes。dnsmasq 设置还会将 127.0.0.1 添加到 resolv.conf,并在必要时将 DHCP 配置为在每次 DHCP 解析后插入该地址。

当应用实际发出请求时,Istio 虚拟机设置将使用 ipnames 通过 Envoy 代理重定向该请求。然后,代理连接到 Istio-Pilot 服务以获取端点列表,并在应用规则后将请求转发到适当的网格端点。

清理

为避免系统因本教程中使用的资源向您的 Google Cloud Platform 帐号收取费用,请执行以下操作:

如果您不想在后续步骤中继续探索 BookInfo 应用,请执行以下操作:

  1. 删除示例所用的各种内部负载平衡器:

    kubectl -n istio-system delete service --all
    kubectl -n kube-system delete service dns-ilb
    
  2. 通过监视以下命令的输出结果,等待所有负载平衡器删除完毕:

    gcloud compute forwarding-rules list
    
  3. 删除容器集群:

    gcloud container clusters delete [CLUSTER_NAME]
    
  4. 删除数据库虚拟机:

    gcloud compute instances delete istio-vm
    

后续步骤

Istio 网站提供了更多指南和示例,其中包含可供您进行试验的 Istio 完整有效示例。其中包括:

  • 智能路由:此示例展示了如何通过 BookInfo 使用 Istio 的各种流量管理功能,包括本教程上一部分所用的路由规则。

  • 深入遥测:此示例演示了如何通过 Istio Mixer 和 Istio Sidecar 代理从各项 BookInfo 服务中提取统一的指标、日志和跟踪记录。

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Compute Engine 文档