You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mathxh@MathxH:~/terraform-docker$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "~> 2.13.0"...
- Installing kreuzwerker/docker v2.13.0...
- Installed kreuzwerker/docker v2.13.0 (self-signed, key ID 24E54F214569A8A5)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:https://www.terraform.io/docs/cli/plugins/signing.htmlTerraform has created a lock file .terraform.lock.hcl to record the providerselections it made above. Include this file in your version control repositoryso that Terraform can guarantee to make the same selections by default whenyou run "terraform init" in the future.Terraform has been successfully initialized!You may now begin working with Terraform. Try running "terraform plan" to seeany changes that are required for your infrastructure. All Terraform commandsshould now work.If you ever set or change modules or backend configuration for Terraform,rerun this command to reinitialize your working directory. If you forget, othercommands will detect it and remind you to do so if necessary.
执行terraform apply 它会执行 main.tf, 拉取Nginx镜像资源并运行容器
mathxh@MathxH:~/terraform-docker$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create
Terraform will perform the following actions:
# docker_container.nginx will be created
+ resource "docker_container""nginx" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ gateway = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = (known after apply)
+ init = (known after apply)
+ ip_address = (known after apply)
+ ip_prefix_length = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = "json-file"
+ logs = false
+ must_run = true
+ name = "tutorial"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "no"
+ rm = false
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ tty = false
+ healthcheck {
+ interval = (known after apply)
+ retries = (known after apply)
+ start_period = (known after apply)
+ test = (known after apply)
+ timeout = (known after apply)
}
+ labels {
+ label = (known after apply)
+ value = (known after apply)
}
+ ports {
+ external = 8000
+ internal = 80
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
}
# docker_image.nginx will be created
+ resource "docker_image""nginx" {
+ id = (known after apply)
+ keep_locally = false
+ latest = (known after apply)
+ name = "nginx:latest"
+ output = (known after apply)
+ repo_digest = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
docker_image.nginx: Creating...
docker_image.nginx: Still creating... [10s elapsed]
docker_image.nginx: Creation complete after 17s [id=sha256:7425d3a7c478efbeb75f0937060117343a9a510f72f5f7ad9f14b1501a36940cnginx:latest]
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 8s [id=b60c7266a7b8b9c0b7d3e306ada54292757e278abd4822c1234a6c95560a14cf]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
mathxh@MathxH:~/terraform-docker$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b60c7266a7b8 7425d3a7c478 "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:8000->80/tcp tutorial
从上面可以看到container运行起来了,好了因为是在WSL2中运行的terraform, 从TF的配置上看到container暴露的external端口也是8000,所以我们从宿主机上访问WSL2中的8000,首先通过 ip address 拿到 eth0的 IP地址,然后通过IP:8000形式访问
mathxh@MathxH:~/terraform-docker$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
624c4ad2d453 7425d3a7c478 "/docker-entrypoint.…" 9 seconds ago Up 4 seconds 0.0.0.0:8000->80/tcp ExampleNginxContainer
mathxh@MathxH:~/terraform-docker$ ls
main.tf outputs.tf terraform.tfstate terraform.tfstate.backup variables.tf
文件中定义你需要的container id和image id的输出
output"container_id" {
description="ID of the Docker container"value=docker_container.nginx.id
}
output"image_id" {
description="ID of the Docker image"value=docker_image.nginx.id
}
前言
在GitOps那篇文章提到过IaC了,TF就是IaC的工具,它主要解决Infra Provisioning的问题。接下来我们直接步入主题吧。
Terraform的基本原理
就是跟之前说的一样,原理和k8s这样基于declarative 的原理一样,都是Desired state跟actual state做对比,做diff,然后变更diff部门,幂等执行。这样就是只要配置文件相同,那么能保证提供的infra环境(VPS, VM等)是一致的。
从大部分公司使用TF来看,主要是用来构建IaaS服务,比如用TF 向Azure,GCP(Google Cloud Platform),AWS, Alibaba Cloud这样的Coud Provider申请配置Infra资源。当然还可以配置本地私有的Infra资源,比如k8s,Docker,自建的Openstack等。所以在TF生态下,有很多TF provider,有了这些provider,就可以通过TF配置对应Provider提供的Infra资源了。这些Provider你可以理解是一些第三方实现的插件,TF只是提供了接口和标准。
下面就是TF配置文件的样例:
上图是向AWS申请并创建一个VPC资源,并且给这台VPC配置了一个IPv4 CIDR block ,这个详情可以看AWS的VPC Provider参数 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#cidr_block
https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#IPv4_CIDR_blocks
上图是向指定的k8s集群申请并创建了一个叫“my-first-namespace”的namespace资源。
Terraform for Docker
由于我没有AWS账号之类的,暂时不弄最流行的Terraform + AWS的教程。我尝试用本地的Docker来完成这个工作。主要是翻译terraform官网的Docker教程。 learning by doing。
好了,我们就根据官网的Interactive Lab作为我们本机环境的学习教程。先我们在WSL2中安装terraform, https://www.terraform.io/cli/install/apt
这样就安装上了。首先先启动Docker的Daemon
sudo service docker start
, 然后查看下terrafrom是否正常terraform version
mathxh@MathxH:~/terraform-docker$ terraform version Terraform v1.1.9 on linux_amd64
terraform init
它会自动安装你指定的Provider插件(kreuzwerker/docker)terraform apply
它会执行 main.tf, 拉取Nginx镜像资源并运行容器从上面可以看到container运行起来了,好了因为是在WSL2中运行的terraform, 从TF的配置上看到container暴露的external端口也是8000,所以我们从宿主机上访问WSL2中的8000,首先通过
ip address
拿到 eth0的 IP地址,然后通过IP:8000形式访问http://172.28.230.233:8000/
terraform destroy
下面我们来对配置文件
main.tf
进行详解。terraform {}块包含了Terraform的设置,包括Terraform用来配置基础设施所需的Provider。对于每个Provider,源属性定义了一个可选的主机名、一个命名空间和Provider类型。Terraform默认从Terraform registry中安装Provider。在这个配置示例中,docker的Provider的来源被定义为kreuzwerker/docker,这是对registry.terraform.io/kreuzwerker/docker的简写。
你还可以为在required_providers块中定义的每个provider设置一个版本约束。版本属性是可选的,但我们建议使用它来约束提供者的版本,这样Terraform就不会安装不适合你的配置的provider的版本。如果你不指定provider的版本,Terraform会在初始化时自动下载最新的版本。
详情参考 https://www.terraform.io/language/providers/requirements
Provider模块配置指定的Provider,在这里是指docker。提供者是一个插件,Terraform使用它来创建和管理你的Infra资源。
你可以在你的Terraform配置中使用多个Provider块来管理不同提供者的资源。你甚至可以同时使用不同的Provider。例如,你可以将Docker镜像ID传递给Kubernetes服务。
使用resource块来定义你的基础设施的组件。一个resource可能是一个物理或虚拟组件,如Docker容器,也可能是一个逻辑资源,如Heroku应用程序。
resource块前面有两个字符串:resource type和resource name。在这个例子中,第一个资源类型是docker_image,名称是nginx。resource type的前缀映射到提供者的名称。在这个配置例子中,Terraform用docker provider管理docker_image resource。resource type和resource name共同构成了resource的唯一ID。例如,你的Docker镜像的ID是docker_image.nginx。
resource块包含参数,你可以用它来配置资源。参数可以包括诸如机器尺寸、磁盘镜像名称或VPC ID等。我们的provider 的文档中 https://www.terraform.io/language/providers 记载了每个resource的必要和可选参数。对于你的容器,该配置示例将Docker镜像作为docker_container资源的镜像源。
Terraform 的 input variable
这样使用会更灵活,毕竟有些工程的配置很复杂。
创建一个
variables.tf
的文件,在之前的目录下,并加入以下内容然后修改main.tf 引用该变量, 并再次
terraform apply
结果就是容器名变成了
ExampleNginxContainer
:如果你要覆盖默认的这个变量值,你可以通过terraform的
-var
来传递进去修改变量值,terraform apply -var="container_name=MathxHChen"
这样terraform就会先destroy之前的container,再启动一个新的名为MathxHChen的新container。Terraform还支持很多关于variable的用法,详情请看 https://learn.hashicorp.com/tutorials/terraform/variables?in=terraform/configuration-language
Terraform的Output Data
之前已经说过利用Terraform提供的input variables让配置文件更灵活,使其参数化。你将使用output value来组织数据,以方便查询和显示给Terraform用户。也算是为了方便调试吧。
在目录下创建一个
outputs.tf
的文件,并且terraform apply
mathxh@MathxH:~/terraform-docker$ ls main.tf outputs.tf terraform.tfstate terraform.tfstate.backup variables.tf
文件中定义你需要的container id和image id的输出
apply完成你就可以看到output了,你也可以用
terraform output
来查看下一步的深入学习
配置语言 - 需要更熟悉variables、outputs、 dependencies, meta-arguments和其他语言功能,以编写更复杂的Terraform配置。
模块 - 用模块来组织和复用Terraform配置。
provision - 使用Packer或Cloud-init自动配置SSH密钥和Web服务器,并 把它们配置到由Terraform在AWS创建的Linux虚拟机上
导入 --将现有基础设施导入Terraform。
还有一个course https://github.com/wardviaene/terraform-course 和一个example https://github.com/futurice/terraform-examples
References
The text was updated successfully, but these errors were encountered: