เรายอมรับ 10 กิจกรรมใน Yandex.Cloud ส่วนที่ 000

สวัสดีทุกคนเพื่อน!

* บทความนี้อิงจากเวิร์กช็อปแบบเปิด REBRAIN & Yandex.Cloud หากคุณต้องการชมวิดีโอ คุณสามารถดูได้ที่ลิงก์นี้ - https://youtu.be/cZLezUm0ekE

เมื่อเร็ว ๆ นี้เราได้มีโอกาสลองใช้ Yandex.Cloud แบบสด เนื่องจากเราต้องการสำรวจอย่างยาวนานและหนักหน่วง เราจึงละทิ้งความคิดที่จะเปิดตัวบล็อก Wordpress ที่เรียบง่ายพร้อมฐานคลาวด์ทันที - มันน่าเบื่อเกินไป หลังจากครุ่นคิดอยู่พักหนึ่ง เราจึงตัดสินใจปรับใช้สิ่งที่คล้ายกับสถาปัตยกรรมบริการการผลิตเพื่อรับและวิเคราะห์เหตุการณ์ในโหมดเรียลไทม์แบบใกล้เคียง

ฉันมั่นใจอย่างยิ่งว่าธุรกิจออนไลน์ส่วนใหญ่ (และไม่เพียงเท่านั้น) รวบรวมข้อมูลมากมายเกี่ยวกับผู้ใช้และการกระทำของพวกเขา อย่างน้อยที่สุด สิ่งนี้จำเป็นสำหรับการตัดสินใจบางอย่าง - ตัวอย่างเช่น หากคุณจัดการเกมออนไลน์ คุณสามารถดูสถิติที่ระดับที่ผู้ใช้มักติดขัดและลบของเล่นของคุณ หรือเหตุใดผู้ใช้จึงออกจากไซต์ของคุณโดยไม่ซื้ออะไรเลย (สวัสดี Yandex.Metrica)

ดังนั้น เรื่องราวของเรา: วิธีที่เราเขียนแอปพลิเคชันใน golang, ทดสอบ kafka กับ rabbitmq กับ yqs, เขียนการสตรีมข้อมูลในคลัสเตอร์ Clickhouse และแสดงภาพข้อมูลโดยใช้ yandex datalens โดยธรรมชาติแล้ว ทั้งหมดนี้ปรุงรสด้วยโครงสร้างพื้นฐานในรูปแบบของ docker, terraform, gitlab ci และแน่นอน prometheus ไปกันเถอะ!

ฉันต้องการจองทันทีว่าเราจะไม่สามารถกำหนดค่าทุกอย่างได้ในคราวเดียว - สำหรับสิ่งนี้เราจะต้องมีบทความหลายบทความในซีรีส์ เล็กน้อยเกี่ยวกับโครงสร้าง:

ตอนที่ 1 (คุณกำลังอ่านอยู่) เราจะตัดสินใจเกี่ยวกับข้อกำหนดและสถาปัตยกรรมของโซลูชัน และเขียนแอปพลิเคชันในภาษา golang ด้วย
ส่วนที่ 2 เราเผยแพร่แอปพลิเคชันของเราสู่การใช้งานจริง ทำให้สามารถปรับขนาดได้ และทดสอบโหลด
ส่วนที่ 3 ลองหาคำตอบว่าทำไมเราต้องเก็บข้อความไว้ในบัฟเฟอร์ไม่ใช่ในไฟล์และเปรียบเทียบบริการคิว kafka, rabbitmq และ yandex
ตอนที่ 4 เราจะปรับใช้คลัสเตอร์ Clickhouse เขียนบริการสตรีมมิ่งเพื่อถ่ายโอนข้อมูลจากบัฟเฟอร์ที่นั่น และตั้งค่าการแสดงภาพในดาต้าเลนส์
ตอนที่ 5 มาทำให้โครงสร้างพื้นฐานทั้งหมดอยู่ในรูปแบบที่เหมาะสม - ตั้งค่า ci/cd โดยใช้ gitlab ci เชื่อมต่อการตรวจสอบและการค้นพบบริการโดยใช้ Prometheus และ Consul

TK

ขั้นแรก เรามากำหนดเงื่อนไขการอ้างอิงกันก่อน - ผลลัพธ์ที่เราต้องการจะได้คืออะไรกันแน่

  1. เราต้องการให้จุดสิ้นสุดเช่น events.kis.im (kis.im คือโดเมนทดสอบที่เราจะใช้ในบทความทั้งหมด) ซึ่งควรรับเหตุการณ์โดยใช้ HTTPS
  2. กิจกรรมเป็น json ธรรมดา เช่น: {“event”: “view”, “os”: “linux”, “browser”: “chrome”} ในขั้นตอนสุดท้าย เราจะเพิ่มฟิลด์อีกเล็กน้อย แต่สิ่งนี้จะไม่มีบทบาทสำคัญ หากต้องการคุณสามารถเปลี่ยนไปใช้ protobuf ได้
  3. บริการจะต้องสามารถประมวลผลเหตุการณ์ได้ 10 เหตุการณ์ต่อวินาที
  4. ควรเป็นไปได้ที่จะปรับขนาดในแนวนอนโดยเพียงแค่เพิ่มอินสแตนซ์ใหม่ให้กับโซลูชันของเรา และคงจะดีถ้าเราสามารถย้ายส่วนหน้าไปยังตำแหน่งทางภูมิศาสตร์ต่างๆ เพื่อลดเวลาแฝงสำหรับคำขอของลูกค้า
  5. ความอดทนต่อความผิดพลาด สารละลายจะต้องมีความเสถียรเพียงพอและสามารถทนต่อการตกของชิ้นส่วนใดๆ ได้ (ขึ้นอยู่กับจำนวนที่แน่นอน)

