跳到主要内容

3、实战:Terraform本地源配置-2024.5.30(测试成功)

实战:Terraform本地源配置-2024.5.30(测试成功)

image-20240530131559498

目录

[toc]

文档来源

感谢泽阳大佬。❤️

补充: Terraform配置本地缓存源文档:https://www.yuque.com/devopsgroup/tf/ext#b0c3c0c6

image-20240526220850965

问题背景

image-20240530210437490

解决思路:

需要手动或者terraform init一次下载, 然后缓存,后续直接使用缓存。

实验环境

本次利用如下配置文件来模拟测试:

前提条件:

已经提前安装好terraform;

然后本次利用次kind.tf文件(见附件)进行模拟测试。

Terraform v1.1.8 on linux_amd64

实验软件

链接:https://pan.baidu.com/s/1DEJ5UjguYl01m-z6iCC2aw?pwd=tpy9 提取码:tpy9 2024.5.30-实战-Terraform本地源配置(测试成功)

image-20240530223720748

故障现象

  • 安装terraform软件
unzip terraform_1.1.8_linux_amd64.zip
mv terraform /usr/local/bin
terraform version
  • 准备测试环境:
[root@devops8 ~]#mkdir k8s

#上传测试文件到k8s目录
[root@devops8 k8s]#ll -a
total 28
drwxr-xr-x 2 root root 58 May 30 21:15 .
dr-xr-x---. 11 root root 4096 May 30 21:15 ..
-rw-r--r-- 1 root root 15343 May 30 17:37 ingress.yaml
-rw-r--r-- 1 root root 2778 May 30 17:37 kind.tf
-rw-r--r-- 1 root root 1010 May 30 17:37 README.md
  • terraform init初始化,观察下载插件情况
[root@devops8 k8s]#terraform init
  • 此时会发现报错了:
[root@devops8 k8s]#terraform init

Initializing the backend...

Initializing provider plugins...
- Finding tehcyx/kind versions matching "0.0.12"...
- Finding hashicorp/null versions matching "3.1.1"...
- Installing tehcyx/kind v0.0.12...
- Installing hashicorp/null v3.1.1...

│ Error: Failed to install provider

│ Error while installing tehcyx/kind v0.0.12: Get
"https://github.com/tehcyx/terraform-provider-kind/releases/download/v0.0.12/terraform-provider-kind_0.0.12_linux_amd64.zip": unexpected
│ EOF



│ Error: Failed to install provider

│ Error while installing hashicorp/null v3.1.1: Get
"https://releases.hashicorp.com/terraform-provider-null/3.1.1/terraform-provider-null_3.1.1_linux_amd64.zip": read tcp
192.168.1.200:46508->108.139.10.20:443: read: connection reset by peer

