Kubernetes + Spring Cloud 集成鏈路追蹤 SkyWalking

1、概述
一、什麼是 SkyWalking ?
分佈式系統的應用程序性能監視工具,專爲微服務、雲原生架構和基於容器(Docker、K8s、Mesos)架構而設計。提供分佈式追蹤、服務網格遙測分析、度量聚合和可視化一體化解決方案。java

官網地址:http://skywalking.apache.org/nginx

二、SkyWalking 特性
多種監控手段,語言探針和 Service Mesh
多語言自動探針,Java,.NET Core和Node.JS
輕量高效,不須要大數據
模塊化,UI、存儲、集羣管理多種機制可選
支持告警
優秀的可視化方案
三、總體結構
image.png
整個架構,分紅上、下、左、右四部分:git

考慮到讓描述更簡單,咱們捨棄掉 Metric 指標相關,而着重在 Tracing 鏈路相關功能。github

上部分 Agent :負責從應用中,收集鏈路信息,發送給 SkyWalking OAP 服務器。目前支持 SkyWalking、Zikpin、Jaeger 等提供的 Tracing 數據信息。而咱們目前採用的是,SkyWalking Agent 收集 SkyWalking Tracing數據,傳遞給服務器。
下部分 SkyWalking OAP :負責接收 Agent 發送的 Tracing 數據信息,而後進行分析(Analysis Core) ,存儲到外部存儲器( Storage ),最終提供查詢( Query)功能。spring

右部分 Storage :Tracing 數據存儲。目前支持 ES、MySQL、Sharding Sphere、TiDB、H2 多種存儲器。而咱們目前採用的是 ES ,主要考慮是 SkyWalking 開發團隊本身的生產image.pngdocker

左部分 SkyWalking UI :負責提供控臺,查看鏈路等等
簡單概況原理爲下圖:
![上傳中...]()apache

2、搭建 skywalking
一、環境準備
Mkubernetes 版本:1.18.5
Nginx Ingress 版本:2.2.8
Helm 版本:3.2.4
持久化存儲驅動:NFS
二、使用 chart 部署
本文主要講述的是如何使用 Helm Charts 將 SkyWalking 部署到 Kubernetes 集羣中,相關文檔能夠參考skywalking-kubernetescentos

目前推薦的四種方式:api

使用 helm 3 提供的 helm serve 啓動本地 helm repo
使用本地 chart 文件部署
使用 harbor 提供的 repo 功能
直接從官方 repo 進行部署(暫不知足)

注意:目前 skywalking 的 chart 尚未提交到官方倉庫,請先參照前三種方式進行部署bash


2.一、 下載 chart 文件
能夠直接使用本地文件部署 skywalking,按照上面的步驟將skywalking chart下載完成以後,直接使用如下命令進行部署:

git clone https://github.com/apache/sky...
cd skywalking-kubernetes/chart
helm repo add elastic https://helm.elastic.co
helm dep up skywalking
export SKYWALKING_RELEASE_NAME=skywalking # 定義本身的名稱
export SKYWALKING_RELEASE_NAMESPACE=default # 定義本身的命名空間
2.二、定義已存在es參數文件
修改values-my-es.yaml:

oap:
image:

tag: 8.1.0-es7      # Set the right tag according to the existing Elasticsearch version

storageType: elasticsearch7

ui:
image:

tag: 8.1.0

elasticsearch:
enabled: false
config: # For users of an existing elasticsearch cluster,takes effect when elasticsearch.enabled is false

host: elasticsearch-client
port:
  http: 9200
user: "elastic"         # [optional]
password: "admin@123"     # [optional]

2.三、helm 安裝
helm install "${SKYWALKING_RELEASE_NAME}" skywalking -n "${SKYWALKING_RELEASE_NAMESPACE}" \
-f ./skywalking/values-my-es.yaml
安裝完成後,咱們覈實下安裝狀況:

$ kubectl get deployment -n skywalking
NAME READY UP-TO-DATE AVAILABLE AGE
my-skywalking-oap 2/2 2 2 9m
my-skywalking-ui 1/1 1 1 9m
3、使用 Skywalking Agent
Java 中使用 agent ,提供瞭如下三種方式供你選擇

