安装 Istio

本页面介绍如何在 GKE On-Prem 集群中安装 Istio。

概览

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

本指南介绍如何在 GKE On-Prem 上安装和配置 Istio,以及部署一个启用 Istio 的多服务演示应用。

准备工作

确保您已安装 Cloud SDK

安装 Helm

要安装 Istio,我们建议将 Helm 与 Istio 的一个可配置的配置文件搭配使用。

如果您尚未安装 Helm,请按照 Helm README 中的说明在集群凭据所在的机器上安装 helm 二进制文件。

权限和凭据

  1. 确保您拥有要安装 Istio 的 GKE On-Prem 用户集群的 kubectl 凭据。请注意,Istio 只能安装在 GKE On-Prem 用户集群上,不能安装在管理员集群上。

  2. 向当前用户授予集群管理员权限。您需要这些权限才能为 Istio 创建必要的基于角色的访问权限控制 (RBAC) 规则:

    kubectl create clusterrolebinding cluster-admin-binding \
      --clusterrole=cluster-admin \
      --user="$(gcloud config get-value core/account)"
    

    虽然您可以在不授予集群管理员权限的情况下运行演示版应用,但如果要访问遥测数据和其他 Istio 功能,则需要这些权限。

下载 Istio

对于 GKE On-Prem,我们建议使用 Istio 版本 1.1.13。

在集群凭据所在的机器上按照以下步骤操作:这是您的集群管理机。

  1. 使用以下命令下载 Istio 1.1.13 软件包并将其在当前目录中展开:

    curl -L https://github.com/istio/istio/releases/download/1.1.13/istio-1.1.13-linux.tar.gz | tar xz
    

    安装目录包含:

    • install/ 中 Kubernetes 的安装 .yaml 文件
    • samples/ 中的示例应用
    • bin/ 目录中的 istioctl 客户端二进制文件。手动注入 Envoy 作为 Sidecar 代理以及创建路由规则和政策时会用到 istioctl
    • istio.VERSION 配置文件
  2. 转到安装根目录,并将 istioctl 添加到 PATH

    cd  istio-1.1.13
    export PATH=$PATH:${PWD}/bin
    

设置命名空间和证书

仍然在集群管理机上,执行以下操作,为控制平面组件设置 istio-system 命名空间:

kubectl create namespace istio-system

然后,将所需的根证书复制到 Citadel 的 istio-system 中。这对于 GKE On-Prem 集群来说是必需的:

kubectl get secret istio-ca-secret --namespace=kube-system --export -o yaml | kubectl apply --validate=false --namespace=istio-system -f -

安装 Istio

现在您可以开始安装 Istio 了。Istio 安装在您刚才创建的 istio-system 命名空间中,并且可以管理来自所有其他命名空间的微服务。安装包括 Istio 核心组件、工具和示例。

  1. 确保您位于 Istio 安装的根目录中。

  2. 安装 Istio 自定义资源定义 (CRD):

    helm template install/kubernetes/helm/istio-init \
      --name istio-init --namespace istio-system | kubectl apply -f -
    
  3. 等待几秒钟,以便在 Kubernetes API 服务器中提交所有 CRD。

  4. 使用默认配置文件安装 Istio。虽然您可以选择其他配置文件,但我们建议使用适用于生产部署的默认配置文件。

    helm template install/kubernetes/helm/istio \
      --name istio --namespace istio-system | kubectl apply -f -
    

    这将部署核心 Istio 组件:

    • Istio-Pilot,负责发现服务以及在 Istio 服务网格中配置 Envoy 辅助信息文件代理。
    • Mixer 组件 Istio-Policy 和 Istio-Telemetry,这些组件实施使用政策并收集服务网格中的遥测数据。
    • Istio-Ingressgateway,为集群外部的流量提供入站点。
    • Istio-Citadel,针对 Istio 自动执行密钥和证书管理。

