为基本生产集群配置网络


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

目标

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

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

费用

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

您可使用价格计算器根据您的预计使用情况来估算费用。

新 Google Cloud 用户可能有资格申请免费试用

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

准备工作

设置项目

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. 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

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Google Kubernetes Engine, Cloud DNS APIs.

    Enable the APIs

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

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Google Kubernetes Engine, Cloud DNS APIs.

    Enable the APIs

    • 您必须拥有域名。域名长度不得超过 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 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

    删除项目

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    删除各个资源

    1. 删除 kubernetes 资源:

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

      terraform destroy --auto-approve
      

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

    后续步骤