news 2026/9/13 10:02:48

使用 Kubespray 与 Terraform 在 AWS 上部署生产级 Kubernetes 集群

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 Kubespray 与 Terraform 在 AWS 上部署生产级 Kubernetes 集群

使用 Kubespray 与 Terraform 在 AWS 上部署生产级 Kubernetes 集群

【免费下载链接】kubesprayDeploy a Production Ready Kubernetes Cluster项目地址: https://gitcode.com/GitHub_Trending/ku/kubespray

导读

本文聚焦 Kubespray 仓库中 contrib/terraform/aws 提供的 Terraform 基础设施即代码(IaC)方案,讲解如何一键在 AWS 上创建包含 VPC、堡垒机、NAT 网关、NLB 与多可用区(AZ)节点组的完整 Kubernetes 基础设施,并自动生成供 Kubespray Ansible playbook 使用的 inventory 文件。读完本文,你将掌握该 Terraform 项目的全部变量语义、多发行版 AMI 适配方法、kubeconfig 获取流程以及常见故障的排查思路,可直接在真实 AWS 账号上完成从"空账号"到"生产级集群"的端到端部署。

项目概述:Terraform 自动创建的核心资源

该 Terraform 项目(入口为 create-infrastructure.tf)会一次性创建以下资源:

  • VPC:包含公有子网与私有子网,分别分布在多个可用区(AZ)内;
  • 堡垒机(Bastion Host)与 NAT 网关:部署在公有子网中,负责对外提供 SSH 跳板与私有子网出网能力;
  • Kubernetes 控制平面(master)、etcd 与 worker 节点:数量均可动态配置,且在私有子网中均匀分布到各可用区;
  • AWS NLB:部署在公有子网,将 Kubernetes API Server 端口(默认 6443)暴露到公网,供kubectl与 kubeadm 使用。

该方案默认将 master、etcd、worker 全部放在私有子网中,公网访问完全依赖 NLB 与堡垒机,这与"生产级集群"的网络隔离诉求一致——控制平面与数据面节点没有公网 IP,仅有出网能力(经 NAT 网关)。

架构解析:模块化 Terraform 代码拆解

项目的核心编排位于 create-infrastructure.tf,通过module关键字调用三个子模块,代码结构清晰:

模块目录职责
aws-vpcmodules/vpc创建 VPC、公有/私有子网、Internet 网关、NAT 网关、路由表、安全组
aws-nlbmodules/nlb创建面向公网的 NLB、目标组与监听器,将流量转发至 master 节点
aws-iammodules/iam创建 master 与 worker 的 IAM 角色/实例配置文件,供云控制器使用

VPC 模块的细节

modules/vpc/main.tf 中,每个公有子网都会配对创建一个 NAT 网关(aws_eip+aws_nat_gateway,数量与公有子网数一致),确保多 AZ 场景下每个可用区都有独立的出网路径;私有子网通过aws_route_table0.0.0.0/0路由指向对应 NAT 网关。同时:

  • 子网标签中写入kubernetes.io/cluster/<cluster_name> = "shared",公有子网带kubernetes.io/role/elb = "1"、私有子网带kubernetes.io/role/internal-elb = "1",这些标签是 AWS 云负载均衡器控制器与 kubeadm 云控制器识别子网用途的标准约定;
  • 安全组(aws_security_group)默认放行 VPC 内部全端口互通(ingress0.0.0.0/0仅限 VPC CIDR)、放行全部出站流量,并对0.0.0.0/0开放 TCP 22 端口供 SSH 连接——生产环境建议按需收紧 SSH 来源 CIDR。

NLB 模块的细节

modules/nlb/main.tf 创建的是Network Load Balancerload_balancer_type = "network"),而非经典 ELB:

  • 监听器端口由aws_nlb_api_port控制,目标组端口由k8s_secure_api_port控制(两者默认均为 6443);
  • 目标组target_type = "ip",直接将 master 节点的私有 IP注册为后端目标(见 create-infrastructure.tf 中的aws_lb_target_group_attachment);
  • 健康检查基于 HTTPS/healthz路径,与 Kubernetes API Server 原生的健康探针对应。

IAM 模块的细节

