Terraform 部署容器服务Kubernetes集群及Wordpress应用

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文档介绍了如何通过 Terraform 在 VPC 环境下部署一个阿里云容器服务 Kubernetes 集群,并在该集群之上,部署一个 WordPress 样例应用。本文档提供一种构建阿里云基础设施的解决方案,让您通过代码来自动创建、编排和管理容器服务以及完成在容器集群上应用的自动化部署。

本文档介绍了如何通过 Terraform 在 VPC 环境下部署一个阿里云容器服务 Kubernetes 集群,并在该集群之上,部署一个 WordPress 样例应用。本文档提供一种构建阿里云基础设施的解决方案,让您通过代码来自动创建、编排和管理容器服务以及完成在容器集群上应用的自动化部署。

前提条件

  • 需要开通阿里云容器服务,用户的账户需有 100 元余额并通过实名认证。
  • 需要启用用户账号的 AccessKey,妥善保存和记录 AccessKey ID 和 AccessKey Secret。

步骤 1 安装 Terraform

详细信息参见 Terraform 部署容器服务Swarm集群及Wordpress应用

除了下载 Terraform 和阿里云的 Terraform Provider 之外,在运行 Wordpress 的模板之前,需要在 Kubernetes Terraform Provider 官方下载地址 下载对应版本和平台的 Provider。

步骤 2 下载容器服务 Kubernetes 的 Terraform 模板

您可以从 GitHub 上下载创建 Kubernetes 集群的 Terraform 模板(模板下载地址)。该模板文件定义了创建 Kubernetes 集群的相关资源,帮助您完成 Kubernetes 集群的快速创建和 Kube Config 的自动下载。

模板中包含以下文件。

main.tf

Terraform 主文件。定义了将要部署的资源。本模版加入了条件判断,可实现对已有网络资源的引用和多个 Kubernetes 集群的同时创建。

  • 地域

定义了资源将要被创建在哪个地域里。

