跳转至

packer创建系统镜像

Packer 是由 HashiCorp 开发的开源工具,用于创建一致且可重复使用的机器映像。它支持多种平台,包括云服务提供商、虚拟化平台和容器。

主要特点

  1. 多平台支持:Packer 支持广泛的构建目标,包括 AWS、Azure、Google Cloud、VMware、VirtualBox、Docker 等。

  2. 模板驱动:使用 JSON 或 HCL(HashiCorp Configuration Language)定义模板,描述机器映像的配置和构建过程。

  3. 并行构建:Packer 可以同时为多个平台创建映像,提高效率。

  4. 可重复性:使用代码定义映像,可以确保每次构建的映像都一致。

  5. 扩展性:支持自定义的构建器、脚本和插件,可以根据需求进行扩展。

工作流程

  1. 定义模板:创建一个模板文件,描述映像的基础配置、构建步骤和安装的软件。

  2. 执行构建:运行 packer build 命令,Packer 根据模板创建并配置机器映像。

  3. 生成映像:Packer 将创建的映像保存到指定的平台上,如 AWS AMI、Docker 镜像等。

使用案例

  1. 开发和测试环境
  2. 快速创建开发和测试环境的一致性映像。

  3. 持续集成和持续交付(CI/CD)

  4. 在 CI/CD 流水线中集成 Packer,自动构建和发布映像。

  5. 跨平台部署

  6. 创建适用于多个云提供商和虚拟化平台的映像,实现跨平台部署。

示例模板(HCL)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
variable "aws_region" {
  default = "us-west-2"
}

source "amazon-ebs" "example" {
  ami_name      = "packer-example {{timestamp}}"
  instance_type = "t2.micro"
  region        = var.aws_region
  source_ami    = "ami-0c55b159cbfafe1f0"
  ssh_username  = "ec2-user"
}

build {
  sources = [
    "source.amazon-ebs.example"
  ]

  provisioner "shell" {
    inline = ["sudo yum install -y httpd"]
  }
}

如果需要运行脚本,只需要把上面的build部分的 provisioner换成 script 即可,如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "variables": {
    "aws_region": "us-west-2"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "ami_name": "packer-example {{timestamp}}",
      "instance_type": "t2.micro",
      "region": "{{user `aws_region`}}",
      "source_ami": "ami-0c55b159cbfafe1f0",
      "ssh_username": "ec2-user"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "script": "setup.sh"
    }
  ]
}

确保 setup.sh 文件在你的工作目录中,运行 Packer 构建命令:

1
2
packer init .
packer build template.pkr.hcl

当然如果不想写 HCL 文件,也可以写 JSON 模板文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "variables": {
    "aws_region": "us-west-2"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "ami_name": "packer-example {{timestamp}}",
      "instance_type": "t2.micro",
      "region": "{{user `aws_region`}}",
      "source_ami": "ami-0c55b159cbfafe1f0",
      "ssh_username": "ec2-user"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "script": "setup.sh"
    }
  ]
}

运行命令与 HCL 模板相同:

1
packer build template.json

部署脚本

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash

#安装mysql服务端
InstallMysql()
{
    #查询是否已经安装Mariadb,如果已经安装,则执行单独卸载有关软件包
    mariadb=`rpm -qa | grep mariadb` #执行指令用反引号
    if [ $mariadb ]; then
        rpm -e $mariadb --nodeps
    fi
    #安装wget工具和所需的库文件,以确保 MySQL 能够正常运行
    yum -y install wget
    yum -y install libaio
    #创建文件夹并下载 MySQL 8 的 RPM 包文件
    mkdir -p ./mysql
    wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.17-1.el7.x86_64.rpm-bundle.tar -O ./mysql/mysql.tar
    #进入目录,解压文件
    cd mysql
    tar -xvf mysql.tar
    #查询压缩包中相应的RPM软件包文件名
    common=`find . -name "mysql-community-common*"`
    libs=`find . -name "mysql-community-libs-8*"`
    client=`find . -name "mysql-community-client*"`
    server=`find . -name "mysql-community-server*"`
    #以顺序安装MySQL相应的共享库、客户端、服务组件,其中--force --nodeps命令行选项可确保成功安装MySQL
    rpm -ivh $common
    rpm -ivh $libs
    rpm -ivh $client
    rpm -ivh $server --force --nodeps
    #初始化 MySQL 数据库
    mysqld --initialize
    #修改MySQL数据库文件夹权限为mysql用户
    chown mysql:mysql /var/lib/mysql -R
    #启动 MySQL 服务
    systemctl start mysqld.service
    #将 MySQL 服务设置为开机启动状态
    systemctl enable mysqld
    #返回上级目录,结束安装过程
    cd ../
}

