El huevo o la gallina: dividiendo IaC

El huevo o la gallina: dividiendo IaC
¿Qué fue primero: el huevo o la gallina? Un comienzo bastante extraño para un artículo sobre infraestructura como código, ¿no?

¿Qué es un huevo?

Muy a menudo, la infraestructura como código (IaC) es una forma declarativa de representar la infraestructura. En él describimos el estado que queremos alcanzar, empezando por la parte de hardware y terminando con la configuración del software. Por lo tanto, IaC se utiliza para:

  1. Provisión de recursos. Estas son VM, S3, VPC, etc. Herramientas básicas para el trabajo: Terraform и Formación de nubes.
  2. Configuración del software. Herramientas básicas: Ansible, Cocinero, etc.

Cualquier código está en los repositorios de git. Y, tarde o temprano, el líder del equipo decidirá que es necesario ponerlos en orden. Y él refactorizará. Y creará alguna estructura. Y verá que esto es bueno.

También es bueno que ya exista. GitLab и GitHub-proveedor de Terraform (y esto es Configuración de software). Con su ayuda, puedes gestionar todo el proyecto: miembros del equipo, CI/CD, git-flow, etc.

¿De dónde vino el huevo?

De modo que nos acercamos gradualmente a la cuestión principal.

En primer lugar, debe comenzar con un repositorio que describa la estructura de otros repositorios, incluido el suyo. Y, por supuesto, como parte de GitOps, es necesario agregar CI para que los cambios se ejecuten automáticamente.

¿Si Git aún no se ha creado?

  1. ¿Cómo almacenarlo en Git?
  2. ¿Cómo instalar CI?
  3. ¿Si también implementamos Gitlab usando IaC, e incluso en Kubernetes?
  4. ¿Y GitLab Runner también en Kubernetes?
  5. ¿Qué pasa con Kubernetes en el proveedor de la nube?

¿Qué fue primero: el GitLab donde subiré mi código o el código que describe qué tipo de GitLab necesito?

pollo con huevos

«Oyakodón3 con un dinosaurio" [src]

Intentemos cocinar un plato usando como proveedor de nube. Selectel de Kubernetes administrado.

TL; DR

¿Es posible unirse a un equipo a la vez?

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

Ingredientes:

  • Cuenta de my.selectel.ru;
  • Token de cuenta;
  • Habilidades de Kubernetes;
  • Habilidades de timón;
  • Habilidades de Terraformación;
  • Gráfico de timón GitLab;
  • Gráfico de timón GitLab Runner.

Receta:

  1. Obtener MY_SELECTEL_TOKEN del panel mi.selectel.com.
  2. Cree un clúster de Kubernetes transfiriéndole un token de cuenta.
  3. Obtenga KUBECONFIG del clúster creado.
  4. Instale GitLab en Kubernetes.
  5. Obtenga el token GitLab de GitLab creado para el usuario raíz.
  6. Cree una estructura de proyecto en GitLab usando GitLab-token.
  7. Inserte el código existente en GitLab.
  8. ?
  9. ¡Beneficio!

Paso 1. El token se puede obtener en la sección Claves API.

El huevo o la gallina: dividiendo IaCPaso 2. Preparamos nuestro Terraform para "hornear" un grupo de 2 nodos. Si está seguro de tener suficientes recursos para todo, puede habilitar las cuotas automáticas:

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",
 }
}

Agregue un usuario al proyecto:

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
}

Datos de salida:

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
}

Lanzamos:

$ 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

El huevo o la gallina: dividiendo IaC
Paso 3. Obtenemos el cubeconfig.

Para descargar KUBECONFIG mediante programación, necesita obtener un token de OpenStack:

openstack token issue -c id -f value > token

Y con este token realice una solicitud a la API Managed Kubernetes Selectel. k8s_id cuestiones terraformar:

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

También se puede acceder a Cupconfig a través del panel.

El huevo o la gallina: dividiendo IaC
Paso 4. Una vez que el grupo esté horneado y tengamos acceso a él, podemos agregar yaml encima al gusto.

Prefiero agregar:

  • espacio de nombres,
  • clase de almacenamiento
  • política de seguridad del pod, etc.

Clase de almacenamiento para Selectel se puede tomar de repositorio oficial.

Como inicialmente seleccioné un cluster en la zona ru-3a, entonces necesito la clase de almacenamiento de esta zona.

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

Paso 5. Instale un equilibrador de carga.

Usaremos el estándar para muchos. nginx-ingreso. Ya hay muchas instrucciones para instalarlo, por lo que no nos detendremos en ello.

$ 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

Esperamos a que reciba una IP externa unos 3-4 minutos:

El huevo o la gallina: dividiendo IaC
IP externa recibida:

El huevo o la gallina: dividiendo IaC
Paso 6. Instale 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"

De nuevo esperamos a que suban todas las vainas.

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

Las vainas subieron:

El huevo o la gallina: dividiendo IaC
Paso 7. Recibimos el token GitLab.

Primero, averigüe la contraseña de inicio de sesión:

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

Ahora iniciemos sesión y obtengamos un token:

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

Paso 8. Llevar los repositorios de Git a la jerarquía correcta utilizando el proveedor Gitlab.

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

Desafortunadamente, el proveedor terraform GitLab tiene un flotante error. Luego, tendrás que eliminar los proyectos en conflicto manualmente para que se solucione tf.state. Luego vuelva a ejecutar el comando `$make all`

Paso 9. Transferimos repositorios locales al servidor.

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

Hecho:

El huevo o la gallina: dividiendo IaC
El huevo o la gallina: dividiendo IaC
El huevo o la gallina: dividiendo IaC

Conclusión

Hemos conseguido que podamos gestionar todo de forma declarativa desde nuestra máquina local. Ahora quiero transferir todas estas tareas a CI y simplemente presionar botones. Para hacer esto, necesitamos transferir nuestros estados locales (estado Terraform) a CI. Cómo hacer esto se encuentra en la siguiente parte.

Suscríbase a nuestro Blog¡Para no perderte el lanzamiento de nuevos artículos!

Fuente: habr.com

Añadir un comentario