Jaynarol Blog

Docker : เข้าใจและจัดการ Logs ด้วย Syslog

สวัสดีครับ ในทุกระบบการดูแลรักษาระยะยาวสิ่งที่ขาดไม่ได้เลยก็คือ Logs ที่ช่วยให้เราสามารถวิเคราะห์การใช้งาน ปัญหา สุขภาพ และข้อมูลสำคัญที่ระบบแจ้ง เพื่อนำไปปรับแต่งแก้ไขให้เข้าที่และตรงกับการใช้งานมากที่สุด ใน Docker เองก็มีเครื่องมือที่ช่วยอำนายความสะดวกเกี่ยวกับ Logs มาให้อยู่แล้ว ซึ่งบทความนี้ผมยกมาแค่ Driver Syslog ตัวเดียวเพราะหลักการทำงานมันคล้ายกันมาก ถ้าเข้าใจตัวนี้ตัวอื่นก็ไม่ยากเลยครับ

 

การจัดการ Logs ใน Docker

โดยปกติ Docker จะใช้ Json Driver ในการบันทึก Logs ให้กับทุก Container โดยอัตโนมัติ โดยเราสามารถตรวจสอบ Logs ของแต่ละ Container แบบ Realtime ได้ด้วยคำสั่ง docker logs -f (container name|id) ซึ่ง Docker จะแสดง Logs ของ Container นั้นๆมาบน Console และอัพเดทให้ตลอดโดยอัตโนมัติ หรือหากเราใช้ Docker-Compose เราสามารถใช้สำสั่ง docker-compose logs -f เพื่อแสดง Logs ของทุก Container พร้อมกันทั้งหมด

 

แต่หากเราอยากดูข้อมูลย้อนหลังละ (Json Driver)? ก็สามารถทำได้เช่นกันครับ แต่ก่อนอื่นเราต้องหา location ที่ Container ใช้จัดเก็บ Logs ของเราก่อน ด้วยคำสั่ง docker inspect (container name|id) | grep LogPath จากนั้นเราจะได้ข้อมูลเป็น path ของ Logs มา แน่นอนว่าเราสามารถเปิดอ่านเลยหรือ copy ไปเก็บไว้ได้ตามอัธยาศัยครับ

 

ใช้ Syslog Driver แทน Json

การใช้ Json Driver ที่ติดมาโดยอัตโนมัติกับ Container ดูสะดวกสบายเพราะสามารถเรียกดู Logs แบบ Realtime ได้ ซึ่งเอาเข้าจริงๆมันเหมาะกับงาน Dev และ Debug เท่านั้น เพราะบน Production เราไม่ได้มานั่งดูตลอดแน่ๆ ที่เราต้องการจริงๆคือการจัดเก็บ Logs ที่ดีและเป็นระบบเพื่อสามารถตรวจสอบย้อนหลังได้ตลอดเวลาที่ต้องการ และ Syslog Driver จะเป็นพระเอกของเราในบทความนี้ครับ (เดี๋ยวมีบททความอื่นมีพระเอกตัวอื่นอีก อิอิ)

การใช้ Syslog Driver มีข้อดีคือ

  • เลือก Location ในการจัดเก็บ Logs เองได้
  • รวม Logs จากทุก Container ไว้ในไฟล์เดียวได้ (หรือจะแยกก็ได้)
  • Logs ยังอยู่แม้ว่า Container ถูกลบ (ถ้าเป็น Json Driver ลบ Container = Logs หายเกลี้ยงนะครับ)
  • ระบบ Logs เป็น Micro Service เราจะแยก Server ออกไปต่างหากหรือไม่ก็ได้ (บทความนี้ผมจะเอาไว้ให้อยู่ในระบบเดียวกัน)
  • นำ Logs ไปจัดการต่อหรือจัดเก็บอย่างเป็นระบบได้

แต่ Syslog Driver ก็มีข้อจำกัดเช่นกัน ได้แก่

  • เราจะไม่สามารถดู Logs แบบ Realtime ด้วยคำสั่ง docker logs กับ Container ที่ใช้ Syslog ได้อีกต่อไป (แต่ใช้เทคนิคอื่นแทนได้ 😉 )
  • ส่วนใหญ่มักจะให้ข้อมูล Logs วิ่งบน Protocol UDP ซึ่งเร็วแต่ไม่รับประกันอะไรเลย ทำให้มีโอกาส(น้อยมากๆ) ที่ Logs จะปลิวหายไประหว่างทาง

 

ลองเล่นกัน

 

ติดตั้ง

ความรู้เกิดจากการอ่าน แต่ทักษะเกิดจากการลงมือ ดังนั้นเรามาเล่นกันเลยดีกว่า ก่อนอื่น clone project ต้นแบบของผมลงมาก่อนครับ

 

จากนั้นสั่งรันระบบที่ Pack มาอย่างดีด้วย Docker-Compose ได้เลย ด้วยคำสั่ง

หลังกด enter เสร็จก็รอมันทำงานสักพักจนขึ้นหน้าแบบนี้ครับ

 

ทดสอบ

เปิด Browser ด้วย IP ของ Docker ได้เลยครับ (ใครไม่ทราบ IP ของ Docker ให้ใช้คำสั่ง docker-machine ip ครับ) เช่นของผม http://192.168.99.100 จะแสดงข้อมูลว่า “Server 1” จากนั้นลองเปิดอีก URL ครับ http://192.168.99.100/2 จะแสดงข้อมูลว่า “Server 2” ดังภาพ

