先有鸡还是先有蛋:分裂 IaC

先有鸡还是先有蛋:分裂 IaC
先有鸡还是先有蛋? 对于一篇关于基础设施即代码的文章来说,这是一个相当奇怪的开始,不是吗?

什么是鸡蛋?

大多数情况下,基础设施即代码 (IaC) 是表示基础设施的声明性方式。 在其中我们描述了我们想要实现的状态,从硬件部分开始到软件配置结束。 因此 IaC 用于:

  1. 资源提供。 这些是 VM、S3、VPC 等。 工作基本工具: Terraform и 云形成.
  2. 软件配置。 基本工具: Ansible、厨师等

任何代码都在 git 存储库中。 团队领导者迟早会决定需要对他们进行整理。 他会重构。 它将创建一些结构。 他会发现这很好。

它已经存在也很好 GitLab и GitHub上-Terraform 的提供者(这是软件配置)。 在他们的帮助下,您可以管理整个项目:团队成员、CI/CD、git-flow 等。

鸡蛋从哪里来?

所以我们正在逐渐接近主要问题。

首先,您需要从一个描述其他存储库(包括您自己)的结构的存储库开始。 当然,作为 GitOps 的一部分,您需要添加 CI 以便自动执行更改。

如果 Git 还没有创建?

  1. 如何将其存储在Git中?
  2. 如何安装CI?
  3. 如果我们也使用 IaC 甚至在 Kubernetes 中部署 Gitlab?
  4. GitLab Runner 也在 Kubernetes 中吗?
  5. 云提供商中的 Kubernetes 怎么样?

首先出现的是:我将上传代码的 GitLab,还是描述我需要哪种类型的 GitLab 的代码?

鸡肉加鸡蛋

«亲子丼3与恐龙”[SRC]

让我们尝试使用云提供商来做菜 托管 Kubernetes Selectel.

TL博士

可以同时加入一个团队吗?

$ export MY_SELECTEL_TOKEN=<token>
$ curl https://gitlab.com/chicken-or-egg/mks/make/-/snippets/2002106/raw | bash

主要成份:

  • my.selectel.ru 的帐户;
  • 账户代币;
  • 库伯内特斯技能;
  • 舵手技能;
  • 地形技能;
  • Helm 图表 GitLab;
  • Helm 图表 GitLab Runner。

方药:

  1. 从面板获取 MY_SELECTEL_TOKEN my.selectel.ru.
  2. 通过向其传输帐户令牌来创建 Kubernetes 集群。
  3. 从创建的集群中获取 KUBECONFIG。
  4. 在 Kubernetes 上安装 GitLab。
  5. 从为用户创建的 GitLab 获取 GitLab 令牌 .
  6. 使用 GitLab-token 在 GitLab 中创建项目结构。
  7. 将现有代码推送到 GitLab。
  8. 利润!

步骤1。 令牌可以在 部分获取 API 密钥.

先有鸡还是先有蛋:分裂 IaC步骤2。 我们准备 Terraform 来“烘焙”2 个节点的集群。 如果您确定有足够的资源来处理所有事情,那么您可以启用自动配额:

provider "selectel" {
 token = var.my_selectel_token
}

variable "my_selectel_token" {}
variable "username" {}
variable "region" {}


resource "selectel_vpc_project_v2" "my-k8s" {
 name = "my-k8s-cluster"
 theme = {
   color = "269926"
 }
 quotas {
   resource_name = "compute_cores"
   resource_quotas {
     region = var.region
     zone = "${var.region}a"
     value = 16
   }
 }
 quotas {
   resource_name = "network_floatingips"
   resource_quotas {
     region = var.region
     value = 1
   }
 }
 quotas {
   resource_name = "load_balancers"
   resource_quotas {
     region = var.region
     value = 1
   }
 }
 quotas {
   resource_name = "compute_ram"
   resource_quotas {
     region = var.region
     zone = "${var.region}a"
     value = 32768
   }
 }
 quotas {
   resource_name = "volume_gigabytes_fast"
   resource_quotas {
     region = var.region
     zone = "${var.region}a"
     # (20 * 2) + 50 + (8 * 3 + 10)
     value = 130
   }
 }
}

resource "selectel_mks_cluster_v1" "k8s-cluster" {
 name         = "k8s-cluster"
 project_id   = selectel_vpc_project_v2.my-k8s.id
 region       = var.region
 kube_version = "1.17.9"
}

resource "selectel_mks_nodegroup_v1" "nodegroup_1" {
 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 = "${var.region}a"
 nodes_count       = 2
 cpus              = 8
 ram_mb            = 16384
 volume_gb         = 15
 volume_type       = "fast.${var.region}a"
 labels            = {
   "project": "my",
 }
}

将用户添加到项目中:

resource "random_password" "my-k8s-user-pass" {
 length = 16
 special = true
 override_special = "_%@"
}

resource "selectel_vpc_user_v2" "my-k8s-user" {
 password = random_password.my-k8s-user-pass.result
 name = var.username
 enabled  = true
}

resource "selectel_vpc_keypair_v2" "my-k8s-user-ssh" {
 public_key = file("~/.ssh/id_rsa.pub")
 user_id    = selectel_vpc_user_v2.my-k8s-user.id
 name = var.username
}

resource "selectel_vpc_role_v2" "my-k8s-role" {
 project_id = selectel_vpc_project_v2.my-k8s.id
 user_id    = selectel_vpc_user_v2.my-k8s-user.id
}

输出数据:

output "project_id" {
 value = selectel_vpc_project_v2.my-k8s.id
}

output "k8s_id" {
 value = selectel_mks_cluster_v1.k8s-cluster.id
}

