【k8s】使用Terraform一鍵部署EKS叢集

鄭立賽發表於2021-12-03

本文適用範文

  • 使用AWS海外賬號
  • 對aws、terraform、k8s有一定的瞭解
  • 新建一個獨立的VPC

Terraform簡介

terraform是一個雲端的資源編排工具,官方對自己的定位:Terraform is an open-source infrastructure as code software。
類似的,在AWS雲上有CloudFormation,我們選擇terraform是因為它更加的通用,能夠同時管理AWS雲,Azure雲,阿里雲等常見的雲服務。
使用方式詳見:https://registry.terraform.io/namespaces/hashicorp

前置條件

  • 有一個AWS海外賬號,並且擁有管理員許可權
  • 執行指令碼的伺服器以賦予角色,角色擁有administrator許可權(實際用不到這麼高的許可權,僅為了演示,未做最小許可權配置)
  • 伺服器已安裝terraform程式(安裝方式見terraform官網)
  • 伺服器已安裝awscli和kubectl

說明

為了方便閱讀,tf指令碼按照aws資源型別拆分(實際上將所有配置打包到一個tf指令碼里也能執行)

指令碼內容

指令碼中已標記註釋,這裡就不解釋每段的含義了。

main.tf

各位客官根據自己需要,修改此指令碼中的引數。其他指令碼均不需要修改

# author zhenglisai
# 使用當前指令碼所在伺服器角色許可權
provider "aws" {
  region = "us-west-2"
}
# 獲取當前可用區
data "aws_availability_zones" "available" {
  state = "available"
}
# 本地引數,下面引數均可根據自己需要修改。
locals {
  # EKS叢集名
  cluster_name = "tf-cluster-zhenglisai"
  # EKS叢集角色名
  cluster_role_name = "tf-cluster-zhenglisai"
  # EKS計算節點名
  node_name = "tf-node-zhenglisai"
  # EKS計算節點角色
  node_role_name = "tf-node-zhenglisai"
  # EKS計算節點使用的啟動模板名
  launch_template_name = "tf-launch_template-zhenglisai"
  # image_id每個區域不同,此ID僅適用於us-west-2區域,其他區域的映象請參見AWS文件
  launch_template_image_id = "ami-0cb182e3037115aa0"
  # EKS計算節點使用的例項型別
  launch_template_instance_type = "t3.small"
  # 伺服器登入金鑰,需要提前在EC2的金鑰管理中配置好
  launch_template_key_name = "你的金鑰名"
  # EKS叢集使用的VPC網段
  vpc_cidr_block = "10.2.0.0/16"
  # EKS叢集使用的子網網段
  subnet_1_cidr_block = "10.2.0.0/20"
  # EKS叢集使用的子網網段
  subnet_2_cidr_block = "10.2.16.0/20"
}

eks.tf

# author zhenglisai
# 叢集
resource "aws_eks_cluster" "eks-cluster" {
  name     = local.cluster_name
  role_arn = aws_iam_role.eks-cluster.arn
  vpc_config {
    subnet_ids = [aws_subnet.subnet_1.id, aws_subnet.subnet_2.id]
    security_group_ids = [aws_security_group.eks-cluster.id]
  }
}
# 計算節點
resource "aws_eks_node_group" "eks-node" {
  cluster_name  = aws_eks_cluster.eks-cluster.name
  node_group_name = local.node_name
  node_role_arn = aws_iam_role.eks-node.arn
  subnet_ids    = [aws_subnet.subnet_1.id, aws_subnet.subnet_2.id]
  scaling_config {
    desired_size = 2
    max_size     = 3
    min_size     = 1
  }
  launch_template {
    version = aws_launch_template.eks-template.latest_version
    id = aws_launch_template.eks-template.id
  }
}

ec2.tf

# author zhenglisai
resource "aws_launch_template" "eks-template" {
  name = local.launch_template_name
  image_id = local.launch_template_image_id
  instance_type = local.launch_template_instance_type
  key_name = local.launch_template_key_name
  vpc_security_group_ids = [aws_security_group.eks-node.id]
  user_data = base64encode("#!/bin/bash\n/etc/eks/bootstrap.sh ${aws_eks_cluster.eks-cluster.name}")
}