使用官方提供的基礎鏡像
將 agent 包構建到已經存在的基礎鏡像中
sidecar 模式掛載 agent(推薦)
一、使用官方提供的基礎鏡像
查看官方 docker hub 提供的基礎鏡像,只須要在你構建服務鏡像是 From 這個鏡像便可,直接集成到 Jenkins 中能夠更加方便

二、將 agent 包構建到已經存在的基礎鏡像中
提供這種方式的緣由是:官方的鏡像屬於精簡鏡像,而且是 openjdk ,可能不少命令沒有,須要本身二次安裝,這裏略過。

三、sidecar 模式掛載 agent
因爲服務是部署在 Kubernetes 中,使用這種方式來使用 Skywalking Agent ,這種方式的好處在不須要修改原來的基礎鏡像,也不用從新構建新的服務鏡像,而是以sidecar 模式,經過共享 volume 的方式將 agent 所需的相關文件掛載到已經存在的服務鏡像中。

3.一、構建 skywalking agent image
本身構建,參考:https://hub.docker.com/r/prop...

經過如下 dockerfile 進行構建:

FROM alpine:3.8

LABEL maintainer="zmailto:uozewei@hotmail.com"

ENV SKYWALKING_VERSION=8.1.0

ADD http://mirrors.tuna.tsinghua....${SKYWALKING_VERSION}/apache-skywalking-apm-${SKYWALKING_VERSION}.tar.gz /

RUN tar -zxvf /apache-skywalking-apm-${SKYWALKING_VERSION}.tar.gz && \

mv apache-skywalking-apm-bin skywalking && \
mv /skywalking/agent/optional-plugins/apm-trace-ignore-plugin* /skywalking/agent/plugins/ && \
echo -e "\n# Ignore Path" >> /skywalking/agent/config/agent.config && \
echo "# see https://github.com/apache/skywalking/blob/v8.1.0/docs/en/setup/service-agent/java-agent/agent-optional-plugins/trace-ignore-plugin.md" >> /skywalking/agent/config/agent.config && \
echo 'trace.ignore_path=${SW_IGNORE_PATH:/health}' >> /skywalking/agent/config/agent.config

docker build -t 172.16.106.237/monitor/skywalking-agent:8.1.0 .
待 docker build 完畢後,push 到倉庫便可。

3.二、使用 sidecar 掛載
示例配置文件以下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-skywalking
spec:
replicas: 1
selector:

matchLabels:
  app: demo-skywalking

strategy:

rollingUpdate:
  maxSurge: 1
  maxUnavailable: 0
type: RollingUpdate

template:

metadata:
  labels:
    app: demo-skywalking
spec:
  initContainers:
    - name: init-skywalking-agent
      image: 172.16.106.237/monitor/skywalking-agent:8.1.0
      command:
        - 'sh'
        - '-c'
        - 'set -ex;mkdir -p /vmskywalking/agent;cp -r /skywalking/agent/* /vmskywalking/agent;'
      volumeMounts:
        - mountPath: /vmskywalking/agent
          name: skywalking-agent
  containers:
    - image: nginx:1.7.9
      imagePullPolicy: Always
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP
      volumeMounts:
        - mountPath: /opt/skywalking/agent
          name: skywalking-agent
  volumes:
    - name: skywalking-agent
      emptyDir: {}

以上是掛載 sidecar 的 deployment.yaml 文件,以 nginx 做爲服務爲例,主要是經過共享 volume 的方式掛載 agent,首先 initContainers 經過 skywalking-agent 卷掛載了 sw-agent-sidecar 中的 /vmskywalking/agent,而且將上面構建好的鏡像中的 agent 目錄 cp 到了 /vmskywalking/agent 目錄,完成以後 nginx 啓動時也掛載了 skywalking-agent 卷,並將其掛載到了容器的 /opt/skywalking/agent 目錄,這樣就完成了共享過程。

4、改造 Spring Cloud 應用
一、docker打包並推送到倉庫
修改下 dockerfile 配置,集成 skywalking agent:

FROM insideo/centos7-java8-build
VOLUME /tmp
ADD mall-admin.jar app.jar
RUN bash -c 'touch /app.jar'
RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai > /etc/timezone
ENTRYPOINT ["java","-Dapp.id=svc-mall-admin","-javaagent:/opt/skywalking/agent/skywalking-agent.jar","-Dskywalking.agent.service_name=svc-mall-admin","-Dskywalking.collector.backend_service=my-skywalking-oap.skywalking.svc.cluster.local:11800","-jar","-Dspring.profiles.active=prod","-Djava.security.egd=file:/dev/./urandom","/app.jar"]
改好了,直接運行 maven package 就能將這個項目打包成鏡像。

