自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在Kubernetes中從零打造可觀測(cè)性

云計(jì)算 云原生
我們使用Start.spring.io創(chuàng)建一個(gè)Java spring boot項(xiàng)目,它可以幫我們快速創(chuàng)建一個(gè)Java項(xiàng)目,并且支持在項(xiàng)目中添加依然和其他配置。

在這篇文章中,我們將在Kubernetes中使用Grafana、Prometheus、Loki、Tempo、OpenTelemetry來(lái)搭建可觀測(cè)性平臺(tái)。其中Grafana作為操作面板,Prometheus、Loki、Tempo作為數(shù)據(jù)源,分別用來(lái)獲取指標(biāo)、日志以及跟蹤數(shù)據(jù)。同時(shí),我們還將使用Exemplars將trace_id與Java指標(biāo)相關(guān)聯(lián),使用OpenTelemetry對(duì)應(yīng)用進(jìn)行檢測(cè)。

在開(kāi)始之前,先簡(jiǎn)單介紹一下這些開(kāi)源工具。

  1. OpenTelemetry:它是CNCF的 開(kāi)源產(chǎn)品,通過(guò)使用代理來(lái)收集指標(biāo)、日志和鏈路,然后將它們發(fā)送給其他工具,它支持多種語(yǔ)言集成,并且有很大的儀表功能。
  2. Prometheus:CNCF的畢業(yè)產(chǎn)品,是目前主流的監(jiān)控工具之一。
  3. Examplars:它可以將trace_id和metrics聯(lián)系起來(lái),可以幫助我們通過(guò)指標(biāo)獲取到具體日志以及鏈路狀況,通常和Prometheus配合工作。
  4. Promtail:日志收集工具,將日志發(fā)送到Loki。
  5. Loki:收集并處理日志,并且支持通過(guò)LogQL來(lái)查詢(xún)?nèi)罩?,其語(yǔ)法和PromQL類(lèi)似
  6. Tempo:接收OpenTelemetry的數(shù)據(jù),并且可以通過(guò)Jaeger將其可視化
  7. Grafana:支持多種數(shù)據(jù)源的可視化面板

圖片

準(zhǔn)備后端應(yīng)用程序

在這個(gè)示例中,我們將使用java spring boot項(xiàng)目作為例子。

首先,我們使用start.spring.io創(chuàng)建一個(gè)java spring boot項(xiàng)目,它可以幫我們快速創(chuàng)建一個(gè)Java項(xiàng)目,并且支持在項(xiàng)目中添加依然和其他配置。

圖片

其中:

  • 使用Gradle作為構(gòu)建自動(dòng)化工具
  • 使用2.7版本的Spring Boot
  • 使用JAR作為包構(gòu)建格式
  • 使用JDK11

當(dāng)完成配置并生成之后,就可以將其壓縮包下載下來(lái)并用IDE打開(kāi)。

圖片

我們先配置build.gradle,確保所有依賴(lài)是沒(méi)問(wèn)題的。

plugins {
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}

repositories {
maven {
url = uri('https://repo.spring.io/libs-snapshot')
}
mavenCentral()
}

dependencyManagement {
imports {
mavenBom 'io.micrometer:micrometer-bom:1.9.0-SNAPSHOT'
}
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus:1.9.0'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.opentelemetry:opentelemetry-api:1.12.0'
}

tasks.named('test') {
useJUnitPlatform()
}

group = 'com.staz'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

然后我們將創(chuàng)建一個(gè)控制器類(lèi)Controller.java?,有兩個(gè)端點(diǎn):/fail? 和 /success?。該文件必須位于${project}/src/main/java/com/staz/observability/的路徑下。

package com.staz.observability;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Controller {

@PostMapping("/fail")
public String fail() {
return "Fail!";
}

@GetMapping("/success")
public String success() {

return "Success!";
}

}

為了將metrics和trace_id關(guān)聯(lián)起來(lái),我們需要在${project}/src/main/java/com/staz/observability/?路徑下創(chuàng)建一個(gè)公共配置類(lèi)PrometheusExemplarConfiguration.java。

package com.staz.observability;

import io.micrometer.core.instrument.Clock;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.opentelemetry.api.trace.Span;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exemplars.DefaultExemplarSampler;
import io.prometheus.client.exemplars.tracer.otel_agent.
OpenTelemetryAgentSpanContextSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PrometheusExemplarConfiguration {
@Bean
public PrometheusMeterRegistry prometheusMeterRegistryWithExemplar
(PrometheusConfig prometheusConfig, CollectorRegistry collectorRegistry,
Clock clock) {
return new PrometheusMeterRegistry(prometheusConfig, collectorRegistry,
clock, new DefaultExemplarSampler(new OpenTelemetryAgentSpanContextSupplier() {

@Override
public String getTraceId() {
if (!Span.current().getSpanContext().isSampled()) {
return null;
}
return super.getTraceId();
}
})
);
}
}