modules/iam/main.tf 分别为控制平面与 worker 创建独立的 IAM 角色(kubernetes-<cluster>-masterkubernetes-<cluster>-node),并附加ec2:*elasticloadbalancing:*等权限。master 实例通过iam_instance_profile = module.aws-iam.kube_control_plane-profile挂载该角色,worker 节点则挂载 worker 角色,这是 AWS 上运行云负载均衡控制器与持久卷(EBS CSI)所需的最小权限骨架。

使用前提

  • Terraform 0.12.0 或更新版本(create-infrastructure.tf 中required_version = ">= 0.12.0",AWS Provider 要求hashicorp/aws ~> 5.0);
  • 一个拥有相应权限的AWS 账号(Access Key / Secret Key);
  • 一个AWS EC2 SSH Key Pair(部署后用于连接堡垒机与节点)。

使用步骤:从配置到集群落地

第一步:提供 AWS 凭证

两种方式二选一:

  • 方式一(环境变量)
export TF_VAR_AWS_ACCESS_KEY_ID="www" export TF_VAR_AWS_SECRET_ACCESS_KEY="xxx" export TF_VAR_AWS_SSH_KEY_NAME="yyy" export TF_VAR_AWS_DEFAULT_REGION="zzz"
  • 方式二(凭据文件):复制 credentials.tfvars.example 为credentials.tfvars并填入实际值:
AWS_ACCESS_KEY_ID = "" AWS_SECRET_ACCESS_KEY = "" AWS_SSH_KEY_NAME = "" AWS_DEFAULT_REGION = "eu-central-1"

注意:Terraform 变量名与环境变量同名,方式二会把凭据明文写入本地文件,请注意文件权限与保管。

第二步:编辑集群规模与网络参数

编辑 terraform.tfvars(仓库中已有可直接运行的示例值),核心参数如下:

变量含义示例值
aws_cluster_name集群名称,会作为所有资源名的前缀"devtest"
aws_vpc_cidr_blockVPC 网段"10.250.192.0/18"
aws_cidr_subnets_private私有子网网段列表(每个元素对应一个 AZ)["10.250.192.0/20", "10.250.208.0/20"]
aws_cidr_subnets_public公有子网网段列表["10.250.224.0/20", "10.250.240.0/20"]
aws_bastion_num/aws_bastion_size堡垒机数量与实例规格1/"t3.small"
aws_kube_master_num/_size/_disk_sizemaster 节点数量、规格、根盘大小(GiB)3/"t3.medium"/50
aws_etcd_num/_size/_disk_size独立 etcd 节点数、规格、根盘大小0/"t3.medium"/50
aws_kube_worker_num/_size/_disk_sizeworker 节点数量、规格、根盘大小4/"t3.medium"/50
aws_nlb_api_port/k8s_secure_api_portNLB 监听端口与 API Server 端口6443/6443
default_tags附加到所有 AWS 资源的通用标签{ Env = "devtest" }
inventory_file生成的 Ansible inventory 写入路径"../../../inventory/hosts"

节点数量与子网数量的配合规则:子网列表的长度决定了使用的可用区数量,master/worker/etcd 实例通过element(module.aws-vpc.aws_subnet_ids_private, count.index)按索引循环分配到各子网,从而实现跨 AZ 均匀分布;因此节点数量最好能被子网数量整除,否则会出现 AZ 间节点数不均。

仓库 terraform.tfvars 还给出了两种典型拓扑的注释示例:

  • 单 AZ 部署:只配置一个公有/私有子网;
  • 3+ AZ 部署:配置 4 个 /24 子网以承载更多节点。

第三步:执行 Terraform 应用

创建好 EC2 SSH Key 后执行:

terraform apply -var-file=credentials.tfvars

若已导出环境变量,直接terraform apply即可。

