Under the Cloud: AWS #2

ก่อนจะดองบล็อคจนลืม ขอเขียนต่อเลยแล้วกัน

หลังจากตอนที่แล้วเราพูดถึง Amazon EC2 ไปแล้ว ตอนนี้อยากจะลองพูดถึง service อื่นๆ ของ AWS ดูบ้าง

Design ของ Cloud หลายเจ้า รวมทั้ง AWS ด้วยนั้น service ต่างๆ ก็มักเอามาประกอบกันเอง

ปลายปีที่แล้วผมมีโอกาสได้สัมภาษณ์คุณ Shaun Ray จาก AWS ในงานวันนั้น AWS เปิดตัวระบบ Managed Blockchain ผมถามเค้าว่าแล้ว AWS ได้ใช้ Blockchain หรือเปล่า? คำตอบที่ได้ผมแปลกใจมาก เพราะเค้าบอกว่า Audit Log ของระบบด้านหลังนั้นอยู่บน Amazon QLDB

Early EC2

ผมเคยอ่านบล็อค On Amazon EC2’s Underlying Architecture มานานแล้ว ตอนที่เขียนบทความที่แล้วกลับไปค้นบทความนี้แล้วหาไม่เจอเลยไม่ได้เอาข้อมูลมาใส่ไว้

ในบทความนี้เค้าได้สำรวจระบบ EC2 สมัยที่ยังเป็น Xen อยู่ ซึ่งสามารถใช้เครื่องไม้เครื่องมือของ Xen สำรวจดูได้

จากบทความสรุปได้ว่า EC2 สมัยแรกนั้นใช้ Stack ต่อไปนี้

  • Virtualization: ข้อมูลตรงนี้เปิดเผยว่าเป็น Xen
  • Management OS: อาจจะเป็น Red Hat ปัจจุบันเราคอนเฟิร์มแล้วว่าเป็น Amazon Linux ซึ่งก็เป็น Red Hat Derivative
  • EBS: มันคือ GNBD แต่เราไม่มีข้อมูลว่าฝั่ง server เป็นโปรแกรมอะไร

ซึ่งเค้าก็สรุปว่ามันคือซอฟต์แวร์ Clustering ของ Red Hat นี่แหละ

Amazon SQS

Inside AWS: Technology Choices for Modern Applications

SQS เป็นระบบ Message queue (คล้ายๆ RabbitMQ) ซึ่งแบ่งเป็น microservice ต่างๆ ดังนี้

  • Frontend สำหรับ REST API
  • Backend เก็บ message ใน queue ไว้ โดยรันเป็นหลายๆ Cluster ใน 1 Cluster จะประกอบด้วยเครื่องจำนวนหนึ่งกระจายอยู่หลายๆ AZ
  • Metadata service ไว้เก็บ mapping ว่า queue ใดอยู่บน Cluster ใด
  • Load Manager ทำหน้าที่เกลี่ย Queue ระหว่าง Cluster ถ้าหาก Cluster ใดมีการใช้งานมากหรือน้อยเกินไป

AWS บอกว่า Database ก่อนจะมาเป็น DynamoDB ครั้งหนึ่งเคยเป็น Oracle มาก่อน ซึ่งวิธีการย้ายก็คือค่อยๆ รันคู่ไปทั้ง cluster ที่ใช้ DynamoDB และ Oracle จน cluster เดิมไม่มีข้อความเหลือแล้วก็ปิดทิ้งไป

Amazon MQ

บริการถัดมาคือ Amazon MQ ซึ่งก็เป็นระบบ message queue เช่นกัน แต่มันคือ Managed ActiveMQ ด้านหลังระบบ control ก็เป็น serverless ทั้งหมด ได้แก่

  • Amazon API Gateway
  • AWS Lambda
  • Amazon DynamoDB

AWS ยังแถมให้อีกด้วยว่ามีอีกหลายบริการที่ API ด้านหลังเป็น serverless ทั้งหมด

ใช่แล้ว Amazon API Gateway เวลาแก้ config มัน ด้านหลังก็ทำงานด้วย serverless เช่นกัน

DynamoDB

จะเห็นว่าหลายๆ Service ของ AWS นั้นจะเก็บข้อมูลบน DynamoDB ทั้งหมด

DynamoDB นั้นเป็นวิวัฒนาการของ Dynamo ซึ่งเคยมี paper ออกมาในปี 2007 แต่จริงๆ แล้ว DynamoDB ก็ไม่ใช่ Dynamo เพราะเปลี่ยนระบบ Quorum เป็น Paxos แทน

AWS เคยมี Talk เกี่ยวกับ DynamoDB ในงาน re:invent 2018 ซึ่งเค้าก็อธิบายไว้ว่า

เวลาเรายิง API Call ใดๆ ไปหา Dynamo นั้นเราจะติด Request Router ซึ่งจะยิงเข้า Service ที่ทำหน้าที่เช็ค IAM Policy ต่างๆ (อยู่ในสไลด์ก่อนหน้า ผมไม่ได้แคปมา) จากนั้นกรณีที่จะอ่านข้อมูล ตัว Router ก็ยิงเข้า Storage Node เอา Data มาได้เลย

