在云计算和容器化技术成为主流的今天,Kubernetes作为容器编排的事实标准,其部署和管理效率直接影响着企业的运维成本和业务敏捷性。传统的手动部署方式不仅耗时费力,而且难以保证环境的一致性,特别是在需要频繁创建和销毁集群的开发测试场景中。
这正是Terraform的价值所在——通过基础设施即代码(IaC)的方式,我们可以用声明式的配置文件定义整个Kubernetes集群的架构和配置,然后通过简单的命令一键部署生产就绪的集群。这种方式不仅提高了效率,还确保了环境的一致性,使得"牛栏环境"问题成为历史。
Terraform作为HashiCorp推出的基础设施编排工具,其核心价值在于:
生产级Kubernetes集群需要考虑的关键因素包括:
以AWS为例,需要准备:
bash复制# 配置AWS CLI凭证
aws configure
bash复制# Linux/macOS安装示例
wget https://releases.hashicorp.com/terraform/1.2.5/terraform_1.2.5_linux_amd64.zip
unzip terraform_1.2.5_linux_amd64.zip
sudo mv terraform /usr/local/bin/
验证安装:
bash复制terraform version
生产级Kubernetes的网络架构应考虑:
示例网络配置:
hcl复制resource "aws_vpc" "k8s" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "k8s-prod-vpc"
}
}
resource "aws_subnet" "public" {
count = 3
vpc_id = aws_vpc.k8s.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = "us-west-2${element(["a", "b", "c"], count.index)}"
tags = {
Name = "k8s-public-${count.index}"
}
}
典型的生产集群应包含:
hcl复制resource "aws_eks_node_group" "workers" {
cluster_name = aws_eks_cluster.demo.name
node_group_name = "worker-group"
node_role_arn = aws_iam_role.node.arn
subnet_ids = aws_subnet.public[*].id
scaling_config {
desired_size = 3
max_size = 10
min_size = 3
}
instance_types = ["t3.large"]
}
最小权限原则下的IAM配置:
hcl复制resource "aws_iam_role" "cluster" {
name = "eks-cluster-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "eks.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.cluster.name
}
通过Terraform配置Kubernetes RBAC:
hcl复制resource "kubernetes_cluster_role" "monitoring" {
metadata {
name = "monitoring"
}
rule {
api_groups = [""]
resources = ["pods", "services", "endpoints"]
verbs = ["get", "list", "watch"]
}
}
bash复制terraform init
bash复制terraform plan -out=tfplan
bash复制terraform apply tfplan
bash复制aws eks --region $(terraform output -raw region) update-kubeconfig \
--name $(terraform output -raw cluster_name)
配置Cluster Autoscaler:
hcl复制resource "kubernetes_deployment" "cluster_autoscaler" {
metadata {
name = "cluster-autoscaler"
namespace = "kube-system"
}
spec {
replicas = 1
selector {
match_labels = {
app = "cluster-autoscaler"
}
}
template {
metadata {
labels = {
app = "cluster-autoscaler"
}
}
spec {
container {
name = "cluster-autoscaler"
image = "k8s.gcr.io/autoscaling/cluster-autoscaler:v1.22.0"
command = [
"./cluster-autoscaler",
"--v=4",
"--stderrthreshold=info",
"--cloud-provider=aws",
"--node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/$(terraform output -raw cluster_name)",
"--balance-similar-node-groups",
"--skip-nodes-with-system-pods=false"
]
}
}
}
}
}
配置Prometheus和Grafana:
hcl复制resource "helm_release" "prometheus" {
name = "prometheus"
repository = "https://prometheus-community.github.io/helm-charts"
chart = "kube-prometheus-stack"
namespace = "monitoring"
create_namespace = true
set {
name = "prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues"
value = "false"
}
}
bash复制# 查看可用版本
aws eks describe-update --region us-west-2 --name my-cluster
# 启动升级
aws eks update-cluster-version --region us-west-2 --name my-cluster --kubernetes-version 1.22
hcl复制resource "aws_eks_node_group" "spot" {
# ...其他配置...
instance_types = ["m5.large", "m5a.large", "m5d.large"] # 多种实例类型提高Spot成功率
capacity_type = "SPOT"
}
通过Lambda函数实现非工作时间自动缩容:
hcl复制resource "aws_cloudwatch_event_rule" "stop_instances" {
name = "stop_instances"
description = "Stop instances at night"
schedule_expression = "cron(0 20 ? * MON-FRI *)" # 工作日晚上8点
}
resource "aws_lambda_function" "scale_down" {
filename = "scale_down.zip"
function_name = "scale_down"
role = aws_iam_role.lambda.arn
handler = "index.handler"
runtime = "python3.8"
environment {
variables = {
CLUSTER_NAME = aws_eks_cluster.demo.name
NODE_GROUP = aws_eks_node_group.workers.node_group_name
DESIRED_SIZE = 0
}
}
}
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 节点无法加入集群 | 网络策略限制 | 检查安全组和NACL规则 |
| Pod一直Pending | 资源不足或调度问题 | 检查资源请求和节点容量 |
| API Server不可用 | 控制平面问题 | 检查Master节点状态和日志 |
在实际生产环境中部署和维护Kubernetes集群时,有几个关键经验值得分享:
版本控制一切:不仅Terraform代码要纳入版本控制,Kubernetes的Manifest也应使用GitOps工作流管理。我们团队使用Argo CD实现了配置的自动同步和回滚能力。
模块化设计:将Terraform代码按功能拆分为多个模块(网络、集群、节点组等),便于复用和维护。例如,我们为不同的环境(dev/staging/prod)创建了不同的变量文件,但复用相同的模块代码。
渐进式部署:首次部署时,建议分阶段应用:先创建网络基础设施,验证无误后再部署集群,最后添加节点组。这可以通过Terraform的目标部署实现:
bash复制terraform apply -target=module.network
terraform apply -target=module.eks
监控先行:在部署业务负载前,先确保监控系统就位。我们通常在集群创建后立即部署Prometheus Operator,这样可以在后续部署中实时观察资源使用情况。
定期销毁重建:为验证部署流程的可靠性,我们每月会销毁并重建一次开发环境。这不仅能发现潜在问题,还能避免"配置漂移"。Terraform的状态管理使这一过程变得可控。