Kubernetes运维-部署Skywalking实现链路追踪

Linux系统
278
0
0
2024-05-07
标签   Kubernetes

Kubernetes运维-部署Skywalking实现链路追踪

王先森2024-01-222024-01-22

Skywalking介绍

Skywalking 是一个国产的开源框架,2015年有吴晟个人开源,2017年加入Apache孵化器,国人开源的产品,主要开发人员来自于华为,2019年4月17日Apache董事会批准SkyWalking成为顶级项目,支持Java、.Net、NodeJs等探针,数据存储支持Mysql、Elasticsearch等,跟Pinpoint一样采用字节码注入的方式实现代码的无侵入,探针采集数据粒度粗,但性能表现优秀,且对云原生支持,目前增长势头强劲,社区活跃。 Skywalking是分布式系统的应用程序性能监视工具,专为微服务,云原生架构和基于容器(Docker,K8S,Mesos)架构而设计,它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪,性能指标分析和服务依赖分析等。

关于微服务

微服务架构已经是一个很通用的系统架构,常见的技术栈如下图所示,这张架构图基本涵括了当前微服务体系下的各种技术栈,可能不同的技术栈有不同的开源实现。

链路追踪工具对比

链路追踪框架对比

目前市面上开源的APM系统主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是参考Google的Dapper实现的

功能和技术方案对比

  • Zipkin是Twitter开源的调用链路分析工具,目前基于Spingcloud sleuth得到了广泛的应用,特点是轻量,部署简单。
  • 一个韩国团队开源的产品,运用了字节码增强技术,只需要在启动时添加启动参数即可,对代码无侵入,目前支持Java和PHP语言,底层采用HBase来存储数据,探针收集的数据粒度非常细,但性能损耗大,因其出现的时间较长,完成度也很高,应用的公司较多
  • Skywalking是本土开源的基于字节码注入的调用链路分析以及应用监控分析工具,特点是支持多种插件,UI功能较强,接入端无代码侵入。
  • CAT是由国内美团点评开源的,基于Java语言开发,目前提供Java、C/C++、Node.js、Python、Go等语言的客户端,监控数据会全量统计,国内很多公司在用,例如美团点评、携程、拼多多等,CAT跟下边要介绍的Zipkin都需要在应用程序中埋点,对代码侵入性强。


Pinpoint

Zipkin

Cat

Skywalking

OpenTracing兼容

客户端支持语言

java、php

java,c#,go,php等

java,.net

Java, .NET Core, NodeJS and PHP

存储

hbase

ES,MySQL,Cassandra,内存

MySQL、本地文件/HDFS

ES,H2,MySQL,TIDB,sharding sphere

传输协议支持

thrift

http、MQ

udp/http

gRPC

ui丰富程度

实现方式-代码侵入性

字节码注入,无侵入

拦截请求,侵入

侵入

字节码注入,无侵入

扩展性

trace查询

不支持

支持

支持

支持

告警支持

支持

不支持

支持

支持

jvm监控

支持

不支持

支持

支持

性能损失

性能对比

模拟了三种并发用户,500,750,1000,使用JMeter测试,每个线程发送30个请求,设置间隔时间为10ms,使用采用频率为1,即100%。下面是性能测试报告:

从上表可以看出,在三种链路监控组件中,

  • skywalking探针对吞吐量影响最小,
  • zipkin对吞吐量影响适中,
  • pinpoint的探针对吞吐量影响最大。
  • 对于内存和cpu的使用,都差不多,相差在10%之内。

Skywalking架构介绍

Skywalking架构

