Elastic APM

說明

Elastic 8.0開始推薦使用Fleet Server + Elastic Agent,先前的各種Beats將會逐漸退場,不過目前Beats還有不少功能是Elastic Agent缺乏的,例如Elastic Agent的輸出,目前看來僅有支援Elasticsearch與Logstash,無法送到如Kafka等Message Queue。

架構

Elastic Agent

Elastic Agent則如同之前的Beats,裝在單機中,可用來讀取Log檔案,或接收TCP, Socket之類的資料流,再傳至Elasticsearch。

Fleet

Fleet server is an elastic-agent running in a server mode。

Fleet Sever也是一個Elastic Agent,僅是以Server mode的狀態運行,Fleet的存在是為透過Policy管理分散的Elastic Agent,並不是做為接收Elastic Agent的資料,這是要特別注意的。

下圖為Elastic Agent -> Fleet Sever -> Elasticsearch的架構。

20210727174241218

在Elastic 8.0版本,要使用APM integrations (Fleet) 的話,一定要將security選項開啟。
Screen Shot 2022-05-03 at 08.49.09

Environment config

.Env

利用.env來指定共用的參數是個好習慣。

ELK_VERSION=8.2.0
TIME_ZONE=Asia/Taipei
ES_JAVA_OPTS=-Xmx512m -Xms512m
KAFKA_VERSION=3.1.0-amd64
SKW_VERSION=9.0.0

ELASTIC_PASSWORD=changeme
LICENSE=basic

在此指定了elastic的版本與root account: elastic的密碼

Elasticsearch

docker-compose.yml

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
    container_name: elasticsearch
    environment:
      - ES_JAVA_OPTS=${ES_JAVA_OPTS}
      - TZ=${TIME_ZONE}
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD:-}
      - cluster.name=docker-cluster
      - discovery.type=single-node
      - network.host=0.0.0.0
      - http.host=0.0.0.0
      - xpack.security.enabled=true
      - xpack.security.authc.api_key.enabled=true
    ports:
      - "9200:9200"
      - "9300:9300"
    healthcheck:
      test: nc -z localhost 9200 || exit 1
      interval: 5s
      timeout: 10s
      retries: 100
    volumes:
      - ./data/elasticsearch:/usr/share/elasticsearch/data
    networks:
      - tracing

其中的

      - xpack.security.enabled=true
      - xpack.security.authc.api_key.enabled=true

一定要開,之後的Fleet Server才能正常接入,但這也會造成要使用kibana時需要登入。

Kibana

docker-compose.yml

  kibana:
    image: docker.elastic.co/kibana/kibana:${ELK_VERSION}
    container_name: kibana
    environment:
      - ES_JAVA_OPTS=${ES_JAVA_OPTS}
      - TZ=${TIME_ZONE}
    ports:
      - "5601:5601"
    volumes:
      - ./config/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
      - ./data/kibana:/usr/share/kibana/data
    healthcheck:
      test: ["CMD-SHELL", "curl -u elastic:changeme -s http://localhost:5601/api/status"]
      interval: 5s
      timeout: 10s
      retries: 120
    networks:
      - tracing
    depends_on:
      elasticsearch:
        condition: service_healthy

kibana.yml

server.name: kibana
server.host: 0.0.0.0
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
monitoring.ui.container.elasticsearch.enabled: true

## X-Pack security credentials
#
elasticsearch.username: kibana_system
elasticsearch.password: changeme

在此預先將kibana_system的帳密寫好,稍待下一部份Security設定後即可使用

Security

Set User Password

docker-compose.yaml中已透過- ELASTIC_PASSWORD=${ELASTIC_PASSWORD:changeme}輸入elasticsearch的root 使用者elastic的密碼為changeme,所以之後的curl操作皆可使用elastic:changeme做為驗証的帳密資料。

若未完成下列的操作,會連Kibana的登入畫面都無法顯示,所以在container啟動後第一步要做的就是將kibana預設的帳號啟用。

Get name of build-in users
curl http://elastic:changeme@localhost:9200/_security/user

可以收到如下的結果,可知預設的user有apm_system beats_system elastic kibana kibana_system logstash_system remote_monitoring_user

{
    "apm_system": {
        ...
        "username": "apm_system"
    },
    "beats_system": {
        ...
        "username": "beats_system"
    },
    "elastic": {
        ...
        "username": "elastic"
    },
    "kibana": {
        ...
        "username": "kibana"
    },
    "kibana_system": {
       ....
        "username": "kibana_system"
    },
    "logstash_system": {
        ....
        "username": "logstash_system"
    },
    "remote_monitoring_user": {
        ....
        "username": "remote_monitoring_user"
    }
}
Update password of build-in users

Changes the passwords of users in the native realm and built-in users.

curl -X POST -H "Content-Type: application/json" -d '{"password" : "changeme"}' http://elastic:changeme@localhost:9200/_security/user/kibana/_password 

curl -X POST -H "Content-Type: application/json" -d '{"password" : "changeme"}' http://elastic:changeme@localhost:9200/_security/user/kibana_system/_password 

用以上的範例,將kibanakibana_system的密碼設定為changeme

此時再用browser連到http://localhost:5601時就可看到要求輸入帳密的畫面,如下圖所示

Screen Shot 2022-05-09 at 16.22.24

