{"id":500351,"date":"2026-10-26T16:16:29","date_gmt":"2026-10-26T13:16:29","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=500351"},"modified":"2026-10-26T16:16:29","modified_gmt":"2026-10-26T13:16:29","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=500351","title":{"rendered":"NKT: \u041a\u0438\u043b\u043b\u0435\u0440 \u0444\u0438\u0447\u0430 \u21167, \u0441\u043a\u0440\u0438\u043f\u0442\u044b: \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u044c \u2014 \u0441\u0435\u0441\u0442\u0440\u0430 \u0442\u0430\u043b\u0430\u043d\u0442\u0430"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0424\u0438\u043b\u043e\u0441\u043e\u0444\u0438\u044f: \u043f\u043e\u0447\u0435\u043c\u0443 29, \u0430 \u043d\u0435 290<\/h3>\n<p>\u042f\u0437\u044b\u043a \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 <a href=\"https:\/\/github.com\/piqab\/nkt\">NKT<\/a> \u2014 <strong>\u043f\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0439 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f<\/strong>. \u041e\u043d \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: \u0432 \u043d\u0451\u043c \u043d\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u0439, \u0446\u0438\u043a\u043b\u043e\u0432 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u042d\u0442\u043e \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440.<\/p>\n<p><strong>\u041f\u0440\u0438\u043d\u0446\u0438\u043f:<\/strong> \u044f\u0437\u044b\u043a \u0440\u0435\u0448\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u2014 <em>\u00ab\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0438 \u0441\u0435\u0440\u0432\u0438\u0441, \u043f\u0440\u043e\u0432\u0435\u0440\u044c, \u0447\u0442\u043e \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0438, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e\u00bb<\/em>. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b \u0441\u043e\u0442\u043d\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439. \u041d\u0443\u0436\u043d\u044b 29 \u0433\u043b\u0430\u0433\u043e\u043b\u043e\u0432.<\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0433\u043b\u0430\u0433\u043e\u043b \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435:<\/p>\n<ul>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442<\/p>\n<\/li>\n<li>\n<p>\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043b\u0443\u0436\u0431\u043e\u0439<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0435\u043a<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0412\u041c<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437 29 \u0433\u043b\u0430\u0433\u043e\u043b\u043e\u0432 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u043b\u044e\u0431\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u2014 \u0435\u0441\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0442 \u044f\u0437\u044b\u043a \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u044f\u0434\u0440\u0430.<\/p>\n<hr\/>\n<h3>\u0412\u0441\u0435 29 \u043a\u043e\u043c\u0430\u043d\u0434<\/h3>\n<h4>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>set<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>set \u0418\u041c\u042f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/code> \u0438\u043b\u0438 <code>set \u0418\u041c\u042f ask<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>set IMAGE ubuntu-24.04<\/code>  <code>set DB_PASS ask<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>param<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>param \u0418\u041c\u042f \"\u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430\"<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>param HOST \"\u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0445\u043e\u0441\u0442\"<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>set<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u0430\u043a <code>${\u0418\u041c\u042f}<\/code>. \u0412\u0430\u0440\u0438\u0430\u043d\u0442 <code>ask<\/code> \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0438 <strong>\u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u0442\u0435\u043a\u0441\u0442 \u0438 \u0436\u0443\u0440\u043d\u0430\u043b<\/strong> \u2014 \u0434\u043b\u044f \u043f\u0430\u0440\u043e\u043b\u0435\u0439 \u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<p><code>param<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u043e\u0439. \u0422\u0430\u043a \u043e\u0434\u0438\u043d \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0442\u0435\u043d\u0434\u044b. \u041d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 (<code>Script.Unresolved<\/code>).<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440:<\/strong><\/p>\n<pre><code class=\"yaml\">set IMAGE ubuntu-24.04set DB_PASS askparam ADDR \"\u0430\u0434\u0440\u0435\u0441 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430\"param NAME \"\u0438\u043c\u044f \u0445\u043e\u0441\u0442\u0430 \u0432 \u0445\u0430\u0431\u0435\"host ${NAME} ${ADDR} user root password ask<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper\"><\/span><\/a><\/div><\/pre>\n<hr\/>\n<h4>\u0425\u043e\u0441\u0442\u044b \u0438 \u0433\u0440\u0443\u043f\u043f\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>group<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>group \u0418\u041c\u042f [profile \u041f\u0420\u041e\u0424\u0418\u041b\u042c]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>group web-farm profile web-base<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>host<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>host \u0418\u041c\u042f \u0410\u0414\u0420\u0415\u0421[:\u041f\u041e\u0420\u0422] user \u041f\u041e\u041b\u042c\u0417\u041e\u0412\u0410\u0422\u0415\u041b\u042c \u2026<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>host web1 192.0.2.10 user root password ask<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>install<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>install \u0425\u041e\u0421\u0422\u2026<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>install web1 web2<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>wait<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>wait \u0425\u041e\u0421\u0422 online [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>wait web1 online 5m<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>group<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 \u0445\u043e\u0441\u0442\u043e\u0432 \u043d\u0430 \u0445\u0430\u0431\u0435. \u0421 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c \u2014 \u043c\u0430\u0448\u0438\u043d\u044b, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432 \u043d\u0435\u0439, \u0434\u0435\u043b\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u043d\u0435\u043c\u0443.<\/p>\n<p><code>host<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0445\u043e\u0441\u0442 \u043d\u0430 \u0445\u0430\u0431 \u043f\u043e SSH \u2014 \u0442\u043e \u0436\u0435, \u0447\u0442\u043e \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0445\u043e\u0441\u0442\u00bb \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435. \u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438: <code>password ask<\/code>, <code>password \"\u2026\"<\/code>, <code>key hub<\/code>.<\/p>\n<p><code>install<\/code> \u0441\u0442\u0430\u0432\u0438\u0442 <code>nkt<\/code> \u043d\u0430 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0445\u043e\u0441\u0442\u044b \u0438 \u0436\u0434\u0451\u0442, \u043f\u043e\u043a\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u0432\u0435\u0442\u0438\u0442.<\/p>\n<p><code>wait<\/code> \u0438\u043c\u0435\u0435\u0442 \u043f\u044f\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432:<\/p>\n<pre><code>wait \u0425\u041e\u0421\u0422 online [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait \u0425\u041e\u0421\u0422 port \u041f\u041e\u0420\u0422 [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait \u0425\u041e\u0421\u0422 http URL [\u041a\u041e\u0414] [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait \u0425\u041e\u0421\u0422 service \u0418\u041c\u042f active [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait url URL [\u041a\u041e\u0414] [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0430\u0434\u0440\u0435\u0441\u0430 \u0441\u043d\u0430\u0440\u0443\u0436\u0438: \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u0445\u0430\u0431\u0430 \u043f\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u0438 (DNS, \u0448\u043b\u044e\u0437, \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f), \u0445\u043e\u0441\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440:<\/strong><\/p>\n<pre><code class=\"yaml\">host web1 192.0.2.10 user root password ask group web-farmhost web2 192.0.2.11:2222 user deploy key hubinstall web1 web2wait web1 online 5mwait web1 port 443 30swait web1 service nginx activewait url https:\/\/git.example.com\/api\/healthz 200 10m<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<hr\/>\n<h4>\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: \u043f\u0430\u043a\u0435\u0442\u044b, \u0441\u043b\u0443\u0436\u0431\u044b, \u0444\u0430\u0439\u0440\u0432\u043e\u043b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>packages<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422\u2026 packages install|remove \u041f\u0410\u041a\u0415\u0422\u2026<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 packages install nginx htop<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>service<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 service \u0418\u041c\u042f start|stop|restart|reload|enable|disable<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 service nginx restart<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>firewall<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 firewall allow|deny \u041f\u041e\u0420\u0422[\/tcp|udp] [from CIDR]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 firewall allow 443\/tcp<\/code>  <code>on web1 firewall allow 5432 from 10.0.0.0\/24<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0430\u043a\u0435\u0442\u044b \u0441\u0442\u0430\u0432\u044f\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439. \u0424\u0430\u0439\u0440\u0432\u043e\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 <code>ufw<\/code> \u0438\u043b\u0438 <code>firewalld<\/code> \u2014 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u043d\u0430 \u0445\u043e\u0441\u0442\u0435.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440:<\/strong><\/p>\n<pre><code class=\"yaml\">on web1 web2 web3 packages install nginx htopon web1 web2 web3 service nginx enableon web1 web2 web3 service nginx starton web1 web2 web3 firewall allow 80\/tcpon web1 web2 web3 firewall allow 443\/tcp<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<hr\/>\n<h4>\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: Docker \u0438 \u0412\u041c<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>docker install<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 docker install<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 docker install<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>docker stack<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 docker stack \u041f\u0423\u0422\u042c up|down|start|stop<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 docker stack \/srv\/app\/docker-compose.yml up<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>vm create<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 vm create \u0418\u041c\u042f image \u041e\u0411\u0420\u0410\u0417 [\u043e\u043f\u0446\u0438\u0438]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 vm create app1 image ubuntu-24.04 cpu 2 mem 2048 disk 20 install<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>vm start\/shutdown\/destroy<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 vm start|shutdown|destroy \u0418\u041c\u042f<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 vm start app1<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>docker stack<\/code> \u0438\u043c\u0435\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><code>up<\/code> \u2014 \u043f\u043e\u0434\u043d\u044f\u0442\u044c (\u0441\u043a\u0430\u0447\u0430\u0432 \u043e\u0431\u0440\u0430\u0437\u044b, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e)<\/p>\n<\/li>\n<li>\n<p><code>down<\/code> \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438 \u0443\u0431\u0440\u0430\u0442\u044c<\/p>\n<\/li>\n<li>\n<p><code>start<\/code> \u2014 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u043c\u0435\u044e\u0449\u0435\u0435\u0441\u044f <strong>\u0431\u0435\u0437 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a registry<\/strong><\/p>\n<\/li>\n<li>\n<p><code>stop<\/code> \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c, \u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b<\/p>\n<\/li>\n<\/ul>\n<p>\u0421 \u0431\u043b\u043e\u043a\u043e\u043c \u0434\u043e <code>end<\/code> \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 compose-\u0444\u0430\u0439\u043b \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438:<\/p>\n<pre><code class=\"yaml\">on web1 docker stack \/srv\/app\/docker-compose.yml upservices:  web:    image: nginx:alpine    ports:      - \"8080:80\"end<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0421\u0442\u0435\u043a, \u0432\u044b\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u043e\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0438 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>deploy \u041a\u041e\u041d\u0412\u0415\u0419\u0415\u0420 start|stop<\/code> \u2014 \u00ab\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c\u00bb \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u043e\u043c\u043d\u0438\u0442.<\/p>\n<p><code>vm create<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u043c\u0430\u0448\u0438\u043d\u0443 \u0438\u0437 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430. \u041e\u043f\u0446\u0438\u0438: <code>cpu<\/code>, <code>mem<\/code>, <code>disk<\/code>, <code>user<\/code>, <code>network<\/code>, <code>profile<\/code>, <code>install<\/code> (\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c <code>nkt<\/code> \u0432\u043d\u0443\u0442\u0440\u044c).<\/p>\n<hr\/>\n<h4>\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: \u0444\u0430\u0439\u043b\u044b, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438, \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b, git<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>file put<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 file put \u041f\u0423\u0422\u042c [mode 0644]<\/code> + \u0431\u043b\u043e\u043a \u0434\u043e <code>end<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 file put \/etc\/motd<\/code>  <code>\u0413\u043e\u0442\u043e\u0432\u043e<\/code>  <code>end<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>user add<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 user add \u0418\u041c\u042f [sudo] [key \"\u2026\"]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 user add deploy sudo key \"ssh-ed25519 \u2026\"<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>system<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 system hostname|timezone|locale|ntp \u0417\u041d\u0410\u0427\u0415\u041d\u0418\u0415<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 system timezone Europe\/Moscow<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>cert<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 cert issue|renew \u0414\u041e\u041c\u0415\u041d\u2026<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 cert issue <\/code><a href=\"http:\/\/example.org\"><code>example.org<\/code><\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>git clone<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 git clone URL \/\u041a\u0410\u0422\u0410\u041b\u041e\u0413 [\u043e\u043f\u0446\u0438\u0438]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web1 git clone <\/code><a href=\"https:\/\/github.com\/org\/app.git\"><code>https:\/\/github.com\/org\/app.git<\/code><\/a><code> \/srv\/app branch main token ask<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>cert issue<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 <code>certbot --standalone<\/code>: \u0441\u043b\u0443\u0436\u0431\u044b \u043d\u0430 80\/443 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0441\u043d\u043e\u0432\u0430.<\/p>\n<p><code>git clone<\/code> \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0445 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432: <code>token ask<\/code> (\u0441\u043f\u0440\u043e\u0441\u044f\u0442 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435) \u0438\u043b\u0438 <code>key hub<\/code> (deploy-\u043a\u043b\u044e\u0447 \u0445\u043e\u0441\u0442\u0430).<\/p>\n<hr\/>\n<h4>\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 \u0438 Kubernetes<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>apply profile<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 apply profile \u041f\u0420\u041e\u0424\u0418\u041b\u042c<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on web2 apply profile web-base<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>k8s create<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 k8s create \u0418\u041c\u042f [\u043e\u043f\u0446\u0438\u0438]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on hv1 k8s create lab flavor kubeadm nodes \"hv1: cp 1, w 2\" cni cilium expose<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>k8s destroy<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on \u0425\u041e\u0421\u0422 k8s destroy \u0418\u041c\u042f<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>on hv1 k8s destroy lab<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>k8s create<\/code> \u2014 \u0441\u0430\u043c\u0430\u044f \u00ab\u0442\u044f\u0436\u0451\u043b\u0430\u044f\u00bb \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u044f\u0437\u044b\u043a\u0430. \u0421\u043e\u0437\u0434\u0430\u0451\u0442 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u043d\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445: \u043c\u0430\u0448\u0438\u043d\u044b \u0438\u0437 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430, control plane, \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u043e\u0432, \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 Ready, \u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u043f\u043e\u0440\u0442\u043e\u0432, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 kubeconfig \u043d\u0430 \u0445\u0430\u0431.<\/p>\n<p>\u041e\u043f\u0446\u0438\u0438: <code>flavor<\/code> (k3s \u0438\u043b\u0438 kubeadm), <code>nodes<\/code> (\u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u043e \u0445\u043e\u0441\u0442\u0430\u043c), <code>image<\/code>, <code>cpu\/mem\/disk<\/code>, <code>network<\/code>, <code>cni<\/code>, <code>no-kube-proxy<\/code>, <code>version<\/code>, <code>expose<\/code>, <code>api\/http\/https<\/code> \u043f\u043e\u0440\u0442\u044b.<\/p>\n<hr\/>\n<h4>\u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b, \u0432\u044b\u043a\u043b\u0430\u0434\u043a\u0438, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>pipeline<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>pipeline \u0418\u041c\u042f ... end<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>pipeline hello<\/code>  <code>repo: <\/code><a href=\"https:\/\/github.com\/org\/app.git\"><code>https:\/\/github.com\/org\/app.git<\/code><\/a>  <code>action: compose<\/code>  <code>compose:<\/code>  <code>file: docker-compose.yml<\/code>  <code>hosts: [web1]<\/code>  <code>env:<\/code>  <code>DB_PASSWORD: generate:password<\/code>  <code>end<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>deploy<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>deploy \u041a\u041e\u041d\u0412\u0415\u0419\u0415\u0420 [start|stop] [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>deploy hello 20m<\/code>  <code>deploy shop stop<\/code>  <code>deploy shop start<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>migrate<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>migrate \u0425\u041e\u0421\u0422 \u041a\u041e\u041d\u0422\u0415\u0419\u041d\u0415\u0420 to \u0425\u041e\u0421\u0422 [\u043e\u043f\u0446\u0438\u0438]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>migrate web1 app-1 to web2 switch-fly switch-pipeline<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>pipeline<\/code> \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0432\u044b\u043a\u043b\u0430\u0434\u043a\u0438. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>env:<\/code> \u0443\u0445\u043e\u0434\u044f\u0442 \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u0430. <code>generate:<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043f\u0430\u0440\u043e\u043b\u044c, \u0442\u043e\u043a\u0435\u043d) \u043d\u0430 \u0445\u0430\u0431\u0435.<\/p>\n<p><code>deploy<\/code> \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0438 \u0436\u0434\u0451\u0442 \u0438\u0442\u043e\u0433\u0430. \u0421 <code>start<\/code> \u0438\u043b\u0438 <code>stop<\/code> \u2014 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0443\u0436\u0435 \u0432\u044b\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u043d\u0430 \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u0445\u043e\u0441\u0442\u0430\u0445.<\/p>\n<p><code>migrate<\/code> \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0441\u0442\u0435\u043a \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0445\u043e\u0441\u0442: \u043f\u043b\u0430\u043d \u0441 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f\u043c\u0438 \u0434\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u0442\u0435\u043a\u0430, \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430, \u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 \u0445\u0430\u0431, \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0430 \u043d\u043e\u0432\u043e\u043c. \u0423\u043f\u0430\u0432\u0448\u0438\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 <strong>\u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c<\/strong>. \u041e\u043f\u0446\u0438\u0438: <code>switch-fly<\/code>, <code>switch-pipeline<\/code>, <code>clean-leftovers<\/code>.<\/p>\n<hr\/>\n<h4>Kubernetes: Ingress, \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u044b, \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>k8s ingress<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>k8s \u041a\u041b\u0410\u0421\u0422\u0415\u0420 ingress cilium [port \u041f\u041e\u0420\u0422]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>k8s lab ingress cilium port 8080<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>k8s apply<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>k8s \u041a\u041b\u0410\u0421\u0422\u0415\u0420 apply<\/code> + \u0431\u043b\u043e\u043a \u0434\u043e <code>end<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>k8s lab apply<\/code>  <code>apiVersion: v1<\/code>  <code>kind: Namespace<\/code>  <code>metadata:<\/code>  <code>name: demo<\/code>  <code>end<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>k8s wait<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>k8s \u041a\u041b\u0410\u0421\u0422\u0415\u0420 wait deployment \u0418\u041c\u042f [\u043e\u043f\u0446\u0438\u0438]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>k8s lab wait deployment hello 5m<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><code>k8s apply<\/code> \u0432 \u0441\u0443\u0445\u043e\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <code>kubectl diff<\/code> \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<hr\/>\n<h4>Traffic Fly<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>fly route<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>fly route \u0418\u0414 \u0412\u0418\u0414 [\u043e\u043f\u0446\u0438\u0438]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>fly route hello https names <\/code><a href=\"http:\/\/hello.example.com\"><code>hello.example.com<\/code><\/a><code> tls gateway targets cluster lab port 8080<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>fly apply<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>fly apply<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>fly apply<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412\u0438\u0434\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432: <code>https<\/code>, <code>http<\/code>, <code>tcp<\/code>, <code>udp<\/code>, <code>tcpudp<\/code>. \u0426\u0435\u043b\u0438: <code>targets cluster \u041a\u041b\u0410\u0421\u0422\u0415\u0420 port N<\/code> (\u0432\u0441\u0435 \u0443\u0437\u043b\u044b \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430) \u0438\u043b\u0438 <code>target \u0425\u041e\u0421\u0422 container|vm|lxd \u0418\u041c\u042f \u041f\u041e\u0420\u0422<\/code> (\u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0446\u0435\u043b\u044c).<\/p>\n<p>\u041d\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. \u0423 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0446\u0435\u043b\u0438 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043b\u0430\u0432\u043d\u043e: \u043d\u043e\u0432\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f, \u043f\u0440\u0435\u0436\u043d\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u044f\u0442\u0441\u044f. \u0412 \u0441\u0443\u0445\u043e\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u0435 \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u0430\u0440\u0442\u044b \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c.<\/p>\n<hr\/>\n<h3>\u0420\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u043f\u043e\u043b\u043d\u044b\u0439 \u0446\u0438\u043a\u043b<\/h3>\n<p>\u0418\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, <a href=\"https:\/\/github.com\/piqab\/nkt\/blob\/main\/examples\/scripts\/forgejo-fly.nkt\"><code>examples\/scripts\/forgejo-fly.nkt<\/code><\/a>:<\/p>\n<pre><code class=\"yaml\"># Forgejo \u0437\u0430 Traffic Fly: \u0432\u044b\u043a\u043b\u0430\u0434\u043a\u0430 \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0445\u043e\u0441\u0442param FROM \"\u0445\u043e\u0441\u0442, \u0433\u0434\u0435 Forgejo \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043b\u043e\u0436\u0435\u043d \u0441\u043d\u0430\u0447\u0430\u043b\u0430\"param TO \"\u0445\u043e\u0441\u0442, \u043a\u0443\u0434\u0430 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438\"param DOMAIN \"\u0438\u043c\u044f Forgejo \u2014 A-\u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 \u0448\u043b\u044e\u0437\u0430 Traffic Fly\"pipeline forgejo  repo: https:\/\/github.com\/piqab\/nkt.git  ref: main  action: compose  compose:    file: examples\/forgejo\/deploy\/docker-compose.yml    project: forgejo    hosts: [${FROM}]    wait_timeout: 5m    env:      POSTGRES_PASSWORD: generate:password      FORGEJO_DOMAIN: ${DOMAIN}      FORGEJO_ROOT_URL: https:\/\/${DOMAIN}\/      FORGEJO_ADMIN_USER: gitadmin      FORGEJO_ADMIN_PASSWORD: generate:password    fly:      - route: forgejo-web        kind: https        names: [${DOMAIN}]        tls: gateway        service: forgejo        target_port: 3000        check: http        check_path: \/api\/healthz      - route: forgejo-ssh        kind: tcp        port: 2222        service: forgejo        target_port: 2222enddeploy forgejo 20mwait url https:\/\/${DOMAIN}\/api\/healthz 200 10mmigrate ${FROM} forgejo-forgejo-1 to ${TO} switch-fly switch-pipelinewait url https:\/\/${DOMAIN}\/api\/healthz 200 5m<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><strong>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044f\u0437\u044b\u043a \u0432 \u044d\u0442\u043e\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438:<\/strong><\/p>\n<ol>\n<li>\n<p><code>param<\/code> \u2014 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0445\u043e\u0441\u0442\u044b \u0438 \u0434\u043e\u043c\u0435\u043d \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435<\/p>\n<\/li>\n<li>\n<p><code>pipeline<\/code> \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0441 Docker Compose \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u0430\u0440\u043e\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p><code>deploy<\/code> \u2014 \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0438 \u0436\u0434\u0451\u0442 \u0434\u043e 20 \u043c\u0438\u043d\u0443\u0442<\/p>\n<\/li>\n<li>\n<p><code>wait url<\/code> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0448\u043b\u044e\u0437 \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><code>migrate<\/code> \u2014 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438<\/p>\n<\/li>\n<\/ol>\n<p><strong>47 \u0441\u0442\u0440\u043e\u043a.<\/strong> \u0412\u043c\u0435\u0441\u0442\u043e \u0441\u0432\u044f\u0437\u043a\u0438 <code>docker-compose.yml<\/code> + <a href=\"http:\/\/deploy.sh\"><code>deploy.sh<\/code><\/a> + <a href=\"http:\/\/migrate.sh\"><code>migrate.sh<\/code><\/a> + <a href=\"http:\/\/healthcheck.sh\"><code>healthcheck.sh<\/code><\/a>.<\/p>\n<hr\/>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441<\/h3>\n<h4>\u0413\u0434\u0435 \u043d\u0430\u0439\u0442\u0438<\/h4>\n<p><strong>\u041f\u0440\u043e\u0444\u0438\u043b\u0438 \u2192 \u0432\u043a\u043b\u0430\u0434\u043a\u0430 \u00ab\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0438\u00bb \u2192 \u00ab\u041d\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439\u00bb<\/strong><\/p>\n<h4>\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/h4>\n<ol>\n<li>\n<p><strong>\u00ab\u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u25be\u00bb<\/strong> \u2014 \u0432\u044b\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 (Forgejo, Kubernetes). \u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c, \u0435\u0441\u043b\u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u0430\u0432\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u00ab?\u00bb<\/strong> \u2014 \u0437\u043d\u0430\u0447\u043e\u043a \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 \u043e\u043a\u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u0438 \u043d\u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432\u00bb \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u043a\u043b\u0430\u0434\u043a\u0430 \u00ab\u0421\u043f\u0440\u0430\u0432\u043a\u0430\u00bb<\/strong> \u2014 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0442\u0443 \u0436\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u0441\u0430\u0439\u0442\u0430. \u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u0435\u043b\u044c \u00ab\u0421\u0430\u0439\u0442 \/ \u0418\u0437 nkt\u00bb \u2014 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430, \u0435\u0441\u043b\u0438 \u0441\u0430\u0439\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d. \u0412\u044b\u0431\u043e\u0440 \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430<\/strong> \u2014 \u043a\u043d\u043e\u043f\u043a\u0430 \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438. \u0418\u043c\u0435\u043d\u0430 \u0445\u043e\u0441\u0442\u043e\u0432 \u0438\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 (<code>on ${HOST}<\/code>) \u043d\u0435 \u0440\u0443\u0433\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u2014 \u043e\u043d\u0438 \u0441\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f \u043d\u0435 \u043c\u0435\u0448\u0430\u044e\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u0435\u0440\u0441\u0438\u0439<\/strong> \u2014 \u0442\u0430\u0431\u043b\u0438\u0446\u0430: \u2116, \u0432\u0440\u0435\u043c\u044f, \u0430\u0432\u0442\u043e\u0440, \u0437\u0430\u043c\u0435\u0442\u043a\u0430, \u0440\u0430\u0437\u043c\u0435\u0440, \u043c\u0435\u0442\u043a\u0430 \u00ab\u0442\u0435\u043a\u0443\u0449\u0430\u044f\u00bb. \u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u0440\u0435\u0434\u0430\u043a\u0446\u0438\u0438: <strong>\u00ab\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435\u00bb<\/strong> (\u0442\u0435\u043a\u0441\u0442 \u0446\u0435\u043b\u0438\u043a\u043e\u043c), <strong>\u00ab\u0420\u0430\u0437\u043d\u0438\u0446\u0430\u00bb<\/strong> \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439, <strong>\u00ab\u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u00bb<\/strong>.<\/p>\n<\/li>\n<li>\n<p><strong>\u041a\u043d\u043e\u043f\u043a\u0430 \u00ab\u0418\u0418 \u25be\u00bb<\/strong> \u2014 \u0442\u0440\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c<\/strong> \u2014 \u0440\u0430\u0437\u0431\u043e\u0440 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e <\/strong><code><strong># \u0418\u0418:<\/strong><\/code> \u2014 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0438\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e<\/strong> \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0434\u0438\u0444\u0444 \u2014 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442. \u0421\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u043c \u043e\u0442 \u0418\u0418 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0430 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435.<\/p>\n<h4>\u0417\u0430\u043f\u0443\u0441\u043a<\/h4>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u00ab\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u00bb:<\/p>\n<ol>\n<li>\n<p>\u0414\u0438\u0430\u043b\u043e\u0433 \u0441 \u043f\u043e\u043b\u044f\u043c\u0438 \u0434\u043b\u044f \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0445 <code>param<\/code><\/p>\n<\/li>\n<li>\n<p>\u0427\u0435\u043a\u0431\u043e\u043a\u0441 <strong>\u0421\u0443\u0445\u043e\u0439 \u043f\u0440\u043e\u0433\u043e\u043d<\/strong> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0437 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p><strong>\u0416\u0443\u0440\u043d\u0430\u043b \u0437\u0430\u0434\u0430\u043d\u0438\u044f<\/strong> \u2014 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0439 \u043b\u043e\u0433 \u0441 \u0442\u0430\u0439\u043c\u0441\u0442\u0430\u043c\u043f\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 API<\/h3>\n<h4>\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f<\/h4>\n<pre><code class=\"bash\"># \u0421\u043f\u0438\u0441\u043e\u043a \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432curl -H \"Authorization: Bearer $TOKEN\" \\  https:\/\/hub.example.com\/api\/hub\/scripts# \u0417\u0430\u043f\u0443\u0441\u043acurl -X POST \\  -H \"Authorization: Bearer $TOKEN\" \\  -H \"Content-Type: application\/json\" \\  https:\/\/hub.example.com\/api\/hub\/scripts\/42\/run \\  -d '{    \"answers\": {      \"param:FROM\": \"web1\",      \"param:TO\": \"web2\",      \"param:DOMAIN\": \"forgejo.example.com\"    },    \"dry_run\": true  }'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h4>\u041f\u0440\u0430\u0432\u0430 \u0442\u043e\u043a\u0435\u043d\u043e\u0432<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0420\u043e\u043b\u044c<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041c\u043e\u0436\u0435\u0442<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0427\u0442\u0435\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432, \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0443\u0445\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u043e\u043d\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u043f\u0443\u0441\u043a, \u043f\u0435\u0440\u0435\u043d\u043e\u0441, \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u041f\u0440\u0435\u0434\u0435\u043b\u044b<\/strong> \u2014 \u0445\u043e\u0441\u0442\u044b \u0438 \u0433\u0440\u0443\u043f\u043f\u044b, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0442\u043e\u043a\u0435\u043d \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f. \u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0443 \u0434\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430: \u0445\u043e\u0441\u0442\u044b\/\u0433\u0440\u0443\u043f\u043f\u044b \u0432\u043d\u0435 \u043f\u0440\u0435\u0434\u0435\u043b\u0430 \u2014 \u043e\u0442\u043a\u0430\u0437 (<code>scriptScopeError<\/code>).<\/p>\n<p><strong>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u0432:<\/strong> \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u043f\u043e \u0442\u043e\u043a\u0435\u043d\u0443 \u043d\u0435\u043b\u044c\u0437\u044f. \u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0435.<\/p>\n<h4>\u041e\u0448\u0438\u0431\u043a\u0438<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u0447\u0438\u043d\u0430<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>Script.Unresolved<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>scriptScopeError<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u0430\u0437\u0431\u043e\u0440 \u0434\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430: \u0445\u043e\u0441\u0442\u044b\/\u0433\u0440\u0443\u043f\u043f\u044b \u0432\u043d\u0435 \u043f\u0440\u0435\u0434\u0435\u043b\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u00ab\u0425\u043e\u0441\u0442 \u0432\u043d\u0435 \u043f\u0440\u0435\u0434\u0435\u043b\u043e\u0432 API-\u0442\u043e\u043a\u0435\u043d\u0430\u00bb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0425\u043e\u0441\u0442 \u043d\u0435 \u0432 \u0445\u043e\u0441\u0442\u0430\u0445 \u0438\u043b\u0438 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 \u0442\u043e\u043a\u0435\u043d\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<hr\/>\n<h3>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 n8n<\/h3>\n<p>\u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u043d\u043e\u0434\u044b \u0434\u043b\u044f n8n:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0423\u0437\u0435\u043b<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Script \u2192 Run<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0441 \u043e\u0442\u0432\u0435\u0442\u0430\u043c\u0438 \u0438 \u0441\u0443\u0445\u0438\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u043c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Script \u2192 Get Many<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043f\u0438\u0441\u043e\u043a \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Migration \u2192 Preview<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u043d \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Migration \u2192 Move Stack<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Cluster \u2192 Apply<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Cluster \u2192 Diff Manifest<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">Diff \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a JSON: <code>{\"param:FROM\": \"web1\"}<\/code>.<\/p>\n<hr\/>\n<h3>\u0420\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u044f\u0437\u044b\u043a\u0430<\/h3>\n<h4>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/h4>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e 29 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434, \u044f\u0437\u044b\u043a \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <strong>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/strong> \u2014 YAML-\u0444\u0430\u0439\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<pre><code class=\"yaml\">name: myappdetect:  any:    - file: \/etc\/myapp\/config.yml    - unit: myapp.servicesources:  - type: file    path: \/etc\/myapp\/config.yml    format: yamlextract:  endpoints:    - each: $.listeners[*]      address: $.address      port: $.port<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0436\u0438\u0432\u0443\u0442 \u0432 <code>\/etc\/netknownsthat\/services.d\/<\/code>, \u0432 \u043f\u0440\u043e\u0444\u0438\u043b\u0435 \u0445\u0430\u0431\u0430 \u0438\u043b\u0438 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0432 <code>nkt<\/code>. \u0421\u0442\u0430\u0440\u0448\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043c\u043b\u0430\u0434\u0448\u0435\u0435. <code>disabled: true<\/code> \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435.<\/p>\n<p><strong>\u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f:<\/strong> Traefik, RabbitMQ, Redis, PostgreSQL, Mosquitto, Envoy \u2014 \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p><strong>\u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u0431\u043e\u0440\u0449\u0438\u043a\u0438<\/strong> (nginx, HAProxy, Caddy, Docker, Podman, LXD, libvirt, Kubernetes, firewall, fail2ban) \u2014 \u0442\u043e\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441 <code>engine:<\/code>. \u0418\u0445 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0445\u043e\u0441\u0442\u0435 \u0438\u043b\u0438 \u0432 \u043f\u0440\u043e\u0444\u0438\u043b\u0435.<\/p>\n<h4>\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b<\/h4>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a:<\/p>\n<pre><code class=\"yaml\"># \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043e\u0442 \u043f\u043b\u0430\u0433\u0438\u043d\u0430plugin cloudflare-dns create-record example.com A 192.0.2.1plugin mail create-domain example.complugin llm list-models<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442:<\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 (<code>plugin \u0418\u041c\u042f \u0421\u041b\u041e\u0412\u041e \u2026<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b MCP \u0434\u043b\u044f \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u0434\u0435\u043b\u044b \u0432 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435<\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<h3>\u0418\u0418-\u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f<\/h3>\n<h4>\u0410\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435<\/h4>\n<p>\u041a\u043d\u043e\u043f\u043a\u0430 <strong>\u00ab\u0418\u0418 \u25be\u00bb<\/strong> \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432:<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c<\/strong> \u2014 \u0440\u0430\u0437\u0431\u043e\u0440 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e <\/strong><code><strong># \u0418\u0418:<\/strong><\/code> \u2014 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0438\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e<\/strong> \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0434\u0438\u0444\u0444 \u2014 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442.<\/p>\n<h4>\u0410\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442 \u0445\u0430\u0431\u0430<\/h4>\n<p>\u041f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0430 \u0441 \u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043e\u043c: \u043e\u043a\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430, \u0438\u043c\u0435\u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0430\u043c\u0438 \u0441 \u043c\u0435\u043d\u044e, \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435. \u0418\u043c\u0435\u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u2014 \u0441\u0441\u044b\u043b\u043a\u0438 \u0441 \u043c\u0435\u043d\u044e \u043f\u043e \u0442\u0438\u043f\u0443: \u0445\u043e\u0441\u0442, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438 \u0441\u043b\u0443\u0436\u0431\u0430, \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440, \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u043a\u043b\u0430\u0441\u0442\u0435\u0440, \u043c\u0430\u0440\u0448\u0440\u0443\u0442, \u0433\u0440\u0443\u043f\u043f\u0430.<\/p>\n<h4>MCP-\u0441\u0435\u0440\u0432\u0435\u0440<\/h4>\n<p>\u0425\u0430\u0431 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 ~40 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u043e\u0432 (Claude Code, Claude Desktop, Cursor):<\/p>\n<ul>\n<li>\n<p>\u0425\u043e\u0441\u0442\u044b, \u043d\u0430\u0445\u043e\u0434\u043a\u0438, \u0441\u043b\u0443\u0436\u0431\u044b, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b (\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435, \u043f\u0440\u0430\u0432\u043a\u0430, \u0441\u0443\u0445\u043e\u0439 \u043f\u0440\u043e\u0433\u043e\u043d)<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0434\u0430\u043d\u0438\u044f, \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b<\/p>\n<\/li>\n<li>\n<p>Traffic Fly, \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u044b<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u2014 \u0432\u044b\u0437\u043e\u0432 \u0442\u043e\u0433\u043e \u0436\u0435 API \u043f\u043e\u0434 \u0442\u0435\u043c \u0436\u0435 \u0442\u043e\u043a\u0435\u043d\u043e\u043c, \u043f\u0440\u0430\u0432\u0430 \u0438 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u2014 \u0442\u043e\u043a\u0435\u043d\u0430.<\/p>\n<hr\/>\n<h3>\u0427\u0435\u0441\u0442\u043d\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u0430<\/h3>\n<h4>\u0427\u0435\u0433\u043e \u043d\u0435\u0442<\/h4>\n<p>\u274c <strong>\u0423\u0441\u043b\u043e\u0432\u0438\u0439<\/strong> (<code>if\/else<\/code>) \u2014 \u044f\u0437\u044b\u043a \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439<br \/> \u274c <strong>\u0426\u0438\u043a\u043b\u043e\u0432<\/strong> (<code>for<\/code>) \u2014 \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0445\u043e\u0441\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435<br \/> \u274c <strong>\u0424\u0443\u043d\u043a\u0446\u0438\u0439<\/strong> \u2014 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438<br \/> \u274c <strong>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043c\u0438<\/strong> \u2014 \u043a\u0430\u0436\u0434\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d<br \/> \u274c <strong>\u042f\u0437\u044b\u043a\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/strong> \u2014 \u043d\u0435\u0442 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u043a\u0438, \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a<\/p>\n<h4>\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440<\/h4>\n<p>\u042f\u0437\u044b\u043a \u0440\u0435\u0448\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0437\u0430\u0434\u0430\u0447\u0443: <strong>\u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0435 \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438<\/strong>. \u0414\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0435\u0441\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b.<\/p>\n<p>\u041f\u0440\u0438\u043d\u0446\u0438\u043f: <strong>\u0435\u0441\u043b\u0438 \u0432 \u044f\u0437\u044b\u043a\u0435 \u043d\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u2014 \u0437\u043d\u0430\u0447\u0438\u0442, \u0432\u0430\u043c \u043e\u043d\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438<\/strong>.<\/p>\n<hr\/>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>29 \u043a\u043e\u043c\u0430\u043d\u0434. \u041e\u0434\u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u043a \u043a\u0430\u0436\u0434\u043e\u0439. \u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435. \u0421\u0443\u0445\u043e\u0439 \u043f\u0440\u043e\u0433\u043e\u043d \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c. \u0416\u0443\u0440\u043d\u0430\u043b \u0441 \u0442\u0430\u0439\u043c\u0441\u0442\u0430\u043c\u043f\u0430\u043c\u0438. \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u0435\u0440\u0441\u0438\u0439. \u0418\u0418-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041f\u043b\u0430\u0433\u0438\u043d\u044b.<\/p>\n<p>\u042d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u00ab\u041a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u044c \u2014 \u0441\u0435\u0441\u0442\u0440\u0430 \u0442\u0430\u043b\u0430\u043d\u0442\u0430\u00bb \u0432 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043d\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438: \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438, \u0430 \u0443\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0441\u0451 \u043b\u0438\u0448\u043d\u0435\u0435, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 29 \u0433\u043b\u0430\u0433\u043e\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u044b.<\/p>\n<p>\u0410 \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u2014 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u044f\u0434\u0440\u0430 \u044f\u0437\u044b\u043a\u0430.<\/p>\n<hr\/>\n<p><strong>\u0421\u0441\u044b\u043b\u043a\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p>\ud83d\udc49 <strong>GitHub:<\/strong> <a href=\"https:\/\/github.com\/piqab\/nkt\">github.com\/piqab\/nkt<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"http:\/\/github.com\/piqab\/nkt%F0%9F%93%9A\">\ud83d\udcda<\/a> <strong>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f:<\/strong> <a href=\"https:\/\/piqab.github.io\/nkt\">github.io\/nkt<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"http:\/\/github.com\/piqab\/nkt%F0%9F%93%9A\">\ud83d\udcda<\/a> <strong>\u0421\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a:<\/strong> <a href=\"https:\/\/piqab.github.io\/nkt\/guide\/script-commands\">github.io\/nkt\/guide\/script-commands<\/a><\/p>\n<\/li>\n<\/ul>\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\/articles\/1099564\/\">https:\/\/habr.com\/ru\/articles\/1099564\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0424\u0438\u043b\u043e\u0441\u043e\u0444\u0438\u044f: \u043f\u043e\u0447\u0435\u043c\u0443 29, \u0430 \u043d\u0435 290\u042f\u0437\u044b\u043a \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 NKT \u2014 \u043f\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0439 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f. \u041e\u043d \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: \u0432 \u043d\u0451\u043c \u043d\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u0439, \u0446\u0438\u043a\u043b\u043e\u0432 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u042d\u0442\u043e \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440.\u041f\u0440\u0438\u043d\u0446\u0438\u043f: \u044f\u0437\u044b\u043a \u0440\u0435\u0448\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u2014 \u00ab\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0438 \u0441\u0435\u0440\u0432\u0438\u0441, \u043f\u0440\u043e\u0432\u0435\u0440\u044c, \u0447\u0442\u043e \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0438, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e\u00bb. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b \u0441\u043e\u0442\u043d\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439. \u041d\u0443\u0436\u043d\u044b 29 \u0433\u043b\u0430\u0433\u043e\u043b\u043e\u0432.\u041a\u0430\u0436\u0434\u044b\u0439 \u0433\u043b\u0430\u0433\u043e\u043b \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435:\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043b\u0443\u0436\u0431\u043e\u0439\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0435\u043a\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0412\u041c\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c\u0418\u0437 29 \u0433\u043b\u0430\u0433\u043e\u043b\u043e\u0432 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u043b\u044e\u0431\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u2014 \u0435\u0441\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0442 \u044f\u0437\u044b\u043a \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u044f\u0434\u0440\u0430.\u0412\u0441\u0435 29 \u043a\u043e\u043c\u0430\u043d\u0434\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440setset \u0418\u041c\u042f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 set \u0418\u041c\u042f askset IMAGE ubuntu-24.04  set DB_PASS askparamparam \u0418\u041c\u042f &#171;\u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430&#187;param HOST &#171;\u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0445\u043e\u0441\u0442&#187;set \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u0430\u043a ${\u0418\u041c\u042f}. \u0412\u0430\u0440\u0438\u0430\u043d\u0442 ask \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0438 \u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u0442\u0435\u043a\u0441\u0442 \u0438 \u0436\u0443\u0440\u043d\u0430\u043b \u2014 \u0434\u043b\u044f \u043f\u0430\u0440\u043e\u043b\u0435\u0439 \u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432.param \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u043e\u0439. \u0422\u0430\u043a \u043e\u0434\u0438\u043d \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0442\u0435\u043d\u0434\u044b. \u041d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 (Script.Unresolved).\u041f\u0440\u0438\u043c\u0435\u0440:set IMAGE ubuntu-24.04set DB_PASS askparam ADDR &#171;\u0430\u0434\u0440\u0435\u0441 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430&#187;param NAME &#171;\u0438\u043c\u044f \u0445\u043e\u0441\u0442\u0430 \u0432 \u0445\u0430\u0431\u0435&#187;host ${NAME} ${ADDR} user root password ask\u0425\u043e\u0441\u0442\u044b \u0438 \u0433\u0440\u0443\u043f\u043f\u044b\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440groupgroup \u0418\u041c\u042f [profile \u041f\u0420\u041e\u0424\u0418\u041b\u042c]group web-farm profile web-basehosthost \u0418\u041c\u042f \u0410\u0414\u0420\u0415\u0421[:\u041f\u041e\u0420\u0422] user \u041f\u041e\u041b\u042c\u0417\u041e\u0412\u0410\u0422\u0415\u041b\u042c \u2026host web1 192.0.2.10 user root password askinstallinstall \u0425\u041e\u0421\u0422\u2026install web1 web2waitwait \u0425\u041e\u0421\u0422 online [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait web1 online 5mgroup \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 \u0445\u043e\u0441\u0442\u043e\u0432 \u043d\u0430 \u0445\u0430\u0431\u0435. \u0421 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c \u2014 \u043c\u0430\u0448\u0438\u043d\u044b, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432 \u043d\u0435\u0439, \u0434\u0435\u043b\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u043d\u0435\u043c\u0443.host \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0445\u043e\u0441\u0442 \u043d\u0430 \u0445\u0430\u0431 \u043f\u043e SSH \u2014 \u0442\u043e \u0436\u0435, \u0447\u0442\u043e \u00ab\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0445\u043e\u0441\u0442\u00bb \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435. \u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438: password ask, password &#171;\u2026&#187;, key hub.install \u0441\u0442\u0430\u0432\u0438\u0442 nkt \u043d\u0430 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0445\u043e\u0441\u0442\u044b \u0438 \u0436\u0434\u0451\u0442, \u043f\u043e\u043a\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u0432\u0435\u0442\u0438\u0442.wait \u0438\u043c\u0435\u0435\u0442 \u043f\u044f\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432:wait \u0425\u041e\u0421\u0422 online [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait \u0425\u041e\u0421\u0422 port \u041f\u041e\u0420\u0422 [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait \u0425\u041e\u0421\u0422 http URL [\u041a\u041e\u0414] [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait \u0425\u041e\u0421\u0422 service \u0418\u041c\u042f active [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]wait url URL [\u041a\u041e\u0414] [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0430\u0434\u0440\u0435\u0441\u0430 \u0441\u043d\u0430\u0440\u0443\u0436\u0438: \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u0445\u0430\u0431\u0430 \u043f\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u0438 (DNS, \u0448\u043b\u044e\u0437, \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f), \u0445\u043e\u0441\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.\u041f\u0440\u0438\u043c\u0435\u0440:host web1 192.0.2.10 user root password ask group web-farmhost web2 192.0.2.11:2222 user deploy key hubinstall web1 web2wait web1 online 5mwait web1 port 443 30swait web1 service nginx activewait url https:\/\/git.example.com\/api\/healthz 200 10m\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: \u043f\u0430\u043a\u0435\u0442\u044b, \u0441\u043b\u0443\u0436\u0431\u044b, \u0444\u0430\u0439\u0440\u0432\u043e\u043b\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440packageson \u0425\u041e\u0421\u0422\u2026 packages install|remove \u041f\u0410\u041a\u0415\u0422\u2026on web1 packages install nginx htopserviceon \u0425\u041e\u0421\u0422 service \u0418\u041c\u042f start|stop|restart|reload|enable|disableon web1 service nginx restartfirewallon \u0425\u041e\u0421\u0422 firewall allow|deny \u041f\u041e\u0420\u0422[\/tcp|udp] [from CIDR]on web1 firewall allow 443\/tcp  on web1 firewall allow 5432 from 10.0.0.0\/24\u041f\u0430\u043a\u0435\u0442\u044b \u0441\u0442\u0430\u0432\u044f\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0435\u0439. \u0424\u0430\u0439\u0440\u0432\u043e\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 ufw \u0438\u043b\u0438 firewalld \u2014 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u043d\u0430 \u0445\u043e\u0441\u0442\u0435.\u041f\u0440\u0438\u043c\u0435\u0440:on web1 web2 web3 packages install nginx htopon web1 web2 web3 service nginx enableon web1 web2 web3 service nginx starton web1 web2 web3 firewall allow 80\/tcpon web1 web2 web3 firewall allow 443\/tcp\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: Docker \u0438 \u0412\u041c\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440docker installon \u0425\u041e\u0421\u0422 docker installon web1 docker installdocker stackon \u0425\u041e\u0421\u0422 docker stack \u041f\u0423\u0422\u042c up|down|start|stopon web1 docker stack \/srv\/app\/docker-compose.yml upvm createon \u0425\u041e\u0421\u0422 vm create \u0418\u041c\u042f image \u041e\u0411\u0420\u0410\u0417 [\u043e\u043f\u0446\u0438\u0438]on web1 vm create app1 image ubuntu-24.04 cpu 2 mem 2048 disk 20 installvm start\/shutdown\/destroyon \u0425\u041e\u0421\u0422 vm start|shutdown|destroy \u0418\u041c\u042fon web1 vm start app1docker stack \u0438\u043c\u0435\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f:up \u2014 \u043f\u043e\u0434\u043d\u044f\u0442\u044c (\u0441\u043a\u0430\u0447\u0430\u0432 \u043e\u0431\u0440\u0430\u0437\u044b, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e)down \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438 \u0443\u0431\u0440\u0430\u0442\u044cstart \u2014 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u043c\u0435\u044e\u0449\u0435\u0435\u0441\u044f \u0431\u0435\u0437 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a registrystop \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c, \u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b\u0421 \u0431\u043b\u043e\u043a\u043e\u043c \u0434\u043e end \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 compose-\u0444\u0430\u0439\u043b \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438:on web1 docker stack \/srv\/app\/docker-compose.yml upservices:  web:    image: nginx:alpine    ports:      &#8212; &#171;8080:80&#8243;end\u0421\u0442\u0435\u043a, \u0432\u044b\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u043e\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0438 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 deploy \u041a\u041e\u041d\u0412\u0415\u0419\u0415\u0420 start|stop \u2014 \u00ab\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c\u00bb \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u043e\u043c\u043d\u0438\u0442.vm create \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u043c\u0430\u0448\u0438\u043d\u0443 \u0438\u0437 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430. \u041e\u043f\u0446\u0438\u0438: cpu, mem, disk, user, network, profile, install (\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c nkt \u0432\u043d\u0443\u0442\u0440\u044c).\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: \u0444\u0430\u0439\u043b\u044b, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438, \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b, git\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440file puton \u0425\u041e\u0421\u0422 file put \u041f\u0423\u0422\u042c [mode 0644] + \u0431\u043b\u043e\u043a \u0434\u043e endon web1 file put \/etc\/motd  \u0413\u043e\u0442\u043e\u0432\u043e  enduser addon \u0425\u041e\u0421\u0422 user add \u0418\u041c\u042f [sudo] [key &#171;\u2026&#187;]on web1 user add deploy sudo key &#171;ssh-ed25519 \u2026&#187;systemon \u0425\u041e\u0421\u0422 system hostname|timezone|locale|ntp \u0417\u041d\u0410\u0427\u0415\u041d\u0418\u0415on web1 system timezone Europe\/Moscowcerton \u0425\u041e\u0421\u0422 cert issue|renew \u0414\u041e\u041c\u0415\u041d\u2026on web1 cert issue example.orggit cloneon \u0425\u041e\u0421\u0422 git clone URL \/\u041a\u0410\u0422\u0410\u041b\u041e\u0413 [\u043e\u043f\u0446\u0438\u0438]on web1 git clone https:\/\/github.com\/org\/app.git \/srv\/app branch main token askcert issue \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 certbot &#8212;standalone: \u0441\u043b\u0443\u0436\u0431\u044b \u043d\u0430 80\/443 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0441\u043d\u043e\u0432\u0430.git clone \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0445 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432: token ask (\u0441\u043f\u0440\u043e\u0441\u044f\u0442 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435) \u0438\u043b\u0438 key hub (deploy-\u043a\u043b\u044e\u0447 \u0445\u043e\u0441\u0442\u0430).\u041d\u0430 \u0445\u043e\u0441\u0442\u0435: \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 \u0438 Kubernetes\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440apply profileon \u0425\u041e\u0421\u0422 apply profile \u041f\u0420\u041e\u0424\u0418\u041b\u042con web2 apply profile web-basek8s createon \u0425\u041e\u0421\u0422 k8s create \u0418\u041c\u042f [\u043e\u043f\u0446\u0438\u0438]on hv1 k8s create lab flavor kubeadm nodes &#171;hv1: cp 1, w 2&#187; cni cilium exposek8s destroyon \u0425\u041e\u0421\u0422 k8s destroy \u0418\u041c\u042fon hv1 k8s destroy labk8s create \u2014 \u0441\u0430\u043c\u0430\u044f \u00ab\u0442\u044f\u0436\u0451\u043b\u0430\u044f\u00bb \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u044f\u0437\u044b\u043a\u0430. \u0421\u043e\u0437\u0434\u0430\u0451\u0442 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u043d\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445: \u043c\u0430\u0448\u0438\u043d\u044b \u0438\u0437 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430, control plane, \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u043e\u0432, \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 Ready, \u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u043f\u043e\u0440\u0442\u043e\u0432, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 kubeconfig \u043d\u0430 \u0445\u0430\u0431.\u041e\u043f\u0446\u0438\u0438: flavor (k3s \u0438\u043b\u0438 kubeadm), nodes (\u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u043e \u0445\u043e\u0441\u0442\u0430\u043c), image, cpu\/mem\/disk, network, cni, no-kube-proxy, version, expose, api\/http\/https \u043f\u043e\u0440\u0442\u044b.\u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b, \u0432\u044b\u043a\u043b\u0430\u0434\u043a\u0438, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440pipelinepipeline \u0418\u041c\u042f &#8230; endpipeline hello  repo: https:\/\/github.com\/org\/app.git  action: compose  compose:  file: docker-compose.yml  hosts: [web1]  env:  DB_PASSWORD: generate:password  enddeploydeploy \u041a\u041e\u041d\u0412\u0415\u0419\u0415\u0420 [start|stop] [\u0414\u041b\u0418\u0422\u0415\u041b\u042c\u041d\u041e\u0421\u0422\u042c]deploy hello 20m  deploy shop stop  deploy shop startmigratemigrate \u0425\u041e\u0421\u0422 \u041a\u041e\u041d\u0422\u0415\u0419\u041d\u0415\u0420 to \u0425\u041e\u0421\u0422 [\u043e\u043f\u0446\u0438\u0438]migrate web1 app-1 to web2 switch-fly switch-pipelinepipeline \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0432\u044b\u043a\u043b\u0430\u0434\u043a\u0438. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f env: \u0443\u0445\u043e\u0434\u044f\u0442 \u0432 \u0441\u0435\u043a\u0440\u0435\u0442\u044b \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u0430. generate: \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043f\u0430\u0440\u043e\u043b\u044c, \u0442\u043e\u043a\u0435\u043d) \u043d\u0430 \u0445\u0430\u0431\u0435.deploy \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0438 \u0436\u0434\u0451\u0442 \u0438\u0442\u043e\u0433\u0430. \u0421 start \u0438\u043b\u0438 stop \u2014 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0443\u0436\u0435 \u0432\u044b\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u043d\u0430 \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u0445\u043e\u0441\u0442\u0430\u0445.migrate \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0441\u0442\u0435\u043a \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0445\u043e\u0441\u0442: \u043f\u043b\u0430\u043d \u0441 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f\u043c\u0438 \u0434\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u0442\u0435\u043a\u0430, \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430, \u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 \u0445\u0430\u0431, \u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0430 \u043d\u043e\u0432\u043e\u043c. \u0423\u043f\u0430\u0432\u0448\u0438\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c. \u041e\u043f\u0446\u0438\u0438: switch-fly, switch-pipeline, clean-leftovers.Kubernetes: Ingress, \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u044b, \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440k8s ingressk8s \u041a\u041b\u0410\u0421\u0422\u0415\u0420 ingress cilium [port \u041f\u041e\u0420\u0422]k8s lab ingress cilium port 8080k8s applyk8s \u041a\u041b\u0410\u0421\u0422\u0415\u0420 apply + \u0431\u043b\u043e\u043a \u0434\u043e endk8s lab apply  apiVersion: v1  kind: Namespace  metadata:  name: demo  endk8s waitk8s \u041a\u041b\u0410\u0421\u0422\u0415\u0420 wait deployment \u0418\u041c\u042f [\u043e\u043f\u0446\u0438\u0438]k8s lab wait deployment hello 5mk8s apply \u0432 \u0441\u0443\u0445\u043e\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 kubectl diff \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0431\u0435\u0437 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f.Traffic Fly\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0440\u0438\u043c\u0435\u0440fly routefly route \u0418\u0414 \u0412\u0418\u0414 [\u043e\u043f\u0446\u0438\u0438]fly route hello https names hello.example.com tls gateway targets cluster lab port 8080fly applyfly applyfly apply\u0412\u0438\u0434\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432: https, http, tcp, udp, tcpudp. \u0426\u0435\u043b\u0438: targets cluster \u041a\u041b\u0410\u0421\u0422\u0415\u0420 port N (\u0432\u0441\u0435 \u0443\u0437\u043b\u044b \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430) \u0438\u043b\u0438 target \u0425\u041e\u0421\u0422 container|vm|lxd \u0418\u041c\u042f \u041f\u041e\u0420\u0422 (\u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0446\u0435\u043b\u044c).\u041d\u043e\u0432\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. \u0423 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0446\u0435\u043b\u0438 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043b\u0430\u0432\u043d\u043e: \u043d\u043e\u0432\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f, \u043f\u0440\u0435\u0436\u043d\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u044f\u0442\u0441\u044f. \u0412 \u0441\u0443\u0445\u043e\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u0435 \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u0430\u0440\u0442\u044b \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c.\u0420\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u043f\u043e\u043b\u043d\u044b\u0439 \u0446\u0438\u043a\u043b\u0418\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, examples\/scripts\/forgejo-fly.nkt:# Forgejo \u0437\u0430 Traffic Fly: \u0432\u044b\u043a\u043b\u0430\u0434\u043a\u0430 \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0445\u043e\u0441\u0442param FROM &#171;\u0445\u043e\u0441\u0442, \u0433\u0434\u0435 Forgejo \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043b\u043e\u0436\u0435\u043d \u0441\u043d\u0430\u0447\u0430\u043b\u0430&#187;param TO &#171;\u0445\u043e\u0441\u0442, \u043a\u0443\u0434\u0430 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438&#187;param DOMAIN &#171;\u0438\u043c\u044f Forgejo \u2014 A-\u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 \u0448\u043b\u044e\u0437\u0430 Traffic Fly&#187;pipeline forgejo  repo: https:\/\/github.com\/piqab\/nkt.git  ref: main  action: compose  compose:    file: examples\/forgejo\/deploy\/docker-compose.yml    project: forgejo    hosts: [${FROM}]    wait_timeout: 5m    env:      POSTGRES_PASSWORD: generate:password      FORGEJO_DOMAIN: ${DOMAIN}      FORGEJO_ROOT_URL: https:\/\/${DOMAIN}\/      FORGEJO_ADMIN_USER: gitadmin      FORGEJO_ADMIN_PASSWORD: generate:password    fly:      &#8212; route: forgejo-web        kind: https        names: [${DOMAIN}]        tls: gateway        service: forgejo        target_port: 3000        check: http        check_path: \/api\/healthz      &#8212; route: forgejo-ssh        kind: tcp        port: 2222        service: forgejo        target_port: 2222enddeploy forgejo 20mwait url https:\/\/${DOMAIN}\/api\/healthz 200 10mmigrate ${FROM} forgejo-forgejo-1 to ${TO} switch-fly switch-pipelinewait url https:\/\/${DOMAIN}\/api\/healthz 200 5m\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044f\u0437\u044b\u043a \u0432 \u044d\u0442\u043e\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438:param \u2014 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0445\u043e\u0441\u0442\u044b \u0438 \u0434\u043e\u043c\u0435\u043d \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435pipeline \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0441 Docker Compose \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u0430\u0440\u043e\u043b\u0435\u0439deploy \u2014 \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0438 \u0436\u0434\u0451\u0442 \u0434\u043e 20 \u043c\u0438\u043d\u0443\u0442wait url \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0448\u043b\u044e\u0437 \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430migrate \u2014 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u0430\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u043847 \u0441\u0442\u0440\u043e\u043a. \u0412\u043c\u0435\u0441\u0442\u043e \u0441\u0432\u044f\u0437\u043a\u0438 docker-compose.yml + deploy.sh + migrate.sh + healthcheck.sh.\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0413\u0434\u0435 \u043d\u0430\u0439\u0442\u0438\u041f\u0440\u043e\u0444\u0438\u043b\u0438 \u2192 \u0432\u043a\u043b\u0430\u0434\u043a\u0430 \u00ab\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0438\u00bb \u2192 \u00ab\u041d\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439\u00bb\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u00ab\u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u25be\u00bb \u2014 \u0432\u044b\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 (Forgejo, Kubernetes). \u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c, \u0435\u0441\u043b\u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u0430\u0432\u043a\u0438.\u00ab?\u00bb \u2014 \u0437\u043d\u0430\u0447\u043e\u043a \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 \u043e\u043a\u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u0438 \u043d\u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u00ab\u041a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432\u00bb \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.\u0412\u043a\u043b\u0430\u0434\u043a\u0430 \u00ab\u0421\u043f\u0440\u0430\u0432\u043a\u0430\u00bb \u2014 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0442\u0443 \u0436\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u0441\u0430\u0439\u0442\u0430. \u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u0435\u043b\u044c \u00ab\u0421\u0430\u0439\u0442 \/ \u0418\u0437 nkt\u00bb \u2014 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430, \u0435\u0441\u043b\u0438 \u0441\u0430\u0439\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d. \u0412\u044b\u0431\u043e\u0440 \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442\u0441\u044f.\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u2014 \u043a\u043d\u043e\u043f\u043a\u0430 \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438. \u0418\u043c\u0435\u043d\u0430 \u0445\u043e\u0441\u0442\u043e\u0432 \u0438\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 (on ${HOST}) \u043d\u0435 \u0440\u0443\u0433\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u2014 \u043e\u043d\u0438 \u0441\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f \u043d\u0435 \u043c\u0435\u0448\u0430\u044e\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c.\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u0435\u0440\u0441\u0438\u0439 \u2014 \u0442\u0430\u0431\u043b\u0438\u0446\u0430: \u2116, \u0432\u0440\u0435\u043c\u044f, \u0430\u0432\u0442\u043e\u0440, \u0437\u0430\u043c\u0435\u0442\u043a\u0430, \u0440\u0430\u0437\u043c\u0435\u0440, \u043c\u0435\u0442\u043a\u0430&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-500351","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/500351","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=500351"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/500351\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=500351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=500351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=500351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}