SkyWalking 逻辑上分为四部分: 探针, 平台后端, 存储和用户界面。

  • 探针 基于不同的来源可能是不一样的, 但作用都是收集数据, 将数据格式化为 SkyWalking 适用的格式.
  • 平台后端, 支持数据聚合, 数据分析以及驱动数据流从探针到用户界面的流程。分析包括 Skywalking 原生追踪和性能指标以及第三方来源,包括 Istio 及 Envoy telemetry , Zipkin 追踪格式化等。 你甚至可以使用 Observability Analysis Language 对原生度量指标用于扩展度量的计量系统 自定义聚合分析。
  • 存储 通过开放的插件化的接口存放 SkyWalking 数据. 你可以选择一个既有的存储系统, 如 ElasticSearch, H2 或 MySQL 集群(Sharding-Sphere 管理),也可以选择自己实现一个存储系统. 当然, 我们非常欢迎你贡献新的存储系统实现。
  • UI 一个基于接口高度定制化的Web系统,用户可以可视化查看和管理 SkyWalking 数据。

Skywalking功能介绍

  • 多种监控手段,可以通过语言探针和service mesh获得监控的数据
  • 支持多重语言的自动探针,包括JAVA, .NET Core和NodeJS
  • 轻量高效,无需大数据平台和大量的服务器资源
  • 模块化,UI ,存储,集群管理都有多种机制可选
  • 支持告警
  • 优秀的可视化解决方案

Skywalking拓扑结构

  • Skywalking agent和业务端绑定在一起,负责收集各种监控数据
  • Skywalking oapservice是负责处理监控数据,接受agent的数据并存储在数据库中,接受来自UI的请求,查询监控数据。
  • Skywalking UI提供给用户,展现各种监控数据和告警。

Skywalking 部署配置

Elasticsearch 部署

Skywalking OAP Server 会将数据存储到 Elasticsearch 中,并通过 Elasticsearch 进行数据查询和分析。Elasticsearch 安装请参考 使用ELK实现日志监控和分析

数据初始化Job

# vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: "skywalking-es-init"
  namespace: skywalking
  labels:
    app: skywalking-job
spec:
  template:
    metadata:
      name: "skywalking-es-init"
      labels:
        app: skywalking-job
    spec:
      nodeName: k8s-node2
      serviceAccountName: skywalking-oap
      restartPolicy: Never
      initContainers:
      - name: wait-for-elasticsearch
        image: busybox:1.30
        imagePullPolicy: IfNotPresent
        command: ['sh', '-c', 'for i in $(seq 1 60); do nc -z -w3 elasticsearch-es-logging.logging.svc 9200 && exit 0 || sleep 5; done; exit 1']
      containers:
      - name: oap
        image: skywalking.docker.scarf.sh/apache/skywalking-oap-server:9.7.0
        imagePullPolicy: IfNotPresent
        env:
        - name: JAVA_OPTS
          value: "-Dmode=init -Xmx2g -Xms2g"
        - name: SW_ENABLE_UPDATE_UI_TEMPLATE 
          value: "true"
        - name: SW_CLUSTER
          value: kubernetes
        - name: SW_CLUSTER_K8S_NAMESPACE
          value: "skywalking"
        - name: SW_CLUSTER_K8S_LABEL
          value: "app=oap"
        - name: SKYWALKING_COLLECTOR_UID
          valueFrom:
            fieldRef:
              fieldPath: metadata.uid
        - name: SW_STORAGE
          value: elasticsearch
        - name: SW_STORAGE_ES_CLUSTER_NODES
          value: "elastic.od.com"            # 指定es地址,由于在k8s内部访问需要通过https协议,这里就指定外部地址,需要pods可以解析此地址。
        - name: SW_ES_USER                   # 指定es用户
          value: "elastic"
        - name: SW_ES_PASSWORD               # 指定es密码
          value: "admin123"
        - name: SW_OTEL_RECEIVER
          value: "default"
        - name: SW_TELEMETRY
          value: "prometheus"

部署OAP Server

RBACDeploymentService

# vim rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app: skywalking
  name: skywalking-oap
  namespace: skywalking
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: skywalking
  namespace: skywalking
  labels:
    app: skywalking
rules:
- apiGroups: [""]
  resources: ["pods", "endpoints", "services", "nodes"]
  verbs: ["get", "watch", "list"]
