0%

Bookinfo示例简介

Bookinfoistio官网示例,应用程序分为四个单独的微服务:

  • productpage。该productpage微服务调用detailsreviews微服务来填充页面。
  • details。该details微服务包含图书信息。
  • reviews。该reviews微服务包含了书评。它们调用ratings微服务。
  • ratings。该ratings微服务包含预定伴随书评排名信息。

reviews微服务有3个版本:

  • 版本v1不会调用该ratings服务。
  • 版本v2调用该ratings服务,并将每个等级显示为1到5个黑星
  • 版本v3调用该ratings服务,并将每个等级显示为1到5个红色星号

Bookinfo架构图

BookinfoIstio中架构

如果想要在Istio中运行BookinfoBookinfo本身不需要任何改动,只需要为Bookinfo的微服务注入IstioSidecar。最终架构图如下:

Bookinfo架构图

所有的微服务都与Envoy边车打包在一起,该Envoy边车拦截对服务的出/入请求,并与Istio控制面交互,提供路由、采集、实施各种策略等。

启动Bookinfo服务,参考官网

进入istio目录

[root@k8s-master istio-1.4.2]# pwd
/root/istio/istio-1.4.2

设置namespace自动注入sidecar

kubectl label namespace default istio-injection=enabled

部署bookinfo服务

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

你也可以手动为这个yaml注入sidecar再部署,参考Istio使用【sidecar注入】

kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)

确定启动完成

[root@k8s-master istio-1.4.2]# kubectl get pod
NAME                                                       READY   STATUS    RESTARTS   AGE
details-v1-74f858558f-7gx6r                                2/2     Running   0          31h
productpage-v1-8554d58bff-fwcj4                            2/2     Running   0          31h
ratings-v1-7855f5bcb9-r7z5l                                2/2     Running   0          31h
reviews-v1-59fd8b965b-jppqr                                2/2     Running   0          31h
reviews-v2-d6cfdb7d6-rx648                                 2/2     Running   0          31h
reviews-v3-75699b5cfb-qpdjm                                2/2     Running   0          31h
[root@k8s-master istio-1.4.2]# kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
details       ClusterIP   10.102.10.128    <none>        9080/TCP    31h
productpage   ClusterIP   10.110.251.239   <none>        9080/TCP    31h
ratings       ClusterIP   10.99.146.247    <none>        9080/TCP    31h
reviews       ClusterIP   10.102.77.22     <none>        9080/TCP    31h

确定程序运行正常

kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>

定义应用的入口网关

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

确认网关已创建

[root@k8s-master istio-1.4.2]# kubectl get gateway
NAME               AGE
bookinfo-gateway   30h

下面可以通过Isito的入口网关来访问了,在访问前,需要确定Isito网关IP和端口

获取Istio入口网关IP和端口:参考官网

kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                                                                      AGE
istio-ingressgateway   LoadBalancer   10.110.94.234   <pending>     15020:32344/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:31933/TCP,15030:30470/TCP,15031:31361/TCP,15032:31151/TCP,15443:31081/TCP   2d2h

如果EXTERNAL-IP设置了该值,则您的环境具有可用于入口网关的外部负载平衡器。如果EXTERNAL-IP值是<none>(或永久<pending>),则您的环境不为入口网关提供外部负载平衡器。在这种情况下,您可以使用服务的节点端口来访问网关。

确定端口

  • 这里80对应的端口是Http服务的端口,映射的主机端口31380

  • 这里443对应的端口是Https服务的端口,映射的主机端口31390

确定IP

可以通过下面命令找个hostIP

[root@k8s-master istio-1.4.2]# kubectl get po -l istio=ingressgateway -n istio-system -o yaml | grep hostIP: -C3
---
      state:
        running:
          startedAt: "2019-12-24T06:46:29Z"
    hostIP: 192.168.1.212
    phase: Running
    podIP: 10.244.3.136
    qosClass: Burstable
---

也可以通过下面的命令找到Ingress部署的节点。

[root@k8s-master istio-1.4.2]# kubectl get po -l istio=ingressgateway -n istio-system -o wide
NAME                                    READY   STATUS    RESTARTS   AGE    IP             NODE     NOMINATED NODE   READINESS GATES
istio-ingressgateway-6b7bfd7459-wljhh   1/1     Running   0          2d2h   10.244.3.136   k8s-02   <none>           <none>

访问Bookinfo应用

浏览器访问刚刚或者的IP+端口+/productpage,例如我的是http://192.168.1.212:31380/productpage

Reviewer-v1
Reviewer-v2
Reviewer-v3

不停的刷新页面,可以看到返回的Reviewer是不同的版本。

简单分析下

针对samples/bookinfo/networking/bookinfo-gateway.yaml,我们可以看看默认配置做了啥。