#安装Iptables,并配置防火墙规则
InstallIptables()
{
    #停止、禁用并屏蔽 firewalld 服务
    systemctl stop firewalld.service
    systemctl disable firewalld.service
    systemctl mask firewalld.service
    #安装 iptables-services 程序包
    yum -y install iptables-services
    systemctl enable iptables
    systemctl start iptables
    #删除阻塞预设端口的规则
    iptables="/etc/sysconfig/iptables"
    sed -i '/COMMIT/d' "$iptables"
    sed -i '/--dport 80 -j/d' "$iptables"
    sed -i '/--dport 3306/d' "$iptables"
    sed -i '/--dport 443/d' "$iptables"
    sed -i '/INPUT -j REJECT/d' "$iptables"
    sed -i '/FORWARD -j REJECT/d' "$iptables"
    #增加需要放行的端口规则
    echo "-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT">>$iptables
    echo "-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT">>$iptables
    echo "-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT">>$iptables
    echo "-A INPUT -j REJECT --reject-with icmp-host-prohibited">>$iptables
    echo "-A FORWARD -j REJECT --reject-with icmp-host-prohibited">>$iptables
    echo "COMMIT">>$iptables
    #重新启动 iptables 服务,并将其注册到系统初始化服务列表中
    systemctl restart iptables.service
    systemctl enable iptables.service
}

#配置 MySQL 数据库,创建必要的数据表等
Configure_mysql()
{
    #库名
    db="test_1"
    #获取默认密码
    initial_passwd=`cat /var/log/mysqld.log | grep password` #执行指令用反引号
    obtain_passwd=${initial_passwd#*localhost: } #冒号后面有个空格,需要注意
    #获取新密码
    new_passwd="123456"
    #把新密码写入临时的环境变量中,变量的名称不可修改,否则无法连接数据库
    export MYSQL_PWD=$new_passwd
    #1.连接数据库并修改密码
    mysql -uroot -p$obtain_passwd --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$new_passwd';"
    #1.在MySQL中创建一个名为root,允许从任何远程主机连接到该实例的用户,并将其密码设置为$new_passwd
    #2.授予MySQL中的root用户在任何数据库中执行所有操作的权限,包括创建和删除数据库、表、视图等,并赋予与该权限相关的GRANT OPTION选项
    #3.在MySQL中修改root用户的密码,并将其密码过期策略设置为“永不过期”
    #4.刷新MySQL权限缓存,以使最新的更改生效
    mysql -u root -e "create user 'root'@'%' identified with mysql_native_password by '$new_passwd';grant all privileges on *.* to 'root'@'%' with grant option;ALTER USER 'root'@'localhost' IDENTIFIED BY '$new_passwd' PASSWORD EXPIRE NEVER;flush privileges;"
    #新建数据库并导入库
    mysql -u root -e "create database $db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
    mysql -u root $db  < $db_file_path
}


#判断网络状态
if ! ping -c3 www.baidu.com &>/dev/null; then
    echo "无法连接互联网,请检查网络!"
    exit 1
fi

#判断文件是否存在
db_file_path="./test.sql"
if [ -e "$db_file_path" ]
then
    echo "数据库文件存在,开始安装..."
    InstallMysql
    InstallIptables
    Configure_mysql
else
    echo "数据库文件不存在"
    exit 1
fi

MySQL 8.x 获取root密码

shell脚本读取mysql用户名和密码文件:

1
2
cat /etc/mysql/debian.cnf
password=$(awk '/password/{if(NR>=1 && NR<=5)print $3}' /etc/mysql/debian.cnf)

mysql登录语句

1
mysql -u debian-sys-maint -p$password

使用脚本登录并操作mysql命令

1
2
3
4
mysql -u debian-sys-maint -p$password <<EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxxxxx';
quit
EOF

操作的shell脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash
password='123456'
Newpassword='xxxxxx'
password=$(awk '/password/{if(NR>=1 && NR<=5)print $3}' /etc/mysql/debian.cnf)
mysql -u debian-sys-maint -p$password <<EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxxxxx';
quit
EOF
mysql -h 127.0.0.1 -u root -p$Newpassword <<EOF
........(其他操作)
quit
EOF

总结

Packer 是一个功能强大的工具,适用于需要创建一致和可重复使用机器映像的各种场景。它的多平台支持、模板驱动和可扩展性使得它成为 DevOps 工具链中的重要组成部分。

捐赠本站(Donate)

weixin_pay
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))