ไก่หรือไข่: แยก IaC

ไก่หรือไข่: แยก IaC
อะไรเกิดก่อน - ไก่หรือไข่? ค่อนข้างเป็นการเริ่มต้นที่แปลกสำหรับบทความเกี่ยวกับ Infrastructure-as-Code ใช่ไหม

ไข่คืออะไร?

ส่วนใหญ่แล้ว Infrastructure-as-Code (IaC) เป็นวิธีการแสดงออกถึงโครงสร้างพื้นฐาน ในนั้นเราจะอธิบายสถานะที่เราต้องการบรรลุ โดยเริ่มจากส่วนฮาร์ดแวร์และลงท้ายด้วยการกำหนดค่าซอฟต์แวร์ ดังนั้น IaC จึงใช้สำหรับ:

  1. การจัดหาทรัพยากร เหล่านี้คือ VM, S3, VPC ฯลฯ เครื่องมือพื้นฐานในการทำงาน: terraform и คลาวด์ฟอร์เมชั่น.
  2. การกำหนดค่าซอฟต์แวร์. เครื่องมือพื้นฐาน: เบิ้ล, เชฟ ฯลฯ

รหัสใด ๆ อยู่ในที่เก็บ git และไม่ช้าก็เร็วหัวหน้าทีมจะตัดสินใจว่าจำเป็นต้องจัดลำดับ และเขาจะปรับโครงสร้างใหม่ และมันจะสร้างโครงสร้างบางอย่างขึ้นมา และเขาจะเห็นว่าสิ่งนี้เป็นสิ่งที่ดี

ยังดีที่มีอยู่แล้ว GitLab и GitHub- ผู้ให้บริการสำหรับ Terraform (และนี่คือการกำหนดค่าซอฟต์แวร์) ด้วยความช่วยเหลือของพวกเขา คุณสามารถจัดการโปรเจ็กต์ทั้งหมดได้: สมาชิกในทีม, CI/CD, git-flow ฯลฯ

ไข่มาจากไหน?

ดังนั้นเราจึงค่อยๆ เข้าใกล้คำถามหลัก

ก่อนอื่น คุณต้องเริ่มต้นด้วยพื้นที่เก็บข้อมูลที่อธิบายโครงสร้างของพื้นที่เก็บข้อมูลอื่น รวมถึงตัวคุณเองด้วย และแน่นอนว่า ในฐานะส่วนหนึ่งของ GitOps คุณต้องเพิ่ม CI เพื่อให้การเปลี่ยนแปลงดำเนินการโดยอัตโนมัติ

หากยังไม่ได้สร้าง Git?

  1. จะเก็บมันไว้ใน Git ได้อย่างไร?
  2. จะติดตั้ง CI ได้อย่างไร?
  3. หากเราปรับใช้ Gitlab โดยใช้ IaC และแม้แต่ใน Kubernetes ด้วยล่ะ
  4. และ GitLab Runner ใน Kubernetes ด้วยใช่ไหม
  5. แล้ว Kubernetes ในผู้ให้บริการคลาวด์ล่ะ?

อะไรมาก่อน: GitLab ที่ฉันจะอัปโหลดโค้ดของฉัน หรือโค้ดที่อธิบายว่า GitLab ประเภทใดที่ฉันต้องการ

ไก่กับไข่

«โอยาโกด้ง3 กับไดโนเสาร์" [สิ่งอำนวยความสะดวก]

มาลองทำอาหารโดยใช้เป็นผู้ให้บริการคลาวด์กัน เลือก Kubernetes ที่มีการจัดการ.

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_TOKEN จากแผงควบคุม my.selectel.ru.
  2. สร้างคลัสเตอร์ Kubernetes โดยโอนโทเค็นบัญชีไปที่คลัสเตอร์
  3. รับ KUBECONFIG จากคลัสเตอร์ที่สร้างขึ้น
  4. ติดตั้ง GitLab บน Kubernetes
  5. รับ GitLab-token จาก GitLab ที่สร้างขึ้นสำหรับผู้ใช้ ราก.
  6. สร้างโครงสร้างโครงการใน GitLab โดยใช้ GitLab-token
  7. พุชโค้ดที่มีอยู่ไปที่ GitLab
  8. ?
  9. กำไร!

ขั้นตอนที่ 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 ลงไปด้านบนเพื่อลิ้มรสได้

ฉันชอบที่จะเพิ่ม:

  • เนมสเปซ
  • ชั้นจัดเก็บข้อมูล
  • นโยบายความปลอดภัยของพ็อดและอื่น ๆ

ชั้นเก็บข้อมูล สำหรับ 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. การนำที่เก็บ Git ไปสู่ลำดับชั้นที่ถูกต้องโดยใช้ผู้ให้บริการ Gitlab

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

น่าเสียดายที่ผู้ให้บริการ GitLab ของ Terraform มีการลอยตัว จุดบกพร่อง. จากนั้นคุณจะต้องลบโปรเจ็กต์ที่ขัดแย้งกันด้วยตนเองเพื่อให้ 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 วิธีการทำเช่นนี้อยู่ในส่วนถัดไป

สมัครสมาชิกของเรา บล็อกเพื่อไม่ให้พลาดบทความใหม่!

ที่มา: will.com

เพิ่มความคิดเห็น