最后,編輯${project}/src/main/resources/?目錄下的配置文件application.yml:

# Enable Actuator endpoints including Prometheus
management:
endpoints:
web:
exposure:
include: health, info, prometheus
metrics:
# Exemplar metrics
distribution:
percentiles-histogram:
http.server.requests: true
minimum-expected-value:
http.server.requests: 5ms
maximum-expected-value:
http.server.requests: 1000ms

# Add trace_id in log. OpenTelemetry set this value using logger-mdc.
# https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/logger-mdc-instrumentation.md
logging:
pattern:
level: '%prefix(%mdc{trace_id:-0}) %5p'

如果想要在本地運(yùn)行項(xiàng)目,需要下載OpenTelemetry Agent,該項(xiàng)目中使用的版本是1.12.1。

準(zhǔn)備工作做完過(guò)后,我們?cè)诒镜貋?lái)測(cè)試一下。

首先,使用gradle build -x test編譯項(xiàng)目。

圖片

然后使用以下命令啟動(dòng):

java -javaagent:opentelemetry-javaagent.jar -Dspring.config.locatinotallow=src/main/resources/application.yml -jar build/libs/observability-0.0.1-SNAPSHOT.jar

圖片

然后可以使用htttp://localhost:8080/fail和htttp://localhost:8080/success進(jìn)行訪問(wèn)測(cè)試。

圖片

再來(lái)使用localhost:8080/actuator/prometheus來(lái)驗(yàn)證Prometheus指標(biāo)是否有效。

圖片

最后,驗(yàn)證metrice和trace_id的關(guān)聯(lián)情況。

curl -H 'Accept: application/openmetrics-text; versinotallow=1.0.0; charset=utf-8' http://localhost:8080/actuator/prometheus | grep trace_id

圖片

我們的Spring Boot應(yīng)用程序已經(jīng)準(zhǔn)備好了,現(xiàn)在我們需要安裝觀察性工具。在此之前,我們會(huì)在本地創(chuàng)建一個(gè)K3s集群,所有的軟件都將部署到里面。

容器化應(yīng)用程序

首先,在項(xiàng)目根目錄創(chuàng)建一個(gè)Dockerfile,內(nèi)容如下:

# Download OpenTelemetryAgent
FROM curlimages/curl:7.81.0 AS OTEL_AGENT
ARG OTEL_AGENT_VERSION="1.12.1"
RUN curl --silent --fail -L "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v${OTEL_AGENT_VERSION}/opentelemetry-javaagent.jar" \
-o "/tmp/opentelemetry-javaagent.jar"

# Build .JAR file
FROM gradle:7.1.1-jdk11-hotspot AS BUILD_IMAGE
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build -x test --no-daemon