[root@k8s-master istio-1.4.2]# cat samples/bookinfo/networking/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
  • 首先创建一个Gateway,这是Istio的一个自定义资源类型(CRD),它创建了这个bookinfo应用的网关bookinfo-gateway,使用了istio默认的controller——ingressgateway,如上文,istioingress网关定义了很多类型端口,这里bookinfo-gateway使用了80端口,域名使用的通配符 *

  • 定义VirtualService,这里需要绑定刚刚创建的bookinfo-gateway,定义了匹配的URI和后台服务。

本文使用的istio版本:1.4.2

开启链路监控

....
#
# addon jaeger tracing configuration
#
tracing:
  enabled: true
....

可以看出。istio链路监控集成使用的是JaegerJaeger是什么,参考开发分布式追踪OpenTracing与Jaeger相关文档整理

查看是否启动成功

[root@k8s-master istio-1.4.2]# kubectl get po -n istio-system --show-labels | grep jaeger
istio-tracing-795c9c64c4-224wm            1/1     Running     0          47h   app=jaeger,chart=tracing,heritage=Tiller,pod-template-hash=795c9c64c4,release=istio

访问jaeger UI

[root@k8s-master istio-1.4.2]# kubectl get svc -n istio-system | grep jaeger
jaeger-agent             ClusterIP      None             <none>        5775/UDP,6831/UDP,6832/UDP                                                                                                                   47h
jaeger-collector         ClusterIP      10.110.206.207   <none>        14267/TCP,14268/TCP,14250/TCP                                                                                                                47h
jaeger-query             NodePort       10.101.53.38     <none>        16686:31944/TCP 

如上所示,默认情况下,jaeger-query类型也是ClusterIP,为了便于访问,直接修改成NodePort类型:

kubectl edit svc jaeger-query  -n istio-system

然后访问IP:31944即可。

UI预览

Jaeger UI
Jaeger UI
Jaeger UI

采集频率控制

如果所有的请求都采集监控,不管出于性能考虑还是资源考虑,都是不实际的。

pilot组件中PILOT_TRACE_SAMPLING环境变量用于控制采集率,默认为10~100),测试的时候可以改大点便于分析:

 kubectl -n istio-system get deploy istio-pilot -oyaml | grep PILOT_TRACE_SAMPLING -A5
 
--
        - name: PILOT_TRACE_SAMPLING
          value: "1"
        - name: PILOT_ENABLE_PROTOCOL_SNIFFING_FOR_OUTBOUND
          value: "true"
        - name: PILOT_ENABLE_PROTOCOL_SNIFFING_FOR_INBOUND
          value: "false"
---

监控数据采集存储

参考控制台kiali配置,其中配置了Prometheusgrafana。参考Istio链路监控和监控可视化

  • prometheus作为基础数据采集和存储方式,可以通过PromQL查询指标。
  • grafana可定制化报表展示。

grafana

Istio简介

Istio是一个开放服务网格,提供了一种连接,管理和保护微服务的统一方法。它支持管理服务之间的流量,执行访问策略以及汇总遥测数据,所有这些都无需更改微服务代码。
Istio:

  • HTTP,gRPC,WebSocket,MongoDB和TCP通信的自动负载平衡。
  • 通过丰富的路由规则,重试,故障转移和故障注入对流量行为进行细粒度控制。
  • 可配置的策略层和API,支持访问控制,速率限制和配额。
  • 群集内所有流量的自动指标,日志和跟踪,包括群集入口和出口。
  • 通过强大的基于身份的身份验证和授权,在群集中进行安全的服务间通信。

Istio架构图

istio

Logback默认配置的步骤

  1. 尝试在 classpath下查找文件logback-test.xml;
  2. 如果文件不存在,则查找文件logback.xml;
  3. 如果两个文件都不存在,logback用BasicConfigurator自动对自己进行配置,这会导致记录输出到控制台。