สถาปัตยกรรม

โดยทั่วไป สำหรับงานประเภทนี้ สถาปัตยกรรมแบบคลาสสิกได้รับการคิดค้นมานานแล้วเพื่อให้สามารถปรับขนาดได้อย่างมีประสิทธิภาพ รูปนี้แสดงตัวอย่างวิธีแก้ปัญหาของเรา

เรายอมรับ 10 กิจกรรมใน Yandex.Cloud ส่วนที่ 000

แล้วสิ่งที่เรามี:

1. ด้านซ้ายคืออุปกรณ์ของเราที่สร้างกิจกรรมต่างๆ ไม่ว่าจะเป็นผู้เล่นผ่านด่านของเล่นบนสมาร์ทโฟนหรือสร้างคำสั่งซื้อในร้านค้าออนไลน์ผ่านเบราว์เซอร์ปกติ เหตุการณ์ตามที่ระบุไว้ในข้อกำหนดจะเป็น json แบบธรรมดาที่ส่งไปยังตำแหน่งข้อมูลของเรา - events.kis.im

2. เซิร์ฟเวอร์สองตัวแรกเป็นตัวสร้างสมดุลอย่างง่าย งานหลักคือ:

  • มีอยู่อย่างต่อเนื่อง ในการดำเนินการนี้ คุณสามารถใช้ Keepalive ซึ่งจะสลับ IP เสมือนระหว่างโหนดต่างๆ ในกรณีที่เกิดปัญหา
  • ยุติ TLS ใช่ เราจะยุติ TLS กับพวกเขา ประการแรก เพื่อให้โซลูชันของเราสอดคล้องกับข้อกำหนดทางเทคนิค และประการที่สอง เพื่อลดภาระในการสร้างการเชื่อมต่อที่เข้ารหัสจากเซิร์ฟเวอร์แบ็กเอนด์ของเรา
  • ปรับสมดุลคำขอขาเข้าไปยังเซิร์ฟเวอร์แบ็กเอนด์ที่มีอยู่ คำสำคัญที่นี่สามารถเข้าถึงได้ จากข้อมูลนี้ เราจึงเข้าใจว่าโหลดบาลานเซอร์จะต้องสามารถตรวจสอบเซิร์ฟเวอร์ของเราด้วยแอปพลิเคชัน และหยุดสมดุลการรับส่งข้อมูลไปยังโหนดที่ล้มเหลว

3. หลังจากบาลานเซอร์แล้ว เรามีแอปพลิเคชันเซิร์ฟเวอร์ที่ใช้งานแอปพลิเคชันที่ค่อนข้างเรียบง่าย ควรยอมรับคำขอที่เข้ามาผ่าน HTTP ตรวจสอบความถูกต้องของ json ที่ส่ง และใส่ข้อมูลลงในบัฟเฟอร์

4. แผนภาพแสดง kafka เป็นบัฟเฟอร์ แม้ว่าแน่นอนว่าสามารถใช้บริการอื่นที่คล้ายคลึงกันในระดับนี้ได้ เราจะเปรียบเทียบ Kafka, rabbitmq และ yqs ในบทความที่สาม

5. จุดสุดท้ายของสถาปัตยกรรมของเราคือ Clickhouse ซึ่งเป็นฐานข้อมูลแบบเรียงเป็นแนวที่ช่วยให้คุณสามารถจัดเก็บและประมวลผลข้อมูลจำนวนมหาศาล ในระดับนี้ เราจำเป็นต้องถ่ายโอนข้อมูลจากบัฟเฟอร์ไปยังระบบจัดเก็บข้อมูลเอง (อ่านเพิ่มเติมในบทความที่ 4)

การออกแบบนี้ช่วยให้เราสามารถปรับขนาดแต่ละเลเยอร์ในแนวนอนได้อย่างอิสระ เซิร์ฟเวอร์แบ็กเอนด์ไม่สามารถรับมือได้ มาเพิ่มอีกอย่างหนึ่งกันดีกว่า เนื่องจากเป็นแอปพลิเคชันไร้สัญชาติ ดังนั้นจึงสามารถทำได้โดยอัตโนมัติด้วยซ้ำ บัฟเฟอร์แบบคาฟคาใช้งานไม่ได้ มาเพิ่มเซิร์ฟเวอร์และโอนพาร์ติชั่นบางส่วนของหัวข้อของเราไปให้พวกเขากันดีกว่า Clickhouse ไม่สามารถจัดการได้ - มันเป็นไปไม่ได้ :) จริงๆ แล้ว เรายังจะเชื่อมต่อเซิร์ฟเวอร์และแบ่งข้อมูลด้วย

อย่างไรก็ตาม หากคุณต้องการใช้ส่วนที่เป็นทางเลือกของข้อกำหนดทางเทคนิคและขนาดของเราในทางภูมิศาสตร์ที่แตกต่างกัน ไม่มีอะไรง่ายไปกว่านี้อีกแล้ว:

