기본 프로덕션 클러스터의 네트워킹 구성

이 튜토리얼은 Google Kubernetes Engine(GKE) 클러스터에 웹 애플리케이션을 배포하고 HTTPS 부하 분산기로 노출하는 데 관심이 있는 클라우드 설계자 및 운영 관리자를 대상으로 합니다.

GKE 클러스터 만들기

다음 Terraform 파일에서 GKE 클러스터를 만듭니다.


terraform {
  required_version = "~> 1.3"
}

provider "google" {}

variable "region" {
  type        = string
  description = "Region where the cluster will be created."
  default     = "us-central1"
}

variable "cluster_name" {
  type        = string
  description = "Name of the cluster"
  default     = "networking-cluster"
}

resource "google_container_cluster" "default" {
  name             = var.cluster_name
  description      = "Cluster for sample web application"
  location         = var.region
  enable_autopilot = true

  ip_allocation_policy {}
}

output "region" {
  value       = var.region
  description = "Compute region"
}

output "cluster_name" {
  value       = google_container_cluster.default.name
  description = "Cluster name"
}

다음 Terraform 파일에서 전역 IP 주소와 Cloud DNS 영역을 만듭니다.


terraform {
  required_version = "~> 1.3"
}

variable "base_domain" {
  type        = string
  description = "Your base domain"
}

variable "name" {
  type        = string
  description = "Name of resources"
  default     = "networking-tutorial"
}

data "google_client_config" "current" {}

resource "google_compute_global_address" "default" {
  name = var.name
}

resource "google_dns_managed_zone" "default" {
  name        = var.name
  dns_name    = "${var.name}.${var.base_domain}."
  description = "DNS Zone for web application"
}

resource "google_dns_record_set" "a" {
  name         = google_dns_managed_zone.default.dns_name
  type         = "A"
  ttl          = 300
  managed_zone = google_dns_managed_zone.default.name

  rrdatas = [google_compute_global_address.default.address]
}

resource "google_dns_record_set" "cname" {
  name         = join(".", compact(["www", google_dns_record_set.a.name]))
  type         = "CNAME"
  ttl          = 300
  managed_zone = google_dns_managed_zone.default.name

  rrdatas = [google_dns_record_set.a.name]
}

output "dns_zone_name_servers" {
  value       = google_dns_managed_zone.default.name_servers
  description = "Write these virtual name servers in your base domain."
}

output "domain" {
  value = trim(google_dns_record_set.a.name, ".")
}
  1. Terraform을 초기화합니다.

    terraform init
    
  2. 인프라 변경사항 보기:

    terraform plan
    

    메시지가 표시되면 my-domain.net과 같은 도메인을 입력하세요.

  3. Terraform 구성을 적용합니다.

    terraform apply --auto-approve
    

    메시지가 표시되면 my-domain.net과 같은 도메인을 입력하세요.

    출력은 다음과 비슷합니다.

    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    cluster_name = "networking-cluster"
    region = "us-central1"
    

외부 애플리케이션 부하 분산기 만들기

  1. 다음 매니페스트에서는 ManagedCertificate, FrontendConfig, 배포, 서비스, 인그레스를 설명합니다.

    ---
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: networking-managed-cert
    spec:
      domains:
        - DOMAIN_NAME
        - www.DOMAIN_NAME
    ---
    apiVersion: networking.gke.io/v1beta1
    kind: FrontendConfig
    metadata:
      name: networking-fc
    spec:
      redirectToHttps:
        enabled: true
        responseCodeName: MOVED_PERMANENTLY_DEFAULT
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
    spec:
      selector:
        matchLabels:
          app: frontend
      replicas: 2
      template:
        metadata:
          labels:
            app: frontend
        spec:
          containers:
          - name: echo-amd64
            image: us-docker.pkg.dev/google-samples/containers/gke/hello-app-cdn:1.0
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: frontend
    spec:
      type: LoadBalancer
      selector:
        app: frontend
      ports:
      - name: http
        port: 80
        targetPort: 8080
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: frontend
      annotations:
        networking.gke.io/managed-certificates: networking-managed-cert
        networking.gke.io/v1beta1.FrontendConfig: networking-fc
        kubernetes.io/ingress.global-static-ip-name: networking-tutorial
        kubernetes.io/ingress.class: gce
      labels:
        app: frontend
    spec:
      defaultBackend:
        service:
          name: frontend
          port:
            number: 80

    DOMAIN_NAME을 도메인 이름으로 바꿉니다(예: my-domain.net).

    이 매니페스트에는 다음과 같은 속성이 있습니다.

    • networking.gke.io/managed-certificates: ManagedCertificate의 이름
    • networking.gke.io/v1beta1.FrontendConfig: FrontendConfig 리소스의 이름
    • kubernetes.io/ingress.global-static-ip-name: IP 주소의 이름
    • kubernetes.io/ingress.class: GKE 인그레스 컨트롤러에 외부 애플리케이션 부하 분산기를 만들도록 지시
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f kubernetes-manifests.yaml
    
  3. 인그레스가 생성되었는지 확인합니다.

    kubectl describe ingress frontend
    

    출력은 다음과 비슷합니다.

    ...
      Events:
        Type    Reason  Age   From                     Message
        ----    ------  ----  ----                     -------
        Normal  ADD     2m    loadbalancer-controller  default/frontend
        Normal  CREATE  1m    loadbalancer-controller  ip: 203.0.113.2
    ...
    

    인그레스가 프로비저닝되는 데 몇 분 정도 걸릴 수 있습니다.

애플리케이션 테스트

  1. SSL 인증서 상태를 확인합니다.

    kubectl get managedcertificates.networking.gke.io networking-managed-cert
    

    SSL 인증서를 프로비저닝하는 데 최대 30분이 걸릴 수 있습니다. 다음 출력은 SSL 인증서가 준비되었음을 나타냅니다.

    NAME                      AGE   STATUS
    networking-managed-cert   28m   Active
    
  2. curl 명령어를 실행합니다.

    curl -Lv https://DOMAIN_NAME
    

    출력은 다음과 비슷합니다.

    *   Trying 34.160.115.33:443...
    * Connected to DOMAIN_NAME (34.160.115.33) port 443 (#0)
    ...
    * TLSv1.3 (IN), TLS handshake, Certificate (11):
    ...
    * Server certificate:
    *  subject: CN=DOMAIN_NAME
    ...
    > Host: DOMAIN_NAME