最近在调研terraform。总结一下,Terraform是IT 基础架构自动化编排工具,从上层的软件配置到底层的网络、系统配置都可以使用 Terraform 统一进行管理。
与 Terraform 类似的 Infrastructure as Code 工具大概有下面几种:Chef、Puppet、Ansible、SaltStack、CloudFormation。
配置管理工具与编排工具
Chef、Puppet、Ansible、SaltStack 都可以称为配置管理工具,这些工具的主要目标是在已经存在的机器上安装和管理软件。
而 Terraform 和 CloudFormation 可以称为编排工具,更注重于数据中心以及相关服务的高级抽象。他们的工作重点是创建资源并且引导进行初始化。
比较表格
名词解释,provider:供应商,类似阿里云,resource:供应商提供的资源,Provisioners:用于对资源做配置管理
由于我没有云平台,这里用docker作为provider模拟了下搭建mysql和mycat的集群,这里mycat属于resource,所以这里打包了一个mycat的docker镜像。
dockerfile如下
FROM centos:7
ENV JAVA_HOME /usr/local/jdk1.8.0_20
ENV CLASSPATH ${JAVA_HOME}/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:${JAVA_HOME}/bin
ENV MYCAT_HOME /usr/local/mycat
ENV MYCAT_CONF /usr/local/mycat/conf
COPY jdk-8u20-linux-x64.tar.gz Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz /usr/local/
RUN cd /usr/local/ && tar -xzvf jdk-8u20-linux-x64.tar.gz && \
tar -xzvf Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz && \
rm -f jdk-8u20-linux-x64.tar.gz Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz && \
mkdir -p mycat/logs
VOLUME ${MYCAT_CONF}
EXPOSE 8066 9066
CMD ${MYCAT_HOME}/bin/mycat start && sleep 1 && tail -f ${MYCAT_HOME}/logs/mycat.log
mycat的迁移部署,只要复制conf配置文件夹就可以了,只要修改下schema.xml中datahost的ip和端口。
记录下mycat、mysql部署遇到的问题
1.日志报Unknown charsetIndex:255
因为我MYSQL默认使用的是utf8mb4,所以修改mycat字符集的配置文件#vi index_to_charset.properties 在配置文件最后加入255=utf8mb4,重启服务即正常
2.MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
3.将mycat部署完成之后,处于正常运行的状态下,使用mysql8.0客户端版本登陆mycat,经过多次登陆访问,都是无法访问,提示密码错误(Access denied for user 'user', because password is error)
由于mycat1.6.5仅支持mysql_native_password认证,而8.0的客户端连接mycat1.6.7.1使用"caching_sha2_password"机制,mysql -h172.18.8.40 -P8066 -ubrain -pbrain66666 --default-auth=mysql_native_password 后面指定方式就可以了
部署的main.tf和variables.tf如下:
main.tf
provider "docker" {
host = "unix:///var/run/docker.sock"
}
resource "docker_container" "mycat" {
name = "mycat"
image = "mycat:1.6.7.1"
hostname = "mycat"
publish_all_ports = true
networks_advanced {
name = "${docker_network.private_network.name}"
}
volumes {
host_path = "${var.mycat_config}"
container_path = "/usr/local/mycat/conf"
}
ports {
internal = 8066
external = 8066
}
}
resource "docker_container" "mysql_node1" {
name = "mysql_node1"
image = "${docker_image.mysq.latest}"
env = ["MYSQL_ROOT_PASSWORD=${var.root_password}"]
hostname = "mysql_node1"
networks_advanced {
name = "${docker_network.private_network.name}"
}
upload {
content = "${var.node1_sql}"
file = "/docker-entrypoint-initdb.d/create.sql"
executable = true
}
}
resource "docker_container" "mysql_node2" {
name = "mysql_node2"
image = "${docker_image.mysq.latest}"
env = ["MYSQL_ROOT_PASSWORD=${var.root_password}"]
hostname = "mysql_node2"
networks_advanced {
name = "${docker_network.private_network.name}"
}
upload {
content = "${var.node2_sql}"
file = "/docker-entrypoint-initdb.d/create.sql"
executable = true
}
}
resource "docker_image" "mysq" {
name = "mysql:latest"
keep_locally = true
}
resource "docker_network" "private_network" {
name = "mysql_network"
}
variables.tf
variable "node1_sql" {
default = <<-EOF
alter user root IDENTIFIED WITH mysql_native_password BY '123456';
CREATE DATABASE IF NOT EXISTS db1 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
CREATE DATABASE IF NOT EXISTS db2 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
use db1;
create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int);
use db2;
create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int);
EOF
}
variable "node2_sql" {
default = <<-EOF
alter user root IDENTIFIED WITH mysql_native_password BY '123456';
CREATE DATABASE IF NOT EXISTS db3 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
use db3;
create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int);
EOF
}
variable "root_password" {
default = "123456"
}
variable "mycat_config" {
default = "/mycat_docker/conf"
}
mycat的schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
</schema>
<dataNode name="dn1" dataHost="datahost1" database="db1" />
<dataNode name="dn2" dataHost="datahost1" database="db2" />
<dataNode name="dn3" dataHost="datahost2" database="db3" />
<dataHost name="datahost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="mysql_node1" url="mysql_node1:3306" user="root"
password="123456">
</writeHost>
</dataHost>
<dataHost name="datahost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="mysql_node2" url="mysql_node2:3306" user="root"
password="123456">
</writeHost>
</dataHost>
</mycat:schema>
terraform apply起来后,往mycat插3条数据
insert into travelrecord(id,user_id,traveldate,fee,days) values(1,'Victor',20160101,100,10);
insert into travelrecord(id,user_id,traveldate,fee,days) values(5000001,'Job',20160102,100,10);
insert into travelrecord(id,user_id,traveldate,fee,days) values(10000001,'Slow',20160103,100,10);
看到mysql后台已经自动分片了