第四步:自动生成 inventory 与 SSH 配置

  • Terraform 会在inventory目录(默认写入路径为inventory_file = "../../../inventory/hosts",即仓库根目录的 inventory/hosts)自动生成 Ansible inventory 文件;
  • 该文件由 templates/inventory.tpl 模板渲染,包含[all][bastion][kube_control_plane][kube_node][etcd][calico_rr]以及[k8s_cluster:children]等组定义,并注入apiserver_loadbalancer_domain_name指向 NLB 的 FQDN;
  • 各实例的ansible_host使用私有 IP/私有 DNS,因此所有对节点的操作都必须经由堡垒机跳转;
  • 仓库根目录同时自动生成ssh-bastion.conf(由角色 roles/bastion-ssh-config 渲染),Ansible 会自动识别堡垒机并调整ssh_args,通过跳板连接各节点。你也可以手动使用:
ssh -F ./ssh-bastion.conf user@$ip

第五步:运行 Kubespray Playbook 完成集群安装

基础设施就绪后,即可用生成好的 inventory 执行 Kubespray 集群编排(以 Ubuntu 为例):

ansible-playbook -i ./inventory/hosts ./cluster.yml -e ansible_user=ubuntu -b --become-user=root --flush-cache

其中 cluster.yml 是 Kubespray 的主 playbook,会依次完成 etcd 部署、kubeadm 初始化控制平面、加入 worker 节点、安装网络插件(默认 Calico)与应用组件(DNS、metrics-server 等)的全流程。

使用非 Ubuntu 发行版:通过 AMI 过滤器自定义镜像

默认情况下,Terraform 脚本以 Ubuntu(当前 variables.tf 中默认ami_name_pattern = "debian-10-amd64-*"ami_owners = ["136693071363"])作为基础镜像。若要切换发行版,无需改动核心 Terraform 文件,只需在terraform.tfvars中覆盖data "aws_ami" "distro"块的搜索过滤器(对应ami_name_patternami_virtualization_typeami_owners三个变量),实现按名称模式与所有者 ID 精确匹配最新 AMI。

常见发行版配置示例

  • Debian Jessie
ami_name_pattern = "debian-jessie-amd64-hvm-*" ami_owners = ["379101102735"]
  • Ubuntu 16.04(Xenial)
ami_name_pattern = "ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-*" ami_owners = ["099720109477"]
  • CentOS 7
ami_name_pattern = "dcos-centos7-*" ami_owners = ["688023202711"]

切换发行版后,务必同步调整第五步中ansible_user(如 CentOS/Amazon Linux 通常为centosec2-user),并确保该发行版在 roles/bootstrap_os/tasks 中有对应的 OS 初始化任务支持。

连接 Kubernetes:获取 kubeconfig

集群安装完成后,在仓库根目录依次执行以下命令,即可从控制平面节点导出 kubeconfig 并接入集群:

# 获取控制平面节点的 IP 地址 CONTROLLER_HOST_NAME=$(cat ./inventory/hosts | grep "\[kube_control_plane\]" -A 1 | tail -n 1) CONTROLLER_IP=$(cat ./inventory/hosts | grep $CONTROLLER_HOST_NAME | grep ansible_host | cut -d'=' -f2) # 获取负载均衡器的域名 LB_HOST=$(cat inventory/hosts | grep apiserver_loadbalancer_domain_name | cut -d'"' -f2) # 将控制平面节点加入 known_hosts,避免首次 SSH 交互 ssh-keygen -R $CONTROLLER_IP > /dev/null 2>&1 ssh-keyscan -H $CONTROLLER_IP >> ~/.ssh/known_hosts 2>/dev/null # 通过堡垒机导出 kubeconfig(CentOS 发行版示例) mkdir -p ~/.kube ssh -F ssh-bastion.conf centos@$CONTROLLER_IP "sudo chmod 644 /etc/kubernetes/admin.conf" scp -F ssh-bastion.conf centos@$CONTROLLER_IP:/etc/kubernetes/admin.conf ~/.kube/config sed -i "s^server:.*^server: https://$LB_HOST:6443^" ~/.kube/config kubectl get nodes

