Lời nói đầu

Ở bài viết Terraform - Infrastructure as Code trên blog VietnamLab, chúng ta đã tìm hiểu sơ qua về công cụ Terraform và khái niệm Infrastructure as Code. Với xu hướng triển khai các service trên cloud ngày càng trở nên phổ biến, vấn đề quản lý infrastructure và tự động hóa việc triển khai infrastructure cũng ngày càng trở lên quan trọng. Terraform và khái niệm Infrastructure as Code sinh ra để giải quyết vấn đề này. Bài viết hôm nay sẽ giới thiệu về việc sử dụng Terraform và Google Kubernetes Engine để khởi tạo 1 cluster Kubernetes đơn giản.

Các thiết lập chuẩn bị cần thiết

Các bước cơ bản

  • Cài đặt Terraform
  • Tạo một tài khoản Google Cloud (Với tài khoản mới, Google sẽ tặng 300$ Credit, sử dụng trong 1 năm, do vậy việc sử dụng Google Cloud trong bài viết này sẽ không tốn xu nào)
  • Cài đặt Google Cloud SDK

Thiết lập Google Cloud SDK

Trước tiên, sau khi tạo tài khoản chúng ta phải vào trang admin của Google Cloud, vào phần Billing, nhập số thẻ Credit Card (yên tâm là tiền sẽ chỉ bị trừ khi phát sinh chi phi sử dụng thật) để có thể bắt đầu sử dụng các dịch vụ của Google Cloud. Sau đó ta cần phải tạo 1 project mới, vì tất cả các thao tác liên quan đến google cloud đều sẽ thực hiện thông qua project.

Khi Google Cloud SDK đã được cài đặt, câu lệnh gcloud sẽ tồn tại trong hệ thống. Thực hiện câu lệnh sau để thiết lập setting cho Google Cloud SDK:

$ gloud init

Khi thực hiện câu lệnh này, thì trình duyệt sẽ được mở để ta có thể log in và xác thực với tài khoản google. Sau khi xác thực xong, thì câu lệnh sẽ hướng dẫn ta để chọn project mặc định để Cloud SDK tương tác. Chúng ta có thể chọn project đã tạo ở trên hoặc tạo 1 project mới, chọn compute zone cho project đã được chọn.

Bước tiếp theo, ta enable các api cần thiết:

$ gcloud services enable container.googleapis.com 
$ gcloud services enable cloudresourcemanager.googleapis.com 
$ gcloud services enable storage-api.googleapis.com 
$ gcloud services enable iam.googleapis.com 

Để Terraform có thể tương tác được với Google Cloud, ta cần tạo một service account, set quyền cho service account này (bạn có thể đọc thêm về service account ở đây)

$ gcloud iam service-accounts create [service_account_name] # service_account_name tuỳ theo ý người đọc
$ gcloud projects add-iam-policy-binding [project_name] "serviceAccount:[service_account_name]@[project_name].iam.gserviceaccount.com" --role "roles/editor" # project_name là tên project đã tạo ở trên

Sau đó sinh key file cho Terraform sử dụng(Chú ý: Key file này sẽ cho phép ta tương tác trực tiếp với Google Cloud nên cần phải được bảo mật, không public):

$ gcloud iam service-accounts keys create key.json --iam-account [service_account_name]@[project_name].iam.gserviceaccount.com

Khởi tạo Cloud Storage Bucket để lưu trữ Terraform state

Trạng thái hiện tại của infrastructure sẽ được Terraform lưu trữ vào một file state và nếu ta sử dụng giá trị mặc định thì nó sẽ được lưu ở trên local, sẽ chỉ có một máy local này access được vào state hiện tại của hệ thống và thao tác với infrastructure đã được tạo. Để có thể chia sẻ access đến file state, ta cần thiết lập để Terraform lưu state trên cloud. Ta sẽ sử dụng Google Cloud Storage trong bài viết này. Câu lệnh gsutil (có sẵn khi cài Google Cloud SDK) dưới đây sẽ khởi tạo một Cloud Storage bucket và thiết lập tính năng versioning cho nó (theo khuyến nghị trên documentation của Terraform):

