Chúng tôi chấp nhận 10 sự kiện trong Yandex.Cloud. Phần 000

Xin chào tất cả mọi người, các bạn!

* Bài viết này dựa trên hội thảo mở REBRAIN & Yandex.Cloud, nếu bạn thích xem video, bạn có thể tìm thấy video tại liên kết này - https://youtu.be/cZLezUm0ekE

Gần đây chúng tôi đã có cơ hội dùng thử Yandex.Cloud trực tiếp. Vì muốn tìm hiểu lâu dài và chăm chỉ nên chúng tôi ngay lập tức từ bỏ ý định ra mắt một blog WordPress đơn giản trên nền tảng đám mây - nó quá nhàm chán. Sau khi suy nghĩ, chúng tôi quyết định triển khai một cái gì đó tương tự như kiến ​​trúc dịch vụ sản xuất để nhận và phân tích các sự kiện ở chế độ gần thời gian thực.

Tôi hoàn toàn chắc chắn rằng phần lớn các doanh nghiệp trực tuyến (và không chỉ) bằng cách nào đó thu thập được hàng núi thông tin về người dùng và hành động của họ. Ở mức tối thiểu, điều này là cần thiết để đưa ra một số quyết định nhất định - ví dụ: nếu bạn quản lý một trò chơi trực tuyến, bạn có thể xem số liệu thống kê ở cấp độ nào người dùng thường gặp khó khăn nhất và xóa đồ chơi của bạn. Hoặc tại sao người dùng rời khỏi trang web của bạn mà không mua bất cứ thứ gì (xin chào, Yandex.Metrica).

Vì vậy, câu chuyện của chúng tôi: cách chúng tôi viết một ứng dụng bằng golang, thử nghiệm kafka, rabbitmq và yqs, viết luồng dữ liệu trong cụm Clickhouse và trực quan hóa dữ liệu bằng cách sử dụng dữ liệu yandex. Đương nhiên, tất cả những điều này đã được bổ sung thêm những thú vui về cơ sở hạ tầng dưới dạng docker, terraform, gitlab ci và tất nhiên là prometheus. Đi nào!

Tôi muốn đặt trước ngay rằng chúng tôi sẽ không thể định cấu hình mọi thứ trong một lần ngồi - để làm được điều này, chúng tôi sẽ cần một số bài viết trong loạt bài này. Một chút về cấu trúc:

Phần 1 (bạn đang đọc nó). Chúng tôi sẽ quyết định các thông số kỹ thuật và kiến ​​trúc của giải pháp, đồng thời viết một ứng dụng bằng golang.
Phần 2. Chúng tôi phát hành ứng dụng của mình vào sản xuất, giúp ứng dụng có thể mở rộng và kiểm tra tải.
Phần 3. Hãy thử tìm hiểu lý do tại sao chúng ta cần lưu trữ thư trong bộ đệm chứ không phải trong tệp, đồng thời so sánh dịch vụ hàng đợi kafka, rabbitmq và yandex.
Phần 4 Chúng tôi sẽ triển khai cụm Clickhouse, viết dịch vụ phát trực tuyến để truyền dữ liệu từ bộ đệm ở đó và thiết lập trực quan hóa trong các cơ sở dữ liệu.
Phần 5 Hãy đưa toàn bộ cơ sở hạ tầng vào trạng thái phù hợp - thiết lập ci/cd bằng gitlab ci, kết nối giám sát và khám phá dịch vụ bằng prometheus và lãnh sự.

TK

Trước tiên, hãy xây dựng các điều khoản tham chiếu - kết quả chính xác là chúng ta muốn nhận được điều gì.

  1. Chúng tôi muốn có một điểm cuối như events.kis.im (kis.im là miền thử nghiệm mà chúng tôi sẽ sử dụng trong tất cả các bài viết), điểm cuối này sẽ nhận các sự kiện bằng HTTPS.
  2. Sự kiện là một json đơn giản như: {“event”: “view”, “os”: “linux”, “browser”: “chrome”}. Ở giai đoạn cuối, chúng tôi sẽ thêm một số trường nữa, nhưng điều này sẽ không đóng vai trò lớn. Nếu muốn, bạn có thể chuyển sang protobuf.
  3. Dịch vụ phải có khả năng xử lý 10 sự kiện mỗi giây.
  4. Có thể mở rộng quy mô theo chiều ngang bằng cách thêm các phiên bản mới vào giải pháp của chúng tôi. Và sẽ thật tuyệt nếu chúng ta có thể di chuyển phần trước sang các vị trí địa lý khác nhau để giảm độ trễ cho các yêu cầu của khách hàng.
  5. Khả năng chịu lỗi. Giải pháp phải đủ ổn định và có thể chịu được khi rơi bất kỳ bộ phận nào (tất nhiên là lên đến một con số nhất định).