关键点说明:

  • ssh -F ssh-bastion.conf显式指定生成的堡垒机 SSH 配置,实现经跳板访问私有子网内的控制平面;
  • 最后一条sed将 kubeconfig 中的server地址改写为 NLB 的 FQDN(https://<LB_HOST>:6443),使kubectl从本地直接经 NLB 访问 API Server;
  • 若使用非 CentOS 发行版,需将命令中的centos@替换为对应用户(如ubuntu@)。

故障排查

IAM 实例配置文件残留

如果集群未通过 Terraform 销毁(例如直接删除了 EC2 实例),AWS 上可能残留 IAM 实例配置文件。可通过 AWS CLI 手动清理:

aws iam delete-instance-profile --region <region_name> --instance-profile-name <profile_name>

Ansible inventory 未自动生成

正常情况下 Terraform 会在 apply 结束时自动渲染 inventory 文件。若未生成,可将terraform apply输出中inventory = ...之后的内容复制出来,手动保存为inventory/hosts文件再继续使用。该输出由 output.tf 中的inventoryoutput 提供,其值即 templates/inventory.tpl 渲染后的完整文本。

与 Kubespray 主流程的衔接要点

  • inventory 变量注入:模板中的apiserver_loadbalancer_domain_name是 Kubespray 必需的变量,它让 kubeadm 使用 NLB FQDN 作为 API Server 的广告地址,同时 cluster.yml 中 HA 模式的负载均衡逻辑也会消费该值;
  • etcd 归组逻辑:当aws_etcd_num > 0时 etcd 独立成组,否则[etcd]组回退为 master 节点(见 create-infrastructure.tf 中list_etcd的条件表达式),这与 Kubespray "etcd 可与控制平面共置"的部署模型完全对应;
  • 后续运维:基础设施重建或扩缩容后重新执行terraform apply,inventory 文件会随实例变更自动重新渲染(null_resource以渲染结果为触发器),随后可继续使用 scale.yml、upgrade_cluster.yml 等 playbook 完成集群的扩缩容与升级。

小结

contrib/terraform/aws为 Kubespray 用户提供了一条从 AWS 空账号直达生产级 Kubernetes 集群的自动化路径:Terraform 负责网络、安全与计算资源的声明式创建,并自动输出与 Kubespray inventory 格式无缝衔接的 hosts 文件;Ansible 侧则借助自动生成的堡垒机 SSH 配置完成全部节点编排。理解其变量语义、模块边界与 inventory 生成规则,是安全、灵活地在 AWS 多可用区环境下落地 Kubespray 集群的关键。

【免费下载链接】kubesprayDeploy a Production Ready Kubernetes Cluster项目地址: https://gitcode.com/GitHub_Trending/ku/kubespray

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 10:00:46

AI写作辅助工具:从文字生成到思维增强

1. 项目概述&#xff1a;重新定义AI写作辅助工具"好写作AI"这个项目名称本身就蕴含着对当前AI写作工具市场的反思与突破。作为一名长期关注内容创作领域的技术从业者&#xff0c;我见证了太多所谓的"智能写作助手"最终沦为低质代写的尴尬现状。这类工具往往…

作者头像 李华
网站建设 2026/9/13 9:59:02

WebSocket协议升级函数attachGatewayUpgradeHandler详解

1. 函数背景与核心作用attachGatewayUpgradeHandler是WebSocket协议实现中的关键函数&#xff0c;主要负责处理HTTP协议升级到WebSocket的连接请求。当客户端发起WebSocket握手时&#xff0c;服务端需要通过这个函数完成以下核心操作&#xff1a;验证HTTP头部的Upgrade字段检查…

作者头像 李华
网站建设 2026/9/13 9:58:03

Python学生信息管理系统开发实战:tkinter+sqlite3从建表到打包

简介&#xff1a;这是一份Python学生信息管理系统设计与实现源码&#xff0c;属于已通过导师指导的高分毕业设计项目&#xff0c;适合计算机专业学生、毕业设计开发者以及需要快速搭建管理系统的学习者参考。资源共2000个文件&#xff0c;压缩包约28.8MB&#xff0c;以Python源…

作者头像 李华
网站建设 2026/9/13 9:56:02

Karpathy工程思维:可迁移的技术决策框架

1. 项目概述&#xff1a;这不是在教你怎么“学Karpathy”&#xff0c;而是在拆解他为什么能成为AI时代最值得细读的实践者提到andrej-karpathy-skills&#xff0c;很多人第一反应是“去刷他的YouTube视频”“把nanoGPT代码逐行抄一遍”“背熟LLM原理图”。但实操过三年以上AI工…

作者头像 李华