ที่เราสามารถแสดงผลได้แบบนี้เพราะระบบเรามี Container Nginx ทำงานอยู่ 2 ตัวครับ แต่บทความนี้เราไม่ได้สนใจที่ Nginx ครับ แต่เราจะ Focus ที่ไฟล์ ~/my-docker-syslog/logs/messages เพราะ Logs จากทั้ง 2 Container จะวิ่งมาบันทึกไว้ที่ไฟล์นี้ และการดู Logs แบบ Realtime เราจะเปลี่ยนมาใช้คำสั่งนี้แทนครับ

 

จากนั้นกด Refresh F5 ทั้ง 2 เว็บที่เปิดไปสักครู่รัวๆ เพื่อดูผลการทำงานของ Logs

จะสังเกตได้ว่ามีข้อมูลวิ่งเข้ามาจัดเก็บบนไฟล์ logs/messages ของเราจาก 2 แหล่งได้แก่ docker/nginx1 และ docker/nginx2 ซึ่งมาจาก Container Nginx ทั้ง 2 ตัวของเรานั่นเองครับ เป็นอันเรียบร้อยใช้งานได้ตามเป้าหมาย

เมื่อเราเล่นจนพอใจแล้ว เราสามารถออกจากหน้าแสดง Logs ด้วยการกด “CTRL + C” และลบทำความสะอาด Container ทั้งหมดด้วยคำสั่ง docker-compose down ครับ

 

ทำความเข้าใจ

docker-syslog-dg

 

ระบบนี้จัดการด้วย Docker Compose มี Container ทั้งหมด 4 ตัว ได้แก่

  • Load Balance สำหรับกระจายงานไปตาม URI ที่กำหนด (ไม่ใช่จุดสำคัญของบทความนี้)
  • Syslog สำหรับรับ Logs จาก Container อื่นๆ เพื่อบันทึกลงไฟล์ตามที่ตั้งค่าไว้ (logs/messages) ซึ่ง Syslog จะเปิด Port udp://127.0.0.1:514 เพื่อรอการติดต่อมาจาก Container ตัวอื่น สาเหตุที่เราต้องเชื่อมต่อโดยวิ่งออกไปนอก Docker และวิ่งกลับเข้ามาใหม่เนื่องจากการตั้งค่า Logs Driver ใน Docker ไม่สามารถ Link ด้วยชื่อ Container ได้ รายละเอียด (เรื่องนี้ทำเอาผมเสียเวลาหาข้อมูลพักใหญ่เหมือนกัน) และนอกจากนี้ Syslog Container ยังทำ Volume โฟลเดอร์ที่เก็บ Logs ไว้ด้วยเพื่อป้องกันไม่ให้ข้อมูลหายไปแม้ Container จะถูกลบไปแล้ว ซึ่งในไฟล์ Docker Compose จะมี Config ดังนี้
 

  • Nginx 1 และ 2 สำหรับทำงานเพื่อส่ง Logs ไปให้ Syslog Container โดยจะมีการ Config พิเศษเพิ่มขึ้นมาคือ logging ระบุ Driver เป็น syslog แทนของเดิมที่เป็น json รวมไปถึงกำหนด address ปลายทางซึ่งก็คือที่เดียวกับ Syslog Container และสุดท้ายกำหนด Tag เพื่อให้เราทราบว่า Logs มาจาก Container ตัวไหน ดังนี้
 

อธิบายการทำงานแบบคร่าวๆอีกที คือเมื่อผู้ใช้งานเรียกเว็บผ่าน Browser และ Nginx เริ่มทำงาน แน่นอนว่าจะต้องเกิด Logs ขึ้นมา โดย Nginx จะส่งต่อ Logs นั้นไปที่ udp://127.0.0.1:514 ซึ่งมี Syslog Container รอรับอยู่ เมื่อมันได้รับ Logs ก็จะเขียนลงไฟล์ logs/messages ทันทีนั่นเองครับ และเราเองก็สามารถเรียกดูไฟล์ logs/messages แบบ Realtime ด้วยคำสั่ง tail -f logs/messages นั่นเอง

 

ปิดท้าย

เรื่องของ Logs เป็นเรื่องที่มีความละเอียดอ่อน มันจะเป็นข้อมูลที่มีคุณค่าหรือขยะก็ขึ้นอยู่กับวิธีที่เราใช้จัดการมัน และแน่นอนว่าเมื่อมันอยู่บน Docker ก็ยิ่งสนุกขึ้นไปอีก เพราะเราสามารถควบคุมและจัดการ “มันทั้งหมด” ได้อย่างใจนึก

ยังมีอีกหลายเรื่องเกี่ยวกับ Logs ที่เรายังไม่ได้พูดถึง ไม่ว่าจะเป็น log rotation ซึ่งแน่นอนว่าจะโยงไปถึง cronjob ด้วย และเทคนิคการจัดเก็บ logs ที่ง่ายกว่านี้เป็นต้น ไว้ผมจะค่อยๆทะยอยลงให้ครับ

ไว้เจอกันใหม่บทความหน้าครับ 🙂