kiến trúc

Nhìn chung, đối với loại nhiệm vụ này, các kiến ​​trúc cổ điển đã được phát minh từ lâu để cho phép mở rộng quy mô một cách hiệu quả. Hình này cho thấy một ví dụ về giải pháp của chúng tôi.

Chúng tôi chấp nhận 10 sự kiện trong Yandex.Cloud. Phần 000

Vì vậy, những gì chúng tôi có:

1. Bên trái là các thiết bị của chúng tôi tạo ra nhiều sự kiện khác nhau, có thể là người chơi hoàn thành cấp độ trong đồ chơi trên điện thoại thông minh hoặc tạo đơn đặt hàng trong cửa hàng trực tuyến thông qua trình duyệt thông thường. Một sự kiện, như được chỉ định trong đặc tả, là một json đơn giản được gửi đến điểm cuối của chúng tôi - events.kis.im.

2. Hai máy chủ đầu tiên là những máy cân bằng đơn giản, nhiệm vụ chính của chúng là:

  • Hãy luôn sẵn sàng. Để thực hiện việc này, bạn có thể sử dụng, ví dụ: keepaliving, tính năng này sẽ chuyển đổi IP ảo giữa các nút trong trường hợp có sự cố.
  • Chấm dứt TLS. Có, chúng tôi sẽ chấm dứt TLS đối với họ. Thứ nhất, để giải pháp của chúng tôi tuân thủ các thông số kỹ thuật và thứ hai, để giảm bớt gánh nặng thiết lập kết nối được mã hóa từ các máy chủ phụ trợ của chúng tôi.
  • Cân bằng các yêu cầu đến với các máy chủ phụ trợ có sẵn. Từ khóa ở đây có thể truy cập được. Dựa trên điều này, chúng tôi hiểu rằng bộ cân bằng tải phải có khả năng giám sát các máy chủ của chúng tôi bằng các ứng dụng và ngừng cân bằng lưu lượng truy cập đến các nút bị lỗi.

3. Sau bộ cân bằng, chúng ta có các máy chủ ứng dụng chạy một ứng dụng khá đơn giản. Nó có thể chấp nhận các yêu cầu đến qua HTTP, xác thực json đã gửi và đưa dữ liệu vào bộ đệm.

4. Sơ đồ hiển thị kafka như một bộ đệm, mặc dù tất nhiên, các dịch vụ tương tự khác có thể được sử dụng ở cấp độ này. Chúng ta sẽ so sánh Kafka, rabbitmq và yqs trong bài viết thứ ba.

5. Điểm áp chót trong kiến ​​trúc của chúng tôi là Clickhouse - cơ sở dữ liệu dạng cột cho phép bạn lưu trữ và xử lý một lượng dữ liệu khổng lồ. Ở cấp độ này, chúng ta cần chuyển dữ liệu từ bộ đệm sang chính hệ thống lưu trữ (xem thêm về điều này trong bài viết 4).

Thiết kế này cho phép chúng tôi chia tỷ lệ từng lớp một cách độc lập theo chiều ngang. Máy chủ phụ trợ không thể đối phó - hãy thêm một điều nữa - xét cho cùng, chúng là các ứng dụng không trạng thái và do đó, việc này thậm chí có thể được thực hiện tự động. Bộ đệm kiểu Kafka không hoạt động — hãy thêm nhiều máy chủ hơn và chuyển một số phân vùng trong chủ đề của chúng ta sang chúng. Clickhouse không thể xử lý được việc đó - điều đó là không thể :) Trên thực tế, chúng tôi cũng sẽ kết nối các máy chủ và phân chia dữ liệu.

Nhân tiện, nếu bạn muốn triển khai phần tùy chọn trong thông số kỹ thuật và tỷ lệ của chúng tôi ở các vị trí địa lý khác nhau, thì không có gì đơn giản hơn:

Chúng tôi chấp nhận 10 sự kiện trong Yandex.Cloud. Phần 000

