使用packer和terraform进行云基础设施的自动化部署

介绍

packer和terraform都是HashiCorp公司的产品,packer是个开源工具,用于构建虚机模板。他们的理念是INFRASTRUCTURE AS CODE,以code的方式来搭建基础架构。诚然各个云平台,从aws到微软的azure到阿里云,都提供了各自的工具来创建虚机模板。而packer提供给我们的是一个相对统一的工具,通过代码格式定义模板,然后作用于各个云平台。此篇文字记录了试用的过程以及踩过的坑。

目的

基于vmware的vsphere平台,构建自动化部署搭建环境所需要的虚机。

实践

- 创建ubuntu18.04模板

通过json文件来定义模板,创建文件ubuntu18.04,其中主要分builders,provisioners和variables三个部分,builders中用来定义虚机模板的硬件配置,网络配置等信息。provisioners用于处理预安装软件的情形,variables则定义变量。以下是一个例子,省略了部分信息。


{
  "builders": [
  {
    "type": "vsphere-iso",
    
    "vcenter_server": "{{user `vcenter-server`}}",
    "username": "{{user `vcenter-username`}}",
    "password": "{{user `vcenter-password`}}",
    ###省略
    "ssh_username": "{{user `ssh-username`}}",
    "ssh_password": "{{user `ssh-password`}}",  
    
    "vm_name": "{{user `vm-name`}}",
    "convert_to_template": "true",
      
    "network_adapters": [
        {
          "network": "{{user `network`}}",
          "network_card": "vmxnet3"
        }
    ],
    ###省略
    "iso_paths": [
        "{{user `os_iso_path`}}"
    ],
    "floppy_files": [
        "./ubuntu/preseed.cfg"
     ],
     "http_directory": ".",
     "boot_command": [
          "",
          "",
          "",
          "",
          "",
          "",
          "",
          "",
          "",
          "",
          "/install/vmlinuz",
          " initrd=/install/initrd.gz",
          " priority=critical",
          " locale=en_US",
          " file=/media/preseed.cfg",
          ""
      ] 
  }
  ],  
     
  "provisioners": [
    {
      "type": "file",
      "sources": ["./ubuntu/containerd.io.deb","./ubuntu/docker-ce.deb","./ubuntu/docker-ce-cli.deb","./ubuntu/docker-compose-Linux-x86_64"],
      "destination": "/tmp/"
    },
   {
      "type": "shell",
      "inline": [
          "echo '{{user `ssh-password`}}' | sudo -S sh -c 'dpkg -i /tmp/containerd.io.deb /tmp/docker-ce.deb /tmp/docker-ce-cli.deb'",
          "echo '{{user `ssh-password`}}' | sudo -S sh -c 'usermod -aG docker witadmin'",
          "echo '{{user `ssh-password`}}' | sudo -S sh -c 'sudo mv /tmp/docker-compose-Linux-x86_64 /usr/local/bin/docker-compose'",
          "echo '{{user `ssh-password`}}' | sudo -S sh -c 'sudo chmod +x /usr/local/bin/docker-compose'",
          "echo 'Packer Template Build -- Complete'"
          ]   
   }  
  ],
  
  "variables": 
  {
    "vm-name": "Ubuntu-1804-Template",
    "datacenter": "DC",
    ###省略
    "os_iso_path": "[datastore1] iso/ubuntu-18.04.5-server-amd64.iso"
  }
} 
    

对于其中比较重要的解释一下:

  • type 用于定义类型,这里我们用的vsphere-iso,packer工具会使用vsphere-iso的provider进行工作,其调用vspshere api进行实际操控。
  • iso_paths 定义iso文件的路径,这里可以指向exsi上存储的某个iso文件,在variables部分可以看到
  • floppy_files 这里的内容会作为一个软盘挂载到虚机中,可能知道软盘,见过软盘的同学已经都转行了吧,哈哈。软盘有容量限制,超过1.44M会报失败,所以这里合适的是放一些需要自动执行的脚本文件。
  • http_directory packer在运行过程中,会启用一个http服务器,这里指定的就是http服务器的根路径,这里适合放需要抓取的内容或者通过http可访问的内容
  • boot_command 启动命令,这里要注意的是file=/media/preseed.cfg指明了自动应答文件,通过这个文件,可以让ubuntu18无人值守自动安装,具体内容格式参考ubuntu官方文档。

provisioners部分定义需要预安装/处理的内容

  • "type": "file" 这里定义需要上传的文件,因为一般权限是非root用户,所以针对linux,最好是将文件都上传到/tmp目录
  • "type": "shell" 这里定义执行的命令,我这里是把docker和docker-compose默认安装了。由于使用的是ubuntu系统,非root用户,当需要用到sudo权限的时候,这里需要小技巧传入sudo 的密码后执行。