注意:


k8s 建立 Service 時,它會建立相應的 DNS 條目。此條目的格式爲 <service-name>.<namespace-name>.svc.cluster.local,這意味着若是容器只使用<service-name>,它將解析爲本地服務到命名空間。若是要跨命名空間訪問,則須要使用徹底限定的域名。


二、編寫 k8s的yaml版本的部署腳本
這裏我以其中某服務舉例:


apiVersion: apps/v1
kind: Deployment
metadata:
name: svc-mall-admin
spec:
replicas: 1
selector:

matchLabels:
  app: svc-mall-admin

strategy:

rollingUpdate:
  maxSurge: 1
  maxUnavailable: 0
type: RollingUpdate

template:

metadata:
  labels:
    app: svc-mall-admin
spec:
  initContainers:
    - name: init-skywalking-agent
      image: 172.16.106.237/monitor/skywalking-agent:8.1.0
      command:
        - 'sh'
        - '-c'
        - 'set -ex;mkdir -p /vmskywalking/agent;cp -r /skywalking/agent/* /vmskywalking/agent;'
      volumeMounts:
        - mountPath: /vmskywalking/agent
          name: skywalking-agent
  containers:
    - image: 172.16.106.237/mall_repo/mall-admin:1.0
      imagePullPolicy: Always
      name: mall-admin
      ports:
        - containerPort: 8180
          protocol: TCP
      volumeMounts:
        - mountPath: /opt/skywalking/agent
          name: skywalking-agent
  volumes:
    - name: skywalking-agent
      emptyDir: {}

apiVersion: v1
kind: Service
metadata:
name: svc-mall-admin
spec:
ports:

- name: http
  port: 8180
  protocol: TCP
  targetPort: 8180

selector:

app: svc-mall-admin

而後就能夠直接運行了,它就能夠將的項目所有跑起來了。

5、測試驗證
完事,能夠去 SkyWalking UI 查看是否鏈路收集成功。

一、 測試應用 API
首先,請求下 Spring Cloud 應用提供的 API。由於,咱們要追蹤下該鏈路。
image.png

二、 查看 SkyWalking UI 界面
image.png
在這裏插入圖片描述
這裏,咱們會看到 SkyWalking 中很是重要的三個概念:

服務(Service) :表示對請求提供相同行爲的一系列或一組工做負載。在使用 Agent 或 SDK 的時候,你能夠定義服務的名字。若是不定義的話,SkyWalking 將會使用你在平臺(例如說 Istio)上定義的名字。這裏,咱們能夠看到 Spring Cloud 應用的服務爲 svc-mall-admin,就是咱們在 agent 環境變量 service_name 中所定義的。

服務實例(Service Instance) :上述的一組工做負載中的每個工做負載稱爲一個實例。就像 Kubernetes 中的 pods 同樣, 服務實例未必就是操做系統上的一個進程。但當你在使用 Agent 的時候, 一個服務實例實際就是操做系統上的一個真實進程。這裏,咱們能夠看到 Spring Cloud 應用的服務爲 UUID@hostname,由 Agent 自動生成。

端點(Endpoint) :對於特定服務所接收的請求路徑, 如 HTTP 的 URI 路徑和 gRPC 服務的類名 + 方法簽名。

這裏,咱們能夠看到 Spring Cloud 應用的一個端點,爲 API 接口 /mall-admin/admin/login。

更多 agent 參數介紹參考:https://github.com/apache/sky...

點擊「拓撲圖」菜單,進入查看拓撲圖的界面:image.png
點擊「追蹤」菜單,進入查看鏈路數據的界面:image.png

6、小結本文詳細介紹瞭如何使用 Kubernetes + Spring Cloud 集成 SkyWalking,順便說下調用鏈監控在目前的微服務系統裏面是必不可少的組件,分佈式追蹤、服務網格遙測分析、度量聚合和可視化仍是挺好用的,這裏咱們選擇了 Skywalking,具體緣由和細節的玩法就不在此詳述了。

相關文章
相關標籤/搜索