image-20240528220724230

  • 再次尝试,还是报错……

  • 但是,多试几次,运气好的话,就可以正常下载插件了(这个和网络有很大关系……

这个有什么办法解决吗?给自己虚机配置http/https proxy??……

image-20240530211948565

可以看到,terraform会在当前目录下生成.terradorm目录,然后里面存放下载好的插件:

image-20240530212030577

另外也会在/root目录下生成.terrform.d目录

image-20240530212159102

接下来,手把手带你配置terraform缓存。

1、 创建配置文件

  • 创建配置文件

.terraformrc是Terraform CLI的配置文件

#vim /root/.terraformrc
plugin_cache_dir = "/root/.terraform.d/terraform-plugin-cache"
disable_checkpoint = true

plugin_cache_dir 是插件的缓存目录(此目录需要提前创建不然init报错)

disable_checkpoint 禁用 需要连接HashiCorp 提供的网络服务的升级和安全公告检查

  • 创建缓存目录
mkdir -p /root/.terraform.d/terraform-plugin-cache

扩展:

文件创建好了之后, 要通过配置TF_CLI_CONFIG_FILE变量,让TerraformCLI可以加载到配置文件。 这个变量的值没有固定配置,而是取决于.terraformrc文件路径。 (也可以直接将这个文件放到~宿主目录下,就不用声明变量了)

export TF_CLI_CONFIG_FILE=$HOME/Desktop/terraform/terraform-module-example/.terraformrc

2、进行初始化

插件下载方式有两种:

  1. 通过 terraform init 自动下载provider 插件;
  2. 或者登入registry.terraform.io手动到GitHub下载,并按照目录结构存放到plugin_cache_dir;

注意:

本次为了测试准确性,我们先来删除前面已经下载好的插件

[root@devops8 k8s]#pwd
/root/k8s
[root@devops8 k8s]#ll -a
total 32
drwxr-xr-x 3 root root 103 May 30 21:18 .
dr-xr-x---. 11 root root 4096 May 30 21:24 ..
-rw-r--r-- 1 root root 15343 May 30 17:37 ingress.yaml
-rw-r--r-- 1 root root 2778 May 30 17:37 kind.tf
-rw-r--r-- 1 root root 1010 May 30 17:37 README.md
drwxr-xr-x 3 root root 23 May 30 21:17 .terraform
-rw-r--r-- 1 root root 1727 May 30 21:18 .terraform.lock.hcl
[root@devops8 k8s]#rm -rf .terraform
[root@devops8 k8s]#rm -rf .terraform.lock.hcl
  • 初始化前,我们来看下kind.tf文件内容
[root@devops8 k8s]#cat kind.tf 
# terraform用到的providers
terraform {
required_providers {
kind = {
source = "tehcyx/kind"
version = "0.0.12"
}
null = {
source = "hashicorp/null"
version = "3.1.1"
}
}
}

provider "kind" {}

# 此变量指定kubeconfig的文件输出路径
variable "kind_cluster_config_path" {
type = string
default = "~/.kube/config"
}

# 此输出会在控制台打印kubeconfig内容
output "kubeconfig" {
value = kind_cluster.default.kubeconfig
}

# 定义k8s集群
resource "kind_cluster" "default" {
name = "devopscluster" # 集群名称
node_image = "kindest/node:v1.24.0" # kind镜像
kubeconfig_path = pathexpand(var.kind_cluster_config_path) # kubeconfig路径
wait_for_ready = true # 等待集群节点ready

# kind配置文件
kind_config {
kind = "Cluster"
api_version = "kind.x-k8s.io/v1alpha4"

# Control节点配置
node {
role = "control-plane"
kubeadm_config_patches = [
<<-EOT
kind: InitConfiguration
imageRepository: registry.aliyuncs.com/google_containers
networking:
serviceSubnet: 10.0.0.0/16
apiServerAddress: "0.0.0.0"
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
---
kind: KubeletConfiguration
cgroupDriver: systemd
cgroupRoot: /kubelet
failSwapOn: false
EOT
]

extra_port_mappings {
container_port = 80
host_port = 80
}
extra_port_mappings {
container_port = 443
host_port = 443
}
extra_port_mappings {
container_port = 6443
host_port = 6443
}
}

# worker 节点1
node {
role = "worker"
}

# worker 节点2
node {
role = "worker"
}
}
}

# null_resource 用于执行shell命令
# 此步骤用于加载ingress镜像并部署ingress
resource "null_resource" "wait_for_instatll_ingress" {
triggers = {
key = uuid()
}

provisioner "local-exec" {
command = <<EOF
sleep 5
kind load docker-image k8s.gcr.io/ingress-nginx/controller:v1.2.0 --name devopscluster
kind load docker-image k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1 --name devopscluster
kubectl create ns ingress-nginx
kubectl apply -f ingress.yaml -n ingress-nginx
printf "\nWaiting for the nginx ingress controller...\n"
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
EOF
}

depends_on = [kind_cluster.default]
}

这个文件的作用就是调用kind来快速搭建一个k8s集群。

  • 本次演示先使用terraform init进行操作, 如果手动到registry下载,需要按照目录结构存放;
[root@devops8 k8s]#pwd
/root/k8s
[root@devops8 k8s]#ls
ingress.yaml kind.tf README.md
[root@devops8 k8s]#terraform init

image-20240530215301812

  • 初始化之后, 查看plugin_cache_dir中的内容:

/root/.terraform.d/terraform-plugin-cache/

[root@devops8 k8s]#tree /root/.terraform.d/terraform-plugin-cache/
/root/.terraform.d/terraform-plugin-cache/
└── registry.terraform.io
├── hashicorp
│   └── null
│   └── 3.1.1
│   └── linux_amd64
│   └── terraform-provider-null_v3.1.1_x5
└── tehcyx
└── kind
└── 0.0.12
└── linux_amd64
├── LICENSE
├── README.md
└── terraform-provider-kind

9 directories, 4 files

需要注意的一点是:在当前目录下也会生成一个.terrform目录

image-20240530215657977

3、模拟断网,离线初始化

这里断开自己虚机网络。

image-20240530214731773

方法1: 初始化时指定plugin-dir terraform init --plugin-dir /root/.terraform.d/terraform-plugin-cache/

[root@devops8 k8s]#terraform init --plugin-dir /root/.terraform.d/terraform-plugin-cache/

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/null from the dependency lock file
- Reusing previous version of tehcyx/kind from the dependency lock file
- Using previously-installed hashicorp/null v3.1.1
- Using previously-installed tehcyx/kind v0.0.12

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should 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, other
commands will detect it and remind you to do so if necessary.

image-20240530215801658

方法2: 定义Terraform插件使用本地mirror**(推荐)**

#vim /root/.terraformrc
plugin_cache_dir = "/root/.terraform.d/terraform-plugin-cache"
disable_checkpoint = true


provider_installation {
filesystem_mirror {
path = "/root/.terraform.d/terraform-plugin-cache"
include = ["registry.terraform.io/*/*"]
}
}

初始化:

[root@devops8 k8s]#terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of tehcyx/kind from the dependency lock file
- Reusing previous version of hashicorp/null from the dependency lock file
- Using previously-installed tehcyx/kind v0.0.12
- Using previously-installed hashicorp/null v3.1.1

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should 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, other
commands will detect it and remind you to do so if necessary.

image-20240530215910034

可见,配置缓存后,再次初始化时就直接从本地缓存目录下载插件了,速度非常快,符合预期,nice。

总结

到此就完成了terraform离线本地源的配置了。

扩展:

除了这种方式外其实也可以基于terraform开放的HTTP API协议,使用Python Flask写一个registry server。

FAQ

特别注意下2个选项的区别

[root@devops8 k8s]#cat /root/.terraformrc
plugin_cache_dir = "/root/.terraform.d/terraform-plugin-cache" #这个目录用于terraform init时,指定插件的下载位置
disable_checkpoint = true


provider_installation {
filesystem_mirror {
path = "/root/.terraform.d/terraform-plugin-cache" #这个目录配置后,每次执行terraform init时,默认就会从当前目录获取插件!
include = ["registry.terraform.io/*/*"]
}
}

注意:不要搞混淆了!

  1. plugin_cache_dir - 指定插件缓存的目录位置,用于加速插件下载和安装。

    plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
  2. provider_installation - 用于配置自定义的提供程序安装选项,例如直接从文件系统中安装,或者指定镜像地址。

    provider_installation {
    filesystem_mirror {
    path = "/mnt/terraform-plugins"
    include = ["registry.terraform.io/*/*"]
    }
    network_mirror {
    url = "https://mirrors.example.com/terraform/"
    include = ["registry.terraform.io/*/*"]
    }
    direct {
    exclude = ["registry.terraform.io/hashicorp/*"]
    }
    }

如果第一次terraform一直无法成功下载插件呢

插件下载方式有两种:

  1. 通过 terraform init 自动下载provider 插件;
  2. 或者登入registry.terraform.io手动到GitHub下载,并按照目录结构存放到plugin_cache_dir;

手动下载后,还需要手动创建很多和目录,比较繁琐,不推荐;

但是 terraform init 一直下载失败,该怎么办呢?---(最好是能给自己虚机配置科学上网代理,那么应该就可以正常下载插件了。)--但是,如何给自己虚机配置代理呢??……(搁置)

windows系统配置

本次实践使用的是Linux/Mac 系统,如果是windows系统有两点不同的配置。

  • CLI配置文件的名称为terraform.rc
  • plugin_cache_dir: D:/xxx/xxx

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码

x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号

《云原生架构师实战》

image-20230107215126971

🍀 个人博客站点

https://onedayxyy.cn/

🍀 csdn

https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎

https://www.zhihu.com/people/foryouone

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!