{"id":363631,"date":"2024-05-21T02:00:17","date_gmt":"2024-05-21T02:00:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=363631"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=363631","title":{"rendered":"<span>\u0417\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Kubernetes \u0437\u0430 60 \u043c\u0438\u043d\u0443\u0442: \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, GitLab, Terraform<\/span>"},"content":{"rendered":"<div><!--[--><img loading=\"lazy\" decoding=\"async\" height=\"1\" src=\"https:\/\/vk.com\/rtrg?p=VK-RTRG-541074-aOhpd&amp;event=habr_devops\" style=\"display:none;\" width=\"1\"><img loading=\"lazy\" decoding=\"async\" height=\"1\" src=\"https:\/\/vk.com\/rtrg?p=VK-RTRG-541074-aOhpd&amp;event=habr_k8s\" style=\"display:none;\" width=\"1\"><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/aw\/xt\/u6\/awxtu69n9p5bdbzzbftwg6uv5gc.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/aw\/xt\/u6\/awxtu69n9p5bdbzzbftwg6uv5gc.jpeg\" data-blurred=\"true\"\/><\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0418\u043b\u044c\u044f \u041d\u044b\u0440\u043a\u043e\u0432, \u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u0432 <a href=\"https:\/\/mcs.mail.ru\/\">VK Cloud<\/a>. \u0412 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0441\u044c \u0441 \u0436\u0435\u043b\u0430\u043d\u0438\u0435\u043c \u043f\u0430\u0440\u0442\u043d\u0435\u0440\u043e\u0432 (\u044d\u0442\u043e \u0438 \u043a\u0440\u0443\u043f\u043d\u044b\u0439 \u044d\u043d\u0442\u0435\u0440\u043f\u0440\u0430\u0439\u0437, \u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430\u043f\u044b) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Kubernetes, \u043d\u043e \u0438\u0445 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f, \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430, \u0434\u0435\u043f\u043b\u043e\u044f \u0432 \u043d\u0451\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f CI\/CD-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0435\u0433\u043e. \u042f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0441\u0430\u043c\u0438, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0437\u0430 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 CI\/CD \u0441 \u0440\u0430\u0431\u043e\u0447\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 CI\/CD-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0440\u0430\u0437\u0431\u0438\u0442\u043e\u0435 \u043d\u0430 \u0434\u0432\u0430 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430 CRUD-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043f\u0443\u0448\u0438\u0442\u0441\u044f \u0432 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 \u0438 \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u0441\u044f \u0432 Kubernetes.\u00a0<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/hs\/y9\/a9\/hsy9a9q91a4uovwnzaud9kv_6y4.png\" data-src=\"https:\/\/habrastorage.org\/webt\/hs\/y9\/a9\/hsy9a9q91a4uovwnzaud9kv_6y4.png\"\/><\/p>\n<p>  \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u0448\u0430\u0433\u0438 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f: \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439 Kubernetes \u0432\u0440\u043e\u0434\u0435 Service, Ingress, Deployment \u0438 \u0442. \u0434. \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0445 \u0430\u0434\u0434\u043e\u043d\u043e\u0432 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441\u0442\u0435\u043d\u0434\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 Infrastructure-as-a-code. \u0412\u0441\u0435 \u0444\u0430\u0439\u043b\u044b Terraform \u0438 Kubernetes, \u043a\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0451\u043d\u043d\u0430\u044f \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u0430\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.\u00a0<\/p>\n<p>  \u0423\u043b\u043e\u0436\u0438\u0442\u0435\u0441\u044c \u043b\u0438 \u0432\u044b \u0432 \u0447\u0430\u0441, \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c. \u0421\u0430\u043c\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0435\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0438\u0445 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0442\u043e\u0447\u043d\u043e \u0437\u0430\u0439\u043c\u0443\u0442 \u0434\u0430\u0436\u0435 \u043c\u0435\u043d\u044c\u0448\u0435 \u0447\u0430\u0441\u0430.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u043e\u0437\u044c\u043c\u0451\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Go, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0440\u0430\u0437\u0431\u0438\u0442\u043e\u0435 \u043d\u0430 \u0434\u0432\u0430 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430: add_user (\u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439) \u0438 get_users (\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445). \u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043c\u0438 \u0431\u0443\u0434\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e API-\u0432\u044b\u0437\u043e\u0432\u043e\u0432.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ec\/0n\/hs\/ec0nhsfammctsf6ogmgennrrrqo.png\" data-src=\"https:\/\/habrastorage.org\/webt\/ec\/0n\/hs\/ec0nhsfammctsf6ogmgennrrrqo.png\"\/><br \/>  <i>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/i><\/p>\n<p>  \u0414\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u044b Docker-\u0444\u0430\u0439\u043b\u044b, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0441\u0431\u043e\u0440\u043a\u0443, \u0438 Make-\u0444\u0430\u0439\u043b \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 VK Cloud <a href=\"https:\/\/mcs.mail.ru\/docs\/dbs\/dbaas\/types\/postgresql\">PostgreSQL<\/a> \u0432 \u0441\u0438\u043d\u0433\u043b-\u0438\u043d\u0441\u0442\u0430\u043d\u0441-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u0414\u043b\u044f \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 Kubernetes \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 Deployment \u0438 Service, \u0430 \u0442\u0430\u043a\u0436\u0435 Ingress-\u043e\u0431\u044a\u0435\u043a\u0442, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 Kubernetes.<\/p>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b<\/h2>\n<p>  \u0414\u043b\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c Infrastructure-as-a-Code, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445. \u0414\u0435-\u0444\u0430\u043a\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u0432 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0441\u0442\u0430\u043b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 Terraform (\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u043e <a href=\"https:\/\/mcs.mail.ru\/docs\/ru\/manage\/tools-for-using-services\/terraform\/quick-start\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435<\/a>), \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0443 VK Cloud \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 <a href=\"https:\/\/github.com\/vk-cs\/terraform-provider-vkcs\">\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440<\/a>. \u042f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0430 \u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u0412\u043e\u043b\u043a\u043e\u0432, \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 Kubernetes \u0432 VK Cloud, <a href=\"https:\/\/habr.com\/ru\/companies\/vk\/articles\/763282\/\">\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b<\/a> \u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 Terraform \u0441 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c Kubernetes.<\/p>\n<p>  \u0418\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 sdn \u2014 sprut, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u0439 <a href=\"https:\/\/habr.com\/ru\/companies\/vk\/articles\/763760\/\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0438 <a href=\"https:\/\/mcs.mail.ru\/docs\/ru\/manage\/tools-for-using-services\/rest-api\/enable-api\">\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043f\u043e API<\/a> \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 VK Cloud. \u0414\u0430\u043b\u044c\u0448\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c RC-\u0444\u0430\u0439\u043b \u0438\u0437 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043e\u0431\u043b\u0430\u043a\u0443 \u043f\u043e API \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/mcs.mail.ru\/docs\/ru\/manage\/tools-for-using-services\/openstack-cli\">OpenStack CLI<\/a> \u0438 Terraform.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/r3\/_8\/hs\/r3_8hsbrt90tiyo5criowij3vtg.png\" data-src=\"https:\/\/habrastorage.org\/webt\/r3\/_8\/hs\/r3_8hsbrt90tiyo5criowij3vtg.png\"\/><br \/>  <i>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 RC-\u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API \u043e\u0431\u043b\u0430\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 Terraform<\/i><\/p>\n<p>  \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API \u043e\u0431\u043b\u0430\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 Terraform \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<pre><code class=\"bash\">source &lt;\u0438\u043c\u044f RC-\u0444\u0430\u0439\u043b\u0430> <\/code><\/pre>\n<p>  \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 Terraform. \u0424\u0430\u0439\u043b\u044b \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438 \u0432\u0435\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u0443 \u0432 \u043d\u0451\u043c.<\/p>\n<p>  \u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e: \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432 \u0432\u0438\u0434\u0435 S3 \u0434\u043b\u044f tfstate. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e <a href=\"https:\/\/mcs.mail.ru\/docs\/base\/s3\/quick-start\">\u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0431\u0430\u043a\u0435\u0442 S3<\/a> \u0432 VK Cloud, \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0435\u0433\u043e \u0438\u043c\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u044d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u0432 \u0444\u0430\u0439\u043b <b>terraform\/provider.tf<\/b>.<\/p>\n<pre><code class=\"python\">terraform { \u00a0\u00a0backend \"s3\" { \u00a0\u00a0\u00a0\u00a0bucket = &lt;\u0438\u043c\u044f \u0431\u0430\u043a\u0435\u0442\u0430 S3> \u00a0\u00a0\u00a0\u00a0key = \"terraform.tfstate\" \u00a0\u00a0\u00a0\u00a0endpoint = \"https:\/\/hb.ru-msk.vkcs.cloud\/\"  \u00a0\u00a0\u00a0\u00a0skip_region_validation = true \u00a0\u00a0\u00a0\u00a0skip_credentials_validation = true \u00a0\u00a0\u00a0\u00a0skip_metadata_api_check = true \u00a0\u00a0} } <\/code><\/pre>\n<p>  \u0418\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0442\u0435\u0439\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>  \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u043e\u043b\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0443 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u0444\u0430\u0439\u043b\u0435 terraform\/variables.tf \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>db_password<\/code>. \u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043e \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u0445 \u043f\u0430\u0440\u043e\u043b\u044f \u0411\u0414 \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0438\u043d\u0430\u0447\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u043e\u0439: \u00ab\u0417\u0430\u0433\u043b\u0430\u0432\u043d\u044b\u0435 \u0438 \u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0435 \u0431\u0443\u043a\u0432\u044b \u043b\u0430\u0442\u0438\u043d\u0441\u043a\u043e\u0433\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0430, \u0446\u0438\u0444\u0440\u044b, \u0441\u0438\u043c\u0432\u043e\u043b\u044b !$&amp;*()-+=.,\u00bb\u00a0<\/p>\n<p>  \u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u0443 \u0431\u0443\u043a\u0432\u0443 \u0438 \u0446\u0438\u0444\u0440\u0443, \u043f\u043e\u043c\u0438\u043c\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<pre><code class=\"bash\">export TF_VAR_db_password=&lt;\u043f\u0430\u0440\u043e\u043b\u044c \u0431\u0434> <\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 Terraform:<\/p>\n<pre><code class=\"bash\">cd terraform <\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0451\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 VK Cloud \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<ul>\n<li>\u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes-as-a-Service:\n<p>  \u25cb \u043e\u0434\u0438\u043d \u043c\u0430\u0441\u0442\u0435\u0440: \u0442\u0438\u043f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b: 2-4 (2 CPU, 4 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438). \u0414\u0438\u0441\u043a: 50 \u0413\u0411;<\/p>\n<p>  \u25cb \u043e\u0434\u043d\u0430 \u043d\u043e\u0434-\u0433\u0440\u0443\u043f\u043f\u0430: \u0442\u0438\u043f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b: 2-4 (2 CPU, 4 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438). \u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u043d\u043e\u0434: 3. \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u043d\u043e\u0434: 4;  <\/li>\n<li>\u0438\u043d\u0441\u0442\u0430\u043d\u0441 PostgreSQL:\n<p>  \u25cb \u0442\u0438\u043f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b: 2-8 (2 CPU, 8 \u0413\u0431 \u043f\u0430\u043c\u044f\u0442\u0438);  <\/li>\n<li>\u0441\u0435\u0442\u044c\/\u043f\u043e\u0434\u0441\u0435\u0442\u044c;  <\/li>\n<li>\u0440\u043e\u0443\u0442\u0435\u0440.  <\/li>\n<\/ul>\n<p>  \u041f\u0440\u043e\u0435\u043a\u0442 Terraform \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443:<\/p>\n<ul>\n<li>variables.tf,  <\/li>\n<li>main.tf,  <\/li>\n<li>data.tf,  <\/li>\n<li>provider.tf.  <\/li>\n<\/ul>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p>  \u0412 <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/terraform\/provider.tf?ref_type=heads\">provider.tf<\/a> \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430. \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u2014 0.6.1, \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/vk-cs\/terraform-provider-vkcs\/releases\">GitHub \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430<\/a>.<\/p>\n<pre><code class=\"python\">terraform { \u00a0\u00a0required_providers { \u00a0\u00a0\u00a0\u00a0vkcs = { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0source = \"vk-cs\/vkcs\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0version = \"~> 0.6.1\" \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0} } <\/code><\/pre>\n<p>  \u0412 \u0444\u0430\u0439\u043b\u0435 <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/terraform\/variables.tf?ref_type=heads\">variables.tf<\/a> \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u041e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0445 <a href=\"https:\/\/developer.hashicorp.com\/terraform\/language\/expressions\/types\">\u0442\u0438\u043f\u043e\u0432<\/a>. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043b\u0438\u0431\u043e \u0432 \u043f\u043e\u043b\u0435 <code>default<\/code>, \u043b\u0438\u0431\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 (\u0435\u0441\u043b\u0438 \u043d\u0435 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e), \u043b\u0438\u0431\u043e \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0445\u043e\u0441\u0442\u0435, \u0433\u0434\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f Terraform, \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c <code>TF_VAR_<\/code>.<\/p>\n<pre><code class=\"python\"># ---- KUBERNETES -----  variable \"k8s_master_count\" { \u00a0\u00a0type = number \u00a0\u00a0default = 1 }  variable \"k8s_master_volume_size\" { \u00a0\u00a0type = number \u00a0\u00a0default = 50 } ... <\/code><\/pre>\n<p>  \u0412 \u0444\u0430\u0439\u043b\u0435 <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/terraform\/data.tf?ref_type=heads\">data.tf<\/a> \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u043e \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 \u0432\u0440\u043e\u0434\u0435 \u0442\u0438\u043f\u043e\u0432 \u0434\u0438\u0441\u043a\u043e\u0432, \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d \u0438 \u0442. \u0434., \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0438 \u0434\u0430\u043b\u0435\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<pre><code class=\"python\">data \"vkcs_compute_flavor\" \"k8s_node\" { \u00a0\u00a0name = \"Standard-2-4-50\" }  data \"vkcs_kubernetes_clustertemplate\" \"ct\" { \u00a0\u00a0version = \"1.26\" }  ... <\/code><\/pre>\n<p>  \u0412 \u0444\u0430\u0439\u043b\u0435 <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/terraform\/main.tf?ref_type=heads\">main.tf<\/a> \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0432 \u043e\u0431\u043b\u0430\u043a\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435;  <\/li>\n<li>\u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0411\u0414 Postgres;  <\/li>\n<li>\u0441\u0435\u0442\u044c, \u043f\u043e\u0434\u0441\u0435\u0442\u044c \u0438 \u0440\u043e\u0443\u0442\u0435\u0440.  <\/li>\n<\/ul>\n<p>  \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c Terraform:<\/p>\n<pre><code class=\"python\">terraform init<\/code><\/pre>\n<p>  \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432\u0440\u043e\u0434\u0435 tfstate \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 tf.lock \u0434\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b:<\/p>\n<pre><code class=\"python\">terraform apply <\/code><\/pre>\n<p>  \u0412\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/u6\/5m\/mr\/u65mmr8zyr-f23crbaln88m9jro.png\" data-src=\"https:\/\/habrastorage.org\/webt\/u6\/5m\/mr\/u65mmr8zyr-f23crbaln88m9jro.png\"\/><\/p>\n<p>  \u0412\u0432\u0435\u0434\u0451\u043c \u00abyes\u00bb \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 Terraform \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 \u0431\u043b\u043e\u043a\u0430\u0445 \u00aboutput\u00bb, \u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0432 \u043e\u0431\u043b\u0430\u043a\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/wk\/sx\/ku\/wksxkuckfzy7cp3ahdwsodfivvi.png\" data-src=\"https:\/\/habrastorage.org\/webt\/wk\/sx\/ku\/wksxkuckfzy7cp3ahdwsodfivvi.png\"\/><\/p>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0438 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c<\/h2>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 Private \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0432 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u043c GitLab.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/4i\/6_\/rp\/4i6_rp9ltgrsc2g6vxjgzlk1i0q.png\" data-src=\"https:\/\/habrastorage.org\/webt\/4i\/6_\/rp\/4i6_rp9ltgrsc2g6vxjgzlk1i0q.png\"\/><br \/>  <i>C\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432 GitLab<\/i><\/p>\n<p>  \u041a\u043b\u043e\u043d\u0438\u0440\u0443\u0439\u0442\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 \u043d\u0438\u043c. \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/tree\/main?ref_type=heads\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438<\/a>.\u00a0<\/p>\n<p>  \u0414\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a Kubernetes \u0432\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u044b keystone authentication \u0438 kubectl. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u0441\u044c \u043a \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0443 Kubernetes, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 <a href=\"https:\/\/mcs.mail.ru\/docs\/ru\/base\/k8s\/connect\/kubectl\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes <a href=\"https:\/\/docs.gitlab.com\/runner\/\">\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0438 GitLab<\/a> \u2014 \u044d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 (<a href=\"https:\/\/docs.gitlab.com\/ee\/ci\/jobs\/\">job<\/a>), \u0442\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u0430\u043f\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e CI\/CD-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430.\u00a0<br \/>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 Helm-\u0447\u0430\u0440\u0442\u043e\u043c (<a href=\"https:\/\/helm.sh\/docs\/intro\/install\/\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Helm<\/a>):<\/p>\n<pre><code class=\"bash\">helm repo add gitlab https:\/\/charts.gitlab.io <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"bash\">helm repo update gitlab <\/code><\/pre>\n<p>  <a href=\"https:\/\/helm.sh\/\">Helm<\/a> \u2014 \u044d\u0442\u043e, \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0439 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0434\u043b\u044f Kubernetes, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u00ab\u0447\u0430\u0440\u0442\u043e\u0432\u00bb \u2014 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0432\u0441\u0435\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u2014 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435. Helm \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0448\u0438\u0440\u043e\u043a\u0438\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/helm.sh\/docs\/chart_best_practices\/templates\/\">\u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f<\/a>.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u043a\u0440\u0435\u0442 (<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/secret\/\">secret<\/a>) \u0441 <a href=\"https:\/\/docs.gitlab.com\/runner\/register\/\">\u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0440\u0430\u043d\u043d\u0435\u0440\u0430<\/a>. \u0421\u0435\u043a\u0440\u0435\u0442 \u2014 \u044d\u0442\u043e \u0440\u0435\u0441\u0443\u0440\u0441 \u0432 Kubernetes, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u044c sensitive \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e. \u0422\u043e\u043a\u0435\u043d \u0440\u0430\u043d\u043d\u0435\u0440\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f-\u0440\u0430\u043d\u043d\u0435\u0440\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 GitLab. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0432 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 GitLab.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0440\u0430\u043d\u043d\u0435\u0440:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/i6\/dd\/fe\/i6ddfefzrhwtavsptgdkr_6_6zy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/i6\/dd\/fe\/i6ddfefzrhwtavsptgdkr_6_6zy.png\"\/><\/p>\n<p>  \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0438\u043f Linux. \u042d\u0442\u043e \u043d\u0435 \u0441\u0442\u043e\u043b\u044c \u0432\u0430\u0436\u043d\u043e, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u043c \u0442\u043e\u043a\u0435\u043d:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/9z\/nx\/zf\/9znxzf4-uxmg-xn1m0zazxyv5tu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/9z\/nx\/zf\/9znxzf4-uxmg-xn1m0zazxyv5tu.png\"\/><\/p>\n<p>  \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0442\u043e\u043a\u0435\u043d, \u043e\u043d \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0430\u043c \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u0439 GitLab \u0447\u0435\u0440\u0435\u0437 Helm:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/pa\/ov\/g3\/paovg3cgwjbeslc88offkrn61sy.png\" data-src=\"https:\/\/habrastorage.org\/webt\/pa\/ov\/g3\/paovg3cgwjbeslc88offkrn61sy.png\"\/><br \/>  <i>\u0422\u043e\u043a\u0435\u043d \u0440\u0430\u043d\u043d\u0435\u0440\u0430<\/i><\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u043a\u0440\u0435\u0442 \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c runner token:<\/p>\n<pre><code class=\"bash\">cat &lt;&lt; EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: \u00a0\u00a0name: dev-gitlab-runner \u00a0\u00a0namespace: gitlab type: Opaque stringData: \u00a0\u00a0# \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u044f\u0432\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u00a0\u00a0runner-registration-token: \"\" \u00a0\u00a0# \u0442\u0443\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0432 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0442\u043e\u043a\u0435\u043d \u00a0\u00a0runner-token: \"glrt-1KJ_ky-66jzYyrpvxM_L\" EOF <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0434\u0435\u043f\u043b\u043e\u044f \u0440\u0430\u043d\u043d\u0435\u0440\u043e\u0432 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0440\u0430\u043d\u043d\u0435\u0440\u0430 GitLab <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/gitlab-config-values.yml?ref_type=heads\">gitlab-config-values.yml<\/a><\/p>\n<pre><code class=\"plaintext\">gitlabUrl: &lt;a href=\"https:\/\/gitlab.com\/\">https:\/\/gitlab.com&lt;\/a> # \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438, \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0438\u0437 # \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0440\u0435\u0442\u0430 runnerToken: # \u042d\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Role-Based Access Control (RBAC) \u0434\u043b\u044f \u0440\u0430\u043d\u043d\u0435\u0440\u0430 \u0432 Kubernetes. \u042d\u0442\u043e \u043f\u0440\u0430\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043f\u043e\u0434 GitLab \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 rbac: # \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0440\u043e\u043b\u044c \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438, \u0435\u0441\u043b\u0438 \u0435\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u00a0create: true # \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043d\u0438\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u044b \u00a0rules: \u00a0- resources: [\"pods\", \"secrets\", \"configmaps\"] \u00a0\u00a0\u00a0verbs: [\"get\", \"list\", \"watch\", \"create\", \"patch\", \"delete\", \"update\"] \u00a0- apiGroups: [\"\"] \u00a0\u00a0\u00a0resources: [\"pods\/exec\", \"pods\/attach\"] \u00a0\u00a0\u00a0verbs: [\"create\", \"patch\", \"delete\"] # \u0420\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c\u0438 \u0432\u044b\u0448\u0435, \u043f\u043e\u0434 GitLab \u0441\u043c\u043e\u0436\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u043e \u0432\u0441\u0435\u0445 # \u043d\u0435\u0439\u043c\u0441\u043f\u0435\u0439\u0441\u0430\u0445. \u0414\u043b\u044f \u043f\u0440\u043e\u0434\u0441\u0440\u0435\u0434\u044b \u043b\u0443\u0447\u0448\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043d\u0435\u0439\u043c\u0441\u043f\u0435\u0439\u0441\u044b \u00a0clusterWideAccess: true # \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c pod security policy \u0434\u043b\u044f \u043f\u043e\u0434\u043e\u0432 GitLab \u0440\u0430\u043d\u043d\u0435\u0440\u0430\u00a0 \u00a0podSecurityPolicy: \u00a0\u00a0\u00a0enabled: false \u00a0\u00a0\u00a0resourceNames: \u00a0\u00a0\u00a0- gitlab-runner # \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0441\u0430\u043c\u0438\u0445 \u0440\u0430\u043d\u043d\u0435\u0440\u043e\u0432 runners: \u00a0config: | \u00a0\u00a0\u00a0# \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0443 \u043f\u043e\u0434\u043e\u0432 \u0440\u0430\u043d\u043d\u0435\u0440\u0430 \u00a0\u00a0\u00a0log_level = \"debug\" \u00a0\u00a0\u00a0# \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u0434\u043e\u0432 \u0440\u0430\u043d\u043d\u0435\u0440\u043e\u0432 \u00a0\u00a0\u00a0[[runners]] \u00a0\u00a0\u00a0\u00a0\u00a0[runners.kubernetes] \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0image = \"ubuntu:22.04\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0434\u044b \u0441 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u044f\u043c\u0438 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u044b \u0441 \u0440\u0443\u0442-\u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0privileged = true \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0allow_privilege_escalation = true # \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u0438\u043f \u0440\u0430\u043d\u043d\u0435\u0440\u0430 \u00a0executor: kubernetes # \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0440\u0435\u0442\u0430 \u00a0secret: dev-gitlab-runner <\/code><\/pre>\n<p>  \u0414\u0435\u043f\u043b\u043e\u0438\u043c \u0440\u0430\u043d\u043d\u0435\u0440\u044b GitLab \u0447\u0435\u0440\u0435\u0437 Helm.<\/p>\n<pre><code class=\"bash\">helm install gitlab-runner gitlab\/gitlab-runner -f gitlab-config-values.yml -n gitlab <\/code><\/pre>\n<p>  <\/p>\n<h2>\u0414\u0435\u043f\u043b\u043e\u0439 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-service-account\/\">\u0441\u0435\u0440\u0432\u0438\u0441-\u0430\u043a\u043a\u0430\u0443\u043d\u0442<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d GitLab \u0434\u043b\u044f \u0434\u0435\u043f\u043b\u043e\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435. \u042d\u0442\u043e \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u0430\u044f \u0443\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 API-\u0441\u0435\u0440\u0432\u0435\u0440 \u0438\u0437 \u043f\u043e\u0434\u043e\u0432.<\/p>\n<pre><code class=\"bash\">kubectl create sa deploy -n vk-cloud-project <\/code><\/pre>\n<p>  \u0418 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <a href=\"https:\/\/kubernetes.io\/docs\/reference\/access-authn-authz\/rbac\/\">rolebinding<\/a>, \u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0439\u0441\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u043e\u0439 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u043e\u043b\u0438:<\/p>\n<pre><code class=\"bash\">kubectl create rolebinding deploy \\ \u00a0\u00a0-n vk-cloud-project \\ \u00a0\u00a0--clusterrole edit \\ \u00a0\u00a0--serviceaccount vk-cloud-project:deploy <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u043e\u043a\u0435\u043d \u043f\u043e\u0434 \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441-\u0430\u043a\u043a\u0430\u0443\u043d\u0442:<\/p>\n<pre><code class=\"bash\">kubectl apply -n vk-cloud-project -f - &lt;&lt;EOF apiVersion: v1 kind: Secret metadata: \u00a0\u00a0name: deploy \u00a0\u00a0annotations: \u00a0\u00a0\u00a0\u00a0kubernetes.io\/service-account.name: deploy \u00a0\u00a0type: kubernetes.io\/service-account-token EOF <\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430 \u0441\u0435\u0440\u0432\u0438\u0441-\u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430:<\/p>\n<pre><code class=\"bash\">kubectl get secrets -n vk-cloud-project deploy -o jsonpath='{.data.token}' <\/code><\/pre>\n<p>  \u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 GitLab \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>K8S_CI_TOKEN<\/code> \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u0430. \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0440\u0430\u043d\u0435\u0435. \u0422\u043e\u043a\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f GitLab \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 API-\u0441\u0435\u0440\u0432\u0435\u0440 Kubernetes \u043f\u0440\u0438 \u0434\u0435\u043f\u043b\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/-0\/fn\/gi\/-0fngir_rd4xf09asxxsmvce1v4.png\" data-src=\"https:\/\/habrastorage.org\/webt\/-0\/fn\/gi\/-0fngir_rd4xf09asxxsmvce1v4.png\"\/><br \/>  <i>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 GitLab<\/i><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/fn\/eu\/oy\/fneuoylqu6gok0dayftihnysouo.png\" data-src=\"https:\/\/habrastorage.org\/webt\/fn\/eu\/oy\/fneuoylqu6gok0dayftihnysouo.png\"\/><br \/>  <i>\u0423\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 GitLab<\/i><\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f Kubernetes \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438\u0437 \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 GitLab.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0451\u043c pull token \u0432 web-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/nw\/-h\/sv\/nw-hsv3dyh392cvu-3he4sjcdgw.png\" data-src=\"https:\/\/habrastorage.org\/webt\/nw\/-h\/sv\/nw-hsv3dyh392cvu-3he4sjcdgw.png\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/_8\/ej\/dr\/_8ejdrbf6ob7p0xm1yoxya3tg6c.png\" data-src=\"https:\/\/habrastorage.org\/webt\/_8\/ej\/dr\/_8ejdrbf6ob7p0xm1yoxya3tg6c.png\"\/><\/p>\n<p>  \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/hc\/to\/3m\/hcto3mws26dxloh3pub39m8vixs.png\" data-src=\"https:\/\/habrastorage.org\/webt\/hc\/to\/3m\/hcto3mws26dxloh3pub39m8vixs.png\"\/><\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u043a\u0440\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 GitLab:<\/p>\n<pre><code class=\"bash\">kubectl create secret docker-registry vkcloud-kubernetes-project-image-pull \\ --docker-server registry.gitlab.com \\ --docker-email 'admin@mycompany.com' \\ --docker-username '&lt;\u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430>' \\ --docker-password '&lt;\u0432\u0442\u043e\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430>' \\ --namespace vk-cloud-project <\/code><\/pre>\n<p>  <\/p>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c<\/h2>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u043a\u0440\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u0411\u0414 Postgres.<\/p>\n<pre><code class=\"bash\">kubectl create secret generic user-app \\ --from-literal=DB_NAME=&lt;\u0438\u043c\u044f \u0431\u0434> \\ --from-literal=DB_USER=&lt;\u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0411\u0414> \\ --from-literal=DB_PASSWORD=&lt;\u043f\u0430\u0440\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0411\u0414> \\ --from-literal=DB_HOST=&lt;\u0441\u0435\u0440\u044b\u0439 IP-\u0430\u0434\u0440\u0435\u0441 \u0411\u0414> \\ --from-literal=DB_PORT=5432 <\/code><\/pre>\n<p>  <\/p>\n<h2>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Kubernetes, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438<\/h2>\n<p>  <\/p>\n<h3>\u0420\u0430\u0431\u043e\u0447\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430<\/h3>\n<p>  <\/p>\n<h4>\u041f\u043e\u0434 (Pod)<\/h4>\n<p>  \u0411\u0430\u0437\u043e\u0432\u043e\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0435\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 Kubernetes \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/pods\/\">\u043f\u043e\u0434<\/a>: \u0432 \u043d\u0451\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432. \u0412 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0434\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0449\u0451 Sidecar-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u043b\u043e\u0433\u043e\u0432 \u0438\u043b\u0438 Reverse-\u043f\u0440\u043e\u043a\u0441\u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 Service Mesh. \u0412 \u043d\u0430\u0448\u0435\u043c Kubernetes \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 CRI-O. \u041f\u043e\u0434\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043d\u043e\u0434\u0430\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430. \u0421\u0430\u043c \u043f\u043e\u0434 \u0440\u0435\u0434\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u043f\u0440\u0438 \u0434\u0435\u043f\u043b\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0443\u0440\u0441 Deployment, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u043e\u0434\u044b \u0447\u0435\u0440\u0435\u0437 ReplicaSet.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/-l\/an\/by\/-lanby33jlbotkxm2lxkjokyfae.png\" data-src=\"https:\/\/habrastorage.org\/webt\/-l\/an\/by\/-lanby33jlbotkxm2lxkjokyfae.png\"\/><\/p>\n<h4>\u041d\u0430\u0431\u043e\u0440 \u0440\u0435\u043f\u043b\u0438\u043a (ReplicaSet)<\/h4>\n<p>  <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/replicaset\/\">ReplicaSet<\/a> \u2014 \u044d\u0442\u043e \u0440\u0435\u0441\u0443\u0440\u0441 \u0432 Kubernetes, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043c\u0435\u0442\u043e\u043a (Labels) \u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 (Selector) \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0434\u043e\u0432. \u0415\u0441\u043b\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u043f\u043e\u0434\u043e\u0432 \u0443\u043f\u0430\u0434\u0451\u0442, \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0441\u0435\u0442 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u0442 \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0439. \u0415\u0441\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043e\u0432 \u0432 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0441\u0435\u0442\u0435, \u0442\u043e \u043e\u043d \u0443\u0434\u0430\u043b\u0438\u0442 \u043b\u0438\u0448\u043d\u0438\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/vn\/7b\/wn\/vn7bwnui8g_lpudvjnsoi1xv2pq.png\" data-src=\"https:\/\/habrastorage.org\/webt\/vn\/7b\/wn\/vn7bwnui8g_lpudvjnsoi1xv2pq.png\"\/><\/p>\n<h4>\u0414\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442 (Deployment)<\/h4>\n<p>  <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/controllers\/deployment\/\">Deployment<\/a> \u2014 \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0434\u0435\u043f\u043b\u043e\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0441\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u043e\u0434\u044b. \u0414\u0435\u043f\u043b\u043e\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u043f\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 (\u043f\u043e\u0434 \u0437\u0430 \u043f\u043e\u0434\u043e\u043c).<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/bw\/qn\/sr\/bwqnsrvya9usp_ajrt_dcorwb1y.png\" data-src=\"https:\/\/habrastorage.org\/webt\/bw\/qn\/sr\/bwqnsrvya9usp_ajrt_dcorwb1y.png\"\/><\/p>\n<h3>\u0421\u0435\u0442\u0435\u0432\u044b\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>  \u0414\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 Kubernetes \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0443\u0440\u0441 Service, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f\u043e\u0432.<\/p>\n<h4>ClusterIP\u00a0<\/h4>\n<p>  \u0421\u0435\u0440\u0432\u0438\u0441 \u0442\u0438\u043f\u0430 \u0421lusterIP \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442 \u043f\u043e\u0434, \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442 \u0438\u043b\u0438 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0441\u0435\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u043a \u0438\u043b\u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 (\u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0432, \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0441\u0435\u0442\u0443). \u0411\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d IP, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430. \u041f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u044d\u0442\u043e\u0442 IP \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0434\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0441\u0435\u0442\u0430 \u0438\u043b\u0438 \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442\u0430).<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/l6\/r6\/b7\/l6r6b7zxlwdvo7nnmdhfqzaj8co.png\" data-src=\"https:\/\/habrastorage.org\/webt\/l6\/r6\/b7\/l6r6b7zxlwdvo7nnmdhfqzaj8co.png\"\/><\/p>\n<h4>NodePort<\/h4>\n<p>  \u0421\u0435\u0440\u0432\u0438\u0441 \u0442\u0438\u043f\u0430 NodePort \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043c\u0438\u0440, \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u044f \u0438\u0445 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0440\u0442\u044b \u043d\u0430 \u043d\u043e\u0434\u0430\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430. \u041f\u043e\u0440\u0442\u044b \u0432\u044b\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 30 000\u201332 767, \u0442\u0430\u043a \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u0438\u0437\u0432\u043d\u0435. \u0422\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437-\u0437\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 IP \u0432\u0441\u0435\u043c \u0432\u043e\u0440\u043a\u0435\u0440-\u043d\u043e\u0434\u0430\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0434\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0435 \u043d\u043e\u0434\u044b \u0438 \u0432\u0441\u0435 \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/u4\/gl\/5c\/u4gl5chrn85dchilhzrqtqlyhqq.png\" data-src=\"https:\/\/habrastorage.org\/webt\/u4\/gl\/5c\/u4gl5chrn85dchilhzrqtqlyhqq.png\"\/><\/p>\n<h4>LoadBalancer\u00a0<\/h4>\n<p>  LoadBalancer \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0448\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0443\u044e \u0432\u044b\u0448\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 NodePort \u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u043f\u043e \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u043e\u0440\u0442\u0443. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u043e\u0431\u043b\u0430\u043a\u043e \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0441\u0432\u043e\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP \u0438 \u043f\u043e\u0440\u0442\u044b 80\/443 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0440\u0430\u0444\u0438\u043a \u0432 \u0432\u043e\u0440\u043a\u0435\u0440-\u043d\u043e\u0434\u044b \u043f\u043e \u043f\u043e\u0440\u0442\u0430\u043c NodePort.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/h2\/f0\/wu\/h2f0wualcztw1prksffnx9jcpfu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/h2\/f0\/wu\/h2f0wualcztw1prksffnx9jcpfu.png\"\/><\/p>\n<h4>Ingress Controller<\/h4>\n<p>  \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u0441 LoadBalancer \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043f\u0440\u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439: \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0432 \u043e\u0431\u043b\u0430\u043a\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0440\u043e\u0433\u043e \u0438 \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e. \u0422\u0430\u043a\u0436\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0432\u043d\u0435\u0448\u043d\u0435\u043c\u0443 IP \u0438 \u043f\u043e \u0440\u0430\u0437\u043d\u044b\u043c URL.\u00a0<\/p>\n<p>  \u042d\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0440\u0435\u0448\u0430\u0435\u0442 \u0438\u043d\u0433\u0440\u0435\u0441\u0441-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0434\u0438\u043d \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/vl\/8y\/52\/vl8y52gbfw7tjpg2d6wd4nf5dxi.png\" data-src=\"https:\/\/habrastorage.org\/webt\/vl\/8y\/52\/vl8y52gbfw7tjpg2d6wd4nf5dxi.png\"\/><\/p>\n<h2>\u0417\u0430\u043f\u0443\u0441\u043a \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>git push<\/code>. \u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/.gitlab-ci.yml?ref_type=heads\">.gitlab-ci.yml<\/a> \u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0451\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/qi\/xr\/wf\/qixrwf60y7e72_ieeu2u3ysi-as.png\" data-src=\"https:\/\/habrastorage.org\/webt\/qi\/xr\/wf\/qixrwf60y7e72_ieeu2u3ysi-as.png\"\/><\/p>\n<p>  \u0412 <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/.gitlab-ci.yml?ref_type=heads\">.gitlab-ci.yml<\/a> \u043e\u043f\u0438\u0441\u0430\u043d\u043e 2 \u044d\u0442\u0430\u043f\u0430 (stage), \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0436\u043e\u0431\u044b.  <\/p>\n<pre><code class=\"plaintext\">stages:   - build   - deploy <\/code><\/pre>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u0430\u043f\u0430 build \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0438 \u043f\u0443\u0448\u0430\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0437\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 add_user, get_users \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f gitlab:  <\/p>\n<pre><code class=\"plaintext\">build_add_user:   image: docker:19.03.12   stage: build   services:     - docker:19.03.12-dind   variables:     DOCKER_HOST: tcp:\/\/docker:2375     DOCKER_TLS_CERTDIR: \"\"   before_script: # \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c login \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0433\u0438\u0442\u043b\u0430\u0431\u0430     - docker login -u \"$CI_REGISTRY_USER\" -p \"$CI_REGISTRY_PASSWORD\" $CI_REGISTRY   script: # \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0433\u043e \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430     - cd app &amp;&amp; docker build -t \"$CI_REGISTRY_IMAGE:add_user.$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID\" -f cmd\/add_user\/Dockerfile . # \u043f\u0443\u0448\u0438\u043c \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438     - docker push \"$CI_REGISTRY_IMAGE:add_user.$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID\"  # \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 \u0434\u043b\u044f add_user build_get_users:   image: docker:19.03.12   stage: build   services:     - docker:19.03.12-dind   variables:     DOCKER_HOST: tcp:\/\/docker:2375     DOCKER_TLS_CERTDIR: \"\"   before_script:     - docker login -u \"$CI_REGISTRY_USER\" -p \"$CI_REGISTRY_PASSWORD\" $CI_REGISTRY   script:     - cd app &amp;&amp; docker build -t \"$CI_REGISTRY_IMAGE:get_users.$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID\" -f cmd\/get_users\/Dockerfile .     - docker push \"$CI_REGISTRY_IMAGE:get_users.$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID\"  <\/code><\/pre>\n<p>  \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u0430\u043f\u0430 deploy \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 kubernetes \u0438\u0437 \u043e\u0431\u0440\u0430\u0437\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0437\u0430\u043f\u0443\u0448\u0435\u043d\u044b \u0440\u0430\u043d\u0435\u0435:<\/p>\n<pre><code class=\"plaintext\">deploy:   stage: deploy   image:      name: bitnami\/kubectl:latest     entrypoint: ['']   variables:     K8S_NAMESPACE: vk-cloud-project   before_script:     # \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u0443\u0431\u043a\u043e\u043d\u0444\u0438\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0438\u0442\u043b\u0430\u0431 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435     - export KUBECONFIG=\/tmp\/kubeconfig     - kubectl config set-cluster k8s --insecure-skip-tls-verify=true --server=https:\/\/kubernetes.default     - kubectl config set-credentials ci --token=\"$(echo $K8S_CI_TOKEN | base64 -d)\"     - kubectl config set-context ci --cluster=k8s --user=ci --namespace $K8S_NAMESPACE     - kubectl config use-context ci   script: # \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c in-place \u0444\u0430\u0439\u043b \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442\u0430, \u0443\u043a\u0430\u0437\u0430\u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043e\u0431\u0440\u0430\u0437\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f add-user, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0432 \u0440\u0435\u0434\u0436\u0438\u0441\u0442\u0440\u0438 \u0433\u0438\u0442\u043b\u0430\u0431\u0430     - sed -i -e \"s,&lt;add_user_image>,$CI_REGISTRY_IMAGE:add_user.$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID,g\" kube\/add-user.yml # \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f get-users     - sed -i -e \"s,&lt;get_users_image>,$CI_REGISTRY_IMAGE:get_users.$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID,g\" kube\/get-users.yml # \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438     - kubectl -n $K8S_NAMESPACE apply -f kube\/ # \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u0435\u043f\u043b\u043e\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u0435\u043f\u043b\u043e\u0439 \u043d\u0430\u0437\u0430\u0434, \u043d\u0430 \u043f\u0440\u043e\u0448\u043b\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e     - kubectl -n $K8S_NAMESPACE rollout status deployment\/add-user ||       (kubectl rollout undo deployment\/add-user &amp;&amp; exit 1)     - kubectl -n $K8S_NAMESPACE rollout status deployment\/get-users ||       (kubectl -n $K8S_NAMESPACE rollout undo deployment\/get-users &amp;&amp; exit 1) # \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c horizontal pod autoscaler \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f get-users: # --cpu-percent=50 - \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0446\u043f\u0443 \u043f\u043e\u0434\u043e\u0432, \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438\/\u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e, \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u0434\u044b, \u0432\u043f\u043b\u043e\u0442\u044c \u0434\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432 --max # --min - \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043d\u0438\u0437\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0435 # --max - \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0435     - kubectl autoscale deployment get-users --cpu-percent=50 --min=3 --max=10 <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e IP Ingress Controller, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0441\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"bash\">kubectl get svc -n ingress-nginx <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/od\/c_\/z0\/odc_z0xgwkj9s6xrfhnpjt6a2ie.png\" data-src=\"https:\/\/habrastorage.org\/webt\/od\/c_\/z0\/odc_z0xgwkj9s6xrfhnpjt6a2ie.png\"\/><\/p>\n<p>  \u0421\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 <code>TYPE = LoadBalancer<\/code> \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>EXTERNAL-IP<\/code>. \u041c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043f\u043e DNS-\u0438\u043c\u0435\u043d\u0438 \u0438\u043b\u0438 \u043e\u0442\u0431\u0440\u043e\u0441\u0438\u0442\u044c <code>.nip.io<\/code> \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP.<\/p>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>  <\/p>\n<h3>\u0421\u0435\u0440\u0432\u0438\u0441 get users<\/h3>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:<\/p>\n<pre><code class=\"bash\">curl &lt;\u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP ingress>\/info\/users <\/code><\/pre>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"json\">[{\"id\":1,\"name\":\"Maxim\",\"location\":\"Moscow\",\"age\":21},{\"id\":2,\"name\":\"Dima\",\"location\":\"Moscow\",\"age\":22}] <\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e ID:<\/p>\n<pre><code class=\"python\">curl &lt;\u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP ingress>\/info\/user\/{id} <\/code><\/pre>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"json\">{\"id\":1,\"name\":\"Maxim\",\"location\":\"Moscow\",\"age\":21} <\/code><\/pre>\n<p>  <\/p>\n<h2>\u0421\u0435\u0440\u0432\u0438\u0441 add user<\/h2>\n<p>  <\/p>\n<pre><code class=\"bash\">curl -X POST -H \"Content-Type: application\/json\" -d '{ \u00a0\u00a0\"name\": \"Dima\", \u00a0\u00a0\"location\": \"Moscow\", \u00a0\u00a0\"age\": 22 }' http:\/\/&lt;\u0432\u043d\u0435\u0448\u043d\u0438\u0439_IP_ingress>\/user-storage\/user <\/code><\/pre>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"json\">{\"id\":2,\"message\":\"User created successfully\"} <\/code><\/pre>\n<p>  <\/p>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u043a\u0430\u0442\u043a\u0438 \u043d\u043e\u0432\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439<\/h2>\n<p>  \u041f\u0440\u0438 \u043f\u0443\u0448\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442, \u0432\u0435\u0440\u0441\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u043e\u043c:<\/p>\n<p>  \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 <code>add_user<\/code>:<\/p>\n<pre><code class=\"bash\">curl http:\/\/&lt;\u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP ingress>\/user-storage\/version <\/code><\/pre>\n<p>  \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 <code>get_users<\/code>:<\/p>\n<pre><code class=\"bash\">curl http:\/\/&lt;\u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP ingress>\/info\/version <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0443 \u043c\u0435\u0442\u043e\u0434\u0430 <code>\/info\/hello<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 app\/internal\/middleware\/handlers.go \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>helloMessage<\/code>:<\/p>\n<pre><code class=\"go\">func Hello(w http.ResponseWriter, r *http.Request) { \u00a0\u00a0helloMessage := \"hello message\" \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435  \u00a0\u00a0res := response { \u00a0\u00a0Message: helloMessage, \u00a0\u00a0}  \u00a0\u00a0json.NewEncoder(w).Encode(res) } <\/code><\/pre>\n<p>  <\/p>\n<h2>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/h2>\n<p>  \u0412 \u0434\u0436\u043e\u0431\u0435 \u00abdeploy\u00bb ci\/cd \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0430\u043d\u0435\u0435, \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 hpa \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 <code>get-users<\/code>. \u0410\u0432\u0442\u043e\u0441\u043a\u0435\u0439\u043b\u0438\u043d\u0433 \u043d\u043e\u0434 \u0431\u044b\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 terraform. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e, \u043f\u043e\u0434\u0430\u0432 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0441\u0435\u0440\u0432\u0438\u0441. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0444\u0430\u0439\u043b <a href=\"https:\/\/gitlab.com\/IlyaNyrkov\/vk-cloud-kuber-ci-cd\/-\/blob\/main\/get-users-load-generator.yml?ref_type=heads\">get-users-load-generator.yml<\/a>. \u041f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP Ingress \u0432 \u0444\u0430\u0439\u043b. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u043f\u043b\u0438\u043a \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<pre><code class=\"bash\">kubectl apply -f get-users-load-generator.yml <\/code><\/pre>\n<p>  \u0421\u0442\u0430\u0442\u0443\u0441 HPA \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code class=\"bash\">kubectl get hpa <\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u0440\u0435\u043f\u043b\u0438\u043a \u043f\u043e\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 <code>pending<\/code>, \u043f\u043e\u043a\u0430 Autoscaler \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043d\u043e\u0432\u044b\u0435 \u043d\u043e\u0434\u044b.<\/p>\n<h2>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/h2>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e\u0434\u044b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 HPA, \u0438 \u043d\u043e\u0434\u044b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 Autoscaler, \u0431\u0443\u0434\u0443\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u044b.<\/p>\n<p>  \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0438 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442, \u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 Terraform \u2014 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code class=\"bash\">terraform destroy <\/code><\/pre>\n<p>  \u0412 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445 \u044d\u0442\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Kubernetes. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0441\u0430\u043c\u0438 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435, \u0443\u043b\u043e\u0436\u0438\u0442\u0435\u0441\u044c \u043b\u0438 \u0432 \u0447\u0430\u0441, \u2014 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u043e\u0441\u044c, \u0435\u0441\u043b\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0439, \u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e.<\/p>\n<blockquote><p>\u0412\u044b \u043f\u0440\u044f\u043c\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/mcs.mail.ru\/containers\/\">Kubernetes \u043e\u0442 VK Cloud<\/a>. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u044b \u043d\u0430\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c 3000 \u0431\u043e\u043d\u0443\u0441\u043d\u044b\u0445 \u0440\u0443\u0431\u043b\u0435\u0439 \u0438 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0434\u044b \u0432\u0430\u0448\u0435\u0439 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438.<\/p>\n<p>  Stay tuned.<\/p>\n<p>  \u041f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0439\u0442\u0435\u0441\u044c \u043a \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u043a\u0430\u043d\u0430\u043b\u0443 <a href=\"http:\/\/t.me\/+cWY7eMrhzNVmMmQy\">\u00ab\u0412\u043e\u043a\u0440\u0443\u0433 Kubernetes\u00bb<\/a>, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u0442\u044c \u0432 \u043a\u0443\u0440\u0441\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0435\u0439 \u0438\u0437 \u043c\u0438\u0440\u0430 K8s: \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0434\u0430\u0439\u0434\u0436\u0435\u0441\u0442\u044b, \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0430\u043d\u043e\u043d\u0441\u044b \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0439 \u0438 \u0432\u0435\u0431\u0438\u043d\u0430\u0440\u043e\u0432.<\/p><\/blockquote>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/782310\/\"> https:\/\/habr.com\/ru\/articles\/782310\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><img loading=\"lazy\" decoding=\"async\" height=\"1\" src=\"https:\/\/vk.com\/rtrg?p=VK-RTRG-541074-aOhpd&amp;event=habr_devops\" style=\"display:none;\" width=\"1\"><img loading=\"lazy\" decoding=\"async\" height=\"1\" src=\"https:\/\/vk.com\/rtrg?p=VK-RTRG-541074-aOhpd&amp;event=habr_k8s\" style=\"display:none;\" width=\"1\"><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/aw\/xt\/u6\/awxtu69n9p5bdbzzbftwg6uv5gc.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/aw\/xt\/u6\/awxtu69n9p5bdbzzbftwg6uv5gc.jpeg\" data-blurred=\"true\"\/><\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0418\u043b\u044c\u044f \u041d\u044b\u0440\u043a\u043e\u0432, \u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440 \u0432 <a href=\"https:\/\/mcs.mail.ru\/\">VK Cloud<\/a>. \u0412 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0441\u044c \u0441 \u0436\u0435\u043b\u0430\u043d\u0438\u0435\u043c \u043f\u0430\u0440\u0442\u043d\u0435\u0440\u043e\u0432 (\u044d\u0442\u043e \u0438 \u043a\u0440\u0443\u043f\u043d\u044b\u0439 \u044d\u043d\u0442\u0435\u0440\u043f\u0440\u0430\u0439\u0437, \u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430\u043f\u044b) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Kubernetes, \u043d\u043e \u0438\u0445 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f, \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430, \u0434\u0435\u043f\u043b\u043e\u044f \u0432 \u043d\u0451\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f CI\/CD-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0435\u0433\u043e. \u042f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0441\u0430\u043c\u0438, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0437\u0430 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 CI\/CD \u0441 \u0440\u0430\u0431\u043e\u0447\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-363631","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/363631","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=363631"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/363631\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=363631"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=363631"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=363631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}