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

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的详细的信息。

实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值