在Istio中部署Bookinfo应用

Istio是一个开源的服务网格,提供流量管理、可观测性,以及安全和策略等能力。在Kubernetes中配合使用Istio,可以帮助您更好地管理和控制容器应用,提高应用程序的性能、安全性和可靠性。本文以Bookinfo应用为例,介绍自建Kubernetes集群通过VNode对接ECI的场景下,如何使用Istio。

背景信息

Istio是一个开源的服务网格(Service Mesh)平台,用于管理微服务之间的流量以及处理各种网络通信和安全问题。Istio可以与Kubernetes集成,提供标准、安全的流量管理,简化部署和运维工作。

Bookinfo是一个样例应用,它模仿在线书店的一个目录,可以显示一本书的信息,包括书籍描述,书籍详细信息(ISBN、页数等),以及关于这本书的一些评论。Bookinfo是一个异构应用,由四个使用不同语言编写的微服务组成,可以演示多种Istio特性。Bookinfo包含的四个微服务如下:

bookinfo

  • Productpage:为Python服务,会调用Details和Reviews两个服务,用来生成页面。同时,Productpage还包含登录和登出功能。

  • Details:为Ruby服务,包含了书籍的信息。

  • Reviews:为Java服务,包含了书籍相关的评论。Reviews包含3个版本:

    • v1版本不会调用Ratings服务。

    • v2版本会调用Ratings服务,并使用1到5个黑色星形图标来显示评分信息。

    • v3版本会调用Ratings服务,并使用1到5个红色星形图标来显示评分信息。

  • Ratings:为Node.js服务,包含了由书籍评价组成的评级信息。

更多信息,请参见Istio Bookinfo

前提条件

本文适用于自建Kubernetes集群,请确保您的集群满足以下条件:

  • 自建Kubernetes集群中已部署VNode。

  • 如果您的Kubernetes集群部署在线下IDC,请确保已打通IDC与阿里云的网络。

  • 如果您的Kubernetes集群部署在ECS上,且使用的网络插件为Flannel,请确保已在集群中部署CCM,保证ECI与标准节点上的Pod可以正常通信。具体操作,请参见部署CCM

准备工作

  1. 安装Istio。具体操作,请参见Istio快速入门

  2. 创建Namespace并配置Label。

    kubectl create namespace istio-test
    kubectl label namespace istio-test istio-injection=enabled

操作步骤