กรณีที่ต้องการ Write นั้น DynamoDB จะต้อง Write ไปยัง 3 เครื่องจึงจะสมบูรณ์ ซึ่งในการทำงานจริงนั้น Router จะต้องยิง Write ไปหาเครื่องที่เป็น Leader (จาก Paxos Leader Election) แล้ว Leader จะต้องบอกให้อีก 2 เครื่อง Write ข้อมูลเดียวกันด้วย เมื่อเครื่องใดเครื่องหนึ่งบอกว่า Write สำเร็จแล้วจึงจะ response กลับไปให้เรา (ส่วน Node ที่ 3 นั้นไม่ได้รอ ไปแก้ปัญหาทีหลังได้)

ในขณะที่การ Write นั้นจะต้องทำที่ Leader การ Read จะสามารถทำที่เครื่องไหนก็ได้ที่มีข้อมูล นั่นแปลว่าเราอาจจะได้ข้อมูลที่ล้าหลังไปได้ ซึ่ง DynamoDB เองก็ได้ระบุไว้แล้วว่าระบบของเค้าเป็นแบบ Eventual consistent

แน่นอนว่าใน scale จริงแล้ว Request Router นั้นก็มีจำนวนมากรันอยู่ในทุกๆ โซน และ Storage Node ก็จะแบ่งเป็น Partition ต่างๆ ที่ Router จะต้องส่งต่อ request ไปให้ถูกต้อง

ด้านหลังของ DynamoDB ยังมี Detail อื่นอีกเยอะมาก เช่น Router จะรู้ได้อย่างไรว่าต้องส่งไป Partition ไหน? หรือถ้า Node fail แล้วจะกลับขึ้นมาได้อย่างไร แนะนำให้ดูจาก Session ของเค้าด้านบนครับ

S3

ใน re:invent Keynote ปี 2018 นั้น AWS ได้ระบุว่า S3 เวอร์ชั่นแรกเมื่อ 13 ปีก่อนประกอบด้วย 8 Microservice และปัจจุบันประกอบด้วย microservice มากกว่า 235 ตัว

น่าเสียดายที่เรายังไม่มีข้อมูลเพิ่มเติมมากกว่านี้ว่า 235 services ทำหน้าที่อะไรบ้าง

Aurora

re:Invent 2018 Keynote with Werner Vogels

การทำงานด้านหลัง Aurora นั้นจริงๆ มีเขียนออกมาเป็น Paper แล้ว แต่ที่ผมแปลกใจมากคือ AWS เคียดแค้น Oracle มากจนถึงกับต้องเอา paper นี้มาเล่าใน Keynote เลย

ด้านหลังนั้น Aurora ประกอบด้วยบริการต่อไปนี้

  • Database instance เป็น RDS เครื่องหนึ่งซึ่งรัน MySQL เวอร์ชั่น fork
  • บนเครื่องจะต่อกับ 3 VPC ได้แก่ VPC ของเรา, RDS VPC เพื่อติดต่อกับส่วนควบคุม และ Storage VPC ใช้ติดต่อกับส่วนเก็บข้อมูล
  • ส่วนเก็บข้อมูลเป็น EC2 cluster กระจายทั้ง 3AZ โดยใช้ Local SSD
  • Backup service เชื่อมต่อกับ Storage node และจะสำรองข้อมูลไปบน S3 อย่างต่อเนื่อง
  • ส่วนควบคุมของส่วนเก็บข้อมูล เก็บข้อมูลไว้บน DynamoDB
  • กรณี node fail ระบบจะต้อง repair โดยใช้ Amazon SWF

ELB

Elastic Load Balancing Deep Dive and Best Practices

ผมเคยนั่งแกะ ELB/ALB แล้วก็พบว่า Hint ที่ค่อนข้างชัดมากของ ELB ว่ามันคืออะไรอยู่ที่หน้า error page ซึ่งของ Classic ELB นั้นจะดูคล้าย HAproxy มาก ส่วนของ ALB ก็คล้าย nginx แต่ก็คาดว่าจะมี custom code อยู่จำนวนมาก

ด้านหลังของ ALB เองก็พอเดาได้ไม่ยาก เนื่องจากว่าเครื่อง EC2 จะมี Reverse DNS record ที่ค่อนข้างชัด เช่นถ้าผมเอา IP ของ wongnai.com ไป Reverse Lookup ก็จะได้ ec2-13-228-38-141.ap-southeast-1.compute.amazonaws.com. เลยค่อนข้างมั่นใจว่ามันเป็น EC2 แน่นอน

ใน Talk Elastic Load Balancing Deep Dive and Best Practices นั้น AWS ก็ได้เปิดเผยว่า ELB นั้นจะรันอยู่ใน VPC ของ ELB เอง โดยเครื่องจะรันอยู่ใน zone ตามที่เราเลือกไว้ จากนั้นเราจะได้ DNS Record มาอันหนึ่งสำหรับเข้า ELB ซึ่งแน่นอน DNS Record นั้นก็ให้บริการโดย Amazon Route 53

