asuhacoder / TechTrain

reports for TechTrain interviews
0 stars 0 forks source link

TerraformでKubernetesクラスター構築 | 2020/11/22 #5

Open asuhacoder opened 3 years ago

asuhacoder commented 3 years ago

TechTrain Report

Description

Terraformを用いてKubernetesクラスターを構築する。 EKSは高くて(月72ドル)使えないのでkopsを使用

Memo

必要なものはVPC, public subnet, private subnet, nat-gateway, Route53

作業レポジトリ

Terraform

terraform init -> terraform plan -> terraform apply -> terraform destroyの流れ

作成したいものをいちいち調べればおおよそのサンプルが出てくるのでそれを見て作ればよい。 実際はAWS Provider Documentを見て書くことになる。 どういうargumentsを指定したらいいかもここを見る

Backend

terraformはterraformの状態をs3で管理するためあらかじめs3 bucketを作っておくことが複数人での開発では必須である。 でないと最新のawsの状態を把握できない。 これだけは自分で作る必要がある。 dynamodbも作れば同時applyも防げる

backend.tf

terraform {
  backend "s3" {
    encrypt = true
    bucket = "xway.me-terraform"
    key    = "backend.tfstate"
    region = "ap-northeast-1"
    dynamodb_table = "xway.me-terraform"
  }
}

kops state store

kopsもstate storeとしてs3が必要
保存場所は他でもいいが安全でterraformで作れるs3が今回は最適解

kops_state.tf

2行目にlocal.kops_state_bucket_nameとあるが"${local.kops_state_bucket_name}"と書いてあるファイルが多いが最新版ではwarningが出るのでやめるべき。

resource "aws_s3_bucket" "kops_state" {
  bucket = local.kops_state_bucket_name
  acl    = "private"

  versioning {
    enabled = true
  }

  tags = {
    Environment = "product"
    Application = "kops"
  }
}

resource "aws_security_group" "k8s_api_http" {
  name   = "${local.environment}_k8s_api_http"
  vpc_id = module.vpc.vpc_id
  tags   = local.tags

  ingress {
    protocol    = "tcp"
    from_port   = 80
    to_port     = 80
    cidr_blocks = local.ingress_ips
  }

  ingress {
    protocol    = "tcp"
    from_port   = 443
    to_port     = 443
    cidr_blocks = local.ingress_ips
  }
}

locals

他のtfファイルで使う変数を宣言している。 こういうのは何度も使うので一箇所にまとめて宣言する。いちいちハードコーディングしない。

locals.tf

locals {
  cluster_name           = "xway.me"
  cidr                   = "10.0.0.0/16"
  azs                    = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
  private_subnets        = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets         = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
  environment            = "product"
  kops_state_bucket_name = "xway.me-kops"
  ingress_ips            = ["10.0.0.100/32", "10.0.0.101/32"]

  tags = {
    environment = local.environment
    terraform   = true
  }
}

VPC

メインのtfファイル

vpc.tf

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "xway.me"
  cidr = local.cidr

  azs             = local.azs
  private_subnets = local.private_subnets
  public_subnets  = local.public_subnets

  enable_nat_gateway = true
  single_nat_gateway = true
  one_nat_gateway_per_az = false

  enable_dns_support = true
  enable_dns_hostnames = true

  private_subnet_tags = {
    "kubernetes.io/role/internal-elb" = 1
  }

  public_subnet_tags = {
    "kubernetes.io/role/elb" = 1
  }

  tags = {
    Environment = local.environment
    Application = "network"
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
  }
}

provider

regionを設定している。
ここにaccess keyを入れることもできる。

provider.tf

provider "aws" {
  region = "ap-northeast-1"
}

output

どんな構成になったかidなどを出力する。 あとあと結構見るので重要

output.tf

output "region" {
  value = "ap-northeast-1"
}

output "vpc_id" {
  value = module.vpc.vpc_id
}

output "vpc_cidr_block" {
  value = module.vpc.vpc_cidr_block
}

output "public_subnet_ids" {
  value = [module.vpc.public_subnets]
}

output "public_route_table_ids" {
  value = [module.vpc.public_route_table_ids]
}

output "private_subnet_ids" {
  value = [module.vpc.private_subnets]
}

output "private_route_table_ids" {
  value = [module.vpc.private_route_table_ids]
}

output "default_security_group_id" {
  value = module.vpc.default_security_group_id
}

output "nat_gateway_ids" {
  value = module.vpc.natgw_ids
}

output "availability_zones" {
  value = [local.azs]
}

output "kops_s3_bucket_name" {
  value = aws_s3_bucket.kops_state.bucket
}

output "cluster_name" {
  value = local.cluster_name
}

output "k8s_api_http_security_group_id" {
  value = aws_security_group.k8s_api_http.id
}

output "aws_vpc_endpoint" {
  value = aws_vpc_endpoint.endpoint.id
}

Task List

References

Kubernetes on AWS (Part. 1): Kops & Terraform 5分で分かるTerraform(Infrastructure as Code) AWS Provider Document

asuhacoder commented 3 years ago

amazon web services - kops update cluster failed with error doing DNS lookup for NS records no such host - Stack Overflow