今天的狀況是只有一個container,這還算好管裡,但你有想過如果有十個,二十個container,你要怎麼辦嗎?於是我們有了K8s,他是一個很好用的container管理工具,這邊我會直接使用EKS,也就是AWS的K8s來帶入。在講解之前,我想要先談談Terraform。
Terraform是一個Iac工具,你可以這樣思考,我們今天要開一個EC2,我們必須要從console端去點選建立。但是你今天做的設定,可能明天就忘了,可能忘記傳承給下一個人,於是每次都要重新看console確認。又或者是你一次要開三台一模一樣的EC2,難道要傻傻的手動作一樣動作三次嗎?
當然不會,所以我們會藉由寫一個文件的方式,將文件傳送給Amazon,讓他們根據文件幫我們開機器。
以下展示開EKS的 Terraform文件
建立第一個EKS Cluster
我們使用Gitlab所提供建立EKS的cluster template gitlab-terraform-eks
。因為我們之後會需要用 GitLab做 CI/CD部署
我會一一介紹 template裡面相關檔案,讓使用者不會因為使用 template就覺得霧煞煞。
providers.tf
# providers.tf
provider "aws" {
region = var.region
default_tags {
tags = {
Owner = "Alvinlin"
}
}
}
provider "helm" {
kubernetes {
host = data.aws_eks_cluster.cluster.endpoint
token = data.aws_eks_cluster_auth.cluster.token
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
}
}
使用AWS 所開的provider,若是執行terraform,他會自動帶入provider。因為也有帶入helm,代表我們也可以傳輸指令給helm(明天來介紹)
2. eks.tf
```
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "18.1.0"
cluster_name = var.cluster_name
cluster_version = var.cluster_version
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
default = {
min_size = 1
max_size = var.instance_count
desired_size = var.instance_count
instance_types = [var.instance_type]
}
}
}
```
module就是人家打包好的套裝軟件,讓你可以直接引用
source: 是 module的來源
cluster_name:我們會建立cluster,他會有cluster name
vpc_id:
可以參考下圖,我們的cluster裡面可能會有多台的EC2,將他們建立在同一個VPC才能夠溝通
eks_managed_node_groups:
主要在建立並管理 Amazon EC2 instances。所以你會在裡面看到instance_types ,他抓的就是variable的type
```tsx
# variables
variable "instance_type" {
default = "t3.small"
description = "EKS node instance type"
}
variable "instance_count" {
default = 1
description = "EKS node count"
}
```
3. module VPC
```tsx
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = var.cluster_name
cidr = "10.0.0.0/16"
azs = data.aws_availability_zones.available.names
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
}
```
name:VPC的名稱
private_subnets及public_subnets:建立subnet
enable_nat_gateway及single_nat_gateway:自動產生gateway
關於網路相關我們之後再用一篇來討論
4. Data
```tsx
data "aws_availability_zones" "available" {}
data "aws_eks_cluster" "cluster" {
name = module.eks.cluster_id
}
data "aws_eks_cluster_auth" "cluster" {
name = module.eks.cluster_id
}
```
data 相關為查詢的概念,{}內是寫查詢條件
這邊是指宣告一個aws_eks_cluster的`data source` ,並將它命名為cluster。
name的意思是從eks cluster找到名字為module.eks.cluster_id的cluster
如果你想取得這個值,可以使用此表達式
```tsx
<data_source>.<name>.<attribute>
```
舉例,我們在provider裡面,使用`data.aws_eks_cluster.cluster.endpoint` 找到eks 的endpoint 。
5. Output Variables
```jsx
output "cluster_endpoint" {
description = "Endpoint for EKS control plane."
value = module.eks.cluster_endpoint
}
```
output最重要的用途有兩個,第一個就是
1. 讓輸出的資訊可以在command line 使用
2. 可以輸出資訊給其他的Terraform configurations使用
1. 子模組可以使用outputs來輸出父模組的resource attributes的subset
2. 使用terraform apply後,root模組可以使用outputs來在CLI印出某些值
Output 除了在`terraform apply`的時候執行會顯示,也可以透過`terraform output`來查詢
來看看這邊的範例,我們定義一個output變數叫`cluster_endpoint` 。他是直接抓我們之前建立的eks的endpoint。之後我們可以用`terraform output cluster_endpoint` 來取得值。
如果你是root 模組,這個name將會展示給使用者(值只有在terraform apply的時候才會渲染,terraform plan不會)
如果你是父模組,可以使用這個子模組output的值。舉例來說,假設下方這個為子模組的設定,你可以在父模組使用module.<MODULE NAME>.<OUTPUT NAME>來調用。
- 相關資源
關於terraform module
[https://github.com/terraform-aws-modules/terraform-aws-eks](https://github.com/terraform-aws-modules/terraform-aws-eks)
關於 node groups
[https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html)