Ayam atau telur: membelah IaC



Mana yang lebih dulu - ayam atau telur? Awal yang cukup aneh untuk artikel tentang Infrastructure-as-Code, bukan?



Apa itu telur?



Paling sering, Infrastructure-as-Code (IaC) adalah cara deklaratif untuk merepresentasikan infrastruktur. Di dalamnya, kami menjelaskan keadaan yang ingin kami dapatkan, mulai dari bagian besi, diakhiri dengan konfigurasi perangkat lunak. Oleh karena itu, IaC digunakan untuk:



  1. Penyediaan Sumber Daya. Ini adalah VM, S3, VPC, dll. Alat dasar untuk bekerja: Terraform dan CloudFormation .
  2. Konfigurasi Perangkat Lunak . Alat dasar: Ansible , Chef, dll.


Kode apa pun ada di repositori git. Dan cepat atau lambat pemimpin tim akan memutuskan bahwa akan perlu untuk mengatur semuanya. Dan itu akan menjadi refaktor. Dan akan menciptakan beberapa struktur. Dan dia akan melihat bahwa itu bagus.



Ada baiknya juga bahwa sudah ada penyedia GitLab dan GitHub untuk Terraform (dan itu adalah Konfigurasi Perangkat Lunak). Dengan bantuan mereka, Anda dapat mengelola seluruh proyek: anggota tim, CI / CD, git-flow, dll.



Darimana telur itu berasal?



Jadi kami secara bertahap sampai pada pertanyaan utama.



Pertama-tama, Anda perlu memulai dengan repositori yang mendeskripsikan struktur repositori lain, termasuk Anda sendiri. Dan tentu saja, di dalam GitOps, Anda perlu menambahkan CI agar perubahan dijalankan secara otomatis.



Jika Git belum dibangun?



  1. Bagaimana cara menyimpannya di Git?
  2. Bagaimana cara mengencangkan CI?
  3. Jika kami juga menerapkan Gitlab menggunakan IaC, dan bahkan di Kubernetes?
  4. Dan GitLab Runner juga ada di Kubernetes?
  5. Bagaimana dengan Kubernetes di penyedia cloud?


Mana yang lebih dulu: GitLab, di mana saya akan mengunggah kode saya, atau kode yang menjelaskan jenis GitLab apa yang saya butuhkan?


Ayam dengan telur



" Dinosaurus Oyakodon 3 ยป [ src ]



Mari kita coba memasak hidangan menggunakan Managed Kubernetes Selectel sebagai penyedia cloud .



TL; DR



Mungkinkah segera dan dalam satu tim?



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




Bahan:



  • Akun dari my.selectel.ru;
  • Token dari akun;
  • Keterampilan Kubernetes;
  • Keterampilan helm;
  • Keterampilan Terraform;
  • Bagan helm GitLab;
  • Bagan helm GitLab Runner.


Resep:



  1. Dapatkan MY_SELECTEL_TOKEN dari panel my.selectel.ru .
  2. Buat cluster Kubernetes dengan mentransfer token dari akun ke cluster tersebut.
  3. Dapatkan KUBECONFIG dari cluster yang dibuat.
  4. Instal GitLab di Kubernetes.
  5. Dapatkan GitLab-token dari GitLab yang dibuat untuk pengguna root .
  6. Buat struktur proyek di GitLab menggunakan GitLab-token.
  7. Unggah kode yang ada ke GitLab.
  8. ???
  9. Keuntungan!


LANGKAH 1 . Token dapat diperoleh di bagian Kunci API .



LANGKAH 2 . Kami menyiapkan Terraform kami untuk memanggang sekelompok 2 node. Jika Anda yakin memiliki cukup sumber daya untuk semua, maka Anda dapat mengaktifkan autoquotas:



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


Tambahkan pengguna ke proyek:



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
}


Keluaran:



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
}


Meluncurkan:



$ 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




LANGKAH 3 . Kami mendapatkan Cubconfig.



Untuk mengunduh KUBECONFIG secara terprogram, Anda perlu mendapatkan token dari OpenStack:



openstack token issue -c id -f value > token


Dan dengan token ini, buat permintaan ke Managed Kubernetes Selectel API. k8s_id menghasilkan 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 juga bisa didapatkan melalui panel.





LANGKAH 4 . Setelah cluster dipanggang dan kami memiliki akses ke sana, kami dapat menambahkan yaml di atas sesuai keinginan kami.



Saya lebih suka menambahkan:



  • namespace,
  • kelas penyimpanan,
  • kebijakan keamanan pod dan banyak lagi.


Kelas Penyimpanan untuk Selectel dapat diambil dari repositori resmi .



Karena saya awalnya memilih cluster di zona ru-3a , saya juga memerlukan Kelas Penyimpanan dari zona ini.



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


LANGKAH 5 . Kami memasang penyeimbang beban.



Kami akan menggunakan nginx-ingress standar untuk banyak orang . Sudah ada banyak instruksi untuk menginstalnya, jadi jangan memikirkan ini.



$ 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


Kami menunggu untuk menerima IP eksternal selama sekitar 3-4 menit:





Menerima IP eksternal:





LANGKAH 6 . Instal 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"


Kami sekali lagi menunggu semua buah kakao tumbuh.



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


Pod naik:





LANGKAH 7 . Kami mendapatkan GitLab-token.



Pertama, kami menemukan kata sandi untuk masuk:



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


Sekarang mari masuk dan dapatkan token:



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


LANGKAH 8 . Membawa repositori Git ke hierarki yang benar menggunakan Penyedia Gitlab.



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


Sayangnya, ada bug mengambang di penyedia terraform GitLab . Kemudian Anda harus menghapus proyek yang berkonflik secara manual agar tf.state dapat diperbaiki. Kemudian restart perintah `$ make all`


LANGKAH 9 . Kami mentransfer repositori lokal ke server.



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


Selesai:











Kesimpulan



Kami telah mencapai bahwa kami dapat mengelola semuanya secara deklaratif dari mesin lokal kami. Sekarang saya ingin mentransfer semua tugas ini ke CI dan hanya menekan tombol. Untuk melakukan ini, kita perlu meneruskan status lokal kita (status Terraform) ke CI. Bagaimana melakukan ini di bagian selanjutnya.



Berlangganan ke blog kami untuk tidak melewatkan artikel baru!



All Articles