๋ฌด์์ด ๋จผ์ ์๋๊ฐ? ๋ญ๊ณ ๊ธฐ์ธ๊ฐ, ๋ฌ๊ฑ์ธ๊ฐ? ์ฝ๋ํ ์ธํ๋ผ(Infrastructure-as-Code)์ ๊ดํ ๊ธฐ์ฌ์ ์์์ ๊ฝค ์ด์ํ์ง ์์ต๋๊น?
๊ณ๋์ด๋ ๋ฌด์์ ๋๊น?
๋๋ถ๋ถ์ ๊ฒฝ์ฐ IaC(Infrastructure-as-Code)๋ ์ธํ๋ผ๋ฅผ ํํํ๋ ์ ์ธ์ ๋ฐฉ์์ ๋๋ค. ์ฌ๊ธฐ์๋ ํ๋์จ์ด ๋ถ๋ถ์์ ์์ํ์ฌ ์ํํธ์จ์ด ๊ตฌ์ฑ์ผ๋ก ๋๋๋ ๋ฌ์ฑํ๋ ค๋ ์ํ๊ฐ ์ค๋ช ๋์ด ์์ต๋๋ค. ๋ฐ๋ผ์ IaC๋ ๋ค์ ์ฉ๋๋ก ์ฌ์ฉ๋ฉ๋๋ค.
- ์์ ์ ๊ณต. VM, S3, VPC ๋ฑ์ด ์์ต๋๋ค. ์
๋ฌด์ฉ ๊ธฐ๋ณธ ๋๊ตฌ:
ํ ๋ผ ํผ ะธํด๋ผ์ฐ๋ ํฌ๋ฉ์ด์ . ์ํํธ์จ์ด ๊ตฌ์ฑ . ๊ธฐ๋ณธ ๋๊ตฌ:์ฑ ์๊ฐ์๋ , ์ ฐํ ๋ฑ
๋ชจ๋ ์ฝ๋๋ git ์ ์ฅ์์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์กฐ๋ง๊ฐ ํ ๋ฆฌ๋๋ ์ ๋ฆฌ๊ฐ ํ์ํ๋ค๊ณ ๊ฒฐ์ ํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ ๋ฆฌํฉํ ๋งํ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ์ด๋ค ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ ์ด๊ฒ์ด ์ข์ ๊ฒ์์ ์๊ฒ ๋ ๊ฒ์ ๋๋ค.
์ด๋ฏธ ์กด์ฌํ๋ค๋ ๊ฒ๋ ์ข์๋ฐ
๊ณ๋์ ์ด๋์ ์๋์?
๊ทธ๋์ ์ฐ๋ฆฌ๋ ์ ์ฐจ ์ฃผ์ ์ง๋ฌธ์ ์ ๊ทผํ๊ณ ์์ต๋๋ค.
์ฐ์ , ์์ ์ ํฌํจํ ๋ค๋ฅธ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๊ตฌ์กฐ๋ฅผ ์ค๋ช ํ๋ ๋ฆฌํฌ์งํ ๋ฆฌ๋ถํฐ ์์ํด์ผ ํฉ๋๋ค. ๋ฌผ๋ก GitOps์ ์ผ๋ถ๋ก ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์ผ๋ก ์คํ๋๋๋ก CI๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
Git์ด ์์ง ์์ฑ๋์ง ์์๋ค๋ฉด?
- Git์ ์ด๋ป๊ฒ ์ ์ฅํ๋์?
- CI๋ฅผ ์ด๋ป๊ฒ ์ค์นํ๋์?
- IaC๋ฅผ ์ฌ์ฉํ์ฌ Gitlab์ ๋ฐฐํฌํ๊ณ Kubernetes์์๋ ๋ฐฐํฌํ๋ค๋ฉด?
- GitLab Runner๋ Kubernetes์ ์๋์?
- ํด๋ผ์ฐ๋ ์ ๊ณต์ ์ฒด์ Kubernetes๋ ์ด๋ป์ต๋๊น?
๋ด ์ฝ๋๋ฅผ ์ ๋ก๋ํ GitLab, ์๋๋ฉด ์ด๋ค ์ข ๋ฅ์ GitLab์ด ํ์ํ์ง ์ค๋ช ํ๋ ์ฝ๋ ์ค ๋ฌด์์ด ๋จผ์ ์์ต๋๊น?
๊ณ๋์ ๋ฃ์ ๋ญ๊ณ ๊ธฐ
ยซ์ค์ผ์ฝ๋ 3 ๊ณต๋ฃก๊ณผ ํจ๊ป" [SRC ]
ํด๋ผ์ฐ๋ ๊ณต๊ธ์๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฆฌ๋ฅผ ๋ง๋ค์ด ๋ด
์๋ค
TL; DR
ํ ํ์ ๋์์ ๊ฐ์ ํ ์ ์๋์?
$ export MY_SELECTEL_TOKEN=<token>
$ curl https://gitlab.com/chicken-or-egg/mks/make/-/snippets/2002106/raw | bash
์ฑ๋ถ :
- my.selectel.ru์ ๊ณ์ ;
- ๊ณ์ ํ ํฐ
- ์ฟ ๋ฒ๋คํฐ์ค ๊ธฐ์ ;
- ํฌ๊ตฌ ๊ธฐ์ ;
- ํ ๋ผํฌ๋ฐ ๊ธฐ์ ;
- ํฌ๋ฆ ์ฐจํธ GitLab;
- ํฌ๊ตฌ ์ฐจํธ GitLab Runner.
์กฐ๋ฆฌ๋ฒ :
- ํจ๋์์ MY_SELECTEL_TOKEN ๊ฐ์ ธ์ค๊ธฐ my.selectel.ru.
- ๊ณ์ ํ ํฐ์ ์ ์กํ์ฌ Kubernetes ํด๋ฌ์คํฐ๋ฅผ ์์ฑํฉ๋๋ค.
- ์์ฑ๋ ํด๋ฌ์คํฐ์์ KUBECONFIG๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
- Kubernetes์ GitLab์ ์ค์นํฉ๋๋ค.
- ์ฌ์ฉ์๋ฅผ ์ํด ์์ฑ๋ GitLab์์ GitLab ํ ํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฟ๋ฆฌ.
- GitLab-token์ ์ฌ์ฉํ์ฌ GitLab์์ ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ๋ง๋ญ๋๋ค.
- ๊ธฐ์กด ์ฝ๋๋ฅผ GitLab์ ํธ์ํฉ๋๋ค.
- ?
- ์ด์ต!
1 ๋จ๊ณ. ํ ํฐ์ ์น์
์์ ์ป์ ์ ์์ต๋๋ค.
2 ๋จ๊ณ. 2๊ฐ ๋ ธ๋๋ก ๊ตฌ์ฑ๋ ํด๋ฌ์คํฐ๋ฅผ "๊ตฝ๊ธฐ" ์ํด Terraform์ ์ค๋นํฉ๋๋ค. ๋ชจ๋ ๊ฒ์ ์ถฉ๋ถํ ๋ฆฌ์์ค๊ฐ ์๋ค๊ณ ํ์ ํ๋ ๊ฒฝ์ฐ ์๋ ํ ๋น๋์ ํ์ฑํํ ์ ์์ต๋๋ค.
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
3 ๋จ๊ณ. ์ฐ๋ฆฌ๋ Cubeconfig๋ฅผ ์ป์ต๋๋ค.
ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก KUBECONFIG๋ฅผ ๋ค์ด๋ก๋ํ๋ ค๋ฉด OpenStack์์ ํ ํฐ์ ๊ฐ์ ธ์์ผ ํฉ๋๋ค.
openstack token issue -c id -f value > token
๊ทธ๋ฆฌ๊ณ ์ด ํ ํฐ์ ์ฌ์ฉํ์ฌ Managed Kubernetes Selectel API์ ์์ฒญํฉ๋๋ค. k8s_id ๋ฌธ์ ํ ๋ผ ํฌ๋ฆ:
curl -XGET -H "x-auth-token: $(cat token)" "https://ru-3.mks.selcloud.ru/v1/clusters/$(cat k8s_id)/kubeconfig" -o kubeConfig.yaml
Cupconfig๋ ํจ๋์ ํตํด์๋ ์ก์ธ์คํ ์ ์์ต๋๋ค.
4 ๋จ๊ณ. ํด๋ฌ์คํฐ๊ฐ ๊ตฌ์์ง๊ณ ์ก์ธ์คํ ์ ์๊ฒ ๋๋ฉด ์์ yaml์ ์ถ๊ฐํ์ฌ ๋ง๋ณผ ์ ์์ต๋๋ค.
๋๋ ๋ค์์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ํธํฉ๋๋ค:
- ๋ค์์คํ์ด์ค,
- ์ ์ฅ ํด๋์ค
- ํฌ๋ ๋ณด์ ์ ์ฑ ๋ฑ.
์ฒ์์ ์์ญ์์ ํด๋ฌ์คํฐ๋ฅผ ์ ํํ๊ธฐ ๋๋ฌธ์ ๋ฃจ-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
์ฝ 3~4๋ถ ๋์ ์ธ๋ถ IP๋ฅผ ์์ ํ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค.
์์ ๋ ์ธ๋ถ 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 ๊ณต๊ธ์๋ ๋ถ๋
๋ฒ๊ทธ . ๊ทธ๋ฐ ๋ค์ 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๋ก ์ด์ ํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ค์ ๋ถ๋ถ์ ์์ต๋๋ค.
์ฐ๋ฆฌ์ ๊ตฌ๋
๋ธ๋ก๊ทธ ์๋ก์ด ๊ธฐ์ฌ์ ์ถ์๋ฅผ ๋์น์ง ์๋๋ก!
์ถ์ฒ : habr.com