美文网首页
使用packer和terraform进行云基础设施的自动化部署

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

作者: wolfwolfgod | 来源:发表于2020-11-29 23:52 被阅读0次

    介绍

    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": [
              "<enter><wait><f6><wait><esc><wait>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs><bs><bs><bs><bs><bs><bs><bs>",
              "<bs><bs><bs>",
              "/install/vmlinuz",
              " initrd=/install/initrd.gz",
              " priority=critical",
              " locale=en_US",
              " file=/media/preseed.cfg",
              "<enter>"
          ] 
      }
      ],  
         
      "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进行云基础设施的自动化部署

          本文链接:https://www.haomeiwen.com/subject/jeqlwktx.html