Elastic:运用 Elastic Stack 对 Kubernetes 进行监控 (五)

11 篇文章 20 订阅

Elastic APM 是基于 Elastic Stack 构建的应用程序性能监视系统。 它使你可以实时监视软件服务和应用程序-收集有关传入请求,数据库查询,对缓存的调用,外部 HTTP 请求等的响应时间的详细性能信息。 这样可以轻松快速地找出并解决性能问题。

Elastic APM 适配 OpenTracing,这意味着您可以利用已经可用的大量库来跟踪应用程序中的组件(例如  MongoDB intrumentation)。

例如,你将能够在高度分布式的环境(微服务体系结构)中跟踪请求,并轻松快速地发现潜在的瓶颈。

Elastic APM 由一个称为 APM-Server 的组件组成,用于收集跟踪并将其发送到 ElasticSearch 以及与应用程序或服务一起运行的各个代理。

安装 APM 服务器

我们首先需要在 k8s 上安装 APM-Server,以收集代理的跟踪并将其转发到 Elasticseach。 它由用于配置设置的 ConfigMap 组成:

apm.configmap.yml

# apm.configmap.yml
---
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: monitoring
  name: apm-server-config
  labels:
    app: apm-server
data:
  apm-server.yml: |-
    apm-server:
      host: "0.0.0.0:8200"

    output.elasticsearch:
      hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}

    setup.kibana:
      host: '${KIBANA_HOST:kibana}:${KIBANA_PORT:5601}'
---

APM 服务器需要公开端口8200,以允许代理转发其跟踪。 以下服务将该端口暴露给环境:

apm.service.yml

# apm.service.yml
---
apiVersion: v1
kind: Service
metadata:
  namespace: monitoring
  name: apm-server
  labels:
    app: apm-server
spec:
  ports:
  - port: 8200
    name: apm-server
  selector:
    app: apm-server
---

最后是 Deployment,它描述了要部署的容器:

apm.deployment.yml

# apm.deployment.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: monitoring
  name: apm-server
  labels:
    app: apm-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apm-server 
  template:
    metadata:
      labels:
        app: apm-server
    spec:
      containers:
      - name: apm-server
        image: docker.elastic.co/apm/apm-server:7.6.2
        env:
        - name: ELASTICSEARCH_HOST
          value: elasticsearch-client.monitoring.svc.cluster.local
        - name: ELASTICSEARCH_PORT
          value: "9200"
        - name: ELASTICSEARCH_USERNAME
          value: elastic
        - name: ELASTICSEARCH_PASSWORD
          valueFrom:
            secretKeyRef:
              name: elasticsearch-pw-elastic
              key: password
        - name: KIBANA_HOST
          value: kibana.monitoring.svc.cluster.local
        - name: KIBANA_PORT
          value: "5601"
        ports:
        - containerPort: 8200
          name: apm-server
        volumeMounts:
        - name: config
          mountPath: /usr/share/apm-server/apm-server.yml
          readOnly: true
          subPath: apm-server.yml
      volumes:
      - name: config
        configMap:
          name: apm-server-config
---

现在,我们可以部署堆栈的这个新组件:

kubectl apply  -f apm.configmap.yml \
                 -f apm.service.yml \
                 -f apm.deployment.yml
$ kubectl apply  -f apm.configmap.yml \
>                  -f apm.service.yml \
>                  -f apm.deployment.yml
configmap/apm-server-config created
service/apm-server created
deployment.apps/apm-server created

检查一切是否正常运行:

 kubectl get all -n monitoring -l app=apm-server
$  kubectl get all -n monitoring -l app=apm-server
NAME                              READY   STATUS    RESTARTS   AGE
pod/apm-server-58b6b7d8d9-jk8r9   1/1     Running   0          43s


NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/apm-server   ClusterIP   10.108.187.142   <none>        8200/TCP   43s


NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/apm-server   1/1     1            1           43s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/apm-server-58b6b7d8d9   1         1         1       43s

现在,我们可以在 Spring-Boot 应用程序上安装代理。

在 Spring-Boot 应用上安装 Java agent

在本文的最后一部分中,我们将在示例应用程序 spring-boot-simple 上配置  Elastic APM Java agent

首先,我们需要 jar elastic-apm-agent-1.8jar 放入容器中。 添加以下行以在 Docker 构建映像时下载代理 JAR。

RUN wget -O /apm-agent.jar https://search.maven.org/remotecontent?filepath=co/elastic/apm/elastic-apm-agent/1.8.0/elastic-apm-agent-1.8.0.jar

Dockfile:

FROM openjdk:8-jdk-alpine

COPY target/spring-boot-simple.jar /app.jar

RUN wget -O /apm-agent.jar https://search.maven.org/remotecontent?filepath=co/elastic/apm/elastic-apm-agent/1.8.0/elastic-apm-agent-1.8.0.jar

CMD java -jar /app.jar

