목표 : eks 의 로드밸런서 콘트롤러와 ebs-csi addon 까지 자동화 구축하기
- root module - terraform registry 의 리소스를 참조하여 구성
provider.tf
# Configure the AWS Provider
provider "aws" {
region = "ap-northeast-2"
alias = "ap-northeast-2"
profile = var.profile
}
provider "kubernetes" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
}
provider "helm" {
kubernetes {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
args = ["eks", "get-token", "--cluster-name", var.cluster_name]
command = "aws"
}
}
}
- 출저 : https://github.com/terraform-aws-modules/terraform-aws-eks/issues/2009
프로바이더는 Terraform 코드 내에서 리소스를 생성하고 관리하기 위해 필요한 연결 및 설정 정보이다.
command = "aws"는 Helm 및 Kubernetes 프로바이더가 AWS CLI를 사용하여 Kubernetes 클러스터와 상호작용하기에 필요한 것으로 자격증명과정이다. 이것이 왜 필요하나면 eks 내부에 aws load balancer 설치와 역할이 연결되어야 하기 때문에 필요하다.
vpc.tf - 처음 테라폼이 실행되면서 생성된 vpc 의 사이더, 서브넷을 지정해준다. 리소스를 사용하면 라우팅 테이블 구성은 알아서 생성된다.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
providers = {
aws = aws.ap-northeast-2
}
name = var.cluster_name
cidr = "10.194.0.0/16"
azs = ["ap-northeast-2a", "ap-northeast-2c"]
public_subnets = ["10.194.0.0/24", "10.194.1.0/24"]
private_subnets = ["10.194.100.0/24", "10.194.101.0/24"]
enable_nat_gateway = true
enable_dns_hostnames = true
public_subnet_tags = {
"kubernetes.io/cluster/simon-test" = "owned" # 클러스터 이름 통일
"kubernetes.io/role/elb" = "1"
}
private_subnet_tags = {
"kubernetes.io/cluster/simon-test" = "owned" # 클러스터 이름 통일
"kubernetes.io/role/internal-elb" = "1"
}
}
각 서브넷의 태그는 매우 중요하다. aws-load-balancer 컨트롤러가 설치되면 vpc 에 접근하여 서브넷에 대한 권한을 얻게 되는데 특히 ingress 를 생성시에는 퍼블릿 서브넷을 부여하는 vpc-cni 역할을 한다. 즉 vpc 에 있는 서브넷을 분배 하는 역할 을 하게 되는데 이 서브넷에 대한 태그를 통하여 외부로 노출할 로드밸런서를 생성할 수 있다. 클러스터가 소유하게 될 서브넷에 대한 태그를 모두 지정해야 로드밸런서 콘트롤러가 애먹지 않는다. 클러스터는 당연히 vpc 에 대한 역할을 소유하고 있다.
eks.tf
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_endpoint_public_access = true
cluster_enabled_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
cluster_name = "simon-test"
cluster_version = "1.29"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
control_plane_subnet_ids = module.vpc.private_subnets
providers = {
aws = aws.ap-northeast-2
}
eks_managed_node_group_defaults = {
ami_type = "AL2_x86_64"
}
eks_managed_node_groups = {
one = {
name = "node-group-1"
instance_types = ["t3.small"]
min_size = 1
max_size = 3
desired_size = 2
}
two = {
name = "node-group-2"
instance_types = ["t3.small"]
min_size = 1
max_size = 2
desired_size = 1
}
}
enable_cluster_creator_admin_permissions = true
cluster_addons = {
coredns = {
preserve = true
most_recent = true
timeouts = {
create = "25m"
delete = "10m"
}
}
kube-proxy = {
most_recent = true
}
vpc-cni = {
most_recent = true
}
}
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
control_plane_subnet_ids = module.vpc.private_subnets ---> vpc.tf 의 모듈에 eks 를 구축한다는 뜻이다. module.vpc 는 vpc를 뜻한다
variables.tf
variable "profile" {
type = string
default = "default"
}
variable "main-region" {
type = string
default = "ap-northeast-2"
}
variable "cluster_name" {
type = string
default = "simon-test"
}
variable "rolearn" {
description = "Add admin role to the aws-auth configmap"
}
variable "CREDENTIAL_FILES" {
description = "This is a path of credentials file"
default = "/.aws/credentials"
}
각 모듈에 참조할 변수이다.
alb.tf
module "aws_load_balancer_controller_irsa_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
role_name = "aws-load-balancer-controller"
attach_load_balancer_controller_policy = true
oidc_providers = {
main = {
provider_arn = module.eks.oidc_provider_arn
namespace_service_accounts = ["kube-system:aws-load-balancer-controller"]
}
}
}
main.tf 에서 eks 가 생성되면 oidc 는 자동 발급된다. 로드밸런서컨트롤러 같은 경우는 aws 에서 서비스 해 주지 않아 꾸버네티스가 aws 에 들어와 RBAC 형태로 서비스해준다. 따라서 AWS 에서는 OIDC 라는 웹자격증명을 통해 로드밸런서 컨트롤러에 대한 역할에 기반한 제어권만을 부여해 주게 된다.
https://registry.terraform.io/modules/terraform-aws-modules/iam/aws/latest/submodules/iam-role-for-service-accounts-eks --출저
-I-AM-ASSUMABLE-OIDC 로 생성해 봤는데
유효한 ARN 을 사용해서 형식에 맞는 정책과 역할에 대한 신뢰관계가 작성되야 한다고 하는 거 같다.
공식문서에 따라서 IRSA 리소스에 맞는 모듈을 사용하면 된다.
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/aws-load-balancer-controller.html- 출저
cat >load-balancer-role-trust-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com",
"oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
}
}
}
]
}
EOF
IRSA 정책과 역할의 신뢰관계 예시
-생성한 역할을 기반으로 이제 KUBE-SYSTEM 에 꾸버네띠스 SA 를 생성해 준다.
resource "kubernetes_service_account" "aws_load_balancer_controller" {
metadata {
name = "aws-load-balancer-controller"
namespace = "kube-system"
labels = {
"app.kubernetes.io/name" = "aws-load-balancer-controller"
"app.kubernetes.io/component" = "controller"
}
annotations = {
"eks.amazonaws.com/role-arn" = module.aws_load_balancer_controller_irsa_role.iam_role_arn
"eks.amazonaws.com/sts-regional-endpoints" = "true"
}
}
depends_on = [module.eks]
}
중요한 것은 여기 주석이다.
"eks.amazonaws.com/role-arn" = module.aws_load_balancer_controller_irsa_role.iam_role_arn
https://github.com/kubernetes-sigs/aws-load-balancer-controller/issues/1138 - 출저
꾸버네티스에 irsa 를 통해 생성된 역할을 부여해줘야 콘트롤러를 실행할 수 있는 권한을 갖는다. 위에서 생성한 모듈의 i am role arn 을 뜻한다. 이 arn 을 통해 자격증명을 얻고 일을 하게 된다.
그 다음은 helm 으로 설치하는 것인데 선수 조건 꾸버네티스 계정이 생성되고 난 이후이다. - helm 최신 버전이 깔렷는데 정책은 구버전 그대로면 애러가 난다. irsa 모듈을 참조해 롤과 정책을 부착하는 것이 가용성이 좋다고 본다.
resource "helm_release" "lb_controller" {
name = "aws-load-balancer-controller"
repository = "https://aws.github.io/eks-charts"
chart = "aws-load-balancer-controller"
namespace = "kube-system"
depends_on = [
kubernetes_service_account.aws_load_balancer_controller
]
set {
name = "clusterName"
value = var.cluster_name
}
set {
name = "serviceAccount.create"
value = "false"
}
set {
name = "serviceAccount.name"
value = kubernetes_service_account.aws_load_balancer_controller.metadata[0].name
}
set {
name = "region"
value = var.main-region
}
set {
name = "vpcId"
value = module.vpc.vpc_id
}
}
EKS - jenkins - ArgoCD 인프라 구축 -Terraform -(2) (0) | 2024.04.18 |
---|---|
EKS - jenkins - ArgoCD 인프라 구축 -Terraform (0) | 2024.04.18 |
테라폼으로 eks 구축하기 (0) | 2024.03.31 |