为基本生产集群配置网络


本教程适用于希望将 Web 应用部署到 Google Kubernetes Engine (GKE) 集群并使用 HTTPS 负载均衡器公开的云架构师和运维管理员。

目标

在本教程中,您将学习如何完成以下操作:

  • 创建 GKE 集群。
  • 使用 Terraform 创建全局 IP 地址和 Cloud DNS 区域。
  • 配置 HTTPS 负载均衡。
  • 部署示例 Web 应用。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

须知事项

设置项目

  1. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  2. 确保您的 Google Cloud 项目已启用结算功能

  3. 启用 Google Kubernetes Engine, Cloud DNS API。

    启用 API

  • 您必须拥有域名。域名长度不得超过 63 个字符。您可以使用 Google Domains 或其他注册商。

设置您的环境

在本教程中,您将使用 Cloud Shell 来管理 Google Cloud 上托管的资源。Cloud Shell 中预安装了本教程所需的软件,包括 Terraformkubectlgcloud CLI

  1. 设置环境变量:

    PROJECT_ID=$(gcloud config get-value project)
    gcloud config set project $PROJECT_ID
    gcloud config set compute/region us-central1
    
  2. 克隆代码库:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    
  3. 切换到工作目录:

    cd kubernetes-engine-samples/autopilot/networking-tutorial
    

创建 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、Deployment、Service 和 Ingress:

    ---
    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 Ingress 控制器创建外部应用负载均衡器。
  2. 将清单应用到您的集群:

    kubectl apply -f kubernetes-manifests.yaml
    
  3. 验证 Ingress 已创建:

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

    Ingress 可能需要几分钟才能完成预配。

测试应用

  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
    

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

    删除 Google Cloud 项目:

    gcloud projects delete PROJECT_ID

删除各个资源

  1. 删除 kubernetes 资源:

    kubectl delete -f kubernetes-manifests.yaml
    
  2. 删除 Terraform 资源:

    terraform destroy --auto-approve
    

    出现提示时,请输入您的网域,例如 my-domain.net

后续步骤