
TĂ€napĂ€eval on vĂ”imatu ette kujutada Kubernetesel pĂ”hinevat projekti ilma ELK tech-stackita, millega salvestatakse logid nii rakendustest kui ka klastrikomponentide sĂŒsteemidest. Oma praktikas kasutame me EFK stacki, asendades Logstashiga Fluentdi.
Fluentd on kaasaegne universaalne logikogumise tööriist, mis muutub ĂŒha populaarsemaks ja on liitunud Cloud Native Computing Foundationiga, mistĂ”ttu on selle arenduse suund suunatud koostööle Kubernetesega.
Fakt, et kasutame Fluentdi Logstash'i asemel, ei muuda programmi kompleksiosaduse ĂŒldiselt, kuid Fluentdi'l on siiski omad spetsiifilised nĂŒansid, mis tulenevad tema mitmekesistest funktsioonidest.
NÀiteks, kui hakkasime EFK't kasutama suure koormusega projektis, kus logide kirjutamise intensiivsus on kÔrge, siis kohtasime Kibanas olukorda, kus mÔned sÔnumid kuvatakse mitu korda. KÀesolevas artiklis selgitame teile, miks see nÀhtus toimub ja kuidas probleemi lahendada.
Dokumentide dubleerimise probleem
Meie projektides on Fluentd kasutusel kui DaemonSet (automaatselt kĂ€ivitatakse igas sĂ”lmes Kubernetes klastris) ning jĂ€lgib konteinerite stdout logisid aadressil /var/log/containers. PĂ€rast kogumist ja töötlemist saadetakse logid JSON-dokumentidena ElasticSearch'i, mis on ĂŒles tĂ”stetud kas klastris vĂ”i iseseisvas reĆŸiimis, sĂ”ltuvalt projekti mahust ja toimivuse ja talitlushĂ€irete nĂ”uetest. Graafilise liidese jaoks kasutatakse Kibana't.
Fluentdi kasutamisel vÀljundpuffri plugiga seisime silmitsi olukorraga, kus mÔned dokumendid ElasticSearch'is sisaldavad tÀiesti sama sisu ja erinevad vaid identifikaatori poolest. Veenduda, et see on tÔepoolest sÔnumite duplikaat, saab Nginxi logi nÀitele toetudes. Logifailis esindab see sÔnum ennast ainus eksemplaris:
127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0" -Kuid ElasticSearch'is on mitu dokumenti, mis sisaldavad seda sÔnumit:
{
"_index": "test-custom-prod-example-2020.01.02",
"_type": "_doc",
"_id": "HgGl_nIBR8C-2_33RlQV",
"_version": 1,
"_score": 0,
"_source": {
"service": "test-custom-prod-example",
"container_name": "nginx",
"namespace": "test-prod",
"@timestamp": "2020-01-14T05:29:47.599052886 00:00",
"log": "127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0" -",
"tag": "custom-log"
}
}
{
"_index": "test-custom-prod-example-2020.01.02",
"_type": "_doc",
"_id": "IgGm_nIBR8C-2_33e2ST",
"_version": 1,
"_score": 0,
"_source": {
"service": "test-custom-prod-example",
"container_name": "nginx",
"namespace": "test-prod",
"@timestamp": "2020-01-14T05:29:47.599052886 00:00",
"log": "127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0" -",
"tag": "custom-log"
}
}Kuid kordusi vÔib olla rohkem kui kaks.
Fluentd logides selle probleemi fikseerimise ajal on palju jÀrgmise sisuga hoiatuseid:
2020-01-16 01:46:46 +0000 [warn]: [test-prod] failed to flush the buffer. retry_time=4 next_retry_seconds=2020-01-16 01:46:53 +0000 chunk="59c37fc3fb320608692c352802b973ce" error_class=Fluent::Plugin::ElasticsearchOutput::RecoverableRequestFailure error="could not push logs to Elasticsearch cluster ({:host="elasticsearch", :port=>9200, :scheme=>"http", :user=>"elastic", :password=>"obfuscated"}): read timeout reached"Need hoiatused tekivad siis, kui ElasticSearch ei suuda vastata pĂ€ringule seadistatud request_timeout aja jooksul, mistĂ”ttu edastatav puhvri fragment ei saa kustutada. PĂ€rast seda ĂŒritab Fluentd saata puhvri fragmendi ElasticSearchile uuesti ja pĂ€rast arbitraarset arvu katseid operation lĂ”puks Ă”nnestub:
2020-01-16 01:47:05 +0000 [warn]: [test-prod] retry succeeded. chunk_id="59c37fc3fb320608692c352802b973ce"
2020-01-16 01:47:05 +0000 [warn]: [test-prod] retry succeeded. chunk_id="59c37fad241ab300518b936e27200747"
2020-01-16 01:47:05 +0000 [warn]: [test-dev] retry succeeded. chunk_id="59c37fc11f7ab707ca5de72a88321cc2"
2020-01-16 01:47:05 +0000 [warn]: [test-dev] retry succeeded. chunk_id="59c37fb5adb70c06e649d8c108318c9b"
2020-01-16 01:47:15 +0000 [warn]: [kube-system] retry succeeded. chunk_id="59c37f63a9046e6dff7e9987729be66f"Siiski, ElasticSearch kÀsitleb iga edastatud puhvri fragmenti unikaalsena ja mÀÀrab neile unikaalsed _id vÀljad indekseerimise ajal. Niisiis tekivadki sÔnumite koopiad.
Kibanas nÀeb see vÀlja nii:

Probleemi lahendus
On olemas mitu vĂ”imalust selle probleemi lahendamiseks. Ăks neist on pluginasse fluent-plugin-elasticsearch integreeritud mehhanism, mis genereerib iga dokumendi jaoks unikaalse hash'i. Kui seda mehhanismi kasutada, tuvastab ElasticSearch dublikaadid edastamise etapis ja ei luba dokumentide dubleerimist. Kuid tuleb arvestada, et see probleemilahendus tegeleb sĂŒmptomite, mitte pĂ”hjuse, lahendamisega, mistĂ”ttu loobusime selle kasutamisest.
Kasutame Fluentd vĂ€ljundis puhverdamise plugina, et vĂ€ltida logide kadumist lĂŒhiajaliste vĂ”rguhĂ€irete vĂ”i suurenenud logimistintensiivsuse korral. Kui mingil pĂ”hjusel ei saa ElasticSearch dokumenti indeksi koheselt salvestada, satub dokument jĂ€rjekorda, mis salvestatakse kettale. SeetĂ”ttu tuleb meie olukorras selle probleemi pĂ”hjuse kĂ”rvaldamiseks mÀÀrata Ă”iged puhverdamise parameetrite vÀÀrtused, mille korral on Fluentd vĂ€ljundpuhver piisava suurusega ja suudab end samas ettenĂ€htud ajaks puhastada.
Tuleb mĂ€rkida, et allpool kĂ€sitletud parameetrite vÀÀrtused on iga konkreetse puhverdamise kasutusjuhtumi puhul individuaalsed, kuna need sĂ”ltuvad paljusid teguritest: teenuste logisĂ”numite salvestamise intensiivsusest, ketta sĂŒsteemi sooritusvĂ”imest, vĂ”rgu koormatusest ja selle lĂ€bilaskevĂ”imest. SeetĂ”ttu, et saada igale individuaalsele juhtumile sobivad, kuid mitte ĂŒlemÀÀrased puhverdusseaded, vĂ€ltides pikaajalist pimedat katsetamist, vĂ”ib kasutada silumisinfot, mida Fluentd töö kĂ€igus oma logisse kirjutab ja suhteliselt kiiresti Ă”igeid vÀÀrtusi saada.
Probleemi fikseerimise hetkel nÀgi konfiguratsioon vÀlja jÀrgmine:
<buffer>
@type file
path /var/log/fluentd-buffers/kubernetes.test.buffer
flush_mode interval
retry_type exponential_backoff
flush_thread_count 2
flush_interval 5s
retry_forever
retry_max_interval 30
chunk_limit_size 8M
queue_limit_length 8
overflow_action block
</buffer>Probleemi lahendamisel valiti kÀsitsi jÀrgmiste parameetrite vÀÀrtused:
chunk_limit_size â chunk'ide suurus, milleks jagatakse sĂ”numid puhveres.
- flush_interval â ajavahemik, mille jooksul puhastatakse puhver.
- queue_limit_length â maksimaalne chunkide arv jĂ€rjekorras.
- request_timeout â aeg, mille jooksul luuakse ĂŒhendus Fluentd ja ElasticSearch'i vahel.
Puhvri kogusuurus arvutatakse, korrutades queue_limit_length ja chunk_limit_size, mida vĂ”ib tĂ”lgendada kui "maksimaalne chunkide arv jĂ€rjekorras, igaĂŒhel on mÀÀratud maht". Kui puhversuure ei ole piisav, ilmub logides jĂ€rgmine hoiatus:
2020-01-21 10:22:57 +0000 [warn]: [test-prod] ei Ă”nnestunud kirjutada andmeid puhvri ĂŒlevoolu toimingu tĂ”ttu action=:blockSee tĂ€hendab, et puhver ei jĂ”ua ette nĂ€htud ajaks puhastuda ja andmed, mis tulevad tĂ€idetud puhvrisse, blokeeritakse, mis viib logide osa kadumiseni.
Puhvrit saab suurendada kahel viisil: suurendades kas iga chunk'i suurust jÀrjekorras vÔi chunkide arvu, mis vÔivad jÀrjekorras olla.
Kui chunk'i suurus chunk_limit_size on suurem kui 32 megabaiti, siis ElasticSearch ei aktsepteeri seda, kuna sissetulev pakett muutub liiga suureks. Seega, kui on vajalik puhvrimahu veelgi suurendamine, on parem suurendada maksimaalset jÀrjekorra pikkust queue_limit_length.
Kui puhver ei hakka enam ĂŒlevoolama ja alles jÀÀb ainult teade ajakuupĂ€eva puudumisest, vĂ”ib alustada request_timeout parameetri suurendamist. Kuid kui seatakse vÀÀrtus suurem kui 20 sekundit, hakkavad Fluentd logides ilmuma jĂ€rgmised hoiatused:
2020-01-21 09:55:33 +0000 [warn]: [test-dev] puhvri puhastamine vĂ”ttis rohkem aega kui slow_flush_log_threshold: elapsed_time=20.85753920301795 slow_flush_log_threshold=20.0 plugin_id="postgresql-dev" See sĂ”num ei mĂ”juta sĂŒsteemi tööd ja tĂ€hendab, et puhvri puhastamine kestis kauem, kui slow_flush_log_threshold parameetriga on seadistatud. See on silumisinfo ja me kasutame seda request_timeout parameetri vÀÀrtuse valimisel.
Ăldine algoritm vÀÀrtuse valimiseks nĂ€eb vĂ€lja jĂ€rgmine:
- Seada request_timeout vÀÀrtus garantii alusel oluliselt suuremaks, kui vajalik (sajad sekundi). Seadistamise ajal on peamine kriteerium selle parameetri Ôige seadistamise osas hoiatused ajakuupÀeva puudumisest.
- Oodata sĂ”numeid, mis ĂŒletavad slow_flush_log_threshold piiri. Hoiatuses olevas lĂ”igus elapsed_time on kirjas tegelik puhvri puhastamise aeg.
- Seada request_timeout vÀÀrtus peab olema suurem kui maksimaalne elapsed_time vÀÀrtus, mis on saadud jÀlgimisperioodi jooksul. Me arvutame request_timeout vÀÀrtuse kui elapsed_time + 50%.
- Omandamaks logi teateid pika puhastusprotsessi kohta, saab suurendada slow_flush_log_threshold vÀÀrtust. Me arvutame selle vÀÀrtuse kui elapsed_time + 25%.
Nende parameetrite lĂ”ppvÀÀrtused, nagu eelnevalt mĂ€rgitud, on iga juhtumi jaoks individuaalsed. JĂ€rgides ĂŒlaltoodud algoritmi, saame kindlasti kĂ”rvaldada vea, mis pĂ”hjustab teatiste kordumist.
Allolevas tabelis on nĂ€idatud kuidas veade koguarv muutub pĂ€eva jooksul, mis pĂ”hjustab teatiste dubleerimist, kui mÀÀrata ĂŒlaltoodud parameetrite vÀÀrtuseid:
node-1
node-2
node-3
node-4
Enne/PĂ€rast
Enne/PĂ€rast
Enne/PĂ€rast
Enne/PĂ€rast
puudus puhastamine puhvrist
1749/2
694/2
47/0
1121/2
kordus Ônnestus
410/2
205/1
24/0
241/2
Tuleb tĂ€iendavalt mĂ€rkida, et saadud seaded vĂ”ivad projektide kasvu kĂ€igus kaotada oma asjakohasuse ja seega logide arvu suurenemise tĂ”ttu. Peamine mĂ€rk puuduvast seadistatud ajaĂŒlesandest on Fluentd logisse naasmine pika puhastamise teated, see tĂ€hendab ĂŒletamine slow_flush_log_threshold piiri. Sellest hetkest on veel vĂ€ike varu enne request_timeout piiri ĂŒletamist, seega on oluline reageerida nendele teadetele Ă”igeaegselt ja uuesti lĂ€bi viia optimaalse seadistamise protsess, nagu eelnevalt kirjeldatud.
KokkuvÔte
Fluentd vĂ€ljundpuhvri peenhÀÀlestamine on ĂŒks peamisi etappe EFK silmuste seadistamisel, mis mÀÀrab kindlaks selle stabiilsuse ja dokumentide korrektse paigutamise indeksitesse. JĂ€rgides kirjeldatud seadistamise algoritmi, vĂ”ib olla kindel, et kĂ”ik logid salvestatakse ElasticSearch indeksisse Ă”iges jĂ€rjekorras, ilma kordusteta ja kaotusteta.
Vaata ka teisi artikleid meie blogis:
Allikas: habr.com