- apiGroups: ["extensions"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: skywalking
  namespace: skywalking
  labels:
    app: skywalking
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: skywalking
subjects:
- kind: ServiceAccount
  name: skywalking-oap
  namespace: skywalking
# vim dp.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: oap
  name: oap
  namespace: skywalking
spec:
  replicas: 1
  selector:
    matchLabels:
      app: oap
  template:
    metadata:
      labels:
        app: oap
    spec:
      serviceAccountName: skywalking-oap
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: app1
                operator: In
                values:
                - skywalking
      initContainers:
      - name: wait-for-elasticsearch
        image: busybox:1.30
        imagePullPolicy: IfNotPresent
        command: ['sh', '-c', 'for i in $(seq 1 60); do nc -z -w3 elasticsearch-es-http.logging.svc 9200 && exit 0 || sleep 5; done; exit 1']
      containers:
      - name: oap
        image: skywalking.docker.scarf.sh/apache/skywalking-oap-server:9.7.0
        imagePullPolicy: IfNotPresent
        livenessProbe:
          tcpSocket:
            port: 12800
          initialDelaySeconds: 15
          periodSeconds: 20
        readinessProbe:
          tcpSocket:
            port: 12800
          initialDelaySeconds: 15
          periodSeconds: 20
        ports:
        - containerPort: 11800
          name: grpc
        - containerPort: 1234
          name: prometheus-port
        - containerPort: 12800
          name: rest
        env:
        - name: JAVA_OPTS
          value: "-Dmode=no-init -Xmx2g -Xms2g"
        - name: TZ                                       # 设置时区
          value: Asia/Shanghai
        - name: SW_OTEL_RECEIVER
          value: "default"
        - name: SW_ENABLE_UPDATE_UI_TEMPLATE             # 开启试图可编辑,默认为:false
          value: "true"
        - name: SW_CLUSTER
          value: kubernetes
        - name: SW_CLUSTER_K8S_NAMESPACE
          value: "skywalking"
        - name: SW_CLUSTER_K8S_LABEL
          value: "app=oap"
        - name: SKYWALKING_COLLECTOR_UID
          valueFrom:
            fieldRef:
              fieldPath: metadata.uid
        - name: SW_STORAGE                               # 使用es作为存储
          value: elasticsearch
        - name: SW_STORAGE_ES_CLUSTER_NODES              # es地址
          value: "elastic.od.com"
        - name: SW_ES_USER                               # es用户
          value: "elastic"
        - name: SW_ES_PASSWORD                           # es密码
          value: "admin123"
        - name: SW_TELEMETRY
          value: "prometheus"
vim svc.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: oap-svc
  namespace: skywalking
  labels:
    app: oap
spec:
  type: ClusterIP
  ports:
  - port: 11800
    name: grpc
  - port: 1234
    name: prometheus-port
  - port: 12800
    name: rest
  selector:
    app: oap

应用资源配置清单

kubectl apply -f rbac.yaml
kubectl apply -f dp.yaml
kubectl apply -f svc.yaml

部署UI

DeploymentServiceIngress

# vim ui-dp.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ui
  namespace: skywalking
  labels:
    app: ui
spec:
  replicas: 1
  selector:
    matchLabels:
        app: ui
  template:
    metadata:
      labels:
        app: ui
    spec:
      affinity:
      containers:
      - name: ui
        image: skywalking.docker.scarf.sh/apache/skywalking-ui:9.7.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: page
        env:
        - name: SW_OAP_ADDRESS
          value: http://oap-svc:12800            # 根据oap的svc一致
# vim ui-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: ui
  name: ui-svc
  namespace: skywalking
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  selector:
    app: ui
# vim ing.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: skywalking-web
  namespace: skywalking
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`skywalking.od.com`)
    kind: Rule
    services:
    - name: ui-svc
      port: 80

应用资源配置清单

kubectl apply -f ui-dp.yaml
kubectl apply -f ui-svc.yaml
kubectl apply -f ing.yaml

通过浏览器访问 http://skywalking.od.com,Skywalking 默认没有任何监控指标的。

skywalkingui界面默认没有访问控制,可以通过下面基于TraefikbasicAuth 方案,实现自定义服务的外部验证。