Trong mỗi vị trí địa lý, chúng tôi triển khai bộ cân bằng tải với ứng dụng và kafka. Nói chung, 2 máy chủ ứng dụng, 3 nút kafka và bộ cân bằng đám mây, chẳng hạn như cloudflare, là đủ, nó sẽ kiểm tra tính khả dụng của các nút ứng dụng và cân bằng các yêu cầu theo vị trí địa lý dựa trên địa chỉ IP nguồn của khách hàng. Do đó, dữ liệu do khách hàng Mỹ gửi sẽ đến máy chủ của Mỹ. Và dữ liệu từ Châu Phi là ở Châu Phi.

Sau đó, mọi thứ khá đơn giản - chúng tôi sử dụng công cụ nhân bản từ bộ Kafka và sao chép tất cả dữ liệu từ tất cả các vị trí đến trung tâm dữ liệu trung tâm của chúng tôi đặt tại Nga. Trong nội bộ, chúng tôi phân tích dữ liệu và ghi lại dữ liệu đó trong Clickhouse để hiển thị sau này.

Vì vậy, chúng tôi đã sắp xếp xong kiến ​​​​trúc - hãy bắt đầu lắc Yandex.Cloud!

Viết một ứng dụng

Trước Cloud, bạn vẫn phải kiên nhẫn một chút và viết một dịch vụ khá đơn giản để xử lý các sự kiện đến. Chúng tôi sẽ sử dụng golang vì nó đã được chứng minh là ngôn ngữ viết ứng dụng mạng rất tốt.

Sau khi dành một giờ (có thể là vài giờ), chúng tôi nhận được kết quả như thế này: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

Những điểm chính tôi muốn lưu ý ở đây là gì:

1. Khi khởi động ứng dụng, bạn có thể chỉ định hai cờ. Một người chịu trách nhiệm về cổng mà chúng tôi sẽ lắng nghe các yêu cầu http đến (-addr). Thứ hai là địa chỉ máy chủ kafka nơi chúng tôi sẽ ghi lại các sự kiện của mình (-kafka):

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

2. Ứng dụng sử dụng thư viện sarama ([] github.com/Shopify/sarama) để gửi tin nhắn đến cụm kafka. Chúng tôi ngay lập tức thiết lập các cài đặt nhằm đạt tốc độ xử lý tối đa:

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

3. Ứng dụng của chúng tôi cũng có ứng dụng khách prometheus tích hợp, thu thập nhiều số liệu khác nhau, chẳng hạn như:

  • số lượng yêu cầu đối với ứng dụng của chúng tôi;
  • số lỗi khi thực hiện yêu cầu (không đọc được yêu cầu bài viết, json bị hỏng, không thể ghi vào Kafka);
  • thời gian xử lý một yêu cầu từ client, bao gồm cả thời gian viết tin nhắn cho Kafka.

4. Ba điểm cuối mà ứng dụng của chúng tôi xử lý:

  • /status - chỉ cần trả về ok để chứng tỏ rằng chúng ta còn sống. Mặc dù bạn có thể thêm một số kiểm tra, chẳng hạn như tính khả dụng của cụm Kafka.
  • /metrics - theo url này, ứng dụng khách prometheus sẽ trả về số liệu mà nó đã thu thập.
  • /post là điểm cuối chính nơi các yêu cầu POST có json bên trong sẽ được gửi. Ứng dụng của chúng tôi kiểm tra tính hợp lệ của json và nếu mọi thứ đều ổn, nó sẽ ghi dữ liệu vào cụm Kafka.

Tôi sẽ bảo đảm rằng mã không hoàn hảo - nó có thể (và nên!) được hoàn thành. Ví dụ: bạn có thể ngừng sử dụng mạng/http tích hợp sẵn và chuyển sang fasthttp nhanh hơn. Hoặc bạn có thể đạt được thời gian xử lý và tài nguyên CPU bằng cách chuyển kiểm tra tính hợp lệ của json sang giai đoạn sau - khi dữ liệu được chuyển từ bộ đệm sang cụm clickhouse.

Ngoài khía cạnh phát triển của vấn đề, chúng tôi nghĩ ngay đến cơ sở hạ tầng trong tương lai của mình và quyết định triển khai ứng dụng của mình thông qua docker. Dockerfile cuối cùng để xây dựng ứng dụng là https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. Nhìn chung, nó khá đơn giản, điểm duy nhất mà tôi muốn chú ý đến là việc lắp ráp nhiều tầng, cho phép chúng ta giảm hình ảnh cuối cùng của container.

Những bước đầu tiên trên đám mây