$ gsutil mb gs://[bucket_id] # bucket_id tuỳ theo ý người đọc miễn là nó phải unique
$ gsutil versioning set on gs://[bucket_id]

Thiết lập Terraform

Việc đầu tiên là tạo 1 folder để chứa các file config Terraform và add ngay 1 file .gitignore với nội dung như sau:

#  Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# secret .tfvars files
secret.tfvars

# account file
*key.json

Sau đó là tạo một file main.tf như sau. Ở trong file này ta đã thiết lập để terraform sử dụng Google Cloud Store để lưu state, đồng thời thiết lập để Terraform có thể tương tác được với Google Cloud.

terraform {
  backend "gcs" {}
}

provider "google" {
  credentials = file("key.json")
  project = var.project
  region = var.region
}

Tiếp đến ta sẽ khai báo các biến sẽ được sử dụng và giá trị của chúng. Mặc định Terraform sẽ load giá trị các biến từ file terraform.tfvars hoặc *.auto.tfvars trong folder thực hiện câu lệnh terraform. Ngoài ra, ta cũng có thể truyền giá trị từ command line hoặc thiết lập để Terraform sử dụng file khác bằng option -var-file (có thể tạo mỗi file cho một môi trường như staging.tfvars, dev.tfvars):

  • Khai báo biến
    # variables.tf
    variable "project" {
      type = string
    }
    variable "region" {
      type = string
    }
    variable "general_machine_type" {
      type = string
    }
    variable "min_node_count" {
      type = number
    }
    variable "max_node_count" {
      type = number
    }
    variable "is_preemptible" {
      type = bool
    }
    
  • Khai báo giá trị
    # terraform.tfvars
    project = "[project_name]"
    region = "asia-southeast1"
    general_machine_type = "n1-standard-1"
    min_node_count = 1
    max_node_count = 2
    is_preemptible = true
    

Cuối cùng ta sẽ setting cho cluster của mình vào file cluster.tf (Trong bài viết này, chúng ta sẽ chỉ sử dụng premptible node để giảm chi phí)

resource "google_container_cluster" "main" {
  name     = "${var.project}-cluster"
  location = var.region


  remove_default_node_pool = true
  initial_node_count       = 1

  master_auth {
    username = ""
    password = ""
  }
}

resource "google_container_node_pool" "main" {
  name       = "${var.project}-main"
  location   = var.region
  cluster    = google_container_cluster.main.name
  node_count = 1

  management {
    auto_repair  = true
    auto_upgrade = true
  }

  autoscaling {
    min_node_count = var.min_node_count
    max_node_count = var.max_node_count
  }

  node_config {
    preemptible  = var.is_preemptible
    machine_type = var.general_machine_type

    metadata = {
      disable-legacy-endpoints = true
    }

    oauth_scopes = [
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
      "https://www.googleapis.com/auth/devstorage.read_only"
    ]
  }
}

Sau đó, ta chạy lệnh terraform init để Terraform download các plugin cần thiết, đồng thời cung cấp thông tin về Google Cloud Storage bucket để lưu state

$ terraform init -backend-config=bucket=[bucket_id] -backend-config=credentials=key.json

Giờ ta đã có thể validate lại các setting của mình và preview qua xem khi setup Terraform sẽ thực hiện những gì:

$ terraform validate
$ terraform plan

Sau khi đã xem xét, chỉ cần một câu lệnh ngắn và đợi chờ 1 chút, cluster Kubernetes của ta đã sẵn sàng

$ terraform apply

Trạng thái của cluster có thể được xác nhận với câu lệnh sau:

$ gcloud container clusters list 

Kết luận

Bài viết đã giới thiệu một cách đơn giản cách sử dụng Terraform để tạo 1 cluster Kubernetes trên Google Cloud. Tuy nhiên còn rất nhiều vấn đề để có thể thiết lập một cluster cho môi trường production thật sự như network, storage, security. Hi vọng sẽ có dịp chia sẻ thêm cùng bạn đọc

References