เรายอมรับ 10 กิจกรรมใน Yandex.Cloud ส่วนที่ 000

ในแต่ละตำแหน่งทางภูมิศาสตร์ เราปรับใช้โหลดบาลานเซอร์กับแอปพลิเคชันและคาฟคา โดยทั่วไปแล้ว แอปพลิเคชันเซิร์ฟเวอร์ 2 รายการ, โหนดคาฟคา 3 รายการ และตัวจัดสรรระบบคลาวด์ เช่น cloudflare ก็เพียงพอแล้ว ซึ่งจะตรวจสอบความพร้อมใช้งานของโหนดแอปพลิเคชัน และปรับสมดุลคำขอตามตำแหน่งทางภูมิศาสตร์โดยอิงตามที่อยู่ IP ต้นทางของไคลเอ็นต์ ดังนั้นข้อมูลที่ส่งโดยไคลเอนต์ชาวอเมริกันจะถูกส่งไปยังเซิร์ฟเวอร์ของอเมริกา และข้อมูลจากแอฟริกาอยู่ในแอฟริกา

จากนั้นทุกอย่างก็ค่อนข้างง่าย - เราใช้เครื่องมือมิเรอร์จากชุด Kafka และคัดลอกข้อมูลทั้งหมดจากสถานที่ทั้งหมดไปยังศูนย์ข้อมูลกลางของเราที่ตั้งอยู่ในรัสเซีย ภายใน เราจะแยกวิเคราะห์ข้อมูลและบันทึกไว้ใน Clickhouse เพื่อให้เห็นภาพในภายหลัง

ดังนั้นเราจึงแยกสถาปัตยกรรมออก - มาเริ่มเขย่า Yandex.Cloud กัน!

การเขียนใบสมัคร

ก่อนที่จะมีคลาวด์ คุณยังคงต้องอดทนอีกสักหน่อยและเขียนบริการที่ค่อนข้างง่ายเพื่อประมวลผลเหตุการณ์ที่เข้ามา เราจะใช้ golang เพราะมันพิสูจน์ตัวเองแล้วว่าเป็นภาษาสำหรับการเขียนแอปพลิเคชันเครือข่ายเป็นอย่างดี

หลังจากใช้เวลาไปหนึ่งชั่วโมง (อาจจะสองสามชั่วโมง) เราก็จะได้สิ่งนี้: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

ประเด็นหลักที่ฉันต้องการทราบที่นี่คืออะไร:

1. เมื่อเริ่มต้นแอปพลิเคชัน คุณสามารถระบุสองแฟล็ก คนหนึ่งรับผิดชอบพอร์ตที่เราจะรับฟังคำขอ http ขาเข้า (-addr) อย่างที่สองคือที่อยู่เซิร์ฟเวอร์ kafka ที่เราจะบันทึกกิจกรรมของเรา (-kafka):

