配置 Terraform 模块

此解决方案所需的资源在 Terraform 模块中定义。

使用须知

开始配置 Terraform 模块之前,请完成以下步骤:

  1. 了解 Terraform 的基本知识。

    至少要阅读 Terrraform 文档中的介绍。

  2. 保持以下信息就绪:
    • 租户的 OCID。

      您可以在Oracle Cloud Infrastructure Web 控制台中找到租户的 OCID。从服务菜单中选择管理,然后单击租户详细信息

    • 您希望 Terraform 在Oracle Cloud Infrastructure中用来验证的用户的 OCID。

      要查找用户的 OCID,请从服务菜单中选择标识,然后选择用户。在列表中找到您的用户名,然后复制其 OCID。

    • 要在其中创建资源的区间的 OCID。

      要查找区间的 OCID,请从服务菜单中选择标识,然后选择间。在列表中找到所需的区间,然后复制其 OCID。

    • 要创建资源的区域的 ID。

      例如,“美国东部” (Ashburn)区域的 ID 为 us-ashburn-1

      请参阅区域和可用性域

  3. 确定以下内容:
    • 要用于 bastion 和 admin 主机的映像的 OCID。
      Bastion 主机的 Terraform 配置中定义的默认映像是 Oracle 自治 Linux 映像。如果要使用其他映像,请标识所需映像的 OCID。
      • 要查找定制映像的 OCID,请登录Oracle Cloud Infrastructure Web 控制台,从服务菜单中选择计算,然后选择定制映像
      • 要查找 Oracle 提供的映像的 OCID,请完成以下步骤:
        1. 转到 Oracle Cloud 映像
        2. 在左侧的导航窗格中,选择一个映像系列(例如Oracle Linux 7.x)。
        3. 在最终的页面上,向下滚动到要使用的图像版本,然后单击(例如,Oracle - Linux -7.7-2019.09.25-0)。
        4. 在最终页面上,向下滚动到图像 Ocid 部分。
        5. 复制与要创建该基础主机的区域相对应的 OCID。

          映像 OCID 包含映像可在其中使用的区域的 ID。例如,德国中部(法国克福)区域中图像的 OCID 的格式为 ocid1.image.oc1.eu-frankfurt-1.aaaaaaaaxxx…,请确保为要创建资源的区域复制该图像的 OCID。

    • Bastion 和 admin 主机的时区。

      在类似 Unix 的系统上,可以通过运行以下命令获取时区列表:timedatectl list-timezones

    • 要用于 bastion 主机、管理主机和 Kubernetes worker 节点的计算配置。

      请参阅计算配置

  4. 完成在 Oracle Cloud Infrastructure 中创建 Kubernetes 集群的先决条件。请参阅《Preparing for Container Engine for Kubernetes》
  5. (可选)如果要从 Oracle Cloud Infrastructure Registry 中的专用资料档案库中提取容器化应用程序的图像,则需要执行此步骤。
    1. 为应该用于从 Oracle Cloud Infrastructure Registry 中提取图像的用户名生成验证标记。请参阅获取验证标记
    2. 将生成为密钥的验证标记存储在 Oracle Cloud Infrastructure Vault 中。请参见 Managing Secrets

下载 Terraform 代码

此解决方案的 Terraform 代码在 GitHub 上提供。

  1. 在左侧的导航窗格中,单击下载代码
  2. 单击 Git 资料档案库
  3. 将资料档案库克隆或下载到本地计算机。

关于 Terraform 代码

此解决方案的 Terraform 代码组织为可重用模块,每个模块包含目标拓扑的特定组件的资源。

对 Terraform 配置文件中的云资源进行编码使您能够快速预配拓扑并高效地管理资源。

Terraform 代码在顶层包含以下目录和文件:
  • docs 目录和 *.adoc:代码文档。所需的所有信息和说明都包含在您现在读取的文档中。您无需参考代码中包含的文档。
  • *.tf:解决方案使用的 Terraform 配置文件。不要编辑这些文件。
  • terraform.tfvars.example:用于创建 Terraform 变量文件的模板。不要编辑或删除模板。将它复制到 terraform.tfvars
  • modules:包含您使用此解决方案创建的资源的核心 Terraform 配置的目录。不要编辑它们。
  • .github 目录和 .gitignore:内部 Github 配置文件。不要编辑它们。

