istio 生产环境搭建

1,176 阅读6分钟

相关组件

整个 istio 环境需要以下组件

  • prometheus -- 用于 K8s 平台和 istio 平台监控
  • jaeger -- 用于服务间的链路追踪
  • elasticsearch -- 用于存储链路追踪的数据,(也可增加部署 fluntd 和 kibana 收集监控 K8s 平台日志)
  • istio -- 平台本体

由于需要用于生产环境中,istio 部署包中所集成的 Prometheus 和 jaeger 均无法满足需求,其中平台中其他服务需要复用 Prometheus;istio 中集成的 jaeger 为 allinone 模式(用于测试),无法满足生产需求,因此单独拆出来。

Prometheus 搭建

Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB)。Prometheus使用Go语言开发,是Google BorgMon监控系统的开源版本。

2016年由Google发起Linux基金会旗下的原生云基金会(Cloud Native Computing Foundation), 将Prometheus纳入其下第二大开源项目,且在开源社区相当活跃。

Prometheus和Heapster(Heapster是K8S的一个子项目,用于获取集群的性能数据。)相比功能更完善、更全面。Prometheus性能也足够支撑上万台规模的集群。

其基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做虚拟化环境监控系统,比如VM、Docker、Kubernetes等。输出被监控组件信息的HTTP接口被叫做exporter 。目前互联网公司常用的组件大部分都有exporter可以直接使用,比如Varnish、Haproxy、Nginx、MySQL、Linux系统信息(包括磁盘、内存、CPU、网络等等

部署

Prometheus 此处采用的是 coreos 提供的 kube-prometheus,其定义了一组 CRD,且提供了 Operator 便于部署。

git clone 下来项目后,就可以无脑部署了:

# 部署 Prometheus 所需的 crd 和 namespace(monitoring)
kubectl create -f manifests/setup
# 检查 crd serverMonitor 是否可用
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
# 部署其他组件
kubectl create -f manifests/

在 kube-prometheus 中,主要定义了 以下几个 crd:

# 常用
prometheusrules.monitoring.coreos.com -- 用于定义告警规则
servicemonitors.monitoring.coreos.com -- 用于定义 metrics 获取的 api
# 不常用
alertmanagers.monitoring.coreos.com -- 用于 告警配置
podmonitors.monitoring.coreos.com   -- 用于 pod 监控配置
prometheuses.monitoring.coreos.com  -- 用于创建相关 adapter 

部署成功后,在 monitoring namespace 下会生成如下 pod 以及 service

# pod
NAME                                   READY   STATUS    RESTARTS   AGE
alertmanager-main-0                    2/2     Running   2          4d17h
alertmanager-main-1                    2/2     Running   0          4d17h
alertmanager-main-2                    2/2     Running   0          4d17h
grafana-5db74b88f4-sfwl5               1/1     Running   0          4d17h
kube-state-metrics-54f98c4687-8x7b7    3/3     Running   0          4d17h
node-exporter-5p8b8                    2/2     Running   0          4d17h
node-exporter-65r4g                    2/2     Running   0          4d17h
node-exporter-946rm                    2/2     Running   0          4d17h
node-exporter-95x66                    2/2     Running   4          4d17h
node-exporter-lzgv7                    2/2     Running   0          4d17h
prometheus-adapter-8667948d79-hdk62    1/1     Running   0          4d17h
prometheus-k8s-0                       3/3     Running   1          4d17h
prometheus-k8s-1                       3/3     Running   1          4d17h
prometheus-operator-548c6dc45c-ltmv8   1/1     Running   2          4d17h

其中 pod/prometheus-k8s-0 即周期性调取 k8s 平台的 api 获取 metrics 信息。通过kubectl get -n monitoring servicemonitors.monitoring.coreos.com获取 serviceMonitor :

NAME                      AGE
alertmanager              4d17h
grafana                   4d17h
coredns                   4d17h |
kube-apiserver            4d17h |
kube-controller-manager   4d17h |
kube-scheduler            4d17h | --> 对 k8s 相关组件的监控配置
kube-state-metrics        4d17h |
kubelet                   4d17h |
node-exporter             4d17h   |
prometheus                4d17h   | --> 对Prometheus 自身组件的监控配置
prometheus-operator       4d17h   |

**注意:**此时我们还没有加入对 isito 组件的监控配置

elasticsearch

es 在环境中的角色是存储链路追踪的信息。因为在链路追踪的选型上我们选择了 jaeger,jaeger 所支持的后端存储为 elasticsearch 和 cassandra,相比之下 es 的可复用性更高。

这里使用的是官方镜像,gcr.io/fluentd-elasticsearch/elasticsearch:v6.6.1

部署成功后,为我们提供了 service elasticsearch-logging

这里推荐一个 chrome 插件,可以很方便的查询 es 集群状态以及数据 ElasticSearch Head

jaeger

目前 es 已经部署完毕,jaeger 的部署可以参考我之前写过的一篇{% post_link jaeger-istio jaeger 在 istio 上的实践 %},此处不再赘述

通过部署,我们在 jaeger namespace 下得到以下三个服务:

NAME               TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE
jaeger-collector   ClusterIP      10.233.15.246   <none>        14267/TCP,14268/TCP,9411/TCP   2d3h
jaeger-query       LoadBalancer   10.233.34.138   <pending>     80:31882/TCP                   2d3h
zipkin             ClusterIP      10.233.53.53    <none>        9411/TCP                       2d3h

其中 zipkin 服务是用于收集使用 zipkin 数据结构的链路信息,jaeger 兼容 zipkin。 jaeger-collector 用于收集 jaeger 使用的数据结构的链路信息;jaeger-query 用于查询。

istio

现在所有的准备已经就绪,终于可以部署 istio 了。istio 所使用的版本是 1.3.4。 我们选择通过 Helm chart 模板安装部署,首先需要自定义部署参数,修改install/kubernetes/helm/values.yaml

# 关闭 grafana prometheus tracing 模块,其他模块可根据需求部署安装
grafana:
  enabled: false

prometheus:
  enabled: false

tracing:
  enabled: false

# 配置 tracing 上报链路信息服务地址
tracer:
  zipkin: 
    address: zipkin.jaeger:9411  # 格式为servicename.namespace:port

执行以下命令进行部署

# 添加官方helm 仓库
helm repo add istio.io https://storage.googleapis.com/istio-release/releases/1.3.4/charts/

# 部署 istio crd
helm install install/kubernetes/helm/istio-init --name istio-init --namespace istio-system

# 检查资源 需要等待结果为 23
kubectl get crds | grep 'istio.io' | wc -l

# 部署istio,pilot.traceSampling 配置链路追踪的采样率,100表示100%;
# kiali.xxx 配置 kiali 连接外部的 jaeger 和 Prometheus
# istio 重要组件需要多副本部署,例如 galley,policy,pilot,telemetry 等
helm install install/kubernetes/helm/istio --name istio --namespace istio-system \
    --set pilot.traceSampling=100, \
    kiali.dashboard.jaegerURL=http://jaeger-query.jaeger:80, \
    kiali.prometheusAddr=http://prometheus-k8s.monitoring:9090, \
    galley.replicaCount=3,\
    mixer.policy.replicaCount=3, \
    mixer.telemetry.replicaCount=3, \
    pilot.autoscaleMin=2

至此,istio部署完毕,jaeger 已经接入 istio,但是 Prometheus 仍未配置收集 istio 的 metrics。我们需要创建自己的 serviceMonitor:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: istio-monitor  
  labels:
    app: prometheus-istio
spec:
  selector:
    matchLabels: # 采集包含以下标签的 pod 的 /metrics 
      app: mixer # 由于 istio 中 业务服务组件的 metrics 均汇总至 mixer 中,因此只采集该组件即可
      istio: mixer
  endpoints:
  - port: prometheus # mixer 组件包含名为 prometheus 的端口,便于采集
    interval: 10s    # 采集周期
  namespaceSelector:
    matchNames:
    - istio-system   # 作用域

此外,由于 Prometheus 没有权限采集 monitoring 和 kube-system 以外的 endpoint,需要增加 rbac 来增加其权限:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: istio-system
  labels:
    app: prometheus

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus-istio
  labels:
    app: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - services
  - endpoints
  - pods
  - nodes/proxy
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources:
  - configmaps
  verbs: ["get"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-istio
  namespace: istio-system
  labels:
    app: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus-istio
subjects:
- kind: ServiceAccount
  name: prometheus-k8s
  namespace: monitoring

至此,平台搭建完成,可以通过部署 istio 示例程序 bookinfo 进行测试

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n <your namespace>