provider "alicloud" {
  access_key = "${var.alicloud_access_key}"
  secret_key = "${var.alicloud_secret_key}"
  region = "${var.region}"
}
  • VPC

    指定 vpc_id 可使用已有 VPC。

    resource "alicloud_vpc" "vpc" {
      count = "${var.vpc_id == "" ? 1 : 0}"
      cidr_block = "${var.vpc_cidr}"
      name = "${var.vpc_name == "" ? var.example_name : var.vpc_name}"
    }
  • VSwitch

    指定 vswitch_ids 可使用已有 VSwitch。

    resource "alicloud_vswitch" "vswitches" {
      count = "${length(var.vswitch_ids) > 0 ? 0 : length(var.vswitch_cidrs)}"
      vpc_id = "${var.vpc_id == "" ? join("", alicloud_vpc.vpc.*.id) : var.vpc_id}"
      cidr_block = "${element(var.vswitch_cidrs, count.index)}"
      availability_zone = "${lookup(data.alicloud_zones.default.zones[count.index%length(data.alicloud_zones.default.zones)], "id")}"
      name = "${var.vswitch_name_prefix == "" ? format("%s-%s", var.example_name, format(var.number_format, count.index+1)) : format("%s-%s", var.vswitch_name_prefix, format(var.number_format, count.index+1))}"
    }
  • Nat Gateway

    指定 new_nat_gateway 来决定是否要为模板中定义的 VPC 自动创建 Nat Gateway,以保证 Kubernetes 集群成功创建。

    resource "alicloud_nat_gateway" "default" {
      count = "${var.new_nat_gateway == true ? 1 : 0}"
      vpc_id = "${var.vpc_id == "" ? join("", alicloud_vpc.vpc.*.id) : var.vpc_id}"
      name = "${var.example_name}"
    }
  • EIP

    resource "alicloud_eip" "default" {
      count = "${var.new_nat_gateway == "true" ? 1 : 0}"
      bandwidth = 10
    }
    
  • EIP Association

    resource "alicloud_eip_association" "default" {
      count = "${var.new_nat_gateway == "true" ? 1 : 0}"
      allocation_id = "${alicloud_eip.default.id}"
      instance_id = "${alicloud_nat_gateway.default.id}"
    }
  • SNAT

    在模板中定义的 Nat Gateway 下自动添加 SNAT Entry 来保证 Kubernetes 集群成功创建。

    
    resource "alicloud_snat_entry" "default"{
      count = "${var.new_nat_gateway == "false" ? 0 : length(var.vswitch_ids) > 0 ? length(var.vswitch_ids) : length(var.vswitch_cidrs)}"
      snat_table_id = "${alicloud_nat_gateway.default.snat_table_ids}"
      source_vswitch_id = "${length(var.vswitch_ids) > 0 ? element(split(",", join(",", var.vswitch_ids)), count.index%length(split(",", join(",", var.vswitch_ids)))) : length(var.vswitch_cidrs) < 1 ? "" : element(split(",", join(",", alicloud_vswitch.vswitches.*.id)), count.index%length(split(",", join(",", alicloud_vswitch.vswitches.*.id))))}"
      snat_ip = "${alicloud_eip.default.ip_address}"
    }
  • 容器服务 Kubernetes 集群

    改变 k8s_number 的值可同时创建多个 Kubernetes 集群。

    resource "alicloud_cs_kubernetes" "k8s" {
      count = "${var.k8s_number}"
      name = "${var.k8s_name_prefix == "" ? format("%s-%s", var.example_name, format(var.number_format, count.index+1)) : format("%s-%s", var.k8s_name_prefix, format(var.number_format, count.index+1))}"
      vswitch_id = "${length(var.vswitch_ids) > 0 ? element(split(",", join(",", var.vswitch_ids)), count.index%length(split(",", join(",", var.vswitch_ids)))) : length(var.vswitch_cidrs) < 1 ? "" : element(split(",", join(",", alicloud_vswitch.vswitches.*.id)), count.index%length(split(",", join(",", alicloud_vswitch.vswitches.*.id))))}"
      new_nat_gateway = false
      master_instance_type = "${var.master_instance_type == "" ? data.alicloud_instance_types.default.instance_types.0.id : var.master_instance_type}"
      worker_instance_type = "${var.worker_instance_type == "" ? data.alicloud_instance_types.default.instance_types.0.id : var.worker_instance_type}"
      worker_number = "${var.k8s_worker_number}"
      master_disk_category = "${var.master_disk_category}"
      worker_disk_category = "${var.worker_disk_category}"
      master_disk_size = "${var.master_disk_size}"
      worker_disk_size = "${var.master_disk_size}"
      password = "${var.ecs_password}"
      pod_cidr = "${var.k8s_pod_cidr}"
      service_cidr = "${var.k8s_service_cidr}"
      enable_ssh = true
      install_cloud_monitor = true
    
      depends_on = ["alicloud_snat_entry.default"]
    }
    
    ## 注意:指定 kube_config = "~/.kube/config" 可在 Kubernetes 集群创建完成后将 Kube Config 内容自动下载并存放在文件 `~/.kube/cofig` 中。

outputs.tf

该文件定义了输出参数。作为执行的一部分而创建的资源会生成这些输出参数。和 ROS 模板指定的输出参数类似。例如,该模板将部署一个 Kubernetes 集群。以下输出参数将提供集群 ID 和其他资源参数。

output "cluster_id" {
  value = "${alicloud_cs_swarm.cs_vpc.id}"
}

variables.tf

该文件包含可传递到 main.tf 的变量,可帮助您自定义环境。

