說明
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的架構。
在Elastic 8.0版本,要使用APM integrations (Fleet) 的話,一定要將security選項開啟。
.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
用以上的範例,將kibana
與 kibana_system
的密碼設定為changeme
此時再用browser連到http://localhost:5601
時就可看到要求輸入帳密的畫面,如下圖所示
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的選項
按下後就開啟了一連串的設定
1. Create policy
第一步是要建立Policy,按下畫面中的Create policy
按鈕,這個操作需要等待一段時間。
完成後會提示已成功建立一個Policy
2. Create Fleet Sevrver Instance
這一步可以略過,主要是在docker-compose.yml裡已經產生了一個fleet server 的container等在那了。
3. Choose a deployment mode
在此使用簡易模式也就是不走https的方式連線
4. Add Fleet Server host
這個部份需要讓稍後新增的agent能連到fleet server,所以相關值要考慮在container裡的network。在這是用http://fleet-server:8220
此步驟可先至Settings裡設定,將Fleet server hosts 與Outpus的server加入
5. Generate a service token
將此token貼回docker-compose.yml裡的FLEET_SERVER_SERVICE_TOKEN
中
再重啟整個docker-compose即可。
登入kibana再去檢視fleet應該可以看到下列的畫面,已經有一個可用的Fleet Server連上了。
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
再選取Elastic APM
2. Config APM Server
Elastic 8前的版本,的確有一個app名為APM Server,但在Elastic 8之後用Elastic Agent來取代,與Fleet Server用的是同樣的image,差別在於Fleet Server是執行為Server模式,而APM Server則僅單單做為Agent使用,這部份不要混淆。
按下APM Integration按鈕。
再按下Add Elastic APM
由於我使用了docker container的方式,務必要修改Host裡的值為0.0.0.0:8200
,不然會收不到container外的資料
儲存按鈕在畫面的右下角,不要找不到了
再回去檢視APM的新增畫面,應該可以看到各項都準備完成。
3. Enrollment Token
再來要到Fleet的畫面取得Enrollment Token
將此token填回FLEET_ENROLLMENT_TOKEN
中,重起container即可。再回到Fleet畫面就可以看到多了一個Agent
Java Agent Client
再來就是在我們要監控的程式裡加入javaagent的設定。
可以參考Kibana中的說明,先下載對應版本的jar,再加上參數。
若是使用idea的話,在Run/Debug Configuration裡設定即可,例如下列這樣。
再執行程式,回到kibana裡就能看到相關的APM資訊
例如下圖,可以分析程式在各個Service裡所使用的時間,以便找出可能的問題。