{"id":494645,"date":"2026-09-14T19:48:44","date_gmt":"2026-09-14T19:48:44","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=494645"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=494645","title":{"rendered":"\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u044e \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0434\u043b\u044f DevOps Cloud.ru Camp 2025"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u042f \u0442\u0443\u0442 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u043d\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u043a\u0443\u0440\u0441\u044b \u043e\u0442 Aston, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043e\u0442\u043a\u0430\u0437 \u0441 \u0442\u0430\u043a\u043e\u0439 \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043a\u043e\u0439.<\/p>\n<pre><code>\u0414\u0435\u043d\u0438\u0441, \u0434\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c!\u041f\u043e\u0441\u043b\u0435 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0430\u0448\u0435\u0439 \u0430\u043d\u043a\u0435\u0442\u044b, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043c\u044b \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u0442\u044c \u0432\u0430\u0441 \u043a \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c\u0443 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e \u043d\u0430 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u0423 \u043d\u0430\u0441 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u043e\u0432 \u043d\u0430 \u043a\u0443\u0440\u0441\u044b. \u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0437\u044f\u043b\u0438 \u0432 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0441 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u0432\u044b\u0448\u0435. \u0412\u0430\u0448\u0430 \u0430\u043d\u043a\u0435\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430,  \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0432\u0430\u0448\u0435\u0439 \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0443\u0440\u0435, \u043f\u0440\u0438 \u043d\u0430\u0431\u043e\u0440\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a.\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0438\u043c \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438.<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0425\u043e\u0442\u044f \u044f \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u043e\u043d\u044f\u043b, \u043a\u0430\u043a \u0441\u043c\u043e\u0433\u043b\u0438 \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u043c\u043e\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0438 \u0432 \u0447\u0435\u043c \u043e\u043d\u0438 \u0438\u0437\u043c\u0435\u0440\u044f\u043b\u0438\u0441\u044c, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0434\u0430\u0432\u0430\u043b\u0438 \u043d\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f, \u043d\u0438 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u0430\u043d\u043a\u0435\u0442\u0435 \u0443 \u043d\u0438\u0445 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u043e \u0434\u0430 \u043b\u0430\u0434\u043d\u043e, \u044d\u0442\u043e \u0442\u0435\u043c\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0439\u0442\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 <a href=\"https:\/\/github.com\/devopscloudrucamp\/tasks\" rel=\"noopener nofollow\">\u043e\u0442 \u043a\u043b\u0430\u0443\u0434.\u0440\u0443<\/a>. \u041e\u043d\u043e \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0441\u0442\u0435\u043a \u0434\u043b\u044f devops, linux, docker, git, kubernetes.<\/p>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a\u0438\u043c \u0443\u0436 \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u043c, \u043e\u0434\u043d\u0430\u043a\u043e, \u0434\u044c\u044f\u0432\u043e\u043b \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u044f\u0445 \u0438 \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u043e \u0432\u044b\u0431\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0422\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 4 \u0437\u0430\u0434\u0430\u0447, \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0435\u0440\u0432\u043e\u0439.<\/p>\n<h3>Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Python\/Golang<\/h3>\n<pre><code>\u0426\u0435\u043b\u044c\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 echo-server \u043d\u0430 Python \u0438\u043b\u0438 Go\u0417\u0430\u0434\u0430\u0447\u0430\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Python\/Go, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439:    \u0438\u043c\u044f \u0445\u043e\u0441\u0442\u0430    ip \u0430\u0434\u0440\u0435\u0441 \u0445\u043e\u0441\u0442\u0430    \u0438\u043c\u044f \u0430\u0432\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f $AUTHOR\u0414\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c Dockerfile \u0438 \u0437\u0430\u043f\u0443\u0448\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0437 \u0432 \u0434\u043e\u043a\u0435\u0440 \u0445\u0430\u0431* (\u0437\u0430\u043f\u0443\u0448\u0438\u0442\u044c \u0432 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438 - \u043f\u0440\u043e\u0439\u0442\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u0432 \u0434\u043e\u043a\u0435\u0440 \u0445\u0430\u0431, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c).\u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u043a \u0437\u0430\u0434\u0430\u0447\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c:    \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434    Dockerfile    \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0434\u043b\u044f \u043f\u0443\u0448\u0430 \u043e\u0431\u0440\u0430\u0437\u0430 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 \/01-application<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0443\u043d\u043a\u0442\u0435 \u0443\u0436\u0435 \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0432\u043e\u0445. Python \u0438\u043b\u0438 Go , \u0437\u0434\u0435\u0441\u044c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0435 \u043d\u0430 \u0433\u043e, \u043e\u0431\u0440\u0430\u0437 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043e\u043a\u043e\u043b\u043e 2 \u043c\u0431, \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u043a\u043e\u043b\u043e 20 \u043d\u0430 \u043f\u0430\u0439\u0442\u043e\u043d\u0435. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043d\u0430 \u043f\u0438\u0442\u043e\u043d\u0435 \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0435\u0433\u0447\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u043a\u0430\u043a \u043c\u0443\u043b\u044c\u0442\u0438\u0441\u0442\u044d\u0439\u0434\u0436 \u0441\u0431\u043e\u0440\u043a\u0430 \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043f\u0440\u043e\u043a\u0430\u0442\u0438\u0442.<\/p>\n<p>\u0414\u043b\u044f \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430, \u044f \u0441\u0434\u0435\u043b\u0430\u044e 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043d\u0430\u0447\u043d\u0443 \u0441 \u0433\u043e.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 01-application, \u0432 \u043d\u0435\u0439 2 \u0444\u0430\u0439\u043b\u0430 main.go, go.mod.<\/p>\n<pre><code class=\"go\">\/\/ main.gopackage mainimport (\"fmt\"\"net\"\"net\/http\"\"os\")func envOr(key, fallback string) string {if v := os.Getenv(key); v != \"\" {return v}return fallback}\/\/ IP \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432 \u0435\u0433\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c network namespace.func getContainerIP() string {conn, err := net.Dial(\"udp\", \"8.8.8.8:80\")if err != nil {return \"unknown\"}defer conn.Close()return conn.LocalAddr().(*net.UDPAddr).IP.String()}func handler(w http.ResponseWriter, r *http.Request) {containerHost, _ := os.Hostname()   \/\/ \u0438\u043c\u044f \u0438\u0437 UTS namespace = ID \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430containerIP := getContainerIP()     \/\/ \u0430\u0434\u0440\u0435\u0441 \u0438\u0437 network namespace\/\/ \u0414\u0430\u043d\u043d\u044b\u0435 \u0425\u041e\u0421\u0422\u0410 \u043d\u0435 \u0434\u043e\u0431\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u2014 \u043e\u043d\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0441\u043d\u0430\u0440\u0443\u0436\u0438.hostHost := envOr(\"HOST_HOSTNAME\", \"(not injected)\")hostIP := envOr(\"HOST_IP\", \"(not injected)\")author := envOr(\"AUTHOR\", \"anonymous\")w.Header().Set(\"Content-Type\", \"text\/html; charset=utf-8\")fmt.Fprintf(w, `&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Echo Server&lt;\/title&gt;&lt;\/head&gt;&lt;body style=\"font-family:monospace\"&gt;  &lt;h1&gt;Echo Server&lt;\/h1&gt;  &lt;ul&gt;    &lt;li&gt;&lt;b&gt;Container hostname:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Container IP:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host hostname:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host IP:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Author:&lt;\/b&gt; %s&lt;\/li&gt;  &lt;\/ul&gt;&lt;\/body&gt;&lt;\/html&gt;`, containerHost, containerIP, hostHost, hostIP, author)}func healthz(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, \"ok\")}func main() {http.HandleFunc(\"\/\", handler)http.HandleFunc(\"\/healthz\", healthz)http.ListenAndServe(\":8000\", nil)}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"go\">\/\/ go.modmodule echo-servergo 1.23<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043b\u0443\u0447\u0448\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438, \u043c\u0443\u043b\u044c\u0442\u0438\u0441\u0442\u044d\u0439\u0434\u0436 \u0441\u0431\u043e\u0440\u043a\u0438, \u0432\u044b\u043a\u0438\u043d\u0435\u043c \u0432\u0441\u0435 \u043b\u0438\u0448\u043d\u0435\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0437 \u0432\u0435\u0441\u0438\u043b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043d\u0435 \u0431\u044b\u043b \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043e\u0442 \u0440\u0443\u0442\u0430.<\/p>\n<pre><code># ---- \u042d\u0442\u0430\u043f 1: \u0441\u0431\u043e\u0440\u043a\u0430 ----FROM golang:1.23-alpine AS builderWORKDIR \/srcCOPY go.mod .\/COPY main.go .\/# CGO_ENABLED=0 \u2014 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043b\u0438\u043d\u043a\u043e\u0432\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a# \u0436\u0438\u043b \u0432 scratch \u0431\u0435\u0437 \u0435\u0434\u0438\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.# -ldflags=\"-s -w\" \u0441\u0440\u0435\u0437\u0430\u0435\u0442 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b (\u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u0435\u0441).RUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o \/echo-server .RUN echo 'appuser:x:10001:10001::\/:' &gt; \/etc\/passwd# ---- \u042d\u0442\u0430\u043f 2: \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 ----FROM scratchCOPY --from=builder \/echo-server \/echo-serverCOPY --from=builder \/etc\/passwd \/etc\/passwdUSER appuserEXPOSE 8000ENV AUTHOR=\"alfabuster\"ENTRYPOINT [\"\/echo-server\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0437\u0430\u0440\u0435\u0433\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0434\u043e\u043a\u0435\u0440\u0445\u0430\u0431\u0435, \u0435\u0441\u043b\u0438 \u0435\u0449\u0435 \u043d\u0435\u0442 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430.<\/p>\n<pre><code class=\"bash\"># 1. \u041b\u043e\u0433\u0438\u043d\u0438\u043c\u0441\u044f (\u0432\u0432\u0435\u0434\u0451\u0442 \u043b\u043e\u0433\u0438\u043d \u0438 Access Token \u2014 \u043d\u0435 \u043f\u0430\u0440\u043e\u043b\u044c, \u043f\u0430\u0440\u043e\u043b\u0438 \u0443\u0436\u0435 \u043d\u0435\u043c\u043e\u0434\u043d\u043e)docker login -u &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;# 2. \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0442\u0435\u0433\u043e\u043c: &lt;\u043b\u043e\u0433\u0438\u043d&gt;\/&lt;\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439&gt;:&lt;\u0432\u0435\u0440\u0441\u0438\u044f&gt;docker build -t &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\/echo-server:1.0 .# 3. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u044b\u0448\u0438\u0442docker run --rm -p 8001:8000 \\  -e AUTHOR=\"alfabuster\" \\  -e HOST_HOSTNAME=\"$(hostname)\" \\  -e HOST_IP=\"$(ip -4 route get 1.1.1.1 | grep -oP 'src \\K\\S+')\" \\  &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\/echo-server:1.0#    \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c http:\/\/localhost:8001 \u2014 \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c hostname\/IP\/author<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0438\u043d\u0444\u0443 \u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0438 \u0445\u043e\u0441\u0442\u0435.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/20e\/392\/e89\/20e392e89918f62ebb041d9e59062fe4.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/20e\/392\/e89\/20e392e89918f62ebb041d9e59062fe4.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/20e\/392\/e89\/20e392e89918f62ebb041d9e59062fe4.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<pre><code class=\"bash\"># 4. \u041f\u0443\u0448\u0438\u043c \u0432 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438docker push &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\/echo-server:1.0<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0435\u043c, \u0432\u0441\u0435 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u043d\u043e \u0434\u043b\u044f \u043f\u0430\u0439\u0442\u043e\u043d\u0430.<\/p>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0437\u0430\u0435\u043c server.py \u0441 \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u0434\u043e\u043c.<\/p>\n<pre><code class=\"python\">#!\/usr\/bin\/env python3import osimport socketfrom http.server import BaseHTTPRequestHandler, ThreadingHTTPServerdef env_or(key, fallback):    return os.getenv(key) or fallbackdef get_container_ip():    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    try:        s.connect((\"8.8.8.8\", 80))        return s.getsockname()[0]    except Exception:        return \"unknown\"    finally:        s.close()class Handler(BaseHTTPRequestHandler):    def do_GET(self):        if self.path == \"\/healthz\":            self.send_response(200)            self.send_header(\"Content-Type\", \"text\/plain\")            self.end_headers()            self.wfile.write(b\"ok\\n\")            return        container_host = socket.gethostname()      # ID \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430        container_ip = get_container_ip()        host_host = env_or(\"HOST_HOSTNAME\", \"(not injected)\")        host_ip = env_or(\"HOST_IP\", \"(not injected)\")        author = env_or(\"AUTHOR\", \"anonymous\")        body = f\"\"\"&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Echo Server&lt;\/title&gt;&lt;\/head&gt;&lt;body style=\"font-family:monospace\"&gt;  &lt;h1&gt;Echo Server (Python)&lt;\/h1&gt;  &lt;ul&gt;    &lt;li&gt;&lt;b&gt;Container hostname:&lt;\/b&gt; {container_host}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Container IP:&lt;\/b&gt; {container_ip}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host hostname:&lt;\/b&gt; {host_host}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host IP:&lt;\/b&gt; {host_ip}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Author:&lt;\/b&gt; {author}&lt;\/li&gt;  &lt;\/ul&gt;&lt;\/body&gt;&lt;\/html&gt;\"\"\"        self.send_response(200)        self.send_header(\"Content-Type\", \"text\/html; charset=utf-8\")        self.end_headers()        self.wfile.write(body.encode(\"utf-8\"))    def log_message(self, *args):        passif __name__ == \"__main__\":    ThreadingHTTPServer((\"0.0.0.0\", 8003), Handler).serve_forever()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b. \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0440\u0430\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0441\u0451 \u0437\u0430\u0442\u0435\u0432\u0430\u043b\u043e\u0441\u044c. \u041f\u043e\u043c\u043d\u0438\u0442\u0435 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u044b\u0439 \u0444\u0438\u043d\u0430\u043b Go-\u0432\u0435\u0440\u0441\u0438\u0438 \u2014 FROM scratch, \u043e\u0431\u0440\u0430\u0437 \u0438\u0437 \u0447\u0438\u0441\u0442\u043e\u0439 \u043f\u0443\u0441\u0442\u043e\u0442\u044b \u0432\u0435\u0441\u043e\u043c \u0432 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u044b? \u0421 Python \u0442\u0430\u043a \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442 \u043d\u0438\u043a\u043e\u0433\u0434\u0430. Python \u2014 \u044f\u0437\u044b\u043a \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439: \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c server.py, \u0432 \u043e\u0431\u0440\u0430\u0437\u0435 \u043e\u0431\u044f\u0437\u0430\u043d \u0436\u0438\u0442\u044c \u0441\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u0441\u043e \u0432\u0441\u0435\u0439 \u0435\u0433\u043e \u0441\u0432\u0438\u0442\u043e\u0439. \u0412 \u043f\u0443\u0441\u0442\u043e\u0442\u0443 \u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0448\u044c, multi-stage \u0442\u0443\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u0435\u043d \u2014 \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0447\u0435\u0433\u043e, \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u043d\u0443\u0436\u0435\u043d \u0446\u0435\u043b\u0438\u043a\u043e\u043c.<\/p>\n<pre><code>FROM python:3.12-alpineWORKDIR \/appRUN adduser -D appuser COPY --chown=appuser:appuser app.py .COPY server.py .EXPOSE 8003ENV AUTHOR=\"alfabuster\"ENTRYPOINT [ \"python3\" , \"server.py\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u043e\u0449\u0435, \u0432\u0441\u0435\u0433\u043e 8 \u0441\u0442\u0440\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e \u0433\u0430\u0439\u0434\u0443 \u0438\u0437 \u0434\u043e\u043a\u0435\u0440\u0430, \u043d\u0430\u043f\u0438\u0448\u0435\u0442 \u0434\u0430\u0436\u0435 \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u0431\u0435\u0437 \u043f\u0440\u043e\u0444\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 IT.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0431\u0438\u043b\u0434\u0430 \u043e\u0431\u0440\u0430\u0437\u043e\u0432.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/67f\/634\/923\/67f63492362baef66a23d2b5f6f3bef3.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/67f\/634\/923\/67f63492362baef66a23d2b5f6f3bef3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/67f\/634\/923\/67f63492362baef66a23d2b5f6f3bef3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 10 \u0440\u0430\u0437. \u0417\u0434\u0435\u0441\u044c \u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 go.<\/p>\n<p>\u0410 \u0447\u0442\u043e \u043d\u0430 \u0441\u0447\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438? \u041e\u0431\u0440\u0430\u0437 \u043d\u0430 scratch \u2014 \u044d\u0442\u043e \u043a\u0440\u0435\u043f\u043e\u0441\u0442\u044c \u0431\u0435\u0437 \u0434\u0432\u0435\u0440\u0435\u0439: \u0442\u0430\u043c \u043d\u0435\u0442 sh, \u043d\u0435\u0442 apt, \u043d\u0435\u0442 curl, \u043d\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430. \u0417\u043b\u043e\u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u0438\u043a, \u043f\u0440\u043e\u0431\u0440\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u0432 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0443\u0441\u0442\u043e\u0439 \u0431\u0435\u0442\u043e\u043d\u043d\u043e\u0439 \u043a\u043e\u0440\u043e\u0431\u043a\u0435 \u2014 \u043d\u0438 \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c\u0441\u044f, \u043d\u0438 \u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c\u0441\u044f, \u043d\u0438 \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b. \u041e\u0434\u043d\u0430\u043a\u043e scratch \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 RCE, \u043f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435\/\u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0438 \u0438\u043b\u0438 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u044f\u0434\u0440\u0430\/\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430.<\/p>\n<p>\u0412 python:3.12-alpine sh \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0432\u0443\u0435\u0442. \u0422\u0430\u043a\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0430\u043c Python, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 RCE \u0430\u0442\u0430\u043a\u0443\u044e\u0449\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Python \u043a\u0430\u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e Unix-\u043a\u043e\u043c\u0430\u043d\u0434 \u043d\u0435\u0442.<\/p>\n<p>\u0421\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0440\u0430\u0434\u0438 \u2014 \u0443 Python \u0435\u0441\u0442\u044c \u0438 \u043a\u043e\u0437\u044b\u0440\u0438. Dockerfile \u043f\u0440\u043e\u0449\u0435 (\u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 \u0441\u0431\u043e\u0440\u043a\u0438), \u043f\u0440\u0430\u0432\u043a\u0438 \u043d\u0430 \u043b\u0435\u0442\u0443 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0430 \u0432\u043d\u0443\u0442\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0439\u0442\u0438 \u0438 \u043f\u043e\u0442\u044b\u043a\u0430\u0442\u044c \u043f\u0430\u043b\u043a\u043e\u0439, \u043a\u043e\u0433\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a. Go-scratch \u0437\u0430 \u0441\u0432\u043e\u044e \u043d\u0435\u043f\u0440\u0438\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u043f\u043b\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u2014 \u043a\u0430\u043a \u0447\u0438\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u044b: \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0434\u0432\u0435\u0440\u0446\u044b \u043d\u0435\u0442. \u042d\u0442\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u043d \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0442\u0438\u0432 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430.<\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u0443\u0447\u0443\u0441\u044c \u043d\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0438\u043a\u0430, \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0432\u044b\u0431\u043e\u0440 \u043e\u0447\u0435\u0432\u0438\u0434\u0435\u043d, \u043e\u0434\u043d\u0430\u043a\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f, \u043d\u0435 \u0437\u043d\u0430\u044e, \u043a\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u043d\u0438 \u043e\u0431\u0430 \u0432\u0435\u0440\u043d\u044b\u0435. \u041f\u0440\u043e\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430, \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0422\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043f\u0435\u0440\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u0439.<\/p>\n<h3>Ansible playbook \u0438\u043b\u0438 \u0440\u043e\u043b\u044c<\/h3>\n<pre><code>\u0426\u0435\u043b\u044c\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 Ansible\u0417\u0430\u0434\u0430\u0447\u0430\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u041c\u0430\u0448\u0438\u043d\u0443 (VM) \u0441 \u041e\u0421 Ubuntu 22.04. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438: \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0447\u0435\u0440\u0435\u0437 Virtual Box (\u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438), \u043b\u0438\u0431\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c Free-tier \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043e\u0442 cloud.ru - https:\/\/cloud.ru\/offers\/free-tier.\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Ansible:    \u041d\u0430 VM \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442 docker-ce;    \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c Web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 3-\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u0445. \u0414\u043b\u044f \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438;    \u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043d\u0430 nginx, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a \u0445\u043e\u0441\u0442\u0443 \u0438 \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b. \u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0432\u044b\u0431\u043e\u0440.\u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u043a \u0437\u0430\u0434\u0430\u0447\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c:    \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 Ansible    \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 \/02-ansible<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0445\u043e\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443 \u043c\u0435\u043d\u044f Void Linux, \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043a\u0430\u0447\u0430\u0442\u044c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c ubuntu, \u044f \u043d\u0435 \u0431\u0443\u0434\u0443, \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 vagrant.<\/p>\n<p>\u0414\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 Brew.<\/p>\n<pre><code>\/bin\/bash -c \"$(curl -fsSL https:\/\/raw.githubusercontent.com\/Homebrew\/install\/HEAD\/install.sh)\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043d \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d \u043d\u0430 bash, \u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0430 fish, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u0442\u043e \u0447\u0442\u043e \u0441\u043e\u0432\u0435\u0442\u0443\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0449\u0438\u043a \u0432 \u0432\u044b\u0432\u043e\u0434\u0435 \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u041d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c Homebrew \u0432 PATH fish<\/p>\n<pre><code class=\"bash\">fish_add_path \/home\/linuxbrew\/.linuxbrew\/binfish_add_path \/home\/linuxbrew\/.linuxbrew\/sbin<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0441\u0430\u043c Vagrant.<\/p>\n<pre><code>brew tap hashicorp\/tapbrew install hashicorp\/tap\/vagrant<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u0445\u043e\u0441\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u044e \u043b\u044e\u0431\u0443\u044e \u043f\u0430\u043f\u043a\u0443, \u0432 \u043d\u0435\u0439 \u0441\u043e\u0437\u0434\u0430\u044e \u0444\u0430\u0439\u043b Vagrantfile.<\/p>\n<pre><code>Vagrant.configure(\"2\") do |config|  config.vm.box = \"ubuntu\/jammy64\"  config.vm.network \"private_network\",  ip: \"10.0.0.7\",  virtualbox__intnet: \"intnet\"  config.vm.provider \"virtualbox\" do |vb|    vb.memory = 2048    vb.cpus   = 2  endend<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u0438\u043c \u0444\u0430\u0439\u043b\u043e\u043c \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043c\u0430\u0448\u0438\u043d\u0443 \u0432\u043e \u0432\u043d\u0442\u0443\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443 \u043c\u0435\u043d\u044f \u0443\u0436\u0435 \u0431\u044b\u043b\u0430.<\/p>\n<p>\u041f\u0438\u043d\u0433\u0443\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u0430\u0433\u0440\u0430\u043d\u0442 \u0432\u0441\u0435 \u0432\u0435\u0440\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b, \u0434\u043e\u0441\u0442\u0443\u043f \u043f\u043e ssh, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u043a\u043b\u044e\u0447\u0438.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043b\u0435\u0439\u0431\u0443\u043a \u0447\u0435\u0440\u0435\u0437 Ansible.<\/p>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 02-ansible \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u0443 \u0444\u0430\u0439\u043b\u043e\u0432 ansible.cfg \u0438 inventory.ini.<\/p>\n<pre><code>[defaults]inventory = inventory.iniremote_user = vagrantprivate_key_file = ~\/.ssh\/id_ed25519<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>[web]web-vm ansible_host=10.0.0.7[web:vars]ansible_python_interpreter=\/usr\/bin\/python3<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u044d\u0442\u0438\u0445 \u0444\u0430\u0439\u043b\u0430\u0445 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043d\u0430\u0448\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u0443\u0431\u0443\u043d\u0442\u0443 \u0447\u0435\u0440\u0435\u0437 \u0432\u0430\u0433\u0440\u0430\u043d\u0442, \u0435\u0435 ip ssh \u043a\u043b\u044e\u0447 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435.<\/p>\n<p>\u0414\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0445\u0432\u0430\u0442\u0438\u0442 \u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0430, \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0433\u043e\u0440\u043e\u0434\u0438\u0442\u044c \u0438 \u0440\u043e\u043b\u044c, \u043d\u043e \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0445\u0432\u0430\u0442\u0438\u0442 \u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0430.<\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c docker, \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0434\u043e\u043a\u0435\u0440 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c 3 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0438 \u043d\u0430\u043a\u0440\u044b\u0442\u044c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c \u043d\u0430 nginx.<\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0440\u0443\u043a\u0430\u043c\u0438, \u0437\u0430\u043b\u0435\u0437\u044c \u043d\u0430 1 \u0441\u0435\u0440\u0432\u0430\u043a, \u0442\u0430\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u043e\u043a\u0435\u0440 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c 3 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u041d\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e ansible, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0444\u0430\u0439\u043b \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043c.<\/p>\n<h4>\u041d\u0430\u0447\u0430\u043b\u043e \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0430<\/h4>\n<pre><code class=\"yaml\">---- name: Deploy echo-server behind an nginx load balancer  hosts: web  become: true          # \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441 sudo \u2014 \u0438\u043d\u0430\u0447\u0435 apt \u0440\u0443\u0433\u043d\u0435\u0442\u0441\u044f \u043d\u0430 permission  vars:    docker_image: \"&lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\/echo-server:1.0\"    author_name: \"alfabuster\"    container_count: 3    base_port: 8000                  # \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441\u044f\u0434\u0443\u0442 \u043d\u0430 8001, 8002, 8003    registry_user: \"&lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\"    registry_password: \"{{ vault_registry_token }}\"   # \u043f\u0440\u044f\u0447\u0435\u043c \u0432 vault, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0430\u043b\u0435\u0435<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u0414\u0430\u043b\u0435\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0441\u0430\u043c \u0434\u043e\u043a\u0435\u0440<\/h4>\n<pre><code class=\"yaml\">  tasks:    - name: Install prerequisites      apt:        name: [ca-certificates, curl, gnupg, python3-pip]        state: present        update_cache: true    - name: Create apt keyrings directory      file:        path: \/etc\/apt\/keyrings        state: directory        mode: '0755'    - name: Download Docker's GPG key      get_url:        url: https:\/\/download.docker.com\/linux\/ubuntu\/gpg        dest: \/etc\/apt\/keyrings\/docker.asc        mode: '0644'    - name: Add Docker apt repository      apt_repository:        repo: \"deb [arch=amd64 signed-by=\/etc\/apt\/keyrings\/docker.asc] https:\/\/download.docker.com\/linux\/ubuntu {{ ansible_distribution_release }} stable\"        filename: docker        state: present    - name: Install docker-ce      apt:        name: [docker-ce, docker-ce-cli, containerd.io]        state: present        update_cache: true    - name: Install Docker SDK for Python      pip:        name: docker        state: present    - name: Ensure docker is running and enabled      service:        name: docker        state: started        enabled: true<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 ansible_distribution_release \u2014 \u044d\u0442\u043e \u0444\u0430\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 Ansible \u0441\u0430\u043c \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043e \u0445\u043e\u0441\u0442\u0435 \u043f\u0435\u0440\u0435\u0434 \u0441\u0442\u0430\u0440\u0442\u043e\u043c (\u0434\u043b\u044f 22.04 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442 jammy).<\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c docker_container \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 \u0447\u0435\u0440\u0435\u0437 CLI, \u0430 \u0447\u0435\u0440\u0435\u0437 Python-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 docker. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u0442\u0430\u0432\u0438\u043c pip install docker \u2014 \u0431\u0435\u0437 \u043d\u0435\u0451 \u043c\u043e\u0434\u0443\u043b\u044c \u0432\u044b\u0434\u0430\u0441\u0442 \u0437\u0430\u0433\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<h4>\u041f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u0442\u0440\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432<\/h4>\n<pre><code class=\"yaml\">- name: Log in to the private registry  community.docker.docker_login:    username: \"{{ registry_user }}\"    password: \"{{ registry_password }}\"- name: Pull the application image  community.docker.docker_image:    name: \"{{ docker_image }}\"    source: pull- name: Run echo-server containers  community.docker.docker_container:    name: \"echo-{{ item }}\"    image: \"{{ docker_image }}\"    state: started    restart_policy: unless-stopped    published_ports:      - \"127.0.0.1:{{ item }}:8000\"    env:      AUTHOR: \"{{ author_name }}\"  loop:    - 8001    - 8002    - 8003<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>published_ports \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a 127.0.0.1, \u0430 \u043d\u0435 \u043a 0.0.0.0. \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441\u043b\u0443\u0448\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u2014 \u0441\u043d\u0430\u0440\u0443\u0436\u0438 \u043a \u043d\u0438\u043c \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u0447\u0430\u0442\u044c\u0441\u044f, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0434\u0432\u0435\u0440\u044c \u043d\u0430\u0440\u0443\u0436\u0443 \u2014 \u0447\u0435\u0440\u0435\u0437 nginx.<\/p>\n<h4>Nginx \u0438 \u0435\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433 \u0447\u0435\u0440\u0435\u0437 \u0448\u0430\u0431\u043b\u043e\u043d.<\/h4>\n<pre><code class=\"yaml\">    - name: Install nginx      apt:        name: nginx        state: present    - name: Deploy the load-balancer config      template:        src: nginx-lb.conf.j2        dest: \/etc\/nginx\/sites-available\/echo-lb.conf      notify: Reload nginx    - name: Enable the site      file:        src: \/etc\/nginx\/sites-available\/echo-lb.conf        dest: \/etc\/nginx\/sites-enabled\/echo-lb.conf        state: link      notify: Reload nginx    - name: Remove the default nginx site      file:        path: \/etc\/nginx\/sites-enabled\/default        state: absent      notify: Reload nginx    - name: Ensure nginx is running and enabled      service:        name: nginx        state: started        enabled: true  handlers:    - name: Reload nginx      service:        name: nginx        state: reloaded<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>handlers \u2014 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442 Ansible \u043e\u0442 \u0442\u0443\u043f\u043e\u0433\u043e \u0448\u0435\u043b\u043b-\u0441\u043a\u0440\u0438\u043f\u0442\u0430. notify: Reload nginx \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 nginx \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u041e\u043d \u0441\u0442\u0430\u0432\u0438\u0442 \u0433\u0430\u043b\u043e\u0447\u043a\u0443 \u00ab\u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u00bb \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0432 \u043a\u043e\u043d\u0446\u0435, \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0444\u0438\u0433 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f.<\/p>\n<h4>\u0428\u0430\u0431\u043b\u043e\u043d templates\/nginx-lb.conf.j2<\/h4>\n<pre><code>upstream echo_backend {    server 127.0.0.1:8001;    server 127.0.0.1:8002;    server 127.0.0.1:8003;}server {    listen 80 default_server;    server_name _;    location \/ {        proxy_pass http:\/\/echo_backend;        proxy_set_header Host              $host;        proxy_set_header X-Real-IP         $remote_addr;        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>\u041e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430<\/h4>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0434\u0438 \u0447\u0435\u0433\u043e \u0432\u0441\u0451 \u0437\u0430\u0442\u0435\u0432\u0430\u043b\u043e\u0441\u044c. \u0423 nginx \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0438, \u0438 \u0432\u043e\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u0440\u0430\u0441\u043a\u043b\u0430\u0434, \u043a\u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0442\u043e:<\/p>\n<ul>\n<li>\n<p>round-robin (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e) \u2014 \u0440\u0430\u0437\u0434\u0430\u0451\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e \u043a\u0440\u0443\u0433\u0443: \u043f\u0435\u0440\u0432\u044b\u0439 \u043d\u0430 8001, \u0432\u0442\u043e\u0440\u043e\u0439 \u043d\u0430 8002, \u0442\u0440\u0435\u0442\u0438\u0439 \u043d\u0430 8003, \u0447\u0435\u0442\u0432\u0451\u0440\u0442\u044b\u0439 \u0441\u043d\u043e\u0432\u0430 \u043d\u0430 8001.<\/p>\n<\/li>\n<li>\n<p>least_conn \u2014 \u043e\u0442\u0434\u0430\u0451\u0442 \u0442\u043e\u043c\u0443 \u0431\u044d\u043a\u0435\u043d\u0434\u0443, \u0443 \u043a\u043e\u0433\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>ip_hash \u2014 \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043a \u0431\u044d\u043a\u0435\u043d\u0434\u0443 \u043f\u043e \u0445\u0435\u0448\u0443 \u0435\u0433\u043e IP (\u043b\u0438\u043f\u043a\u0438\u0435 \u0441\u0435\u0441\u0441\u0438\u0438).<\/p>\n<\/li>\n<li>\n<p>hash \/ random \u2014 \u044d\u043a\u0437\u043e\u0442\u0438\u043a\u0430 \u0434\u043b\u044f \u043e\u0441\u043e\u0431\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 stateless \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u0435\u0442 \u043d\u0438 \u043a\u0443\u043a\u043e\u0432, \u043d\u0438 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430, \u043d\u0438 \u0441\u0435\u0441\u0441\u0438\u0439. \u0412\u0441\u0435 3 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0440\u0430\u0432\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u044b \u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0440\u0443\u0433\u0443 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u043c \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438.<\/p>\n<p>Least_conn \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u043a\u0430\u043a \u043d\u0430\u0433\u0440\u0437\u0443\u043a\u0430 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430. ip_hash \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043a\u0430\u0437\u0430\u043d, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0435\u0441\u044c \u0442\u0440\u0430\u0444\u0438\u043a \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441 localhost \u0438 \u0431\u044b\u043b \u0431\u044b \u043f\u0440\u0438\u043a\u043e\u0432\u0430\u043d \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c round-robin.<\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u0435\u043c vault \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043b\u0435\u0439\u0431\u0443\u043a<\/h4>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 vault \u0438 \u043f\u0430\u0440\u043e\u043b\u044f \u043a \u043d\u0435\u043c\u0443.<\/p>\n<pre><code>ansible-vault create group_vars\/web\/vault.yml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0438\u0437 \u0434\u043e\u043a\u0435\u0440\u0430<\/p>\n<pre><code>vault_registry_token: \"docker_token\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u043b\u0435\u0439\u0431\u0443\u043a.<\/p>\n<pre><code>ansible-playbook playbook.yaml --ask-vault-pass<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u043d\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u0433\u043b\u0430\u0434\u043a\u043e, \u0432\u044b\u043b\u0435\u0437\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<pre><code>fatal: [web-vm]: FAILED! =&gt; {\"changed\": false, \"msg\": \"Error connecting: Error while fetching server API version: Not supported URL scheme http+docker\"}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e, \u044f \u0434\u0430\u0432\u043d\u043e \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438\u0437 ansible. \u0427\u0438\u043d\u0438\u043c.<\/p>\n<pre><code>ansible-galaxy collection install community.docker --upgrade<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043b\u0435\u0439\u0431\u0443\u043a \u0435\u0449\u0435 \u0440\u0430\u0437 \u0438 \u0432\u0441\u0435 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u0435\u0440\u0432\u0430\u043a.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6aa84f9c965b561e9f3b328a\" data-style=\"\" id=\"6aa84f9c965b561e9f3b328a\" width=\"\" data-habr-games=\"\"><\/div>\n<p>\u0411\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0432\u0442\u043e\u0440\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e.<\/p>\n<h3>Kubernetes manifest<\/h3>\n<pre><code>\u0426\u0435\u043b\u044c\u0414\u0435\u043f\u043b\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 Kubernetes\u0417\u0430\u0434\u0430\u0447\u0430\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 Kubernetes \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043d\u0435\u0439\u043c\u0441\u043f\u0435\u0439\u0441\u0435 \u0432 \u0432\u0438\u0434\u0435 Deployment \u0441 3 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u043c\u0438 \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0441 \u0442\u0438\u043f\u043e\u043c ClusterIP.\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438:    \u0414\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 AUTHOR;    \u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c readiness- \u0438 liveness- \u043f\u0440\u043e\u0431\u044b;    \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0437 \u0438\u0437 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447\u0438 1;    \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e: \u043f\u043e\u0434\u043d\u044f\u0442\u044c ingress-controller \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e ingress;    \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c helm-chart, \u0430 \u043d\u0435 raw \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442.\u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u043a \u0437\u0430\u0434\u0430\u0447\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c:    \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u0441\u0435\u0445 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u043e\u0432\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 \/03-kubernetes<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0437\u0430\u0434\u0430\u043d\u0438\u0438 \u043d\u0435 \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043a\u0443\u0431\u0435\u0440 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0443. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u044b.<\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u043d\u0430 \u0443\u0431\u0443\u043d\u0442\u0443 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043a\u0430\u043a \u0440\u0430\u0437 \u0441\u0442\u043e\u0438\u0442 \u043a\u0443\u0431\u0435\u0440 \u0438 2 \u0432\u043e\u0440\u043a\u0435\u0440 \u043d\u043e\u0434\u044b \u0432\u0435\u0440\u0441\u0438\u0438 v1.31.14. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u044b.<\/p>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043b \u043a\u0443\u0440\u0441 Certified Kubernetes Administrator \u043e\u0442 kodekloud, \u0442\u0430\u043c \u043f\u043e\u0434\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u0442\u0435\u043c\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0412\u043e \u043f\u0435\u0440\u0432\u044b\u0445, \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0430\u043b\u0438\u0430\u0441, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043d\u0435 \u0432\u0432\u043e\u0434\u0438\u0442\u044c kubectl.<\/p>\n<pre><code>alias k=kubectl<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u044b\u0445, \u043f\u043e\u0447\u0442\u0438 \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 kubectl create \u0443\u043c\u0435\u0435\u0442 \u043d\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f.<\/p>\n<pre><code>--dry-run=client -o yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0432 \u0444\u0430\u0439\u043b \u0438 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430, \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c\u0438 \u043e\u0442\u0441\u0442\u0443\u043f\u0430\u043c\u0438 \u043f\u043e \u043a\u0430\u043d\u043e\u043d\u0430\u043c yaml.<\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u0435\u043c namespace<\/h4>\n<pre><code class=\"bash\">k create ns cloud --dry-run=client -o yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0432\u044b\u0432\u043e\u0434\u0435 \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442.<\/p>\n<pre><code class=\"yaml\">apiVersion: v1kind: Namespacemetadata:  creationTimestamp: null  name: cloudspec: {}status: {}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0432\u0440\u044f\u0434\u043b\u0438, \u043a\u0442\u043e \u043f\u0438\u0448\u0435\u0442 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f namespace, \u0435\u0433\u043e \u043f\u0440\u043e\u0449\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 k create ns name. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u0437\u0430\u0434\u0430\u043d\u0438\u0438 \u043d\u0443\u0436\u0435\u043d \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442.<\/p>\n<h4>\u0421\u0435\u043a\u0440\u0435\u0442<\/h4>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439. \u0414\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0435\u043a\u0440\u0435\u0442. \u0418\u043d\u0430\u0447\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u0435\u0447\u043d\u044b\u0439 ImagePullBackOff.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0441\u0435\u043a\u0440\u0435\u0442 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0432 git.<\/p>\n<pre><code class=\"bash\">kubectl create secret docker-registry regcred \\  --docker-server=https:\/\/index.docker.io\/v1\/ \\  --docker-username=&lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt; \\  --docker-password=&lt;\u0432\u0430\u0448_access_token&gt; \\  --namespace=cloud<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0435\u043a\u0440\u0435\u0442 \u0436\u0438\u0432\u0451\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0439\u043c\u0441\u043f\u0435\u0439\u0441\u0430 cloud \u2014 \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043d\u0435\u0439\u043c\u0441\u043f\u0435\u0439\u0441\u0435 \u043e\u043d \u043d\u0435\u0432\u0438\u0434\u0438\u043c.<\/p>\n<h4>Configmap<\/h4>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u043f\u0438\u0445\u043d\u0443\u0442\u044c AUTHOR \u043f\u0440\u044f\u043c\u043e \u0432 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u043a\u0430\u043a value: \u201calfabuster\u201d. \u041d\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0438\u0442 \u00ab\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u00bb, \u0430 \u043f\u043e-\u0432\u0437\u0440\u043e\u0441\u043b\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0436\u0438\u0432\u0443\u0442 \u0432 ConfigMap \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 \u043a\u043e\u0434\u0430 \u0434\u0435\u043f\u043b\u043e\u044f:<\/p>\n<pre><code class=\"yaml\">apiVersion: v1kind: ConfigMapmetadata:  creationTimestamp: null  name: cloud-configmap  namespace: clouddata:  AUTHOR: alfabuster<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Deployment<\/h4>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0435\u0442 \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442 \u0441 3 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u043c\u0438 \u0438 \u043f\u0440\u043e\u0431\u0430\u043c\u0438. \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u0430\u0432\u0438\u043c \u0440\u0443\u043a\u0430\u043c\u0438.<\/p>\n<pre><code class=\"bash\">k create deploy cloud-deploy --image=alfabuster\/echo-server:1.0 --replicas=3 --port=8000 -n cloud --dry-run=client -o yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439.<\/p>\n<pre><code class=\"yaml\">apiVersion: apps\/v1kind: Deploymentmetadata:  creationTimestamp: null  labels:    app: cloud-deploy  name: cloud-deploy  namespace: cloudspec:  replicas: 3  selector:    matchLabels:      app: cloud-deploy  strategy: {}  template:    metadata:      creationTimestamp: null      labels:        app: cloud-deploy    spec:      imagePullSecrets:        - name: regcred      containers:      - image: alfabuster\/echo-server:1.0        name: echo-server        ports:        - containerPort: 8000        env:          - name: AUTHOR            valueFrom:              configMapKeyRef:                name: cloud-configmap                key: AUTHOR        livenessProbe:          httpGet:            path: \/healthz            port: 8000          initialDelaySeconds: 10          periodSeconds: 5          timeoutSeconds: 3          failureThreshold: 3        readinessProbe:          httpGet:            path: \/healthz            port: 8000          periodSeconds: 5<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<ul>\n<li>\n<p>livenessProbe \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 \u00ab\u043f\u0430\u0446\u0438\u0435\u043d\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u0436\u0438\u0432?\u00bb. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0431\u0430 \u043f\u0430\u0434\u0430\u0435\u0442 \u2014 Kubernetes \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440. \u042d\u0442\u043e \u043b\u0435\u043a\u0430\u0440\u0441\u0442\u0432\u043e \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u0438 \u0434\u0435\u0434\u043b\u043e\u043a\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>readinessProbe \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 \u00ab\u043f\u0430\u0446\u0438\u0435\u043d\u0442 \u0433\u043e\u0442\u043e\u0432 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435\u043b\u0435\u0439?\u00bb. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0431\u0430 \u043f\u0430\u0434\u0430\u0435\u0442 \u2014 \u043f\u043e\u0434 \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f, \u0435\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u0438\u0437 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 Service, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u044e\u0442 \u0441\u043b\u0430\u0442\u044c \u0442\u0440\u0430\u0444\u0438\u043a, \u043f\u043e\u043a\u0430 \u043e\u043d \u043d\u0435 \u043e\u043a\u043b\u0435\u043c\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<h4>Service<\/h4>\n<p>Service \u0432 Kubernetes \u2014 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a. ClusterIP \u0440\u0430\u0441\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u0432\u0441\u0435\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043f\u043e\u0434\u0430\u043c.<\/p>\n<pre><code class=\"yaml\">apiVersion: v1kind: Servicemetadata:  name: cloud-deploy  namespace: cloudspec:  type: ClusterIP  selector:    app: cloud-deploy  ports:    - port: 80      targetPort: 8000      protocol: TCP<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>Ingress<\/h4>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c, \u0447\u0435\u0440\u0435\u0437 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440.<\/p>\n<pre><code class=\"bash\">k create ingress cloud-ingress --rule=\"cloud.local\/*=cloud-deploy:80\" -n cloud --dry-run=client -o yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"yaml\">apiVersion: networking.k8s.io\/v1kind: Ingressmetadata:  creationTimestamp: null  name: cloud-ingress  namespace: cloudspec:  rules:  - host: cloud.local    http:      paths:      - backend:          service:            name: cloud-deploy            port:              number: 80        path: \/        pathType: Prefixstatus:  loadBalancer: {}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043e\u043c\u0435\u043d cloud.local \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \/etc\/hosts, \u0443\u043a\u0430\u0437\u0430\u0432 \u043d\u0430 IP \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 (minikube ip \u0438\u043b\u0438 \u0430\u0434\u0440\u0435\u0441 \u043d\u043e\u0434\u044b). \u0411\u0435\u0437 \u044d\u0442\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c cloud.local \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/703\/984\/eae\/703984eaeb10b526324294729a686374.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/703\/984\/eae\/703984eaeb10b526324294729a686374.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/703\/984\/eae\/703984eaeb10b526324294729a686374.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e \u0438\u0442\u043e\u0433\u0443 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f, \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u043e \u0443\u0436\u0435 \u0432 \u043a\u0443\u0431\u0435\u0440\u0435 \u043d\u0430 \u0441\u0432\u043e\u0435\u043c \u0434\u043e\u043c\u0435\u043d\u0435, \u0441 3 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u043c\u0438 \u0438 \u043f\u0440\u043e\u0431\u0430\u043c\u0438.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/208\/ced\/f62\/208cedf621f416973b0efbc7a83bac66.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/208\/ced\/f62\/208cedf621f416973b0efbc7a83bac66.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/208\/ced\/f62\/208cedf621f416973b0efbc7a83bac66.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<h3>\u0417\u0430\u043f\u0435\u0440\u0435\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438\u0437\u043d\u0443\u0442\u0440\u0438*<\/h3>\n<pre><code>\u0426\u0435\u043b\u044c\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0432\u044b\u043a\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f *nix\u0417\u0430\u0434\u0430\u0447\u0430    \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0412\u041c \u0441 \u041e\u0421 Ubuntu 22.04;    \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442 docker-ce;    \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 docker run -it --rm ubuntu -- bash;    \u041d\u0435 \u043f\u043e\u043a\u0438\u0434\u0430\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043d\u0435 \u043c\u0435\u043d\u044f\u044f \u0444\u043b\u0430\u0433\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u0435\u043c\u043e\u043d\u0430, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438:    4.1. \u0441\u0434\u0435\u043b\u0430\u0442\u044c apt-get update, \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e;    4.2. \u0438\u0437\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u043c\u0443 \u0432\u044b\u0445\u043e\u0434 \u0432 \u0441\u0435\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442, \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c \u043a \u0437\u0430\u0434\u0430\u0447\u0435;    4.3. \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e apt-get update \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.    \u0414\u043e\u043f. \u0437\u0430\u0434\u0430\u0447\u0430 - \u043d\u0430\u0439\u0442\u0438 \u0435\u0449\u0451 +1 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u0443\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0438\u0437\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430.\u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u043a \u0437\u0430\u0434\u0430\u0447\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c:    \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0445 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 \/04-unix<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u0430\u044f, \u043e\u0434\u043d\u0430\u043a\u043e \u043d\u0435 \u0437\u0440\u044f \u043e\u043d\u0430 \u0441\u043e \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u043e\u0439. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u0443\u0431\u0443\u043d\u0442\u043e\u0439 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0441\u0432\u044f\u0437\u044c.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2a5\/fec\/c58\/2a5fecc588541d9229bb6c6f2f181a6b.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/2a5\/fec\/c58\/2a5fecc588541d9229bb6c6f2f181a6b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2a5\/fec\/c58\/2a5fecc588541d9229bb6c6f2f181a6b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u043e\u0442 \u0432 \u0447\u0451\u043c \u0444\u043e\u043a\u0443\u0441: Docker \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441 \u0443\u0440\u0435\u0437\u0430\u043d\u043d\u044b\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c Linux capabilities, \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0439, \u0434\u0430\u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u044b root.<\/p>\n<p>Root \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0435 \u0440\u0430\u0432\u043d\u044f\u0435\u0442\u0441\u044f \u0440\u0443\u0442 \u043d\u0430 \u0445\u043e\u0441\u0442\u0435.<\/p>\n<p>\u0418\u0437 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0433\u043e \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c iptables \u0438 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0442\u0440\u0430\u0444\u0438\u043a. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u043e\u0436\u0435\u043c, \u043e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0443\u0442\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<pre><code class=\"bash\">root@d79ba688c2c9:\/# iptables -A OUTPUT -j DROPiptables v1.8.11 (nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0434 root, \u043d\u043e \u0434\u0435\u043c\u043e\u043d docker \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 capabilities, \u043a\u0440\u043e\u043c\u0435 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430. \u0410 \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0432\u0443\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u043b\u0435\u0433\u0438\u044f NET_ADMIN, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0438 \u0442\u0440\u043e\u0433\u0430\u0442\u044c iptables, \u043d\u0438 \u0433\u0430\u0441\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u043d\u0438 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0424\u043b\u0430\u0433\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u0435\u043c\u043e\u043d\u0430 \u0442\u0440\u043e\u0433\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f, \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u043a\u0430\u043f\u0443 \u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0448\u0438\u043b\u0430\u0441\u044c \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e.<\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u044b apt.<\/p>\n<h4>\u0421\u043f\u043e\u0441\u043e\u0431 \u21161 &#8212; nsswitch.conf<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0443 \u043d\u0435 \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0444\u0430\u0439\u043b\u0430 \/etc\/nsswitch.conf, \u044f \u043e \u043d\u0435\u043c \u0441\u0430\u043c \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u0443\u0437\u043d\u0430\u043b, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044f \u0443\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 \u043e\u0434\u043d\u043e\u043c CTF.<\/p>\n<p>NSS \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a Name Service Switch. \u042d\u0442\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 C (glibc). \u041a\u043e\u0433\u0434\u0430 \u043b\u044e\u0431\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0443\u0437\u043d\u0430\u0442\u044c IP-\u0430\u0434\u0440\u0435\u0441 \u043f\u043e \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u0438 \u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043e\u043d\u0430 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a glibc. \u0410 glibc \u043f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0447\u0438\u0442\u0430\u0435\u0442 \/etc\/nsswitch.conf, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u0433\u0434\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442.<\/p>\n<p>\u0412 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0430 <code>hosts: files dns<\/code><\/p>\n<p>\u0423\u0431\u0440\u0430\u0432 dns \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438 hosts:, \u0432\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a DNS \u2014 \u0440\u0435\u0437\u043e\u043b\u0432\u0438\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u044f\u0432\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \/etc\/hosts.<\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438 NSS \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0441\u0442\u0430\u043c\u0438. \u0412 \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0442\u0430\u0441\u043a\u0435 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 dns, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 apt.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1db\/260\/b81\/1db260b81044d3c125dd5ffce95a368f.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/1db\/260\/b81\/1db260b81044d3c125dd5ffce95a368f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1db\/260\/b81\/1db260b81044d3c125dd5ffce95a368f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<h4>\u0421\u043f\u043e\u0441\u043e\u0431 \u21162 &#8212; resolv.conf<\/h4>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u0435\u043d \u043f\u0435\u0440\u0432\u043e\u043c\u0443, \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0444\u0430\u0439\u043b <code>\/etc\/resolv.conf<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 <code>\/etc\/nsswitch.conf<\/code> \u0440\u0435\u0448\u0430\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u0435\u043b\u0430\u0442\u044c DNS-\u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e <code>\/etc\/resolv.conf<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u043a \u043a\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0441 \u043d\u0438\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f. \u042d\u0442\u043e \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b DNS-\u0440\u0435\u0437\u043e\u043b\u0432\u0435\u0440\u0430. \u041e\u043d \u0447\u0430\u0441\u0442\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f networkmanager\u2019\u043e\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u043d \u0437\u0430\u0442\u0440\u0435\u0442\u0441\u044f, \u043d\u043e \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u0445\u0432\u0430\u0442\u0438\u0442 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u043f\u0440\u0430\u0432\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 <code>vim<\/code> \u0438\u043b\u0438 <code>nano<\/code>.<\/p>\n<pre><code>&gt; \/etc\/resolv.conf<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/21d\/de3\/2e1\/21dde32e158278d3bcd1694410a2de2e.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/21d\/de3\/2e1\/21dde32e158278d3bcd1694410a2de2e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/21d\/de3\/2e1\/21dde32e158278d3bcd1694410a2de2e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u043d\u043e\u0432\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442.<\/p>\n<h4>\u0421\u043f\u043e\u0441\u043e\u0431 3 &#8212; \/etc\/hosts<\/h4>\n<p><code>\/etc\/hosts<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0436\u0435\u0441\u0442\u043a\u043e \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 IP-\u0430\u0434\u0440\u0435\u0441\u0430 \u0441 \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438.<\/p>\n<p>\u0412 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 ip \u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u0443\u0431\u0443\u043d\u0442\u0443 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u0442.<\/p>\n<pre><code>127.0.0.1 archive.ubuntu.com127.0.0.1 security.ubuntu.com127.0.0.1 ports.ubuntu.com<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/372\/ad9\/630\/372ad9630fec30c0200313efa35c8fb8.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/372\/ad9\/630\/372ad9630fec30c0200313efa35c8fb8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/372\/ad9\/630\/372ad9630fec30c0200313efa35c8fb8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<h4>\u0421\u043f\u043e\u0441\u043e\u0431 4 &#8212; apt proxy<\/h4>\n<p>\u0423 APT \u0435\u0441\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 HTTP\/HTTPS-\u043f\u0440\u043e\u043a\u0441\u0438. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043a\u0441\u0438 127.0.0.1:9.<\/p>\n<p>\u041f\u043e\u0440\u0442 9 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 Discard (RFC 863), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0435\u0442\u0435\u0432\u044b\u043c \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043e\u043c \u0447\u0435\u0440\u043d\u043e\u0439 \u0434\u044b\u0440\u044b (\/dev\/null). \u041b\u044e\u0431\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u044d\u0442\u043e\u0442 \u043f\u043e\u0440\u0442 \u043f\u043e TCP \u0438\u043b\u0438 UDP, \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0431\u0435\u0437 \u043a\u0430\u043a\u043e\u0433\u043e-\u043b\u0438\u0431\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u043b\u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"bash\">cat &gt; \/etc\/apt\/apt.conf.d\/99-block-network &lt;&lt;'EOF'Acquire::http::Proxy \"http:\/\/127.0.0.1:9\";Acquire::https::Proxy \"http:\/\/127.0.0.1:9\";EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/15a\/32b\/ef1\/15a32bef1f5bf0326236aab42f57ae2d.png\" alt=\"alt text\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/15a\/32b\/ef1\/15a32bef1f5bf0326236aab42f57ae2d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/15a\/32b\/ef1\/15a32bef1f5bf0326236aab42f57ae2d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>alt text<\/figcaption><\/div>\n<\/figure>\n<h3>\u041a\u0430\u043a \u0438\u0442\u043e\u0433<\/h3>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435, \u043c\u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c. \u041c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u043e\u0441\u0432\u0435\u0436\u0438\u043b, \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0449\u0438 \u0438\u0437\u0443\u0447\u0438\u043b. \u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u043d\u0435 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u043d\u043e \u0438 \u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0435. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0438 \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0435 \u0437\u043d\u0430\u043d\u0438\u0435 linux.<\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u043b \u0438 \u0432\u044b\u043b\u043e\u0436\u0438\u043b \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431 <a href=\"https:\/\/github.com\/alfabuster\/devops-camp-cloudru-2025-writeup\/tree\/main\" rel=\"noopener nofollow\">alfabuster<\/a>.<\/p>\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\/1082220\/\">https:\/\/habr.com\/ru\/articles\/1082220\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u042f \u0442\u0443\u0442 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u043d\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u043a\u0443\u0440\u0441\u044b \u043e\u0442 Aston, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043e\u0442\u043a\u0430\u0437 \u0441 \u0442\u0430\u043a\u043e\u0439 \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043a\u043e\u0439.\u0414\u0435\u043d\u0438\u0441, \u0434\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c!\u041f\u043e\u0441\u043b\u0435 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0430\u0448\u0435\u0439 \u0430\u043d\u043a\u0435\u0442\u044b, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043c\u044b \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u0442\u044c \u0432\u0430\u0441 \u043a \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c\u0443 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e \u043d\u0430 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u0423 \u043d\u0430\u0441 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u043e\u0432 \u043d\u0430 \u043a\u0443\u0440\u0441\u044b. \u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0437\u044f\u043b\u0438 \u0432 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0441 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u0432\u044b\u0448\u0435. \u0412\u0430\u0448\u0430 \u0430\u043d\u043a\u0435\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430,  \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0432\u0430\u0448\u0435\u0439 \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0443\u0440\u0435, \u043f\u0440\u0438 \u043d\u0430\u0431\u043e\u0440\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a.\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0438\u043c \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438.\u0425\u043e\u0442\u044f \u044f \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u043e\u043d\u044f\u043b, \u043a\u0430\u043a \u0441\u043c\u043e\u0433\u043b\u0438 \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u043c\u043e\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0438 \u0432 \u0447\u0435\u043c \u043e\u043d\u0438 \u0438\u0437\u043c\u0435\u0440\u044f\u043b\u0438\u0441\u044c, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0434\u0430\u0432\u0430\u043b\u0438 \u043d\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f, \u043d\u0438 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u0430\u043d\u043a\u0435\u0442\u0435 \u0443 \u043d\u0438\u0445 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u043e \u0434\u0430 \u043b\u0430\u0434\u043d\u043e, \u044d\u0442\u043e \u0442\u0435\u043c\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0439\u0442\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043e\u0442 \u043a\u043b\u0430\u0443\u0434.\u0440\u0443. \u041e\u043d\u043e \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0441\u0442\u0435\u043a \u0434\u043b\u044f devops, linux, docker, git, kubernetes.\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a\u0438\u043c \u0443\u0436 \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u043c, \u043e\u0434\u043d\u0430\u043a\u043e, \u0434\u044c\u044f\u0432\u043e\u043b \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u044f\u0445 \u0438 \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u043e \u0432\u044b\u0431\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438.\u0422\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 4 \u0437\u0430\u0434\u0430\u0447, \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0435\u0440\u0432\u043e\u0439.Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Python\/Golang\u0426\u0435\u043b\u044c\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 echo-server \u043d\u0430 Python \u0438\u043b\u0438 Go\u0417\u0430\u0434\u0430\u0447\u0430\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Python\/Go, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439:    \u0438\u043c\u044f \u0445\u043e\u0441\u0442\u0430    ip \u0430\u0434\u0440\u0435\u0441 \u0445\u043e\u0441\u0442\u0430    \u0438\u043c\u044f \u0430\u0432\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f $AUTHOR\u0414\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c Dockerfile \u0438 \u0437\u0430\u043f\u0443\u0448\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0437 \u0432 \u0434\u043e\u043a\u0435\u0440 \u0445\u0430\u0431* (\u0437\u0430\u043f\u0443\u0448\u0438\u0442\u044c \u0432 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438 &#8212; \u043f\u0440\u043e\u0439\u0442\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u0432 \u0434\u043e\u043a\u0435\u0440 \u0445\u0430\u0431, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c).\u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u043a \u0437\u0430\u0434\u0430\u0447\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c:    \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434    Dockerfile    \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0434\u043b\u044f \u043f\u0443\u0448\u0430 \u043e\u0431\u0440\u0430\u0437\u0430 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 \/01-application\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0443\u043d\u043a\u0442\u0435 \u0443\u0436\u0435 \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0432\u043e\u0445. Python \u0438\u043b\u0438 Go , \u0437\u0434\u0435\u0441\u044c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0435 \u043d\u0430 \u0433\u043e, \u043e\u0431\u0440\u0430\u0437 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043e\u043a\u043e\u043b\u043e 2 \u043c\u0431, \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u043a\u043e\u043b\u043e 20 \u043d\u0430 \u043f\u0430\u0439\u0442\u043e\u043d\u0435. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043d\u0430 \u043f\u0438\u0442\u043e\u043d\u0435 \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0435\u0433\u0447\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u043a\u0430\u043a \u043c\u0443\u043b\u044c\u0442\u0438\u0441\u0442\u044d\u0439\u0434\u0436 \u0441\u0431\u043e\u0440\u043a\u0430 \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043f\u0440\u043e\u043a\u0430\u0442\u0438\u0442.\u0414\u043b\u044f \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430, \u044f \u0441\u0434\u0435\u043b\u0430\u044e 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043d\u0430\u0447\u043d\u0443 \u0441 \u0433\u043e.\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 01-application, \u0432 \u043d\u0435\u0439 2 \u0444\u0430\u0439\u043b\u0430 main.go, go.mod.\/\/ main.gopackage mainimport (&#171;fmt&#187;&#187;net&#187;&#187;net\/http&#187;&#187;os&#187;)func envOr(key, fallback string) string {if v := os.Getenv(key); v != &#171;&#187; {return v}return fallback}\/\/ IP \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432 \u0435\u0433\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c network namespace.func getContainerIP() string {conn, err := net.Dial(&#171;udp&#187;, &#171;8.8.8.8:80&#187;)if err != nil {return &#171;unknown&#187;}defer conn.Close()return conn.LocalAddr().(*net.UDPAddr).IP.String()}func handler(w http.ResponseWriter, r *http.Request) {containerHost, _ := os.Hostname()   \/\/ \u0438\u043c\u044f \u0438\u0437 UTS namespace = ID \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430containerIP := getContainerIP()     \/\/ \u0430\u0434\u0440\u0435\u0441 \u0438\u0437 network namespace\/\/ \u0414\u0430\u043d\u043d\u044b\u0435 \u0425\u041e\u0421\u0422\u0410 \u043d\u0435 \u0434\u043e\u0431\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u2014 \u043e\u043d\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0441\u043d\u0430\u0440\u0443\u0436\u0438.hostHost := envOr(&#171;HOST_HOSTNAME&#187;, &#171;(not injected)&#187;)hostIP := envOr(&#171;HOST_IP&#187;, &#171;(not injected)&#187;)author := envOr(&#171;AUTHOR&#187;, &#171;anonymous&#187;)w.Header().Set(&#171;Content-Type&#187;, &#171;text\/html; charset=utf-8&#8243;)fmt.Fprintf(w, `&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Echo Server&lt;\/title&gt;&lt;\/head&gt;&lt;body style=&#187;font-family:monospace&#187;&gt;  &lt;h1&gt;Echo Server&lt;\/h1&gt;  &lt;ul&gt;    &lt;li&gt;&lt;b&gt;Container hostname:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Container IP:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host hostname:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host IP:&lt;\/b&gt; %s&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Author:&lt;\/b&gt; %s&lt;\/li&gt;  &lt;\/ul&gt;&lt;\/body&gt;&lt;\/html&gt;`, containerHost, containerIP, hostHost, hostIP, author)}func healthz(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, &#171;ok&#187;)}func main() {http.HandleFunc(&#171;\/&#187;, handler)http.HandleFunc(&#171;\/healthz&#187;, healthz)http.ListenAndServe(&#171;:8000&#8243;, nil)}\/\/ go.modmodule echo-servergo 1.23\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043b\u0443\u0447\u0448\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438, \u043c\u0443\u043b\u044c\u0442\u0438\u0441\u0442\u044d\u0439\u0434\u0436 \u0441\u0431\u043e\u0440\u043a\u0438, \u0432\u044b\u043a\u0438\u043d\u0435\u043c \u0432\u0441\u0435 \u043b\u0438\u0448\u043d\u0435\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0437 \u0432\u0435\u0441\u0438\u043b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043d\u0435 \u0431\u044b\u043b \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043e\u0442 \u0440\u0443\u0442\u0430.# &#8212;- \u042d\u0442\u0430\u043f 1: \u0441\u0431\u043e\u0440\u043a\u0430 &#8212;-FROM golang:1.23-alpine AS builderWORKDIR \/srcCOPY go.mod .\/COPY main.go .\/# CGO_ENABLED=0 \u2014 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043b\u0438\u043d\u043a\u043e\u0432\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a# \u0436\u0438\u043b \u0432 scratch \u0431\u0435\u0437 \u0435\u0434\u0438\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.# -ldflags=&#187;-s -w&#187; \u0441\u0440\u0435\u0437\u0430\u0435\u0442 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b (\u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u0435\u0441).RUN CGO_ENABLED=0 GOOS=linux go build -ldflags=&#187;-s -w&#187; -o \/echo-server .RUN echo &#8216;appuser:x:10001:10001::\/:&#8217; &gt; \/etc\/passwd# &#8212;- \u042d\u0442\u0430\u043f 2: \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 &#8212;-FROM scratchCOPY &#8212;from=builder \/echo-server \/echo-serverCOPY &#8212;from=builder \/etc\/passwd \/etc\/passwdUSER appuserEXPOSE 8000ENV AUTHOR=&#187;alfabuster&#187;ENTRYPOINT [&#171;\/echo-server&#187;]\u0414\u0430\u043b\u0435\u0435 \u0437\u0430\u0440\u0435\u0433\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0434\u043e\u043a\u0435\u0440\u0445\u0430\u0431\u0435, \u0435\u0441\u043b\u0438 \u0435\u0449\u0435 \u043d\u0435\u0442 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430.# 1. \u041b\u043e\u0433\u0438\u043d\u0438\u043c\u0441\u044f (\u0432\u0432\u0435\u0434\u0451\u0442 \u043b\u043e\u0433\u0438\u043d \u0438 Access Token \u2014 \u043d\u0435 \u043f\u0430\u0440\u043e\u043b\u044c, \u043f\u0430\u0440\u043e\u043b\u0438 \u0443\u0436\u0435 \u043d\u0435\u043c\u043e\u0434\u043d\u043e)docker login -u &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;# 2. \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0442\u0435\u0433\u043e\u043c: &lt;\u043b\u043e\u0433\u0438\u043d&gt;\/&lt;\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439&gt;:&lt;\u0432\u0435\u0440\u0441\u0438\u044f&gt;docker build -t &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\/echo-server:1.0 .# 3. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u044b\u0448\u0438\u0442docker run &#8212;rm -p 8001:8000 \\  -e AUTHOR=&#187;alfabuster&#187; \\  -e HOST_HOSTNAME=&#187;$(hostname)&#187; \\  -e HOST_IP=&#187;$(ip -4 route get 1.1.1.1 | grep -oP &#8216;src \\K\\S+&#8217;)&#187; \\  &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\/echo-server:1.0#    \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c http:\/\/localhost:8001 \u2014 \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c hostname\/IP\/author\u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0438\u043d\u0444\u0443 \u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0438 \u0445\u043e\u0441\u0442\u0435.# 4. \u041f\u0443\u0448\u0438\u043c \u0432 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438docker push &lt;\u0432\u0430\u0448_\u043b\u043e\u0433\u0438\u043d&gt;\/echo-server:1.0\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0435\u043c, \u0432\u0441\u0435 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u043d\u043e \u0434\u043b\u044f \u043f\u0430\u0439\u0442\u043e\u043d\u0430.\u0412 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0437\u0430\u0435\u043c server.py \u0441 \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u0434\u043e\u043c.#!\/usr\/bin\/env python3import osimport socketfrom http.server import BaseHTTPRequestHandler, ThreadingHTTPServerdef env_or(key, fallback):    return os.getenv(key) or fallbackdef get_container_ip():    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    try:        s.connect((&#171;8.8.8.8&#187;, 80))        return s.getsockname()[0]    except Exception:        return &#171;unknown&#187;    finally:        s.close()class Handler(BaseHTTPRequestHandler):    def do_GET(self):        if self.path == &#171;\/healthz&#187;:            self.send_response(200)            self.send_header(&#171;Content-Type&#187;, &#171;text\/plain&#187;)            self.end_headers()            self.wfile.write(b&#187;ok\\n&#187;)            return        container_host = socket.gethostname()      # ID \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430        container_ip = get_container_ip()        host_host = env_or(&#171;HOST_HOSTNAME&#187;, &#171;(not injected)&#187;)        host_ip = env_or(&#171;HOST_IP&#187;, &#171;(not injected)&#187;)        author = env_or(&#171;AUTHOR&#187;, &#171;anonymous&#187;)        body = f&#187;&#187;&#187;&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;Echo Server&lt;\/title&gt;&lt;\/head&gt;&lt;body style=&#187;font-family:monospace&#187;&gt;  &lt;h1&gt;Echo Server (Python)&lt;\/h1&gt;  &lt;ul&gt;    &lt;li&gt;&lt;b&gt;Container hostname:&lt;\/b&gt; {container_host}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Container IP:&lt;\/b&gt; {container_ip}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host hostname:&lt;\/b&gt; {host_host}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Host IP:&lt;\/b&gt; {host_ip}&lt;\/li&gt;    &lt;li&gt;&lt;b&gt;Author:&lt;\/b&gt; {author}&lt;\/li&gt;  &lt;\/ul&gt;&lt;\/body&gt;&lt;\/html&gt;&#187;&#187;&#187;        self.send_response(200)        self.send_header(&#171;Content-Type&#187;, &#171;text\/html; charset=utf-8&#187;)        self.end_headers()        self.wfile.write(body.encode(&#171;utf-8&#187;))    def log_message(self, *args):        passif __name__ == &#171;__main__&#187;:    ThreadingHTTPServer((&#171;0.0.0.0&#187;, 8003), Handler).serve_forever()\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b. \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0440\u0430\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0441\u0451 \u0437\u0430\u0442\u0435\u0432\u0430\u043b\u043e\u0441\u044c. \u041f\u043e\u043c\u043d\u0438\u0442\u0435 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u044b\u0439 \u0444\u0438\u043d\u0430\u043b Go-\u0432\u0435\u0440\u0441\u0438\u0438 \u2014 FROM scratch, \u043e\u0431\u0440\u0430\u0437 \u0438\u0437 \u0447\u0438\u0441\u0442\u043e\u0439 \u043f\u0443\u0441\u0442\u043e\u0442\u044b \u0432\u0435\u0441\u043e\u043c \u0432 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u044b? \u0421 Python \u0442\u0430\u043a \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442 \u043d\u0438\u043a\u043e\u0433\u0434\u0430. Python \u2014 \u044f\u0437\u044b\u043a \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439: \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c server.py, \u0432 \u043e\u0431\u0440\u0430\u0437\u0435 \u043e\u0431\u044f\u0437\u0430\u043d \u0436\u0438\u0442\u044c \u0441\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u0441\u043e \u0432\u0441\u0435\u0439 \u0435\u0433\u043e \u0441\u0432\u0438\u0442\u043e\u0439. \u0412 \u043f\u0443\u0441\u0442\u043e\u0442\u0443 \u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0448\u044c, multi-stage \u0442\u0443\u0442 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u0435\u043d \u2014 \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0447\u0435\u0433\u043e, \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u043d\u0443\u0436\u0435\u043d \u0446\u0435\u043b\u0438\u043a\u043e\u043c.FROM python:3.12-alpineWORKDIR \/appRUN adduser -D appuser COPY &#8212;chown=appuser:appuser app.py .COPY server.py .EXPOSE 8003ENV AUTHOR=&#187;alfabuster&#187;ENTRYPOINT [ &#171;python3&#187; , &#171;server.py&#187;]\u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u043e\u0449\u0435, \u0432\u0441\u0435\u0433\u043e 8 \u0441\u0442\u0440\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e \u0433\u0430\u0439\u0434\u0443 \u0438\u0437 \u0434\u043e\u043a\u0435\u0440\u0430, \u043d\u0430\u043f\u0438\u0448\u0435\u0442 \u0434\u0430\u0436\u0435 \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u0431\u0435\u0437 \u043f\u0440\u043e\u0444\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 IT.\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0431\u0438\u043b\u0434\u0430 \u043e\u0431\u0440\u0430\u0437\u043e\u0432.alt text\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 10 \u0440\u0430\u0437. \u0417\u0434\u0435\u0441\u044c \u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 go.\u0410 \u0447\u0442\u043e \u043d\u0430 \u0441\u0447\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438? \u041e\u0431\u0440\u0430\u0437 \u043d\u0430 scratch \u2014 \u044d\u0442\u043e \u043a\u0440\u0435\u043f\u043e\u0441\u0442\u044c \u0431\u0435\u0437 \u0434\u0432\u0435\u0440\u0435\u0439: \u0442\u0430\u043c \u043d\u0435\u0442 sh, \u043d\u0435\u0442 apt, \u043d\u0435\u0442 curl, \u043d\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430. \u0417\u043b\u043e\u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u0438\u043a, \u043f\u0440\u043e\u0431\u0440\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u0432 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0443\u0441\u0442\u043e\u0439 \u0431\u0435\u0442\u043e\u043d\u043d\u043e\u0439 \u043a\u043e\u0440\u043e\u0431\u043a\u0435 \u2014 \u043d\u0438 \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c\u0441\u044f, \u043d\u0438 \u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c\u0441\u044f, \u043d\u0438 \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b. \u041e\u0434\u043d\u0430\u043a\u043e scratch \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 RCE, \u043f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435\/\u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0438 \u0438\u043b\u0438 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u044f\u0434\u0440\u0430\/\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430.\u0412 python:3.12-alpine sh \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0432\u0443\u0435\u0442. \u0422\u0430\u043a\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0430\u043c Python, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 RCE \u0430\u0442\u0430\u043a\u0443\u044e\u0449\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Python \u043a\u0430\u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e Unix-\u043a\u043e\u043c\u0430\u043d\u0434 \u043d\u0435\u0442.\u0421\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0440\u0430\u0434\u0438 \u2014 \u0443 Python \u0435\u0441\u0442\u044c \u0438 \u043a\u043e\u0437\u044b\u0440\u0438. Dockerfile \u043f\u0440\u043e\u0449\u0435 (\u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0441\u0442\u0430\u0434\u0438\u0438 \u0441\u0431\u043e\u0440\u043a\u0438), \u043f\u0440\u0430\u0432\u043a\u0438 \u043d\u0430 \u043b\u0435\u0442\u0443 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0430 \u0432\u043d\u0443\u0442\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0439\u0442\u0438 \u0438 \u043f\u043e\u0442\u044b\u043a\u0430\u0442\u044c \u043f\u0430\u043b\u043a\u043e\u0439, \u043a\u043e\u0433\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a. Go-scratch \u0437\u0430 \u0441\u0432\u043e\u044e \u043d\u0435\u043f\u0440\u0438\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u043f\u043b\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u2014 \u043a\u0430\u043a \u0447\u0438\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u044b: \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0434\u0432\u0435\u0440\u0446\u044b \u043d\u0435\u0442. \u042d\u0442\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u043d \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0442\u0438\u0432 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430.\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u0443\u0447\u0443\u0441\u044c \u043d\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0438\u043a\u0430, \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0432\u044b\u0431\u043e\u0440 \u043e\u0447\u0435\u0432\u0438\u0434\u0435\u043d, \u043e\u0434\u043d\u0430\u043a\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f, \u043d\u0435 \u0437\u043d\u0430\u044e, \u043a\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u043d\u0438 \u043e\u0431\u0430 \u0432\u0435\u0440\u043d\u044b\u0435. \u041f\u0440\u043e\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430, \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438.\u0422\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043f\u0435\u0440\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u0439.Ansible playbook \u0438\u043b\u0438 \u0440\u043e\u043b\u044c\u0426\u0435\u043b\u044c\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 Ansible\u0417\u0430\u0434\u0430\u0447\u0430\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u041c\u0430\u0448\u0438\u043d\u0443 (VM) \u0441 \u041e\u0421 Ubuntu 22.04. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438: \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0447\u0435\u0440\u0435\u0437 Virtual Box (\u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438), \u043b\u0438\u0431\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c Free-tier \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043e\u0442 cloud.ru &#8212; https:\/\/cloud.ru\/offers\/free-tier.\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Ansible:    \u041d\u0430 VM \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442 docker-ce;    \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c Web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 3-\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u0445. \u0414\u043b\u044f \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438&#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-494645","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/494645","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=494645"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/494645\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=494645"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=494645"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=494645"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}