addr     = flag.String("addr", ":8080", "TCP address to listen to")
kafka    = flag.String("kafka", "127.0.0.1:9092", "Kafka endpoints”)

2. แอปพลิเคชันใช้ไลบรารี sarama ([] github.com/Shopify/sarama) เพื่อส่งข้อความไปยังคลัสเตอร์คาฟคา เราตั้งค่าการตั้งค่าโดยมุ่งเป้าไปที่ความเร็วการประมวลผลสูงสุดทันที:

config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForLocal
config.Producer.Compression = sarama.CompressionSnappy
config.Producer.Return.Successes = true

3. แอปพลิเคชันของเรายังมีไคลเอนต์ Prometheus ในตัว ซึ่งรวบรวมการวัดต่างๆ เช่น:

  • จำนวนคำขอในใบสมัครของเรา
  • จำนวนข้อผิดพลาดเมื่อดำเนินการตามคำขอ (ไม่สามารถอ่านคำขอโพสต์, json ที่เสียหาย, ไม่สามารถเขียนถึง Kafka ได้)
  • เวลาในการประมวลผลสำหรับคำขอหนึ่งรายการจากไคลเอนต์ รวมถึงเวลาในการเขียนข้อความถึง Kafka

4. จุดสิ้นสุดสามจุดที่แอปพลิเคชันของเราประมวลผล:

  • /status - เพียงส่งคืน ok เพื่อแสดงว่าเรายังมีชีวิตอยู่ แม้ว่าคุณจะสามารถเพิ่มการตรวจสอบบางอย่างได้ เช่น ความพร้อมใช้งานของคลัสเตอร์ Kafka
  • /metrics - ตาม URL นี้ ลูกค้า Prometheus จะส่งคืนตัววัดที่รวบรวมไว้
  • /post เป็นจุดสิ้นสุดหลักที่คำขอ POST ที่มี json ภายในจะถูกส่งไป แอปพลิเคชันของเราจะตรวจสอบความถูกต้องของ json และหากทุกอย่างเรียบร้อยดี แอปพลิเคชันจะเขียนข้อมูลไปยังคลัสเตอร์ Kafka

ฉันจะจองว่ารหัสไม่สมบูรณ์ - สามารถ (และควร!) เสร็จสมบูรณ์ ตัวอย่างเช่น คุณสามารถหยุดใช้ net/http ในตัวแล้วเปลี่ยนไปใช้ fasthttp ที่เร็วกว่าได้ หรือคุณสามารถรับเวลาในการประมวลผลและทรัพยากร cpu ได้โดยการย้ายการตรวจสอบความถูกต้องของ json ไปยังขั้นตอนภายหลัง - เมื่อข้อมูลจากบัฟเฟอร์ไปยังคลัสเตอร์คลิกเฮาส์

นอกเหนือจากด้านการพัฒนาของปัญหาแล้ว เรายังคิดถึงโครงสร้างพื้นฐานในอนาคตของเราทันที และตัดสินใจปรับใช้แอปพลิเคชันของเราผ่านนักเทียบท่า Dockerfile สุดท้ายสำหรับการสร้างแอปพลิเคชันคือ https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. โดยทั่วไปแล้ว มันค่อนข้างง่าย จุดเดียวที่ผมอยากใส่ใจคือการประกอบแบบหลายขั้นตอน ซึ่งช่วยให้เราลดขนาดภาพสุดท้ายของคอนเทนเนอร์ของเราได้

ก้าวแรกในระบบคลาวด์

ก่อนอื่นให้ลงทะเบียนที่ cloud.yandex.ru. หลังจากกรอกข้อมูลในช่องที่จำเป็นทั้งหมดแล้ว เราจะสร้างบัญชีและได้รับเงินช่วยเหลือจำนวนหนึ่ง ซึ่งสามารถนำไปใช้ทดสอบบริการคลาวด์ได้ หากคุณต้องการทำซ้ำขั้นตอนทั้งหมดจากบทความของเรา เงินช่วยเหลือนี้น่าจะเพียงพอสำหรับคุณ

หลังจากการลงทะเบียน ระบบจะสร้างคลาวด์แยกต่างหากและไดเร็กทอรีเริ่มต้นสำหรับคุณ ซึ่งคุณสามารถเริ่มสร้างทรัพยากรคลาวด์ได้ โดยทั่วไปใน Yandex.Cloud ความสัมพันธ์ของทรัพยากรจะเป็นดังนี้:

เรายอมรับ 10 กิจกรรมใน Yandex.Cloud ส่วนที่ 000

คุณสามารถสร้างคลาวด์หลายอันสำหรับบัญชีเดียว และภายในระบบคลาวด์ สร้างไดเร็กทอรีที่แตกต่างกันสำหรับโปรเจ็กต์ของบริษัทต่างๆ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับสิ่งนี้ได้ในเอกสารประกอบ - https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. โดยวิธีการที่ฉันมักจะอ้างถึงมันด้านล่างในข้อความ เมื่อฉันตั้งค่าโครงสร้างพื้นฐานทั้งหมดตั้งแต่เริ่มต้น เอกสารช่วยฉันได้มากกว่าหนึ่งครั้ง ดังนั้นฉันขอแนะนำให้คุณศึกษามัน

ในการจัดการคลาวด์ คุณสามารถใช้ทั้งเว็บอินเตอร์เฟสและยูทิลิตี้คอนโซล - yc การติดตั้งทำได้ด้วยคำสั่งเดียว (สำหรับ Linux และ Mac Os):

curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash

หากผู้เชี่ยวชาญด้านความปลอดภัยภายในของคุณกำลังเดือดดาลเกี่ยวกับการเรียกใช้สคริปต์จากอินเทอร์เน็ต ประการแรก คุณสามารถเปิดสคริปต์และอ่านได้ และประการที่สอง เราจะเรียกใช้สคริปต์ภายใต้ผู้ใช้ของเรา โดยไม่มีสิทธิ์รูท

หากคุณต้องการติดตั้งไคลเอนต์สำหรับ Windows คุณสามารถใช้คำแนะนำได้ ที่นี่ แล้วดำเนินการ yc initเพื่อปรับแต่งอย่างเต็มที่:

vozerov@mba:~ $ yc init
Welcome! This command will take you through the configuration process.
Please go to https://oauth.yandex.ru/authorize?response_type=token&client_id= in order to obtain OAuth token.

Please enter OAuth token:
Please select cloud to use:
 [1] cloud-b1gv67ihgfu3bp (id = b1gv67ihgfu3bpt24o0q)
 [2] fevlake-cloud (id = b1g6bvup3toribomnh30)
Please enter your numeric choice: 2
Your current cloud has been set to 'fevlake-cloud' (id = b1g6bvup3toribomnh30).
Please choose folder to use:
 [1] default (id = b1g5r6h11knotfr8vjp7)
 [2] Create a new folder
Please enter your numeric choice: 1
Your current folder has been set to 'default' (id = b1g5r6h11knotfr8vjp7).
Do you want to configure a default Compute zone? [Y/n]
Which zone do you want to use as a profile default?
 [1] ru-central1-a
 [2] ru-central1-b
 [3] ru-central1-c
 [4] Don't set default zone
Please enter your numeric choice: 1
Your profile default Compute zone has been set to 'ru-central1-a'.
vozerov@mba:~ $

โดยหลักการแล้ว กระบวนการนี้ง่ายมาก ขั้นแรกคุณต้องได้รับโทเค็น oauth เพื่อจัดการคลาวด์ เลือกคลาวด์และโฟลเดอร์ที่คุณจะใช้

หากคุณมีบัญชีหรือโฟลเดอร์หลายบัญชีภายในคลาวด์เดียวกัน คุณสามารถสร้างโปรไฟล์เพิ่มเติมด้วยการตั้งค่าแยกกันผ่านการสร้างโปรไฟล์ yc config และสลับระหว่างโปรไฟล์เหล่านั้น

นอกเหนือจากวิธีการข้างต้นแล้ว ทีมงาน Yandex.Cloud ยังเขียนได้ดีมาก ปลั๊กอินสำหรับ Terraform สำหรับการจัดการทรัพยากรคลาวด์ ในส่วนของฉัน ฉันได้เตรียมพื้นที่เก็บข้อมูล git ซึ่งฉันได้อธิบายทรัพยากรทั้งหมดที่จะถูกสร้างขึ้นโดยเป็นส่วนหนึ่งของบทความ - https://github.com/rebrainme/yandex-cloud-events/. เราสนใจสาขาหลัก มาโคลนมันในเครื่องกันดีกว่า:


vozerov@mba:~ $ git clone https://github.com/rebrainme/yandex-cloud-events/ events
Cloning into 'events'...
remote: Enumerating objects: 100, done.
remote: Counting objects: 100% (100/100), done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 100 (delta 37), reused 89 (delta 26), pack-reused 0
Receiving objects: 100% (100/100), 25.65 KiB | 168.00 KiB/s, done.
Resolving deltas: 100% (37/37), done.
vozerov@mba:~ $ cd events/terraform/

ตัวแปรหลักทั้งหมดที่ใช้ใน Terraform จะถูกเขียนในไฟล์ main.tf ในการเริ่มต้น ให้สร้างไฟล์ private.auto.tfvars ในโฟลเดอร์ terraform โดยมีเนื้อหาดังต่อไปนี้:

# Yandex Cloud Oauth token
yc_token = ""
# Yandex Cloud ID
yc_cloud_id = ""
# Yandex Cloud folder ID
yc_folder_id = ""
# Default Yandex Cloud Region
yc_region = "ru-central1-a"
# Cloudflare email
cf_email = ""
# Cloudflare token
cf_token = ""
# Cloudflare zone id
cf_zone_id = ""

ตัวแปรทั้งหมดสามารถนำมาจากรายการกำหนดค่า yc เนื่องจากเราได้กำหนดค่ายูทิลิตี้คอนโซลแล้ว ฉันแนะนำให้คุณเพิ่ม private.auto.tfvars ใน .gitignore ทันที เพื่อไม่ให้ข้อมูลส่วนตัวถูกเผยแพร่โดยไม่ได้ตั้งใจ

ใน private.auto.tfvars เรายังระบุข้อมูลจาก Cloudflare เพื่อสร้างบันทึก DNS และพร็อกซีโดเมนหลัก events.kis.im ไปยังเซิร์ฟเวอร์ของเรา หากคุณไม่ต้องการใช้ cloudflare ให้ลบการเริ่มต้นของผู้ให้บริการ cloudflare ใน main.tf และไฟล์ dns.tf ซึ่งมีหน้าที่สร้างบันทึก DNS ที่จำเป็น

ในงานของเรา เราจะรวมวิธีการทั้งสามวิธีเข้าด้วยกัน - เว็บอินเตอร์เฟส, ยูทิลิตี้คอนโซล และ เทอร์ราฟอร์ม

เครือข่ายเสมือน

พูดตามตรง คุณสามารถข้ามขั้นตอนนี้ได้ เนื่องจากเมื่อคุณสร้างคลาวด์ใหม่ คุณจะมีเครือข่ายแยกกันและสร้างเครือข่ายย่อย 3 รายการโดยอัตโนมัติ - หนึ่งเครือข่ายสำหรับแต่ละโซนความพร้อมใช้งาน แต่เรายังคงต้องการสร้างเครือข่ายแยกต่างหากสำหรับโครงการของเราโดยมีที่อยู่ของตัวเอง แผนภาพทั่วไปของวิธีการทำงานของเครือข่ายใน Yandex.Cloud แสดงในรูปด้านล่าง (นำมาโดยสุจริต) https://cloud.yandex.ru/docs/vpc/concepts/)

เรายอมรับ 10 กิจกรรมใน Yandex.Cloud ส่วนที่ 000

ดังนั้นคุณจึงสร้างเครือข่ายทั่วไปที่ทรัพยากรสามารถสื่อสารระหว่างกันได้ สำหรับแต่ละโซนความพร้อมใช้งาน ซับเน็ตจะถูกสร้างขึ้นพร้อมที่อยู่ของตัวเองและเชื่อมต่อกับเครือข่ายทั่วไป เป็นผลให้ทรัพยากรคลาวด์ทั้งหมดในนั้นสามารถสื่อสารได้ แม้ว่าจะอยู่ในโซนความพร้อมใช้งานที่แตกต่างกันก็ตาม ทรัพยากรที่เชื่อมต่อกับเครือข่ายคลาวด์ที่แตกต่างกันสามารถเห็นกันได้ผ่านที่อยู่ภายนอกเท่านั้น อย่างไรก็ตาม เวทมนตร์นี้ทำงานข้างในได้อย่างไร ได้รับการอธิบายอย่างดีเกี่ยวกับHabré.

การสร้างเครือข่ายอธิบายไว้ในไฟล์ network.tf จากพื้นที่เก็บข้อมูล ที่นั่นเราสร้างเครือข่ายส่วนตัวทั่วไปหนึ่งเครือข่ายภายในและเชื่อมต่อเครือข่ายย่อยสามเครือข่ายเข้ากับเครือข่ายย่อยในโซนความพร้อมใช้งานที่แตกต่างกัน - Internal-a (172.16.1.0/24), Internal-b (172.16.2.0/24), Internal-c (172.16.3.0/24 ).

เริ่มต้น Terraform และสร้างเครือข่าย:

vozerov@mba:~/events/terraform (master) $ terraform init
... skipped ..

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_vpc_subnet.internal-a -target yandex_vpc_subnet.internal-b -target yandex_vpc_subnet.internal-c

... skipped ...

Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

yandex_vpc_network.internal: Creating...
yandex_vpc_network.internal: Creation complete after 3s [id=enp2g2rhile7gbqlbrkr]
yandex_vpc_subnet.internal-a: Creating...
yandex_vpc_subnet.internal-b: Creating...
yandex_vpc_subnet.internal-c: Creating...
yandex_vpc_subnet.internal-a: Creation complete after 6s [id=e9b1dad6mgoj2v4funog]
yandex_vpc_subnet.internal-b: Creation complete after 7s [id=e2liv5i4amu52p64ac9p]
yandex_vpc_subnet.internal-c: Still creating... [10s elapsed]
yandex_vpc_subnet.internal-c: Creation complete after 10s [id=b0c2qhsj2vranoc9vhcq]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

ยอดเยี่ยม! เราได้สร้างเครือข่ายของเราแล้ว และตอนนี้ก็พร้อมที่จะสร้างบริการภายในของเราแล้ว

การสร้างเครื่องเสมือน

ในการทดสอบแอปพลิเคชัน เราจะต้องสร้างเครื่องเสมือนสองเครื่องเท่านั้น - เราจะต้องมีเครื่องแรกเพื่อสร้างและรันแอปพลิเคชัน เครื่องที่สองสำหรับเรียกใช้ kafka ซึ่งเราจะใช้เพื่อจัดเก็บข้อความขาเข้า และเราจะสร้างเครื่องอีกเครื่องหนึ่งที่เราจะกำหนดค่า Prometheus เพื่อตรวจสอบแอปพลิเคชัน

เครื่องเสมือนจะได้รับการกำหนดค่าโดยใช้ ansible ดังนั้นก่อนที่จะเริ่ม Terraform ตรวจสอบให้แน่ใจว่าคุณมี ansible เวอร์ชันล่าสุด และติดตั้งบทบาทที่จำเป็นกับกาแล็กซีที่มองเห็นได้:

vozerov@mba:~/events/terraform (master) $ cd ../ansible/
vozerov@mba:~/events/ansible (master) $ ansible-galaxy install -r requirements.yml
- cloudalchemy-prometheus (master) is already installed, skipping.
- cloudalchemy-grafana (master) is already installed, skipping.
- sansible.kafka (master) is already installed, skipping.
- sansible.zookeeper (master) is already installed, skipping.
- geerlingguy.docker (master) is already installed, skipping.
vozerov@mba:~/events/ansible (master) $

ภายในโฟลเดอร์ ansible มีตัวอย่างไฟล์การกำหนดค่า .ansible.cfg ที่ฉันใช้ มันอาจจะมีประโยชน์

ก่อนสร้างเครื่องเสมือน ตรวจสอบให้แน่ใจว่าคุณใช้งาน ssh-agent และเพิ่มคีย์ ssh ไม่เช่นนั้น terraform จะไม่สามารถเชื่อมต่อกับเครื่องที่สร้างขึ้นได้ แน่นอนฉันเจอข้อผิดพลาดใน os x: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. เพื่อป้องกันไม่ให้สิ่งนี้เกิดขึ้นอีก ให้เพิ่มตัวแปรเล็กๆ ให้กับ env ก่อนเปิดตัว Terraform:

vozerov@mba:~/events/terraform (master) $ export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

ในโฟลเดอร์ที่มี Terraform เราสร้างทรัพยากรที่จำเป็น:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_compute_instance.build -target yandex_compute_instance.monitoring -target yandex_compute_instance.kafka
yandex_vpc_network.internal: Refreshing state... [id=enp2g2rhile7gbqlbrkr]
data.yandex_compute_image.ubuntu_image: Refreshing state...
yandex_vpc_subnet.internal-a: Refreshing state... [id=e9b1dad6mgoj2v4funog]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

... skipped ...

Plan: 3 to add, 0 to change, 0 to destroy.

... skipped ...

หากทุกอย่างจบลงได้สำเร็จ (และควรจะเป็นเช่นนั้น) เราจะมีเครื่องเสมือนสามเครื่อง:

  1. build - เครื่องจักรสำหรับการทดสอบและสร้างแอปพลิเคชัน Docker ได้รับการติดตั้งโดยอัตโนมัติโดย Ansible
  2. การตรวจสอบ - เครื่องตรวจสอบ - โพรและกราฟาน่าติดตั้งอยู่ มาตรฐานการเข้าสู่ระบบ / รหัสผ่าน: ผู้ดูแลระบบ / ผู้ดูแลระบบ
  3. kafka เป็นเครื่องจักรขนาดเล็กที่ติดตั้ง kafka เข้าถึงได้จากพอร์ต 9092

ตรวจสอบให้แน่ใจว่าพวกเขาทั้งหมดเข้าที่แล้ว:

vozerov@mba:~/events (master) $ yc compute instance list
+----------------------+------------+---------------+---------+---------------+-------------+
|          ID          |    NAME    |    ZONE ID    | STATUS  |  EXTERNAL IP  | INTERNAL IP |
+----------------------+------------+---------------+---------+---------------+-------------+
| fhm081u8bkbqf1pa5kgj | monitoring | ru-central1-a | RUNNING | 84.201.159.71 | 172.16.1.35 |
| fhmf37k03oobgu9jmd7p | kafka      | ru-central1-a | RUNNING | 84.201.173.41 | 172.16.1.31 |
| fhmt9pl1i8sf7ga6flgp | build      | ru-central1-a | RUNNING | 84.201.132.3  | 172.16.1.26 |
+----------------------+------------+---------------+---------+---------------+-------------+

มีทรัพยากรอยู่แล้ว และจากที่นี่เราจะได้รับที่อยู่ IP ของพวกเขา ตลอดสิ่งต่อไปนี้ ฉันจะใช้ที่อยู่ IP เพื่อเชื่อมต่อผ่าน ssh และทดสอบแอปพลิเคชัน หากคุณมีบัญชี Cloudflare ที่เชื่อมต่อกับ Terraform คุณสามารถใช้ชื่อ DNS ที่สร้างขึ้นใหม่ได้ตามต้องการ
อย่างไรก็ตาม เมื่อสร้างเครื่องเสมือน จะมีการกำหนด IP ภายในและชื่อ DNS ภายใน เพื่อให้คุณสามารถเข้าถึงเซิร์ฟเวอร์ภายในเครือข่ายตามชื่อ:

ubuntu@build:~$ ping kafka.ru-central1.internal
PING kafka.ru-central1.internal (172.16.1.31) 56(84) bytes of data.
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=1 ttl=63 time=1.23 ms
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=2 ttl=63 time=0.625 ms
^C
--- kafka.ru-central1.internal ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.625/0.931/1.238/0.308 ms

สิ่งนี้จะมีประโยชน์สำหรับเราในการระบุจุดสิ้นสุดด้วย kafk ให้กับแอปพลิเคชัน

การประกอบแอพพลิเคชั่น

เยี่ยมมาก มีเซิร์ฟเวอร์ มีแอปพลิเคชัน สิ่งที่เหลืออยู่คือการประกอบและเผยแพร่ สำหรับบิลด์เราจะใช้บิลด์นักเทียบท่าตามปกติ แต่เราจะใช้บริการจาก Yandex - คอนเทนเนอร์รีจิสตรีในฐานะที่เก็บรูปภาพ แต่สิ่งแรกก่อน

เราคัดลอกแอปพลิเคชันไปยังเครื่อง build เข้าสู่ระบบผ่าน ssh และประกอบอิมเมจ:

vozerov@mba:~/events/terraform (master) $ cd ..
vozerov@mba:~/events (master) $ rsync -av app/ [email protected]:app/

... skipped ...

sent 3849 bytes  received 70 bytes  7838.00 bytes/sec
total size is 3644  speedup is 0.93

vozerov@mba:~/events (master) $ ssh 84.201.132.3 -l ubuntu
ubuntu@build:~$ cd app
ubuntu@build:~/app$ sudo docker build -t app .
Sending build context to Docker daemon  6.144kB
Step 1/9 : FROM golang:latest AS build
... skipped ...

Successfully built 9760afd8ef65
Successfully tagged app:latest

เสร็จสิ้นไปแล้วครึ่งหนึ่งของการต่อสู้ - ตอนนี้เราสามารถตรวจสอบฟังก์ชันการทำงานของแอปพลิเคชันของเราได้โดยเปิดใช้งานและส่งไปที่คาฟคา:

ubuntu@build:~/app$ sudo docker run --name app -d -p 8080:8080 app /app/app -kafka=kafka.ru-central1.internal:9092</code>

С локальной машинки можно отправить тестовый event и посмотреть на ответ:

<code>vozerov@mba:~/events (master) $ curl -D - -s -X POST -d '{"key1":"data1"}' http://84.201.132.3:8080/post
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 13 Apr 2020 13:53:54 GMT
Content-Length: 41

{"status":"ok","partition":0,"Offset":0}
vozerov@mba:~/events (master) $

แอปพลิเคชันตอบสนองความสำเร็จในการบันทึกและระบุ id ของพาร์ติชันและออฟเซ็ตที่มีข้อความรวมอยู่ด้วย สิ่งที่คุณต้องทำคือสร้างรีจิสทรีใน Yandex.Cloud และอัปโหลดรูปภาพของเราที่นั่น (วิธีดำเนินการโดยใช้สามบรรทัดอธิบายไว้ในไฟล์ Registry.tf) สร้างที่เก็บข้อมูล:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_container_registry.events

... skipped ...

Plan: 1 to add, 0 to change, 0 to destroy.

... skipped ...

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

มีหลายวิธีในการตรวจสอบสิทธิ์ในรีจีสทรีคอนเทนเนอร์ โดยใช้โทเค็น oauth โทเค็น iam หรือคีย์บัญชีบริการ รายละเอียดเพิ่มเติมเกี่ยวกับวิธีการเหล่านี้สามารถพบได้ในเอกสารประกอบ https://cloud.yandex.ru/docs/container-registry/operations/authentication. เราจะใช้รหัสบัญชีบริการ ดังนั้นเราจึงสร้างบัญชี:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_iam_service_account.docker -target yandex_resourcemanager_folder_iam_binding.puller -target yandex_resourcemanager_folder_iam_binding.pusher

... skipped ...

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

ตอนนี้สิ่งที่เหลืออยู่คือการสร้างกุญแจสำหรับมัน:

vozerov@mba:~/events/terraform (master) $ yc iam key create --service-account-name docker -o key.json
id: ajej8a06kdfbehbrh91p
service_account_id: ajep6d38k895srp9osij
created_at: "2020-04-13T14:00:30Z"
key_algorithm: RSA_2048

เราได้รับข้อมูลเกี่ยวกับรหัสพื้นที่เก็บข้อมูลของเรา ถ่ายโอนคีย์ และเข้าสู่ระบบ:

vozerov@mba:~/events/terraform (master) $ scp key.json [email protected]:
key.json                                                                                                                    100% 2392   215.1KB/s   00:00

vozerov@mba:~/events/terraform (master) $ ssh 84.201.132.3 -l ubuntu

ubuntu@build:~$ cat key.json | sudo docker login --username json_key --password-stdin cr.yandex
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
ubuntu@build:~$

ในการอัปโหลดรูปภาพไปยังรีจิสตรี เราจำเป็นต้องมีรหัสรีจิสตรีของคอนเทนเนอร์ โดยนำมาจากยูทิลิตี้ yc:

vozerov@mba:~ $ yc container registry get events
id: crpdgj6c9umdhgaqjfmm
folder_id:
name: events
status: ACTIVE
created_at: "2020-04-13T13:56:41.914Z"

หลังจากนั้น เราจะแท็กรูปภาพของเราด้วยชื่อใหม่ และอัปโหลด:

ubuntu@build:~$ sudo docker tag app cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
ubuntu@build:~$ sudo docker push cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
The push refers to repository [cr.yandex/crpdgj6c9umdhgaqjfmm/events]
8c286e154c6e: Pushed
477c318b05cb: Pushed
beee9f30bc1f: Pushed
v1: digest: sha256:1dd5aaa9dbdde2f60d833be0bed1c352724be3ea3158bcac3cdee41d47c5e380 size: 946

เราสามารถตรวจสอบได้ว่าโหลดรูปภาพสำเร็จแล้ว:

vozerov@mba:~/events/terraform (master) $ yc container repository list
+----------------------+-----------------------------+
|          ID          |            NAME             |
+----------------------+-----------------------------+
| crpe8mqtrgmuq07accvn | crpdgj6c9umdhgaqjfmm/events |
+----------------------+-----------------------------+

อย่างไรก็ตาม หากคุณติดตั้งยูทิลิตี้ yc บนเครื่อง Linux คุณสามารถใช้คำสั่งได้

yc container registry configure-docker

เพื่อกำหนดค่านักเทียบท่า

ข้อสรุป

เราได้ทำงานหนักมามาก และผลที่ตามมาก็คือ:

  1. เรามาพร้อมกับสถาปัตยกรรมของบริการในอนาคตของเรา
  2. เราเขียนแอปพลิเคชันใน golang ที่ใช้ตรรกะทางธุรกิจของเรา
  3. เรารวบรวมมันและเทลงในรีจิสตรีคอนเทนเนอร์ส่วนตัว

ในส่วนถัดไป เราจะไปยังสิ่งที่น่าสนใจ - เราจะเผยแพร่แอปพลิเคชันของเราไปสู่การใช้งานจริง และสุดท้ายคือการเปิดตัวโหลดในนั้น อย่าเปลี่ยน!

เนื้อหานี้อยู่ในการบันทึกวิดีโอของเวิร์กช็อปแบบเปิด REBRAIN & Yandex.Cloud: เรายอมรับ 10 คำขอต่อวินาทีบน Yandex Cloud - https://youtu.be/cZLezUm0ekE

หากคุณสนใจเข้าร่วมกิจกรรมดังกล่าวทางออนไลน์และถามคำถามแบบเรียลไทม์ สามารถติดต่อได้ที่ ช่อง DevOps โดย REBRAIN.

เราขอขอบคุณ Yandex.Cloud เป็นพิเศษสำหรับโอกาสในการจัดกิจกรรมดังกล่าว เชื่อมโยงไปยังพวกเขา - https://cloud.yandex.ru/prices

หากคุณต้องการย้ายไปยังระบบคลาวด์หรือมีคำถามเกี่ยวกับโครงสร้างพื้นฐานของคุณ รู้สึกอิสระที่จะออกคำขอ.

ป.ล. เรามีการตรวจสอบฟรี 2 ครั้งต่อเดือน บางทีโครงการของคุณอาจเป็นหนึ่งในนั้น

ที่มา: will.com

เพิ่มความคิดเห็น