# Final image copying OTEL Agent and .JAR File
FROM gradle:7.1.1-jdk11-hotspot
ENV TIME_ZONE America/Lima
ENV TZ=$TIME_ZONE
ENV JAVA_OPTS "-Dspring.config.locatinotallow=src/main/resources/application.yml"
COPY --from=OTEL_AGENT /tmp/opentelemetry-javaagent.jar /otel-javaagent.jar
COPY --from=BUILD_IMAGE home/gradle/src/build/libs/*.jar app.jar
ENTRYPOINT exec java -javaagent:/otel-javaagent.jar -jar app.jar

使用以下命令構(gòu)建并測(cè)試:

$ docker build --no-cache -t otel-springboot-prometheus .
$ docker run -it -p 8080:8080 otel-springboot-prometheus

待容器啟動(dòng)過(guò)后,使用http://localhost:8080/success驗(yàn)證是否可以正常使用。

創(chuàng)建單節(jié)點(diǎn)集群

首先,使用multipass創(chuàng)建一個(gè)Ubuntu實(shí)例:

$ multipass launch --name demo --mem 4G --disk 20G

圖片

然后登錄實(shí)例:

$ multipass shell demo

圖片

可以通過(guò)sudo su命令驗(yàn)證是否正確進(jìn)去Ubuntu實(shí)例。

其次,使用以下命令安裝K3s:

$ curl -sfL https://get.k3s.io | sh -

集群創(chuàng)建完成后,將KUBECONFIG添加到環(huán)境變量。

$ export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

檢查集群是否正常運(yùn)行。

$ kubectl cluster-info

圖片

然后,安裝Helm,后續(xù)都將使用它來(lái)安裝應(yīng)用軟件。

$ snap install helm --classic

將K3s的KUBECONFIG?拷貝到~/.kube/config目錄下。

$ kubectl config view --raw > ~/.kube/config

最后,檢查Helm是否能正常工作。

$ helm

圖片

部署可觀測(cè)性組件

在該階段,我們將使用Helm部署Prometheus、Promtail、Loki、Tempo以及Grafana,最后部署應(yīng)用并驗(yàn)證。

 以上應(yīng)用都將部署到K3s中。

首先,從倉(cāng)庫(kù)把需要的manifests克隆下來(lái)。

$ git clone https://github.com/stazdx/otel-springboot-grafana-tools.git
$ cd otel-springboot-grafana-tools/kubernetes

然后,添加Helm倉(cāng)庫(kù)。

$ helm repo add grafana https://grafana.github.io/helm-charts
$ helm repo update

圖片

最后,創(chuàng)建一個(gè)namespace,所有應(yīng)用都部署到該namespace下。

$ kubectl create ns observability

圖片

部署Promtail

使用以下命令進(jìn)行部署:

$ cd promtail
$ helm upgrade --install promtail grafana/promtail -n observability -f promtail.yaml

圖片

注意檢查Promtail?所指向的Loki地址。

部署Loki

部署命令如下:

$ helm upgrade --install loki grafana/loki-distributed -n observability

圖片

loki-loki-distributed-gateway這個(gè)Service非常重要,Promtail將向它發(fā)送數(shù)據(jù),Grafana將通過(guò)它獲取數(shù)據(jù)。

部署Tempo

首先,進(jìn)入Tempo清單所在的目錄:

$ cd ../tempo

在安裝Tempo之前,我們需要先安裝minio,命令如下:

$ kubectl apply -f minio.yaml

圖片

 Minio被部署在default命名空間中,因?yàn)樗且粋€(gè)更通用的對(duì)象存儲(chǔ)工具,而不是直接用于觀察性。

現(xiàn)在,使用以下命令部署Tempo:

$ helm upgrade --install tempo grafana/tempo-distributed -n observability -f tempo.yaml

圖片

!! Grafana將通過(guò)_tempo-tempo-distributed-query-frontend:3100_來(lái)獲取數(shù)據(jù)。

部署Prometheus和Grafana

Prometheus和Grafana直接使用官網(wǎng)倉(cāng)庫(kù)進(jìn)行部署。

首先,添加Helm倉(cāng)庫(kù)。

$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm repo update

然后,使用倉(cāng)庫(kù)清單進(jìn)行部署。

$ cd ../prometheus-grafana
$ helm dependency update
helm upgrade --install kube-prometheus-stack -n observability .

圖片

檢查Deployments

使用Helm命令查看部署的所有應(yīng)用。

$ helm ls -n observability

圖片

然后,使用kubectl檢查應(yīng)用是否都啟動(dòng)成功。

$ kubectl get po -n observability

圖片

檢查Service是否正常。

$ kubectl get svc -n observability

圖片

我們看到所有應(yīng)用都正常部署完成。

部署后端應(yīng)用

直接到倉(cāng)庫(kù)目錄清單部署即可。

$ cd ../springboot-app

需要注意的是,為了能夠讓Prometheus能夠正常抓取指標(biāo),我們需要添加以下??Annotations??。

annotations:
# Annotations for Prometheus - scrape config
prometheus.io/path: '/actuator/prometheus'
prometheus.io/port: 'actuator'
prometheus.io/scrape: 'true'

另外一個(gè)重要的配置就是OpenTelemetry配置,如下:

env:
- name: SERVER_PORT
value: '8080'
- name: MANAGEMENT_SERVER_PORT
value: '8081'
# Setting OTEL_EXPORTER_METRICS: none - Default: OTLP
- name: OTEL_METRICS_EXPORTER
value: none
- name: OTEL_TRACES_EXPORTER
value: otlp,logging
# Setting Tempo Distributor Service using GRPC Port -> 4317
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://tempo-tempo-distributed-distributor.observability.svc.cluster.local:4317
- name: OTEL_SERVICE_NAME
value: springboot-app
- name: KUBE_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OTEL_RESOURCE_ATTRIBUTES
value: app=springboot-app

最后,我們有一個(gè)包含Spring Boot的Grafana儀表盤(pán)的配置圖,這將使我們能夠通過(guò)請(qǐng)求延遲等指標(biāo)看到Exemplar與Tempo的關(guān)聯(lián)。

配置檢查無(wú)誤后,就可以進(jìn)行部署了。

$ kubectl apply -f springboot-app.yaml

圖片

檢查應(yīng)用是否部署成功。

$ kubectl get deploy,svc,cm -l app=springboot-app

圖片

接口測(cè)試

首先,測(cè)試/fail?接口:http://{external-ip}:8080/fail。

圖片

然后,測(cè)試/success?接口:http://{external-ip}:8080/success。

圖片

最后,測(cè)試/actuator/prometheus?接口:http://{external-ip}:8081/actuator/prometheus。

圖片

可以看到所有接口返回正常。

Grafana測(cè)試

上面以及完成了所有的配置,接下來(lái)就在Grafana中驗(yàn)證是否能夠正常使用。

首先,獲取Grafana的訪問(wèn)地址。

$ kubectl get svc -n observability

圖片

在瀏覽器輸入地址http://{external-ip}:32656。

圖片

然后,添加數(shù)據(jù)源。

圖片

我們把Prometheus、Loki以及Tempo數(shù)據(jù)源都添加上。

圖片

其中,Prometheus的配置如下:

圖片

!! 可以看到Prometheus和Tempo通過(guò)Exemplars進(jìn)行關(guān)聯(lián)了。

Loki的配置如下:

圖片

!! 可以看到Loki和Tempo通過(guò)trace_id進(jìn)行關(guān)聯(lián)了。

Tempo的配置如下:

圖片

!! 在這里我們將Tempo與Loki相關(guān)聯(lián),并映射我們?cè)谖⒎?wù)中配置的應(yīng)用標(biāo)簽。

測(cè)試一下

通過(guò)Explore可以查看應(yīng)用日志。

圖片

選擇Loki數(shù)據(jù)源。

圖片

通過(guò)Loki,我們可以通過(guò)label對(duì)監(jiān)控日志進(jìn)行過(guò)濾。

圖片

從日志中,我們可以看到trace信息。

圖片

然后,我們查看Grafana面板。

圖片

我們選擇Spring Boot Demo,它是我們自己創(chuàng)建的面板。

圖片

我們可以看到應(yīng)用的請(qǐng)求延遲,另外星星是由Exemplar生成。

圖片

圖片

用鼠標(biāo)懸停在它上面,我們可以看到它是如何與一個(gè)trace_id相關(guān)聯(lián)的,當(dāng)點(diǎn)擊它時(shí),它將把我們重定向到Tempo。

圖片

我們可以看到它產(chǎn)生的跟蹤,我們也可以看到日志,因?yàn)樗彩桥cLoki相關(guān)的,當(dāng)點(diǎn)擊時(shí)我們會(huì)看到具體信息:

圖片

屏幕被分割,但是我們可以看到具體的日志了。

最后

我們實(shí)現(xiàn)了指標(biāo)、日志和跟蹤之間的可觀察性關(guān)聯(lián)。這可以幫助我們?cè)谖⒎?wù)的故障排除過(guò)程中,識(shí)別瓶頸,看到我們的應(yīng)用指標(biāo)的行為,并能夠獲得特定的跟蹤和日志。

責(zé)任編輯:姜華 來(lái)源: 運(yùn)維開(kāi)發(fā)故事
相關(guān)推薦

2022-08-05 14:26:50

Kubernetes容器工具

2025-02-24 13:46:40

2023-03-30 16:30:08

可觀測(cè)云原生

2023-04-25 16:47:48

Kubernetes可觀測(cè)性Prometheus

2022-08-30 08:22:14

可觀測(cè)性監(jiān)控軟件

2023-10-26 08:47:30

云原生數(shù)據(jù)采集

2022-07-05 15:50:25

Kubernetes工具DevOps

2023-08-03 15:13:59

混合云Kubernetes

2023-03-09 08:00:22

2023-05-18 22:44:09

2022-02-12 00:00:00

架構(gòu)

2023-10-13 13:40:29

2022-08-24 10:01:57

云原生容器

2021-06-23 10:00:46

eBPFKubernetesLinux

2025-03-03 00:46:00

GolangAPI客戶(hù)端

2023-08-21 09:37:57

MySQL工具MariaDB

2023-09-20 16:11:32

云原生分布式系統(tǒng)

2024-05-28 09:37:48

2022-05-24 13:47:11

云原生數(shù)據(jù)分辨率
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)