EKS Blueprints 概述
AWS EKS Blueprints 是一套由 AWS 開發的開源框架,用於快速建立符合生產環境需求的 Amazon EKS(Elastic Kubernetes Service)叢集。它整合了最佳實踐、常用的 add-ons,以及多租戶和團隊管理功能,讓組織能夠以一致且可重複的方式部署 Kubernetes 基礎架構。
為什麼選擇 EKS Blueprints?
傳統的 EKS 叢集建置往往需要手動配置許多元件:網路、安全性群組、IAM 角色、add-ons 等。這個過程不僅耗時,還容易產生配置差異和安全漏洞。EKS Blueprints 解決了這些問題:
- 標準化部署:提供經過驗證的叢集配置模板
- 模組化設計:透過 add-ons 機制輕鬆擴展功能
- 團隊管理:內建多團隊和多租戶支援
- GitOps 整合:原生支援 ArgoCD 和 Flux
- 基礎設施即程式碼:支援 Terraform 和 AWS CDK
EKS Blueprints 架構
EKS Blueprints 的核心架構包含以下元件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ┌─────────────────────────────────────────────────────────────┐
│ EKS Blueprints │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Teams │ │ Add-ons │ │ GitOps │ │
│ │ Management │ │ Management │ │ Integration │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ EKS Cluster │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Control │ │ Node │ │ VPC & │ │
│ │ Plane │ │ Groups │ │ Networking │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
|
Terraform EKS Blueprints 是使用 Terraform 語言實作的版本,適合已經採用 Terraform 進行基礎設施管理的團隊。
安裝前置需求
在開始之前,請確保已安裝以下工具:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 安裝 Terraform (version >= 1.0.0)
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
# 驗證安裝
terraform version
# 安裝 AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# 配置 AWS 憑證
aws configure
# 安裝 kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# 安裝 Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
|
基本叢集部署
建立專案目錄結構:
1
2
| mkdir -p eks-blueprints-demo
cd eks-blueprints-demo
|
建立 versions.tf 檔案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.20.0"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.9.0"
}
kubectl = {
source = "gavinbunney/kubectl"
version = ">= 1.14.0"
}
}
}
|
建立 main.tf 檔案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
| provider "aws" {
region = var.region
}
# 取得可用區域資訊
data "aws_availability_zones" "available" {
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
# 本地變數定義
locals {
name = "eks-blueprints-demo"
cluster_version = "1.29"
region = var.region
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Blueprint = local.name
Environment = "demo"
Terraform = "true"
}
}
# VPC 模組
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
intra_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 52)]
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
# 為 EKS 標記子網路
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
}
tags = local.tags
}
# EKS Blueprints 模組
module "eks_blueprints" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints?ref=v4.32.1"
cluster_name = local.name
cluster_version = local.cluster_version
vpc_id = module.vpc.vpc_id
private_subnet_ids = module.vpc.private_subnets
# EKS 管理的節點群組
managed_node_groups = {
initial = {
node_group_name = "managed-ondemand"
instance_types = ["m5.large"]
min_size = 2
max_size = 5
desired_size = 3
subnet_ids = module.vpc.private_subnets
}
}
tags = local.tags
}
# Kubernetes 與 Helm Provider 配置
provider "kubernetes" {
host = module.eks_blueprints.eks_cluster_endpoint
cluster_ca_certificate = base64decode(module.eks_blueprints.eks_cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
args = ["eks", "get-token", "--cluster-name", module.eks_blueprints.eks_cluster_id]
}
}
provider "helm" {
kubernetes {
host = module.eks_blueprints.eks_cluster_endpoint
cluster_ca_certificate = base64decode(module.eks_blueprints.eks_cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
args = ["eks", "get-token", "--cluster-name", module.eks_blueprints.eks_cluster_id]
}
}
}
|
建立 variables.tf 檔案:
1
2
3
4
5
| variable "region" {
description = "AWS region"
type = string
default = "ap-northeast-1"
}
|
建立 outputs.tf 檔案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| output "cluster_name" {
description = "EKS cluster name"
value = module.eks_blueprints.eks_cluster_id
}
output "cluster_endpoint" {
description = "EKS cluster endpoint"
value = module.eks_blueprints.eks_cluster_endpoint
}
output "cluster_version" {
description = "EKS cluster version"
value = module.eks_blueprints.eks_cluster_version
}
output "configure_kubectl" {
description = "Configure kubectl command"
value = "aws eks update-kubeconfig --region ${var.region} --name ${module.eks_blueprints.eks_cluster_id}"
}
|
部署叢集
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 初始化 Terraform
terraform init
# 檢視執行計畫
terraform plan
# 執行部署(約需 15-20 分鐘)
terraform apply -auto-approve
# 配置 kubectl
aws eks update-kubeconfig --region ap-northeast-1 --name eks-blueprints-demo
# 驗證叢集
kubectl get nodes
kubectl cluster-info
|
CDK EKS Blueprints
AWS CDK(Cloud Development Kit)版本的 EKS Blueprints 讓開發者能夠使用熟悉的程式語言(如 TypeScript、Python)來定義基礎架構。
安裝 CDK 環境
1
2
3
4
5
6
7
8
9
10
11
12
| # 安裝 Node.js (如果尚未安裝)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# 安裝 AWS CDK
npm install -g aws-cdk
# 驗證安裝
cdk --version
# Bootstrap CDK(首次使用需要執行)
cdk bootstrap aws://ACCOUNT_ID/REGION
|
建立 CDK 專案
1
2
3
4
5
6
7
8
| # 建立專案目錄
mkdir eks-blueprints-cdk && cd eks-blueprints-cdk
# 初始化 TypeScript CDK 專案
cdk init app --language typescript
# 安裝 EKS Blueprints 套件
npm install @aws-quickstart/eks-blueprints
|
實作 EKS Blueprint
編輯 lib/eks-blueprints-cdk-stack.ts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as blueprints from '@aws-quickstart/eks-blueprints';
export class EksBlueprintsCdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const account = props?.env?.account || process.env.CDK_DEFAULT_ACCOUNT;
const region = props?.env?.region || process.env.CDK_DEFAULT_REGION;
// 定義 Add-ons
const addOns: Array<blueprints.ClusterAddOn> = [
new blueprints.addons.VpcCniAddOn(),
new blueprints.addons.CoreDnsAddOn(),
new blueprints.addons.KubeProxyAddOn(),
new blueprints.addons.AwsLoadBalancerControllerAddOn(),
new blueprints.addons.MetricsServerAddOn(),
new blueprints.addons.ClusterAutoScalerAddOn(),
new blueprints.addons.ContainerInsightsAddOn(),
];
// 定義 Teams
const platformTeam = new blueprints.PlatformTeam({
name: 'platform-admin',
users: [
new blueprints.ArnPrincipal(`arn:aws:iam::${account}:user/platform-admin`),
],
});
const applicationTeam = new blueprints.ApplicationTeam({
name: 'app-team',
users: [
new blueprints.ArnPrincipal(`arn:aws:iam::${account}:user/app-developer`),
],
teamManifestDir: './teams/app-team',
});
// 建立 Blueprint
blueprints.EksBlueprint.builder()
.account(account)
.region(region)
.version('auto')
.addOns(...addOns)
.teams(platformTeam, applicationTeam)
.build(scope, 'eks-blueprints-cluster');
}
}
|
編輯 bin/eks-blueprints-cdk.ts:
1
2
3
4
5
6
7
8
9
10
11
12
13
| #!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { EksBlueprintsCdkStack } from '../lib/eks-blueprints-cdk-stack';
const app = new cdk.App();
new EksBlueprintsCdkStack(app, 'EksBlueprintsCdkStack', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION || 'ap-northeast-1',
},
});
|
部署 CDK Stack
1
2
3
4
5
6
7
8
9
10
11
| # 編譯 TypeScript
npm run build
# 檢視 CloudFormation 模板
cdk synth
# 部署
cdk deploy
# 部署完成後配置 kubectl
aws eks update-kubeconfig --region ap-northeast-1 --name eks-blueprints-cluster
|
Add-ons 管理
EKS Blueprints 的核心優勢之一是其豐富的 add-ons 生態系統。Add-ons 是預先配置好的 Kubernetes 元件,可以透過簡單的配置啟用。
常用 Add-ons 清單
網路與服務發現
| Add-on | 說明 |
|---|
| VPC CNI | AWS 原生的容器網路介面 |
| CoreDNS | Kubernetes DNS 服務 |
| AWS Load Balancer Controller | 自動配置 ALB/NLB |
| External DNS | 自動管理 Route53 記錄 |
| Ingress NGINX | NGINX Ingress Controller |
監控與可觀測性
| Add-on | 說明 |
|---|
| Metrics Server | 資源指標收集 |
| Container Insights | CloudWatch 容器監控 |
| Prometheus | 開源監控系統 |
| Grafana | 視覺化儀表板 |
| AWS Distro for OpenTelemetry | 分散式追蹤 |
安全性
| Add-on | 說明 |
|---|
| AWS Secrets Manager CSI Driver | 機密管理整合 |
| External Secrets Operator | 外部機密同步 |
| Cert Manager | TLS 憑證管理 |
| Kyverno | Policy 引擎 |
| OPA Gatekeeper | 政策合規 |
GitOps 與 CI/CD
| Add-on | 說明 |
|---|
| ArgoCD | GitOps 持續部署 |
| Flux | GitOps 工具套件 |
建立 addons.tf 檔案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| module "eks_blueprints_kubernetes_addons" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/kubernetes-addons?ref=v4.32.1"
eks_cluster_id = module.eks_blueprints.eks_cluster_id
eks_cluster_endpoint = module.eks_blueprints.eks_cluster_endpoint
eks_oidc_provider = module.eks_blueprints.oidc_provider
eks_cluster_version = module.eks_blueprints.eks_cluster_version
# EKS Managed Add-ons
enable_amazon_eks_vpc_cni = true
enable_amazon_eks_coredns = true
enable_amazon_eks_kube_proxy = true
enable_amazon_eks_aws_ebs_csi_driver = true
# Self-managed Add-ons
enable_aws_load_balancer_controller = true
enable_metrics_server = true
enable_cluster_autoscaler = true
enable_aws_cloudwatch_metrics = true
# 監控
enable_prometheus = true
enable_amazon_prometheus = true
enable_grafana = true
# 安全性
enable_cert_manager = true
enable_external_secrets = true
enable_aws_secrets_manager_csi_driver = true
# GitOps
enable_argocd = true
argocd_helm_config = {
set = [
{
name = "server.service.type"
value = "LoadBalancer"
}
]
}
tags = local.tags
}
|
自訂 Add-on 配置
每個 add-on 都可以透過 Helm values 進行自訂:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| # 自訂 AWS Load Balancer Controller
enable_aws_load_balancer_controller = true
aws_load_balancer_controller_helm_config = {
name = "aws-load-balancer-controller"
chart = "aws-load-balancer-controller"
repository = "https://aws.github.io/eks-charts"
version = "1.6.2"
namespace = "kube-system"
values = [
<<-EOT
replicaCount: 2
enableShield: false
enableWaf: false
enableWafv2: true
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
EOT
]
}
# 自訂 Prometheus
enable_prometheus = true
prometheus_helm_config = {
name = "prometheus"
repository = "https://prometheus-community.github.io/helm-charts"
chart = "prometheus"
version = "25.8.0"
namespace = "prometheus"
values = [
<<-EOT
server:
persistentVolume:
size: 50Gi
retention: 15d
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1024Mi
alertmanager:
enabled: true
EOT
]
}
|
Team 與 Workload 管理
EKS Blueprints 提供了強大的多租戶管理功能,讓不同團隊能夠安全地共享叢集資源。
團隊類型
EKS Blueprints 定義了兩種團隊類型:
- Platform Team:叢集管理員,擁有完整的叢集存取權限
- Application Team:應用程式開發團隊,僅能存取指定的 namespace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
| module "eks_blueprints" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints?ref=v4.32.1"
# ... 叢集配置 ...
# Platform Team
platform_teams = {
admin = {
users = [
"arn:aws:iam::123456789012:user/admin-user",
"arn:aws:iam::123456789012:role/admin-role"
]
}
}
# Application Teams
application_teams = {
team-frontend = {
"labels" = {
"team" = "frontend"
"environment" = "production"
}
"quota" = {
"requests.cpu" = "10"
"requests.memory" = "20Gi"
"limits.cpu" = "20"
"limits.memory" = "40Gi"
"pods" = "50"
"secrets" = "20"
"services" = "20"
}
# 團隊成員
users = [
"arn:aws:iam::123456789012:user/frontend-dev-1",
"arn:aws:iam::123456789012:user/frontend-dev-2"
]
}
team-backend = {
"labels" = {
"team" = "backend"
"environment" = "production"
}
"quota" = {
"requests.cpu" = "20"
"requests.memory" = "40Gi"
"limits.cpu" = "40"
"limits.memory" = "80Gi"
"pods" = "100"
"secrets" = "50"
"services" = "30"
}
users = [
"arn:aws:iam::123456789012:user/backend-dev-1",
"arn:aws:iam::123456789012:role/backend-developer-role"
]
}
}
tags = local.tags
}
|
團隊 Manifest 配置
為每個團隊建立額外的 Kubernetes 資源:
1
2
| mkdir -p teams/team-frontend
mkdir -p teams/team-backend
|
建立 teams/team-frontend/network-policy.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: team-frontend
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: team-frontend
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
|
建立 teams/team-frontend/limit-range.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-frontend
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
type: Container
|
CDK Team 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| import * as blueprints from '@aws-quickstart/eks-blueprints';
// Platform Team
const platformTeam = new blueprints.PlatformTeam({
name: 'platform-admin',
users: [
new blueprints.ArnPrincipal('arn:aws:iam::123456789012:user/admin'),
],
});
// Application Team with custom configurations
const frontendTeam = new blueprints.ApplicationTeam({
name: 'frontend',
users: [
new blueprints.ArnPrincipal('arn:aws:iam::123456789012:user/frontend-dev'),
],
namespaceLabels: {
team: 'frontend',
environment: 'production',
},
namespaceAnnotations: {
'scheduler.alpha.kubernetes.io/node-selector': 'workload=frontend',
},
teamManifestDir: './teams/frontend',
});
const backendTeam = new blueprints.ApplicationTeam({
name: 'backend',
users: [
new blueprints.ArnPrincipal('arn:aws:iam::123456789012:user/backend-dev'),
],
namespaceLabels: {
team: 'backend',
environment: 'production',
},
teamManifestDir: './teams/backend',
});
// 建立 Blueprint
blueprints.EksBlueprint.builder()
.teams(platformTeam, frontendTeam, backendTeam)
// ... 其他配置
.build(scope, 'multi-team-cluster');
|
GitOps 整合
EKS Blueprints 原生支援 GitOps 工作流程,主要透過 ArgoCD 和 Flux 兩種工具實現。
ArgoCD 整合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| module "eks_blueprints_kubernetes_addons" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/kubernetes-addons?ref=v4.32.1"
# ... 基本配置 ...
enable_argocd = true
argocd_helm_config = {
name = "argocd"
chart = "argo-cd"
repository = "https://argoproj.github.io/argo-helm"
version = "5.51.6"
namespace = "argocd"
create_namespace = true
values = [
<<-EOT
server:
service:
type: LoadBalancer
extraArgs:
- --insecure
configs:
params:
server.insecure: true
EOT
]
}
# ArgoCD 管理的應用程式
argocd_manage_add_ons = true
argocd_applications = {
workloads = {
path = "envs/dev"
repo_url = "https://github.com/your-org/gitops-workloads.git"
target_revision = "main"
destination = "https://kubernetes.default.svc"
project = "default"
values = {
environment = "development"
}
}
platform-services = {
path = "platform"
repo_url = "https://github.com/your-org/platform-services.git"
target_revision = "main"
destination = "https://kubernetes.default.svc"
project = "platform"
}
}
tags = local.tags
}
|
存取 ArgoCD UI
1
2
3
4
5
6
7
8
| # 取得 ArgoCD 服務 URL
kubectl get svc argocd-server -n argocd
# 取得初始 admin 密碼
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# 或使用 port-forward
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
ArgoCD Application 範例
建立 gitops/apps/sample-app.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: sample-application
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/your-org/sample-app.git
targetRevision: HEAD
path: kubernetes
helm:
valueFiles:
- values-production.yaml
destination:
server: https://kubernetes.default.svc
namespace: sample-app
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
|
Flux 整合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| module "eks_blueprints_kubernetes_addons" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/kubernetes-addons?ref=v4.32.1"
# ... 基本配置 ...
enable_flux = true
flux_helm_config = {
create_namespace = true
namespace = "flux-system"
}
flux_git_repo_url = "https://github.com/your-org/gitops-config.git"
flux_git_branch = "main"
flux_git_path = "clusters/production"
flux_git_poll_interval = "1m"
tags = local.tags
}
|
Flux Kustomization 範例
建立 clusters/production/apps.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 10m0s
sourceRef:
kind: GitRepository
name: flux-system
path: ./apps/production
prune: true
wait: true
timeout: 5m0s
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: sample-app
namespace: sample-app
|
建立 clusters/production/infrastructure.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 1h0m0s
sourceRef:
kind: GitRepository
name: flux-system
path: ./infrastructure
prune: true
wait: true
dependsOn:
- name: sources
|
多叢集架構
EKS Blueprints 支援多叢集架構的部署與管理,適用於多區域、多環境的企業需求。
多叢集架構模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| ┌─────────────────┐
│ GitOps Repo │
│ (ArgoCD Hub) │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌────────▼────────┐ ┌───▼───┐ ┌────────▼────────┐
│ Hub Cluster │ │ │ │ Hub Cluster │
│ (ap-northeast) │ │ │ │ (us-west-2) │
└────────┬────────┘ │ │ └────────┬────────┘
│ │ │ │
┌───────┴───────┐ │ │ ┌───────┴───────┐
│ │ │ │ │ │
┌─────▼─────┐ ┌───────▼──▼┐ ┌──▼──▼───────┐ ┌─────▼─────┐
│ Dev │ │ Staging │ │ Staging │ │ Prod │
│ Cluster │ │ Cluster │ │ Cluster │ │ Cluster │
└───────────┘ └───────────┘ └─────────────┘ └───────────┘
|
建立 environments/ 目錄結構:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| environments/
├── dev/
│ ├── main.tf
│ ├── variables.tf
│ └── terraform.tfvars
├── staging/
│ ├── main.tf
│ ├── variables.tf
│ └── terraform.tfvars
├── production/
│ ├── main.tf
│ ├── variables.tf
│ └── terraform.tfvars
└── modules/
└── eks-blueprint/
├── main.tf
├── variables.tf
└── outputs.tf
|
建立共用模組 environments/modules/eks-blueprint/main.tf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| module "eks_blueprints" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints?ref=v4.32.1"
cluster_name = "${var.project_name}-${var.environment}"
cluster_version = var.cluster_version
vpc_id = var.vpc_id
private_subnet_ids = var.private_subnet_ids
managed_node_groups = {
primary = {
node_group_name = "${var.environment}-primary"
instance_types = var.instance_types
min_size = var.min_nodes
max_size = var.max_nodes
desired_size = var.desired_nodes
subnet_ids = var.private_subnet_ids
}
}
platform_teams = var.platform_teams
application_teams = var.application_teams
tags = merge(var.tags, {
Environment = var.environment
})
}
module "kubernetes_addons" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/kubernetes-addons?ref=v4.32.1"
eks_cluster_id = module.eks_blueprints.eks_cluster_id
eks_cluster_endpoint = module.eks_blueprints.eks_cluster_endpoint
eks_oidc_provider = module.eks_blueprints.oidc_provider
eks_cluster_version = module.eks_blueprints.eks_cluster_version
# 基本 add-ons
enable_amazon_eks_vpc_cni = true
enable_amazon_eks_coredns = true
enable_amazon_eks_kube_proxy = true
enable_metrics_server = true
# 環境特定 add-ons
enable_cluster_autoscaler = var.enable_cluster_autoscaler
enable_aws_load_balancer_controller = var.enable_alb_controller
enable_argocd = var.enable_argocd
tags = var.tags
}
|
建立環境配置 environments/production/terraform.tfvars:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| project_name = "mycompany"
environment = "production"
region = "ap-northeast-1"
cluster_version = "1.29"
instance_types = ["m5.xlarge", "m5.2xlarge"]
min_nodes = 3
max_nodes = 20
desired_nodes = 5
enable_cluster_autoscaler = true
enable_alb_controller = true
enable_argocd = true
platform_teams = {
admin = {
users = ["arn:aws:iam::123456789012:role/PlatformAdmin"]
}
}
application_teams = {
production-apps = {
labels = {
environment = "production"
}
quota = {
"requests.cpu" = "100"
"requests.memory" = "200Gi"
"pods" = "500"
}
users = ["arn:aws:iam::123456789012:role/ProductionDeveloper"]
}
}
tags = {
Project = "EKS-Blueprints"
ManagedBy = "Terraform"
CostCenter = "Platform"
}
|
跨叢集服務網格
對於需要跨叢集通訊的場景,可以整合 Istio 服務網格:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| module "kubernetes_addons" {
# ... 基本配置 ...
enable_istio = true
istio_helm_config = {
name = "istio"
repository = "https://istio-release.storage.googleapis.com/charts"
chart = "base"
version = "1.20.0"
namespace = "istio-system"
values = [
<<-EOT
global:
meshID: mesh1
multiCluster:
clusterName: ${var.cluster_name}
network: network1
EOT
]
}
}
|
自訂 Blueprint 開發
當標準的 add-ons 無法滿足需求時,您可以開發自訂的 Blueprint 元件。
建立 modules/custom-addon/main.tf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| resource "helm_release" "custom_addon" {
name = var.addon_name
namespace = var.namespace
create_namespace = var.create_namespace
repository = var.helm_repo
chart = var.helm_chart
version = var.helm_version
dynamic "set" {
for_each = var.helm_settings
content {
name = set.key
value = set.value
}
}
values = var.helm_values
depends_on = [var.addon_dependencies]
}
# 如果需要 IAM 角色
module "irsa" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "~> 5.0"
count = var.create_irsa ? 1 : 0
role_name = "${var.addon_name}-irsa"
oidc_providers = {
main = {
provider_arn = var.oidc_provider_arn
namespace_service_accounts = ["${var.namespace}:${var.service_account_name}"]
}
}
role_policy_arns = var.irsa_policies
tags = var.tags
}
|
建立 modules/custom-addon/variables.tf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
| variable "addon_name" {
description = "Name of the addon"
type = string
}
variable "namespace" {
description = "Kubernetes namespace"
type = string
default = "default"
}
variable "create_namespace" {
description = "Create namespace if it doesn't exist"
type = bool
default = true
}
variable "helm_repo" {
description = "Helm repository URL"
type = string
}
variable "helm_chart" {
description = "Helm chart name"
type = string
}
variable "helm_version" {
description = "Helm chart version"
type = string
}
variable "helm_settings" {
description = "Helm chart settings"
type = map(string)
default = {}
}
variable "helm_values" {
description = "Helm chart values as list of strings"
type = list(string)
default = []
}
variable "create_irsa" {
description = "Create IAM role for service account"
type = bool
default = false
}
variable "oidc_provider_arn" {
description = "OIDC provider ARN"
type = string
default = ""
}
variable "service_account_name" {
description = "Service account name"
type = string
default = "default"
}
variable "irsa_policies" {
description = "IAM policies for IRSA"
type = list(string)
default = []
}
variable "addon_dependencies" {
description = "Dependencies for the addon"
type = list(any)
default = []
}
variable "tags" {
description = "Tags"
type = map(string)
default = {}
}
|
使用自訂 Add-on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| module "custom_monitoring" {
source = "./modules/custom-addon"
addon_name = "custom-monitoring"
namespace = "monitoring"
create_namespace = true
helm_repo = "https://charts.example.com"
helm_chart = "custom-monitoring"
helm_version = "1.0.0"
helm_settings = {
"replicaCount" = "2"
"resources.cpu" = "500m"
"resources.memory" = "512Mi"
}
helm_values = [
<<-EOT
ingress:
enabled: true
hosts:
- monitoring.example.com
persistence:
enabled: true
size: 100Gi
EOT
]
create_irsa = true
oidc_provider_arn = module.eks_blueprints.oidc_provider_arn
service_account_name = "custom-monitoring"
irsa_policies = ["arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"]
addon_dependencies = [module.eks_blueprints]
tags = local.tags
}
|
CDK 自訂 Add-on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| import * as blueprints from '@aws-quickstart/eks-blueprints';
import { Construct } from 'constructs';
import * as cdk from 'aws-cdk-lib';
export interface CustomAddonProps extends blueprints.addons.HelmAddOnUserProps {
customSetting?: string;
}
export class CustomAddon extends blueprints.addons.HelmAddOn {
readonly options: CustomAddonProps;
constructor(props?: CustomAddonProps) {
super({
name: 'custom-addon',
namespace: 'custom-namespace',
chart: 'custom-chart',
repository: 'https://charts.example.com',
version: '1.0.0',
release: 'custom-addon',
...props,
});
this.options = props ?? {};
}
deploy(clusterInfo: blueprints.ClusterInfo): Promise<Construct> {
const cluster = clusterInfo.cluster;
// 建立 IRSA
const serviceAccount = cluster.addServiceAccount('custom-addon-sa', {
name: 'custom-addon',
namespace: this.options.namespace,
});
// 附加 IAM 政策
serviceAccount.role.addManagedPolicy(
cdk.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy')
);
// 設定 Helm values
const values = {
serviceAccount: {
create: false,
name: serviceAccount.serviceAccountName,
},
customSetting: this.options.customSetting ?? 'default-value',
};
// 部署 Helm chart
return Promise.resolve(
this.addHelmChart(clusterInfo, values)
);
}
}
|
使用自訂 add-on:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| const addOns: Array<blueprints.ClusterAddOn> = [
// 標準 add-ons
new blueprints.addons.VpcCniAddOn(),
new blueprints.addons.CoreDnsAddOn(),
// 自訂 add-on
new CustomAddon({
customSetting: 'my-custom-value',
values: {
replicaCount: 2,
},
}),
];
blueprints.EksBlueprint.builder()
.addOns(...addOns)
.build(scope, 'custom-cluster');
|
驗證與測試
部署完成後,驗證叢集狀態:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 檢查節點狀態
kubectl get nodes -o wide
# 檢查所有 namespace 的 pods
kubectl get pods --all-namespaces
# 檢查 add-ons 狀態
kubectl get pods -n kube-system
kubectl get pods -n argocd
kubectl get pods -n monitoring
# 檢查服務
kubectl get svc --all-namespaces
# 檢查 Ingress
kubectl get ingress --all-namespaces
# 檢查 PVC
kubectl get pvc --all-namespaces
|
總結
AWS EKS Blueprints 提供了一個強大且靈活的框架,用於快速部署符合企業需求的 Kubernetes 叢集。透過本文介紹的內容,您已經學會:
- EKS Blueprints 基礎:理解架構設計和核心概念
- Terraform 部署:使用 Terraform 建立和管理 EKS 叢集
- CDK 部署:使用 AWS CDK 以程式化方式定義基礎架構
- Add-ons 管理:配置和自訂各種 Kubernetes 元件
- 團隊管理:實作多租戶和資源配額
- GitOps 整合:透過 ArgoCD 和 Flux 實現持續部署
- 多叢集架構:設計和部署跨區域、多環境的叢集
- 自訂開發:建立符合特定需求的自訂 add-ons
最佳實踐建議
- 版本控制:將所有 Blueprint 配置存放在 Git 儲存庫中
- 模組化設計:使用可重複使用的模組來管理共用配置
- 環境隔離:為不同環境(dev、staging、production)維護獨立的配置
- 安全優先:啟用必要的安全 add-ons,如 Secrets Manager、Cert Manager
- 監控完善:確保部署監控和日誌收集工具
- GitOps 實踐:採用 GitOps 工作流程管理應用程式部署
- 定期更新:定期更新 EKS 版本和 add-ons 以獲取安全修復
透過遵循這些最佳實踐,您可以建立一個穩定、安全且易於管理的 Kubernetes 平台。