Trước hết hãy đăng ký trên đám mây.yandex.ru. Sau khi điền vào tất cả các trường cần thiết, chúng tôi sẽ được tạo một tài khoản và được cấp một số tiền nhất định, số tiền này có thể được sử dụng để thử nghiệm các dịch vụ đám mây. Nếu bạn muốn lặp lại tất cả các bước trong bài viết của chúng tôi, khoản trợ cấp này là đủ đối với bạn.

Sau khi đăng ký, một đám mây riêng và một thư mục mặc định sẽ được tạo cho bạn, trong đó bạn có thể bắt đầu tạo tài nguyên đám mây. Nói chung, trong Yandex.Cloud, mối quan hệ giữa các tài nguyên trông như thế này:

Chúng tôi chấp nhận 10 sự kiện trong Yandex.Cloud. Phần 000

Bạn có thể tạo nhiều đám mây cho một tài khoản. Và bên trong đám mây, hãy tạo các thư mục khác nhau cho các dự án khác nhau của công ty. Bạn có thể đọc thêm về điều này trong tài liệu - https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. Nhân tiện, tôi sẽ thường xuyên đề cập đến nó bên dưới trong văn bản. Khi tôi thiết lập toàn bộ cơ sở hạ tầng từ đầu, tài liệu này đã nhiều lần giúp tôi, vì vậy tôi khuyên bạn nên nghiên cứu nó.

Để quản lý đám mây, bạn có thể sử dụng giao diện web hoặc tiện ích dòng lệnh - yc. Việc cài đặt được thực hiện bằng một lệnh duy nhất (đối với Linux và Mac OS):

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

Nếu chuyên gia bảo mật nội bộ của bạn đang phản đối việc chạy các tập lệnh từ Internet, thì trước tiên, bạn có thể mở tập lệnh và đọc nó, và thứ hai, chúng tôi chạy nó dưới quyền người dùng của mình - không có quyền root.

Nếu bạn muốn cài đặt client cho Windows, bạn có thể sử dụng hướng dẫn đây và sau đó thực hiện yc initđể tùy chỉnh đầy đủ nó:

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:~ $

Về nguyên tắc, quy trình này rất đơn giản - trước tiên bạn cần lấy mã thông báo oauth để quản lý đám mây, chọn đám mây và thư mục bạn sẽ sử dụng.

Nếu bạn có nhiều tài khoản hoặc thư mục trong cùng một đám mây, bạn có thể tạo các hồ sơ bổ sung với các cài đặt riêng biệt thông qua việc tạo và chuyển đổi hồ sơ yc config giữa chúng.

Ngoài các phương pháp trên, nhóm Yandex.Cloud đã viết rất hay plugin cho địa hình để quản lý tài nguyên đám mây. Về phần mình, tôi đã chuẩn bị một kho git, nơi tôi mô tả tất cả các tài nguyên sẽ được tạo như một phần của bài viết - https://github.com/rebrainme/yandex-cloud-events/. Chúng tôi quan tâm đến nhánh chính, hãy sao chép nó cục bộ:


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/

Tất cả các biến chính được sử dụng trong terraform đều được ghi trong tệp main.tf. Để bắt đầu, hãy tạo tệp Private.auto.tfvars trong thư mục terraform với nội dung sau:

# 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 = ""

Tất cả các biến có thể được lấy từ danh sách cấu hình yc, vì chúng tôi đã định cấu hình tiện ích bảng điều khiển. Tôi khuyên bạn nên thêm ngay Private.auto.tfvars vào .gitignore để không vô tình xuất bản dữ liệu riêng tư.

Trong Private.auto.tfvars, chúng tôi cũng đã chỉ định dữ liệu từ Cloudflare - để tạo bản ghi DNS và ủy quyền miền chính events.kis.im cho máy chủ của chúng tôi. Nếu bạn không muốn sử dụng cloudflare, hãy xóa phần khởi tạo của nhà cung cấp cloudflare trong main.tf và tệp dns.tf, tệp này chịu trách nhiệm tạo các bản ghi dns cần thiết.

Trong công việc của mình, chúng tôi sẽ kết hợp cả ba phương pháp - giao diện web, tiện ích bảng điều khiển và địa hình.

Mạng ảo

