Foundations of Application Security (พื้นฐานของ Application Security)
เอาล่ะ ตอนนี้ เรามีหลักการพื้นฐานและมีความเข้าใจในระดับหนึ่งเกี่ยวกับขอบเขตกว้างๆ ที่กิจกรรมด้าน security ครอบคลุมแล้ว ลองมาดูหัวข้อพื้นฐานด้าน security บางส่วนในบริบทของสถาปัตยกรรม microservice กันบ้าง หากคุณต้องการสร้างระบบที่ปลอดภัยยิ่งขึ้น—credentials, การ patch, backup และการ rebuild
Credentials (ข้อมูลรับรองตัวตน)
โดยกว้างๆ แล้ว credentials คือสิ่งที่ให้บุคคล (หรือคอมพิวเตอร์) เข้าถึงทรัพยากรที่ถูกจำกัดบางรูปแบบได้ อาจเป็นฐานข้อมูล คอมพิวเตอร์ บัญชีผู้ใช้ หรืออย่างอื่น ในสถาปัตยกรรม microservice เมื่อเทียบกับสถาปัตยกรรม monolithic ที่เทียบเท่ากัน เรามีแนวโน้มที่จะมีจำนวนมนุษย์ที่เกี่ยวข้องเท่าเดิม แต่เรามี credential มากขึ้น อย่างมากในระบบ ที่แทน microservice, (virtual) machine, ฐานข้อมูล และอื่นๆ ที่แตกต่างกัน สิ่งนี้อาจนำไปสู่ความสับสนในระดับหนึ่งเกี่ยวกับวิธีจำกัด (หรือไม่จำกัด) การเข้าถึง และในหลายกรณีอาจนำไปสู่แนวทางแบบ “ขี้เกียจ” ที่ใช้ credential จำนวนน้อยที่มีสิทธิ์กว้างเพื่อพยายามทำให้เรื่องต่างๆ ง่ายขึ้น ซึ่งในทางกลับกันอาจนำไปสู่ปัญหามากขึ้นหาก credential เหล่านั้นถูกขโมยไป
เราสามารถแบ่งหัวข้อเรื่อง credentials ออกเป็นสองส่วนหลักได้ ประการแรกคือ credential ของผู้ใช้ (และผู้ดูแลระบบ) ของระบบเรา ซึ่งมักเป็นจุดที่อ่อนแอที่สุดของระบบเรา และมักถูกใช้เป็นช่องทางโจมตีโดยฝ่ายไม่หวังดี อย่างที่เราจะเห็นในอีกไม่ช้า ประการที่สอง เราสามารถพิจารณา secret—ข้อมูลสำคัญที่จำเป็นต่อการรัน microservice ของเรา ทั้งสองชุดของ credential เราจำเป็นต้องพิจารณาประเด็นเรื่องการหมุนเวียน (rotation) การเพิกถอน (revocation) และการจำกัดขอบเขต (limiting scope)
User credentials (Credentials ของผู้ใช้)
Credential ของผู้ใช้ เช่น การรวมกันของอีเมลและรหัสผ่าน ยังคงเป็นสิ่งจำเป็นต่อการทำงานของเราหลายๆ คนกับซอฟต์แวร์ แต่ก็เป็นจุดอ่อนที่อาจถูกฝ่ายไม่หวังดีเข้าถึงระบบของเราได้ด้วยเช่นกัน รายงาน 2020 Data Breach Investigations Report ของ Verizon พบว่าการขโมย credential ในรูปแบบใดรูปแบบหนึ่งถูกใช้ใน 80% ของกรณีที่เกิดจากการแฮ็ก ซึ่งรวมถึงสถานการณ์ที่ credential ถูกขโมยผ่านกลไกอย่าง phishing หรือการสุ่มเดารหัสผ่าน (brute-force)
มีคำแนะนำดีๆ มากมายเกี่ยวกับวิธีจัดการเรื่องต่างๆ อย่างรหัสผ่านอย่างเหมาะสม—คำแนะนำที่แม้จะเรียบง่ายและชัดเจนในการปฏิบัติตาม แต่ก็ยังไม่ถูกนำไปใช้อย่างแพร่หลายพอ Troy Hunt มีบทความภาพรวมที่ยอดเยี่ยมเกี่ยวกับคำแนะนำล่าสุดจากทั้ง NIST และ UK’s National Cyber Security Centre 6 คำแนะนำนี้รวมถึงการแนะนำให้ใช้ password manager และรหัสผ่านที่ยาว หลีกเลี่ยงกฎรหัสผ่านที่ซับซ้อน และ—ที่น่าแปลกใจ—หลีกเลี่ยงการบังคับเปลี่ยนรหัสผ่านเป็นประจำ บทความฉบับเต็มของ Troy คุ้มค่าแก่การอ่านอย่างละเอียด
ในยุคของระบบที่ขับเคลื่อนด้วย API ในปัจจุบัน credential ของเรายังขยายไปถึงการจัดการสิ่งต่างๆ อย่าง API key สำหรับระบบของบุคคลที่สาม เช่น บัญชีของ public cloud provider ของคุณ หากฝ่ายไม่หวังดีเข้าถึงบัญชี root AWS ของคุณได้ ยกตัวอย่างเช่น พวกเขาอาจตัดสินใจทำลายทุกอย่างที่รันอยู่ในบัญชีนั้น ในตัวอย่างสุดโต่งกรณีหนึ่ง การโจมตีลักษณะนี้ส่งผลให้บริษัทชื่อ Code Spaces 7 ต้องปิดกิจการ—ทรัพยากรทั้งหมดของพวกเขารันอยู่ในบัญชีเดียว รวมถึง backup ด้วย ความย้อนแย้งที่ Code Spaces เสนอบริการ “Rock Solid, Secure and Affordable Svn Hosting, Git Hosting and Project Management” นั้นผมสังเกตเห็นเป็นอย่างดี
แม้ว่าใครสักคนจะได้ API key สำหรับ cloud provider ของคุณไป และไม่ได้ตัดสินใจทำลายทุกอย่างที่คุณสร้างขึ้นมา พวกเขาก็อาจตัดสินใจสร้าง virtual machine ราคาแพงขึ้นมาเพื่อทำ bitcoin mining โดยหวังว่าคุณจะไม่สังเกตเห็น เรื่องนี้เกิดขึ้นกับลูกค้าคนหนึ่งของผม ซึ่งพบว่ามีคนใช้เงินไปกว่า $10K ทำแบบนี้ก่อนที่บัญชีจะถูกปิด ปรากฏว่าผู้โจมตีก็รู้จักการทำ automation เช่นกัน—มีบอทที่คอยสแกนหา credential และพยายามใช้มันเพื่อรัน machine สำหรับทำ cryptocurrency mining
Secrets (ความลับ)
โดยกว้างๆ แล้ว secret คือข้อมูลสำคัญที่ microservice จำเป็นต้องใช้ในการทำงาน และมีความอ่อนไหวมากพอที่จำเป็นต้องได้รับการปกป้องจากฝ่ายไม่หวังดี ตัวอย่างของ secret ที่ microservice อาจต้องการ ได้แก่:
-
ใบรับรอง (certificate) สำหรับ TLS
-
SSH key
-
Public/private API keypair
-
Credentials สำหรับเข้าถึงฐานข้อมูล
ถ้า เราพิจารณา life cycle ของ secret เราจะเริ่มแยกแยะแง่มุมต่างๆ ของ secrets management ที่อาจต้องการความปลอดภัยที่แตกต่างกันออกไปได้:
Creation (การสร้าง)
เราสร้าง secret ขึ้นมาตั้งแต่แรกได้อย่างไร?
Distribution (การกระจาย)
เมื่อ secret ถูกสร้างขึ้นแล้ว เราจะมั่นใจได้อย่างไรว่ามันไปถึงที่ที่ถูกต้อง (และเฉพาะที่ที่ถูกต้องเท่านั้น)?
Storage (การจัดเก็บ)
Secret ถูกจัดเก็บในรูปแบบที่มั่นใจได้ว่ามีเพียงฝ่ายที่ได้รับอนุญาตเท่านั้นที่เข้าถึงได้หรือไม่?
Monitoring (การเฝ้าติดตาม)
เรารู้หรือไม่ว่า secret นี้ถูกใช้งานอย่างไร?
Rotation (การหมุนเวียน)
เราสามารถเปลี่ยน secret ได้โดยไม่ก่อให้เกิดปัญหาหรือไม่?
ถ้า เรามี microservice หลายตัว ซึ่งแต่ละตัวอาจต้องการ secret ชุดที่แตกต่างกัน เราก็จำเป็นต้องใช้ tooling เพื่อช่วยจัดการทั้งหมดนี้
Kubernetes มี secrets solution ในตัว แม้จะมีความสามารถค่อนข้างจำกัด แต่ก็มาพร้อมกับการติดตั้ง Kubernetes พื้นฐาน ดังนั้นจึงอาจเพียงพอสำหรับหลายกรณีการใช้งาน 8
ถ้า คุณกำลังมองหาเครื่องมือที่ซับซ้อนกว่าในพื้นที่นี้ Hashicorp’s Vault ก็คุ้มค่าแก่การพิจารณา เป็นเครื่องมือ open source ที่มีตัวเลือกเชิงพาณิชย์ด้วย มันเป็นเสมือนมีดพับสวิสของ secrets management ที่จัดการได้ทุกอย่างตั้งแต่แง่มุมพื้นฐานของการกระจาย secret ไปจนถึงการสร้าง credential แบบมีเวลาจำกัดสำหรับฐานข้อมูลและ cloud platform Vault ยังมีข้อดีเพิ่มเติมตรงที่เครื่องมือสนับสนุนอย่าง consul-template สามารถอัปเดต secret แบบไดนามิกในไฟล์ configuration ปกติได้ ซึ่งหมายความว่าส่วนต่างๆ ของระบบคุณที่ต้องการอ่าน secret จาก local filesystem ไม่จำเป็นต้องเปลี่ยนแปลงเพื่อรองรับ secrets management tool เมื่อ secret ถูกเปลี่ยนใน Vault consul-template จะสามารถอัปเดต entry นี้ในไฟล์ configuration ทำให้ microservice ของคุณสามารถเปลี่ยน secret ที่ใช้ได้แบบไดนามิก นี่ยอดเยี่ยมมากสำหรับการจัดการ credential ในระดับใหญ่
บาง public cloud provider ก็มีโซลูชันในพื้นที่นี้ให้ด้วยเช่นกัน ตัวอย่างเช่น AWS Secrets Manager หรือ Azure’s Key Vault บางคนไม่ชอบแนวคิดการเก็บข้อมูล secret สำคัญไว้ใน public cloud service แบบนี้ แต่ก็ขึ้นอยู่กับ threat model ของคุณอีกครั้ง หากเป็นเรื่องที่น่ากังวลจริงจัง ก็ไม่มีอะไรมาห้ามคุณรัน Vault บน public cloud provider ที่คุณเลือกได้ และจัดการระบบนั้นด้วยตัวเอง แม้ว่าข้อมูล at rest จะถูกเก็บไว้บน cloud provider แต่ด้วย storage backend ที่เหมาะสม คุณสามารถมั่นใจได้ว่าข้อมูลถูกเข้ารหัสในลักษณะที่แม้ว่าฝ่ายภายนอกจะได้ข้อมูลไป ก็ไม่สามารถทำอะไรกับมันได้เลย
Rotation (การหมุนเวียน Credentials)
ตามหลักการแล้ว เรา ต้องการหมุนเวียน credential บ่อยๆ เพื่อจำกัดความเสียหายที่ใครบางคนอาจทำได้หากเข้าถึง credential นั้นได้ หากฝ่ายไม่หวังดีเข้าถึง AWS API public/private keypair ของคุณได้ แต่ credential นั้นถูกเปลี่ยนทุกสัปดาห์ พวกเขาก็มีเวลาแค่หนึ่งสัปดาห์ในการใช้ประโยชน์จาก credential นั้น แน่นอนว่าพวกเขายังสามารถสร้างความเสียหายได้มากในหนึ่งสัปดาห์ แต่คุณคงเข้าใจแนวคิด ผู้โจมตีบางประเภทชอบเข้าถึงระบบแล้วซ่อนตัวอยู่โดยไม่ถูกตรวจพบ เพื่อให้พวกเขาสามารถเก็บรวบรวมข้อมูลที่มีค่าเพิ่มขึ้นเรื่อยๆ และหาทางเข้าไปยังส่วนอื่นๆ ของระบบของคุณ หากพวกเขาใช้ credential ที่ถูกขโมยเพื่อเข้าถึงระบบ คุณอาจสามารถหยุดพวกเขาได้ทันทีหาก credential ที่พวกเขาใช้หมดอายุก่อนที่จะสามารถใช้ประโยชน์จากมันได้มาก
ตัวอย่างที่ดีของการทำ rotation สำหรับ credential ของผู้ดูแลระบบคือการสร้าง API key แบบมีเวลาจำกัดสำหรับใช้งาน AWS หลายองค์กรตอนนี้สร้าง API key แบบทันทีสำหรับพนักงานของตน โดยที่ public/private keypair จะใช้ได้ในระยะเวลาสั้นๆ เท่านั้น—โดยทั่วไปน้อยกว่าหนึ่งชั่วโมง วิธีนี้ทำให้คุณสามารถสร้าง API key ที่คุณต้องการสำหรับดำเนินการใดๆ ก็ตาม โดยมั่นใจได้ว่าแม้ฝ่ายไม่หวังดีจะเข้าถึง key เหล่านี้ในภายหลัง พวกเขาก็ไม่สามารถใช้ประโยชน์จากมันได้ แม้ว่าคุณจะเผลอ check keypair นั้นเข้าไปใน public GitHub มันก็จะไม่มีประโยชน์กับใครเลยเมื่อมันหมดอายุแล้ว
การใช้ credential แบบมีเวลาจำกัดยังมีประโยชน์สำหรับระบบด้วยเช่นกัน Hashicorp’s Vault สามารถสร้าง credential แบบมีเวลาจำกัดสำหรับฐานข้อมูลได้ แทนที่ microservice instance ของคุณจะอ่านรายละเอียดการเชื่อมต่อฐานข้อมูลจาก configuration store หรือไฟล์ text มันสามารถถูกสร้างขึ้นแบบทันทีสำหรับ instance เฉพาะของ microservice คุณได้แทน
การเปลี่ยนไปสู่กระบวนการหมุนเวียน credential อย่างเช่น key บ่อยๆ อาจเป็นเรื่องเจ็บปวด ผมเคยคุยกับบริษัทที่เจอเหตุการณ์อันเป็นผลจากการทำ key rotation ซึ่งทำให้ระบบหยุดทำงานเมื่อ key ถูกเปลี่ยน สิ่งนี้มักเกิดจากความไม่ชัดเจนว่าอะไรกำลังใช้ credential นั้นอยู่ หากขอบเขตของ credential ถูกจำกัด ผลกระทบที่อาจเกิดขึ้นจาก rotation ก็จะลดลงอย่างมาก แต่ถ้า credential มีการใช้งานที่กว้าง การหาผลกระทบของการเปลี่ยนแปลงก็อาจเป็นเรื่องยาก นี่ไม่ได้หมายความว่าคุณควรเลิกทำ rotation แต่แค่อยากให้คุณตระหนักถึงความเสี่ยงที่อาจเกิดขึ้น และผมยังเชื่อมั่นว่ามันเป็นสิ่งที่ถูกต้องที่ควรทำ ทางเดินที่เหมาะสมที่สุดน่าจะเป็นการนำ tooling มาช่วยทำ automation ในกระบวนการนี้ พร้อมกับจำกัดขอบเขตของ credential แต่ละชุดไปพร้อมกันด้วย
Revocation (การเพิกถอน)
การมี นโยบายเพื่อให้แน่ใจว่า credential สำคัญถูกหมุนเวียนเป็นประจำ อาจเป็นวิธีที่สมเหตุสมผลในการจำกัดผลกระทบของการรั่วไหลของ credential แต่จะเกิดอะไรขึ้นถ้าคุณ รู้ ว่า credential ตัวใดตัวหนึ่งตกไปอยู่ในมือของคนที่ไม่ควรได้รับ คุณต้องรอจนกว่าจะถึงรอบ rotation ตามกำหนดเพื่อให้ credential นั้นไม่สามารถใช้งานได้อีกหรือไม่ นั่นอาจไม่ใช่วิธีที่ปฏิบัติได้จริง—หรือสมเหตุสมผล แทนที่จะเป็นแบบนั้น คุณอยากจะสามารถ revoke และสร้าง credential ขึ้นมาใหม่ได้โดยอัตโนมัติเมื่อเกิดสถานการณ์แบบนี้ขึ้น
การใช้เครื่องมือที่รองรับ centralized secrets management สามารถช่วยได้ในเรื่องนี้ แต่อาจต้องการให้ microservice ของคุณสามารถอ่านค่าที่ถูกสร้างขึ้นใหม่ได้ หาก microservice ของคุณอ่าน secret โดยตรงจากสิ่งอย่าง Kubernetes secrets store หรือ Vault มันสามารถได้รับการแจ้งเตือนเมื่อค่าเหล่านี้เปลี่ยนแปลง ทำให้ microservice ของคุณสามารถใช้ค่าที่เปลี่ยนแปลงไปได้ ในทางกลับกัน หาก microservice ของคุณอ่าน secret เหล่านี้แค่ตอน startup เท่านั้น คุณอาจต้องทำ rolling restart ของระบบเพื่อโหลด credential ใหม่ หากคุณหมุนเวียน credential เป็นประจำอยู่แล้ว มีโอกาสสูงที่คุณจะแก้ปัญหาเรื่อง microservice ของคุณต้องอ่านข้อมูลนี้ใหม่ได้แล้ว หากคุณสะดวกใจกับการหมุนเวียน credential เป็นประจำ มีโอกาสสูงที่คุณจะพร้อมรับมือกับการเพิกถอนฉุกเฉินได้เช่นกัน
Scanning for Keys (การสแกนหา Key)
การเผลอ check-in private key เข้าไปใน source code repository เป็นวิธีทั่วไปที่ credential รั่วไหลไปสู่ฝ่ายที่ไม่ได้รับอนุญาต—มันเกิดขึ้นบ่อยอย่างน่าตกใจ GitHub สแกน repository โดยอัตโนมัติเพื่อหา secret บางประเภท แต่คุณก็สามารถรันการสแกนของตัวเองได้เช่นกัน มันจะดีมากถ้าคุณสามารถจับ secret ได้ก่อน check-in และ git-secrets ช่วยให้คุณทำแบบนั้นได้ มันสามารถสแกน commit ที่มีอยู่แล้วเพื่อหา secret ที่อาจเกิดขึ้น แต่ด้วยการตั้งค่าให้เป็น commit hook มันสามารถหยุด commit ไม่ให้เกิดขึ้นได้เลย ยังมีเครื่องมือคล้ายกันอย่าง gitleaks ซึ่งนอกจากจะรองรับ pre-commit hook และการสแกน commit ทั่วไปแล้ว ยังมีฟีเจอร์บางอย่างที่ทำให้มันมีประโยชน์มากขึ้นในฐานะเครื่องมือทั่วไปสำหรับสแกนไฟล์ local
Limiting scope (การจำกัดขอบเขต)
การจำกัด ขอบเขตของ credential เป็นหัวใจของการนำหลักการ least privilege มาใช้ สิ่งนี้สามารถนำไปใช้ได้กับ credential ทุกรูปแบบ แต่การจำกัดขอบเขตของสิ่งที่ credential ชุดหนึ่งให้คุณเข้าถึงได้นั้นมีประโยชน์อย่างมาก ตัวอย่างเช่น ใน Figure 11-1 แต่ละ instance ของ microservice Inventory ได้รับ username และ password ชุดเดียวกันสำหรับฐานข้อมูลที่รองรับ เรายังให้สิทธิ์เข้าถึงแบบอ่านอย่างเดียวแก่โปรเซส Debezium ที่รองรับอยู่ ซึ่งจะใช้อ่านข้อมูลและส่งออกผ่าน Kafka เป็นส่วนหนึ่งของกระบวนการ ETL ที่มีอยู่แล้ว ถ้า username และ password ของ microservice ถูกขโมยไป ฝ่ายภายนอกในทางทฤษฎีก็จะสามารถเข้าถึงฐานข้อมูลได้ทั้งแบบอ่านและเขียน แต่ถ้าพวกเขาเข้าถึง credential ของ Debezium ได้แทน พวกเขาก็จะมีสิทธิ์แค่แบบอ่านอย่างเดียวเท่านั้น
Figure 11-1. การจำกัดขอบเขตของ credential เพื่อลดผลกระทบจากการใช้งานในทางที่ผิด
การจำกัดขอบเขตสามารถนำไปใช้ได้ทั้งในแง่ของสิ่งที่ credential ชุดหนึ่งเข้าถึงได้ และในแง่ของใครมีสิทธิ์เข้าถึง credential ชุดนั้นด้วย ใน Figure 11-2 เราได้เปลี่ยนแปลงให้แต่ละ instance ของ Inventory ได้รับ credential ชุดที่แตกต่างกัน ซึ่งหมายความว่าเราสามารถ rotate credential แต่ละชุดได้อย่างเป็นอิสระ หรือแค่ revoke credential ของ instance ใดหนึ่งที่ถูกขโมยไปก็ได้ ยิ่งไปกว่านั้น ด้วย credential ที่เจาะจงมากขึ้น มันจะง่ายขึ้นในการหาว่า credential นั้นถูกขโมยไปจากที่ใดและอย่างไร แน่นอนว่ายังมีประโยชน์อื่นๆ ที่มาจากการมี username ที่ระบุตัวตนได้เฉพาะตัวสำหรับ microservice instance เช่น มันอาจทำให้ง่ายขึ้นในการติดตามว่า instance ใดเป็นสาเหตุของ query ที่แพงเกินไป เป็นต้น
Figure 11-2. แต่ละ instance ของ Inventory มี access credential ของตัวเองสำหรับฐานข้อมูล ซึ่งช่วยจำกัดการเข้าถึงมากยิ่งขึ้น
อย่างที่เราได้พูดถึงไปแล้ว การจัดการ credential แบบ fine-grained ในระดับใหญ่อาจซับซ้อน และถ้าคุณต้องการนำแนวทางแบบนี้มาใช้ automation ในรูปแบบใดรูปแบบหนึ่งจะเป็นสิ่งจำเป็นอย่างยิ่ง—secret store อย่าง Vault ก็นับเป็นตัวเลือกที่ดีเยี่ยมในการนำโครงร่างแบบนี้ไปปฏิบัติจริง
Patching (การแพตช์)
เหตุการณ์ การรั่วไหลของข้อมูล Equifax ในปี 2017 เป็นตัวอย่างที่ดีของความสำคัญของการ patch ช่องโหว่ที่รู้จักใน Apache Struts ถูกใช้เพื่อเข้าถึงข้อมูลที่ Equifax เก็บไว้โดยไม่ได้รับอนุญาต เนื่องจาก Equifax เป็น credit bureau ข้อมูลนี้จึงมีความอ่อนไหวเป็นพิเศษ ในท้ายที่สุด พบว่าข้อมูลของคนกว่า 160 ล้านคนถูกขโมยไปในการรั่วไหลครั้งนี้ Equifax ต้องจ่ายค่า settlement ถึง 700 ล้านดอลลาร์
หลายเดือนก่อนเกิดการรั่วไหล ช่องโหว่ใน Apache Struts ได้ถูกระบุแล้ว และ maintainer ได้ออก release ใหม่มาแก้ไขปัญหานี้แล้ว แต่น่าเสียดายที่ Equifax ไม่ได้อัปเดตเป็นเวอร์ชันใหม่ของซอฟต์แวร์ แม้ว่ามันจะพร้อมใช้งานมาหลายเดือนก่อนการโจมตีแล้วก็ตาม หาก Equifax อัปเดตซอฟต์แวร์นี้ทันเวลา ดูเหมือนว่าการโจมตีครั้งนี้จะไม่มีทางเกิดขึ้นได้เลย
ประเด็นเรื่องการตามให้ทันกับการ patch กำลังซับซ้อนขึ้นเรื่อยๆ เมื่อเรา deploy ระบบที่ซับซ้อนมากขึ้นเรื่อยๆ เราจำเป็นต้องพัฒนาความเชี่ยวชาญให้มากขึ้นในการจัดการกับแนวคิดพื้นฐานนี้
Figure 11-3 แสดงตัวอย่างของชั้นต่างๆ ของ infrastructure และซอฟต์แวร์ที่มีอยู่ใต้ Kubernetes cluster ทั่วไป หากคุณรัน infrastructure ทั้งหมดนั้นด้วยตัวเอง คุณก็รับผิดชอบในการจัดการและ patch ทุกชั้นเหล่านั้น คุณมั่นใจแค่ไหนว่าคุณตามทันการ patch อยู่? แน่นอนว่าถ้าคุณสามารถโยนงานบางส่วนนี้ไปให้ public cloud provider ได้ คุณก็สามารถโยนภาระบางส่วนนี้ไปได้เช่นกัน
Figure 11-3. ชั้นต่างๆ ใน infrastructure สมัยใหม่ที่ล้วนต้องการการดูแลรักษาและ patch
หากคุณใช้ managed Kubernetes cluster บนหนึ่งใน public cloud vendor หลักๆ ยกตัวอย่างเช่น คุณก็จะลดขอบเขตความรับผิดชอบของคุณลงอย่างมาก ดังที่เราเห็นใน Figure 11-4 .
Figure 11-4. การโยนความรับผิดชอบของชั้นบางส่วนของ stack นี้ไปให้ผู้อื่นสามารถลด ความซับซ้อน ได้
Container โยนความท้าทายที่น่าสนใจมาให้เราตรงนี้ เราปฏิบัติต่อ container instance หนึ่งๆ ว่าเป็น immutable แต่ container ไม่ได้มีแค่ซอฟต์แวร์ของเราเท่านั้น มันยังมีระบบปฏิบัติการด้วย แล้วคุณรู้หรือไม่ว่า container นั้นมาจากที่ไหน? Container ถูกสร้างจาก image ซึ่งในทางกลับกันก็สามารถ extend image อื่นๆ ได้อีก—คุณแน่ใจหรือว่า base image ที่คุณใช้ไม่ได้มี backdoor ซ่อนอยู่แล้ว? ถ้าคุณไม่ได้เปลี่ยน container instance มาหกเดือนแล้ว นั่นหมายถึง patch ของระบบปฏิบัติการ 6 เดือนที่ยังไม่ได้ถูกนำมาใช้ การตามให้ทันเรื่องนี้เป็นปัญหา ซึ่งเป็นเหตุผลว่าทำไมบริษัทอย่าง Aqua จึงมี tooling ที่ช่วยคุณวิเคราะห์ container ที่รันอยู่ใน production เพื่อให้คุณเข้าใจว่ามีปัญหาอะไรบ้างที่ต้องได้รับการแก้ไข
ที่ชั้นบนสุดของกลุ่มชั้นนี้ แน่นอนว่าคือโค้ดแอปพลิเคชันของเรา มันอัปเดตอยู่เสมอหรือไม่? ไม่ใช่แค่โค้ดที่ เรา เขียนเท่านั้น แล้วโค้ดของบุคคลที่สามที่เราใช้ล่ะ? บั๊กใน third-party library หนึ่งอาจทำให้แอปพลิเคชันของเราเปราะบางต่อการโจมตีได้ ในกรณีของการรั่วไหลของข้อมูล Equifax ช่องโหว่ที่ไม่ได้ patch นั้นอยู่ใน Struts จริงๆ—ซึ่งเป็น Java web framework .
ในระดับใหญ่ การหาว่า microservice ตัวไหนกำลังเชื่อมโยงกับ library ที่มีช่องโหว่ที่รู้จักอยู่นั้นอาจยากมาก นี่คือพื้นที่ที่ผมแนะนำอย่างยิ่งให้ใช้เครื่องมืออย่าง Snyk หรือ GitHub code scanning ซึ่งสามารถสแกน third-party dependency ของคุณโดยอัตโนมัติ และแจ้งเตือนคุณหากคุณกำลังเชื่อมโยงกับ library ที่มีช่องโหว่ที่รู้จัก ถ้ามันพบช่องโหว่ มันสามารถส่ง pull request มาช่วยคุณอัปเดตเป็นเวอร์ชันที่ patch แล้วได้ คุณสามารถนำสิ่งนี้เข้าไปเป็นส่วนหนึ่งของกระบวนการ CI ของคุณได้ด้วยซ้ำ และทำให้ microservice build ล้มเหลวหากมันเชื่อมโยงกับ library ที่มีปัญหา
Backups (การสำรองข้อมูล)
บางครั้ง ผมคิดว่าการทำ backup ก็เหมือนกับการใช้ไหมขัดฟัน ตรงที่มีคนพูดว่าตัวเองทำมากกว่าคนที่ทำจริงๆ ผมไม่รู้สึกอยากย้ำข้อโต้แย้งเรื่อง backup มากนักในที่นี้ นอกจากจะบอกว่า: คุณควรทำ backup เพราะข้อมูลมีค่า และคุณไม่อยากสูญเสียมันไป
ข้อมูลมีค่ามากกว่าที่เคยเป็นมา แต่บางครั้งผมก็สงสัยว่าความก้าวหน้าทางเทคโนโลยีทำให้เราให้ความสำคัญกับ backup น้อยลงหรือไม่ ดิสก์มีความน่าเชื่อถือมากกว่าที่เคยเป็นมา ฐานข้อมูลมักจะมี replication ในตัวเพื่อหลีกเลี่ยงการสูญเสียข้อมูล ด้วยระบบแบบนี้ เราอาจโน้มน้าวตัวเองว่าเราไม่ต้องการ backup แล้ว แต่จะเกิดอะไรขึ้นถ้าเกิดข้อผิดพลาดร้ายแรงและ Cassandra cluster ทั้งหมดของคุณถูกลบทิ้งไป? หรือถ้าบั๊กในโค้ดทำให้แอปพลิเคชันของคุณลบข้อมูลที่มีค่าไปจริงๆ? Backup ยังคงมีความสำคัญเช่นเดิม ดังนั้นโปรดสำรองข้อมูลสำคัญของคุณ
เนื่องจากการ deploy microservice ของเราถูกทำแบบอัตโนมัติ เราจึงไม่จำเป็นต้อง backup ทั้งเครื่อง เพราะเราสามารถ rebuild infrastructure ของเราจาก source code ได้ ดังนั้นเราจึงไม่ได้พยายามคัดลอกสถานะของเครื่องทั้งหมด แต่เรามุ่งเป้า backup ไปที่สถานะที่มีค่าที่สุดแทน ซึ่งหมายความว่าจุดสนใจของเราสำหรับ backup จำกัดอยู่แค่สิ่งอย่างข้อมูลในฐานข้อมูลของเรา หรือบางทีก็ application log ของเรา ด้วยเทคโนโลยี filesystem ที่เหมาะสม มันเป็นไปได้ที่จะทำ block-level clone ของข้อมูลฐานข้อมูลแบบเกือบทันที โดยไม่รบกวนบริการอย่างเห็นได้ชัด