部署Bookinfo应用

  1. 将以下内容保存为bookinfo.yaml。

    说明

    下述YAML示例中已增加nodeSelector实现将Pod调度到VNode,您也可以配置eci-profile来实现。更多信息,请参见将Pod调度到VNode使用eci-profile调度Pod到VNode

    展开查看bookinfo.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # This file defines the services, service accounts, and deployments for the Bookinfo sample.
    #
    # To apply all 4 Bookinfo services, their corresponding service accounts, and deployments:
    #
    #   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
    #
    # Alternatively, you can deploy any resource separately:
    #
    #   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service
    #   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount
    #   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment
    ##################################################################################################
    
    ##################################################################################################
    # Details service
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: details
      labels:
        app: details
        service: details
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: details
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-details
      labels:
        account: details
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: details-v1
      labels:
        app: details
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: details
          version: v1
      template:
        metadata:
          labels:
            app: details
            version: v1
        spec:
          nodeSelector:     #配置特定的nodeSelector
            k8s.aliyun.com/vnode: "true"
          tolerations:      #配置特定的tolerations
          - key: k8s.aliyun.com/vnode
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          serviceAccountName: bookinfo-details
          containers:
          - name: details
            image: docker.io/istio/examples-bookinfo-details-v1:1.16.4
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
            securityContext:
              runAsUser: 1000
    ---
    ##################################################################################################
    # Ratings service
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: ratings
      labels:
        app: ratings
        service: ratings
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: ratings
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-ratings
      labels:
        account: ratings
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ratings-v1
      labels:
        app: ratings
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ratings
          version: v1
      template:
        metadata:
          labels:
            app: ratings
            version: v1
        spec:
          nodeSelector:     #配置特定的nodeSelector
            k8s.aliyun.com/vnode: "true"
          tolerations:      #配置特定的tolerations
          - key: k8s.aliyun.com/vnode
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          serviceAccountName: bookinfo-ratings
          containers:
          - name: ratings
            image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.4
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
            securityContext:
              runAsUser: 1000
    ---
    ##################################################################################################
    # Reviews service
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews
      labels:
        app: reviews
        service: reviews
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: reviews
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-reviews
      labels:
        account: reviews
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v1
      labels:
        app: reviews
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v1
      template:
        metadata:
          labels:
            app: reviews
            version: v1
        spec:
          nodeSelector:     #配置特定的nodeSelector
            k8s.aliyun.com/vnode: "true"
          tolerations:      #配置特定的tolerations
          - key: k8s.aliyun.com/vnode
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.4
            imagePullPolicy: IfNotPresent
            env:
            - name: LOG_DIR
              value: "/tmp/logs"
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
            securityContext:
              runAsUser: 1000
          volumes:
          - name: wlp-output
            emptyDir: {}
          - name: tmp
            emptyDir: {}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v2
      labels:
        app: reviews
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v2
      template:
        metadata:
          labels:
            app: reviews
            version: v2
        spec:
          nodeSelector:     #配置特定的nodeSelector
            k8s.aliyun.com/vnode: "true"
          tolerations:      #配置特定的tolerations
          - key: k8s.aliyun.com/vnode
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.4
            imagePullPolicy: IfNotPresent
            env:
            - name: LOG_DIR
              value: "/tmp/logs"
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
            securityContext:
              runAsUser: 1000
          volumes:
          - name: wlp-output
            emptyDir: {}
          - name: tmp
            emptyDir: {}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v3
      labels:
        app: reviews
        version: v3
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v3
      template:
        metadata:
          labels:
            app: reviews
            version: v3
        spec:
          nodeSelector:     #配置特定的nodeSelector
            k8s.aliyun.com/vnode: "true"
          tolerations:      #配置特定的tolerations
          - key: k8s.aliyun.com/vnode
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.4
            imagePullPolicy: IfNotPresent
            env:
            - name: LOG_DIR
              value: "/tmp/logs"
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
            securityContext:
              runAsUser: 1000
          volumes:
          - name: wlp-output
            emptyDir: {}
          - name: tmp
            emptyDir: {}
    ---
    ##################################################################################################
    # Productpage services
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: productpage
      labels:
        app: productpage
        service: productpage
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: productpage
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-productpage
      labels:
        account: productpage
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productpage-v1
      labels:
        app: productpage
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: productpage
          version: v1
      template:
        metadata:
          labels:
            app: productpage
            version: v1
        spec:
          nodeSelector:     #配置特定的nodeSelector
            k8s.aliyun.com/vnode: "true"
          tolerations:      #配置特定的tolerations
          - key: k8s.aliyun.com/vnode
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          serviceAccountName: bookinfo-productpage
          containers:
          - name: productpage
            image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.4
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            securityContext:
              runAsUser: 1000
          volumes:
          - name: tmp
            emptyDir: {}
    ---
  2. 部署Bookinfo。

    kubectl -n istio-test apply -f bookinfo.yaml

    预期返回:

    istio-1

  3. 查看Bookinfo运行情况。

    kubectl -n istio-test get pods -o wide

    预期返回:

    istio-2

  4. 检查Services。

    kubectl -n istio-test get services

    预期返回:

    istio-3

部署Gateway

  1. 将以下内容保存为bookinfo-gateway.yaml。

    展开查看bookinfo-gateway.yaml

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: bookinfo-gateway
    spec:
      selector:
        istio: ingressgateway # use istio default controller
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
        route:
        - destination:
            host: productpage
            port:
              number: 9080
  2. 部署Gateway。

    kubectl -n istio-test apply -f bookinfo-gateway.yaml

    预期返回:istio-4

  3. 查看Gateway。

    kubectl -n istio-test get gateway

    预期返回:

    istio-5

验证Bookinfo服务

  1. 确定Istio Gateway的Host地址。

    请根据集群情况选择Istio Ingress Service,本文使用LoadBalancer方式:

    kubectl -n istio-system get service istio-ingressgateway

    预期返回:

    istio-6

    通过返回信息可以得到istio-ingressgateway的Host地址(IP:Port格式)为10.96.XX.XX:80

  2. 创建一个测试Pod,用于验证服务。

    1. 将以下内容保存为test-pod.yaml。

      展开查看test-pod.yaml

      apiVersion: v1
      kind: Pod
      metadata:
        name: centos
      spec:
        nodeSelector:    
          k8s.aliyun.com/vnode: "true"
        tolerations:      
        - key: k8s.aliyun.com/vnode
          operator: "Equal"
          value: "true"
          effect: "NoSchedule"
        containers:
        - name: eip
          image: registry-vpc.cn-shanghai.aliyuncs.com/eci_open/centos:7
          command:
          - bash
          - -c
          - sleep inf
    2. 部署Pod。

      kubectl apply -f test-pod.yaml
  3. 登录测试Pod,然后执行命令验证服务。

    kubectl exec -it centos -- bash
    curl -s http://10.96.XX.XX:80/productpage | grep -o "<title>.*</title>"

    其中10.96.XX.XX:80为步骤1获取的Host地址。如果返回<title>Simple BookStore App<title>,则表示Istio已经成功运行在VNode上。示例如下:

    istio-7