Thành thật mà nói, bạn có thể bỏ qua bước này, vì khi tạo một đám mây mới, bạn sẽ tự động có một mạng riêng và 3 mạng con được tạo - một mạng con cho mỗi vùng khả dụng. Nhưng chúng tôi vẫn muốn tạo một mạng riêng cho dự án của mình với địa chỉ riêng. Sơ đồ chung về cách hoạt động của mạng trong Yandex.Cloud được hiển thị trong hình bên dưới (được lấy trung thực từ https://cloud.yandex.ru/docs/vpc/concepts/)

Chúng tôi chấp nhận 10 sự kiện trong Yandex.Cloud. Phần 000

Vì vậy, bạn tạo một mạng chung trong đó các tài nguyên có thể giao tiếp với nhau. Đối với mỗi vùng sẵn sàng, một mạng con được tạo với địa chỉ riêng và được kết nối với mạng chung. Kết quả là tất cả tài nguyên đám mây trong đó có thể giao tiếp, ngay cả khi chúng ở các vùng khả dụng khác nhau. Các tài nguyên được kết nối với các mạng đám mây khác nhau chỉ có thể nhìn thấy nhau thông qua các địa chỉ bên ngoài. Nhân tiện, phép thuật này hoạt động như thế nào bên trong, đã được mô tả rất hay trên Habré.

Việc tạo mạng được mô tả trong tệp network.tf từ kho lưu trữ. Ở đó, chúng tôi tạo một mạng riêng chung nội bộ và kết nối ba mạng con với mạng đó ở các vùng sẵn sàng khác nhau - nội bộ-a (172.16.1.0/24), nội bộ-b (172.16.2.0/24), nội bộ-c (172.16.3.0/24 ).

Khởi tạo địa hình và tạo mạng:

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.

Tuyệt vời! Chúng tôi đã tạo mạng lưới của mình và hiện đã sẵn sàng tạo các dịch vụ nội bộ của mình.

Tạo máy ảo

Để kiểm tra ứng dụng, chúng tôi sẽ chỉ cần tạo hai máy ảo - chúng tôi sẽ cần máy đầu tiên để xây dựng và chạy ứng dụng, máy thứ hai chạy kafka, chúng tôi sẽ sử dụng máy này để lưu trữ các tin nhắn đến. Và chúng tôi sẽ tạo một máy khác để cấu hình prometheus để giám sát ứng dụng.

Các máy ảo sẽ được cấu hình bằng ansible, vì vậy trước khi bắt đầu terraform, hãy đảm bảo rằng bạn có một trong những phiên bản mới nhất của ansible. Và cài đặt các vai trò cần thiết với thiên hà 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) $

Bên trong thư mục ansible có một tệp cấu hình .ansible.cfg mẫu mà tôi sử dụng. Nó có thể có ích.

Trước khi tạo máy ảo, hãy đảm bảo rằng bạn đã chạy ssh-agent và thêm khóa ssh, nếu không terraform sẽ không thể kết nối với các máy đã tạo. Tất nhiên, tôi đã gặp một lỗi trong os x: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. Để ngăn điều này xảy ra lần nữa, hãy thêm một biến nhỏ vào env trước khi khởi chạy Terraform:

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

Trong thư mục có terraform, chúng tôi tạo các tài nguyên cần thiết:

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 ...

Nếu mọi thứ kết thúc thành công (và lẽ ra phải như vậy), thì chúng ta sẽ có ba máy ảo:

  1. build - một máy để thử nghiệm và xây dựng một ứng dụng. Docker được Ansible cài đặt tự động.
  2. giám sát - một máy giám sát - prometheus & grafana được cài đặt trên đó. Tiêu chuẩn đăng nhập/mật khẩu: admin/admin
  3. kafka là một máy nhỏ được cài đặt kafka, có thể truy cập trên cổng 9092.

Hãy đảm bảo rằng tất cả chúng đều ở đúng vị trí:

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 |
+----------------------+------------+---------------+---------+---------------+-------------+

Các tài nguyên đã có sẵn và từ đây chúng ta có thể lấy địa chỉ IP của họ. Trong suốt phần tiếp theo, tôi sẽ sử dụng địa chỉ IP để kết nối qua ssh và kiểm tra ứng dụng. Nếu bạn có tài khoản cloudflare được kết nối với terraform, vui lòng sử dụng tên DNS mới được tạo.
Nhân tiện, khi tạo một máy ảo, IP nội bộ và tên DNS nội bộ sẽ được cung cấp, do đó bạn có thể truy cập các máy chủ trong mạng theo tên:

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

Điều này sẽ hữu ích khi chúng ta chỉ ra cho ứng dụng điểm cuối bằng kafk.

Lắp ráp ứng dụng