创建模板

执行命令

packer.exe build ubuntu\ubuntu18.json

packer会连接vsphere,等待10分钟,即可创好虚机并自动转换为模板。注意网络中需要有DHCP服务器,因为packer会等待创建的虚机获得IP,然后才能通过ssh或者powershell(windows虚机)进行后面的动作,否则会创建失败。

创建虚机

有了模板,下一步可以根据模板来创建虚机了。terraform是我们要使用的工具,可以先定义好我们需要的虚机的各个方面,即一个蓝图,然后统一来执行。
用到的文件包括以下几个:

  • main.tf 定义虚机
  • varable.tf 定义用到的变量
  • terraform.tfvars 定义变量的值,如果这里没有,运行时就会询问用户输入
  • output.tf 定义输出的执行计划中关键项,会高亮显示(如果终端支持高亮)

看一个 main.tf的例子

provider "vsphere" {
  user           = var.vsphere_user
  password       = var.vsphere_password
  vsphere_server = var.vsphere_server

  # If you have a self-signed cert
  allow_unverified_ssl = true
}

##### Data sources
data "vsphere_datacenter" "target_dc" {
  name = var.vsphere_datacenter
}

data "vsphere_datastore" "target_datastore" {
  name          = var.vsphere_datastore
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

data "vsphere_compute_cluster" "target_cluster" {
  name          = var.vsphere_cluster
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

data "vsphere_network" "target_network" {
  name          = var.vsphere_network
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

data "vsphere_virtual_machine" "source_template" {
  name          = var.guest_template
  datacenter_id = data.vsphere_datacenter.target_dc.id
}

resource "vsphere_virtual_machine" "witith01" {
  name             = "WiTiTH01"
  resource_pool_id = data.vsphere_compute_cluster.target_cluster.resource_pool_id
  datastore_id     = data.vsphere_datastore.target_datastore.id

  num_cpus = 2
  memory   = 1024
  guest_id = data.vsphere_virtual_machine.source_template.guest_id
  scsi_type = data.vsphere_virtual_machine.source_template.scsi_type
  
  network_interface {
    network_id = data.vsphere_network.target_network.id
    adapter_type = data.vsphere_virtual_machine.source_template.network_interface_types[0]
  }

  disk {
    label = "disk0"
    size  = 20
    eagerly_scrub    = data.vsphere_virtual_machine.source_template.disks[0].eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.source_template.disks[0].thin_provisioned   
  }
  
  clone {
    template_uuid = data.vsphere_virtual_machine.source_template.id

    customize {
      timeout = "20"
      linux_options {
        host_name = "WiTiTH01"
        domain    = var.guest_domain
      }

      network_interface {
        ipv4_address = var.guest_ipv4_ith01
        ipv4_netmask = 24
      }

      ipv4_gateway    = var.guest_ipv4_gateway
      dns_server_list = [var.guest_dns_servers]
    }
  }  
}
  • provider 指明了我们是用vsphere
  • data 项定义了vsphere中的信息
  • resource 定义了具体的虚机,指明了从哪个模板克隆

一般定义文件都是放在一个文件夹中,都定义好以后,可以通过命令初始化

terraform.exe init

这个一个项目只需运行一次,terraform会去下载vsphere的provider,就像nodejs项目的init类似

然后生成执行计划

terraform.exe plan -out ./test.out

这一步会检查并显示输出具体的计划,确认无误了就可以应用了

terraform.exe apply ./test.out

然后terraform就会去连接vsphere帮你创建虚机了。

坑爹的事情来了,我在创建虚机时,报错,虚机创建出来了,但是customize 失败,自定义项完全没有应用上去,虚机的network都没有,主机名也没变。花了一晚上的时间找原因。通过无数次比较,发现手动创建的ubuntu18模板没问题,而通过packer创建的模板就有问题。再查看虚机的日志,发现有问题的虚机会报错,缺少模块 File/stat.pm. 搜索得知,open-vm-tools 开源工具需要这个文件,在ubuntu下对应的包是perl-modules-5.26, 一看出问题的虚机上果然没有。从模板就没有。
所以,在packer制作模板时就要加上这个包,具体方法可以定义在preseed.cfg文件里面,指明安装

d-i pkgsel/include string open-vm-tools openssh-server vim wget curl python perl-modules-5.26

重新制作模板后,测试通过,可快速创建虚机。

最终效果,创建模板花了10分钟,创建3台ubuntu虚机花了2分钟,下一步就是将业务软件的安装全自动化,这又是另一个故事了。

你可能感兴趣的:(使用packer和terraform进行云基础设施的自动化部署)