设置 Terraform 变量

指定 Terraform 连接到Oracle Cloud Infrastructure 租户所需的参数。此外,还应指定网络参数、bastion 主机和管理主机的属性以及 Kubernetes 设置。

  1. 在下载或克隆的代码的顶层目录中,创建名为 provider.tf 的纯文本文件,该文件包含以下代码:
    provider "oci" {
      tenancy_ocid         = var.tenancy_id
      user_ocid            = var.user_id
      fingerprint          = var.api_fingerprint
      private_key_path     = var.api_private_key_path
      region               = var.region
      disable_auto_retries = var.disable_auto_retries
    }
  2. 在下载或克隆的代码的顶级目录中找到 terraform.tfvars.example 文件,然后将该文件复制到 terraform.tfvars

    注 :

    要管理多个租户中的资源,请为每个租户维护一个单独的 terraform.tfvars 文件。
  3. 确保您已完成先前描述的先决条件。请参阅开始之前
  4. 在纯文本编辑器中打开 terraform.tfvars,并按如下所示设置变量的值:
    变量 说明
    api_fingerprint(必需) 您上载的 API 签名密钥的指纹。
    api_private_key_path(必需) 包含您的私有 API 签名密钥的文件的完整路径和名称。
    compartment_id(必需) 要在其中创建资源的区间的 OCID。
    tenancy_id(必需) 租户的 OCID。
    user_id(必需) 您希望 Terraform 在Oracle Cloud Infrastructure中用来验证的用户的 OCID。
    ssh_private_key_path 包含私有 SSH 密钥的文件的完整路径和名称 , 该私有密钥与要为该基础主机提供的公共密钥相对应。

    此值用于构造 ssh 命令,该命令可用来访问基础主机。应用 Terraform 配置时,输出中将显示 ssh 命令。请注意,Terraform 不会读取或复制私钥。

    ssh_public_key_path 包含要为基础主机提供的公共 SSH 密钥的文件的完整路径和名称。
    label_prefix 短标识符,将其用作资源名称中的前缀。

    使用一个字符串可帮助您通过查看资源的名称来识别资源的用途或特性。例如,如果您要使用 Terraform 配置来设置测试或临时环境,请考虑使用前缀 teststaging

    region 要创建资源的区域的 ID。

    例如,“美国东部” (Ashburn)区域的 ID 为 us-ashburn-1

    nat_gateway_enabled 指定 true 为 VCN 创建 NAT 网关。

    如果任何专用计算实例(例如管理主机或 Kubernetes worker 节点)需要访问公共互联网上的主机,则需要 NAT 网关。

    newbitsnetnum 应用配置时,Terraform 会将 newbitsnetnum 的值作为 Terraform 函数 cidrsubnet() 的参数传递。此函数计算 bastion 主机、管理主机、负载平衡器节点和 Kubernetes worker 节点的子网的 CIDR 前缀。
    • newbits 用于确定子网的大小。它是 VCN 的网络掩码与您需要的网络掩码之间的基本子网差异。

      例如,要在 /16 VCN 中创建网络掩码为 /29 的子网,请指定 13 作为 newbits 的值(即 29 减去 16)。

      较低的 newbits 值会导致一个地址空间较大的子网。

    • netnum 用于确定子网的边界。当网络使用 newbits 进行掩码时,它是子网的从零开始的索引。

      继续上一个示例,如果指定 newbits=13netnum=0,则 cidrsubnet() 函数将返回子网 CIDR 前缀 10.0.0.0/29,该前缀是 10.0.0.0/16 VCN 中的第一个 /29 地址空间。

    默认值 :
    netnum = {
      admin   = 33
      bastion = 32
      int_lb  = 16
      pub_lb  = 17
      workers = 1
    }
    
    newbits = {
      admin   = 13
      bastion = 13
      lb      = 11
      workers = 2
    }
    如果将这些变量保留为默认值并将 10.0.0.0/16 指定为 VCN 的 CIDR 范围,则 Terraform 函数 cidrsubnet() 会计算子网的以下 CIDR 前缀。可用地址显示在括号中。请注意,子网中的前两个地址和最后一个地址是网络服务保留的地址。
    • 基本子网:10.0.1.0/29(可用地址:10.0.1.210.0.1.6;即 5 台主机)
    • 管理子网:10.0.1.8/2910.0.1.1010.0.1.14;5 台主机)
    • 内部负载平衡器子网:10.0.2.0/2710.0.2.210.0.2.30;29 个节点)
    • 公共负载平衡器子网 : 10.0.2.32/2710.0.2.3410.0.2.62; 29 个节点)
    • Kubernetes worker 节点子网:10.0.64.0/1810.0.64.210.0.127.254;16381 节点)

    如果您需要使用与默认设置不同的地址或大小的子网,则应确定 newbitsnetnum 的适当值。为此,必须了解有关不少量 IP 地址的基本知识。另请参阅 cidrsubnet() 函数的 Terraform 文档。

    请确保在此处指定的 CIDR 块与为 Kubernetes pods (pods_cidr)指定的 CIDR 块不重叠。

    service_gateway_enabled 指定 true 为 VCN 创建服务网关。

    如果 VCN 中的计算实例需要访问Oracle Cloud Infrastructure 对象存储等其他 Oracle 服务,则需要提供服务网关。

    vcn_cidr 您为 VCN 选择的 IPv4 CIDR 块。

    默认值为 10.0.0.0/16。允许的范围为 /16/30

    请确保您在此处指定的 CIDR 块与您为 Kubernetes 服务(services_cidr)指定的 CIDR 块不重叠。

    vcn_dns_label VCN 的内部 DNS 名称的名称前缀。

    在此处指定的名称将添加前缀为 oraclevcn.com,以形成 VCN 的 DNS 域名。例如,如果将 oke 指定为前缀,则 VCN 的 DNS 域名将为 oke.oraclevcn.com

    vcn_name VCN 资源的名称。
    bastion_access 必须允许来自其对基础设施进行 SSH 访问的 IP 地址范围(采用 CIDR 表示法)。

    要允许从任何主机(即 0.0.0.0/0)进行 SSH 访问,请将变量保留为默认值 ANYWHERE

    bastion_enabled 指定 true 可创建基础主机。
    bastion_image_id 要用于创建基础主机的映像的 OCID。

    如果您将此变量保留在默认值 NONE,则将使用 Oracle 自治 Linux 映像。

    bastion_notification_enabled 应用更新或者 Oracle Ksplice 检测到已知的 exploit 尝试时,可以使用Oracle Cloud Infrastructure Notification 服务从 bastion 主机接收状态消息。
    指定 true 可允许为基本主机发送通知。

    注 :

    仅当使用默认 Oracle Autonomous Linux 映像时,此解决方案中的 Terraform 代码才会为 bastion 主机配置通知。
    bastion_notification_endpoint 应将通知发送到的电子邮件地址。如果将 bastion_notification_enabled 设置为 true,则此变量是必需的。
    bastion_notification_protocol 将此变量设置为 EMAIL
    bastion_notification_topic 要创建的通知话题的名称。如果将 bastion_notification_enabled 设置为 true,则此变量是必需的。
    bastion_package_upgrade 如果希望在主机首次引导时升级 bastion 主机的安全程序包,请指定 true

    请注意,如果此变量设置为 true,则在预配基本主机后,在升级安全程序包的过程中,此变量将不可用。但启用此升级可以最大程度地减少 bastion 主机的漏洞。

    bastion_shape 要用于 bastion 主机的计算配置。
    bastion_timezone 以 IANA 时区格式(例如 America/Los_Angeles)为基本主机配置的时区。
    admin_enabled 指定 true 可创建管理主机。
    admin_image_id 要用于创建基础主机的映像的 OCID。

    如果将此变量保留为默认值 NONE,则会使用 Oracle 提供的 Linux 映像。

    admin_instance_principal 如果要使管理主机能够管理您指定的区间中的所有资源,请指定 true
    如果您打算运行 CLI 命令或从管理主机调用 API 来管理拓扑中的资源,请使用此功能。

    注 :

    任何可以使用 SSH 连接到计算实例的用户都会继承授予实例的实例委派权限。决定是否将管理主机指定为实例主用户时,请考虑这一点。可以随时关闭或打开此功能,而不会对管理主机造成任何影响。

    如果将此变量设置为 true,则管理主机将成为动态组的成员,并且会创建策略语句以允许动态组管理区间中的所有资源。

    admin_notification_enabled

    admin_notification_endpoint

    admin_notification_protocol

    admin_notification_topic

    将这些变量保留为默认值。当前在此 Terraform 代码中不支持为管理主机启用通知。
    admin_package_upgrade 如果希望在主机首次引导时升级管理主机的安全程序包,请指定 true

    请注意,如果此变量设置为 true,则在预配管理主机后,在升级安全程序包的同时,此变量将对短时段不可用。但启用此升级可将管理主机的漏洞最小化。

    admin_shape 要用于管理主机的计算配置。
    admin_timezone 以 IANA 时区格式(例如 America/Los_Angeles)为管理主机配置的时区。
    availability_domains 要在其中预配管理主机和基础主机的可用性域。

    例如,要在第二个可用性域中预配基本主机,请设置 bastion = 2

    如果指定的区域仅包含一个可用性域,则将此变量保留为默认值 1

    tagging 指定要分配给计算和网络资源的标记。
    allow_node_port_access 如果希望在公共模式下部署 Kubernetes worker 节点时允许 TCP 通信,请指定 true
    allow_worker_ssh_access 如果希望允许通过基础主机与 Kubernetes worker 节点建立 SSH 连接,请指定 true

    请注意,即使 worker 节点是以公共模式部署的,SSH 连接也必须通过 bastion 主机。

    如果将此变量设置为 true,则还必须设置 bastion_enabled = true

    cluster_name Kubernetes 集群的名称。
    dashboard_enabled 如果希望创建默认的 Kubernetes 仪表盘,请指定 true
    kubernetes_version 要用于 Worker 节点的 Kubernetes 版本。

    如果将此变量保留为默认值 LATEST,则会选择最新支持的版本。要使用特定版本,请指定该版本。

    node_pools 要创建的节点池数、每个池的大小以及要用于 Worker 节点的计算配置,格式如下:
    node_pools = {
      "np1" = ["computeShape", numberOfNodes]
      "np2" = ["computeShape", numberOfNodes]
      "np3" = ["computeShape", numberOfNodes]
      ...
    }
    • np1np2np3 是表示各个节点池的任意名称。
    • computeShape 是要用于池中员工节点的计算配置。
    • numberOfNodes 是要在池中创建的 Kubernetes 工作进程节点的数量。在每个池中最少创建三个节点,即使指定了较低值也是如此。
    以下示例针对的是包含两个池的群集,每个池使用不同的计算配置并包含不同数量的 Kubernetes worker 节点:
    node_pools = {
      "np1" = ["VM.Standard2.1", 3]
      "np2" = ["VM.Standard2.2", 5]
    }
    node_pool_name_prefix 节点池的名称前缀。

    通过连接 label_prefixnode_pool_name_prefix 和节点池编号的值来生成节点池的名称。例如,如果指定 label_prefix = "prod"node_pool_name_prefix = "np",则生成的节点池名称将为 prod-np-1prod-np-2prod-np-3 等等。

    node_pool_image_id 要用于 Kubernetes worker 节点的映像 OCID。

    如果将此变量保留为默认值 NONE,则会使用与为 node_pool_osnode_pool_os_version 指定的值匹配的图像。

    node_pool_os 应该用于 Kubernetes worker 节点的操作系统(例如 "Oracle Linux")。

    此设置仅在设置 node_pool_image_id = "NONE" 时考虑

    node_pool_os_version 应该用于 Kubernetes worker 节点的操作系统版本(例如 "7.7")。

    此设置仅在设置 node_pool_image_id = "NONE" 时考虑

    pods_cidr 您为 Kubernetes 云池选择的 IPv4 CIDR 块。

    请确保您在此处指定的 CIDR 块与您为 VCN (vcn_cidr)指定的 CIDR 块不重叠。

    services_cidr 您为 Kubernetes 云池选择的 IPv4 CIDR 块。

    请确保您在此处指定的 CIDR 块与您为 VCN (vcn_cidr)指定的 CIDR 块不重叠。

    worker_mode 如果必须能够从公共互联网访问员工节点,请指定 public。否则,请将此变量设置为 private

    如果设置了 worker_mode = "private",则设置 nat_gateway_enabled = true

    lb_subnet_typepreferred_lb_subnets lb_subnet_typepreferred_lb_subnets 指定的值确定您使用 LoadBalancer 类型的 Kubernetes 服务部署的任何负载平衡器节点所必须使用的子网类型。

    公共负载平衡器具有公共 IP 地址。内部负载平衡器仅具有专用 IP 地址,不能通过公共互联网访问。

    • 如果您打算使用公共负载平衡器,请将 preferred_lb_subnet = "public"subnet_type 设置为 "both""public"
    • 如果您打算使用内部负载平衡器,请将 preferred_lb_subnet = "internal"subnet_type 设置为 "both""internal"

      即使将负载平衡器子网设置为内部,当您创建内部负载平衡器服务时,也必须设置适当的注释(如 service.beta.kubernetes.io/oci-load-balancer-internal: "true")。Merely 将子网设置为专用不足。

      有关创建内部负载平衡器的信息,请参阅Oracle Cloud Infrastructure 文档。

    secret_id Oracle Cloud Infrastructure Vault 服务中密钥的 ID,用于从 Oracle Cloud Infrastructure Registry 提取应用程序映像的验证标记存储在此处。
    还必须设置以下内容:
    bastion_enabled = true
    admin_enabled = true
    admin_instance_principal = true
    email_address 在生成 Docker 密钥时使用的电子邮件地址。电子邮件地址是必需的,但与指定的地址无关。

    如果指定 secret_id,则此变量是必需的。

    tenancy_name 包含注册表的租户的Oracle Cloud Infrastructure 对象存储名称空间 , 应从该注册表中提取映像以将部署到 Kubernetes 集群。

    如果指定 secret_id,则此变量是必需的。

    username 为其生成存储在 secret_id 中的验证标记的用户名。

    如果指定 secret_id,则此变量是必需的。

    install_helm 如果要安装 Helm,请指定 true

    Helm 是 Kubernetes 的一个程序包管理器。

    要安装 Helm,您还必须设置 admin_instance_principal = true

    helm_version 要安装的 Helm 客户机的版本。

    会自动升级 Tiller(平铺窗口的服务器端对应性)。

    install_calico 如果希望安装计量表,请指定 true

    对于部署到 Kubernetes 集群的容器工作量,可以使用 Calico 实施网络策略。

    如果设置了 install_calico = true,则还必须设置以下内容:
    bastion_enabled = true
    admin_enabled = true
    admin_instance_principal = true
    calico_version 要安装的计量表的版本。
    install_metricserver 如果希望安装 Kubernetes Metrics Server, 请指定 true

    默认情况下,最新版本安装在 kube-system 名称空间中。Kubernetes Metrics 服务器聚集集集群中的资源使用情况数据。

    如果设置了 install_metricserver = true,则还必须设置以下内容:
    bastion_enabled = true
    admin_enabled = true
    admin_instance_principal = true
    use_encryption 如果要使用 Oracle Cloud Infrastructure Vault 服务对 Kubernetes 密钥进行加密,请将此变量设置为 true
    如果设置了 use_encryption = true,则还必须设置以下内容:
    bastion_enabled = true
    admin_enabled = true
    admin_instance_principal = true
    existing_key_id 在 Oracle Cloud Infrastructure Vault 服务中创建的现有密钥的 OCID。

    如果将 use_encryption 设置为 true,则此变量是必需的。

    create_service_account 如果您希望外部进程和工具(例如连续集成/CD 管道)访问该集群,则将此变量设置为 true。使用自己的验证标记创建服务帐户。
    如果设置了 create_service_account = true,则还必须设置以下内容:
    bastion_enabled = true
    admin_enabled = true
    admin_instance_principal = true
    service_account_name 要创建的服务帐户的名称。
    service_account_namespace 应在其中创建帐户的 Kubernetes 名称空间。
    service_account_cluster_role_binding 服务帐户的集群角色绑定的名称。

    下面是一个已完成的 terraform.tfvars 文件示例。

    # Identity and access parameters
    
    api_fingerprint = "d4:dc:...(truncated)"
    
    api_private_key_path = "/home/joe/.oci/oci_api_key.pem"
    
    compartment_id = "ocid1.compartment.oc1..aaaaaaaaxxx... (truncated)"
    
    tenancy_id = "ocid1.tenancy.oc1..aaaaaaaaxxx... (truncated)"
    
    user_id = "ocid1.user.oc1..aaaaaaaaxxx... (truncated)"
    
    ssh_private_key_path = "/home/joe/.ssh/id_rsa"
    
    ssh_public_key_path = "/home/joe/.ssh/id_rsa.pub"
    
    # general oci parameters
    label_prefix = "prod"
    
    region = "us-phoenix-1"
    
    # networking
    
    nat_gateway_enabled = true
    
    netnum = {
      admin   = 33
      bastion = 32
      int_lb  = 16
      pub_lb  = 17
      workers = 1
    }
    
    newbits = {
      admin   = 13
      bastion = 13
      lb      = 11
      workers = 2
    }
    
    service_gateway_enabled = true
    
    vcn_cidr = "10.0.0.0/16"
    
    vcn_dns_label = "oke"
    
    vcn_name = "oke vcn"
    
    # bastion
    
    bastion_access = "ANYWHERE"
    
    bastion_enabled = true
    
    bastion_image_id = "NONE"
    
    bastion_notification_enabled = true
    
    bastion_notification_endpoint = "joe@example.com"
    
    bastion_notification_protocol = "EMAIL"
    
    bastion_notification_topic = "bastion_server_notification"
    
    bastion_package_upgrade = true
    
    bastion_shape = "VM.Standard.E2.1"
    
    bastion_timezone = "America/Los_Angeles"
    
    admin_enabled = true
    
    admin_image_id = "NONE"
    
    admin_instance_principal = true
    
    admin_notification_enabled = false
    
    admin_notification_endpoint = "joe@example.com"
    
    admin_notification_protocol = "EMAIL"
    
    admin_notification_topic = "admin_server_notification"
    
    admin_package_upgrade = true
    
    admin_shape = "VM.Standard.E2.1"
    
    admin_timezone = "America/Los_Angeles"
    
    # availability_domains
    
    availability_domains = {
      bastion = 1
      admin   = 1
    }
    
    tagging = {
      computetag = {"Environment" = "dev" }
      networktag = { "Name" = "network" }
    }
    
    # oke
    
    allow_node_port_access = false
    
    allow_worker_ssh_access = false
    
    cluster_name = "oke"
    
    dashboard_enabled = true
    
    kubernetes_version = "LATEST"
    
    node_pools = {
      np1 = ["VM.Standard2.1", 3]
      #np2 = ["VM.Standard2.8", 4]
      #np3 = ["VM.Standard1.4", 5]
    }
    
    node_pool_name_prefix = "np"
    
    node_pool_image_id = "NONE"
    
    node_pool_os = "Oracle Linux"
    
    node_pool_os_version = "7.7"
    
    pods_cidr = "10.244.0.0/16"
    
    services_cidr = "10.96.0.0/16"
    
    worker_mode = "private"
    
    # oke load balancers
    
    lb_subnet_type = "public"
    
    preferred_lb_subnets = "public"
    
    # ocir
    
    secret_ocid = "ocid1.key.oc1..aaaaaaaaxxx... (truncated)"
    
    email_address = "joe@example.com"
    
    tenancy_name = "mytenancy"
    
    username = "joe_k8s_admin"
    
    # helm
    
    helm_version = "3.0.0"
    
    install_helm = false
    
    # calico
    
    calico_version = "3.9"
    
    install_calico = false
    
    # metrics server
    
    install_metricserver = false
    
    use_encryption = false
    
    existing_key_id = ""
    
    # service accountcreate_service_account = true
    service_account_name = "kubeconfigsa"
    service_account_namespace = "kube-system"
    service_account_cluster_role_binding = "myapps-manage-binding"
  5. 保存并关闭 terraform.tfvars