output "user_name" {
 value = selectel_vpc_user_v2.my-k8s-user.name
}

output "user_pass" {
 value = selectel_vpc_user_v2.my-k8s-user.password
}

让我们启动:

$ env 
TF_VAR_region=ru-3 
TF_VAR_username=diamon 
TF_VAR_my_selectel_token=<token> 
terraform plan -out planfile

$ terraform apply -input=false -auto-approve planfile

先有鸡还是先有蛋:分裂 IaC
步骤3。 我们得到了cubeconfig。

要以编程方式下载 KUBECONFIG,您需要从 OpenStack 获取令牌:

openstack token issue -c id -f value > token

并使用此令牌向 Managed Kubernetes Selectel API 发出请求。 k8s_id 放弃 terraform:

curl -XGET -H "x-auth-token: $(cat token)" "https://ru-3.mks.selcloud.ru/v1/clusters/$(cat k8s_id)/kubeconfig" -o kubeConfig.yaml

Cupconfig 也可以通过面板访问。

先有鸡还是先有蛋:分裂 IaC
步骤4。 当簇被烘烤并且我们可以访问它之后,我们可以在上面添加 yaml 来调味。

我更喜欢添加:

  • 命名空间,
  • 存储类
  • Pod 安全策略等。

存储类 对于 Selectel 可以取自 官方存储库.

由于最初我在区域中选择了一个集群 ru-3a,那么我需要该区域的存储类。

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
 name: fast.ru-3a
 annotations:
   storageclass.kubernetes.io/is-default-class: "true"
provisioner: cinder.csi.openstack.org
parameters:
 type: fast.ru-3a
 availability: ru-3a
allowVolumeExpansion: true

步骤5。 安装负载平衡器。

我们将使用标准的许多 nginx入口。 已经有很多安装说明了,所以我们不再赘述。

$ 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

我们等待它接收外部IP大约3-4分钟:

先有鸡还是先有蛋:分裂 IaC
收到外部IP:

先有鸡还是先有蛋:分裂 IaC
步骤6。 安装 GitLab。

$ helm repo add gitlab https://charts.gitlab.io
$ helm upgrade gitlab gitlab/gitlab -n gitlab  --install -f gitlab/values.yml --set "global.hosts.domain=gitlab.$EXTERNAL_IP.nip.io"

我们再次等待所有豆荚升起。

kubectl get po -n gitlab
NAME                                      	READY   STATUS  	RESTARTS   AGE
gitlab-gitaly-0                           	0/1 	Pending 	0      	0s
gitlab-gitlab-exporter-88f6cc8c4-fl52d    	0/1 	Pending 	0      	0s
gitlab-gitlab-runner-6b6867c5cf-hd9dp     	0/1 	Pending 	0      	0s
gitlab-gitlab-shell-55cb6ccdb-h5g8x       	0/1 	Init:0/2	0      	0s
gitlab-migrations.1-2cg6n                 	0/1 	Pending 	0      	0s
gitlab-minio-6dd7d96ddb-zd9j6             	0/1 	Pending 	0      	0s
gitlab-minio-create-buckets.1-bncdp       	0/1 	Pending 	0      	0s
gitlab-postgresql-0                       	0/2 	Pending 	0      	0s
gitlab-prometheus-server-6cfb57f575-v8k6j 	0/2 	Pending 	0      	0s
gitlab-redis-master-0                     	0/2 	Pending 	0      	0s
gitlab-registry-6bd77b4b8c-pb9v9          	0/1 	Pending 	0      	0s
gitlab-registry-6bd77b4b8c-zgb6r          	0/1 	Init:0/2	0      	0s
gitlab-shared-secrets.1-pc7-5jgq4         	0/1 	Completed   0      	20s
gitlab-sidekiq-all-in-1-v1-54dbcf7f5f-qbq67   0/1 	Pending 	0      	0s
gitlab-task-runner-6fd6857db7-9x567       	0/1 	Pending 	0      	0s
gitlab-webservice-d9d4fcff8-hp8wl         	0/2 	Pending 	0      	0s
Waiting gitlab
./wait_gitlab.sh ../internal/gitlab/gitlab/.pods
waiting for pod...
waiting for pod...
waiting for pod...

豆荚升起:

先有鸡还是先有蛋:分裂 IaC
步骤7。 我们收到 GitLab 令牌。

首先,找出登录密码:

kubectl get secret -n gitlab gitlab-gitlab-initial-root-password -o jsonpath='{.data.password}' | base64 --decode

现在让我们登录并获取令牌:

python3 get_gitlab_token.py root $GITLAB_PASSWORD http://gitlab.gitlab.$EXTERNAL_IP.nip.io

步骤8。 使用 Gitlab 提供程序将 Git 存储库引入正确的层次结构。

cd ../internal/gitlab/hierarchy && terraform apply -input=false -auto-approve planfile

不幸的是,terraform GitLab 提供商有一个浮动的 一个错误。 然后,您必须手动删除冲突的项目才能修复 tf.state。 然后重新运行命令 `$make all`

步骤9。 我们将本地存储库传输到服务器。

$ 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)

表面处理:

先有鸡还是先有蛋:分裂 IaC
先有鸡还是先有蛋:分裂 IaC
先有鸡还是先有蛋:分裂 IaC

结论

我们已经实现了可以从本地机器以声明方式管理一切。 现在我想将所有这些任务转移到 CI,只需按下按钮即可。 为此,我们需要将本地状态(Terraform 状态)转移到 CI。 如何做到这一点将在下一部分中介绍。

订阅我们的 博客以免错过新文发布!

来源: habr.com

添加评论