variable "alicloud_access_key" {
  description = "The Alicloud Access Key ID to launch resources. Support to environment 'ALICLOUD_ACCESS_KEY'."
}
variable "alicloud_secret_key" {
  description = "The Alicloud Access Secret Key to launch resources.  Support to environment 'ALICLOUD_SECRET_KEY'."
}
variable "region" {
  description = "The region to launch resources."
  default = "cn-hongkong"
}
variable "vpc_cidr" {
  description = "The cidr block used to launch a new vpc."
  default = "172.16.0.0/12"
}
variable "vswitch_cidrs" {
  description = "List of cidr blocks used to create several new vswitches when 'vswitch_ids' is not specified."
  type = "list"
  default = ["10.1.2.0/24"]
}
variable "k8s_number" {
  description = "The number of kubernetes cluster."
  default = 1
}
variable "k8s_worker_number" {
  description = "The number of worker nodes in each kubernetes cluster."
  default = 3
}

步骤 3 执行 Kubernetes Terraform 脚本

首先,定位到您存放以上文件的目录,如 /root/terraform/kuberneters。然后,您可以利用以下 terraform 的相关命令,运行脚本,构建容器集群和部署应用。更多的命令用法和介绍,参见 [Terraform 部署容器服务Kubernetes集群及Wordpress应用]() 和 Terraform Commands (CLI)

运行terraform apply 命令,开始创建 Kubernetes 集群。

$ terraform apply

data.alicloud_instance_types.default: Refreshing state...
data.alicloud_zones.default: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:
...

Plan: 7 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

alicloud_vpc.vpc: Creating...
...

Apply complete! Resources: 7 added, 0 changed, 0 destroyed.

Outputs:    ##注意

cluster_id = [
    c0f2e04c77e234******
]
......
vswitch_ids = [
    vsw-bp1c3hfcd6l80izqc3tbx
]

terraform apply 命令执行完毕后, 输出集群 ID 和其他参数。除此之外,将 Kubernetes 的 Kube Config 文件存放在了目录 ~/.kube 下。

您现在可以在容器服务控制台查看通过 terraform 创建的 Kubernetes 集群,查看集群信息、节点信息、日志信息和容器信息等信息。

image1

image2

步骤 4 下载 Wordpress 的 Terraform 模板

在创建好 Kubernetes 并完成了 Kube Config 的下载后,接下来就可以在 Kubernetes 上部署 Wordpress。 您可以从 GitHub 上下载创建 Wordpress 的 Terraform 模板(模板下载地址)。该模板文件是根据 Kubernetes Tutorials 编写的。模板中定义了创建 Wordpress 的相关资源和配置,帮助您完成在 Kubernetes 集群的快速搭建 Wordpress。

更多 Terraform Kubernetes 的操作可参考 Terraform 官网的 Kubernetes 文档介绍.

模板中包含以下文件。

localvolumes.tf

定义 Wordpress 和 Mysql 存储自己数据的 Persistent Volume。

  • Persistent Volume

    
    resource "kubernetes_persistent_volume" "mysql" {
      metadata {
        name = "local-pv-mysql"
        labels {
          type = "local"
        }
      }
      spec {
        capacity {
          storage = "20Gi"
        }
        access_modes = ["ReadWriteOnce"]
        persistent_volume_source {
          host_path {
            path = "/tmp/data/pv-mysql"
          }
        }
      }
    }

mysql.tf

创建 MySQL 密码 Secret,并部署 MySQL。

  • secret

    
    resource "kubernetes_secret" "mysql" {
      metadata {
        name = "mysql-pass"
      }
    
      data {
        password = "${var.mysql_password}"
      }
    }
  • Deployment

    
    resource "kubernetes_service" "mysql" {
      metadata {
        name = "wordpress-mysql"
        labels {
          app = "wordpress"
        }
      }
      spec {
        port {
          port = 3306
        }
        selector {
          app = "wordpress"
          tier = "${kubernetes_replication_controller.mysql.spec.0.selector.tier}"
        }
        cluster_ip = "None"
      }
    }
    
    resource "kubernetes_replication_controller" "mysql" {
      metadata {
        name = "wordpress-mysql"
        labels {
          app = "wordpress"
        }
      }
      spec {
        selector {
          app = "wordpress"
          tier = "mysql"
        }
        template {
          container {
            image = "mysql:${var.mysql_version}"
            name  = "mysql"
    
            env {
              name = "MYSQL_ROOT_PASSWORD"
              value_from {
                secret_key_ref {
                  name = "${kubernetes_secret.mysql.metadata.0.name}"
                  key = "password"
                }
              }
            }
    
            port {
              container_port = 3306
              name = "mysql"
            }
    
            volume_mount {
              name = "mysql-persistent-storage"
              mount_path = "/var/lib/mysql"
            }
          }
    
          volume {
            name = "mysql-persistent-storage"
            persistent_volume_claim {
              claim_name = "${kubernetes_persistent_volume_claim.mysql.metadata.0.name}"
            }
          }
        }
      }
    }

