โพสต์นี้ร่วมเขียนโดย Hart Hoover และ Ryan Walker
เมื่อเร็ว ๆ นี้ทีม Rackspace DevOps Automation ได้ประกาศบริการที่ส่งการแจ้งเตือนจาก New Relic ไปยังการสนับสนุน Rackspace การแจ้งเตือนเหล่านี้จะสร้างตั๋วสำหรับวิศวกร DevOps ของเราเพื่อตอบกลับ เพื่อให้ลูกค้าของเรานอนหลับได้อย่างสบายเมื่อมีการสร้างการแจ้งเตือนตอนตี 3 เมื่อรวมกับจุดข้อมูลอื่นๆ ที่รวบรวมเกี่ยวกับสภาพแวดล้อมของลูกค้า วิศวกรของเราจะระบุว่าปัญหาอยู่ที่ใด จากนั้นจึงดำเนินการตามแนวทางปฏิบัติที่เหมาะสม
ขณะออกแบบโครงสร้างพื้นฐานสำหรับบริการนี้ เราพบปัญหาทั่วไป แต่น่าสนใจที่เราจำเป็นต้องจำกัดการเข้าถึงระบบภายในของ Rackspace เพื่อความปลอดภัยในขณะที่ยังคงรักษาปลายทางสาธารณะที่ New Relic สามารถพูดคุยด้วยได้ โซลูชันของเราคือการออกแบบบริการด้วยจุดปลาย API สาธารณะและพนักงานส่วนตัวที่แยกจากกันโดยสิ้นเชิง ตำแหน่งข้อมูล API สาธารณะได้รับการแจ้งเตือนจาก New Relic และส่งผ่านไปยังอินสแตนซ์ ObjectRocket Redis ซึ่งทำหน้าที่เป็นคิว บริการของผู้ปฏิบัติงานทำงานภายในหลังไฟร์วอลล์ RackConnect และดึงข้อความจากคิวและสร้างการแจ้งเตือน
สิ่งนี้แบ่งพาร์ติชันสภาพแวดล้อมได้ดีมาก แต่สร้างปัญหาให้เราเกี่ยวกับการรวมบันทึก เราเรียกใช้สแต็ก ElasticSearch/Kibana ภายในสภาพแวดล้อมส่วนตัวของเรา เบื้องหลังไฟร์วอลล์ เราใช้ความชำนาญในการส่งบันทึกไปยัง ElasticSearch โดยตรง ภายนอกไฟร์วอลล์ ไม่สามารถเข้าถึง EK stack ได้ เพื่อแก้ปัญหานี้ เราเริ่มใช้ความชำนาญในการส่งบันทึกจากบริการ API สาธารณะของเราไปยังอินสแตนซ์ ObjectRocket MongoDB ภายในเราใช้ คล่องแคล่ว อีกครั้งเพื่อดึงบันทึกจาก ObjectRocket ไปยัง ElasticSearch สิ่งนี้ทำให้เรามีจุดหมายเดียวสำหรับกิจกรรมด้านสิ่งแวดล้อมทั้งหมดของเรา
Fluentd คืออะไร
Fluentd เป็นตัวรวบรวมข้อมูลโอเพ่นซอร์สที่พยายามจัดโครงสร้างข้อมูลเป็น JSON ให้ได้มากที่สุด ซึ่งหมายความว่าคุณไม่จำเป็นต้องเขียนและดูแลสคริปต์จำนวนมากเพื่อรับข้อมูลการบันทึกในรูปแบบที่คล้ายคลึงกัน มันคือ JSON ทั้งหมด
พลังของความคล่องแคล่วอยู่ในการสนับสนุนแหล่งที่มาและปลายทางหลายแห่ง ตัวอย่างเช่น คุณสามารถรวบรวมข้อมูลจากสตรีม Twitter และแจ้งให้คุณทราบใน IRC มีปลั๊กอินชุมชนมากมาย
การใช้ Fluentd กับ Docker
ด้วยการใช้ปลั๊กอิน MongoDB ที่คล่องแคล่ว เราสามารถผลักบันทึกลงใน ObjectRocket ได้อย่างง่ายดาย ขั้นแรกต้องกำหนดแหล่งที่มา เนื่องจากบริการทั้งหมดของเราใช้ Docker เราจึงต้องทำให้บันทึกคอนเทนเนอร์ของเรามีความคล่องแคล่ว มีโพสต์ที่ยอดเยี่ยมที่ช่วยเติมเต็มสิ่งนี้เกี่ยวกับวิธีการรวมบันทึกให้สำเร็จด้วย docker-gen และ Jason Wilder คล่องแคล่วที่นี่ เมื่อคอนเทนเนอร์ที่คล่องแคล่วกำลังทำงาน (และ docker-gen ได้สร้างการกำหนดค่าที่คล่องแคล่ว) คุณควรมีส่วนเช่นนี้สำหรับคอนเทนเนอร์ที่ทำงานอยู่แต่ละอัน:
<source>
type tail
format json
time_key time
path /var/lib/docker/containers/abcdef/abcdef-json.log
pos_file /var/lib/docker/containers/abcdef/abcdef-json.log.pos
tag docker.container.abcdef
rotate_wait 5
</source>
นี่เป็นส่วนท้ายของบันทึกคอนเทนเนอร์ และติดตามตำแหน่งที่อยู่ในบันทึกด้วยไฟล์ตำแหน่ง สิ่งสำคัญคือต้องสังเกตว่าแท็กที่แสดงในส่วนการกำหนดค่านี้เป็นแท็กที่คล่องแคล่ว ซึ่งใช้เพื่อบอกว่าต้องทำอย่างไรกับข้อมูลที่รวบรวมมาอย่างคล่องแคล่ว
การใช้ Fluentd กับ MongoDB
ในด้านสาธารณะ เราบอกได้อย่างคล่องแคล่วว่าจะทำอย่างไรกับข้อมูลด้วย "การจับคู่" ในกรณีนี้ ให้แทนที่ตัวแปรด้วยข้อมูลจริงจากฐานข้อมูล ObjectRocket ของคุณในไฟล์การกำหนดค่าเดียวกัน:
<match docker.**>
type mongo
database $DBNAME
collection prod
host $HOSTNAME
port $PORT
ssl
capped
capped_size 100m
user $MONGOUSER
password $MONGOPASS
include_tag_key true
</match>
การตั้งค่า include_tag_key บอกให้คล่องแคล่วรวมแท็กในบันทึกสำหรับบันทึกใน MongoDB วิธีนี้ทำให้เราทราบได้อย่างชัดเจนว่ารายการบันทึกใดเป็นของคอนเทนเนอร์ใด Fluentd จะเริ่มเติม MongoDB ด้วยข้อมูล ซึ่งเราสามารถดึงลงมาที่ด้านส่วนตัวของแอปพลิเคชันของเราได้
ในด้านส่วนตัว เรายังคงใช้ปลั๊กอิน MongoDB ที่คล่องแคล่ว แต่คราวนี้ตั้งเป็นแหล่งที่มา:
<source>
type mongo_tail
database $DBNAME
collection prod
host $HOSTNAME
port $PORT
user $MONGOUSER
password $MONGOPASS
ssl
time_key time
wait_time 5
tag prod
id_store_file /app/prod_last_id
</source>
จากนั้น เราจัดเตรียม "การจับคู่" สำหรับบันทึกของเราเพื่อส่งไปยัง ElasticSearch:
<match **>
type forest
subtype elasticsearch
<template>
host elasticsearch.domain.com
port 9200
index_name fluentd
logstash_format true
buffer_type memory
type_name ${tag}
flush_interval 3
retry_limit 17
retry_wait 1.0
num_threads 1
</template>
</match>
เรายังใช้ปลั๊กอินฟอเรสต์ที่คล่องแคล่วซึ่งทำให้การกำหนดค่าการแท็กของเราง่ายขึ้นในหลายสภาพแวดล้อม
Fluentd เป็นวิธีที่ยอดเยี่ยมในการรวมบันทึก Docker ของคุณในหลายโฮสต์และพุชไปยังฐานข้อมูล MongoDB ในกรณีของเรา ObjectRocket เป็นช่องทางระหว่างสภาพแวดล้อมสาธารณะและส่วนตัวของเราสำหรับการรวมบันทึก กรณีการใช้งานอื่นๆ อาจรวมถึงการวิเคราะห์แบบเรียลไทม์เกี่ยวกับข้อมูลที่คุณกำลังรวบรวม ส่วนที่ดีที่สุดสำหรับทีมของเราคือเราไม่ต้องจัดการ MongoDB ด้วยความน่าเชื่อถือและความรู้ของ ObjectRocket