验证 Istio 安装

  1. 确保已部署以下 Kubernetes 服务:istio-citadelistio-pilotistio-ingressgatewayistio-policyistio-telemetry(您也会看到其他已部署的服务):

    kubectl get service -n istio-system
    
    输出:
    NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                               AGE
    ...
    istio-citadel              ClusterIP      10.19.253.95            8060/TCP,9093/TCP                                                     37s
    istio-galley               ClusterIP      10.19.245.2             443/TCP,15014/TCP,9901/TCP                                            37s
    istio-ingressgateway       LoadBalancer   10.19.247.233        80:31380/TCP,443:31390/TCP,31400:31400/TCP                            40s
    istio-pilot                ClusterIP      10.19.243.14            15003/TCP,15005/TCP,15007/TCP,15010/TCP,15011/TCP,8080/TCP,9093/TCP   38s
    istio-policy               ClusterIP      10.19.254.117           9091/TCP,15004/TCP,9093/TCP                                           39s
    istio-sidecar-injector     ClusterIP      10.19.248.228           443/TCP                                                               37s
    istio-statsd-prom-bridge   ClusterIP      10.19.252.35            9102/TCP,9125/UDP                                                     39s
    istio-telemetry            ClusterIP      10.19.250.11            9091/TCP,15004/TCP,9093/TCP,42422/TCP                                 39s
    ...
  2. 确保已部署相应的 Kubernetes Pod,并且所有容器均正常运行:istio-pilot-*istio-policy-*istio-telemetry-*istio-ingressgateway-*istio-citadel-*

    kubectl get pods -n istio-system
    
    输出:
    NAME                                        READY     STATUS      RESTARTS   AGE
    istio-citadel-54f4678f86-4549b              1/1       Running     0          12m
    istio-cleanup-secrets-5pl77                 0/1       Completed   0          12m
    istio-galley-7bd8b5f88f-nhwlc               1/1       Running     0          12m
    istio-ingressgateway-665699c874-l62rg       1/1       Running     0          12m
    istio-pilot-68cbbcd65d-l5298                2/2       Running     0          12m
    istio-policy-7c5b5bb744-k6vm9               2/2       Running     0          12m
    istio-security-post-install-g9l9p           0/1       Completed   3          12m
    istio-sidecar-injector-85ccf84984-2hpfm     1/1       Running     0          12m
    istio-telemetry-5b6c57fffc-9j4dc            2/2       Running     0          12m
    istio-tracing-77f9f94b98-jv8vh              1/1       Running     0          12m
    prometheus-7456f56c96-7hrk5                 1/1       Running     0          12m
    ...

配置外部 IP 地址

默认 Istio 安装假设外部 IP 地址会自动分配给 LoadBalancer 服务。但在 GKE On-Prem 集群中却并非如此。因此,您需要手动为 Istio 入站网关资源分配 IP 地址。

要配置外部 IP 地址,请根据集群的负载平衡模式进行相应操作:

集成式负载平衡模式

  1. 打开 istio-ingressgateway Service 的配置:

    kubectl edit svc -n istio-system istio-ingressgateway
    

    istio-ingressgateway Service 的配置会在 shell 的默认文本编辑器中打开。

  2. 在文件中的规范 (spec) 块下添加以下行:

    loadBalancerIP: <your static external IP address>
    

    例如:

    spec:
     loadBalancerIP: 203.0.113.1
    
  3. 保存文件。

手动负载平衡模式

要在所选的负载平衡器上使用 VIP 公开 NodePort 类型的服务,您需要先找出 nodePort 值:

  1. 在 shell 中查看 istio-ingressgateway Service 的配置:

    kubectl get svc -n istio-system istio-ingressgateway -o yaml
    

    istio 网关的每个端口都会显示出来。命令输出可能如下所示:

     ...
     ports:

    • name: status-port nodePort: 30391 port: 15020 protocol: TCP targetPort: 15020
    • name: http2 nodePort: 31380 port: 80 protocol: TCP targetPort: 80
    • name: https nodePort: 31390 port: 443 protocol: TCP targetPort: 443
    • name: tcp nodePort: 31400 port: 31400 protocol: TCP targetPort: 31400
    • name: https-kiali nodePort: 31073 port: 15029 protocol: TCP targetPort: 15029
    • name: https-prometheus nodePort: 30253 port: 15030 protocol: TCP targetPort: 15030
    • name: https-grafana nodePort: 30050 port: 15031 protocol: TCP targetPort: 15031
    • name: https-tracing nodePort: 31204 port: 15032 protocol: TCP targetPort: 15032
    • name: tls nodePort: 30158 port: 15443 protocol: TCP targetPort: 15443 ...
  2. 通过负载平衡器公开这些端口。

    例如,名为 http2 的服务端口具有 port 80 和 nodePort 31380。假设您的用户集群的节点地址是 192.168.0.10192.168.0.11192.168.0.12,并且负载平衡器的 VIP 是 203.0.113.1

    配置负载平衡器以将发送到 203.0.113.1:80 的流量转发到 192.168.0.10:31380192.168.0.11:31380192.168.0.12:31380。您可以选择要在此给定 VIP 上公开的服务端口。