wordpress.tf

接下来部署 Wordpress。

  • Deployment

    
    resource "kubernetes_service" "wordpress" {
      metadata {
        name = "wordpress"
        labels {
          app = "wordpress"
        }
      }
      spec {
        port {
          port = 80
        }
        selector {
          app = "wordpress"
          tier = "${kubernetes_replication_controller.wordpress.spec.0.selector.tier}"
        }
        type = "LoadBalancer"
      }
    }
    
    
    resource "kubernetes_replication_controller" "wordpress" {
      metadata {
        name = "wordpress"
        labels {
          app = "wordpress"
        }
      }
      spec {
        selector {
          app = "wordpress"
          tier = "frontend"
        }
        template {
          container {
            image = "wordpress:${var.wordpress_version}-apache"
            name  = "wordpress"
    
            env {
              name = "WORDPRESS_DB_HOST"
              value = "wordpress-mysql"
            }
            env {
              name = "WORDPRESS_DB_PASSWORD"
              value_from {
                secret_key_ref {
                  name = "${kubernetes_secret.mysql.metadata.0.name}"
                  key = "password"
                }
              }
            }
    
            port {
              container_port = 80
              name = "wordpress"
            }
    
            volume_mount {
              name = "wordpress-persistent-storage"
              mount_path = "/var/www/html"
            }
          }
    
          volume {
            name = "wordpress-persistent-storage"
            persistent_volume_claim {
              claim_name = "${kubernetes_persistent_volume_claim.wordpress.metadata.0.name}"
            }
          }
        }
      }
    }

outputs.tf

该文件定义了输出参数。输出 Loadbalancer Public IP,借助该 IP 地址可直接访问部署好的 Wordpress 应用。

output "slb_ip" {
  value = "${kubernetes_service.wordpress.load_balancer_ingress.0.ip}"
}

variables.tf

该文件包含了部署 MySQL 和 WordPress 所依赖的参数。

variable "wordpress_version" {
  description = "The version of wordpress. Default to 4.7.3."
  default = "4.7.3"
}
variable "mysql_password" {
  description = "Please input mysql password."
}
variable "mysql_version" {
  description = "The version of mysql which wordpress used. Default to 5.6."
  default = "5.6"
}

步骤 5 执行 Wordpress Terraform 脚本

首先定位到您存放以上文件的目录,如 /root/terraform/kuberneters-wordpress。运行terraform apply 命令,开始在创建好的 Kubernetes 集群上部署 MySQL 和 WordPress 应用。

值得注意的是,由于变量 mysql_password 在变量文件中没有定义默认值,因此在执行命令是应输入参数值。

$ terraform apply -var 'mysql_password=Abc1234'

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:
...

Plan: 9 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

kubernetes_secret.mysql: Creating...
  data.%:                      "" => "1"
  data.password:               "<sensitive>" => "<sensitive>"
  metadata.#:                  "" => "1"
  metadata.0.generation:       "" => "<computed>"
  metadata.0.name:             "" => "mysql-pass"

......

Apply complete! Resources: 9 added, 0 changed, 0 destroyed.

Outputs:

slb_ip = 47.99.xx.xx

