{"id":308090,"date":"2020-08-06T15:00:31","date_gmt":"2020-08-06T15:00:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=308090"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=308090","title":{"rendered":"\u041a\u0443\u0440\u0438\u0446\u0430 \u0438\u043b\u0438 \u044f\u0439\u0446\u043e: \u0440\u0430\u0441\u043a\u0430\u043b\u044b\u0432\u0430\u0435\u043c IaC"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/selectel\/blog\/514060\/\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/nh\/hh\/qf\/nhhhqf45nqshea1l4iphtppgzgc.png\"><\/div>\n<p>  \u0427\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u044c\u0448\u0435 \u2014 \u043a\u0443\u0440\u0438\u0446\u0430 \u0438\u043b\u0438 \u044f\u0439\u0446\u043e? \u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e Infrastructure-as-Code, \u043d\u0435 \u0442\u0430\u043a \u043b\u0438?<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u044f\u0439\u0446\u043e?<\/h2>\n<p>  \u0427\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e Infrastructure-as-Code (IaC) \u2014 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0412 \u043d\u0435\u043c \u043c\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u0436\u0435\u043b\u0435\u0437\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u041f\u041e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 IaC \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f:<\/p>\n<ol>\n<li><b>Resource Provision.<\/b> \u042d\u0442\u043e VMs, S3, VPC \u0438 \u0442.\u0434. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b: <a href=\"https:\/\/terraform.io\">Terraform<\/a> \u0438 <a href=\"https:\/\/aws.amazon.com\/ru\/cloudformation\/\">CloudFormation<\/a>.<\/li>\n<li><a href=\"https:\/\/ru.wikipedia.org\/wiki\/System_Center_Configuration_Manager\"><b>Software Configuration<\/b><\/a>. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b: <a href=\"https:\/\/www.ansible.com\">Ansible<\/a>, Chef \u0438 \u0442.\u0434.<\/li>\n<\/ol>\n<p>   \u041b\u044e\u0431\u043e\u0439 \u043a\u043e\u0434 \u043b\u0435\u0436\u0438\u0442 \u0432 git-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u0445. \u0418 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u0442\u0438\u043c\u043b\u0438\u0434 \u0440\u0435\u0448\u0438\u0442, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0431\u044b \u043d\u0430\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432 \u043d\u0438\u0445. \u0418 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u043e\u043d. \u0418 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. \u0418 \u0443\u0432\u0438\u0434\u0438\u0442 \u043e\u043d, \u0447\u0442\u043e \u044d\u0442\u043e \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u043e.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u043e, \u0447\u0442\u043e \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 <a href=\"https:\/\/www.terraform.io\/docs\/providers\/gitlab\/index.html\">GitLab<\/a> \u0438 <a href=\"https:\/\/www.terraform.io\/docs\/providers\/github\/index.html\">GitHub<\/a>-\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0434\u043b\u044f Terraform (\u0438 \u044d\u0442\u043e Software Configuration). \u0421 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c: \u0447\u043b\u0435\u043d\u0430\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, CI\/CD, git-flow \u0438 \u0442.\u0434.<\/p>\n<h2>\u041e\u0442\u043a\u0443\u0434\u0430 \u0432\u0437\u044f\u043b\u043e\u0441\u044c \u044f\u0439\u0446\u043e?<\/h2>\n<p>  \u0412\u043e\u0442 \u043c\u044b \u0438 \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u043c \u043a \u0433\u043b\u0430\u0432\u043d\u043e\u043c\u0443 \u0432\u043e\u043f\u0440\u043e\u0441\u0443.<\/p>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u0434\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441\u0435\u0431\u044f. \u0418 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 GitOps \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c CI, \u0447\u0442\u043e\u0431\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c.<\/p>\n<p>  \u0415\u0441\u043b\u0438 Git \u0435\u0449\u0435 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d?<\/p>\n<ol>\n<li>\u041a\u0430\u043a \u0435\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 Git?<\/li>\n<li>\u041a\u0430\u043a \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c CI?<\/li>\n<li>\u0415\u0441\u043b\u0438 Gitlab \u043c\u044b \u0442\u043e\u0436\u0435 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e IaC, \u0434\u0430 \u0435\u0449\u0435 \u0438 \u0432 Kubernetes?<\/li>\n<li>\u0418 GitLab Runner \u0442\u043e\u0436\u0435 \u0432 Kubernetes?<\/li>\n<li>\u0410 Kubernetes \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0435?<\/li>\n<\/ol>\n<p>  <\/p>\n<blockquote><p><b><i>\u0427\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u044c\u0448\u0435: GitLab, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0443 \u0441\u0432\u043e\u0439 \u043a\u043e\u0434, \u0438\u043b\u0438 \u043a\u043e\u0434, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u043e, \u043a\u0430\u043a\u043e\u0439 GitLab \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d?<\/i><\/b><\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u041a\u0443\u0440\u0438\u0446\u0430 \u0441 \u044f\u0439\u0446\u0430\u043c\u0438<\/h2>\n<p>  <\/p>\n<h3>\u00ab<a href=\"https:\/\/en.wikipedia.org\/wiki\/Oyakodon\">\u041e\u044f\u043a\u043e\u0434\u043e\u043d<\/a><sup>3<\/sup> \u0441 \u0434\u0438\u043d\u043e\u0437\u0430\u0432\u0440\u043e\u043c\u00bb [<a href=\"https:\/\/gitlab.com\/chicken-or-egg\/mks\">src<\/a>]<\/h3>\n<p>  \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0431\u043b\u044e\u0434\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 <a href=\"http:\/\/slc.tl\/UgP-9\">Managed Kubernetes Selectel<\/a>.<\/p>\n<h3>TL;DR<\/h3>\n<p>  \u0410 \u043c\u043e\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0440\u0430\u0437\u0443 \u0438 \u0432 \u043e\u0434\u043d\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443?<\/p>\n<pre><code class=\"plaintext\">$ export MY_SELECTEL_TOKEN=&lt;token&gt; $ curl https:\/\/gitlab.com\/chicken-or-egg\/mks\/make\/-\/snippets\/2002106\/raw | bash<\/code><\/pre>\n<h3>\u0418\u043d\u0433\u0440\u0435\u0434\u0438\u0435\u043d\u0442\u044b:<\/h3>\n<p>  <\/p>\n<ul>\n<li>\u0410\u043a\u043a\u0430\u0443\u043d\u0442 \u043e\u0442 my.selectel.ru;<\/li>\n<li>\u0422\u043e\u043a\u0435\u043d \u043e\u0442 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430;<\/li>\n<li>\u041d\u0430\u0432\u044b\u043a\u0438 Kubernetes;<\/li>\n<li>\u041d\u0430\u0432\u044b\u043a\u0438 Helm;<\/li>\n<li>\u041d\u0430\u0432\u044b\u043a\u0438 Terraform;<\/li>\n<li>Helm chart GitLab;<\/li>\n<li>Helm chart GitLab Runner.<\/li>\n<\/ul>\n<p>  <\/p>\n<h3>\u0420\u0435\u0446\u0435\u043f\u0442:<\/h3>\n<p>  <\/p>\n<ol>\n<li>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c MY_SELECTEL_TOKEN \u0438\u0437 \u043f\u0430\u043d\u0435\u043b\u0438 <b>my.selectel.ru<\/b>.<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0432 \u043d\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d \u043e\u0442 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430.<\/li>\n<li>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c KUBECONFIG \u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430.<\/li>\n<li>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c GitLab \u0432 Kubernetes.<\/li>\n<li>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c GitLab-token \u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e GitLab \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f <i>root<\/i>.<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0432 GitLab, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f GitLab-token.<\/li>\n<li>\u0417\u0430\u043f\u0443\u0448\u0438\u0442\u044c \u0438\u043c\u0435\u044e\u0449\u0438\u0439\u0441\u044f \u043a\u043e\u0434 \u0432 GitLab.<\/li>\n<li>???<\/li>\n<li>Profit!<\/li>\n<\/ol>\n<p>  <b>\u0428\u0430\u0433 1<\/b>. \u0422\u043e\u043a\u0435\u043d \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <a href=\"https:\/\/my.selectel.ru\/profile\/apikeys\">\u041a\u043b\u044e\u0447\u0438 API<\/a>.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/zq\/1n\/cj\/zq1ncj8c1xhia5cploe3njuzjmc.png\"><\/div>\n<p><b>\u0428\u0430\u0433 2<\/b>. \u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0430\u0448 Terraform \u0434\u043b\u044f \u00ab\u0437\u0430\u043f\u0435\u043a\u0430\u043d\u0438\u044f\u00bb \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0438\u0437 2 \u043d\u043e\u0434. \u0415\u0441\u043b\u0438 \u0432\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0445\u0432\u0430\u0442\u0438\u0442 \u043d\u0430 \u0432\u0441\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043a\u0432\u043e\u0442\u044b:<\/p>\n<pre><code class=\"plaintext\">provider &quot;selectel&quot; {  token = var.my_selectel_token }  variable &quot;my_selectel_token&quot; {} variable &quot;username&quot; {} variable &quot;region&quot; {}   resource &quot;selectel_vpc_project_v2&quot; &quot;my-k8s&quot; {  name = &quot;my-k8s-cluster&quot;  theme = {    color = &quot;269926&quot;  }  quotas {    resource_name = &quot;compute_cores&quot;    resource_quotas {      region = var.region      zone = &quot;${var.region}a&quot;      value = 16    }  }  quotas {    resource_name = &quot;network_floatingips&quot;    resource_quotas {      region = var.region      value = 1    }  }  quotas {    resource_name = &quot;load_balancers&quot;    resource_quotas {      region = var.region      value = 1    }  }  quotas {    resource_name = &quot;compute_ram&quot;    resource_quotas {      region = var.region      zone = &quot;${var.region}a&quot;      value = 32768    }  }  quotas {    resource_name = &quot;volume_gigabytes_fast&quot;    resource_quotas {      region = var.region      zone = &quot;${var.region}a&quot;      # (20 * 2) + 50 + (8 * 3 + 10)      value = 130    }  } }  resource &quot;selectel_mks_cluster_v1&quot; &quot;k8s-cluster&quot; {  name         = &quot;k8s-cluster&quot;  project_id   = selectel_vpc_project_v2.my-k8s.id  region       = var.region  kube_version = &quot;1.17.9&quot; }  resource &quot;selectel_mks_nodegroup_v1&quot; &quot;nodegroup_1&quot; {  cluster_id        = selectel_mks_cluster_v1.k8s-cluster.id  project_id        = selectel_mks_cluster_v1.k8s-cluster.project_id  region            = selectel_mks_cluster_v1.k8s-cluster.region  availability_zone = &quot;${var.region}a&quot;  nodes_count       = 2  cpus              = 8  ram_mb            = 16384  volume_gb         = 15  volume_type       = &quot;fast.${var.region}a&quot;  labels            = {    &quot;project&quot;: &quot;my&quot;,  } }<\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code class=\"plaintext\">resource &quot;random_password&quot; &quot;my-k8s-user-pass&quot; {  length = 16  special = true  override_special = &quot;_%@&quot; }  resource &quot;selectel_vpc_user_v2&quot; &quot;my-k8s-user&quot; {  password = random_password.my-k8s-user-pass.result  name = var.username  enabled  = true }  resource &quot;selectel_vpc_keypair_v2&quot; &quot;my-k8s-user-ssh&quot; {  public_key = file(&quot;~\/.ssh\/id_rsa.pub&quot;)  user_id    = selectel_vpc_user_v2.my-k8s-user.id  name = var.username }  resource &quot;selectel_vpc_role_v2&quot; &quot;my-k8s-role&quot; {  project_id = selectel_vpc_project_v2.my-k8s.id  user_id    = selectel_vpc_user_v2.my-k8s-user.id }<\/code><\/pre>\n<p>  \u0412\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<pre><code class=\"plaintext\">output &quot;project_id&quot; {  value = selectel_vpc_project_v2.my-k8s.id }  output &quot;k8s_id&quot; {  value = selectel_mks_cluster_v1.k8s-cluster.id }  output &quot;user_name&quot; {  value = selectel_vpc_user_v2.my-k8s-user.name }  output &quot;user_pass&quot; {  value = selectel_vpc_user_v2.my-k8s-user.password }<\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c:<\/p>\n<pre><code class=\"plaintext\">$ env \\ TF_VAR_region=ru-3 \\ TF_VAR_username=diamon \\ TF_VAR_my_selectel_token=&lt;token&gt; \\ terraform plan -out planfile  $ terraform apply -input=false -auto-approve planfile<\/code><\/pre>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/uz\/pi\/sl\/uzpislfilwzuesbbonaez-7he30.png\"><\/div>\n<p>  <b>\u0428\u0430\u0433 3<\/b>. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0443\u0431\u043a\u043e\u043d\u0444\u0438\u0433.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c KUBECONFIG, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u043e\u0442 OpenStack:<\/p>\n<pre><code class=\"plaintext\">openstack token issue -c id -f value &gt; token<\/code><\/pre>\n<p>  \u0418 \u0443\u0436\u0435 \u0441 \u044d\u0442\u0438\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 Managed Kubernetes Selectel API. <i>k8s_id<\/i> \u0432\u044b\u0434\u0430\u0435\u0442 <i>terraform<\/i>:<\/p>\n<pre><code class=\"plaintext\">curl -XGET -H &quot;x-auth-token: $(cat token)&quot; &quot;https:\/\/ru-3.mks.selcloud.ru\/v1\/clusters\/$(cat k8s_id)\/kubeconfig&quot; -o kubeConfig.yaml<\/code><\/pre>\n<p>  \u041a\u0443\u0431\u043a\u043e\u043d\u0444\u0438\u0433 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043f\u0430\u043d\u0435\u043b\u044c.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ig\/5l\/nv\/ig5lnvfzpqrq7i51rci7sl9g6li.png\"><\/div>\n<p>  <b>\u0428\u0430\u0433 4<\/b>. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0437\u0430\u043f\u0435\u043a\u0441\u044f \u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a \u043d\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u0435\u0440\u0445\u0443 yaml \u043f\u043e \u0432\u043a\u0443\u0441\u0443.<\/p>\n<p>  \u042f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c:<\/p>\n<ul>\n<li>namespace,<\/li>\n<li>storage class,<\/li>\n<li>pod security policy \u0438 \u043f\u0440\u043e\u0447\u0435\u0435.<\/li>\n<\/ul>\n<p>  <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/storage-classes\/\">Storage Class<\/a> \u0434\u043b\u044f Selectel \u043c\u043e\u0436\u043d\u043e \u0431\u0440\u0430\u0442\u044c \u0438\u0437 <a href=\"https:\/\/github.com\/selectel\/kubernetes-examples\/blob\/master\/storageclasses\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/a>.<\/p>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0432 \u0437\u043e\u043d\u0435 <b>ru-3a<\/b>, \u0442\u043e \u0438 Storage Class \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0438\u0437 \u044d\u0442\u043e\u0439 \u0437\u043e\u043d\u044b.<\/p>\n<pre><code class=\"plaintext\">kind: StorageClass apiVersion: storage.k8s.io\/v1 metadata:  name: fast.ru-3a  annotations:    storageclass.kubernetes.io\/is-default-class: &quot;true&quot; provisioner: cinder.csi.openstack.org parameters:  type: fast.ru-3a  availability: ru-3a allowVolumeExpansion: true<\/code><\/pre>\n<p>  <b>\u0428\u0430\u0433 5<\/b>. \u0421\u0442\u0430\u0432\u0438\u043c \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<p>  \u0411\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 <b>nginx-ingress<\/b>. \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043f\u043e \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0443\u0436\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043d\u0430 \u044d\u0442\u043e\u043c \u0437\u0430\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<pre><code class=\"plaintext\">$ helm repo add nginx-stable https:\/\/helm.nginx.com\/stable $ helm upgrade nginx-ingress nginx-stable\/nginx-ingress -n ingress --install -f ..\/internal\/K8S-cluster\/ingress\/values.yml<\/code><\/pre>\n<p>  \u0416\u0434\u0435\u043c, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 3-4 \u043c\u0438\u043d\u0443\u0442\u044b:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/of\/y6\/j8\/ofy6j8isd_yooj5q3u9ycibh5va.png\"><\/div>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/jd\/el\/al\/jdelal66c3jmoq-toasohlberjc.png\"><\/div>\n<p>  <b>\u0428\u0430\u0433 6<\/b>. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c GitLab.<\/p>\n<pre><code class=\"plaintext\">$ helm repo add gitlab https:\/\/charts.gitlab.io $ helm upgrade gitlab gitlab\/gitlab -n gitlab  --install -f gitlab\/values.yml --set &quot;global.hosts.domain=gitlab.$EXTERNAL_IP.nip.io&quot;<\/code><\/pre>\n<p>  \u0421\u043d\u043e\u0432\u0430 \u0436\u0434\u0435\u043c, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043f\u043e\u0434\u044b \u043f\u043e\u0434\u043d\u0438\u043c\u0443\u0442\u0441\u044f.<\/p>\n<pre><code class=\"plaintext\">kubectl get po -n gitlab NAME                                      \tREADY   STATUS  \tRESTARTS   AGE gitlab-gitaly-0                           \t0\/1 \tPending \t0      \t0s gitlab-gitlab-exporter-88f6cc8c4-fl52d    \t0\/1 \tPending \t0      \t0s gitlab-gitlab-runner-6b6867c5cf-hd9dp     \t0\/1 \tPending \t0      \t0s gitlab-gitlab-shell-55cb6ccdb-h5g8x       \t0\/1 \tInit:0\/2\t0      \t0s gitlab-migrations.1-2cg6n                 \t0\/1 \tPending \t0      \t0s gitlab-minio-6dd7d96ddb-zd9j6             \t0\/1 \tPending \t0      \t0s gitlab-minio-create-buckets.1-bncdp       \t0\/1 \tPending \t0      \t0s gitlab-postgresql-0                       \t0\/2 \tPending \t0      \t0s gitlab-prometheus-server-6cfb57f575-v8k6j \t0\/2 \tPending \t0      \t0s gitlab-redis-master-0                     \t0\/2 \tPending \t0      \t0s gitlab-registry-6bd77b4b8c-pb9v9          \t0\/1 \tPending \t0      \t0s gitlab-registry-6bd77b4b8c-zgb6r          \t0\/1 \tInit:0\/2\t0      \t0s gitlab-shared-secrets.1-pc7-5jgq4         \t0\/1 \tCompleted   0      \t20s gitlab-sidekiq-all-in-1-v1-54dbcf7f5f-qbq67   0\/1 \tPending \t0      \t0s gitlab-task-runner-6fd6857db7-9x567       \t0\/1 \tPending \t0      \t0s gitlab-webservice-d9d4fcff8-hp8wl         \t0\/2 \tPending \t0      \t0s Waiting gitlab .\/wait_gitlab.sh ..\/internal\/gitlab\/gitlab\/.pods waiting for pod... waiting for pod... waiting for pod...<\/code><\/pre>\n<p>  \u041f\u043e\u0434\u044b \u043f\u043e\u0434\u043d\u044f\u043b\u0438\u0441\u044c:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/dz\/px\/zp\/dzpxzp8nx94lsppsjqwb2hj5rfq.png\"><\/div>\n<p>  <b>\u0428\u0430\u0433 7<\/b>. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c GitLab-token.<\/p>\n<p>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0437\u043d\u0430\u0435\u043c \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430:<\/p>\n<pre><code class=\"plaintext\">kubectl get secret -n gitlab gitlab-gitlab-initial-root-password -o jsonpath='{.data.password}' | base64 --decode<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u043e\u043a\u0435\u043d:<\/p>\n<pre><code class=\"plaintext\">python3 get_gitlab_token.py root $GITLAB_PASSWORD http:\/\/gitlab.gitlab.$EXTERNAL_IP.nip.io<\/code><\/pre>\n<p>  <b>\u0428\u0430\u0433 8<\/b>. \u041f\u0440\u0438\u0432\u043e\u0434\u0438\u043c Git-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Gitlab Provider.<\/p>\n<pre><code class=\"plaintext\">cd ..\/internal\/gitlab\/hierarchy &amp;&amp; terraform apply -input=false -auto-approve planfile<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><i>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0432 terraform GitLab provider \u0435\u0441\u0442\u044c \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0438\u0439 <a href=\"https:\/\/github.com\/terraform-providers\/terraform-provider-gitlab\/issues\/109\">\u0431\u0430\u0433<\/a>. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0440\u0443\u043a\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b tf.state \u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0441\u044f. \u0417\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 `$ make all`<\/i><\/p><\/blockquote>\n<p>  <b>\u0428\u0430\u0433 9<\/b>. \u041f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<pre><code class=\"plaintext\">$ make push  [master (root-commit) b61d977]  Initial commit  3 files changed, 46 insertions(+)  create mode 100644 .gitignore  create mode 100644 values.yml Enumerating objects: 5, done. Counting objects: 100% (5\/5), done. Delta compression using up to 8 threads Compressing objects: 100% (5\/5), done. Writing objects: 100% (5\/5), 770 bytes | 770.00 KiB\/s, done. Total 5 (delta 0), reused 0 (delta 0)<\/code><\/pre>\n<p>  \u0413\u043e\u0442\u043e\u0432\u043e:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xm\/at\/er\/xmaterkztn2fg0wr9kzpqbz-kpu.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/9i\/lp\/9i\/9ilp9ikarahgxdiqx8naad5bpoi.png\"><\/div>\n<p>  <a href=\"https:\/\/asciinema.org\/a\/351942\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/asciinema.org\/a\/351942.svg\"><\/a><\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041c\u044b \u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441 \u043d\u0430\u0448\u0435\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435\u043c. \u0422\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u044d\u0442\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 CI \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043d\u043e\u043f\u043e\u0447\u043a\u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f (Terraform state) \u0432 CI. \u041e \u0442\u043e\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<blockquote><p><b><i>\u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0439\u0442\u0435\u0441\u044c \u043d\u0430 \u043d\u0430\u0448 <a href=\"https:\/\/habr.com\/ru\/company\/selectel\/\">\u0431\u043b\u043e\u0433<\/a>, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u044b \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439!<\/i><\/b><\/p><\/blockquote>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/selectel\/blog\/514060\/\"> https:\/\/habr.com\/ru\/company\/selectel\/blog\/514060\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/selectel\/blog\/514060\/\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/nh\/hh\/qf\/nhhhqf45nqshea1l4iphtppgzgc.png\"><\/div>\n<p>  \u0427\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u044c\u0448\u0435 \u2014 \u043a\u0443\u0440\u0438\u0446\u0430 \u0438\u043b\u0438 \u044f\u0439\u0446\u043e? \u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e Infrastructure-as-Code, \u043d\u0435 \u0442\u0430\u043a \u043b\u0438?  <\/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-308090","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/308090","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=308090"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/308090\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=308090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=308090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=308090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}