Fleet Server

docker-compose.yml

  fleet-server:
    image: docker.elastic.co/beats/elastic-agent:${ELK_VERSION}
    container_name: fleet-server
    user: root
    environment:
      - FLEET_SERVER_ENABLE=1
      - FLEET_SERVER_ELASTICSEARCH_HOST=http://elasticsearch:9200
      - FLEET_SERVER_SERVICE_TOKEN= #must edit
      - FLEET_SERVER_POLICY_ID=fleet-server-policy
      - FLEET_SERVER_INSECURE_HTTP=true
    ports:
      - "8220:8220"
    networks:
      - tracing
    healthcheck:
      test: [ "CMD-SHELL", "curl -f http://127.0.0.1:8220/api/status | grep HEALTHY 2>&1 >/dev/null" ]
      interval: 5s
      timeout: 10s
      retries: 120
    depends_on:
      kibana:
        condition: service_healthy

這部份的FLEET_SERVER_SERVICE_TOKEN設定在稍後操作會產生,再回頭補上。

kibana

登入Kibana後可以在menu找到Fleet的選項

Screen Shot 2022-05-09 at 16.43.46

按下後就開啟了一連串的設定

1. Create policy

第一步是要建立Policy,按下畫面中的Create policy按鈕,這個操作需要等待一段時間。

Screen Shot 2022-05-09 at 16.45.44

完成後會提示已成功建立一個Policy

Screen Shot 2022-05-09 at 16.48.18

2. Create Fleet Sevrver Instance

這一步可以略過,主要是在docker-compose.yml裡已經產生了一個fleet server 的container等在那了。

Screen Shot 2022-05-09 at 16.49.12

3. Choose a deployment mode

在此使用簡易模式也就是不走https的方式連線

Screen Shot 2022-05-09 at 16.54.12

4. Add Fleet Server host

這個部份需要讓稍後新增的agent能連到fleet server,所以相關值要考慮在container裡的network。在這是用http://fleet-server:8220

Screen Shot 2022-05-09 at 16.56.03

此步驟可先至Settings裡設定,將Fleet server hosts 與Outpus的server加入

Screen Shot 2022-05-10 at 08.37.43

5. Generate a service token

Screen Shot 2022-05-10 at 00.54.51

將此token貼回docker-compose.yml裡的FLEET_SERVER_SERVICE_TOKEN

再重啟整個docker-compose即可。

登入kibana再去檢視fleet應該可以看到下列的畫面,已經有一個可用的Fleet Server連上了。

Screen Shot 2022-05-10 at 01.19.54

APM Agent

再來就是加入一個APM Agent,用以接受稍後的APM Log,並傳送到Elasticsearch。

docker-compose

  agent01:
    image: docker.elastic.co/beats/elastic-agent:${ELK_VERSION}
    container_name: agent01
    user: root
    environment:
      - FLEET_ENROLLMENT_TOKEN= #must edit
      - FLEET_ENROLL=1
      - FLEET_URL=http://fleet-server:8220
      - FLEET_INSECURE=true
    ports:
      - "8200:8200"
    networks:
      - tracing
    depends_on:
      fleet-server:
        condition: service_healthy

先將docker-compose內容準備好,稍後填入FLEET_ENROLLMENT_TOKEN即可運作

1. Add Elastic APM

在Menu中選取Integraton
Screen Shot 2022-05-10 at 01.27.16

再選取Elastic APM
Screen Shot 2022-05-10 at 01.27.34

2. Config APM Server

Elastic 8前的版本,的確有一個app名為APM Server,但在Elastic 8之後用Elastic Agent來取代,與Fleet Server用的是同樣的image,差別在於Fleet Server是執行為Server模式,而APM Server則僅單單做為Agent使用,這部份不要混淆。

按下APM Integration按鈕。

Screen Shot 2022-05-10 at 01.34.48

再按下Add Elastic APM

Screen Shot 2022-05-10 at 01.37.05

由於我使用了docker container的方式,務必要修改Host裡的值為0.0.0.0:8200,不然會收不到container外的資料

Screen Shot 2022-05-10 at 09.00.03

儲存按鈕在畫面的右下角,不要找不到了

Screen Shot 2022-05-10 at 01.41.33

再回去檢視APM的新增畫面,應該可以看到各項都準備完成。

Screen Shot 2022-05-10 at 01.44.05

3. Enrollment Token

再來要到Fleet的畫面取得Enrollment Token

Screen Shot 2022-05-10 at 01.48.04

將此token填回FLEET_ENROLLMENT_TOKEN中,重起container即可。再回到Fleet畫面就可以看到多了一個Agent

Screen Shot 2022-05-10 at 02.01.00

Java Agent Client

再來就是在我們要監控的程式裡加入javaagent的設定。

可以參考Kibana中的說明,先下載對應版本的jar,再加上參數。
Screen Shot 2022-05-10 at 02.05.43

若是使用idea的話,在Run/Debug Configuration裡設定即可,例如下列這樣。

Screen Shot 2022-05-10 at 02.07.41

再執行程式,回到kibana裡就能看到相關的APM資訊

例如下圖,可以分析程式在各個Service裡所使用的時間,以便找出可能的問題。

Screen Shot 2022-05-10 at 08.53.50

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料