terraform apply 命令执行完毕后, 输出负载均衡 Public IP。

步骤 6 访问 WordPress

根据负载均衡 Public IP,运行如下命令或者直接在浏览器中输入 IP 地址即可实现对部署好的 Wordpress 直接访问:

open http://47.99.xx.xx
  1. 进入 WordPress 欢迎页面,可选择语言,然后继续配置。

image3

  1. 输入站点名称以及管理员的用户名和密码。选择安装 WordPress。

image4

  1. WordPress 安装完成后,单击 登录,输入管理员的用户名和密码,进入 WordPress 应用。

image5

延伸阅读

阿里云目前是 Terraform 官方的 Major Cloud Provider,如果您想通过 terraform 灵活构建阿里云上的基础设施资源,您可参见 Alicloud Provider 了解更多信息,自定义资源描述文件,快速搭建属于您的云上设施 。

相关实践学习
巧用云服务器ECS制作节日贺卡
本场景带您体验如何在一台CentOS 7操作系统的ECS实例上,通过搭建web服务器,上传源码到web容器,制作节日贺卡网页。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
23天前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
111 60
|
24天前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
145 62
|
20天前
|
运维 JavaScript 虚拟化
探索容器化技术:Docker的实践与应用
【10月更文挑战第9天】探索容器化技术:Docker的实践与应用
45 3
|
15天前
|
运维 JavaScript Linux
容器内的Nodejs应用如何获取宿主机的基础信息-系统、内存、cpu、启动时间,以及一个df -h的坑
本文介绍了如何在Docker容器内的Node.js应用中获取宿主机的基础信息,包括系统信息、内存使用情况、磁盘空间和启动时间等。核心思路是将宿主机的根目录挂载到容器,但需注意权限和安全问题。文章还提到了使用`df -P`替代`df -h`以获得一致性输出,避免解析错误。
|
17天前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
46 0
|
22天前
|
NoSQL 关系型数据库 Redis
高可用和性能:基于ACK部署Dify的最佳实践
本文介绍了基于阿里云容器服务ACK,部署高可用、可伸缩且具备高SLA的生产可用的Dify服务的详细解决方案。
|
23天前
|
运维 监控 Cloud Native
深入了解容器化技术:Docker 的应用与实践
【10月更文挑战第6天】深入了解容器化技术:Docker 的应用与实践
30 0
|
2月前
|
弹性计算 持续交付 API
基于 ROS 的Terraform托管服务轻松部署ChatGLM-6B
文章介绍了如何利用ROS和Terraform模板轻松自动化部署基于GLM架构、优化中文对话的ChatGLM-6B模型至阿里云,提高了部署效率与便捷性,适用于多种应用场景,且模型部署过程详细,彰显了基础设施即代码(IaC)的优势。
47 3
基于 ROS 的Terraform托管服务轻松部署ChatGLM-6B
|
2月前
|
弹性计算 人工智能 持续交付
基于 ROS 的Terraform托管服务轻松部署Qwen-7B-Chat
文章介绍了如何利用ROS和Terraform模板轻松自动化部署阿里云的Qwen-7B-Chat大语言模型服务,提高了部署效率与便捷性,是实现云资源和服务快速上线的最佳实践。
64 2
基于 ROS 的Terraform托管服务轻松部署Qwen-7B-Chat
|
5月前
|
弹性计算 API 持续交付
基于 ROS 的 Terraform 托管服务轻松部署文本转语音系统 ChatTTS
基于 IaC 的理念,通过定义一个模板,使用 ROS 提供的 Terraform 托管服务进行自动化部署,可以非常高效快捷地部署任意云资源和应用(比如 ChatTTS 服务)。相比于手动部署或者通过 API、SDK 的部署方式,有着高效、稳定等诸多优势,也是服务上云的最佳实践。
66 1
基于 ROS 的 Terraform 托管服务轻松部署文本转语音系统 ChatTTS

相关产品

  • 容器计算服务
  • 容器服务Kubernetes版