使用Terraform和Ansible在KVM上自动部署k3s
目的 – 我只需要一种选择 :
当需要进行K8s验证时,创建K8s集群本身需要花费很多时间。在这次中,我们将使用Ansible和Terraform来解决时间上的瓶颈问题。
构成

目录结构
-
- main.tf
-
- provider.tf
-
- k3s-ansible
ansible.cfg
site.yml
inventory
my-cluster
hosts.ini
group_vars
– all.yml
Terraform的配置
提供者.tf
由于本次的VM供应商是基于KVM主机的,所以我们将使用libvirt提供者。
provider "libvirt" {
uri = "qemu+ssh://shoma@172.24.20.3/system"
}
resource "libvirt_volume" "os-image" {
count = 5
name = "${format("terraform-vm%02d.qcow2", count.index + 1)}"
source = "https://cloud-images.ubuntu.com/releases/23.04/release-20230714/ubuntu-23.04-server-cloudimg-amd64.img"
format = "qcow2"
}
resource "libvirt_cloudinit_disk" "cloudinit_terraform-vm" {
count = 5
name = "${format("terraform-vm%02d.iso", count.index + 1)}"
pool = "default"
user_data = <<EOF
#cloud-config
hostname: "${format("terraform-vm%02d.qcow2", count.index + 1)}"
user: tmcit
password: tmcit
chpasswd: { expire: False }
ssh_pwauth: True
EOF
network_config = <<EOF
version: 2
ethernets:
ens3:
addresses:
- "${format("172.24.20.20%d/24", count.index + 1)}"
gateway4: 172.24.20.254
nameservers:
addresses: [172.24.2.51]
EOF
}
resource "libvirt_domain" "terraform-vm" {
count = 5
name = "${format("ubuntu-terraform%02d", count.index + 1)}"
memory = 2048
vcpu = 2
disk { volume_id = libvirt_volume.os-image[count.index].id }
cloudinit = libvirt_cloudinit_disk.cloudinit_terraform-vm[count.index].id
cpu {
mode = "host-passthrough"
}
network_interface {
bridge = "bridge1"
}
console {
type = "pty"
target_port = "0"
}
graphics {
type = "vnc"
listen_type = "address"
autoport = "true"
}
}
resource "null_resource" "ssh-keydelete" {
count = 5
triggers = {
vm_id = libvirt_domain.terraform-vm[count.index].id
}
provisioner "local-exec" {
command = <<COMMAND
sleep 45
ssh-keygen -R ${format("172.24.20.20%d", count.index + 1)}
COMMAND
}
}
resource "null_resource" "ssh_key" {
count = 5
triggers = {
vm_id = libvirt_domain.terraform-vm[count.index].id
}
provisioner "local-exec" {
command = <<COMMAND
sleep 60
sshpass -p tmcit ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub tmcit@${format("172.24.20.20%d", count.index + 1)}
COMMAND
}
}
resource "null_resource" "run_ansible" {
count = length(libvirt_domain.terraform-vm)
triggers = {
vm_id = libvirt_domain.terraform-vm[count.index].id
}
provisioner "local-exec" {
command = <<COMMAND
sleep 75
cd k3s-ansible
ansible-playbook site.yml
COMMAND
}
}
Ansible的配置
k3s-ansible/inventory/my-cluster/hosts.ini的翻译如下:
[master]
172.24.20.201
[node]
172.24.20.202
172.24.20.203
172.24.20.204
172.24.20.205
[k3s_cluster:children]
master
node
k3s-ansible/site.yml的翻译如下:
---
- hosts: k3s_cluster
gather_facts: yes
become: yes
roles:
- role: prereq
- role: download
- role: raspberrypi
- hosts: master
become: yes
roles:
- role: k3s/master
- hosts: node
become: yes
roles:
- role: k3s/node
k3s-ansible/ansible.cfg:
修改库存部分
[defaults]
nocows = True
roles_path = ./roles
inventory = inventory/my-cluster/hosts.ini
remote_tmp = $HOME/.ansible/tmp
local_tmp = $HOME/.ansible/tmp
pipelining = True
become = True
host_key_checking = False
deprecation_warnings = False
callback_whitelist = profile_tasks
确认
$ terraform apply
$ ssh tmcit@172.24.20.201
$ kubectl get nodess
NAME STATUS ROLES AGE VERSION
terraform-vm05 Ready <none> 57s v1.22.3+k3s1
terraform-vm04 Ready <none> 57s v1.22.3+k3s1
terraform-vm02 Ready <none> 57s v1.22.3+k3s1
terraform-vm03 Ready <none> 57s v1.22.3+k3s1
terraform-vm01 Ready control-plane,master 106s v1.22.3+k3s1