{"id":321114,"date":"2021-04-08T15:00:22","date_gmt":"2021-04-08T15:00:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=321114"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=321114","title":{"rendered":"\u0414\u0435\u043f\u043b\u043e\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 Kubernetes \u0432 Mail.ru Cloud Solutions. \u0427\u0430\u0441\u0442\u044c 2: \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u0431\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e66\/71c\/d3b\/e6671cd3bebd801965d51e24a391f262.jpg\" width=\"780\" height=\"520\"><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443\u043c\u0430 \u043f\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044e <a href=\"https:\/\/mcs.mail.ru\/containers\/\">Kubernetes-\u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u043d\u0430 \u0431\u0430\u0437\u0435 \u043e\u0431\u043b\u0430\u043a\u0430 Mail.ru Cloud Solutions<\/a> \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e MVP \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0435\u0433\u043e \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u0431\u0430\u0446\u0438\u044e \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 YouTube.<\/p>\n<p>\u042f \u0412\u0430\u0441\u0438\u043b\u0438\u0439 \u041e\u0437\u0435\u0440\u043e\u0432, \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0430\u0433\u0435\u043d\u0442\u0441\u0442\u0432\u0430 Fevlake \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 DevOps-\u0438\u043d\u0436\u0435\u043d\u0435\u0440 (\u043e\u043f\u044b\u0442 \u0432 DevOps \u2014 8 \u043b\u0435\u0442), \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0441\u0435 \u044d\u0442\u0430\u043f\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Cloud-Native \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 K8s: \u043e\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0434\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f CI\/CD \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e Helm-\u0447\u0430\u0440\u0442\u0430.<\/p>\n<p>\u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0432 <a href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/549680\/\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 API-\u0441\u0435\u0440\u0432\u0435\u0440, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 Kubernetes c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c \u0438 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u043c\u0438 \u0431\u0430\u0437\u0430\u043c\u0438, \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 RabbitMQ \u0447\u0435\u0440\u0435\u0437 Helm \u0432 Kubernetes. \u0421\u0435\u0439\u0447\u0430\u0441 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0434 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435. <\/p>\n<blockquote>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443\u043c\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c: <a href=\"https:\/\/www.youtube.com\/watch?v=8rchh2qRzEE&amp;feature=youtu.be\">\u0447\u0430\u0441\u0442\u044c 1<\/a>, <a href=\"https:\/\/www.youtube.com\/watch?v=sKuHz5-GdaI&amp;feature=youtu.be\">\u0447\u0430\u0441\u0442\u044c 2<\/a>, <a href=\"https:\/\/www.youtube.com\/watch?v=pXRtzQjLGUE&amp;feature=youtu.be\">\u0447\u0430\u0441\u0442\u044c 3<\/a>.<\/p>\n<\/blockquote>\n<h3>\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 Worker \u043d\u0430 Python<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432 (Worker), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 RabbitMQ \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412 \u0438\u0445 \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u0445\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0438\u0434\u0435\u043e, \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043d\u0435\u0433\u043e \u0430\u0443\u0434\u0438\u043e, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0432 \u0431\u0430\u043a\u0435\u0442 S3. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Python. \u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\">\u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435<\/a>.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0444\u0430\u0439\u043b <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/worker.py\">worker.py<\/a>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 os, sys, time, logging, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 JSON (json), HTTP (requests), RabbitMQ (pika) \u0438  Environment-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 (Env). \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0438\u0434\u0435\u043e \u0441 Youtube, \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/www.youtube-dl.org\/\">youtube_dl<\/a>. \u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 S3 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c boto3: <\/p>\n<pre><code># System modules import json import os import sys import time import logging import subprocess  # Third party modules import pika import requests from environs import Env import youtube_dl import boto3 from urllib import parse<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/.env\">.env<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0441 \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0442\u0443\u0434\u0430 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0435\u0442 Kubernetes \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 configMap \u2014 \u0436\u0435\u0441\u0442\u043a\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u0432 Docker-\u043e\u0431\u0440\u0430\u0437\u0435 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c:<\/p>\n<pre><code>## read config env = Env() env.read_env()  # read .env file, if it exists  rabbitmq_host = env(\"RABBIT_HOST\", 'localhost') rabbitmq_port = env(\"RABBIT_PORT\", 5672) rabbitmq_user = env(\"RABBIT_USER\") rabbitmq_pass = env(\"RABBIT_PASS\") rabbitmq_queue = env(\"RABBIT_QUEUE\", \"AutoUrlTemplateQueue\")  api_url = env(\"API_URL\") api_key = env(\"API_KEY\")  s3_endpoint = env(\"S3_ENDPOINT\") s3_web = env(\"S3_WEB\") s3_access_key = env(\"S3_ACCESS_KEY\") s3_secret_key = env(\"S3_SECRET_KEY\") s3_bucket = env(\"S3_BUCKET\")<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u043f\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c:<\/p>\n<ul>\n<li>\n<p>RABBIT_HOST, RABBIT_PORT, RABBIT_USER, RABBIT_PASS \u0438 RABBIT_QUEUE \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 RabbitMQ.<\/p>\n<\/li>\n<li>\n<p>API_URL \u0438 API_KEY \u2014 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0438\u0434\u0435\u043e \u043d\u0430 API-\u0441\u0435\u0440\u0432\u0435\u0440. <\/p>\n<\/li>\n<li>\n<p>S3_ENDPOINT \u2014 Endpoint \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a S3: \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u043e\u0442 AWS \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435.<\/p>\n<\/li>\n<li>\n<p>S3_WEB \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 URL \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0445 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0432\u0438\u0434\u0435\u043e. <\/p>\n<\/li>\n<li>\n<p>S3_ACCESS_KEY, S3_SECRET_KEY \u0438 S3_BUCKET \u2014 \u044d\u0442\u043e \u043a\u043b\u044e\u0447\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0431\u0430\u043a\u0435\u0442 S3, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0444\u0430\u0439\u043b\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a RabbitMQ \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430 S3:<\/p>\n<pre><code># Connecting to rabbitmq credentials = pika.PlainCredentials(rabbitmq_user, rabbitmq_pass) connection = pika.BlockingConnection(pika.ConnectionParameters(rabbitmq_host, rabbitmq_port, '\/', credentials)) channel = connection.channel()  s3client = boto3.client('s3', endpoint_url=s3_endpoint, aws_access_key_id = s3_access_key, aws_secret_access_key = s3_secret_key)<\/code><\/pre>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435:<\/p>\n<pre><code># Setting logger logging.basicConfig(   format='%(asctime)s | %(levelname)-7s | %(name)-12s | %(message)s',   datefmt='%d-%b-%y %H:%M:%S',   level=logging.INFO )  logger = logging.getLogger(__name__)<\/code><\/pre>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0447\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f process_event \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u044f Auto Acknowledgement (auto_ack=false). \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0430 \u0431\u0443\u0434\u0435\u043c \u0436\u0434\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 channel.start_consuming \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043a RabbitMQ \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f Ctrl+C \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u0432\u0435\u0442\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c sys.exit(0):<\/p>\n<pre><code># Starting consuming rabbitmq queue logger.info('Waiting for messages. To exit press CTRL+C')  channel.basic_consume(queue=rabbitmq_queue, on_message_callback=process_event, auto_ack=False)  try:     channel.start_consuming() except KeyboardInterrupt:     logger.info('Interrupted')     try:         sys.exit(0)     except SystemExit:         os._exit(0)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/worker.py#L48\">process_event<\/a>. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 RabbitMQ \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0442\u0430\u0439\u043c\u0435\u0440 \u0434\u043b\u044f \u043e\u0442\u0441\u0447\u0435\u0442\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c JSON \u0438\u0437 \u0442\u0435\u043b\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043f\u0430\u0440\u0441\u0438\u043c \u0435\u0433\u043e, \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044f \u0434\u0432\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435: \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (name) \u0438 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 Youtube-\u0432\u0438\u0434\u0435\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c (video_url). \u041b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430:<\/p>\n<pre><code># Processing event from rabbit and sending to internal queue def process_event(ch, method, properties, body):     logger.info(\"Got new message from rabbitmq %r\" % body)     t_start = time.time()      # Parsing data     event = json.loads(body)      name = event['name']     video_url = event['video_url']      logger.info(\"Got name: \" + str(name) + \", video_url: \" + str(video_url))<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c .wav:<\/p>\n<pre><code># Removing audio.wav before downloading os.chdir(\"\/app\") filelist = [ f for f in os.listdir(\"\/app\") if f.endswith(\".wav\") ] for f in filelist:   os.remove(os.path.join(\"\/app\", f))<\/code><\/pre>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0431\u043b\u043e\u043a\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0432\u0438\u0434\u0435\u043e \u0441 YouTube, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f YouTube Downloader (youtube_dl).<\/p>\n<p>\u041f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0446\u0438\u0439 ydl_opts. \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0443\u0434\u0438\u043e, \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e (keepvideo: False). \u0412 \u0431\u043b\u043e\u043a\u0435 postprocessors \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c FFmpeg, \u043a\u043e\u0434\u0435\u043a wav \u0438 quality 192 \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0444\u0430\u0439\u043b\u0430. \u0412 \u0431\u043b\u043e\u043a\u0435 postprocessor_args \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c rate, \u0440\u0430\u0432\u043d\u044b\u0439 16 \u043a\u0413\u0446, \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0430\u0443\u0434\u0438\u043e, \u0440\u0430\u0432\u043d\u043e\u0435 1. <\/p>\n<p>\u041d\u0430 YouTube \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u0432\u0438\u0434\u0435\u043e stereo, \u043d\u043e \u043d\u0430\u043c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e mono, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043e\u0444\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0435\u0447\u044c \u0432 \u0442\u0435\u043a\u0441\u0442, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 mono-\u0430\u0443\u0434\u0438\u043e\u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u0412 \u043f\u043e\u043b\u0435 outtmpl \u0432\u0432\u043e\u0434\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f \u0438\u043c\u0435\u043d\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430: &lt;ID \u0432\u0438\u0434\u0435\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438&gt;.&lt;\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 (wav)&gt;.<\/p>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 ydl.download \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c video_url, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f RabbitMQ. \u041f\u0440\u0438 \u043b\u044e\u0431\u043e\u043c \u0441\u0431\u043e\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u043b\u043e\u0433 \u0437\u0430\u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u00abCan\u2019t download audio file\u00bb, \u0430 \u0432 API \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u00abError downloading video\u00bb. \u0418 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0438\u0434\u0435\u043e \u043a\u043b\u0438\u0435\u043d\u0442 \u0443\u0432\u0438\u0434\u0438\u0442 \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<pre><code># Downloading video     ydl_opts = {         'format': 'bestaudio\/best',         'postprocessors': [{             'key': 'FFmpegExtractAudio',             'preferredcodec': 'wav',             'preferredquality': '192'         }],         'postprocessor_args': [             '-ar', '16000', '-ac', '1'         ],         'prefer_ffmpeg': True,         'keepvideo': False,         'outtmpl': '%(id)s.%(ext)s'     }      try:       with youtube_dl.YoutubeDL(ydl_opts) as ydl:         ydl.download([video_url])     except:       logger.error(\"Can't download audio file, sending callback\")       headers = {\"X-API-KEY\": api_key}       payload = {\"processed\": True, \"text_url\": \"Error downloading video\"}       r = requests.put(api_url + '\/requests\/' + name, data=json.dumps(payload), headers=headers)       logger.info(\"Callback sent, response code: \" + str(r.status_code))       return<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u2013 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0446\u0435\u043b\u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/Picovoice\/leopard\">Leopard<\/a> \u043e\u0442 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Picovoice. Leopard \u0447\u0438\u0442\u0430\u0435\u0442 wav-\u0444\u0430\u0439\u043b \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0432 \u0442\u0435\u043a\u0441\u0442. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0431\u0435\u0437 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u043c API. \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043b\u0430\u0442\u043d\u044b\u0439, \u043d\u043e \u0434\u043b\u044f \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u0442\u044c 30-\u0434\u043d\u0435\u0432\u043d\u044b\u0439 \u0442\u0440\u0438\u0430\u043b. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 real-time \u0440\u0435\u0436\u0438\u043c\u0435 \u0443 \u044d\u0442\u043e\u0433\u043e \u0436\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 <a href=\"https:\/\/github.com\/Picovoice\/cheetah\">Cheetah<\/a>.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Leopard \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432 GitHub \u0435\u0441\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f: \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c GNU C Compiler (GCC) \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430 \u043d\u0430 C.<\/p>\n<p>\u041c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Leopard, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043f\u0443\u0442\u044c \u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 C, \u043a \u0430\u043a\u0443\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044f\u043c, \u043a \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u043c \u043c\u043e\u0434\u0435\u043b\u044f\u043c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b (\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435 Picovoice) \u0438 wav-\u0444\u0430\u0439\u043b. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432 stdout \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u043f\u0442 \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0431\u043e\u0435\u0432 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043a\u0430\u043a \u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0448\u0430\u0433\u0435, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e callback \u0447\u0435\u0440\u0435\u0437 API:<\/p>\n<pre><code># Converting audio to text     logger.info(\"Converting audio to text\")     try:       p = subprocess.Popen(\"\/app\/leopard\/leopard_demo        leopard\/lib\/linux\/x86_64\/libpv_leopard.so        leopard\/lib\/common\/acoustic_model.pv leopard\/lib\/common\/language_model.pv license.lic *.wav\", stdout=subprocess.PIPE, shell=True)       (output, err) = p.communicate()       p_status = p.wait()       logger.info(\"Command output : \" + str(output))       logger.info(\"Command exit status\/return code : \" + str(p_status))     except:       logger.error(\"Can't convert audio to text, sending callback\")       headers = {\"X-API-KEY\": api_key}       payload = {\"processed\": True, \"text_url\": \"Error converting audio\"}       r = requests.put(api_url + '\/requests\/' + name, data=json.dumps(payload), headers=headers)       logger.info(\"Callback sent, response code: \" + str(r.status_code))       return<\/code><\/pre>\n<p>\u0418 \u0434\u0430\u043b\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0448 \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u043f\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0432 output, \u043d\u0430 S3. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0431\u0430\u043a\u0435\u0442\u0430 \u0431\u0435\u0440\u0435\u043c \u0438\u0437 environment-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 S3_BUCKET. \u041f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434: &lt;URL \u0431\u0430\u043a\u0435\u0442\u0430 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 S3_WEB&gt;\/converted\/&lt;name \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430&gt;.txt. \u0412 ACL \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c public-read, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u043c\u043e\u0433\u043b\u0438 \u043f\u0440\u043e\u0447\u0435\u0441\u0442\u044c \u0444\u0430\u0439\u043b:<\/p>\n<pre><code>   # Uploading file to s3     try:       s3client.put_object(Body=output, Bucket=s3_bucket, Key='converted\/' + name + '.txt', ACL='public-read')     except:       logger.error(\"Can't upload text to s3, sending callback\")       headers = {\"X-API-KEY\": api_key}       payload = {\"processed\": True, \"text_url\": \"Error uploading to s3\"}       r = requests.put(api_url + '\/requests\/' + name, data=json.dumps(payload), headers=headers)       logger.info(\"Callback sent, response code: \" + str(r.status_code))       return<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 API \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0444\u0430\u0439\u043b\u0430, \u0441\u043e\u043e\u0431\u0449\u0430\u044f URL, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0438\u0437 S3:<\/p>\n<pre><code>   # Sending callback to API     headers = {\"X-API-KEY\": api_key}     payload = {\"processed\": True, \"text_url\": s3_web + \"\/converted\/\" + name}     r = requests.put(api_url + '\/requests\/' + name, data=json.dumps(payload), headers=headers)     logger.info(\"Callback sent, response code: \" + str(r.status_code))<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c:<\/p>\n<pre><code>   t_elapsed = time.time() - t_start     logger.info(\"Finished with \" + video_url  + \" in \" + str(t_elapsed) + \" seconds\")      ch.basic_ack(delivery_tag = method.delivery_tag)<\/code><\/pre>\n<p>\u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/Dockerfile\">Dockerfile<\/a>. \u041c\u044b \u0431\u0435\u0440\u0435\u043c Python 3.9, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u00ab\/app\u00bb \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043d\u0435\u0435. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c ffmpeg, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0444\u0430\u0439\u043b\u043e\u0432, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0441 Youtube. \u041a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 Leopard, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 \u0441 \u043d\u0438\u043c, \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/requirements.txt\">requirements.txt<\/a>, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 Python: soundfile, youtube_dl, pika, boto, numpy. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0438\u0445. \u0418 \u0434\u0430\u043b\u0435\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b:<\/p>\n<pre><code>FROM python:3.9  WORKDIR \"\/app\"  RUN apt update &amp;&amp; apt-get install -y ffmpeg  RUN git clone https:\/\/github.com\/Picovoice\/leopard &amp;&amp; cd leopard &amp;&amp; gcc -I include\/ -O3 demo\/c\/leopard_demo.c -ldl -o leopard_demo &amp;&amp; cd ..  COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt  COPY . .<\/code><\/pre>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0430\u043a\u0435\u0442\u0430 S3<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c environment-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/.env\">.env<\/a> \u0444\u0430\u0439\u043b\u0435:<\/p>\n<pre><code>API_URL = \"http:\/\/video-api-svc.stage.svc:8080\" API_KEY = \"804b95f13b714ee9912b19861faf3d25\"  RABBIT_HOST = \"rabbitmq.stage.svc\" RABBIT_USER = \"user\" RABBIT_PASS = \"6NvlZY77Fu\" RABBIT_QUEUE = \"VideoParserWorkerQueue\"  S3_ENDPOINT = \"http:\/\/hb.bizmrg.com\/\" S3_SECRET_KEY = \"6qg2TaFo3tq9L93mNkd959Kw7YxPEp7iyybK4FsXw9T8\" S3_ACCESS_KEY = \"fAFSLdYjNKVEdEh2Vs27vc\" S3_BUCKET = \"converted\" S3_WEB = \"http:\/\/converted.hb.bizmrg.com\"<\/code><\/pre>\n<p>\u0412\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0432\u0441\u0435 \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043c\u044b \u0437\u0430\u0448\u0438\u0444\u0440\u0443\u0435\u043c \u0438 \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u0430\u0445. \u041f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0430 \u0442\u043e\u043c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0434\u043b\u044f \u043d\u0438\u0445 \u0431\u0440\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>API_KEY \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d \u0432 <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api\/-\/blob\/master\/main.go\">main.go<\/a>, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e. \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f API_URL \u0438 RABBIT_HOST \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0432 Kubernetes-\u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435. <\/p>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 <code>kubectl \u2013n stage get svc<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0432 Namespace stage:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/280\/52d\/ce5\/28052dce513cb7c08be693e52c7bc078.png\" width=\"1311\" height=\"100\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 <code>kubectl \u2013n stage get ing<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0435 API:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b34\/f97\/e9f\/b34f97e9fddca841a91edc6ce4ab4550.jpg\" width=\"766\" height=\"75\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430, \u0442\u043e \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0430\u0434\u0440\u0435\u0441\u043e\u0432. \u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0438\u043c\u044f \u0445\u043e\u0441\u0442\u0430 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u043c\u0430\u0441\u043a\u0435 &lt;NAME \u0438\u0437 \u0432\u044b\u0432\u043e\u0434\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b&gt;.&lt;Namespace (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 stage)&gt;.svc.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 RABBIT_USER, RABBIT_PASS, RABBIT_QUEUE \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043f\u0430\u0440\u043e\u043b\u044c \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0432 RabbitMQ.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0438\u0434\u0443\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a S3. \u041d\u0430 \u043d\u0438\u0445 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u043a\u0435\u0442 S3 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 MCS. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u0430\u043a\u0435\u0442\u00bb \u0432 \u043f\u0443\u043d\u043a\u0442\u0435 \u043c\u0435\u043d\u044e \u00ab<a href=\"https:\/\/mcs.mail.ru\/app\/services\/storage\/\">\u041e\u0431\u044a\u0435\u043a\u0442\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435<\/a>\u00bb. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0431\u0430\u043a\u0435\u0442\u0430 \u0443\u043a\u0430\u0436\u0435\u043c converted (\u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0432 \u0435\u0433\u043e \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e S3_BUCKET), \u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u2014 Hotbox. \u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0433\u043e\u0440\u044f\u0447\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Icebox \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0440\u0435\u0434\u043a\u0438\u0445 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f\u0445 \u043a \u0434\u0430\u043d\u043d\u044b\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0432 \u043c\u0435\u0441\u044f\u0446:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/786\/f42\/105\/786f4210547fefcb00a083af3b64b937.jpg\" width=\"411\" height=\"577\"><figcaption><\/figcaption><\/figure>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e MCS \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 CDN \u043a \u0432\u0430\u0448\u0438\u043c \u0431\u0430\u043a\u0435\u0442\u0430\u043c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430. \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043c\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0432 \u043f\u0443\u043d\u043a\u0442\u0435 \u043c\u0435\u043d\u044e \u00ab\u041e\u0431\u044a\u0435\u043a\u0442\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u00bb \u2014 \u00ab<a href=\"https:\/\/mcs.mail.ru\/app\/services\/storage\/accounts\/\">\u0410\u043a\u043a\u0430\u0443\u043d\u0442\u044b<\/a>\u00bb \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 worker \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0431\u0430\u043a\u0435\u0442\u0443:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/277\/d37\/071\/277d37071bcb5de506b3e2bcb0a5ce4f.jpg\" width=\"1144\" height=\"675\"><figcaption><\/figcaption><\/figure>\n<p>\u0417\u0430\u0442\u0435\u043c \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u044b Access Key Id \u0438 Secret Key \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 S3_ACCESS_KEY \u0438 S3_SECRET_KEY, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/dd9\/ec9\/83f\/dd9ec983fce8b006cebc9c3a65381a09.jpg\" width=\"671\" height=\"296\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043f\u0443\u043d\u043a\u0442\u0435 \u043c\u0435\u043d\u044e \u00ab\u041e\u0431\u044a\u0435\u043a\u0442\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u00bb \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c S3 Endpoint URL. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 S3_ENDPOINT. \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0431\u0430\u043a\u0435\u0442\u0443 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u044d\u0442\u043e\u0433\u043e URL \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0431\u0430\u043a\u0435\u0442\u0430: <a href=\"http:\/\/converted.hb.bizmrg.com\">http:\/\/converted.hb.bizmrg.com<\/a>. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 S3_WEB: <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/941\/a59\/14f\/941a5914f7758589a72caacb481cdd41.jpg\" width=\"1052\" height=\"389\"><figcaption><\/figcaption><\/figure>\n<h3>\u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 Worker \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 Kubernetes<\/h3>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0443 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e CPU, \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0438 \u043d\u0430 Master-\u043d\u043e\u0434\u0435, \u043d\u0438 \u043d\u0430 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u043d\u043e\u0434\u0435, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u043d\u0430\u0448\u0438 API \u0438 RabbitMQ. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 MCS \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0443 \u0443\u0437\u043b\u043e\u0432 \u0432 \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0442\u0435\u0440.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u0440\u0430\u0437\u0434\u0435\u043b \u00ab<a href=\"https:\/\/mcs.mail.ru\/app\/services\/containers\/list\/\">\u041a\u043b\u0430\u0441\u0442\u0435\u0440\u044b<\/a>\u00bb, \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u0442\u0440\u0438 \u0442\u043e\u0447\u043a\u0438 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0443 \u0443\u0437\u043b\u043e\u0432\u00bb:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9d0\/98f\/010\/9d098f0103ffb208f0d63e90329b9b40.jpg\" width=\"867\" height=\"334\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0435 converters, \u043f\u0443\u0441\u0442\u044c \u0443 \u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 2 CPU \u0438 4 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438, SSD \u043d\u0430 50 \u0413\u0411 \u0438 \u043e\u0434\u0438\u043d \u0443\u0437\u0435\u043b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<p>\u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0444\u043b\u0430\u0436\u043e\u043a \u00ab\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u00bb \u0438 \u0443\u043a\u0430\u0436\u0435\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0437\u043b\u043e\u0432 \u0440\u0430\u0432\u043d\u044b\u043c 1, \u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u2014 \u0440\u0430\u0432\u043d\u044b\u043c 5. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u043e\u0437\u0434\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4bd\/346\/333\/4bd3463336a0831c2e18541cc1fff5f8.jpg\" width=\"554\" height=\"816\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043d\u043e\u0434\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>kubectl get nodes<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/31d\/c54\/395\/31dc54395129d4c42637a722a568eb45.jpg\" width=\"791\" height=\"72\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b get node \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u043e\u0434\u044b \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 YAML: <\/p>\n<pre><code>kubectl get node kub-vc-dev-converters-0 -o yaml<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u043a\u0446\u0438\u044e allocatable: \u0437\u0434\u0435\u0441\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f, \u043a\u0430\u043a\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0438 \u0432 \u043a\u0430\u043a\u043e\u043c \u043e\u0431\u044a\u0435\u043c\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u044b \u043d\u0430 \u043d\u043e\u0434\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043f\u043e\u043b\u0435 cpu \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043d\u0430 \u043d\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c 1930 milicores, \u0438\u043b\u0438 \u043c\u0438\u043b\u043b\u0438\u044f\u0434\u0435\u0440 (\u0432 \u043e\u0434\u043d\u043e\u043c \u044f\u0434\u0440\u0435 1000 \u043c\u0438\u043b\u043b\u0438\u044f\u0434\u0435\u0440):<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/542\/4af\/780\/5424af7803b2430ac15f14f942fae9a9.jpg\" width=\"756\" height=\"787\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u0441\u0435\u043a\u0446\u0438\u0438 labels \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043c\u0435\u0442\u043a\u0438 \u043d\u043e\u0434\u044b. \u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u043c\u0435\u0442\u043a\u0430 <code>msc.mail.ru\/mcs-nodepool: converters<\/code>. \u041c\u044b \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0435\u0435 \u0432 deployment \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u044f\u0432\u043d\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u043d\u0430 \u043a\u0430\u043a\u043e\u043c node-\u043f\u0443\u043b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bb9\/13e\/212\/bb913e212a2ba5b344c7fdca2f24e8b0.jpg\" width=\"911\" height=\"501\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/.infra\/yaml\/deployment.yaml\">deployment<\/a> \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430, \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e converter-dp. \u0412 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c worker \u0441 \u043e\u0431\u0440\u0430\u0437\u043e\u043c vozerov\/converter:v24 (\u044d\u0442\u043e\u0442 \u043e\u0431\u0440\u0430\u0437 \u044f \u0442\u0430\u043a\u0436\u0435 <a href=\"https:\/\/hub.docker.com\/r\/vozerov\/converter\">\u0437\u0430\u043b\u0438\u043b \u043d\u0430 hub.docker.com<\/a>). \u0412\u043d\u0443\u0442\u0440\u0438 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f python3 \/app\/worker.py. \u0414\u0430\u043b\u0435\u0435 \u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 1,5 \u044f\u0434\u0440\u0430 CPU (1500 \u043c\u0438\u043b\u043b\u0438\u044f\u0434\u0435\u0440) \u0438 1 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438, \u0432 \u043b\u0438\u043c\u0438\u0442\u0430\u0445 \u0443\u043a\u0430\u0436\u0435\u043c \u0442\u0435 \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0418 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c nodeSelector, \u0441\u043e\u043e\u0431\u0449\u0430\u044f Deployment, \u0447\u0442\u043e \u043f\u043e\u0434\u044b \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043d\u043e\u0434\u0430\u0445, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c <code>label mcs.mail.ru\/mcs-nodepool: converters<\/code>:<\/p>\n<pre><code>apiVersion: apps\/v1 kind: Deployment metadata:   name: converter-dp spec:   selector:     matchLabels:       app: converter   template:     metadata:       labels:         app: converter     spec:       containers:         - name: worker           image: vozerov\/converter:v24           command: [\"python3\"]           args: [\"\/app\/worker.py\"]           volumeMounts:           - name: config             mountPath: \/app\/.env             subPath: .env           resources:             requests:               cpu: 1500m               memory: 1Gi             limits:               cpu: 1500m               memory: 1Gi       nodeSelector:         mcs.mail.ru\/mcs-nodepool: converters       volumes:       - name: config         configMap:           name: converter-config<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. \u041e\u0431\u044b\u0447\u043d\u043e \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043d\u043e\u0434, \u0438 \u0432\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u0442\u0435 \u0437\u043d\u0430\u0442\u044c, \u043d\u0430 \u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043d\u043e\u0434\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u0432\u0430\u0448 \u043f\u043e\u0434. \u041f\u043e\u043c\u0435\u0449\u0430\u0442\u044c \u0432 Docker-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u0441\u0440\u0435\u0434 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u2014 \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 Kubernetes \u0435\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u044b\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 \u2014 configMap. \u0412\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 configMap \u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0435 Kubernetes, \u0447\u0442\u043e \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u043e\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0438\u0437 configMap, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0432\u0430\u0448 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441\u043c\u043e\u0436\u0435\u0442 \u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 configMap \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0444\u0430\u0439\u043b\u0430 .env. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e converter-config:<\/p>\n<pre><code>kubectl -n stage create configmap converter-config --from-file=.env<\/code><\/pre>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u0435\u0433\u043e \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 YAML:<\/p>\n<pre><code>kubectl -n stage get configmap\/converter-config -o yaml<\/code><\/pre>\n<p>\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0432 \u043d\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u0440 &lt;\u043a\u043b\u044e\u0447&gt;|&lt;\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435&gt;. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043b\u044e\u0447 \u043e\u0434\u0438\u043d \u2014 .env. \u041d\u043e \u0438\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c90\/92d\/201\/c9092d201bfee9b5d0d79672d130b458.jpg\" width=\"866\" height=\"553\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/.infra\/yaml\/deployment.yaml\">Deployment<\/a>. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c volume \u0441 \u0438\u043c\u0435\u043d\u0435\u043c config, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u043c\u0438 configMap \u0441 \u0438\u043c\u0435\u043d\u0435\u043c converter-config. \u0418 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e configMap \u043c\u044b \u0431\u0435\u0440\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0430 .env, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \/app\/.env:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e03\/db9\/aff\/e03db9affc89f64f56ffce72b0ec741f.jpg\" width=\"434\" height=\"726\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440, \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 deployment:<\/p>\n<pre><code>kubectl -n stage apply -f yaml\/deployment.yaml<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>kubectl -n stage get pods<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0c0\/902\/eea\/0c0902eea6c2e3231c2b8508bb13fc7a.jpg\" width=\"832\" height=\"120\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0432\u043e\u0434\u0438\u043c \u043b\u043e\u0433\u0438 \u043f\u043e\u0434\u0430 <code>kubectl -n stage logs -f converter-dp-68cdfdf9c8-ctbqc<\/code> \u0438 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 RabbitMQ:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/80d\/605\/dc9\/80d605dc9e428b66681b129bd29f13ef.jpg\" width=\"1073\" height=\"41\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u043d\u0430\u0448\u0435 API. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043c\u0435\u043d\u0438 name \u0443\u043a\u0430\u0436\u0435\u043c roger, \u0430 \u0432 video_url \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0434\u0440\u0435\u0441 \u043b\u044e\u0431\u043e\u0433\u043e \u0432\u0438\u0434\u0435\u043e \u0441 YouTube \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435:<\/p>\n<pre><code>curl -X POST -d '{\"name\": \"roger\", \"\u201cvideo_url\":  \u201chttps:\/\/www.youtube.com\/watch?v=A72M2mZ2wHA\"}' -s -H 'X-API-KEY: 804b95f13b714ee9912b19861faf3d25' http:\/\/api.stage.kis.im\/requests | jq .<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0438\u043d\u044f\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/944\/425\/94e\/94442594e8b32e1cdfe07db2c002a78c.jpg\" width=\"568\" height=\"114\"><figcaption><\/figcaption><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043b\u043e\u0433\u0438 \u043f\u043e\u0434\u0430 <code>cubectl -n stage logs -f converter-dp-68cdfdf9c8-ctbqc<\/code>, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432\u0441\u0435 \u044d\u0442\u0430\u043f\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/735\/dae\/b13\/735daeb1386511ba090a16d540383b5a.jpg\" width=\"1551\" height=\"820\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u2014 23 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 API \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 request \u043f\u043e \u0438\u043c\u0435\u043d\u0438 roger:<\/p>\n<pre><code>curl -X GET -s -H 'X-API-KEY: 804b95f13b714ee9912b19861faf3d25'  http:\/\/api.stage.kis.im\/requests\/roger | jq .<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432 \u043f\u043e\u043b\u0435 text_url \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f URL \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u0444\u0430\u0439\u043b\u0430 \u0432 S3. \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b URL \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c .txt: \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/923\/a52\/e24\/923a52e24ee429355d5c69e85957d5aa.jpg\" width=\"797\" height=\"318\"><figcaption><\/figcaption><\/figure>\n<p>\u041c\u043e\u0436\u0435\u043c \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 CURL:<\/p>\n<pre><code>curl http:\/\/converted.hb.bizmrg.com\/converted\/roger.txt<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u0443\u044e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043c\u0438 \u0432\u0438\u0434\u0435\u043e:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b8e\/72a\/97a\/b8e72a97a98a930ceb1b4ececaa7d053.jpg\" width=\"1557\" height=\"512\"><figcaption><\/figcaption><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0439\u0442\u0438 \u0432 \u043e\u0431\u043b\u0430\u043a\u043e MCS \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u043c\u0438 \u0431\u0430\u043a\u0435\u0442 converted, \u0442\u043e \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \/converted \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6d3\/fd5\/c08\/6d3fd5c085620ef7ce9cf41f5bda615b.jpg\" width=\"1051\" height=\"431\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430\u0448\u0435\u0433\u043e MVP-\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.<\/p>\n<h3>\u0410\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Kubernetes<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u043c\u043e\u0433 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u0422\u0430\u043a \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044e \u043e\u0434\u0438\u043d Worker \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u043b\u0433\u043e. \u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 Worker, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u0441\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438, \u0430 \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0437\u0430\u0434\u0430\u0447 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u043b\u0438\u0441\u044c.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0433\u0443\u0442 Cluster Autoscaler \u0438 Horizontal Pod Autoscaler, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432 Kubernetes. \u041f\u0435\u0440\u0432\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043d\u043e\u0434, \u0432\u0442\u043e\u0440\u043e\u0439 \u2014 \u0437\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0434\u043e\u0432. \u041a\u0440\u043e\u043c\u0435 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u0435\u0449\u0435 Vertical Pod Autoscaler, \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0439 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0434\u043b\u044f \u043f\u043e\u0434\u0430, \u043d\u043e \u043c\u044b \u0435\u0433\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/.infra\/yaml\/deployment.yaml\">deployment<\/a> \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0435\u043c\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0441\u0435\u043a\u0446\u0438\u044f resources, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u0438\u0437 \u0434\u0432\u0443\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432: requests \u0438 limits:<\/p>\n<pre><code>         resources:             requests:               cpu: 1500m               memory: 1Gi             limits:               cpu: 1500m               memory: 1Gi<\/code><\/pre>\n<p>\u0411\u043b\u043e\u043a requests \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c Kubernetes. \u041a\u043e\u0433\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434, \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0435\u0433\u043e \u0431\u0435\u0440\u0435\u0442 \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0430 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043d\u043e\u0434\u0443, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0435\u0432 \u0438 \u043f\u0440\u0430\u0432\u0438\u043b. \u041c\u043e\u0433\u0443\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f Labels (\u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u0441 Node Selector), Affinity, Anti-Affinity, Taints, Tolerations \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<p>\u041d\u0430\u0441 \u0441\u0435\u0439\u0447\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0435\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, \u0443 \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0434\u044b \u0435\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (allocatable). \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 1930 \u043c\u0438\u043b\u043b\u0438\u044f\u0434\u0435\u0440. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u0434\u0438\u043d \u043f\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f 1,5 \u044f\u0434\u0440\u0430, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u043d\u043e\u0434\u0435, \u0430 \u0432\u0442\u043e\u0440\u043e\u043c\u0443 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0443\u0436\u0435 \u043d\u0435 \u0445\u0432\u0430\u0442\u0438\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442 \u0435\u0433\u043e \u043d\u0430 \u0438\u043c\u0435\u044e\u0449\u0443\u044e\u0441\u044f \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0443\u044e \u043d\u043e\u0434\u0443.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0431\u043b\u043e\u043a \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 limits \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u0436\u0435\u0441\u0442\u043a\u0438\u0435 \u043b\u0438\u043c\u0438\u0442\u044b, \u0430\u043d\u0430\u043b\u043e\u0433 Docker Limits. \u041c\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 1,5 \u044f\u0434\u0435\u0440 \u0438 1 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u041e\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0435\u043a\u0446\u0438\u0438 resources \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 describe \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u043e\u0434\u0443, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e QoS (Quality of Service) Class. \u0412 \u043d\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u0442\u0440\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: Best Effort, Burstable \u0438 Guaranteed. Guaranteed \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043c \u043f\u043e\u0434\u0430\u043c, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0441\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 limits \u0438 requests. \u0415\u0441\u043b\u0438 requests \u043b\u0438\u0431\u043e limits \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u044b \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u043b\u0438\u0431\u043e \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c (limits \u0432\u044b\u0448\u0435), \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 Burstable. \u0415\u0441\u043b\u0438 \u0436\u0435 resources \u043d\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u044b \u0438\u043b\u0438 \u0432\u043e\u0432\u0441\u0435 \u0443\u0431\u0440\u0430\u043d\u044b, \u0442\u043e \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441 Best Effort. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 Kubernetes \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u043d\u043e\u0434\u043e\u0439, \u043e\u043d \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0431\u0443\u0434\u0435\u0442 \u0443\u0431\u0438\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 Best Effort, \u0437\u0430\u0442\u0435\u043c Burstable \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c Guaranteed. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435\u0433\u0434\u0430 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0439\u0442\u0435 \u0441\u0435\u043a\u0446\u0438\u044e resources:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/91c\/942\/499\/91c94249989987653b014c680ce4ca6d.jpg\" width=\"662\" height=\"95\"><figcaption><\/figcaption><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c <code>kubectl describe node kub-vc-dev-converters-0<\/code> \u043a \u043d\u043e\u0434\u0435, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u043d\u043e\u0434\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/423\/91e\/241\/42391e241404f1b02d541aaaec43c9a4.jpg\" width=\"1562\" height=\"356\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0430\u0432\u0442\u043e\u0441\u043a\u0435\u0439\u043b\u0438\u043d\u0433\u0443. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u0434\u043e\u0432 \u043f\u043e\u0434 \u043d\u0430\u0448 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u0434\u043e \u0434\u0432\u0443\u0445, \u0438 \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0434\u043e\u0432:<\/p>\n<pre><code>kubectl -n stage scale deploy converter-dp --replicas=2 kubectl -n stage get pods<\/code><\/pre>\n<p>\u041d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434 \u043f\u043e\u043a\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 Pending:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/51e\/442\/a6c\/51e442a6cb29ba9b5ea60bb20f8378d1.jpg\" width=\"846\" height=\"139\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u043a \u043d\u0435\u043c\u0443 <code>kubectl -n stage describe pod converter-dp-68cdfdf9c8-6tfvr<\/code> \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0435\u043a\u0446\u0438\u044e Events:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/da3\/c9d\/5b5\/da3c9d5b53e72457c92acb3e8e3cfcbc.jpg\" width=\"1559\" height=\"160\"><figcaption><\/figcaption><\/figure>\n<p>\u0418\u0437 \u0442\u0440\u0435\u0445 \u043d\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043d\u043e\u043b\u044c. \u041e\u0434\u043d\u0430 \u043d\u043e\u0434\u0430 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043f\u043e Node Selector, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438, \u0430 \u0443 \u0434\u0432\u0443\u0445 \u043d\u043e\u0434 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e CPU. \u0418 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432 \u0434\u0435\u043b\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f Cluster Autoscaler. \u041e\u043d \u0432\u0438\u0434\u0438\u0442, \u0447\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u043d\u0435 \u043c\u043e\u0436\u0435\u0442: \u043d\u0430 \u043d\u043e\u0434\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e 1930 \u043c\u0438\u043b\u043b\u0438\u044f\u0434\u0435\u0440, \u0430 \u0434\u043b\u044f \u0434\u0432\u0443\u0445 \u043f\u043e\u0434\u043e\u0432 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f 3000. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0433\u0440\u0443\u043f\u043f\u0430 \u0443\u0437\u043b\u043e\u0432, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u043e\u043f\u0446\u0438\u044e \u00ab\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u00bb, \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c\u0441\u044f \u0434\u043e \u0434\u0432\u0443\u0445 \u043d\u043e\u0434. \u0415\u0441\u043b\u0438 \u0437\u0430\u0439\u0442\u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u043b\u0430\u043a\u043e\u043c MCS, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u00ab\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430\u00bb:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/987\/7e7\/d7a\/9877e7d7ab0efbe87e680f7b6b589f29.jpg\" width=\"1472\" height=\"362\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0430\u0432\u0442\u043e\u0441\u043a\u0435\u0439\u043b\u0438\u043d\u0433\u0430 \u0432 \u043e\u0431\u043b\u0430\u043a\u0430\u0445: \u043e\u0442 \u043d\u0430\u0441 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u0411\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u043d\u043e\u0434\u0430 \u0441 \u0442\u0435\u043c \u0436\u0435 Node Selector, \u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u0439. \u041f\u043e\u0434\u043e\u0436\u0434\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043f\u043e\u0434\u044b:<\/p>\n<pre><code>kubectl -n stage get pods<\/code><\/pre>\n<p>\u041e\u0431\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b34\/d58\/e0a\/b34d58e0a9c16e8151a36deebd5921e6.jpg\" width=\"496\" height=\"82\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043d\u043e\u0434\u044b:<\/p>\n<pre><code>kubectl get nodes<\/code><\/pre>\n<p>\u041f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043d\u043e\u0432\u0430\u044f \u043d\u043e\u0434\u0430:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/930\/b0f\/9e0\/930b0f9e0d82d58c9e9b54a9cf306a4a.jpg\" width=\"424\" height=\"68\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u0447\u0438\u0441\u043b\u043e \u0440\u0435\u043f\u043b\u0438\u043a \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0434\u043e \u043e\u0434\u043d\u043e\u0439:<\/p>\n<pre><code>kubectl -n stage scale deploy converter-dp --replicas=1<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u043e\u0441\u044c \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0434\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>kubectl -n stage get pods<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d9c\/ef6\/335\/d9cef6335fc096bdfa10b2688edbf237.jpg\" width=\"886\" height=\"138\"><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0435\u0440\u0435\u0437 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f Cluster Autoscaler \u0443\u0432\u0438\u0434\u0438\u0442, \u0447\u0442\u043e \u043d\u043e\u0432\u0430\u044f \u043d\u043e\u0434\u0430 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442 \u0438 \u0435\u0435 \u2014 \u0438 \u0443 \u043d\u0430\u0441 \u043e\u043f\u044f\u0442\u044c \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u043d\u0430 \u043d\u043e\u0434\u0430 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 \u0443\u0437\u043b\u043e\u0432.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043a\u0430\u043a \u043f\u0440\u0438 \u0440\u0443\u0447\u043d\u043e\u043c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0438 \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0434\u043e\u0432 Cluster Autoscaler \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u043d\u043e\u0434\u0443 \u0432 \u0433\u0440\u0443\u043f\u043f\u0443 \u0443\u0437\u043b\u043e\u0432. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0432 \u043f\u0440\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u043d\u0438\u0445. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 Kubernetes \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0435\u0441\u0443\u0440\u0441 HPA (Horizontal Pod Autoscaler). <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/.infra\/yaml\/hpa.yaml\">hpa.yaml<\/a> \u043f\u043e\u0434 \u043d\u0430\u0448\u0443 \u0437\u0430\u0434\u0430\u0447\u0443. \u0417\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0438\u043c\u044f \u2014 converter_hpa. \u0412 scaleTragetRef \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c deployment, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 converter-dp. \u0412 minReplicas \u0438 maxReplicas \u0432\u0432\u043e\u0434\u0438\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u0434\u043e\u0432 \u2014 1 \u0438 5. \u0412 \u0441\u0435\u043a\u0446\u0438\u0438 resource \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 CPU \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043f\u0440\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0432 \u2014 50%. \u041c\u044b \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0438\u0437\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 HPA:<\/p>\n<pre><code>apiVersion: autoscaling\/v2beta1 kind: HorizontalPodAutoscaler metadata:   name: converter-hpa spec:   scaleTargetRef:     apiVersion: apps\/v1     kind: Deployment     name: converter-dp   minReplicas: 1   maxReplicas: 5   metrics:   - type: Resource     resource:       name: cpu       targetAverageUtilization: 50<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c hpa.yaml \u043a Namespace stage:<\/p>\n<pre><code>kubectl -n stage apply -f hpa.yaml<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>kubectl -n stage top pods<\/code>, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044e\u0442 \u043f\u043e\u0434\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8dc\/753\/3a6\/8dc7533a6d9bb0ae804f593ac0dbd3da.jpg\" width=\"724\" height=\"117\"><figcaption><\/figcaption><\/figure>\n<p> \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 get hpa \u0432\u0438\u0434\u0438\u043c \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f CPU \u043d\u0430 15%:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/36a\/1fd\/f6c\/36a1fdf6cdbda0cc5f2323ab4e6c7afd.jpg\" width=\"1044\" height=\"45\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u043c <code>kubectl -n stage describe hpa converter-hpa<\/code> \u043a \u043d\u0430\u0448\u0435\u043c\u0443 converter-hpa \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u0412 \u0441\u0435\u043a\u0446\u0438\u0438 Events \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0434\u043e\u0432 \u0434\u043e \u0434\u0432\u0443\u0445: \u00abNew size: 2\u00bb. Horizontal Pod Autoscaler \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u0434\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d7a\/ed1\/5a4\/d7aed15a40466633f0eeb2ca75f421cb.jpg\" width=\"1534\" height=\"502\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0435 \u043f\u043e\u0434 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f, \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 Pending, \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>kubectl -n stage get pods<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/853\/f9a\/44d\/853f9a44db9eeec3e9d039b8554ddd42.jpg\" width=\"890\" height=\"138\"><figcaption><\/figcaption><\/figure>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u043a \u043d\u043e\u0432\u043e\u043c\u0443 \u043f\u043e\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 describe, \u0442\u043e \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 Events \u0443\u0432\u0438\u0434\u0438\u043c, \u043a\u0430\u043a \u043a \u0441\u043a\u0435\u0439\u043b\u0438\u043d\u0433\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f Cluster Autoscaler. Horizontal Pod Autoscaler \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043e\u0432, \u043d\u043e \u043f\u043e\u0434\u0430\u043c \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u2014 \u0438 Cloud Autoscaler \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0434\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/116\/2bf\/5b8\/1162bf5b8ed6f040f8265bfbd3066b3a.jpg\" width=\"1568\" height=\"164\"><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0441\u0445\u0435\u043c\u0430 \u0441 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435\u043c CPU \u043d\u0435 \u0441\u0430\u043c\u0430\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043e\u0434\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. Worker \u0431\u0435\u0440\u0435\u0442 \u0435\u0433\u043e \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0432\u0435\u0441\u044c CPU. \u0412 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u044d\u0442\u043e HPA \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434, \u0430 Cluster Scaler \u2014 \u043d\u043e\u0432\u0443\u044e \u043d\u043e\u0434\u0443. \u041d\u043e \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0435\u0449\u0435 \u043d\u0435\u0442, \u0438 \u043f\u043e\u0434\u0443 \u043d\u0435\u0447\u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u2014 \u0432 \u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u043f\u043b\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u043d\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0430\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u043d\u0435 CPU, \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c HPA \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0431\u044b\u043b\u043e \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0433\u043e. \u0415\u0441\u043b\u0438 \u0438\u0445 \u0431\u043e\u043b\u044c\u0448\u0435 \u2014 \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043e\u0432. <\/p>\n<p>\u0412 Kubernetes api-resources \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438. \u041e\u043d\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 metrics.k8s.io. \u0417\u0430 \u043d\u0438\u0445 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 kube-system\/metrics-server. Metrics-server \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u043f\u043e\u0434\u0430\u043c\u0438, \u043d\u043e\u0434\u0430\u043c\u0438 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b PodMetrics \u0438 NodeMetrics, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 Horizontal Pod Autoscaler \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u0434\u043e\u0432. <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>kubectl -n stage get podmetrics<\/code>, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 PodMetrics \u043d\u0430\u0448\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/397\/1d6\/fd2\/3971d6fd29e2b8f8e57d1977fe9ed421.jpg\" width=\"528\" height=\"140\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0437\u0432\u0430\u0432 \u0442\u0443 \u0436\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>kubectl -n stage get pods podmetrics rabbitmq-0 -o yaml<\/code> \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 rabbitmq-0, \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e RabbitMQ, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443 \u043d\u0430\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 121 \u043c\u0438\u043b\u043b\u0438\u044f\u0434\u0440\u043e \u0438 119 \u041c\u0411 \u043f\u0430\u043c\u044f\u0442\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/76d\/69c\/1f9\/76d69c1f9ece5b50e24ad96392063a1f.jpg\" width=\"1189\" height=\"323\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0448\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043c\u0435\u0442\u0440\u0438\u043a \u0434\u043b\u044f RabbitMQ \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 HPA. <\/p>\n<p>\u0412 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0443\u0435\u043c \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Prometheus, \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c CI\/CD \u0438 \u0434\u0430\u0436\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 Helm-\u0447\u0430\u0440\u0442.<\/p>\n<blockquote>\n<p>\u041d\u043e\u0432\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b Mail.ru Cloud Solutions \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b <a href=\"https:\/\/mcs.mail.ru\/containers\/#support\">3000 \u0431\u043e\u043d\u0443\u0441\u043e\u0432<\/a> \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u043d\u043e\u0439 \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430. \u0412\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b.<\/p>\n<p>\u0418 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0441\u0442\u0443\u043f\u0430\u0439\u0442\u0435<a href=\"https:\/\/t.me\/joinchat\/AAAAAETc75B9xuzl3n0-sQ\">&nbsp;<em><u>\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e<\/u><\/em><\/a><em>&nbsp;Rebrain \u0432 Telegram \u2014 \u0442\u0430\u043c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0437 \u0441\u0444\u0435\u0440\u044b Devops, \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u044e\u0442 \u0432\u0435\u0449\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f \u0438 \u043d\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\u0445, \u0438 \u0432 \u0440\u0430\u0431\u043e\u0442\u0435.<\/em><\/p>\n<\/blockquote>\n<p>\u0427\u0442\u043e \u0435\u0449\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e \u0442\u0435\u043c\u0435:<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/mcs.mail.ru\/blog\/razvorachivaem-kubernetes-na-mcs\">\u041a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 MCS<\/a>.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/mcs.mail.ru\/blog\/zapuskaem-etcd-klaster-dlya-kubernetes\">\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c etcd-\u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f Kubernetes<\/a>.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/519366\/\">\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d Kubernetes aaS \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Mail.ru Cloud Solutions<\/a>.<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/549804\/\"> https:\/\/habr.com\/ru\/company\/mailru\/blog\/549804\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443\u043c\u0430 \u043f\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044e <a href=\"https:\/\/mcs.mail.ru\/containers\/\">Kubernetes-\u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u043d\u0430 \u0431\u0430\u0437\u0435 \u043e\u0431\u043b\u0430\u043a\u0430 Mail.ru Cloud Solutions<\/a> \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e MVP \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0435\u0433\u043e \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u0431\u0430\u0446\u0438\u044e \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 YouTube.<\/p>\n<p>\u042f \u0412\u0430\u0441\u0438\u043b\u0438\u0439 \u041e\u0437\u0435\u0440\u043e\u0432, \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0430\u0433\u0435\u043d\u0442\u0441\u0442\u0432\u0430 Fevlake \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 DevOps-\u0438\u043d\u0436\u0435\u043d\u0435\u0440 (\u043e\u043f\u044b\u0442 \u0432 DevOps \u2014 8 \u043b\u0435\u0442), \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0441\u0435 \u044d\u0442\u0430\u043f\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Cloud-Native \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 K8s: \u043e\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0434\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f CI\/CD \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e Helm-\u0447\u0430\u0440\u0442\u0430.<\/p>\n<p>\u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0432 <a href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/549680\/\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 API-\u0441\u0435\u0440\u0432\u0435\u0440, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 Kubernetes c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c \u0438 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u043c\u0438 \u0431\u0430\u0437\u0430\u043c\u0438, \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 RabbitMQ \u0447\u0435\u0440\u0435\u0437 Helm \u0432 Kubernetes. \u0421\u0435\u0439\u0447\u0430\u0441 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0434 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435. <\/p>\n<blockquote>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443\u043c\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c: <a href=\"https:\/\/www.youtube.com\/watch?v=8rchh2qRzEE&amp;feature=youtu.be\">\u0447\u0430\u0441\u0442\u044c 1<\/a>, <a href=\"https:\/\/www.youtube.com\/watch?v=sKuHz5-GdaI&amp;feature=youtu.be\">\u0447\u0430\u0441\u0442\u044c 2<\/a>, <a href=\"https:\/\/www.youtube.com\/watch?v=pXRtzQjLGUE&amp;feature=youtu.be\">\u0447\u0430\u0441\u0442\u044c 3<\/a>.<\/p>\n<\/blockquote>\n<h3>\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 Worker \u043d\u0430 Python<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432 (Worker), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 RabbitMQ \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412 \u0438\u0445 \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u0445\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0438\u0434\u0435\u043e, \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043d\u0435\u0433\u043e \u0430\u0443\u0434\u0438\u043e, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0432 \u0431\u0430\u043a\u0435\u0442 S3. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Python. \u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\">\u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435<\/a>.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0444\u0430\u0439\u043b <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/worker.py\">worker.py<\/a>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 os, sys, time, logging, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 JSON (json), HTTP (requests), RabbitMQ (pika) \u0438  Environment-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 (Env). \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0438\u0434\u0435\u043e \u0441 Youtube, \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/www.youtube-dl.org\/\">youtube_dl<\/a>. \u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 S3 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c boto3: <\/p>\n<pre><code># System modules import json import os import sys import time import logging import subprocess  # Third party modules import pika import requests from environs import Env import youtube_dl import boto3 from urllib import parse<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/.env\">.env<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0441 \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0442\u0443\u0434\u0430 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0435\u0442 Kubernetes \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 configMap \u2014 \u0436\u0435\u0441\u0442\u043a\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u0432 Docker-\u043e\u0431\u0440\u0430\u0437\u0435 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c:<\/p>\n<pre><code>## read config env = Env() env.read_env()  # read .env file, if it exists  rabbitmq_host = env(\"RABBIT_HOST\", 'localhost') rabbitmq_port = env(\"RABBIT_PORT\", 5672) rabbitmq_user = env(\"RABBIT_USER\") rabbitmq_pass = env(\"RABBIT_PASS\") rabbitmq_queue = env(\"RABBIT_QUEUE\", \"AutoUrlTemplateQueue\")  api_url = env(\"API_URL\") api_key = env(\"API_KEY\")  s3_endpoint = env(\"S3_ENDPOINT\") s3_web = env(\"S3_WEB\") s3_access_key = env(\"S3_ACCESS_KEY\") s3_secret_key = env(\"S3_SECRET_KEY\") s3_bucket = env(\"S3_BUCKET\")<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u043f\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c:<\/p>\n<ul>\n<li>\n<p>RABBIT_HOST, RABBIT_PORT, RABBIT_USER, RABBIT_PASS \u0438 RABBIT_QUEUE \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 RabbitMQ.<\/p>\n<\/li>\n<li>\n<p>API_URL \u0438 API_KEY \u2014 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0438\u0434\u0435\u043e \u043d\u0430 API-\u0441\u0435\u0440\u0432\u0435\u0440. <\/p>\n<\/li>\n<li>\n<p>S3_ENDPOINT \u2014 Endpoint \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a S3: \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u043e\u0442 AWS \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435.<\/p>\n<\/li>\n<li>\n<p>S3_WEB \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 URL \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0445 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0432\u0438\u0434\u0435\u043e. <\/p>\n<\/li>\n<li>\n<p>S3_ACCESS_KEY, S3_SECRET_KEY \u0438 S3_BUCKET \u2014 \u044d\u0442\u043e \u043a\u043b\u044e\u0447\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0431\u0430\u043a\u0435\u0442 S3, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0444\u0430\u0439\u043b\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a RabbitMQ \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430 S3:<\/p>\n<pre><code># Connecting to rabbitmq credentials = pika.PlainCredentials(rabbitmq_user, rabbitmq_pass) connection = pika.BlockingConnection(pika.ConnectionParameters(rabbitmq_host, rabbitmq_port, '\/', credentials)) channel = connection.channel()  s3client = boto3.client('s3', endpoint_url=s3_endpoint, aws_access_key_id = s3_access_key, aws_secret_access_key = s3_secret_key)<\/code><\/pre>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435:<\/p>\n<pre><code># Setting logger logging.basicConfig(   format='%(asctime)s | %(levelname)-7s | %(name)-12s | %(message)s',   datefmt='%d-%b-%y %H:%M:%S',   level=logging.INFO )  logger = logging.getLogger(__name__)<\/code><\/pre>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0447\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f process_event \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u044f Auto Acknowledgement (auto_ack=false). \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0430 \u0431\u0443\u0434\u0435\u043c \u0436\u0434\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 channel.start_consuming \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043a RabbitMQ \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f Ctrl+C \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u0432\u0435\u0442\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c sys.exit(0):<\/p>\n<pre><code># Starting consuming rabbitmq queue logger.info('Waiting for messages. To exit press CTRL+C')  channel.basic_consume(queue=rabbitmq_queue, on_message_callback=process_event, auto_ack=False)  try:     channel.start_consuming() except KeyboardInterrupt:     logger.info('Interrupted')     try:         sys.exit(0)     except SystemExit:         os._exit(0)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/gitlab.rebrainme.com\/webinars\/video-api-worker\/-\/blob\/master\/worker.py#L48\">process_event<\/a>. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 RabbitMQ \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0442\u0430\u0439\u043c\u0435\u0440 \u0434\u043b\u044f \u043e\u0442\u0441\u0447\u0435\u0442\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c JSON \u0438\u0437 \u0442\u0435\u043b\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043f\u0430\u0440\u0441\u0438\u043c \u0435\u0433\u043e, \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044f \u0434\u0432\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435: \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (name) \u0438 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 Youtube-\u0432\u0438\u0434\u0435\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c (video_url). \u041b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430:<\/p>\n<pre><code># Processing event from rabbit and sending to internal queue def process_event(ch, method, properties, body):     logger.info(\"Got new message from rabbitmq %r\" % body)     t_start = time.time()      # Parsing data     event = json.loads(body)      name = event['name']     video_url = event['video_url']      logger.info(\"Got name: \" + str(name) + \", video_url: \" + str(video_url))<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c .wav:<\/p>\n<pre><code># Removing audio.wav before downloading os.chdir(\"\/app\") filelist = [ f for f in os.listdir(\"\/app\") if f.endswith(\".wav\") ] for f in filelist:   os.remove(os.path.join(\"\/app\", f))<\/code><\/pre>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0431\u043b\u043e\u043a\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0432\u0438\u0434\u0435\u043e \u0441 YouTube, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f YouTube Downloader (youtube_dl).<\/p>\n<p>\u041f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0446\u0438\u0439 ydl_opts. \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0443\u0434\u0438\u043e, \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e (keepvideo: False). \u0412 \u0431\u043b\u043e\u043a\u0435 postprocessors \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c FFmpeg, \u043a\u043e\u0434\u0435\u043a wav \u0438 quality 192 \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0444\u0430\u0439\u043b\u0430. \u0412 \u0431\u043b\u043e\u043a\u0435 postprocessor_args \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c rate, \u0440\u0430\u0432\u043d\u044b\u0439 16 \u043a\u0413\u0446, \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0430\u0443\u0434\u0438\u043e, \u0440\u0430\u0432\u043d\u043e\u0435 1. <\/p>\n<p>\u041d\u0430 YouTube \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u0432\u0438\u0434\u0435\u043e stereo, \u043d\u043e \u043d\u0430\u043c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e mono, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043e\u0444\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0435\u0447\u044c \u0432 \u0442\u0435\u043a\u0441\u0442, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 mono-\u0430\u0443\u0434\u0438\u043e\u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u0412 \u043f\u043e\u043b\u0435 outtmpl \u0432\u0432\u043e\u0434\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f \u0438\u043c\u0435\u043d\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430: &lt;ID \u0432\u0438\u0434\u0435\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438&gt;.&lt;\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 (wav)&gt;.<\/p>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 ydl.download \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c video_url, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0438\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f RabbitMQ. \u041f\u0440\u0438 \u043b\u044e\u0431\u043e\u043c \u0441\u0431\u043e\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u043b\u043e\u0433 \u0437\u0430\u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u00abCan\u2019t download audio file\u00bb, \u0430 \u0432 API \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u00abError downloading video\u00bb. \u0418 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0438\u0434\u0435\u043e \u043a\u043b\u0438\u0435\u043d\u0442 \u0443\u0432\u0438\u0434\u0438\u0442 \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<pre><code># Downloading video     ydl_opts = {         'format': 'bestaudio\/best',         'postprocessors': [{             'key': 'FFmpegExtractAudio',             'preferredcodec': 'wav',             'preferredquality': '192'         }],         'postprocessor_args': [             '-ar', '16000', '-ac', '1'         ],         'prefer_ffmpeg': True,         'keepvideo': False,         'outtmpl': '%(id)s.%(ext)s'     }      try:       with youtube_dl.YoutubeDL(ydl_opts) as ydl:         ydl.download([video_url])     except:       logger.error(\"Can't download audio file, sending callback\")       headers = {\"X-API-KEY\": api_key}       payload = {\"processed\": True, \"text_url\": \"Error downloading video\"}       r = requests.put(api_url + '\/requests\/' + name, data=json.dumps(payload), headers=headers)       logger.info(\"Callback sent, response code: \" + str(r.status_code))       return<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u2013 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0446\u0435\u043b\u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/Picovoice\/leopard\">Leopard<\/a> \u043e\u0442 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Picovoice. Leopard \u0447\u0438\u0442\u0430\u0435\u0442 wav-\u0444\u0430\u0439\u043b \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0432 \u0442\u0435\u043a\u0441\u0442. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0431\u0435\u0437 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u043c API. \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043b\u0430\u0442\u043d\u044b\u0439, \u043d\u043e \u0434\u043b\u044f \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u0442\u044c 30-\u0434\u043d\u0435\u0432\u043d\u044b\u0439 \u0442\u0440\u0438\u0430\u043b. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 real-time \u0440\u0435\u0436\u0438\u043c\u0435 \u0443 \u044d\u0442\u043e\u0433\u043e \u0436\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 <a href=\"https:\/\/github.com\/Picovoice\/cheetah\">Cheetah<\/a>.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Leopard \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432 GitHub \u0435\u0441\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f: \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c GNU C Compiler (GCC) \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430 \u043d\u0430 C.<\/p>\n<p>\u041c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Leopard, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043f\u0443\u0442\u044c \u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 C, \u043a \u0430\u043a\u0443\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044f\u043c, \u043a \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u043c \u043c\u043e\u0434\u0435\u043b\u044f\u043c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b (\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435 Picovoice) \u0438 wav-\u0444\u0430\u0439\u043b. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432 stdout \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u043f\u0442 \u0430\u0443\u0434\u0438\u043e \u0432 \u0442\u0435\u043a\u0441\u0442. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0431\u043e\u0435\u0432 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043a\u0430\u043a \u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0448\u0430\u0433\u0435, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e callback \u0447\u0435\u0440\u0435\u0437 API:<\/p>\n<pre><code># Converting audio to text     logger.info(\"Converting audio to text\")     try:       p = subprocess.Popen(\"\/app\/leopard\/leopard_demo        leopard\/lib\/linux\/x86_64\/libpv_leopard.so        leopard\/lib\/common\/acoustic_model.pv leopard\/lib\/common\/language_model.pv license.lic *.wav\", stdout=subprocess.PIPE, shell=True)       (output, err) = p.communicate()       p_status = p.wait()       logger.info(\"Command output : \" + str(output))       logger.info(\"Command exit status\/return code : \" + str(p_status))     except:       logger.error(\"Can't convert audio to text, sending callback\")       headers = {\"X-API-KEY\": api_key}       payload = {\"processed\": True, \"text_url\": \"Error converting audio\"}       r = requests.put(api_url + '\/requests\/' + name, data=json.dumps(payload), headers=headers)       logger.info(\"Callback sent, response code: \" + str(r.status_code))       return<\/code><\/pre>\n<p>\u0418 \u0434\u0430\u043b\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0448 \u0442\u0440\u0430\u043d\u0441\u043a\u0440\u0438\u043f\u0442, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0432 output, \u043d\u0430 S3. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0431\u0430\u043a\u0435\u0442\u0430 \u0431\u0435\u0440\u0435\u043c \u0438\u0437 environment-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 S3_BUCKET. \u041f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434: &lt;URL \u0431\u0430\u043a\u0435\u0442\u0430 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 S3_WEB&gt;\/converted\/&lt;name \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430&gt;.txt. \u0412 ACL \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c public-read, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u043c\u043e\u0433\u043b\u0438 \u043f\u0440\u043e\u0447\u0435\u0441\u0442\u044c \u0444\u0430\u0439\u043b:<\/p>\n<pre><code>   # Uploading file to s3     try:       s3client.put_object(Body=output, Bucket=s3_bucket, Key='converted\/' + name + '.txt', ACL='public-read')     except:       logger.error(\"Can't upload text to s3, sending<\/code><\/pre>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-321114","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/321114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=321114"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/321114\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=321114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=321114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=321114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}