Tuyệt vời, có máy chủ, có ứng dụng - tất cả những gì còn lại là lắp ráp và xuất bản nó. Đối với bản dựng, chúng tôi sẽ sử dụng bản dựng docker thông thường, nhưng để lưu trữ hình ảnh, chúng tôi sẽ sử dụng dịch vụ từ Yandex - đăng ký vùng chứa. Nhưng điều đầu tiên trước tiên.

Chúng ta copy ứng dụng vào máy build, đăng nhập qua ssh và lắp ráp image:

vozerov@mba:~/events/terraform (master) $ cd ..
vozerov@mba:~/events (master) $ rsync -av app/ ubuntu@84.201.132.3: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

Một nửa trận chiến đã hoàn thành - bây giờ chúng ta có thể kiểm tra chức năng của ứng dụng bằng cách khởi chạy và gửi nó tới kafka:

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) $

Ứng dụng đã phản hồi với việc ghi thành công và cho biết id của phân vùng cũng như phần bù trong đó có thông báo. Tất cả những gì còn lại phải làm là tạo một sổ đăng ký trong Yandex.Cloud và tải hình ảnh của chúng tôi lên đó (cách thực hiện việc này bằng ba dòng được mô tả trong tệp register.tf). Tạo một kho lưu trữ:

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.

Có một số cách để xác thực trong sổ đăng ký vùng chứa - sử dụng mã thông báo oauth, mã thông báo iam hoặc khóa tài khoản dịch vụ. Thông tin chi tiết về các phương pháp này có thể được tìm thấy trong tài liệu. https://cloud.yandex.ru/docs/container-registry/operations/authentication. Chúng tôi sẽ sử dụng khóa tài khoản dịch vụ để tạo một tài khoản:

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.

Bây giờ tất cả những gì còn lại là tạo chìa khóa cho nó:

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

Chúng tôi nhận được thông tin về id bộ lưu trữ của mình, chuyển khóa và đăng nhập:

vozerov@mba:~/events/terraform (master) $ scp key.json ubuntu@84.201.132.3:
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:~$

Để tải hình ảnh lên sổ đăng ký, chúng tôi cần ID đăng ký vùng chứa, chúng tôi lấy nó từ tiện ích yc:

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

Sau đó, chúng tôi gắn thẻ hình ảnh của mình bằng tên mới và tải lên:

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

Chúng tôi có thể xác minh rằng hình ảnh được tải thành công:

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

Nhân tiện, nếu bạn cài đặt tiện ích yc trên máy Linux, bạn có thể sử dụng lệnh

yc container registry configure-docker

để cấu hình docker.

Kết luận

Chúng tôi đã làm việc chăm chỉ và kết quả là:

  1. Chúng tôi đã đưa ra kiến ​​trúc cho dịch vụ tương lai của mình.
  2. Chúng tôi đã viết một ứng dụng bằng golang để triển khai logic nghiệp vụ của mình.
  3. Chúng tôi đã thu thập nó và chuyển nó vào sổ đăng ký vùng chứa riêng.

Trong phần tiếp theo, chúng ta sẽ chuyển sang nội dung thú vị - chúng ta sẽ phát hành ứng dụng của mình vào giai đoạn sản xuất và cuối cùng khởi chạy tải trên đó. Đừng chuyển đổi!

Tài liệu này có trong đoạn video ghi lại hội thảo mở REBRAIN & Yandex.Cloud: Chúng tôi chấp nhận 10 yêu cầu mỗi giây trên Yandex Cloud - https://youtu.be/cZLezUm0ekE

Nếu bạn muốn tham dự các sự kiện trực tuyến như vậy và đặt câu hỏi trong thời gian thực, hãy kết nối với kênh DevOps của REBRAIN.

Chúng tôi muốn gửi lời cảm ơn đặc biệt đến Yandex.Cloud vì đã có cơ hội tổ chức một sự kiện như vậy. Liên kết với họ - https://cloud.yandex.ru/prices

Nếu bạn cần chuyển sang đám mây hoặc có thắc mắc về cơ sở hạ tầng của mình, vui lòng để lại yêu cầu.

Tái bút Chúng tôi có 2 đợt kiểm tra miễn phí mỗi tháng, có lẽ dự án của bạn sẽ là một trong số đó.

Nguồn: www.habr.com

Mua dịch vụ lưu trữ đáng tin cậy cho các trang web có bảo vệ DDoS, máy chủ VPS VDS 🔥 Mua dịch vụ hosting website đáng tin cậy với bảo vệ DDoS, máy chủ VPS VDS | ProHoster