
¿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:
- Provisión de recursos. Estas son VM, S3, VPC, etc. Herramientas básicas para el trabajo: и .
- . Herramientas básicas: , 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. и -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?
- ¿Cómo almacenarlo en Git?
- ¿Cómo instalar CI?
- ¿Si también implementamos Gitlab usando IaC, e incluso en Kubernetes?
- ¿Y GitLab Runner también en Kubernetes?
- ¿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
«3 con un dinosaurio" []
Intentemos cocinar un plato usando como proveedor de nube. .
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 | bashIngredientes:
- 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:
- Obtener MY_SELECTEL_TOKEN del panel mi.selectel.com.
- Cree un clúster de Kubernetes transfiriéndole un token de cuenta.
- Obtenga KUBECONFIG del clúster creado.
- Instale GitLab en Kubernetes.
- Obtenga el token GitLab de GitLab creado para el usuario raíz.
- Cree una estructura de proyecto en GitLab usando GitLab-token.
- Inserte el código existente en GitLab.
- ?
- ¡Beneficio!
Paso 1. El token se puede obtener en la sección .
Paso 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 
Paso 3. Obtenemos el cubeconfig.
Para descargar KUBECONFIG mediante programación, necesita obtener un token de OpenStack:
openstack token issue -c id -f value > tokenY 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.yamlTambién se puede acceder a Cupconfig a través del panel.

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.
para Selectel se puede tomar de .
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: truePaso 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.ymlEsperamos a que reciba una IP externa unos 3-4 minutos:

IP externa recibida:

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:

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 --decodeAhora iniciemos sesión y obtengamos un token:
python3 get_gitlab_token.py root $GITLAB_PASSWORD http://gitlab.gitlab.$EXTERNAL_IP.nip.ioPaso 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 planfileDesafortunadamente, el proveedor terraform GitLab tiene un flotante . 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:


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 ¡Para no perderte el lanzamiento de nuevos artículos!
Fuente: habr.com