logback配置文件模板

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
    <property name="ROOT" value="./logs/" />
    <property name="FILESIZE" value="100MB" />
    <property name="MAXHISTORY" value="30" />
    <timestamp key="DATETIME" datePattern="yyyy-MM-dd HH:mm:ss" />
    <!-- 控制台打印 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %logger{36} - %m%n</pattern>
        </encoder>
    </appender>
    <!-- 输入到文件,按日期和文件大小 -->
    <appender name="FILEOUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %logger{36} - %m%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROOT}/log.%d.%i.log</fileNamePattern>
            <maxHistory>${MAXHISTORY}</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${FILESIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <!-- Logger 根目录 -->
    <root level="INFO">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILEOUT" />
    </root>
</configuration>

本文使用的istio版本号:1.4.2

配置安装kiali

默认配置,istio并未选择安装kiali,参考上一章安装,修改values.yaml

vim install/kubernetes/helm/istio/values.yaml
# ....
kiali:
  enabled: true
# ....

同时如果需要链路监控,需要开启安装jaeger

#....
tracing:
  enabled: true
#....

如果系统中没有安装grafanaPrometheus,也需要开启

#.....
grafana:
  enabled: true
 
prometheus:
  enabled: true
#.....

配置kiali

可以在安装前配置好kaili,主要配置集中在

vim install/kubernetes/helm/istio/charts/kiali/values.yaml
#......
ingress:
  enabled: false
  hosts:
    - kiali.local
 
dashboard:
  auth:
    strategy: login
  secretName: kiali 
  viewOnlyMode: false 
  grafanaURL:  
  jaegerURL:  
prometheusAddr: http://prometheus:9090
#.....
  • 配置访问:ingress是否开启,hosts地址,tls…
  • strategy:认证策略,可以是anonymous, login, openshift,默认login
  • secretName:登录用户名/密码,需要提前创建好secret
apiVersion: v1
kind: Secret
metadata:
  name: kiali
  labels:
    app: kiali
    version: v1.9
type: Opaque
data:
  username: YWRtaW4=    # admin
  passphrase: YWRtaW4=    # admin
#base64 加密
echo -n "admin" | base64
  • grafanaURL:grafana地址,如果是在同一个namespace下,可以是
http://grafana:3000 或者 http://grafana.monitoring.svc.cluster.local:3000
  • prometheusAddr:Prometheus地址,如果是在同一个namespace下,可以是
http://prometheus:9090 或者 http://prometheus.monitoring.svc.cluster.local:9090
  • jaegerURL:jaeger地址,默认在同一个namespace istio-system下,可以是
http://jaeger-query:16686/jaeger

如果是在安装后,想要修改kiali配置,可以修改istio-systemconfigmap kiali

kubectl edit cm  kiali   -n istio-system

修改configmap里面的config.yaml文件,对应的

istio_namespace: istio-system
deployment:
  accessible_namespaces: ['**']
auth:
  strategy: login
server:
  port: 20001
  web_root: /kiali
external_services:
  tracing:
    url: http://jaeger-query:16686/jaeger
  grafana:
    url: http://grafana:3000
  prometheus:
    url: http://prometheus:9090

修改完需要重启kiali POD

预览

istio

本文使用的istio版本号:1.4.2

简介(参考官网,Naftis小米开源,不在维护)

Naftis 是一个基于 web 的 Istio dashboard,通过任务模板的方式来帮助用户更方便地执行 Istio 任务。 用户可以在 Naftis 中定义自己的任务模板,并填充变量来构造单个或多个构造任务实例,从而完成各种服务治理功能。

  • 内部集成了一些常用 dashboard
  • 可定制的任务模板支持
  • 支持回滚指定任务
  • 支持指定根服务节点的服务拓扑图
  • 提供查看 Istio 的 Services 和 Pod 的支持
  • 开箱即用,通过 Kubectl 相关指令即可快速部署
  • 支持 Istio 1.0

快速安装

# 下载最新 release 文件和部署清单
wget -O - https://raw.githubusercontent.com/XiaoMi/naftis/master/tool/getlatest.sh | bash
 
# 创建 Naftis 命名空间
$ kubectl create namespace naftis
 
# 确认 Naftis 命名空间已创建
$ kubectl get namespace naftis
NAME           STATUS    AGE
naftis         Active    18m
 
# 部署 Naftis MySQL 服务(本地 Kuberenetes 集群)
$ kubectl apply -n naftis -f mysql.yaml
# 部署 Naftis MySQL 服务(云服务商提供的 Kuberenetes 集群)
$ kubectl apply -n naftis -f mysql-cloud.yaml
 
# 确认 MySQL 已部署
NAME                           READY     STATUS    RESTARTS   AGE
naftis-mysql-c78f99d6c-kblbq   0/1       Running   0          9s
naftis-mysql-test              1/1       Running   0          10s
 
# 部署 Naftis API 和 UI 服务
kubectl apply -n naftis -f naftis.yaml
 
# 确认 Naftis 所有的服务已经正确定义并正常运行中
kubectl get svc -n naftis
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
naftis-api     ClusterIP      10.233.3.144            50000/TCP      7s
naftis-mysql   ClusterIP      10.233.57.230           3306/TCP       55s
naftis-ui      LoadBalancer   10.233.18.125        80:31286/TCP   6s
 
kubectl get pod -n naftis
NAME                           READY     STATUS    RESTARTS   AGE
naftis-api-0                   1/2       Running   0          19s
naftis-mysql-c78f99d6c-kblbq   1/1       Running   0          1m
naftis-mysql-test              1/1       Running   0          1m
naftis-ui-69f7d75f47-4jzwz     1/1       Running   0          19s
 
# 端口转发访问 Naftis
kubectl -n naftis port-forward $(kubectl -n naftis get pod -l app=naftis-ui -o jsonpath='{.items[0].metadata.name}') 8080:80 &
 
# 打开浏览器,访问 http://localhost:8080 即可。默认用户名和密码分别为 admin、admin。

预览

naftis

安装比较简单,功能也比较简单。