iam.tf

# author zhenglisai
data "aws_iam_policy" "AmazonEKSClusterPolicy" {
  name = "AmazonEKSClusterPolicy"
}
data "aws_iam_policy" "AmazonEKSWorkerNodePolicy" {
  name = "AmazonEKSWorkerNodePolicy"
}
data "aws_iam_policy" "AmazonEC2ContainerRegistryReadOnly" {
  name = "AmazonEC2ContainerRegistryReadOnly"
}
data "aws_iam_policy" "AmazonEKS_CNI_Policy" {
  name = "AmazonEKS_CNI_Policy"
}
data "aws_iam_policy_document" "ec2-instance" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}
data "aws_iam_policy_document" "eks-instance" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["eks.amazonaws.com"]
    }
  }
}
resource "aws_iam_role" "eks-cluster" {
  name = local.cluster_role_name
  assume_role_policy = data.aws_iam_policy_document.eks-instance.json
  managed_policy_arns = [data.aws_iam_policy.AmazonEKSClusterPolicy.arn]
}
resource "aws_iam_role" "eks-node" {
  name = local.node_role_name
  assume_role_policy = data.aws_iam_policy_document.ec2-instance.json
  managed_policy_arns = [data.aws_iam_policy.AmazonEC2ContainerRegistryReadOnly.arn, data.aws_iam_policy.AmazonEKS_CNI_Policy.arn, data.aws_iam_policy.AmazonEKSWorkerNodePolicy.arn]
}

securitygroup.tf

# author zhenglisai
resource "aws_security_group" "eks-cluster" {
  name        = "eks-cluster"
  description = "Allow local vpc"
  vpc_id      = aws_vpc.eks.id
  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [local.vpc_cidr_block]
  }
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "eks-cluster"
  }
}
resource "aws_security_group" "eks-node" {
  name        = "eks-node"
  description = "Allow local vpc"
  vpc_id      = aws_vpc.eks.id
  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [local.vpc_cidr_block]
  }
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "eks-node"
  }
}

vpc.tf

# author zhenglisai
resource "aws_vpc" "eks" {
  cidr_block = local.vpc_cidr_block
  enable_dns_hostnames = "true"
  tags = {
    Name = "eks"
  }
}

# 定義Subnet子網
resource "aws_subnet" "subnet_1" {
  vpc_id = aws_vpc.eks.id
  map_public_ip_on_launch = true
  cidr_block = local.subnet_1_cidr_block
  availability_zone = data.aws_availability_zones.available.names[0]
  tags = {
    Name = "subnet_1"
    "kubernetes.io/role/elb" = "1"
  }
}
resource "aws_subnet" "subnet_2" {
  vpc_id = aws_vpc.eks.id
  map_public_ip_on_launch = true
  cidr_block = local.subnet_2_cidr_block
  availability_zone = data.aws_availability_zones.available.names[1]
  tags = {
    Name = "subnet_2"
    "kubernetes.io/role/elb" = "1"
  }
}
# 建立公網介面
resource "aws_internet_gateway" "igw-eks" {
  vpc_id = aws_vpc.eks.id
  tags = {
    Name = "igw-eks"
  }
}
# 修改路由表
data "aws_route_table" "route_table_eks" {
  vpc_id = aws_vpc.eks.id
  filter {
    name = "association.main"
    values = [true]
  }
}
resource "aws_route" "route_table_eks" {
  route_table_id = data.aws_route_table.route_table_eks.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id = aws_internet_gateway.igw-eks.id
}

將以上檔案儲存在一個目錄中,比如eks_demo目錄

開始執行

進入目錄,並初始化terraform資源

cd eks_demo && terraform init

初始化完成後,開始執行terraform部署

terraform apply

執行後會開始檢查資源,等待檢查完畢後,確認輸入yes開始部署

整個部署過程大概需要持續15分鐘左右
部署完成後,配置kubectl許可權,之後便可與EKS開始互動

刪除資源

實驗結束後,如果不需要保留資源,在tf指令碼所在目錄執行

terraform destroy

即可刪除所有terraform建立的資源

相關文章