From f462387ece424029a0f0b3db29dd5d1ccba7dc71 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 16:55:08 +0900 Subject: [PATCH 1/9] =?UTF-8?q?chore:=20dev=EC=9A=A9=20iaC=20=EC=B4=88?= =?UTF-8?q?=EC=95=88=20=EC=9E=91=EC=84=B1=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../environments/dev/artifact-registry.tf | 14 + terraform/environments/dev/backend.tf | 9 + terraform/environments/dev/compute.tf | 44 ++++ terraform/environments/dev/firewall.tf | 67 +++++ terraform/environments/dev/iap.tf | 13 + terraform/environments/dev/load-balancer.tf | 30 +++ terraform/environments/dev/outputs.tf | 90 +++++++ .../environments/dev/private-google-access.tf | 14 + terraform/environments/dev/provider.tf | 7 + terraform/environments/dev/secret-manager.tf | 13 + terraform/environments/dev/storage.tf | 68 +++++ terraform/environments/dev/variables.tf | 249 ++++++++++++++++++ terraform/environments/dev/versions.tf | 13 + terraform/environments/dev/vpc.tf | 45 ++++ 14 files changed, 676 insertions(+) create mode 100644 terraform/environments/dev/artifact-registry.tf create mode 100644 terraform/environments/dev/backend.tf create mode 100644 terraform/environments/dev/compute.tf create mode 100644 terraform/environments/dev/firewall.tf create mode 100644 terraform/environments/dev/iap.tf create mode 100644 terraform/environments/dev/load-balancer.tf create mode 100644 terraform/environments/dev/outputs.tf create mode 100644 terraform/environments/dev/private-google-access.tf create mode 100644 terraform/environments/dev/provider.tf create mode 100644 terraform/environments/dev/secret-manager.tf create mode 100644 terraform/environments/dev/storage.tf create mode 100644 terraform/environments/dev/variables.tf create mode 100644 terraform/environments/dev/versions.tf create mode 100644 terraform/environments/dev/vpc.tf diff --git a/terraform/environments/dev/artifact-registry.tf b/terraform/environments/dev/artifact-registry.tf new file mode 100644 index 0000000..a4e49cc --- /dev/null +++ b/terraform/environments/dev/artifact-registry.tf @@ -0,0 +1,14 @@ +# ======================================== +# Artifact Registry 모듈 +# ======================================== +module "artifact_registry" { + source = "../../modules/artifact-registry" + + project_id = var.project_id + default_location = var.artifact_registry_location + common_tags = var.common_tags + + repositories = var.artifact_registry_repositories + repository_iam_bindings = var.artifact_registry_repository_iam_bindings + repository_iam_members = var.artifact_registry_repository_iam_members +} diff --git a/terraform/environments/dev/backend.tf b/terraform/environments/dev/backend.tf new file mode 100644 index 0000000..9a9d37b --- /dev/null +++ b/terraform/environments/dev/backend.tf @@ -0,0 +1,9 @@ +# ======================================== +# Terraform Backend 설정 +# ======================================== +terraform { + backend "gcs" { + bucket = "pinhouse-dev-state-bucket" + prefix = "terraform/dev/state" + } +} diff --git a/terraform/environments/dev/compute.tf b/terraform/environments/dev/compute.tf new file mode 100644 index 0000000..186219f --- /dev/null +++ b/terraform/environments/dev/compute.tf @@ -0,0 +1,44 @@ +# ======================================== +# 웹 서버 컴퓨트 모듈 +# ======================================== +locals { + web_server_tags = ["web-server", var.environment] +} + +module "web_servers" { + source = "../../modules/compute" + + name_prefix = "${var.environment}-web" + network = module.vpc.vpc_self_link + subnetwork = module.vpc.subnets["web"].self_link + + # 개별 인스턴스 정의 + instances = var.create_web_instances ? tomap({ + web1 = { + name = "${var.environment}-web-01" + zone = "${var.region}-a" + machine_type = var.web_machine_type + enable_external_ip = var.enable_web_external_ip + tags = local.web_server_tags + } + }) : tomap({}) + + # 공통 인스턴스 설정 + machine_type = var.web_machine_type + source_image = var.web_source_image + boot_disk_size_gb = 20 + boot_disk_type = "pd-balanced" + enable_external_ip = var.enable_web_external_ip + tags = local.web_server_tags + + # 태그 + common_tags = merge(var.common_tags, { + Service = "Backend" + }) + + # 서비스 계정 설정 + service_account_email = var.service_account_email + service_account_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] +} diff --git a/terraform/environments/dev/firewall.tf b/terraform/environments/dev/firewall.tf new file mode 100644 index 0000000..c2af42e --- /dev/null +++ b/terraform/environments/dev/firewall.tf @@ -0,0 +1,67 @@ +# ======================================== +# 개발 환경 방화벽 규칙 +# ======================================== +locals { + dev_firewall_rules = merge( + { + allow_http = { + name = "${var.vpc_name}-allow-http" + allow = [ + { + protocol = "tcp" + ports = ["80"] + } + ] + source_ranges = ["0.0.0.0/0"] + target_tags = ["web-server"] + priority = 1000 + } + allow_https = { + name = "${var.vpc_name}-allow-https" + allow = [ + { + protocol = "tcp" + ports = ["443"] + } + ] + source_ranges = ["0.0.0.0/0"] + target_tags = ["web-server"] + priority = 1000 + } + }, + var.enable_iap_ssh ? { + allow_iap_ssh = { + name = "${var.vpc_name}-allow-iap-ssh" + allow = [ + { + protocol = "tcp" + ports = ["22"] + } + ] + source_ranges = var.iap_ssh_source_ranges + target_tags = var.management_target_tags + priority = 1000 + } + } : {}, + { + allow_internal = { + name = "${var.vpc_name}-allow-internal" + allow = [ + { + protocol = "tcp" + ports = ["0-65535"] + }, + { + protocol = "udp" + ports = ["0-65535"] + }, + { + protocol = "icmp" + } + ] + source_ranges = ["10.0.0.0/16"] + priority = 65534 + } + } + ) +} diff --git a/terraform/environments/dev/iap.tf b/terraform/environments/dev/iap.tf new file mode 100644 index 0000000..3e564ff --- /dev/null +++ b/terraform/environments/dev/iap.tf @@ -0,0 +1,13 @@ +# ======================================== +# IAP SSH 접근 모듈 +# ======================================== +module "iap_access" { + source = "../../modules/iap-access" + + project_id = var.project_id + + enable_iap_ssh = var.enable_iap_ssh + iap_ssh_members = var.iap_ssh_members + iap_ssh_admin_members = var.iap_ssh_admin_members + service_account_email = var.service_account_email +} diff --git a/terraform/environments/dev/load-balancer.tf b/terraform/environments/dev/load-balancer.tf new file mode 100644 index 0000000..714f6cb --- /dev/null +++ b/terraform/environments/dev/load-balancer.tf @@ -0,0 +1,30 @@ +# ======================================== +# 로드 밸런서 모듈 +# ======================================== +module "load_balancer" { + source = "../../modules/load-balancer" + + count = var.create_load_balancer ? 1 : 0 + + name_prefix = "${var.environment}-lb" + region = var.region + + # 헬스 체크 설정 + create_health_check = true + health_check_protocol = "TCP" + health_check_port = 80 + health_check_request_path = "/" + health_check_interval = 10 + health_check_timeout = 5 + health_check_healthy_threshold = 2 + health_check_unhealthy_threshold = 2 + + # 백엔드 서비스 설정 + backend_protocol = "TCP" + backend_timeout_sec = 30 + + # 포워딩 규칙 설정 + forwarding_rule_ip_protocol = "TCP" + forwarding_rule_port_range = "80" + network_tier = "PREMIUM" +} diff --git a/terraform/environments/dev/outputs.tf b/terraform/environments/dev/outputs.tf new file mode 100644 index 0000000..00efeff --- /dev/null +++ b/terraform/environments/dev/outputs.tf @@ -0,0 +1,90 @@ +# ======================================== +# VPC 출력값 +# ======================================== +output "vpc_id" { + description = "생성된 VPC 네트워크 ID입니다." + value = module.vpc.vpc_id +} + +output "vpc_name" { + description = "생성된 VPC 네트워크 이름입니다." + value = module.vpc.vpc_name +} + +output "vpc_self_link" { + description = "생성된 VPC 네트워크 self link입니다." + value = module.vpc.vpc_self_link +} + +output "subnets" { + description = "생성된 서브넷 정보입니다." + value = module.vpc.subnets +} + +# ======================================== +# 스토리지 출력값 +# ======================================== +output "storage_buckets" { + description = "생성된 스토리지 버킷 정보입니다." + value = module.storage.buckets +} + +output "bucket_urls" { + description = "생성된 버킷 URL 목록입니다." + value = module.storage.bucket_urls +} + +# ======================================== +# Artifact Registry 출력값 +# ======================================== +output "artifact_registry_repositories" { + description = "생성된 Artifact Registry 저장소 정보입니다." + value = module.artifact_registry.repositories +} + +output "artifact_registry_docker_repository_urls" { + description = "생성된 Docker Artifact Registry 저장소 URL 목록입니다." + value = module.artifact_registry.docker_repository_urls +} + +# ======================================== +# Artifact Registry 네트워크 출력값 +# ======================================== +output "artifact_registry_private_access" { + description = "Artifact Registry용 Private Google Access 구성 정보입니다." + value = { + domain_option = module.artifact_registry_private_access.google_api_domain_option + googleapis_private_zone_name = module.artifact_registry_private_access.googleapis_private_zone_name + pkg_dev_private_zone_name = module.artifact_registry_private_access.pkg_dev_private_zone_name + google_api_route_name = module.artifact_registry_private_access.google_api_route_name + direct_connectivity_route_name = module.artifact_registry_private_access.google_api_direct_connectivity_route_name + } +} + +# ======================================== +# 웹 서버 출력값 +# ======================================== +output "web_instances" { + description = "생성된 웹 인스턴스 정보입니다." + value = module.web_servers.instances +} + +# ======================================== +# 로드 밸런서 출력값 +# ======================================== +output "load_balancer_ip" { + description = "로드 밸런서 IP 주소입니다." + value = var.create_load_balancer ? module.load_balancer[0].forwarding_rule_ip_address : null +} + +# ======================================== +# IAP 접근 출력값 +# ======================================== +output "iap_ssh_configuration" { + description = "IAP SSH 접근 구성 정보입니다." + value = { + enabled = var.enable_iap_ssh + members = module.iap_access.iap_access_members + admin_members = module.iap_access.iap_admin_members + } +} diff --git a/terraform/environments/dev/private-google-access.tf b/terraform/environments/dev/private-google-access.tf new file mode 100644 index 0000000..0787d44 --- /dev/null +++ b/terraform/environments/dev/private-google-access.tf @@ -0,0 +1,14 @@ +# ======================================== +# Artifact Registry Private Google Access 모듈 +# ======================================== +module "artifact_registry_private_access" { + source = "../../modules/private-google-access" + + project_id = var.project_id + network_self_link = module.vpc.vpc_self_link + name_prefix = "${var.environment}-artifact-registry" + google_api_domain_option = var.google_api_domain_option + + # Cloud NAT를 사용하므로 route_tags는 비어있습니다. + route_tags = [] +} diff --git a/terraform/environments/dev/provider.tf b/terraform/environments/dev/provider.tf new file mode 100644 index 0000000..b98e2ca --- /dev/null +++ b/terraform/environments/dev/provider.tf @@ -0,0 +1,7 @@ +# ======================================== +# Google Provider 설정 +# ======================================== +provider "google" { + project = var.project_id + region = var.region +} diff --git a/terraform/environments/dev/secret-manager.tf b/terraform/environments/dev/secret-manager.tf new file mode 100644 index 0000000..fb2c4c9 --- /dev/null +++ b/terraform/environments/dev/secret-manager.tf @@ -0,0 +1,13 @@ +# ======================================== +# Secret Manager 모듈 +# ======================================== +module "secret_manager" { + source = "../../modules/secret-manager" + + project_id = var.project_id + common_tags = var.common_tags + + secret_ids = var.secret_manager_secret_ids + secret_iam_bindings = var.secret_manager_secret_iam_bindings + secret_iam_members = var.secret_manager_secret_iam_members +} diff --git a/terraform/environments/dev/storage.tf b/terraform/environments/dev/storage.tf new file mode 100644 index 0000000..6cdb8f7 --- /dev/null +++ b/terraform/environments/dev/storage.tf @@ -0,0 +1,68 @@ +# ======================================== +# 스토리지 모듈 +# ======================================== +module "storage" { + source = "../../modules/storage" + + project_id = var.project_id + default_location = var.storage_location + + # 태그 + common_tags = merge(var.common_tags, { + Service = "Storage" + }) + + # 버킷 정의 + buckets = var.create_storage_buckets ? tomap({ + static_assets = { + name = "${var.project_id}-${var.environment}-static-assets" + storage_class = "STANDARD" + uniform_bucket_level_access = true + versioning_enabled = false + force_destroy = true # 개발 환경에서는 빠른 정리를 위해 강제 삭제를 허용합니다. + + # 90일이 지난 정적 파일은 자동 삭제합니다. + lifecycle_rules = [ + { + action = { + type = "Delete" + } + condition = { + age = 90 + } + } + ] + + # 정적 자산 조회를 위한 CORS 설정입니다. + cors = [ + { + origin = ["*"] + method = ["GET", "HEAD"] + response_header = ["*"] + max_age_seconds = 3600 + } + ] + } + + backups = { + name = "${var.project_id}-${var.environment}-backups" + storage_class = "NEARLINE" + uniform_bucket_level_access = true + versioning_enabled = true + force_destroy = true + + # 최신 버전 일부를 제외한 오래된 백업은 자동 삭제합니다. + lifecycle_rules = [ + { + action = { + type = "Delete" + } + condition = { + age = 30 + num_newer_versions = 3 + } + } + ] + } + }) : tomap({}) +} diff --git a/terraform/environments/dev/variables.tf b/terraform/environments/dev/variables.tf new file mode 100644 index 0000000..199bdaa --- /dev/null +++ b/terraform/environments/dev/variables.tf @@ -0,0 +1,249 @@ +# ======================================== +# 프로젝트 기본 변수 +# ======================================== +variable "project_id" { + description = "배포 대상 GCP 프로젝트 ID입니다." + type = string + default = "dev-pinhouse" +} + +variable "project" { + description = "현재 프로젝트 이름입니다." + type = string + default = "pinhouse" +} + +variable "region" { + description = "인프라를 배포할 GCP 리전입니다." + type = string + default = "asia-northeast3" +} + +variable "environment" { + description = "현재 Terraform 환경 이름입니다." + type = string + default = "dev" +} + +# ======================================== +# VPC 관련 변수 +# ======================================== +variable "vpc_name" { + description = "생성할 VPC 네트워크 이름입니다." + type = string + default = "dev-vpc" +} + +variable "ssh_source_ranges" { + description = "직접 SSH 접근을 허용할 CIDR 목록입니다. 비워두면 IAP만 허용합니다." + type = list(string) + default = [] +} + +variable "enable_iap_ssh" { + description = "IAP TCP 터널 기반 SSH 접근 허용 여부입니다." + type = bool + default = true +} + +variable "iap_ssh_source_ranges" { + description = "IAP TCP 터널이 인스턴스로 접근할 때 허용할 Google 관리 소스 CIDR 목록입니다." + type = list(string) + default = ["35.235.240.0/20"] +} + +variable "management_target_tags" { + description = "SSH 및 IAP 관리 접근을 허용할 인스턴스 태그 목록입니다." + type = list(string) + default = ["web-server"] +} + +variable "enable_nat" { + description = "Cloud NAT 사용 여부입니다." + type = bool + default = true +} + +# ======================================== +# IAP 관련 변수 +# ======================================== +variable "iap_ssh_members" { + description = "IAP 터널과 일반 OS Login 권한을 부여할 IAM 주체 목록입니다." + type = list(string) + default = [] +} + +variable "iap_ssh_admin_members" { + description = "IAP 터널과 관리자 OS Login 권한을 부여할 IAM 주체 목록입니다." + type = list(string) + default = [] +} + +# ======================================== +# Artifact Registry 관련 변수 +# ======================================== +variable "artifact_registry_location" { + description = "Artifact Registry 저장소 기본 생성 위치입니다." + type = string + default = "asia-northeast3" +} + +variable "artifact_registry_repositories" { + description = "생성할 Artifact Registry 저장소 정의 목록입니다." + type = map(object({ + repository_id = string + format = string + description = optional(string) + location = optional(string) + immutable_tags = optional(bool) + common_tags = optional(map(string)) + })) + default = { + fe = { + repository_id = "pinhouse-dev-fe" + format = "DOCKER" + description = "개발 환경용 프런트엔드 이미지 저장소" + immutable_tags = false + } + be = { + repository_id = "pinhouse-dev-be" + format = "DOCKER" + description = "개발 환경용 백엔드 이미지 저장소" + immutable_tags = false + } + } +} + +variable "artifact_registry_repository_iam_bindings" { + description = "Artifact Registry 저장소 IAM 바인딩 정의 목록입니다." + type = map(object({ + repository_key = string + role = string + members = list(string) + })) + default = {} +} + +variable "artifact_registry_repository_iam_members" { + description = "Artifact Registry 저장소 IAM 멤버 정의 목록입니다." + type = map(object({ + repository_key = string + role = string + member = string + })) + default = {} +} + +# ======================================== +# Secret Manager 관련 변수 +# ======================================== +variable "secret_manager_secret_ids" { + description = "생성할 Secret Manager 비밀 ID 목록입니다." + type = list(string) + default = [] +} + +variable "secret_manager_secret_iam_bindings" { + description = "Secret Manager 비밀 IAM 바인딩 정의 목록입니다." + type = map(object({ + secret_id = string + role = string + members = list(string) + })) + default = {} +} + +variable "secret_manager_secret_iam_members" { + description = "Secret Manager 비밀 IAM 멤버 정의 목록입니다." + type = map(object({ + secret_id = string + role = string + member = string + })) + default = {} +} + +# ======================================== +# Private Google Access 관련 변수 +# ======================================== +variable "google_api_domain_option" { + description = "Artifact Registry와 Google APIs에 사용할 Private Google Access 도메인 옵션입니다." + type = string + default = "private.googleapis.com" + + validation { + condition = contains(["private.googleapis.com", "restricted.googleapis.com"], var.google_api_domain_option) + error_message = "google_api_domain_option은 private.googleapis.com 또는 restricted.googleapis.com 중 하나여야 합니다." + } +} + +# ======================================== +# 스토리지 관련 변수 +# ======================================== +variable "create_storage_buckets" { + description = "스토리지 버킷 생성 여부입니다." + type = bool + default = true +} + +variable "storage_location" { + description = "스토리지 버킷을 생성할 위치입니다." + type = string + default = "ASIA-NORTHEAST3" +} + +# ======================================== +# 컴퓨트 관련 변수 +# ======================================== +variable "create_web_instances" { + description = "웹 인스턴스 생성 여부입니다." + type = bool + default = true +} + +variable "web_machine_type" { + description = "웹 서버에 사용할 머신 타입입니다." + type = string + default = "e2-small" # 개발 환경에 맞춘 소형 인스턴스입니다. +} + +variable "web_source_image" { + description = "웹 서버 부팅 디스크에 사용할 이미지입니다." + type = string + default = "debian-cloud/debian-11" +} + +variable "enable_web_external_ip" { + description = "웹 인스턴스 외부 IP 할당 여부입니다. false면 IAP와 Cloud NAT 기반 운영을 전제로 합니다." + type = bool + default = false +} + +variable "service_account_email" { + description = "인스턴스에 연결할 서비스 계정 이메일입니다." + type = string + default = null +} + +# ======================================== +# 로드 밸런서 관련 변수 +# ======================================== +variable "create_load_balancer" { + description = "로드 밸런서 생성 여부입니다." + type = bool + default = false +} + +# ======================================== +# 공통 태그 변수 +# ======================================== +variable "common_tags" { + description = "공통 태그입니다." + type = map(string) + default = { + Project = "pinhouse" + Environment = "dev" + Version = "v1" + ManagedBy = "terraform" + } +} diff --git a/terraform/environments/dev/versions.tf b/terraform/environments/dev/versions.tf new file mode 100644 index 0000000..49f0907 --- /dev/null +++ b/terraform/environments/dev/versions.tf @@ -0,0 +1,13 @@ +# ======================================== +# Terraform 공통 설정 +# ======================================== +terraform { + required_version = ">= 1.0" + + required_providers { + google = { + source = "hashicorp/google" + version = "~> 5.0" + } + } +} diff --git a/terraform/environments/dev/vpc.tf b/terraform/environments/dev/vpc.tf new file mode 100644 index 0000000..1f4cd82 --- /dev/null +++ b/terraform/environments/dev/vpc.tf @@ -0,0 +1,45 @@ +# ======================================== +# VPC 모듈 +# ======================================== +module "vpc" { + source = "../../modules/vpc" + + vpc_name = var.vpc_name + description = "개발 환경용 VPC 네트워크" + routing_mode = "REGIONAL" + + # 서브넷 정의 + subnets = { + web = { + name = "${var.vpc_name}-web-subnet" + ip_cidr_range = "10.0.1.0/24" + region = var.region + description = "웹 서버용 서브넷" + private_ip_google_access = true + } + app = { + name = "${var.vpc_name}-app-subnet" + ip_cidr_range = "10.0.2.0/24" + region = var.region + description = "애플리케이션 서버용 서브넷" + private_ip_google_access = true + } + db = { + name = "${var.vpc_name}-db-subnet" + ip_cidr_range = "10.0.3.0/24" + region = var.region + description = "데이터베이스용 서브넷" + private_ip_google_access = true + } + } + + # 방화벽 규칙 정의 + firewall_rules = local.dev_firewall_rules + + # Cloud NAT 설정 + enable_nat = var.enable_nat + nat_region = var.region + router_asn = 64514 + nat_log_enable = true + nat_log_filter = "ERRORS_ONLY" +} From 71cb369906e8cd74ffb97ade80648415edff5208 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 17:09:46 +0900 Subject: [PATCH 2/9] =?UTF-8?q?chore:=20prod=EC=99=80=20=EC=9C=A0=EC=82=AC?= =?UTF-8?q?=ED=95=98=EA=B2=8C=20dev=20=EA=B5=AC=EC=B6=95=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/environments/dev/compute.tf | 102 +++++++--- terraform/environments/dev/firewall.tf | 135 +++++++++++-- terraform/environments/dev/load-balancer.tf | 186 ++++++++++++++++-- terraform/environments/dev/outputs.tf | 65 +++++- .../dev/scripts/k8s-master-init.sh | 174 ++++++++++++++++ .../dev/scripts/k8s-worker-init.sh | 130 ++++++++++++ terraform/environments/dev/storage.tf | 103 +++++----- terraform/environments/dev/variables.tf | 118 +++++++++-- 8 files changed, 886 insertions(+), 127 deletions(-) create mode 100755 terraform/environments/dev/scripts/k8s-master-init.sh create mode 100755 terraform/environments/dev/scripts/k8s-worker-init.sh diff --git a/terraform/environments/dev/compute.tf b/terraform/environments/dev/compute.tf index 186219f..7965cfe 100644 --- a/terraform/environments/dev/compute.tf +++ b/terraform/environments/dev/compute.tf @@ -1,39 +1,95 @@ # ======================================== -# 웹 서버 컴퓨트 모듈 +# Kubernetes 마스터 노드 컴퓨트 모듈 # ======================================== -locals { - web_server_tags = ["web-server", var.environment] +module "k8s_master_nodes" { + source = "../../modules/compute" + + name_prefix = "${var.project}-${var.environment}-k8s-master" + network = module.vpc.vpc_self_link + subnetwork = module.vpc.subnets["app"].self_link + + # 관리형 인스턴스 그룹 설정 + create_instance_template = true + create_instance_group = true + + instance_group_zone = "${var.region}-a" + instance_group_target_size = var.k8s_master_instance_group_size + + # 마스터 노드는 단일 인스턴스로 고정 운영합니다. + enable_autoscaling = false + + # 공통 인스턴스 설정 + machine_type = var.k8s_master_machine_type + source_image = var.k8s_node_source_image + boot_disk_size_gb = var.k8s_node_boot_disk_size_gb + boot_disk_type = "pd-balanced" + enable_external_ip = false + startup_script = templatefile("${path.module}/scripts/k8s-master-init.sh", { + k8s_pod_cidr = var.k8s_pod_cidr + k8s_service_cidr = var.k8s_service_cidr + calico_version = var.calico_version + }) + tags = ["k8s-master", var.environment] + + # 태그 + common_tags = merge(var.common_tags, { + Service = "Kubernetes" + Role = "Master" + }) + + # 서비스 계정 설정 + service_account_email = var.service_account_email + service_account_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] } -module "web_servers" { +# ======================================== +# Kubernetes 워커 노드 컴퓨트 모듈 +# ======================================== +module "k8s_worker_nodes" { source = "../../modules/compute" - name_prefix = "${var.environment}-web" + name_prefix = "${var.project}-${var.environment}-k8s-workers" network = module.vpc.vpc_self_link - subnetwork = module.vpc.subnets["web"].self_link - - # 개별 인스턴스 정의 - instances = var.create_web_instances ? tomap({ - web1 = { - name = "${var.environment}-web-01" - zone = "${var.region}-a" - machine_type = var.web_machine_type - enable_external_ip = var.enable_web_external_ip - tags = local.web_server_tags - } - }) : tomap({}) + subnetwork = module.vpc.subnets["app"].self_link + + # 관리형 인스턴스 그룹 설정 + create_instance_template = true + create_instance_group = true + + instance_group_zone = "${var.region}-a" + instance_group_target_size = var.k8s_worker_instance_group_size + + # target_size가 0이면 워커 MIG를 완전히 비워둘 수 있도록 오토스케일러를 비활성화합니다. + enable_autoscaling = var.k8s_worker_instance_group_size > 0 ? var.enable_autoscaling : false + autoscaling_min_replicas = var.autoscaling_min_replicas + autoscaling_max_replicas = var.autoscaling_max_replicas + autoscaling_cpu_target = 0.7 # 공통 인스턴스 설정 - machine_type = var.web_machine_type - source_image = var.web_source_image - boot_disk_size_gb = 20 + machine_type = var.k8s_worker_machine_type + source_image = var.k8s_node_source_image + boot_disk_size_gb = var.k8s_node_boot_disk_size_gb boot_disk_type = "pd-balanced" - enable_external_ip = var.enable_web_external_ip - tags = local.web_server_tags + enable_external_ip = false + startup_script = file("${path.module}/scripts/k8s-worker-init.sh") + named_ports = [ + { + name = "ngf-http" + port = var.nginx_gateway_http_node_port + }, + { + name = "ngf-https" + port = var.nginx_gateway_https_node_port + } + ] + tags = ["k8s-worker", var.environment] # 태그 common_tags = merge(var.common_tags, { - Service = "Backend" + Service = "Kubernetes" + Role = "Worker" }) # 서비스 계정 설정 diff --git a/terraform/environments/dev/firewall.tf b/terraform/environments/dev/firewall.tf index c2af42e..ad0c134 100644 --- a/terraform/environments/dev/firewall.tf +++ b/terraform/environments/dev/firewall.tf @@ -2,34 +2,141 @@ # 개발 환경 방화벽 규칙 # ======================================== locals { + gcp_load_balancer_health_check_source_ranges = [ + "35.191.0.0/16", + "130.211.0.0/22", + ] + dev_firewall_rules = merge( + var.create_load_balancer ? { + # 외부 프록시 NLB와 헬스 체크가 워커 NodePort로 접근할 수 있도록 허용합니다. + allow_nginx_gateway_nodeports = { + name = "${var.vpc_name}-allow-nginx-gateway-nodeports" + allow = [ + { + protocol = "tcp" + ports = [ + tostring(var.nginx_gateway_http_node_port), + tostring(var.nginx_gateway_https_node_port), + ] + } + ] + source_ranges = concat( + local.gcp_load_balancer_health_check_source_ranges, + [var.load_balancer_proxy_only_subnet_cidr] + ) + target_tags = ["k8s-worker"] + priority = 1000 + } + } : {}, { - allow_http = { - name = "${var.vpc_name}-allow-http" + # 마스터와 워커 노드가 Kubernetes API 서버에 접근할 수 있도록 허용합니다. + allow_k8s_api_from_nodes = { + name = "${var.vpc_name}-allow-k8s-api-from-nodes" allow = [ { protocol = "tcp" - ports = ["80"] + ports = ["6443"] } ] - source_ranges = ["0.0.0.0/0"] - target_tags = ["web-server"] - priority = 1000 + source_tags = ["k8s-master", "k8s-worker"] + target_tags = ["k8s-master"] + priority = 1000 + } + + # 마스터 노드 간 etcd와 컨트롤 플레인 포트를 허용합니다. + allow_k8s_control_plane = { + name = "${var.vpc_name}-allow-k8s-control-plane" + allow = [ + { + protocol = "tcp" + ports = ["2379-2380", "10250", "10257", "10259"] + } + ] + source_tags = ["k8s-master"] + target_tags = ["k8s-master"] + priority = 1000 + } + + # 마스터 노드가 워커 노드 kubelet에 접근할 수 있도록 허용합니다. + allow_kubelet_from_control_plane = { + name = "${var.vpc_name}-allow-kubelet-from-control-plane" + allow = [ + { + protocol = "tcp" + ports = ["10250"] + } + ] + source_tags = ["k8s-master"] + target_tags = ["k8s-worker"] + priority = 1000 + } + + # 노드 간 kube-proxy 헬스 및 프록시 포트를 허용합니다. + allow_kube_proxy_from_nodes = { + name = "${var.vpc_name}-allow-kube-proxy-from-nodes" + allow = [ + { + protocol = "tcp" + ports = ["10256"] + } + ] + source_tags = ["k8s-master", "k8s-worker"] + target_tags = ["k8s-worker"] + priority = 1000 } - allow_https = { - name = "${var.vpc_name}-allow-https" + + # Calico BGP 피어링에 필요한 TCP 179 포트를 허용합니다. + allow_calico_bgp = { + name = "${var.vpc_name}-allow-calico-bgp" allow = [ { protocol = "tcp" - ports = ["443"] + ports = ["179"] + } + ] + source_tags = ["k8s-master", "k8s-worker"] + target_tags = ["k8s-master", "k8s-worker"] + priority = 1000 + } + + # Calico VXLAN 터널링 트래픽을 허용합니다. + allow_calico_vxlan = { + name = "${var.vpc_name}-allow-calico-vxlan" + allow = [ + { + protocol = "udp" + ports = ["4789"] + } + ] + source_tags = ["k8s-master", "k8s-worker"] + target_tags = ["k8s-master", "k8s-worker"] + priority = 1000 + } + + # Pod CIDR 대역에서 노드로 들어오는 Calico 워크로드 트래픽을 허용합니다. + allow_calico_pod_cidr = { + name = "${var.vpc_name}-allow-calico-pod-cidr" + allow = [ + { + protocol = "tcp" + ports = ["0-65535"] + }, + { + protocol = "udp" + ports = ["0-65535"] + }, + { + protocol = "icmp" } ] - source_ranges = ["0.0.0.0/0"] - target_tags = ["web-server"] + source_ranges = [var.k8s_pod_cidr] + target_tags = ["k8s-master", "k8s-worker"] priority = 1000 } }, var.enable_iap_ssh ? { + # IAP TCP 터널을 통한 SSH 접근을 허용합니다. allow_iap_ssh = { name = "${var.vpc_name}-allow-iap-ssh" allow = [ @@ -44,6 +151,7 @@ locals { } } : {}, { + # Kubernetes 노드 태그를 가진 인스턴스끼리 내부 통신을 허용합니다. allow_internal = { name = "${var.vpc_name}-allow-internal" allow = [ @@ -59,8 +167,9 @@ locals { protocol = "icmp" } ] - source_ranges = ["10.0.0.0/16"] - priority = 65534 + source_tags = ["k8s-master", "k8s-worker"] + target_tags = ["k8s-master", "k8s-worker"] + priority = 65534 } } ) diff --git a/terraform/environments/dev/load-balancer.tf b/terraform/environments/dev/load-balancer.tf index 714f6cb..1f11677 100644 --- a/terraform/environments/dev/load-balancer.tf +++ b/terraform/environments/dev/load-balancer.tf @@ -1,30 +1,174 @@ # ======================================== -# 로드 밸런서 모듈 +# 외부 프록시 NLB 기본 로컬 값 # ======================================== -module "load_balancer" { - source = "../../modules/load-balancer" +locals { + load_balancer_name_prefix = "${var.project}-${var.environment}-nlb" +} + +# ======================================== +# 외부 프록시 NLB용 proxy-only 서브넷 +# ======================================== +resource "google_compute_subnetwork" "load_balancer_proxy_only" { + count = var.create_load_balancer ? 1 : 0 + + name = "${local.load_balancer_name_prefix}-proxy-only-subnet" + ip_cidr_range = var.load_balancer_proxy_only_subnet_cidr + region = var.region + network = module.vpc.vpc_self_link + description = "개발 환경 외부 프록시 NLB용 proxy-only subnet" + purpose = "REGIONAL_MANAGED_PROXY" + role = "ACTIVE" +} + +# ======================================== +# 외부 프록시 NLB 공인 IP +# ======================================== +resource "google_compute_address" "load_balancer_ip" { + count = var.create_load_balancer ? 1 : 0 + + name = "${local.load_balancer_name_prefix}-ip" + region = var.region + network_tier = "PREMIUM" +} + +# ======================================== +# HTTP NodePort 헬스 체크 +# ======================================== +resource "google_compute_region_health_check" "nginx_gateway_http" { + count = var.create_load_balancer ? 1 : 0 + + name = "${local.load_balancer_name_prefix}-http-health-check" + region = var.region + check_interval_sec = 5 + timeout_sec = 5 + healthy_threshold = 2 + unhealthy_threshold = 3 + + tcp_health_check { + port = var.nginx_gateway_http_node_port + } +} + +# ======================================== +# HTTPS NodePort 헬스 체크 +# ======================================== +resource "google_compute_region_health_check" "nginx_gateway_https" { + count = var.create_load_balancer ? 1 : 0 + + name = "${local.load_balancer_name_prefix}-https-health-check" + region = var.region + check_interval_sec = 5 + timeout_sec = 5 + healthy_threshold = 2 + unhealthy_threshold = 3 + + tcp_health_check { + port = var.nginx_gateway_https_node_port + } +} + +# ======================================== +# HTTP 백엔드 서비스 +# ======================================== +resource "google_compute_region_backend_service" "nginx_gateway_http" { + count = var.create_load_balancer ? 1 : 0 + + name = "${local.load_balancer_name_prefix}-http-backend-service" + region = var.region + protocol = "TCP" + load_balancing_scheme = "EXTERNAL_MANAGED" + port_name = "ngf-http" + timeout_sec = 30 + session_affinity = "CLIENT_IP" + health_checks = [google_compute_region_health_check.nginx_gateway_http[0].id] + + backend { + group = module.k8s_worker_nodes.instance_group_instance_group + balancing_mode = "UTILIZATION" + max_utilization = 0.6 + capacity_scaler = 1.0 + } +} + +# ======================================== +# HTTPS 백엔드 서비스 +# ======================================== +resource "google_compute_region_backend_service" "nginx_gateway_https" { + count = var.create_load_balancer ? 1 : 0 + + name = "${local.load_balancer_name_prefix}-https-backend-service" + region = var.region + protocol = "TCP" + load_balancing_scheme = "EXTERNAL_MANAGED" + port_name = "ngf-https" + timeout_sec = 30 + session_affinity = "CLIENT_IP" + health_checks = [google_compute_region_health_check.nginx_gateway_https[0].id] + + backend { + group = module.k8s_worker_nodes.instance_group_instance_group + balancing_mode = "UTILIZATION" + max_utilization = 0.8 + capacity_scaler = 1.0 + } +} + +# ======================================== +# HTTP 타깃 TCP 프록시 +# ======================================== +resource "google_compute_region_target_tcp_proxy" "nginx_gateway_http" { + count = var.create_load_balancer ? 1 : 0 + name = "${local.load_balancer_name_prefix}-http-proxy" + region = var.region + backend_service = google_compute_region_backend_service.nginx_gateway_http[0].id +} + +# ======================================== +# HTTPS 타깃 TCP 프록시 +# ======================================== +resource "google_compute_region_target_tcp_proxy" "nginx_gateway_https" { count = var.create_load_balancer ? 1 : 0 - name_prefix = "${var.environment}-lb" - region = var.region + name = "${local.load_balancer_name_prefix}-https-proxy" + region = var.region + backend_service = google_compute_region_backend_service.nginx_gateway_https[0].id +} - # 헬스 체크 설정 - create_health_check = true - health_check_protocol = "TCP" - health_check_port = 80 - health_check_request_path = "/" - health_check_interval = 10 - health_check_timeout = 5 - health_check_healthy_threshold = 2 - health_check_unhealthy_threshold = 2 +# ======================================== +# HTTP 포워딩 규칙 +# ======================================== +resource "google_compute_forwarding_rule" "nginx_gateway_http" { + count = var.create_load_balancer ? 1 : 0 + + name = "${local.load_balancer_name_prefix}-http-forwarding-rule" + region = var.region + ip_protocol = "TCP" + load_balancing_scheme = "EXTERNAL_MANAGED" + network = module.vpc.vpc_self_link + port_range = "80" + target = google_compute_region_target_tcp_proxy.nginx_gateway_http[0].id + network_tier = "PREMIUM" + ip_address = google_compute_address.load_balancer_ip[0].address + + depends_on = [google_compute_subnetwork.load_balancer_proxy_only] +} + +# ======================================== +# HTTPS 포워딩 규칙 +# ======================================== +resource "google_compute_forwarding_rule" "nginx_gateway_https" { + count = var.create_load_balancer ? 1 : 0 - # 백엔드 서비스 설정 - backend_protocol = "TCP" - backend_timeout_sec = 30 + name = "${local.load_balancer_name_prefix}-https-forwarding-rule" + region = var.region + ip_protocol = "TCP" + load_balancing_scheme = "EXTERNAL_MANAGED" + network = module.vpc.vpc_self_link + port_range = "443" + target = google_compute_region_target_tcp_proxy.nginx_gateway_https[0].id + network_tier = "PREMIUM" + ip_address = google_compute_address.load_balancer_ip[0].address - # 포워딩 규칙 설정 - forwarding_rule_ip_protocol = "TCP" - forwarding_rule_port_range = "80" - network_tier = "PREMIUM" + depends_on = [google_compute_subnetwork.load_balancer_proxy_only] } diff --git a/terraform/environments/dev/outputs.tf b/terraform/environments/dev/outputs.tf index 00efeff..caae922 100644 --- a/terraform/environments/dev/outputs.tf +++ b/terraform/environments/dev/outputs.tf @@ -47,6 +47,19 @@ output "artifact_registry_docker_repository_urls" { value = module.artifact_registry.docker_repository_urls } +# ======================================== +# Secret Manager 출력값 +# ======================================== +output "secret_manager_secrets" { + description = "생성된 Secret Manager secret 정보입니다." + value = module.secret_manager.secrets +} + +output "secret_manager_secret_ids" { + description = "생성된 Secret Manager secret ID 목록입니다." + value = module.secret_manager.secret_ids +} + # ======================================== # Artifact Registry 네트워크 출력값 # ======================================== @@ -62,11 +75,31 @@ output "artifact_registry_private_access" { } # ======================================== -# 웹 서버 출력값 +# Kubernetes 출력값 # ======================================== -output "web_instances" { - description = "생성된 웹 인스턴스 정보입니다." - value = module.web_servers.instances +output "k8s_master_instances" { + description = "생성된 Kubernetes 마스터 인스턴스 정보입니다." + value = module.k8s_master_nodes.instances +} + +output "k8s_worker_instances" { + description = "생성된 Kubernetes 워커 인스턴스 정보입니다." + value = module.k8s_worker_nodes.instances +} + +output "k8s_master_instance_group_id" { + description = "생성된 Kubernetes 마스터 인스턴스 그룹 ID입니다." + value = module.k8s_master_nodes.instance_group_id +} + +output "k8s_worker_instance_group_id" { + description = "생성된 Kubernetes 워커 인스턴스 그룹 ID입니다." + value = module.k8s_worker_nodes.instance_group_id +} + +output "instance_group_id" { + description = "생성된 Kubernetes 워커 인스턴스 그룹 ID입니다." + value = module.k8s_worker_nodes.instance_group_id } # ======================================== @@ -74,7 +107,20 @@ output "web_instances" { # ======================================== output "load_balancer_ip" { description = "로드 밸런서 IP 주소입니다." - value = var.create_load_balancer ? module.load_balancer[0].forwarding_rule_ip_address : null + value = var.create_load_balancer ? google_compute_address.load_balancer_ip[0].address : null +} + +# ======================================== +# Kubernetes 네트워크 출력값 +# ======================================== +output "k8s_network_configuration" { + description = "Kubernetes 및 Calico 네트워크 구성 정보입니다." + value = { + pod_cidr = var.k8s_pod_cidr + service_cidr = var.k8s_service_cidr + calico_version = var.calico_version + encapsulation = "IPIP" + } } # ======================================== @@ -83,8 +129,11 @@ output "load_balancer_ip" { output "iap_ssh_configuration" { description = "IAP SSH 접근 구성 정보입니다." value = { - enabled = var.enable_iap_ssh - members = module.iap_access.iap_access_members - admin_members = module.iap_access.iap_admin_members + enabled = var.enable_iap_ssh + source_ranges = var.enable_iap_ssh ? var.iap_ssh_source_ranges : [] + target_tags = var.management_target_tags + members = module.iap_access.iap_access_members + admin_members = module.iap_access.iap_admin_members + direct_ssh_ranges = var.ssh_source_ranges } } diff --git a/terraform/environments/dev/scripts/k8s-master-init.sh b/terraform/environments/dev/scripts/k8s-master-init.sh new file mode 100755 index 0000000..f0417e7 --- /dev/null +++ b/terraform/environments/dev/scripts/k8s-master-init.sh @@ -0,0 +1,174 @@ +#!/usr/bin/env bash +set -euxo pipefail + +# ======================================== +# 기본 환경 점검 +# ======================================== +if [ "$(id -u)" -ne 0 ]; then + echo "이 스크립트는 root 권한으로 실행해야 합니다." + exit 1 +fi + +export DEBIAN_FRONTEND=noninteractive + +# ======================================== +# Ubuntu 기본 패키지 업데이트 +# ======================================== +apt-get update -y +apt-get upgrade -y +apt-get install -y apt-transport-https ca-certificates curl gpg containerd + +# ======================================== +# swap 비활성화 +# ======================================== +swapoff -a +sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab + +# ======================================== +# Kubernetes 네트워크용 커널 모듈 및 sysctl 설정 +# ======================================== +mkdir -p /etc/modules-load.d /etc/sysctl.d /etc/apt/keyrings /etc/containerd + +cat <<'EOF' >/etc/modules-load.d/k8s.conf +overlay +br_netfilter +EOF + +modprobe overlay +modprobe br_netfilter + +cat <<'EOF' >/etc/sysctl.d/99-kubernetes-cri.conf +net.bridge.bridge-nf-call-iptables = 1 +net.bridge.bridge-nf-call-ip6tables = 1 +net.ipv4.ip_forward = 1 +EOF + +sysctl --system + +# ======================================== +# containerd 설정 +# ======================================== +containerd config default >/etc/containerd/config.toml +sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml +systemctl daemon-reload +systemctl enable --now containerd + +# ======================================== +# Kubernetes apt 저장소 설정 +# ======================================== +curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg +echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /' >/etc/apt/sources.list.d/kubernetes.list + +# ======================================== +# Kubernetes 패키지 설치 +# ======================================== +apt-get update -y +apt-get install -y kubelet kubeadm kubectl +apt-mark hold kubelet kubeadm kubectl + +# ======================================== +# kubelet Artifact Registry credential provider 설정 +# ======================================== +mkdir -p /etc/kubernetes /opt/image-credential-provider + +cat <<'PROVIDER_EOF' >/opt/image-credential-provider/gcp-artifact-registry-provider +#!/usr/bin/env bash +set -euo pipefail + +# kubelet 요청 본문은 현재 인증 계산에 사용하지 않으므로 읽고 종료합니다. +cat >/dev/null + +token_response="$(curl -fsSL -H 'Metadata-Flavor: Google' \ + http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token)" +access_token="$(printf '%s' "$${token_response}" | sed -n 's/.*"access_token"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" + +if [ -z "$${access_token}" ]; then + echo "메타데이터 서버에서 Artifact Registry access token을 가져오지 못했습니다." >&2 + exit 1 +fi + +cat </etc/kubernetes/credential-provider-config.yaml +apiVersion: kubelet.config.k8s.io/v1 +kind: CredentialProviderConfig +providers: + - name: gcp-artifact-registry-provider + apiVersion: credentialprovider.kubelet.k8s.io/v1 + matchImages: + - "*.pkg.dev" + defaultCacheDuration: "30m" +EOF + +cat <<'EOF' >/etc/default/kubelet +KUBELET_EXTRA_ARGS="--image-credential-provider-config=/etc/kubernetes/credential-provider-config.yaml --image-credential-provider-bin-dir=/opt/image-credential-provider" +EOF + +# ======================================== +# 서비스 활성화 +# ======================================== +systemctl enable --now kubelet + +# ======================================== +# kubeadm 및 Calico 초기 설정 파일 생성 +# ======================================== +cat </root/kubeadm-config.yaml +apiVersion: kubeadm.k8s.io/v1beta4 +kind: ClusterConfiguration +networking: + podSubnet: ${k8s_pod_cidr} + serviceSubnet: ${k8s_service_cidr} +--- +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +cgroupDriver: systemd +EOF + +cat </root/calico-custom-resources.yaml +apiVersion: operator.tigera.io/v1 +kind: Installation +metadata: + name: default +spec: + calicoNetwork: + ipPools: + - blockSize: 26 + cidr: ${k8s_pod_cidr} + encapsulation: IPIP + natOutgoing: Enabled + nodeSelector: all() +EOF + +cat </root/install-calico.sh +#!/usr/bin/env bash +set -euxo pipefail + +kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/${calico_version}/manifests/operator-crds.yaml +kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/${calico_version}/manifests/tigera-operator.yaml +kubectl create -f /root/calico-custom-resources.yaml +EOF + +chmod +x /root/install-calico.sh + +# ======================================== +# 후속 작업 안내 +# ======================================== +echo "마스터 노드 초기 설정이 완료되었습니다." +echo "1. kubeadm init --config /root/kubeadm-config.yaml --upload-certs" +echo "2. mkdir -p \$HOME/.kube && cp /etc/kubernetes/admin.conf \$HOME/.kube/config && chown \$(id -u):\$(id -g) \$HOME/.kube/config" +echo "3. /root/install-calico.sh" diff --git a/terraform/environments/dev/scripts/k8s-worker-init.sh b/terraform/environments/dev/scripts/k8s-worker-init.sh new file mode 100755 index 0000000..372d12e --- /dev/null +++ b/terraform/environments/dev/scripts/k8s-worker-init.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +set -euxo pipefail + +# ======================================== +# 기본 환경 점검 +# ======================================== +if [ "$(id -u)" -ne 0 ]; then + echo "이 스크립트는 root 권한으로 실행해야 합니다." + exit 1 +fi + +export DEBIAN_FRONTEND=noninteractive + +# ======================================== +# Ubuntu 기본 패키지 업데이트 +# ======================================== +apt-get update -y +apt-get upgrade -y +apt-get install -y apt-transport-https ca-certificates curl gpg containerd + +# ======================================== +# swap 비활성화 +# ======================================== +swapoff -a +sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab + +# ======================================== +# Kubernetes 네트워크용 커널 모듈 및 sysctl 설정 +# ======================================== +mkdir -p /etc/modules-load.d /etc/sysctl.d /etc/apt/keyrings /etc/containerd + +cat <<'EOF' >/etc/modules-load.d/k8s.conf +overlay +br_netfilter +EOF + +modprobe overlay +modprobe br_netfilter + +cat <<'EOF' >/etc/sysctl.d/99-kubernetes-cri.conf +net.bridge.bridge-nf-call-iptables = 1 +net.bridge.bridge-nf-call-ip6tables = 1 +net.ipv4.ip_forward = 1 +EOF + +sysctl --system + +# ======================================== +# containerd 설정 +# ======================================== +containerd config default >/etc/containerd/config.toml +sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml +systemctl daemon-reload +systemctl enable --now containerd + +# ======================================== +# Kubernetes apt 저장소 설정 +# ======================================== +curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg +echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /' >/etc/apt/sources.list.d/kubernetes.list + +# ======================================== +# Kubernetes 패키지 설치 +# ======================================== +apt-get update -y +apt-get install -y kubelet kubeadm +apt-mark hold kubelet kubeadm + +# ======================================== +# kubelet Artifact Registry credential provider 설정 +# ======================================== +mkdir -p /etc/kubernetes /opt/image-credential-provider + +cat <<'PROVIDER_EOF' >/opt/image-credential-provider/gcp-artifact-registry-provider +#!/usr/bin/env bash +set -euo pipefail + +# kubelet 요청 본문은 현재 인증 계산에 사용하지 않으므로 읽고 종료합니다. +cat >/dev/null + +token_response="$(curl -fsSL -H 'Metadata-Flavor: Google' \ + http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token)" +access_token="$(printf '%s' "${token_response}" | sed -n 's/.*"access_token"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" + +if [ -z "${access_token}" ]; then + echo "메타데이터 서버에서 Artifact Registry access token을 가져오지 못했습니다." >&2 + exit 1 +fi + +cat </etc/kubernetes/credential-provider-config.yaml +apiVersion: kubelet.config.k8s.io/v1 +kind: CredentialProviderConfig +providers: + - name: gcp-artifact-registry-provider + apiVersion: credentialprovider.kubelet.k8s.io/v1 + matchImages: + - "*.pkg.dev" + defaultCacheDuration: "30m" +EOF + +cat <<'EOF' >/etc/default/kubelet +KUBELET_EXTRA_ARGS="--image-credential-provider-config=/etc/kubernetes/credential-provider-config.yaml --image-credential-provider-bin-dir=/opt/image-credential-provider" +EOF + +# ======================================== +# 서비스 활성화 +# ======================================== +systemctl enable --now kubelet + +# ======================================== +# 후속 작업 안내 +# ======================================== +echo "워커 노드 초기 설정이 완료되었습니다. 이후 kubeadm join 명령을 실행하세요." diff --git a/terraform/environments/dev/storage.tf b/terraform/environments/dev/storage.tf index 6cdb8f7..56890ad 100644 --- a/terraform/environments/dev/storage.tf +++ b/terraform/environments/dev/storage.tf @@ -13,56 +13,63 @@ module "storage" { }) # 버킷 정의 - buckets = var.create_storage_buckets ? tomap({ - static_assets = { - name = "${var.project_id}-${var.environment}-static-assets" - storage_class = "STANDARD" - uniform_bucket_level_access = true - versioning_enabled = false - force_destroy = true # 개발 환경에서는 빠른 정리를 위해 강제 삭제를 허용합니다. + buckets = merge( - # 90일이 지난 정적 파일은 자동 삭제합니다. - lifecycle_rules = [ - { - action = { - type = "Delete" - } - condition = { - age = 90 - } - } - ] - - # 정적 자산 조회를 위한 CORS 설정입니다. - cors = [ - { - origin = ["*"] - method = ["GET", "HEAD"] - response_header = ["*"] - max_age_seconds = 3600 - } - ] - } + # 기본 버킷 추가 + var.create_storage_buckets ? tomap({ + static_assets = { + name = "${var.project}-${var.environment}" + storage_class = "STANDARD" + uniform_bucket_level_access = true + versioning_enabled = true + force_destroy = true # 개발 환경에서는 빠른 정리를 위해 강제 삭제를 허용합니다. + public_access_prevention = "enforced" - backups = { - name = "${var.project_id}-${var.environment}-backups" - storage_class = "NEARLINE" - uniform_bucket_level_access = true - versioning_enabled = true - force_destroy = true - - # 최신 버전 일부를 제외한 오래된 백업은 자동 삭제합니다. - lifecycle_rules = [ - { - action = { - type = "Delete" + # 365일이 지난 정적 파일은 Nearline 클래스로 이동합니다. + lifecycle_rules = [ + { + action = { + type = "SetStorageClass" + storage_class = "NEARLINE" + } + condition = { + age = 365 + } } - condition = { - age = 30 - num_newer_versions = 3 + ] + + # 정적 자산 제공을 위한 CORS 설정입니다. + cors = length(var.allowed_cors_origins) > 0 ? [ + { + origin = var.allowed_cors_origins + method = ["GET", "HEAD"] + response_header = ["Content-Type"] + max_age_seconds = 3600 } - } - ] - } - }) : tomap({}) + ] : [] + } + }) : tomap({}), + + # 모니터링 버킷 추가 + var.create_monitoring_buckets ? tomap({ + loki = { + name = "${var.project}-${var.environment}-${var.monitoring_loki}" + storage_class = "STANDARD" + uniform_bucket_level_access = true + versioning_enabled = true + force_destroy = true # 개발 환경에서는 빠른 정리를 위해 강제 삭제를 허용합니다. + public_access_prevention = "enforced" + cors = [] + } + tempo = { + name = "${var.project}-${var.environment}-${var.monitoring_tempo}" + storage_class = "STANDARD" + uniform_bucket_level_access = true + versioning_enabled = true + force_destroy = true # 개발 환경에서는 빠른 정리를 위해 강제 삭제를 허용합니다. + public_access_prevention = "enforced" + cors = [] + } + }) : tomap({}), + ) } diff --git a/terraform/environments/dev/variables.tf b/terraform/environments/dev/variables.tf index 199bdaa..e44f027 100644 --- a/terraform/environments/dev/variables.tf +++ b/terraform/environments/dev/variables.tf @@ -55,7 +55,7 @@ variable "iap_ssh_source_ranges" { variable "management_target_tags" { description = "SSH 및 IAP 관리 접근을 허용할 인스턴스 태그 목록입니다." type = list(string) - default = ["web-server"] + default = ["k8s-master", "k8s-worker"] } variable "enable_nat" { @@ -186,37 +186,109 @@ variable "create_storage_buckets" { default = true } +variable "create_monitoring_buckets" { + description = "모니터링 버킷 생성 여부입니다." + type = bool + default = false +} + +variable "monitoring_loki" { + description = "Loki에서 사용할 모니터링 라벨입니다." + type = string + default = "loki" +} + +variable "monitoring_tempo" { + description = "Tempo에서 사용할 모니터링 라벨입니다." + type = string + default = "tempo" +} + variable "storage_location" { description = "스토리지 버킷을 생성할 위치입니다." type = string default = "ASIA-NORTHEAST3" } +variable "allowed_cors_origins" { + description = "정적 자산 버킷에서 허용할 CORS Origin 목록입니다." + type = list(string) + default = [] +} + # ======================================== # 컴퓨트 관련 변수 # ======================================== -variable "create_web_instances" { - description = "웹 인스턴스 생성 여부입니다." +variable "k8s_master_instance_group_size" { + description = "Kubernetes 마스터 관리형 인스턴스 그룹의 목표 인스턴스 수입니다." + type = number + default = 1 +} + +variable "k8s_worker_instance_group_size" { + description = "Kubernetes 워커 관리형 인스턴스 그룹의 목표 인스턴스 수입니다." + type = number + default = 1 # 개발 환경에서는 비용 절감을 위해 1개로 설정합니다. +} + +variable "enable_autoscaling" { + description = "오토스케일링 사용 여부입니다." type = bool - default = true + default = false # 개발 환경에서는 비활성화합니다. +} + +variable "autoscaling_min_replicas" { + description = "오토스케일링 최소 인스턴스 수입니다." + type = number + default = 1 +} + +variable "autoscaling_max_replicas" { + description = "오토스케일링 최대 인스턴스 수입니다." + type = number + default = 3 # 개발 환경에서는 3개로 제한합니다. } -variable "web_machine_type" { - description = "웹 서버에 사용할 머신 타입입니다." +variable "k8s_master_machine_type" { + description = "Kubernetes 마스터 노드에 사용할 머신 타입입니다." type = string - default = "e2-small" # 개발 환경에 맞춘 소형 인스턴스입니다. + default = "e2-custom-2-4096" } -variable "web_source_image" { - description = "웹 서버 부팅 디스크에 사용할 이미지입니다." +variable "k8s_worker_machine_type" { + description = "Kubernetes 워커 노드에 사용할 머신 타입입니다." type = string - default = "debian-cloud/debian-11" + default = "e2-custom-2-4096" } -variable "enable_web_external_ip" { - description = "웹 인스턴스 외부 IP 할당 여부입니다. false면 IAP와 Cloud NAT 기반 운영을 전제로 합니다." - type = bool - default = false +variable "k8s_node_boot_disk_size_gb" { + description = "Kubernetes 노드 부팅 디스크 크기(GB)입니다." + type = number + default = 50 +} + +variable "k8s_node_source_image" { + description = "Kubernetes 노드 부팅 디스크에 사용할 이미지입니다." + type = string + default = "ubuntu-os-cloud/ubuntu-2204-lts" +} + +variable "k8s_pod_cidr" { + description = "Kubernetes Pod CIDR 대역입니다. Calico IPPool과 kubeadm podSubnet에 동일하게 사용합니다." + type = string + default = "192.168.0.0/16" +} + +variable "k8s_service_cidr" { + description = "Kubernetes Service CIDR 대역입니다." + type = string + default = "10.96.0.0/12" +} + +variable "calico_version" { + description = "초기 설치에 사용할 Calico 오픈소스 릴리스 버전입니다." + type = string + default = "v3.31.4" } variable "service_account_email" { @@ -234,6 +306,24 @@ variable "create_load_balancer" { default = false } +variable "load_balancer_proxy_only_subnet_cidr" { + description = "외부 프록시 NLB용 proxy-only 서브넷 CIDR 대역입니다." + type = string + default = "10.0.10.0/23" +} + +variable "nginx_gateway_http_node_port" { + description = "NGINX Gateway Fabric HTTP NodePort 포트입니다." + type = number + default = 30080 +} + +variable "nginx_gateway_https_node_port" { + description = "NGINX Gateway Fabric HTTPS NodePort 포트입니다." + type = number + default = 30443 +} + # ======================================== # 공통 태그 변수 # ======================================== From f287f4f6fdc39f5b7891835244fbcb47c66801b5 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 17:56:49 +0900 Subject: [PATCH 3/9] =?UTF-8?q?chore:=20tfvars.example=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../environments/dev/terraform.tfvars.example | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 terraform/environments/dev/terraform.tfvars.example diff --git a/terraform/environments/dev/terraform.tfvars.example b/terraform/environments/dev/terraform.tfvars.example new file mode 100644 index 0000000..d0e6689 --- /dev/null +++ b/terraform/environments/dev/terraform.tfvars.example @@ -0,0 +1,102 @@ +# ======================================== +# 프로젝트 기본 값 +# ======================================== +project_id = "your-prod-gcp-project-id" +project = "pinhouse" + +# ======================================== +# 배포 환경 기본 값 +# ======================================== +region = "asia-northeast3" +environment = "dev" + +# ======================================== +# VPC 관련 값 +# ======================================== +vpc_name = "dev-vpc" + +# 직접 SSH를 열지 않고 IAP만 사용할 경우 빈 배열로 둡니다. +ssh_source_ranges = [] + +enable_iap_ssh = true +iap_ssh_members = ["group:platform@example.com"] +iap_ssh_admin_members = ["group:sre-admin@example.com"] + +enable_nat = true + +# ======================================== +# Artifact Registry 관련 값 +# ======================================== +artifact_registry_location = "asia-northeast3" + +artifact_registry_repositories = { + fe = { + repository_id = "pinhouse-dev-fe" + format = "DOCKER" + description = "프로덕션 환경용 프런트엔드 이미지 저장소" + immutable_tags = false + } + be = { + repository_id = "pinhouse-dev-be" + format = "DOCKER" + description = "프로덕션 환경용 백엔드 이미지 저장소" + immutable_tags = false + } +} + +google_api_domain_option = "private.googleapis.com" + +# ======================================== +# Kubernetes 컴퓨트 관련 값 +# ======================================== +k8s_master_instance_group_size = 1 +k8s_worker_instance_group_size = 2 + +enable_autoscaling = true +autoscaling_min_replicas = 2 +autoscaling_max_replicas = 5 + +k8s_master_machine_type = "e2-custom-2-4096" +k8s_worker_machine_type = "e2-custom-2-4096" +k8s_node_boot_disk_size_gb = 50 +k8s_node_source_image = "ubuntu-os-cloud/ubuntu-2204-lts" +k8s_pod_cidr = "192.168.0.0/16" +k8s_service_cidr = "10.96.0.0/12" +calico_version = "v3.31.4" + +# ======================================== +# 스토리지 관련 값 +# ======================================== +create_storage_buckets = true +create_monitoring_buckets = true +storage_location = "ASIA-NORTHEAST3" + +# CORS 허용 Origin +allowed_cors_origins = [ + "https://www.example.com", + "https://api.example.com", +] + +# ======================================== +# 로드 밸런서 관련 값 +# ======================================== +create_load_balancer = true +load_balancer_proxy_only_subnet_cidr = "10.2.10.0/23" +nginx_gateway_http_node_port = 30080 +nginx_gateway_https_node_port = 30443 + +# ======================================== +# Secret Manager 관련 값 +# ======================================== +secret_manager_secret_ids = [ + "Dev_BE_DB_URL" + ] + +ESO 또는 특정 서비스 계정에 접근 권한을 줄 때만 아래 값을 채웁니다. +secret_manager_secret_iam_members = { + eso = { + secret_id = "Dev_BE_DB_URL" + role = "roles/secretmanager.secretAccessor" + member = "serviceAccount:example-secrets@example-pinhouse.iam.gserviceaccount.com" + } +} \ No newline at end of file From f6fbd6a827313646170de2533c188f9e8dd1019a Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 18:16:00 +0900 Subject: [PATCH 4/9] =?UTF-8?q?chore:=20=EA=B0=9C=EB=B0=9C=EC=9A=A9=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20kustomize=20=EC=A0=95=EC=9D=98=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../overlays/dev/backend/deployment.yaml | 19 +++++++++++++ .../overlays/dev/backend/httproute.yaml | 26 ++++++++++++++++++ .../overlays/dev/backend/kustomization.yaml | 27 +++++++++++++++++++ .../overlays/dev/frontend/deployment.yaml | 19 +++++++++++++ .../overlays/dev/frontend/httproute.yaml | 26 ++++++++++++++++++ .../overlays/dev/frontend/kustomization.yaml | 27 +++++++++++++++++++ k8s-kustomize/overlays/dev/kustomization.yaml | 7 +++++ .../argocd/overlays/dev/httproute.yaml | 27 +++++++++++++++++++ .../argocd/overlays/dev/kustomization.yaml | 9 +++++++ .../dev/notifications-cm-context-patch.yaml | 8 ++++++ .../monitoring/overlays/dev/httproute.yaml | 27 +++++++++++++++++++ .../overlays/dev/kustomization.yaml | 9 +++++++ 12 files changed, 231 insertions(+) create mode 100644 k8s-kustomize/overlays/dev/backend/deployment.yaml create mode 100644 k8s-kustomize/overlays/dev/backend/httproute.yaml create mode 100644 k8s-kustomize/overlays/dev/backend/kustomization.yaml create mode 100644 k8s-kustomize/overlays/dev/frontend/deployment.yaml create mode 100644 k8s-kustomize/overlays/dev/frontend/httproute.yaml create mode 100644 k8s-kustomize/overlays/dev/frontend/kustomization.yaml create mode 100644 k8s-kustomize/overlays/dev/kustomization.yaml create mode 100644 k8s-kustomize/platform/argocd/overlays/dev/httproute.yaml create mode 100644 k8s-kustomize/platform/argocd/overlays/dev/kustomization.yaml create mode 100644 k8s-kustomize/platform/argocd/overlays/dev/notifications-cm-context-patch.yaml create mode 100644 k8s-kustomize/platform/monitoring/overlays/dev/httproute.yaml create mode 100644 k8s-kustomize/platform/monitoring/overlays/dev/kustomization.yaml diff --git a/k8s-kustomize/overlays/dev/backend/deployment.yaml b/k8s-kustomize/overlays/dev/backend/deployment.yaml new file mode 100644 index 0000000..d75dad0 --- /dev/null +++ b/k8s-kustomize/overlays/dev/backend/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment + +# 기본 설정 +metadata: + name: pinhouse-be + +# 스펙 +spec: + replicas: 1 + + template: + metadata: + labels: + environment: dev + + spec: + containers: + - name: pinhouse-be diff --git a/k8s-kustomize/overlays/dev/backend/httproute.yaml b/k8s-kustomize/overlays/dev/backend/httproute.yaml new file mode 100644 index 0000000..8d34bd5 --- /dev/null +++ b/k8s-kustomize/overlays/dev/backend/httproute.yaml @@ -0,0 +1,26 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute + +# 기본 설정 +metadata: + name: backend + +# 스펙 +spec: + parentRefs: + - name: pinhouse-gateway + namespace: nginx-gateway + + # 도메인 명 + hostnames: + - "api.dev.pinhouse.co.kr" + + # 참조 규칙 + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: backend-service-dev + port: 80 diff --git a/k8s-kustomize/overlays/dev/backend/kustomization.yaml b/k8s-kustomize/overlays/dev/backend/kustomization.yaml new file mode 100644 index 0000000..b31c68e --- /dev/null +++ b/k8s-kustomize/overlays/dev/backend/kustomization.yaml @@ -0,0 +1,27 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# 네임 스페이스 +namespace: dev-app + +resources: + - ../../../base/backend + - httproute.yaml + +nameSuffix: -dev + +# 이미지 수정 +# ArgoCD Image Updater가 자동으로 newTag를 업데이트 +images: + - name: REPLACE_ME + newName: asia-northeast3-docker.pkg.dev/dev-pinhouse/pinhouse-dev-be/pinhouse-server + newTag: latest + +# overlays 수정내용 반영 +patches: + - path: deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: pinhouse-be diff --git a/k8s-kustomize/overlays/dev/frontend/deployment.yaml b/k8s-kustomize/overlays/dev/frontend/deployment.yaml new file mode 100644 index 0000000..9aa95b0 --- /dev/null +++ b/k8s-kustomize/overlays/dev/frontend/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment + +# 기본 설정 +metadata: + name: pinhouse-fe + +# 스펙 +spec: + replicas: 2 + + template: + metadata: + labels: + environment: dev + + spec: + containers: + - name: pinhouse-fe diff --git a/k8s-kustomize/overlays/dev/frontend/httproute.yaml b/k8s-kustomize/overlays/dev/frontend/httproute.yaml new file mode 100644 index 0000000..2efbd11 --- /dev/null +++ b/k8s-kustomize/overlays/dev/frontend/httproute.yaml @@ -0,0 +1,26 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute + +# 기본 설정 +metadata: + name: frontend + +# 스펙 +spec: + parentRefs: + - name: pinhouse-gateway + namespace: nginx-gateway + + # 도메인 명 + hostnames: + - "dev.pinhouse.co.kr" + + # 참조 규칙 + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: frontend-service-dev + port: 80 diff --git a/k8s-kustomize/overlays/dev/frontend/kustomization.yaml b/k8s-kustomize/overlays/dev/frontend/kustomization.yaml new file mode 100644 index 0000000..62d6eb8 --- /dev/null +++ b/k8s-kustomize/overlays/dev/frontend/kustomization.yaml @@ -0,0 +1,27 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# 네임 스페이스 +namespace: dev-app + +resources: + - ../../../base/frontend + - httproute.yaml + +nameSuffix: -dev + +# 이미지 수정 +# ArgoCD Image Updater가 자동으로 newTag를 업데이트 +images: + - name: REPLACE_ME + newName: asia-northeast3-docker.pkg.dev/dev-pinhouse/pinhouse-dev-fe/pinhouse-web + newTag: latest + +# overlays 수정내용 반영 +patches: + - path: deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: pinhouse-fe diff --git a/k8s-kustomize/overlays/dev/kustomization.yaml b/k8s-kustomize/overlays/dev/kustomization.yaml new file mode 100644 index 0000000..6b53bca --- /dev/null +++ b/k8s-kustomize/overlays/dev/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# 반영하는 리소스 +resources: + - frontend + - backend diff --git a/k8s-kustomize/platform/argocd/overlays/dev/httproute.yaml b/k8s-kustomize/platform/argocd/overlays/dev/httproute.yaml new file mode 100644 index 0000000..9e6e879 --- /dev/null +++ b/k8s-kustomize/platform/argocd/overlays/dev/httproute.yaml @@ -0,0 +1,27 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute + +# 기본 설정 +metadata: + name: argocd + namespace: argocd + +# 스펙 +spec: + parentRefs: + - name: pinhouse-gateway + namespace: nginx-gateway + + # 도메인 명 + hostnames: + - "argo.dev.pinhouse.co.kr" + + # 참조 규칙 + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: argocd-server + port: 80 diff --git a/k8s-kustomize/platform/argocd/overlays/dev/kustomization.yaml b/k8s-kustomize/platform/argocd/overlays/dev/kustomization.yaml new file mode 100644 index 0000000..5b89931 --- /dev/null +++ b/k8s-kustomize/platform/argocd/overlays/dev/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../../base + - httproute.yaml + +patches: + - path: notifications-cm-context-patch.yaml diff --git a/k8s-kustomize/platform/argocd/overlays/dev/notifications-cm-context-patch.yaml b/k8s-kustomize/platform/argocd/overlays/dev/notifications-cm-context-patch.yaml new file mode 100644 index 0000000..5bc15e4 --- /dev/null +++ b/k8s-kustomize/platform/argocd/overlays/dev/notifications-cm-context-patch.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-notifications-cm + namespace: argocd + +data: + context.argocdUrl: "https://argo.dev.pinhouse.co.kr" diff --git a/k8s-kustomize/platform/monitoring/overlays/dev/httproute.yaml b/k8s-kustomize/platform/monitoring/overlays/dev/httproute.yaml new file mode 100644 index 0000000..bd5fb43 --- /dev/null +++ b/k8s-kustomize/platform/monitoring/overlays/dev/httproute.yaml @@ -0,0 +1,27 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute + +# 기본 설정 +metadata: + name: grafana + namespace: monitoring + +# 스펙 +spec: + parentRefs: + - name: pinhouse-gateway + namespace: nginx-gateway + + # 도메인 명 + hostnames: + - "grafana.dev.pinhouse.co.kr" + + # 참조 규칙 + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: monitoring-core-grafana + port: 80 diff --git a/k8s-kustomize/platform/monitoring/overlays/dev/kustomization.yaml b/k8s-kustomize/platform/monitoring/overlays/dev/kustomization.yaml new file mode 100644 index 0000000..157f4b0 --- /dev/null +++ b/k8s-kustomize/platform/monitoring/overlays/dev/kustomization.yaml @@ -0,0 +1,9 @@ +# ======================================== +# Grafana HTTPRoute (Dev) +# ======================================== + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - httproute.yaml From 7b75df30f83e18932ecce073536ec27c815b7961 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 18:20:54 +0900 Subject: [PATCH 5/9] =?UTF-8?q?chore:=20=EA=B0=9C=EB=B0=9C=EC=9A=A9=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20helm-values=20=EC=A0=95=EC=9D=98=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- k8s-helm/.gitignore | 3 + k8s-helm/platform-chart/values-dev.yaml | 205 ++++++++++++++++++ .../monitoring-alloy/values-dev-gitops.yaml | 21 ++ .../monitoring-core/values-dev-gitops.yaml | 75 +++++++ .../monitoring-loki/values-dev-gitops.yaml | 46 ++++ .../monitoring-tempo/values-dev-gitops.yaml | 100 +++++++++ 6 files changed, 450 insertions(+) create mode 100644 k8s-helm/platform-chart/values-dev.yaml create mode 100644 k8s-helm/releases/monitoring-alloy/values-dev-gitops.yaml create mode 100644 k8s-helm/releases/monitoring-core/values-dev-gitops.yaml create mode 100644 k8s-helm/releases/monitoring-loki/values-dev-gitops.yaml create mode 100644 k8s-helm/releases/monitoring-tempo/values-dev-gitops.yaml diff --git a/k8s-helm/.gitignore b/k8s-helm/.gitignore index 799419b..7a60143 100644 --- a/k8s-helm/.gitignore +++ b/k8s-helm/.gitignore @@ -4,6 +4,7 @@ platform-chart/**/*.yaml platform-chart/**/README.md !platform-chart/**/values.yaml +!platform-chart/**/values-dev.yaml !platform-chart/**/values-nonprod.yaml !platform-chart/**/values-prod.yaml !platform-chart/templates/**/*.yaml @@ -26,6 +27,8 @@ releases/argocd/values-*.yaml releases/monitoring-*/values-*.yaml releases/monitoring-*/README.md !releases/monitoring-*/values-prod-gitops.yaml +!releases/monitoring-*/values-dev-gitops.yaml +!releases/monitoring-*/values-nonprod-gitops.yaml # ======================================== # 로컬 오버라이드 파일 diff --git a/k8s-helm/platform-chart/values-dev.yaml b/k8s-helm/platform-chart/values-dev.yaml new file mode 100644 index 0000000..1d387df --- /dev/null +++ b/k8s-helm/platform-chart/values-dev.yaml @@ -0,0 +1,205 @@ +# Dev values + +# SSL 매니저 +certManager: + enabled: true + + # 실제 이메일 주소로 변경 + acmeEmail: "pinhousekr@gmail.com" + + # 비운영 환경에서는 Let's Encrypt Staging issuer로 검증합니다. + letsencrypt: + staging: + enabled: true + production: + enabled: false + + # DNS-01 Challenge (CloudDNS) + cloudDNS: + projectId: "dev-pinhouse" + +# 게이트웨이 +gateway: + enabled: true + name: pinhouse-gateway + namespace: nginx-gateway + gatewayClassName: nginx + + http: + enabled: true + port: 80 + + # HTTP to HTTPS 리다이렉트 (301 Permanent Redirect) + http_redirect: + enabled: true + + # 환경별 리스너 + environments: + - name: dev + enabled: true + tlsSecretName: pinhouse-tls-dev + services: + - name: web + hostname: dev.pinhouse.co.kr + - name: api + hostname: api.dev.pinhouse.co.kr + + - name: stg + enabled: false + tlsSecretName: pinhouse-tls-stg + services: + - name: web + hostname: stg.pinhouse.co.kr + - name: api + hostname: api.stg.pinhouse.co.kr + + # 추가 리스너 + listeners: + argo: + enabled: true + domain: argo.dev.pinhouse.co.kr + tlsSecretName: pinhouse-tls-argo + + grafana: + enabled: true + domain: grafana.dev.pinhouse.co.kr + tlsSecretName: pinhouse-tls-grafana + +# 접근 제어 (Access Control) - 비운영도 운영과 같은 기준으로 차단 +accessControl: + enabled: true + blockedPaths: + - name: api-dev-swagger + hostnames: ["api.dev.pinhouse.co.kr"] + paths: + - "/swagger-ui" + - "/v3/api-docs" + + - name: api-dev-management + hostnames: ["api.dev.pinhouse.co.kr"] + paths: + - "/actuator" + - "/metrics" + - "/prometheus" + + - name: common-dev-metrics + hostnames: ["dev.pinhouse.co.kr"] + paths: + - "/api/metrics" + - "/prometheus" + +# 네트워크 정책 +networkPolicy: + enabled: false + + database: + rds: + cidr: "192.168.0.0/16" + ec2: + ip: "172.16.10.81/32" + + ports: + frontend: 3000 + backend: 8080 + ai: 8000 + postgres: 5432 + redis: 6379 + rabbitmq: 5672 + dns: 53 + http: 80 + https: 443 + + namespaces: + - name: nginx-gateway + enabled: true + - name: app + enabled: true + +# 인증서 +certificates: + enabled: true + issuer: letsencrypt-staging + + certs: + - name: pinhouse-tls-dev + namespace: nginx-gateway + dnsNames: + - dev.pinhouse.co.kr + - api.dev.pinhouse.co.kr + enabled: true + + - name: pinhouse-tls-stg + namespace: nginx-gateway + dnsNames: + - stg.pinhouse.co.kr + - api.stg.pinhouse.co.kr + enabled: false + + - name: pinhouse-tls-argo + namespace: nginx-gateway + dnsNames: + - argo.dev.pinhouse.co.kr + enabled: true + + - name: pinhouse-tls-grafana + namespace: nginx-gateway + dnsNames: + - grafana.dev.pinhouse.co.kr + enabled: true + +# GCP Secret Manager 기반 시크릿 적용 +externalSecrets: + enabled: true + + secretStores: + - kind: ClusterSecretStore + name: gcp-secret-manager + spec: + provider: + gcpsm: + projectID: dev-pinhouse + + secrets: + - name: backend-secret-kv + namespace: dev-app + spec: + refreshInterval: 1h + secretStoreRef: + name: gcp-secret-manager + kind: ClusterSecretStore + target: + name: backend-secret-kv + creationPolicy: Owner + deletionPolicy: Retain + dataFrom: + - find: + name: + regexp: "^Dev_BE_" + conversionStrategy: Default + decodingStrategy: None + rewrite: + - regexp: + source: "^Dev_BE_(.*)$" + target: "$1" + + - name: monitoring-secret-kv + namespace: monitoring + spec: + refreshInterval: 1h + secretStoreRef: + name: gcp-secret-manager + kind: ClusterSecretStore + target: + name: monitoring-secret-kv + creationPolicy: Owner + deletionPolicy: Retain + dataFrom: + - find: + name: + regexp: "^Dev_MONITORING_" + conversionStrategy: Default + decodingStrategy: None + rewrite: + - regexp: + source: "^Dev_MONITORING_(.*)$" + target: "$1" diff --git a/k8s-helm/releases/monitoring-alloy/values-dev-gitops.yaml b/k8s-helm/releases/monitoring-alloy/values-dev-gitops.yaml new file mode 100644 index 0000000..d74fb61 --- /dev/null +++ b/k8s-helm/releases/monitoring-alloy/values-dev-gitops.yaml @@ -0,0 +1,21 @@ +# ======================================== +# Dev Monitoring Alloy GitOps 값 +# ======================================== + +# 애플리케이션 OTLP 엔드포인트 예시 +# gRPC: monitoring-alloy.monitoring.svc.cluster.local:4317 +# HTTP: http://monitoring-alloy.monitoring.svc.cluster.local:4318/v1/traces + +global: + # Alloy가 Loki로 보내는 로그 라벨과 공통 식별값에 사용합니다. + clusterName: "pinhouse-dev" + environment: "dev" + +alloy: + resources: + requests: + cpu: 300m + memory: 512Mi + limits: + cpu: 1000m + memory: 1Gi diff --git a/k8s-helm/releases/monitoring-core/values-dev-gitops.yaml b/k8s-helm/releases/monitoring-core/values-dev-gitops.yaml new file mode 100644 index 0000000..1eb8187 --- /dev/null +++ b/k8s-helm/releases/monitoring-core/values-dev-gitops.yaml @@ -0,0 +1,75 @@ +# ======================================== +# Dev Monitoring Core GitOps 값 +# ======================================== + +kube-prometheus-stack: + grafana: + # Grafana 관리자 계정은 ExternalSecret이 만든 Kubernetes Secret을 사용합니다. + admin: + existingSecret: monitoring-secret-kv + userKey: GRAFANA_ADMIN_USER + passwordKey: GRAFANA_ADMIN_PASSWORD + + # Grafana Sidecar를 통한 대시보드 자동 로딩 설정 + sidecar: + dashboards: + enabled: true + label: grafana_dashboard + labelValue: "1" + searchNamespace: ALL + folderAnnotation: grafana_folder + provider: + foldersFromFilesStructure: true + + # 비운영도 데이터 보존과 설정 확인을 위해 PVC를 사용합니다. + persistence: + enabled: true + type: sts + size: 20Gi + storageClassName: "gce-standard-rwo" + + prometheus: + prometheusSpec: + retention: 15d + retentionSize: 50GB + enableRemoteWriteReceiver: true + + serviceMonitorSelectorNilUsesHelmValues: false + serviceMonitorSelector: + matchLabels: + "pinhouse.co.kr/scrape-via": "prometheus" + serviceMonitorNamespaceSelector: {} + + podMonitorSelectorNilUsesHelmValues: false + podMonitorSelector: + matchLabels: + "pinhouse.co.kr/scrape-via": "prometheus" + podMonitorNamespaceSelector: {} + + probeSelectorNilUsesHelmValues: false + probeSelector: + matchLabels: + "pinhouse.co.kr/scrape-via": "prometheus" + probeNamespaceSelector: {} + + storageSpec: + volumeClaimTemplate: + spec: + storageClassName: "gce-standard-rwo" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 50Gi + + alertmanager: + alertmanagerSpec: {} + + prometheusOperator: + resources: {} + + kube-state-metrics: + resources: {} + + prometheus-node-exporter: + resources: {} diff --git a/k8s-helm/releases/monitoring-loki/values-dev-gitops.yaml b/k8s-helm/releases/monitoring-loki/values-dev-gitops.yaml new file mode 100644 index 0000000..5828237 --- /dev/null +++ b/k8s-helm/releases/monitoring-loki/values-dev-gitops.yaml @@ -0,0 +1,46 @@ +# ======================================== +# Dev Monitoring Loki GitOps 값 +# ======================================== + +loki: + # Loki 공용 ServiceAccount 이름을 고정해 두면 추후 인증 방식 전환 시 추적이 쉽습니다. + serviceAccount: + create: true + name: monitoring-loki-sa + annotations: {} + + loki: + # 로그 보관 기간은 14일로 유지합니다. + limits_config: + retention_period: 336h + + # Loki 로그 청크와 인덱스는 GCS 버킷에 저장합니다. + storage: + bucketNames: + chunks: "pinhouse-dev-loki" + ruler: "pinhouse-dev-loki" + admin: "pinhouse-dev-loki" + gcs: + bucket_name: "pinhouse-dev-loki" + + singleBinary: + replicas: 1 + + persistence: + enabled: true + size: 30Gi + storageClass: "gce-standard-rwo" + + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: 2000m + memory: 1Gi + + chunksCache: + enabled: false + + resultsCache: + allocatedMemory: 256 diff --git a/k8s-helm/releases/monitoring-tempo/values-dev-gitops.yaml b/k8s-helm/releases/monitoring-tempo/values-dev-gitops.yaml new file mode 100644 index 0000000..a9fa73a --- /dev/null +++ b/k8s-helm/releases/monitoring-tempo/values-dev-gitops.yaml @@ -0,0 +1,100 @@ +# ======================================== +# Dev Monitoring Tempo GitOps 값 +# ======================================== + +tempo: + # Tempo 공용 ServiceAccount 이름을 고정해 두면 인증 설정을 추적하기 쉽습니다. + serviceAccount: + create: true + name: monitoring-tempo-sa + annotations: {} + + storage: + # 트레이스 원본 데이터는 GCS 버킷에 저장합니다. + trace: + gcs: + bucket_name: "pinhouse-dev-tempo" + block: + retention: 336h + + ingester: + replicas: 1 + persistence: + enabled: true + size: 20Gi + storageClass: "gce-standard-rwo" + resources: + requests: + cpu: 500m + memory: 1Gi + limits: + cpu: 1000m + memory: 2Gi + + distributor: + replicas: 1 + resources: + requests: + cpu: 200m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + + compactor: + replicas: 1 + config: + compaction: + block_retention: 336h + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 500m + memory: 1Gi + + querier: + replicas: 1 + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 500m + memory: 1Gi + + queryFrontend: + replicas: 1 + resources: + requests: + cpu: 200m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + + overrides: + defaults: + metrics_generator: + processors: + - span-metrics + - local-blocks + + metricsGenerator: + enabled: true + replicas: 1 + resources: + requests: + cpu: 200m + memory: 256Mi + limits: + cpu: 500m + memory: 1Gi + config: + processor: + local_blocks: + flush_to_storage: true + storage: + remote_write: + - url: http://monitoring-core-kube-prome-prometheus.monitoring.svc.cluster.local:9090/api/v1/write From 8a374303e9947b26c419a8c3fc5f6ff4a50b6e70 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 18:22:42 +0900 Subject: [PATCH 6/9] =?UTF-8?q?chore:=20=EA=B0=9C=EB=B0=9C=EC=9A=A9=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20argocd=20=EC=A0=95=EC=9D=98=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- k8s-argocd/applications/dev/app.yaml | 38 +++++++++++++++ k8s-argocd/applications/dev/app/backend.yaml | 47 +++++++++++++++++++ k8s-argocd/applications/dev/app/frontend.yaml | 46 ++++++++++++++++++ .../applications/dev/app/image-updater.yaml | 20 ++++++++ k8s-argocd/applications/dev/monitoring.yaml | 38 +++++++++++++++ .../dev/monitoring/monitoring-alloy.yaml | 42 +++++++++++++++++ .../dev/monitoring/monitoring-core.yaml | 43 +++++++++++++++++ .../dev/monitoring/monitoring-loki.yaml | 42 +++++++++++++++++ .../dev/monitoring/monitoring-tempo.yaml | 42 +++++++++++++++++ k8s-argocd/applications/dev/platform.yaml | 38 +++++++++++++++ .../dev/platform/argocd-config.yaml | 38 +++++++++++++++ .../dev/platform/cert-manager.yaml | 46 ++++++++++++++++++ .../dev/platform/external-secret.yaml | 47 +++++++++++++++++++ .../dev/platform/gateway-api.yaml | 39 +++++++++++++++ .../dev/platform/gce-pd-csi-driver.yaml | 39 +++++++++++++++ .../dev/platform/metrics-server.yaml | 46 ++++++++++++++++++ .../dev/platform/monitoring-httproute.yaml | 38 +++++++++++++++ .../dev/platform/nginx-gateway-fabric.yaml | 46 ++++++++++++++++++ .../dev/platform/platform-resources.yaml | 42 +++++++++++++++++ .../dev/platform/storageclass.yaml | 38 +++++++++++++++ k8s-argocd/root-apps/root-dev.yaml | 36 ++++++++++++++ 21 files changed, 851 insertions(+) create mode 100644 k8s-argocd/applications/dev/app.yaml create mode 100644 k8s-argocd/applications/dev/app/backend.yaml create mode 100644 k8s-argocd/applications/dev/app/frontend.yaml create mode 100644 k8s-argocd/applications/dev/app/image-updater.yaml create mode 100644 k8s-argocd/applications/dev/monitoring.yaml create mode 100644 k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml create mode 100644 k8s-argocd/applications/dev/monitoring/monitoring-core.yaml create mode 100644 k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml create mode 100644 k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml create mode 100644 k8s-argocd/applications/dev/platform.yaml create mode 100644 k8s-argocd/applications/dev/platform/argocd-config.yaml create mode 100644 k8s-argocd/applications/dev/platform/cert-manager.yaml create mode 100644 k8s-argocd/applications/dev/platform/external-secret.yaml create mode 100644 k8s-argocd/applications/dev/platform/gateway-api.yaml create mode 100644 k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml create mode 100644 k8s-argocd/applications/dev/platform/metrics-server.yaml create mode 100644 k8s-argocd/applications/dev/platform/monitoring-httproute.yaml create mode 100644 k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml create mode 100644 k8s-argocd/applications/dev/platform/platform-resources.yaml create mode 100644 k8s-argocd/applications/dev/platform/storageclass.yaml create mode 100644 k8s-argocd/root-apps/root-dev.yaml diff --git a/k8s-argocd/applications/dev/app.yaml b/k8s-argocd/applications/dev/app.yaml new file mode 100644 index 0000000..4dbf9bd --- /dev/null +++ b/k8s-argocd/applications/dev/app.yaml @@ -0,0 +1,38 @@ +# =================================== +# Dev App Root +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: app-root-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: app + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-argocd/applications/dev/app + directory: + recurse: false + + destination: + server: https://kubernetes.default.svc + namespace: argocd + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/app/backend.yaml b/k8s-argocd/applications/dev/app/backend.yaml new file mode 100644 index 0000000..7f87dbd --- /dev/null +++ b/k8s-argocd/applications/dev/app/backend.yaml @@ -0,0 +1,47 @@ +# =================================== +# Dev Backend +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: backend-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/image-updater: enabled + finalizers: + - resources-finalizer.argocd.argoproj.io + annotations: + argocd-image-updater.argoproj.io/image-list: asia-northeast3-docker.pkg.dev/dev-pinhouse/pinhouse-dev-be/pinhouse-server + argocd-image-updater.argoproj.io/backend.update-strategy: newest-build + argocd-image-updater.argoproj.io/backend.allow-tags: regexp:^[0-9]{8}_[0-9]{6}-[a-f0-9]{7}$ + argocd-image-updater.argoproj.io/backend.kustomize.image-name: REPLACE_ME + argocd-image-updater.argoproj.io/write-back-method: git + argocd-image-updater.argoproj.io/git-branch: main + + notifications.argoproj.io/subscribe.on-sync-running.backend-nonprod: "" + notifications.argoproj.io/subscribe.on-deployed.backend-nonprod: "" + notifications.argoproj.io/subscribe.on-sync-failed.backend-nonprod: "" + notifications.argoproj.io/subscribe.on-health-degraded.backend-nonprod: "" + +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-kustomize/overlays/dev/backend + + destination: + server: https://kubernetes.default.svc + namespace: dev-app + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/app/frontend.yaml b/k8s-argocd/applications/dev/app/frontend.yaml new file mode 100644 index 0000000..3605327 --- /dev/null +++ b/k8s-argocd/applications/dev/app/frontend.yaml @@ -0,0 +1,46 @@ +# =================================== +# Dev Frontend +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: frontend-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/image-updater: enabled + finalizers: + - resources-finalizer.argocd.argoproj.io + annotations: + argocd-image-updater.argoproj.io/image-list: asia-northeast3-docker.pkg.dev/dev-pinhouse/pinhouse-dev-fe/pinhouse-web + argocd-image-updater.argoproj.io/frontend.update-strategy: newest-build + argocd-image-updater.argoproj.io/frontend.allow-tags: regexp:^[0-9]{8}_[0-9]{6}-[a-f0-9]{7}$ + argocd-image-updater.argoproj.io/frontend.kustomize.image-name: REPLACE_ME + argocd-image-updater.argoproj.io/write-back-method: git + argocd-image-updater.argoproj.io/git-branch: main + + notifications.argoproj.io/subscribe.on-deployed.frontend-nonprod: "" + notifications.argoproj.io/subscribe.on-sync-failed.frontend-nonprod: "" + notifications.argoproj.io/subscribe.on-health-degraded.frontend-nonprod: "" + +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-kustomize/overlays/dev/frontend + + destination: + server: https://kubernetes.default.svc + namespace: dev-app + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/app/image-updater.yaml b/k8s-argocd/applications/dev/app/image-updater.yaml new file mode 100644 index 0000000..17fd980 --- /dev/null +++ b/k8s-argocd/applications/dev/app/image-updater.yaml @@ -0,0 +1,20 @@ +# =================================== +# Image Updator +# =================================== + +apiVersion: argocd-image-updater.argoproj.io/v1alpha1 +kind: ImageUpdater + +# 기본 정보 +metadata: + name: dev-applications + namespace: argocd + +spec: + applicationRefs: + - namePattern: "*" + labelSelectors: + matchLabels: + pinhouse.co.kr/image-updater: enabled + pinhouse.co.kr/environment: dev + useAnnotations: true diff --git a/k8s-argocd/applications/dev/monitoring.yaml b/k8s-argocd/applications/dev/monitoring.yaml new file mode 100644 index 0000000..5bbd6b9 --- /dev/null +++ b/k8s-argocd/applications/dev/monitoring.yaml @@ -0,0 +1,38 @@ +# =================================== +# Dev Monitoring Root +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: monitoring-root-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: monitoring + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-argocd/applications/dev/monitoring + directory: + recurse: false + + destination: + server: https://kubernetes.default.svc + namespace: argocd + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml new file mode 100644 index 0000000..8bdbccb --- /dev/null +++ b/k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml @@ -0,0 +1,42 @@ +# =================================== +# Dev Monitoring Alloy +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: monitoring-alloy-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: monitoring + pinhouse.co.kr/monitoring-component: alloy + annotations: + argocd.argoproj.io/sync-wave: "2" + finalizers: + - resources-finalizer.argocd.argoproj.io + +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-helm/releases/monitoring-alloy + helm: + releaseName: monitoring-alloy + valueFiles: + - values-dev-gitops.yaml + + destination: + server: https://kubernetes.default.svc + namespace: monitoring + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-core.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-core.yaml new file mode 100644 index 0000000..b5b46c3 --- /dev/null +++ b/k8s-argocd/applications/dev/monitoring/monitoring-core.yaml @@ -0,0 +1,43 @@ +# =================================== +# Dev Monitoring Core +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: monitoring-core-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: monitoring + pinhouse.co.kr/monitoring-component: core + annotations: + argocd.argoproj.io/sync-wave: "0" + finalizers: + - resources-finalizer.argocd.argoproj.io + +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-helm/releases/monitoring-core + helm: + releaseName: monitoring-core + valueFiles: + - values-dev-gitops.yaml + + destination: + server: https://kubernetes.default.svc + namespace: monitoring + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml new file mode 100644 index 0000000..2611b5b --- /dev/null +++ b/k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml @@ -0,0 +1,42 @@ +# =================================== +# Dev Monitoring Loki +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: monitoring-loki-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: monitoring + pinhouse.co.kr/monitoring-component: loki + annotations: + argocd.argoproj.io/sync-wave: "1" + finalizers: + - resources-finalizer.argocd.argoproj.io + +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-helm/releases/monitoring-loki + helm: + releaseName: monitoring-loki + valueFiles: + - values-dev-gitops.yaml + + destination: + server: https://kubernetes.default.svc + namespace: monitoring + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml new file mode 100644 index 0000000..8c0fee1 --- /dev/null +++ b/k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml @@ -0,0 +1,42 @@ +# =================================== +# Dev Monitoring Tempo +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: monitoring-tempo-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: monitoring + pinhouse.co.kr/monitoring-component: tempo + annotations: + argocd.argoproj.io/sync-wave: "1" + finalizers: + - resources-finalizer.argocd.argoproj.io + +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-helm/releases/monitoring-tempo + helm: + releaseName: monitoring-tempo + valueFiles: + - values-dev-gitops.yaml + + destination: + server: https://kubernetes.default.svc + namespace: monitoring + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/platform.yaml b/k8s-argocd/applications/dev/platform.yaml new file mode 100644 index 0000000..7c308b1 --- /dev/null +++ b/k8s-argocd/applications/dev/platform.yaml @@ -0,0 +1,38 @@ +# =================================== +# Dev Platform Root +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-root-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-argocd/applications/dev/platform + directory: + recurse: false + + destination: + server: https://kubernetes.default.svc + namespace: argocd + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/platform/argocd-config.yaml b/k8s-argocd/applications/dev/platform/argocd-config.yaml new file mode 100644 index 0000000..c845b91 --- /dev/null +++ b/k8s-argocd/applications/dev/platform/argocd-config.yaml @@ -0,0 +1,38 @@ +# =================================== +# Dev Platform Argo CD Config +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-argocd-config-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "3" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-kustomize/platform/argocd/overlays/dev + + destination: + server: https://kubernetes.default.svc + namespace: argocd + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/platform/cert-manager.yaml b/k8s-argocd/applications/dev/platform/cert-manager.yaml new file mode 100644 index 0000000..c20ae96 --- /dev/null +++ b/k8s-argocd/applications/dev/platform/cert-manager.yaml @@ -0,0 +1,46 @@ +# =================================== +# Dev Platform cert-manager +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-cert-manager-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "1" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + sources: + - repoURL: https://charts.jetstack.io + chart: cert-manager + targetRevision: v1.16.2 + helm: + releaseName: cert-manager + valueFiles: + - $values/k8s-helm/releases/cert-manager/values-nonprod.yaml + - repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + ref: values + + destination: + server: https://kubernetes.default.svc + namespace: cert-manager + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/k8s-argocd/applications/dev/platform/external-secret.yaml b/k8s-argocd/applications/dev/platform/external-secret.yaml new file mode 100644 index 0000000..ce9d73a --- /dev/null +++ b/k8s-argocd/applications/dev/platform/external-secret.yaml @@ -0,0 +1,47 @@ +# =================================== +# Dev Platform External Secrets Operator +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-external-secret-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "1" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + sources: + - repoURL: https://charts.external-secrets.io + chart: external-secrets + targetRevision: 0.20.4 + helm: + releaseName: external-secrets + valueFiles: + - $values/k8s-helm/releases/external-secret/values-nonprod.yaml + - repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + ref: values + + destination: + server: https://kubernetes.default.svc + namespace: external-secrets + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true + - Replace=true diff --git a/k8s-argocd/applications/dev/platform/gateway-api.yaml b/k8s-argocd/applications/dev/platform/gateway-api.yaml new file mode 100644 index 0000000..3ea5bbb --- /dev/null +++ b/k8s-argocd/applications/dev/platform/gateway-api.yaml @@ -0,0 +1,39 @@ +# =================================== +# Dev Platform Gateway API CRD +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-gateway-api-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "0" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/kubernetes-sigs/gateway-api + targetRevision: v1.2.1 + path: config/crd/standard + + destination: + server: https://kubernetes.default.svc + namespace: argocd + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml b/k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml new file mode 100644 index 0000000..b18e461 --- /dev/null +++ b/k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml @@ -0,0 +1,39 @@ +# =================================== +# Dev Platform GCE PD CSI Driver +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-gce-pd-csi-driver-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "-1" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-kustomize/platform/gce-pd-csi-driver + + destination: + server: https://kubernetes.default.svc + namespace: gce-pd-csi-driver + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/k8s-argocd/applications/dev/platform/metrics-server.yaml b/k8s-argocd/applications/dev/platform/metrics-server.yaml new file mode 100644 index 0000000..46f6daa --- /dev/null +++ b/k8s-argocd/applications/dev/platform/metrics-server.yaml @@ -0,0 +1,46 @@ +# =================================== +# Dev Platform Metrics Server +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-metrics-server-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "1" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + sources: + - repoURL: https://kubernetes-sigs.github.io/metrics-server/ + chart: metrics-server + targetRevision: 3.13.0 + helm: + releaseName: metrics-server + valueFiles: + - $values/k8s-helm/releases/metrics-server/values-nonprod.yaml + - repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + ref: values + + destination: + server: https://kubernetes.default.svc + namespace: kube-system + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/k8s-argocd/applications/dev/platform/monitoring-httproute.yaml b/k8s-argocd/applications/dev/platform/monitoring-httproute.yaml new file mode 100644 index 0000000..90887df --- /dev/null +++ b/k8s-argocd/applications/dev/platform/monitoring-httproute.yaml @@ -0,0 +1,38 @@ +# =================================== +# Dev Platform Monitoring HTTPRoute +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-monitoring-httproute-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "3" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-kustomize/platform/monitoring/overlays/dev + + destination: + server: https://kubernetes.default.svc + namespace: monitoring + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml b/k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml new file mode 100644 index 0000000..d525073 --- /dev/null +++ b/k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml @@ -0,0 +1,46 @@ +# =================================== +# Dev Platform NGINX Gateway Fabric +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-nginx-gateway-fabric-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "1" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + sources: + - repoURL: ghcr.io/nginx/charts + chart: nginx-gateway-fabric + targetRevision: 2.4.2 + helm: + releaseName: ngf + valueFiles: + - $values/k8s-helm/releases/nginx-gateway-fabric/values-nonprod.yaml + - repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + ref: values + + destination: + server: https://kubernetes.default.svc + namespace: nginx-gateway + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/k8s-argocd/applications/dev/platform/platform-resources.yaml b/k8s-argocd/applications/dev/platform/platform-resources.yaml new file mode 100644 index 0000000..3d705f3 --- /dev/null +++ b/k8s-argocd/applications/dev/platform/platform-resources.yaml @@ -0,0 +1,42 @@ +# =================================== +# Dev Platform Resources +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-resources-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "2" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-helm/platform-chart + helm: + releaseName: pinhouse-platform + valueFiles: + - values-dev.yaml + + destination: + server: https://kubernetes.default.svc + namespace: platform-system + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/applications/dev/platform/storageclass.yaml b/k8s-argocd/applications/dev/platform/storageclass.yaml new file mode 100644 index 0000000..f74164e --- /dev/null +++ b/k8s-argocd/applications/dev/platform/storageclass.yaml @@ -0,0 +1,38 @@ +# =================================== +# Dev Platform StorageClass +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: platform-storageclass-dev + namespace: argocd + labels: + pinhouse.co.kr/environment: dev + pinhouse.co.kr/component: platform + annotations: + argocd.argoproj.io/sync-wave: "0" + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-kustomize/platform/storageclass + + destination: + server: https://kubernetes.default.svc + namespace: argocd + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-argocd/root-apps/root-dev.yaml b/k8s-argocd/root-apps/root-dev.yaml new file mode 100644 index 0000000..0f14fb6 --- /dev/null +++ b/k8s-argocd/root-apps/root-dev.yaml @@ -0,0 +1,36 @@ +# =================================== +# App of Apps 패턴 +# Dev 환경의 모든 애플리케이션을 관리 +# =================================== + +apiVersion: argoproj.io/v1alpha1 +kind: Application + +# 기본 정보 +metadata: + name: root-dev + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io + +# 스펙 +spec: + project: default + + source: + repoURL: https://github.com/PinHouse/PinHouse_CLOUD + targetRevision: main + path: k8s-argocd/applications/dev + directory: + recurse: false + + destination: + server: https://kubernetes.default.svc + namespace: argocd + + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true From 2141e237573316589080f5e54c3958e02247cbf5 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 18:43:57 +0900 Subject: [PATCH 7/9] =?UTF-8?q?refactor:=20helm=20nonprod=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EC=97=90=EC=84=9C=20dev=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- k8s-helm/.gitignore | 1 + k8s-helm/releases/argocd/values-dev.yaml | 18 +++++++++++++++ k8s-helm/releases/calico/values-dev.yaml | 8 +++++++ .../releases/cert-manager/values-dev.yaml | 4 ++++ .../releases/external-secret/values-dev.yaml | 11 ++++++++++ .../releases/metrics-server/values-dev.yaml | 22 +++++++++++++++++++ .../nginx-gateway-fabric/values-dev.yaml | 16 ++++++++++++++ 7 files changed, 80 insertions(+) create mode 100644 k8s-helm/releases/argocd/values-dev.yaml create mode 100644 k8s-helm/releases/calico/values-dev.yaml create mode 100644 k8s-helm/releases/cert-manager/values-dev.yaml create mode 100644 k8s-helm/releases/external-secret/values-dev.yaml create mode 100644 k8s-helm/releases/metrics-server/values-dev.yaml create mode 100644 k8s-helm/releases/nginx-gateway-fabric/values-dev.yaml diff --git a/k8s-helm/.gitignore b/k8s-helm/.gitignore index 7a60143..95a7ef5 100644 --- a/k8s-helm/.gitignore +++ b/k8s-helm/.gitignore @@ -20,6 +20,7 @@ releases/**/secrets/*.yaml # ======================================== releases/argocd/values-*.yaml !releases/argocd/*.yaml.example +!releases/argocd/values-dev.yaml # ======================================== # Monitoring 로컬 오버라이드 diff --git a/k8s-helm/releases/argocd/values-dev.yaml b/k8s-helm/releases/argocd/values-dev.yaml new file mode 100644 index 0000000..70bdbe4 --- /dev/null +++ b/k8s-helm/releases/argocd/values-dev.yaml @@ -0,0 +1,18 @@ +# Dev 환경용 Argo CD 설정 +global: + domain: argo.dev.pinhouse.co.kr + +configs: + cm: + # Git/Helm 변경 감지 주기. + timeout.reconciliation: "60s" + timeout.reconciliation.jitter: "15s" + + # TLS Termination을 Gateway에서 수행하므로 ArgoCD Server는 insecure 모드로 실행 + params: + server.insecure: "true" + +# ArgoCD Server에 --insecure 플래그 추가 +server: + extraArgs: + - --insecure diff --git a/k8s-helm/releases/calico/values-dev.yaml b/k8s-helm/releases/calico/values-dev.yaml new file mode 100644 index 0000000..f3e2e1f --- /dev/null +++ b/k8s-helm/releases/calico/values-dev.yaml @@ -0,0 +1,8 @@ +installation: + calicoNetwork: + bgp: Disabled + ipPools: + - cidr: 192.168.0.0/16 + encapsulation: VXLAN + natOutgoing: Enabled + nodeSelector: all() diff --git a/k8s-helm/releases/cert-manager/values-dev.yaml b/k8s-helm/releases/cert-manager/values-dev.yaml new file mode 100644 index 0000000..d9d6f2b --- /dev/null +++ b/k8s-helm/releases/cert-manager/values-dev.yaml @@ -0,0 +1,4 @@ +config: + enableGatewayAPI: true +crds: + enabled: true \ No newline at end of file diff --git a/k8s-helm/releases/external-secret/values-dev.yaml b/k8s-helm/releases/external-secret/values-dev.yaml new file mode 100644 index 0000000..5393cb9 --- /dev/null +++ b/k8s-helm/releases/external-secret/values-dev.yaml @@ -0,0 +1,11 @@ +installCRDs: true + +replicaCount: 2 + +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi diff --git a/k8s-helm/releases/metrics-server/values-dev.yaml b/k8s-helm/releases/metrics-server/values-dev.yaml new file mode 100644 index 0000000..cf9876b --- /dev/null +++ b/k8s-helm/releases/metrics-server/values-dev.yaml @@ -0,0 +1,22 @@ +# ======================================== +# Metrics Server 비운영 값 +# ======================================== +replicas: 1 + +# kubeadm 기반 노드에서 kubelet 메트릭을 안정적으로 수집하기 위한 기본 인자입니다. +defaultArgs: + - --cert-dir=/tmp + - --secure-port=10250 + - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP + - --kubelet-use-node-status-port + - --kubelet-insecure-tls + - --metric-resolution=15s + +# 기본 클러스터 규모에 맞춘 리소스 요청값입니다. +resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 200m + memory: 300Mi diff --git a/k8s-helm/releases/nginx-gateway-fabric/values-dev.yaml b/k8s-helm/releases/nginx-gateway-fabric/values-dev.yaml new file mode 100644 index 0000000..3692f1e --- /dev/null +++ b/k8s-helm/releases/nginx-gateway-fabric/values-dev.yaml @@ -0,0 +1,16 @@ +fullnameOverride: ngf-nginx-gateway-fabric + +# GatewayClass 설정 +nginxGateway: + gatewayClassName: nginx + gatewayControllerName: gateway.nginx.org/nginx-gateway-controller + +# Service 설정 +nginx: + service: + type: NodePort + nodePorts: + - port: 30080 + listenerPort: 80 + - port: 30443 + listenerPort: 443 From 68d1addf78a014c0b4c845383f33baf1b7f39030 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 18:45:07 +0900 Subject: [PATCH 8/9] =?UTF-8?q?refactor:=20=ED=95=9C=EA=B8=80=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EB=B0=8F=20dev-values=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- k8s-argocd/applications/dev/app.yaml | 3 +++ k8s-argocd/applications/dev/app/backend.yaml | 3 +++ k8s-argocd/applications/dev/app/frontend.yaml | 3 +++ .../applications/dev/app/image-updater.yaml | 1 + k8s-argocd/applications/dev/monitoring.yaml | 3 +++ .../dev/monitoring/monitoring-alloy.yaml | 3 +++ .../dev/monitoring/monitoring-core.yaml | 9 +++++++++ .../dev/monitoring/monitoring-loki.yaml | 3 +++ .../dev/monitoring/monitoring-tempo.yaml | 3 +++ k8s-argocd/applications/dev/platform.yaml | 3 +++ .../applications/dev/platform/argocd-config.yaml | 4 ++++ .../applications/dev/platform/cert-manager.yaml | 6 +++++- .../dev/platform/external-secret.yaml | 6 +++++- .../applications/dev/platform/gateway-api.yaml | 4 ++++ .../dev/platform/gce-pd-csi-driver.yaml | 4 ++++ .../dev/platform/metrics-server.yaml | 6 +++++- .../dev/platform/monitoring-httproute.yaml | 4 ++++ .../dev/platform/nginx-gateway-fabric.yaml | 6 +++++- .../dev/platform/platform-resources.yaml | 4 ++++ .../applications/dev/platform/storageclass.yaml | 4 ++++ k8s-argocd/root-apps/root-dev.yaml | 3 +++ k8s-argocd/root-apps/root-prod.yaml | 3 +++ .../monitoring-core/values-dev-gitops.yaml | 16 ++++++++++++++++ 23 files changed, 100 insertions(+), 4 deletions(-) diff --git a/k8s-argocd/applications/dev/app.yaml b/k8s-argocd/applications/dev/app.yaml index 4dbf9bd..071252a 100644 --- a/k8s-argocd/applications/dev/app.yaml +++ b/k8s-argocd/applications/dev/app.yaml @@ -19,6 +19,7 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -26,10 +27,12 @@ spec: directory: recurse: false + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: argocd + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/app/backend.yaml b/k8s-argocd/applications/dev/app/backend.yaml index 7f87dbd..08c1965 100644 --- a/k8s-argocd/applications/dev/app/backend.yaml +++ b/k8s-argocd/applications/dev/app/backend.yaml @@ -30,15 +30,18 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main path: k8s-kustomize/overlays/dev/backend + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: dev-app + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/app/frontend.yaml b/k8s-argocd/applications/dev/app/frontend.yaml index 3605327..ae58cd7 100644 --- a/k8s-argocd/applications/dev/app/frontend.yaml +++ b/k8s-argocd/applications/dev/app/frontend.yaml @@ -29,15 +29,18 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main path: k8s-kustomize/overlays/dev/frontend + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: dev-app + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/app/image-updater.yaml b/k8s-argocd/applications/dev/app/image-updater.yaml index 17fd980..9e5261b 100644 --- a/k8s-argocd/applications/dev/app/image-updater.yaml +++ b/k8s-argocd/applications/dev/app/image-updater.yaml @@ -11,6 +11,7 @@ metadata: namespace: argocd spec: + # 라벨을 기준으로 Image Updater 적용 대상을 찾습니다. applicationRefs: - namePattern: "*" labelSelectors: diff --git a/k8s-argocd/applications/dev/monitoring.yaml b/k8s-argocd/applications/dev/monitoring.yaml index 5bbd6b9..c1cc55a 100644 --- a/k8s-argocd/applications/dev/monitoring.yaml +++ b/k8s-argocd/applications/dev/monitoring.yaml @@ -19,6 +19,7 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -26,10 +27,12 @@ spec: directory: recurse: false + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: argocd + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml index 8bdbccb..0779ec0 100644 --- a/k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml +++ b/k8s-argocd/applications/dev/monitoring/monitoring-alloy.yaml @@ -21,6 +21,7 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -30,10 +31,12 @@ spec: valueFiles: - values-dev-gitops.yaml + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: monitoring + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-core.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-core.yaml index b5b46c3..20529d6 100644 --- a/k8s-argocd/applications/dev/monitoring/monitoring-core.yaml +++ b/k8s-argocd/applications/dev/monitoring/monitoring-core.yaml @@ -9,18 +9,25 @@ kind: Application metadata: name: monitoring-core-dev namespace: argocd + + # 라벨 추가 labels: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: monitoring pinhouse.co.kr/monitoring-component: core + + # 어노테이션 메타데이터 annotations: argocd.argoproj.io/sync-wave: "0" + + # Finalizers를 설정하면 Application 삭제 시 관련 리소스도 함께 삭제됨 finalizers: - resources-finalizer.argocd.argoproj.io spec: project: default + # Helm 소스 설정 source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -30,10 +37,12 @@ spec: valueFiles: - values-dev-gitops.yaml + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: monitoring + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml index 2611b5b..00fbab3 100644 --- a/k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml +++ b/k8s-argocd/applications/dev/monitoring/monitoring-loki.yaml @@ -21,6 +21,7 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -30,10 +31,12 @@ spec: valueFiles: - values-dev-gitops.yaml + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: monitoring + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml b/k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml index 8c0fee1..f604655 100644 --- a/k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml +++ b/k8s-argocd/applications/dev/monitoring/monitoring-tempo.yaml @@ -21,6 +21,7 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -30,10 +31,12 @@ spec: valueFiles: - values-dev-gitops.yaml + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: monitoring + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform.yaml b/k8s-argocd/applications/dev/platform.yaml index 7c308b1..ba6bc01 100644 --- a/k8s-argocd/applications/dev/platform.yaml +++ b/k8s-argocd/applications/dev/platform.yaml @@ -19,6 +19,7 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -26,10 +27,12 @@ spec: directory: recurse: false + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: argocd + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/argocd-config.yaml b/k8s-argocd/applications/dev/platform/argocd-config.yaml index c845b91..51a313f 100644 --- a/k8s-argocd/applications/dev/platform/argocd-config.yaml +++ b/k8s-argocd/applications/dev/platform/argocd-config.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # Gateway와 인증서가 준비된 뒤 Argo CD HTTPRoute를 연결합니다. argocd.argoproj.io/sync-wave: "3" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,15 +22,18 @@ metadata: spec: project: default + # Kustomize 오버레이로 Argo CD 부가 설정을 적용합니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main path: k8s-kustomize/platform/argocd/overlays/dev + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: argocd + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/cert-manager.yaml b/k8s-argocd/applications/dev/platform/cert-manager.yaml index c20ae96..a1b4568 100644 --- a/k8s-argocd/applications/dev/platform/cert-manager.yaml +++ b/k8s-argocd/applications/dev/platform/cert-manager.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # cert-manager는 platform-chart가 생성하는 Certificate보다 먼저 준비되어야 합니다. argocd.argoproj.io/sync-wave: "1" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,6 +22,7 @@ metadata: spec: project: default + # 외부 Helm chart와 Git 저장소 values 파일을 함께 사용합니다. sources: - repoURL: https://charts.jetstack.io chart: cert-manager @@ -28,15 +30,17 @@ spec: helm: releaseName: cert-manager valueFiles: - - $values/k8s-helm/releases/cert-manager/values-nonprod.yaml + - $values/k8s-helm/releases/cert-manager/values-dev.yaml - repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main ref: values + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: cert-manager + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/external-secret.yaml b/k8s-argocd/applications/dev/platform/external-secret.yaml index ce9d73a..d93be4c 100644 --- a/k8s-argocd/applications/dev/platform/external-secret.yaml +++ b/k8s-argocd/applications/dev/platform/external-secret.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # ExternalSecret 리소스를 해석할 컨트롤러를 먼저 준비합니다. argocd.argoproj.io/sync-wave: "1" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,6 +22,7 @@ metadata: spec: project: default + # 외부 Helm chart와 Git 저장소 values 파일을 함께 사용합니다. sources: - repoURL: https://charts.external-secrets.io chart: external-secrets @@ -28,15 +30,17 @@ spec: helm: releaseName: external-secrets valueFiles: - - $values/k8s-helm/releases/external-secret/values-nonprod.yaml + - $values/k8s-helm/releases/external-secret/values-dev.yaml - repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main ref: values + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: external-secrets + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/gateway-api.yaml b/k8s-argocd/applications/dev/platform/gateway-api.yaml index 3ea5bbb..b5c3844 100644 --- a/k8s-argocd/applications/dev/platform/gateway-api.yaml +++ b/k8s-argocd/applications/dev/platform/gateway-api.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # GatewayClass, Gateway, HTTPRoute보다 먼저 CRD를 설치해야 합니다. argocd.argoproj.io/sync-wave: "0" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,15 +22,18 @@ metadata: spec: project: default + # Gateway API CRD를 GitHub에서 직접 가져옵니다. source: repoURL: https://github.com/kubernetes-sigs/gateway-api targetRevision: v1.2.1 path: config/crd/standard + # CRD는 cluster-scoped 리소스라 argocd 네임스페이스로 보냅니다. destination: server: https://kubernetes.default.svc namespace: argocd + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml b/k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml index b18e461..8ea8a2d 100644 --- a/k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml +++ b/k8s-argocd/applications/dev/platform/gce-pd-csi-driver.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # StorageClass보다 먼저 CSI Driver를 설치해야 합니다. argocd.argoproj.io/sync-wave: "-1" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,15 +22,18 @@ metadata: spec: project: default + # Kustomize 소스 설정 source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main path: k8s-kustomize/platform/gce-pd-csi-driver + # CSI Driver는 gce-pd-csi-driver 네임스페이스에 배포됩니다. destination: server: https://kubernetes.default.svc namespace: gce-pd-csi-driver + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/metrics-server.yaml b/k8s-argocd/applications/dev/platform/metrics-server.yaml index 46f6daa..1a59e62 100644 --- a/k8s-argocd/applications/dev/platform/metrics-server.yaml +++ b/k8s-argocd/applications/dev/platform/metrics-server.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # kube-system에 설치되는 공용 컨트롤러이므로 플랫폼 계층에서 관리합니다. argocd.argoproj.io/sync-wave: "1" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,6 +22,7 @@ metadata: spec: project: default + # 외부 Helm chart와 Git 저장소 values 파일을 함께 사용합니다. sources: - repoURL: https://kubernetes-sigs.github.io/metrics-server/ chart: metrics-server @@ -28,15 +30,17 @@ spec: helm: releaseName: metrics-server valueFiles: - - $values/k8s-helm/releases/metrics-server/values-nonprod.yaml + - $values/k8s-helm/releases/metrics-server/values-dev.yaml - repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main ref: values + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: kube-system + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/monitoring-httproute.yaml b/k8s-argocd/applications/dev/platform/monitoring-httproute.yaml index 90887df..0e159e9 100644 --- a/k8s-argocd/applications/dev/platform/monitoring-httproute.yaml +++ b/k8s-argocd/applications/dev/platform/monitoring-httproute.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # Gateway와 인증서가 준비된 뒤 HTTPRoute를 연결합니다. argocd.argoproj.io/sync-wave: "3" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,15 +22,18 @@ metadata: spec: project: default + # Grafana HTTPRoute 설정 source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main path: k8s-kustomize/platform/monitoring/overlays/dev + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: monitoring + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml b/k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml index d525073..de12fcd 100644 --- a/k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml +++ b/k8s-argocd/applications/dev/platform/nginx-gateway-fabric.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # Gateway API CRD 설치 이후에 게이트웨이 컨트롤러를 배포합니다. argocd.argoproj.io/sync-wave: "1" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,6 +22,7 @@ metadata: spec: project: default + # 외부 Helm chart와 Git 저장소 values 파일을 함께 사용합니다. sources: - repoURL: ghcr.io/nginx/charts chart: nginx-gateway-fabric @@ -28,15 +30,17 @@ spec: helm: releaseName: ngf valueFiles: - - $values/k8s-helm/releases/nginx-gateway-fabric/values-nonprod.yaml + - $values/k8s-helm/releases/nginx-gateway-fabric/values-dev.yaml - repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main ref: values + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: nginx-gateway + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/platform-resources.yaml b/k8s-argocd/applications/dev/platform/platform-resources.yaml index 3d705f3..c57018a 100644 --- a/k8s-argocd/applications/dev/platform/platform-resources.yaml +++ b/k8s-argocd/applications/dev/platform/platform-resources.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # 컨트롤러가 준비된 뒤 Gateway, Certificate, ExternalSecret 같은 실제 리소스를 생성합니다. argocd.argoproj.io/sync-wave: "2" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,6 +22,7 @@ metadata: spec: project: default + # 로컬 Helm chart를 사용해 플랫폼 공통 리소스를 배포합니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -30,10 +32,12 @@ spec: valueFiles: - values-dev.yaml + # 배포 대상 클러스터 destination: server: https://kubernetes.default.svc namespace: platform-system + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/applications/dev/platform/storageclass.yaml b/k8s-argocd/applications/dev/platform/storageclass.yaml index f74164e..bb1cb87 100644 --- a/k8s-argocd/applications/dev/platform/storageclass.yaml +++ b/k8s-argocd/applications/dev/platform/storageclass.yaml @@ -13,6 +13,7 @@ metadata: pinhouse.co.kr/environment: dev pinhouse.co.kr/component: platform annotations: + # PVC를 사용하는 워크로드보다 먼저 StorageClass를 준비합니다. argocd.argoproj.io/sync-wave: "0" finalizers: - resources-finalizer.argocd.argoproj.io @@ -21,15 +22,18 @@ metadata: spec: project: default + # Kustomize 소스 설정 source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main path: k8s-kustomize/platform/storageclass + # StorageClass는 cluster-scoped 리소스라 argocd 네임스페이스로 보냅니다. destination: server: https://kubernetes.default.svc namespace: argocd + # 동기화 정책 syncPolicy: automated: prune: true diff --git a/k8s-argocd/root-apps/root-dev.yaml b/k8s-argocd/root-apps/root-dev.yaml index 0f14fb6..32807c6 100644 --- a/k8s-argocd/root-apps/root-dev.yaml +++ b/k8s-argocd/root-apps/root-dev.yaml @@ -17,6 +17,7 @@ metadata: spec: project: default + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: repoURL: https://github.com/PinHouse/PinHouse_CLOUD targetRevision: main @@ -24,10 +25,12 @@ spec: directory: recurse: false + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: argocd + # Git 기준으로 자동 동기화합니다. syncPolicy: automated: prune: true diff --git a/k8s-argocd/root-apps/root-prod.yaml b/k8s-argocd/root-apps/root-prod.yaml index 5b9206a..6cbef48 100644 --- a/k8s-argocd/root-apps/root-prod.yaml +++ b/k8s-argocd/root-apps/root-prod.yaml @@ -19,6 +19,7 @@ spec: project: default # GitOps 소 설정 + # Git 저장소에서 관리하는 매니페스트 경로입니다. source: # Git 리포지토리 URL repoURL: https://github.com/PinHouse/PinHouse_CLOUD @@ -32,11 +33,13 @@ spec: recurse: false # 배포 대상 클러스터 + # 배포 대상 클러스터와 네임스페이스입니다. destination: server: https://kubernetes.default.svc namespace: argocd # 동기화 정책 + # Git 기준으로 자동 동기화합니다. syncPolicy: # GitOps 자동 동기화 설정 automated: diff --git a/k8s-helm/releases/monitoring-core/values-dev-gitops.yaml b/k8s-helm/releases/monitoring-core/values-dev-gitops.yaml index 1eb8187..96ea569 100644 --- a/k8s-helm/releases/monitoring-core/values-dev-gitops.yaml +++ b/k8s-helm/releases/monitoring-core/values-dev-gitops.yaml @@ -14,10 +14,14 @@ kube-prometheus-stack: sidecar: dashboards: enabled: true + # ConfigMap에서 찾을 라벨 label: grafana_dashboard labelValue: "1" + # 모든 네임스페이스에서 대시보드 ConfigMap 검색 searchNamespace: ALL + # 폴더 어노테이션 지원 folderAnnotation: grafana_folder + # 대시보드 프로비저닝 설정 provider: foldersFromFilesStructure: true @@ -30,10 +34,13 @@ kube-prometheus-stack: prometheus: prometheusSpec: + # 비운영 환경 기준 메트릭 보관 기간과 최대 디스크 사용량입니다. retention: 15d retentionSize: 50GB + # 실제 scrape는 Alloy가 수행하고, Prometheus는 remote write receiver로 메트릭을 받습니다. enableRemoteWriteReceiver: true + # Prometheus가 직접 ServiceMonitor/PodMonitor/Probe를 scrape하지 않도록 둡니다. serviceMonitorSelectorNilUsesHelmValues: false serviceMonitorSelector: matchLabels: @@ -52,6 +59,7 @@ kube-prometheus-stack: "pinhouse.co.kr/scrape-via": "prometheus" probeNamespaceSelector: {} + # 메트릭 보관을 위해 PVC를 사용합니다. storageSpec: volumeClaimTemplate: spec: @@ -63,13 +71,21 @@ kube-prometheus-stack: storage: 50Gi alertmanager: + # Alertmanager는 알림 라우팅 전용이라 상대적으로 작은 리소스로 시작합니다. + # 비어 있는 map을 유지해 차트 기본값과 타입 충돌이 나지 않도록 합니다. alertmanagerSpec: {} prometheusOperator: + # Operator는 scrape 주체는 아니지만 Prometheus/Alertmanager 리소스를 생성하므로 계속 필요합니다. + # 비어 있는 map을 유지해 차트 기본값을 그대로 사용합니다. resources: {} kube-state-metrics: + # Kubernetes 리소스 상태 수집용 컴포넌트입니다. + # 비어 있는 map을 유지해 차트 기본값을 그대로 사용합니다. resources: {} prometheus-node-exporter: + # 노드 메트릭 수집기라서 가볍게 시작하되 과도한 사용을 막기 위해 제한을 둡니다. + # 비어 있는 map을 유지해 차트 기본값을 그대로 사용합니다. resources: {} From 89766d7a6f3ed4437cdf7060acffd66450e2f545 Mon Sep 17 00:00:00 2001 From: eedo_y Date: Sat, 11 Apr 2026 18:55:59 +0900 Subject: [PATCH 9/9] =?UTF-8?q?chore:=20=EB=B3=91=EB=A0=AC=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC=EC=9D=B8=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/terraform-apply.yml | 106 ++++++++++++++++---------- .github/workflows/terraform-plan.yml | 21 +++-- 2 files changed, 77 insertions(+), 50 deletions(-) diff --git a/.github/workflows/terraform-apply.yml b/.github/workflows/terraform-apply.yml index 73a4c8e..e4f2358 100644 --- a/.github/workflows/terraform-apply.yml +++ b/.github/workflows/terraform-apply.yml @@ -4,14 +4,14 @@ name: PinHouse Terraform Apply 파이프라인 on: workflow_dispatch: inputs: - environment: - description: "적용할 환경을 선택합니다. dev, staging, prod 중 하나를 사용합니다." + target: + description: "적용할 대상을 선택합니다. all을 선택하면 dev와 prod를 병렬로 적용합니다." required: true type: choice options: - dev - - staging - prod + - all confirm: description: '"apply"를 입력해야 실제 적용이 진행됩니다.' required: true @@ -22,18 +22,50 @@ permissions: contents: read id-token: write -env: - GCP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} - GCP_SERVICE_ACCOUNT: ${{ secrets.GCP_SERVICE_ACCOUNT }} - TERRAFORM_STATE_BUCKET: ${{ secrets.TERRAFORM_STATE_BUCKET }} - TERRAFORM_TFVARS_DEV: ${{ secrets.TERRAFORM_TFVARS_DEV }} - TERRAFORM_TFVARS_PROD: ${{ secrets.TERRAFORM_TFVARS_PROD }} - jobs: + prepare-matrix: + name: 적용 대상 준비 + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.prepare.outputs.matrix }} + + steps: + - name: 적용 대상 Matrix 생성 + id: prepare + run: | + case "${{ github.event.inputs.target }}" in + dev) + MATRIX='[{"terraform_environment":"dev","github_environment":"PinHouse_dev"}]' + ;; + prod) + MATRIX='[{"terraform_environment":"prod","github_environment":"PinHouse_prod"}]' + ;; + all) + MATRIX='[{"terraform_environment":"dev","github_environment":"PinHouse_dev"},{"terraform_environment":"prod","github_environment":"PinHouse_prod"}]' + ;; + *) + echo "오류: 지원하지 않는 대상입니다: ${{ github.event.inputs.target }}" + exit 1 + ;; + esac + + echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT" + terraform-apply: - name: Apply - ${{ github.event.inputs.environment }} + name: Apply - ${{ matrix.terraform_environment }} runs-on: ubuntu-latest - environment: ${{ github.event.inputs.environment }} + needs: prepare-matrix + if: needs.prepare-matrix.outputs.matrix != '' + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.prepare-matrix.outputs.matrix) }} + environment: ${{ matrix.github_environment }} + env: + GCP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} + GCP_SERVICE_ACCOUNT: ${{ secrets.GCP_SERVICE_ACCOUNT }} + TERRAFORM_STATE_BUCKET: ${{ secrets.TERRAFORM_STATE_BUCKET }} + TERRAFORM_TFVARS: ${{ secrets.TERRAFORM_TFVARS }} steps: - name: 적용 확인 값 검증 @@ -63,44 +95,33 @@ jobs: - name: State 버킷 변수 확인 run: | if [ -z "${{ env.TERRAFORM_STATE_BUCKET }}" ]; then - echo "오류: GitHub Secrets에 TERRAFORM_STATE_BUCKET을 설정해야 합니다." + echo "오류: GitHub Environment Secret TERRAFORM_STATE_BUCKET을 설정해야 합니다." exit 1 fi - name: Terraform 초기화 id: init - working-directory: terraform/environments/${{ github.event.inputs.environment }} + working-directory: terraform/environments/${{ matrix.terraform_environment }} run: | terraform init \ -backend-config="bucket=${{ env.TERRAFORM_STATE_BUCKET }}" \ - -backend-config="prefix=terraform/${{ github.event.inputs.environment }}/state" + -backend-config="prefix=terraform/${{ matrix.terraform_environment }}/state" - name: Terraform tfvars 복원 id: tfvars - working-directory: terraform/environments/${{ github.event.inputs.environment }} + working-directory: terraform/environments/${{ matrix.terraform_environment }} run: | - case "${{ github.event.inputs.environment }}" in - prod) - TFVARS_CONTENT="${TERRAFORM_TFVARS_PROD}" - SECRET_NAME="TERRAFORM_TFVARS_PROD" - ;; - *) - echo "오류: 지원하지 않는 환경입니다: ${{ github.event.inputs.environment }}" - exit 1 - ;; - esac - - if [ -z "${TFVARS_CONTENT}" ]; then - echo "오류: GitHub Secret ${SECRET_NAME}를 설정해야 합니다." + if [ -z "${TERRAFORM_TFVARS}" ]; then + echo "오류: GitHub Environment Secret TERRAFORM_TFVARS를 설정해야 합니다." exit 1 fi - printf '%s\n' "${TFVARS_CONTENT}" > terraform.tfvars + printf '%s\n' "${TERRAFORM_TFVARS}" > terraform.tfvars chmod 600 terraform.tfvars - name: Terraform Plan 실행 id: plan - working-directory: terraform/environments/${{ github.event.inputs.environment }} + working-directory: terraform/environments/${{ matrix.terraform_environment }} run: | terraform plan -no-color -out=tfplan terraform show -no-color tfplan > plan_output.txt @@ -108,14 +129,14 @@ jobs: - name: Plan 결과 업로드 uses: actions/upload-artifact@v4 with: - name: tfplan-${{ github.event.inputs.environment }}-${{ github.run_number }} + name: tfplan-${{ matrix.terraform_environment }}-${{ github.run_number }} path: | - terraform/environments/${{ github.event.inputs.environment }}/tfplan - terraform/environments/${{ github.event.inputs.environment }}/plan_output.txt + terraform/environments/${{ matrix.terraform_environment }}/tfplan + terraform/environments/${{ matrix.terraform_environment }}/plan_output.txt - name: Terraform Apply 실행 id: apply - working-directory: terraform/environments/${{ github.event.inputs.environment }} + working-directory: terraform/environments/${{ matrix.terraform_environment }} run: | terraform apply -auto-approve tfplan 2>&1 | tee apply_output.txt @@ -123,25 +144,26 @@ jobs: uses: actions/upload-artifact@v4 if: always() with: - name: tfapply-${{ github.event.inputs.environment }}-${{ github.run_number }} - path: terraform/environments/${{ github.event.inputs.environment }}/apply_output.txt + name: tfapply-${{ matrix.terraform_environment }}-${{ github.run_number }} + path: terraform/environments/${{ matrix.terraform_environment }}/apply_output.txt - name: 배포 요약 생성 if: always() run: | - echo "## Terraform Apply 요약 - ${{ github.event.inputs.environment }}" >> $GITHUB_STEP_SUMMARY + echo "## Terraform Apply 요약 - ${{ matrix.terraform_environment }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - echo "**환경:** ${{ github.event.inputs.environment }}" >> $GITHUB_STEP_SUMMARY + echo "**환경:** ${{ matrix.terraform_environment }}" >> $GITHUB_STEP_SUMMARY + echo "**GitHub Environment:** ${{ matrix.github_environment }}" >> $GITHUB_STEP_SUMMARY echo "**실행 결과:** ${{ steps.apply.outcome }}" >> $GITHUB_STEP_SUMMARY echo "**실행 사용자:** @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY echo "**커밋 SHA:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - if [ -f terraform/environments/${{ github.event.inputs.environment }}/apply_output.txt ]; then + if [ -f terraform/environments/${{ matrix.terraform_environment }}/apply_output.txt ]; then echo "
Apply 출력 보기" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY - cat terraform/environments/${{ github.event.inputs.environment }}/apply_output.txt >> $GITHUB_STEP_SUMMARY + cat terraform/environments/${{ matrix.terraform_environment }}/apply_output.txt >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY echo "
" >> $GITHUB_STEP_SUMMARY fi @@ -149,5 +171,5 @@ jobs: - name: 실패 시 워크플로우 종료 if: failure() run: | - echo "::error::${{ github.event.inputs.environment }} 환경 Terraform apply 실행에 실패했습니다." + echo "::error::${{ matrix.terraform_environment }} 환경 Terraform apply 실행에 실패했습니다." exit 1 diff --git a/.github/workflows/terraform-plan.yml b/.github/workflows/terraform-plan.yml index 9114cf6..ed7d5b5 100644 --- a/.github/workflows/terraform-plan.yml +++ b/.github/workflows/terraform-plan.yml @@ -24,6 +24,7 @@ jobs: GCP_WORKLOAD_IDENTITY_PROVIDER: "" GCP_SERVICE_ACCOUNT: "" TERRAFORM_STATE_BUCKET: "" + TERRAFORM_TFVARS_DEV: "" TERRAFORM_TFVARS_PROD: "" outputs: environments: ${{ steps.detect.outputs.environments || '[]' }} @@ -45,11 +46,16 @@ jobs: # 변경된 환경 목록을 배열로 수집합니다. ENVIRONMENTS=() + if echo "$CHANGED_FILES" | grep -q "terraform/environments/dev/"; then + ENVIRONMENTS+=("dev") + fi + if echo "$CHANGED_FILES" | grep -q "terraform/environments/prod/"; then ENVIRONMENTS+=("prod") fi if echo "$CHANGED_FILES" | grep -q "terraform/modules/"; then + ENVIRONMENTS+=("dev") ENVIRONMENTS+=("prod") fi @@ -73,6 +79,7 @@ jobs: GCP_WORKLOAD_IDENTITY_PROVIDER: "" GCP_SERVICE_ACCOUNT: "" TERRAFORM_STATE_BUCKET: "" + TERRAFORM_TFVARS_DEV: "" TERRAFORM_TFVARS_PROD: "" steps: @@ -99,11 +106,12 @@ jobs: runs-on: ubuntu-22.04 needs: detect-changes if: (needs.detect-changes.outputs.environments || '[]') != '[]' # 변경된 환경이 있을 때만 실행합니다. + environment: ${{ matrix.environment == 'dev' && 'PinHouse_dev' || matrix.environment == 'prod' && 'PinHouse_prod' }} env: GCP_WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} GCP_SERVICE_ACCOUNT: ${{ secrets.GCP_SERVICE_ACCOUNT }} TERRAFORM_STATE_BUCKET: ${{ secrets.TERRAFORM_STATE_BUCKET }} - TERRAFORM_TFVARS_PROD: ${{ secrets.TERRAFORM_TFVARS_PROD }} + TERRAFORM_TFVARS: ${{ secrets.TERRAFORM_TFVARS }} strategy: fail-fast: false # 한 환경 실패가 다른 환경 확인을 막지 않도록 유지합니다. matrix: @@ -140,7 +148,7 @@ jobs: id: state-bucket run: | if [ -z "${{ env.TERRAFORM_STATE_BUCKET }}" ]; then - echo "오류: GitHub Secrets에 TERRAFORM_STATE_BUCKET을 설정해야 합니다." + echo "오류: GitHub Environment Secret TERRAFORM_STATE_BUCKET을 설정해야 합니다." exit 1 fi @@ -158,15 +166,12 @@ jobs: if: steps.init.outcome == 'success' working-directory: terraform/environments/${{ matrix.environment }} run: | - TFVARS_CONTENT="${TERRAFORM_TFVARS_PROD}" - SECRET_NAME="TERRAFORM_TFVARS_PROD" - - if [ -z "${TFVARS_CONTENT}" ]; then - echo "오류: GitHub Secret ${SECRET_NAME}를 설정해야 합니다." + if [ -z "${TERRAFORM_TFVARS}" ]; then + echo "오류: GitHub Environment Secret TERRAFORM_TFVARS를 설정해야 합니다." exit 1 fi - printf '%s\n' "${TFVARS_CONTENT}" > terraform.tfvars + printf '%s\n' "${TERRAFORM_TFVARS}" > terraform.tfvars chmod 600 terraform.tfvars - name: Terraform 유효성 검사