Lambda

ด้านหลังของ Lambda นั้น เมื่อเรา request เข้ามาทาง ALB จะถูกส่งต่อให้กับ Lambda Frontend ซึ่งจะไปขอเครื่องจาก Worker manager ถ้ามีเครื่องว่างอยู่แล้วก็จะได้เครื่องเดิม แต่ถ้าไม่มีก็จะสร้างใหม่ให้ จากนั้น Frontend ก็ยิง request ไปหา Worker โดยตรง

และ surprise ที่ไม่ surprise ครับ ตัว Lambda worker นั้นก็คือ EC2 instance นั่นเอง โดยลูกค้าแต่ละคนก็จะแยก EC2 กันไปเพื่อความปลอดภัย

ในปี 2018 AWS เปิดตัว AWS Firecracker ซึ่งเป็นระบบจัดการ VM ที่ตัดทุกอย่างออกหมดทำให้ overhead ต่ำมาก

หลังจากเปิดตัวไปไม่นาน Lambda ก็ประกาศลดราคาตามมาเนื่องจากย้ายไปใช้ Firecracker แทนการแยก EC2 แล้ว

ใน Lambda บน Firecracker นี้ ระบบจะรันอยู่บน EC2 Bare Metal (ที่เขียนถึงในตอนก่อนหน้านี้) โดยเครื่องหนึ่งรัน microVM ได้หลายแสนตัว ทำให้ utilization ของเครื่อง host สูงมากกว่าการ scale ตามปกติ

ปัญหาของการทำแบบนี้คือ Lambda ที่เชื่อมต่อกับ VPC จะเปิดช้ามาก เพราะต้องเอา ENI ใน VPC ของเราเสียบเข้ากับเครื่อง worker ซึ่งใช้เวลานาน AWS ก็ได้แก้ไขปัญหานี้โดยให้ worker สร้าง VPN ไปยังอีกเครื่องหนึ่งซึ่งมี ENI เสียบอยู่แล้วแทน ทำให้สามารถแชร์ ENI ระหว่างเครื่อง worker จำนวนมากได้

Wall of Text #2: Copy protection

คำถามที่สองถามว่า จะเขียนแอพ Android ป้องกันไม่ให้คน Crack ได้ไหม?

คำตอบคือ It depends

อืม ตอบแบบนี้เปลี่ยนอาชีพเป็น consult เลย…

Depends ยังไง คำตอบคือเราสามารถใช้ Google Play Licensing API เพื่อเช็คได้ว่าผู้ใช้งานซื้อแอพเราหรือยัง

แต่ถ้าเราเช็คในแอพ ปัญหาที่ตามมาคือมันถูกเจาะได้ 2 ท่า

  1. ปลอม response จาก Google Play ให้บอกว่ามีแอพแล้ว (คล้ายๆ iAP Cracker ใน iOS)
  2. ถ้าเราเช็ค 1 อย่างดีแล้ว cracker ก็จะ recompile app เราใหม่โดยลบ check ออก

วิธีเดียวที่จะปลอดภัยคือย้าย check นี้ไปรันบน server ของเราเวลาเราขอให้ server ทำอะไรบางอย่าง

ถ้าไม่มี license ก็ปฏิเสธ ไม่ทำให้

แต่ไม่ใช่ทุกแอพจะสามารถทำแบบนี้ได้ เพราะต้องมี server และ server ต้องทำอะไรบางอย่างด้วย ไม่ใช่แค่ยิงไป check license บน server อย่างเดียว แบบนี้โดนถอดโค้ดแบบข้อ 2 แน่นอน

ตัวอย่างการใช้ server เช่น

  1. Music Game ขายเพลงเป็น In app purchase เวลาจะกดโหลดเพลงฝั่ง server จะต้องเช็ค Licensing ก่อนถึงจะเอาไฟล์เพลงไปให้โหลดได้
  2. แอพที่มี Cloud backup อาจจะล็อคไม่ให้ Cloud backup ได้ (แต่ก็ยัง crack ใช้ feature อื่นๆ ได้อยู่ดี)
  3. ระบบ Social เช่น WhatApps ตอน Login ก็ส่ง Licensing status ไปด้วยเลย ถ้าไม่ซื้อ Login ไม่ได้

แอพที่ทำงานเป็น offline อย่างเดียว ก็ทำอะไรไม่ได้เท่าไรนัก เช่นแอพ Keyboard หรือแอพกล้องถ่ายรูป

วิธีหนึ่งที่พอจะช่วยได้คือใช้โปรแกรมประเภท Obfuscator เพื่อทำให้โค้ดโปรแกรมที่ถอดออกมาแล้วอ่านไม่ออก จะได้ลบ check ได้ยากขึ้น แต่ก็เป็นแค่วิธีถ่วงเวลาเท่านั้นไม่ได้สามารถป้องกันการ crack ได้ 100%