在Docker环境中运行Terraform,并掌握基本操作(计划、应用、显示、销毁)
首先
因为工作上要使用Terraform,所以要学习Terraform的基本操作方法。
Terraform的博客文章,参考译文- Qiita
http://qiita.com/zembutsu/items/402e02950ce9d59fa0e6
Terraform入门日本语译文- Qiita
http://qiita.com/zembutsu/items/84f5478701c5391df537
环境( )
-
- Windows7
-
- VirtualBox V5.1.26
-
- Terraform v0.10.5
- docker 17.06.2-ce
1. 下载和安装
不需要额外的虚拟化层模块,只需将terraform引入到Windows或Linux中即可。但通过Docker Swarm、Kubernetes等工具可以实现以下功能,因此选择Docker版本。简单来说,无论是什么软件,如果没有特殊原因,我个人都会选择Docker版本。
1. 提高成本效益
– 在需要时自动添加或删除服务器
– 通过不使用不必要的资源来提高成本效益
2. 提高可用性
– 在多个可用区域设置自动扩展,即使一个可用区域无法使用,也可以在其他可用区域启动新实例
3. 提高容错能力
– 检测到服务器异常时,终止当前服务器并启动新服务器
在桌面上双击图标,启动Docker快速启动终端。按照这里的步骤执行docker pull命令。
$ docker pull hashicorp/terraform:light
$ docker pull hashicorp/terraform:full
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hashicorp/terraform full 57305292ab71 3 days ago 647.9 MB
hashicorp/terraform latest e84f3c7e4c2e 3 days ago 96.65 MB
$ docker run -it hashicorp/terraform:latest version
Terraform v0.10.5
$ docker run -it hashicorp/terraform:full version
Terraform v0.10.5
2. 版本选择
轻量版本(=标签为latest)和完整版本都可用,但由于想要登录到容器中,所以选择使用完整版本。两者的大小相差647.9MB和96.65MB。
确认了Dockerfile后发现,已经设置了ENTRYPOINT [“terraform”]。在轻量版本中,尝试将ENTRYPOINT覆盖为/bin/bash并启动容器,但却提示找不到文件或目录。轻量版本似乎是专注于执行terraform命令的容器。
FROM golang:alpine
MAINTAINER "HashiCorp Terraform Team <terraform@hashicorp.com>"
ENV TERRAFORM_VERSION=0.10.0
RUN apk add --update git bash openssh
ENV TF_DEV=true
ENV TF_RELEASE=true
WORKDIR $GOPATH/src/github.com/hashicorp/terraform
RUN git clone https://github.com/hashicorp/terraform.git ./ && \
git checkout v${TERRAFORM_VERSION} && \
/bin/bash scripts/build.sh
WORKDIR $GOPATH
ENTRYPOINT ["terraform"]
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.99.100:2376 v17.06.2-ce
$ docker-machine ssh default
docker@default:~$ sudo -s
root@default:/home/docker# docker run -it --entrypoint /bin/bash hashicorp/terraform:latest
docker: Error response from daemon: oci runtime error: container_linux.go:262: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory".
3. 預先準備
根据Terraform官方网站的指导,创建一个名为test01.tf的配置文件,并将其存储在虚拟机(主机操作系统/名称: default)上的/test01目录中。
root@default:~# mkdir /test01
root@default:~# cat /test01/test01.tf
provider "docker" {
host = "tcp://192.168.99.100:2376/"
}
resource "docker_container" "hoge" {
image = "${docker_image.centos.latest}"
name = "hoge"
hostname = "hoge"
command = ["/bin/sh", "-c", "while true ; do sleep 1; hostname -s ; done"]
}
resource "docker_image" "centos" {
name = "centos:latest"
}
在Unix环境中,可以设置unix域套接字(unix:///var/run/docker.sock)来操作主机。在这次的情况下,由Terraform运行的容器(= GuestOS)将在虚拟机(=HostOS/名字:default)上设置unix域套接字,因此也可以通过以下设置进行操作,但我选择了tcp://xxx。从docker容器内操作主机的docker- Qiita
此外,为了遵守以上注意事项,将与键相关的文件(=C:\ Users \ shimizu.docker \ machine \ machines \ default)存储在虚拟机(=HostOS / 名称:default)的 /test0上,这里是个棘手的地方。
对于docker-machine环境来说,Docker守护程序使用加密的TCP套接字(TLS)并要求cert_path进行成功连接。作为替代方案,如果使用docker-machine,在运行Terraform之前运行eval $(docker-machine env)命令,主机和证书路径将从环境中提取。
如果不考虑这一点,将输出错误消息”malformed HTTP response “\x15\x03\x01\x00\x02\x02″。
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.99.100:2376 v17.06.2-ce
$ docker-machine env default
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="C:\Users\shimizu\.docker\machine\machines\default"
export DOCKER_MACHINE_NAME="default"
# Run this command to configure your shell:
# eval $("C:\Program Files\Docker Toolbox\docker-machine.exe" env default)
root@default:/test01# ls -la /test01
total 36
drwxr-xr-x 3 root root 240 Sep 18 15:34 .
drwxr-xr-x 18 tc staff 440 Sep 18 14:32 ..
-rw-r--r-- 1 root root 1039 Sep 18 14:45 ca.pem
-rw-r--r-- 1 root root 1079 Sep 18 14:45 cert.pem
-rw-r--r-- 1 root root 1676 Sep 18 14:45 key.pem
-rw-r--r-- 1 root root 1680 Sep 18 14:46 server-key.pem
-rw-r--r-- 1 root root 1112 Sep 18 14:46 server.pem
-rw-r--r-- 1 root root 330 Sep 18 14:34 test01.tf
将这些文件存储在虚拟机(=HostOS / 名称:默认)的/test01上,是为了使Terraform正在运行的容器(=GuestOS)能够读取数据。虽然可能有更聪明的方法,但我们的目的是理解原理,所以我认为这样就可以了。
4. 基本操作 -> 基本操作
执行docker run命令,启动一个已安装了Terraform的容器。将HostOS:/test01挂载到GuestOS:/mnt/test01。覆盖ENTRYPOINT为/bin/bash,登录到容器中。
- コンテナーの起動
$ docker run -v /test01:/mnt/test01 -it --entrypoint /bin/bash hashicorp/terraform:full
- 環境変数の設定
bash-4.3# export DOCKER_TLS_VERIFY="1"
bash-4.3# export DOCKER_HOST="tcp://192.168.99.100:2376"
bash-4.3# export DOCKER_CERT_PATH="/mnt/test01"
bash-4.3# export DOCKER_MACHINE_NAME="default"
- 初期化:terraform init
bash-4.3# terraform init /mnt/test01
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "docker" (0.1.0)...
(省略)
- 計画:terraform plan
bash-4.3# terraform plan /mnt/test01/
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage.
(省略)
- 実行:terraform apply
bash-4.3# terraform apply /mnt/test01
docker_image.centos: Creating...
latest: "" => "<computed>"
name: "" => "centos:latest"
- 確認:terraform state
bash-4.3# terraform state list
docker_image.centos
bash-4.3# terraform state show
id = sha256:196e0ce0c9fbb31da595b893dd39bc9fd4aa78a474bbdc21459a3ebe855b7768centos:latest
latest = sha256:196e0ce0c9fbb31da595b893dd39bc9fd4aa78a474bbdc21459a3ebe855b7768
name = centos:latest
- 確認:docker ps
root@default:/test01# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58a7abd9022a hashicorp/terraform:full "/bin/bash" 24 minutes ago Up 24 minutes priceless_shaw
8ea9cb51ff36 196e0ce0c9fb "/bin/sh -c 'while..." 2 hours ago Up 2 hours hoge
- 計画(破棄):terraform plan -destroy
bash-4.3# terraform plan -destroy
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
docker_image.centos: Refreshing state... (ID: sha256:196e0ce0c9fbb31da595b893dd39bc9f...474bbdc21459a3ebe855b7768centos:latest)
- コンテナー停止: docker stop / docker rm
root@default:/test01# docker stop 8ea9cb51ff36
root@default:/test01# docker rm 8ea9cb51ff36
- 破棄:terraform destroy
bash-4.3# terraform destroy
docker_image.centos: Refreshing state... (ID: sha256:196e0ce0c9fbb31da595b893dd39bc9f...474bbdc21459a3ebe855b7768centos:latest)
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
(省略)
5. 输出日志
若要输出详细日志,请执行 export TF_LOG=1。若不希望输出日志,请执行 export TF_LOG=”。您还可以将日志写入日志文件。详细信息请参阅 https://www.terraform.io/docs/configuration/environment-variables.html。
bash-4.3# export TF_LOG=1
bash-4.3# export TF_LOG_PATH='./terraform.log'
bash-4.3# terraform version
2017/09/18 17:30:54 [WARN] Invalid log level: "1". Defaulting to level: TRACE. Valid levels are: [TRACE DEBUG INFO WARN ERROR]
Terraform v0.10.5
总结
当我选择使用Terraform的Docker版本时,需要使用mount(run -v),环境变量(DOCKER_CERT_PATH),ENTRYPOINT(/bin/bash)等功能,这使我能够复习Docker。然而,我有点困难…
由于Terraform不是多云环境,所以在这次验证中我无法享受到其价值。不过,我还是大致理解了。通过将服务器设置部分进行代码化,并与Github和Jenkins进行集成,可以实现基础设施的CI环境,这才是真正的价值所在…
此外,作为Terraform的资源,提供了docker_container、docker_image、docker_network和docker_volume,所以我要尝试一下docker_network和docker_volume。以前,可能只有docker_container和docker_image存在吧…
还有,通过Terraform无法启动/停止通过虚拟机进行的提供。terraform命令中没有start/stop,只有destroy(不是停止而是销毁)