其次,将以下依赖项添加到您的应用程序中,以便您能够集成开放式跟踪库(了解更多)和/或使用 Elastic APM API 手动检测某些组件(了解更多)。

        <dependency>
            <groupId>co.elastic.apm</groupId>
            <artifactId>apm-agent-api</artifactId>
            <version>${elastic-apm.version}</version>
        </dependency>
        <dependency>
            <groupId>co.elastic.apm</groupId>
            <artifactId>apm-opentracing</artifactId>
            <version>${elastic-apm.version}</version>
        </dependency>
        <dependency>
            <groupId>io.opentracing.contrib</groupId>
            <artifactId>opentracing-spring-cloud-mongo-starter</artifactId>
            <version>${opentracing-spring-cloud.version}</version>
        </dependency>

然后,我们将更改 Deployment,以在启用 Java 代理并将其连接到 APM 服务器的情况下启动 Spring-Boot 应用程序。

# spring-boot-simple.deployment.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  name: spring-boot-simple
  labels:
    app: spring-boot-simple
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-simple
  template:
    metadata:
      labels:
        app: spring-boot-simple
    spec:
      containers:
      - image: gjeanmart/spring-boot-simple:0.0.1-SNAPSHOT
        imagePullPolicy: Always
        name: spring-boot-simple
        command:
          - "java"
          - "-javaagent:/apm-agent.jar"
          - "-Delastic.apm.active=$(ELASTIC_APM_ACTIVE)"
          - "-Delastic.apm.server_urls=$(ELASTIC_APM_SERVER)"
          - "-Delastic.apm.service_name=spring-boot-simple"
          - "-jar"
          - "app.jar"
        env:
          - name: SPRING_DATA_MONGODB_HOST
            value: mongo
          - name: ELASTIC_APM_ACTIVE
            value: "true"
          - name: ELASTIC_APM_SERVER
            value: http://apm-server.monitoring.svc.cluster.local:8200
        ports:
        - containerPort: 8080
---

现在重新应用部署,并且 spring-boot-simple 应该重新启动:

 kubectl apply -f spring-boot-simple.yml

然后,我们执行像在第一篇文章中介绍的那样:

kubectl get svc

上面显示所有的 service:

$ kubectl get svc
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes           ClusterIP   10.96.0.1       <none>        443/TCP          10h
mongo                ClusterIP   10.98.1.3       <none>        27017/TCP        9h
spring-boot-simple   NodePort    10.101.241.38   <none>        8080:30202/TCP   9h

我们通过如下的方式来找到 spring-boot-simple 的服务地址:

 minikube service spring-boot-simple --url
$ minikube service spring-boot-simple --url
🏃  Starting tunnel for service spring-boot-simple.
|-----------|--------------------|-------------|------------------------|
| NAMESPACE |        NAME        | TARGET PORT |          URL           |
|-----------|--------------------|-------------|------------------------|
| default   | spring-boot-simple |             | http://127.0.0.1:62891 |
|-----------|--------------------|-------------|------------------------|
http://127.0.0.1:62891
❗  Because you are using docker driver on Mac, the terminal needs to be open to run it.

get messages

curl -X GET http://YourIP:YourPort/message

get messages (slow request)

使用属性 sleep = <ms> 可以减慢请求的速度。

curl -X GET http://YourIP:YourPort/message?sleep=3000

get messages (error)

curl -X GET http://YourIP:YourPort/message?error=true

针对我的情况就是:

$ curl http://127.0.0.1:62891
Greetings from Spring Boot!liuxg:minikube liuxg$ 

liuxg:minikube liuxg$ curl http://127.0.0.1:62891
Greetings from Spring Boot!

liuxg:minikube liuxg$ curl http://127.0.0.1:62891
Greetings from Spring Boot!

liuxg:minikube liuxg$ curl http://127.0.0.1:62891/message?sleep=300
[{"id":"5eace24730c49e000198b8d6","message":"hello+world=","postedAt":"2020-05-02T03:00:23.860+0000"}]

liuxg:minikube liuxg$ curl http://127.0.0.1:62891/message?sleep=5000
[{"id":"5eace24730c49e000198b8d6","message":"hello+world=","postedAt":"2020-05-02T03:00:23.860+0000"}]

liuxg:minikube liuxg$ curl http://127.0.0.1:62891/message?error=true
{"timestamp":"2020-05-02T12:39:07.913+0000","status":500,"error":"Internal Server Error","message":"java.lang.Exception: Random error","path":"/message"}

liuxg:minikube liuxg$ curl http://127.0.0.1:62891/message?error=true
{"timestamp":"2020-05-02T12:39:12.307+0000","status":500,"error":"Internal Server Error","message":"java.lang.Exception: Random error","path":"/message"}

我们打开Kibana APM应用:

我们可以看到在 Kibana 中有一个叫做 spring-boot-simple 的 Service。我们点击上面的超链接:

我们可以看到里面的 transactions。点击其中的 getMessages:

 

它详细地显示了我们快的和慢的 transaction 所花的时间在哪里。我们也可以点击 Error 来查看 erros:

我们可以看到 Error 的详细的信息。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值