鸡肉或鸡蛋:分裂IaC



首先出现的是鸡肉还是鸡蛋?关于基础设施即代码的文章的开头很奇怪,不是吗?



什么是鸡蛋?



通常,基础架构即代码(IaC)是表示基础架构的一种声明方式。在其中,我们从铁件部分开始描述要获得的状态,并以软件配置结束。因此,IaC用于:



  1. 资源提供。这些是VM,S3,VPC等。工作的基本工具:TerraformCloudFormation
  2. 软件配置基本工具: Ansible,Chef等


任何代码都在git仓库中。团队负责人迟早会决定有必要按顺序整理东西。并且它将重构。它将创建一些结构。他会看到这很好。



很好的是已经存在Terraform的GitLabGitHub(这就是软件配置)。在他们的帮助下,您可以管理整个项目:团队成员,CI / CD,git-flow等。



鸡蛋从哪里来?



因此,我们逐渐提出了主要问题。



首先,您需要从一个存储库开始,该存储库描述了包括您自己在内的其他存储库的结构。当然,在GitOps中,您需要添加CI,以便自动执行更改。



如果尚未构建Git?



  1. 如何将其存储在Git中?
  2. 如何搞定CI?
  3. 是否还要使用IaC甚至在Kubernetes中部署Gitlab?
  4. GitLab Runner也可以在Kubernetes上使用吗?
  5. 云提供商中的Kubernetes呢?


首先出现的是:GitLab,我将在哪里上传我的代码,或者描述我需要哪个GitLab的代码?


鸡鸡蛋



Oyakodon 3恐龙»[ src ]



让我们尝试使用Managed Kubernetes Selectel作为云服务提供商来烹饪菜肴



TL; DR



是否可以立即组成一个团队?



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




配料:



  • 来自my.selectel.ru的帐户;
  • 来自帐户的令牌;
  • Kubernetes技能;
  • 掌舵技能;
  • 地形技能;
  • 头盔图GitLab;
  • 头盔图GitLab Runner。


食谱:



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


步骤1可以在“ API密钥”部分中获得令牌



第二步我们准备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




第三步我们得到kubconfig。



要以编程方式下载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


也可以通过面板获取Cubconfig。





第四步在集群被烘焙并且可以访问它之后,我们可以在自己喜欢的顶部添加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-ingress已经有很多安装说明,所以我们不要再赘述了。



$ 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分钟:





收到的外部IP:





步骤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...


豆荚上升:





步骤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 Provider将Git存储库放入正确的层次结构。



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


不幸的是,terraform GitLab provider中存在一个浮动错误然后,您必须手动删除有冲突的项目才能修复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)


完成:











结论



我们已经实现了可以以声明方式管理本地计算机上的所有内容。现在,我想将所有这些任务转移到CI并仅按按钮。为此,我们需要将本地状态(Terraform状态)传递给CI。下一部分将如何进行。



订阅我们的博客,不要错过任何新文章!



All Articles