部署示例应用

一旦完成 Istio 安装且 Istio 的所有组件都在运行后,您可以尝试部署随安装提供的其中一个示例应用。在本教程中,我们将安装 BookInfo。这是一个简单的模拟书店应用,由四个服务组成,这些服务提供一个网页商品页面、图书详情、评论(有多个版本的评论服务)以及评分,且全部使用 Istio 进行管理。您可以在 Istio 安装的 samples/bookinfo 目录中找到此示例中使用的源代码及所有其他文件。

如果按照以下步骤操作,则会在已启用 Istio 的环境中部署 BookInfo 应用的服务,并且 Envoy 辅助信息文件代理会与每项服务一起注入,从而提供 Istio 功能。

  1. 确保您仍位于集群管理机上的 Istio 安装目录的根目录中。

  2. 使用 kubectl applyistioctl kube-inject 部署应用。kube-inject 命令用于更新 BookInfo 部署,以便在每个应用 pod 以及对应服务中部署 sidecar。

    kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
    
  3. 通过运行以下命令确认是否已正确部署应用:

    kubectl get services
    输出:
    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)              AGE
    details                    10.0.0.31    <none>        9080/TCP             6m
    kubernetes                 10.0.0.1     <none>        443/TCP              7d
    productpage                10.0.0.120   <none>        9080/TCP             6m
    ratings                    10.0.0.15    <none>        9080/TCP             6m
    reviews                    10.0.0.170   <none>        9080/TCP             6m

    kubectl get pods
    输出:
    NAME                                        READY     STATUS    RESTARTS   AGE
    details-v1-1520924117-48z17                 2/2       Running   0          6m
    productpage-v1-560495357-jk1lz              2/2       Running   0          6m
    ratings-v1-734492171-rnr5l                  2/2       Running   0          6m
    reviews-v1-874083890-f0qf0                  2/2       Running   0          6m
    reviews-v2-1343845940-b34q5                 2/2       Running   0          6m
    reviews-v3-1813607990-8ch52                 2/2       Running   0          6m
  4. 最后,为应用定义入站网关路由:

    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
    

验证应用部署

在完成部署后,接下来我们来查看 BookInfo 应用的运行情况。 由于之前已进行了配置,您已经知道入站网关的外部 IP 地址。例如,如果使用 203.0.113.1 作为外部 IP:

export GATEWAY_URL=203.0.113.1

试用应用

  1. 使用 curl 来检查 BookInfo 应用是否在运行:

    curl -I http://${GATEWAY_URL}/productpage
    

    如果响应显示 200,则表示应用与 Istio 正常配合使用。

  2. 现在在浏览器中访问 http://$GATEWAY_URL/productpage 以查看 BookInfo 网页。如果您多次刷新该页面,您应该会看到产品页面中显示的不同版本的评论,以循环方式呈现(红色星标、黑色星标、无星标),这是因为我们尚未使用 Istio 来控制版本路由。

部署您自己的应用

如果您想要尝试部署一个您自己的应用,只需在自己的 YAML 部署中执行相同的过程:Istio 不需要更改应用本身。请注意,应用必须对其所有 HTTP 流量使用 HTTP/1.1 或 HTTP/2.0 协议,这是因为 Envoy 代理不支持 HTTP/1.0:Envoy 代理依赖 HTTP/1.0 中不存在的标头进行路由。

您可以在部署应用时使用 kube-inject 来添加 sidecar(如示例所示),也可以为运行应用的命名空间启用 Istio 的自动 sidecar 注入功能

卸载

  1. 使用以下命令卸载 Istio 组件:

    helm template install/kubernetes/helm/istio --name istio --namespace istio-system | kubectl delete -f -
    
  2. 然后删除 istio-system 命名空间:

    kubectl delete namespace istio-system
    

后续步骤

如需详细了解 Istio,请参阅 Istio 网站以及 Google Cloud Platform Istio 文档