安装 htpasswd 工具生成密码文件

yum -y install httpd-tools.x86_64

# 密码文件名称为htpasswd
htpasswd -bc htpasswd wangxiansen 123456  

kubectl create secret generic basic-auth --from-file=htpasswd -n skywalking

创建 ingressroute,使用 basicAuth 中间件

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: basic-auth-middleware
  namespace: skywalking
spec:
  basicAuth:
    secret: basic-auth
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: skywalking-web
  namespace: skywalking
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`skywalking.od.com`)
    kind: Rule
    services:
    - name: ui-svc
      port: 80
    middlewares:
    - name: basic-auth-middleware

Helm方式部署

设置环境变量

# 配置安装helm软件的名称
export SKYWALKING_RELEASE_NAME=skywalking
# 配置skywalking安装到k8s的命名空间
export SKYWALKING_RELEASE_NAMESPACE=devops
# 配置helm仓库名称
export REPO=skywalking

helm添加仓库

$ helm repo add ${REPO} https://apache.jfrog.io/artifactory/skywalking-helm

把skywalking安装包拉取下来

$ helm pull  ${REPO}/skywalking --untar

修改values.yaml

elasticsearch:
...
config:
  host: elasticsearch.devops.svc
  password:
  port:
    http: 9200
  user:
enabled: false
...
oap:
antiAffinity: soft
dynamicConfigEnabled: false
env: null
envoy:
  als:
    enabled: false
image:
  pullPolicy: IfNotPresent
  repository: skywalking.docker.scarf.sh/apache/skywalking-oap-server
  tag: 9.7.0
....
ui:
image:
  pullPolicy: IfNotPresent
  repository: skywalking.docker.scarf.sh/apache/skywalking-ui
  tag: 9.7.0

部署&&升级

## 安装部署
$ helm install skywalking skywalking -n devops --values ./skywalking/values.yaml

## 更新
$ helm upgrade skywalking skywalking -n devops --values ./skywalking/values.yaml

## 卸载
$ helm uninstall skywalking -ndevops

总结

基于 Kubernetes 的 SkyWalking 部署方式总结:

  1. 弹性伸缩:Kubernetes 是一个流行的容器编排平台,它提供了自动伸缩的能力。当负载增加时,可以通过调整副本数量来自动扩展 SkyWalking 服务实例,以适应更大的监控需求。
  2. 故障恢复:Kubernetes 提供了高可用性和故障恢复机制。如果某个 SkyWalking 服务实例出现故障或崩溃,Kubernetes 能够自动重启该实例或将其替换为新的实例,从而确保监控服务的连续性。
  3. 资源管理:Kubernetes 具有强大的资源管理功能。通过配置资源限制和请求,可以为 SkyWalking 分配适当的计算资源(如 CPU 和内存),以满足监控服务的性能需求。同时,Kubernetes 还支持资源配额和优先级设置,以确保 SkyWalking 应用程序在共享的集群环境中获得公平的资源分配。
  4. 安装和部署简化:Kubernetes 提供了简洁的部署和管理方式。使用 Kubernetes 部署 SkyWalking,可以通过声明性的配置文件及比较成熟的HELM方式部署落地,并使用 Kubernetes 资源对象(如 Deployment、Service、Ingress 等)来管理应用的生命周期。提高了可维护性和可重复性。
  5. 与微服务集成:Kubernetes 与微服务架构天生契合。SkyWalking 作为一个分布式追踪和监控系统,可以无缝地与 Kubernetes 中的微服务应用程序集成。它能够自动发现和跟踪各个微服务之间的调用关系,提供全面的分布式追踪和性能监控。

总的来说,基于 Kubernetes 的 SkyWalking 部署方式充分利用了 Kubernetes 的弹性伸缩、故障恢复、资源管理和简化部署等优势。

这种部署方式使 SkyWalking 能够更好地适应动态的监控需求,并与微服务架构紧密集成,提供高效、可靠的分布式追踪和监控能力。